public AccumCounter Push() { var ret = new AccumCounter { _parent = this, Enabled = true }; Logger.WriteLine(4, "Push {0} => {1}", this, ret); return(ret); }
public bool Exit(bool accums = false) { Symbols.CurrentScope.Pop(); if (accums) { _accum = _accum.Pop(); } return(true); }
// Where is just a funcall with a code predicate (that may have a fold) public AstWhere Where(string name, AstValue predicate) { var lookup = DataHeading.Create(Symbols.CurrentScope.LookupItems.Items); var code = Code(predicate, lookup, "&p", false, _accum.Total, _accum.HasWin); _accum = _accum.Push(); return(new AstWhere { Func = FindFunc(name), DataType = Types.Relof(CurrentHeading()), Arguments = Args(code), }); }
// Enter scope for a transform, with accumulator tracking public bool Enter(AstValue value) { Symbols.CurrentScope.Push(value.DataType); _accum = _accum.Push(); return(true); }
///============================================================================================ /// /// scopes /// // Enter scope for a function definition, with accumulator tracking public bool Enter(string ident, AstType rettype, IList <AstField> arguments) { // missing args means lazy; else check for dups if (arguments != null) { var dups = arguments.GroupBy(a => a.Name).Where(g => g.Count() > 1).Select(d => d.Key); if (dups.Count() > 0) { Parser.ParseError($"duplicate parameter '{dups.First()}'"); } } var args = (arguments == null) ? null : arguments.Select(a => DataColumn.Create(a.Name, a.DataType)).ToArray(); var rtype = (rettype == null) ? DataTypes.Unknown : rettype.DataType; // ident means it's func def not funval if (ident != null) { // if cannot define, then see if can overload Symbol overfunc = null; if (!Symbols.CanDefGlobal(ident)) { overfunc = Symbols.FindIdent(ident); if (!overfunc.IsCallable) { overfunc = null; } if (overfunc == null) { Parser.ParseError("already defined: {0}", ident); } } // create new symbol or add an overload // error if dup on args; return type not counter if (overfunc == null) { Symbols.AddDeffun(ident, rtype, args, 0, false); } else { if (args == null) { Parser.ParseError($"overload not allowed: '{ident}'"); } if (!Symbols.AddOverload(overfunc, rtype, args)) { Parser.ParseError($"overload argument type conflict: '{ident}'"); } } } // now prepare scope Symbols.CurrentScope.Push(); if (args != null) { foreach (var a in args) { Symbols.AddVariable(a.Name, a.DataType, SymKinds.PARAM, false); } } _accum = _accum.Push(); return(true); }