private void AddMethod(string name, CallInfo binfo, PredefScopes scope) { var sb = new StringBuilder(); foreach (var ch in name) { if (Char.IsUpper(ch)) { if (sb.Length > 0) { sb.Append("-"); } sb.Append(Char.ToLower(ch)); } else if (ch == '_') { sb.Append('-'); } else { sb.Append(ch); } } if (sb[sb.Length - 1] == '-') { sb[sb.Length - 1] = '?'; } AddBuiltin(sb.ToString(), binfo, scope); }
Symbol AddBuiltin(string name, CallInfo binfo, PredefScopes scope) { return(Add(name, new BuiltinSymbol { Atom = Atoms.IDENT, Kind = SymKinds.PREDEF, PredefScope = scope, CallInfo = binfo, DataType = TypedValue.DataTypeDict.SafeLookup(binfo.ReturnType), // UNKNOWN if not found })); }
Symbol AddPredef(string name, PredefScopes pscope, PredefKinds pkind, DataTypes datatype = DataTypes.Unknown) { return(Add(name, new Symbol { Atom = Atoms.IDENT, Kind = SymKinds.PREDEF, PredefScope = pscope, PredefKind = pkind, DataType = datatype, })); }
// Add a specific set of methods into a new scope // Pop the scope but keep a pointer to it in a look up table private void AddBuiltinMethods(PredefScopes predefscope, Type codetype, Type deftype, PredefKinds kind) { var scope = CurrentScope.Push(); PredefScopeDict[predefscope] = new BuiltinScopeInfo { Predef = predefscope, CodeType = codetype, DefType = deftype, Scope = scope, Kind = kind, }; foreach (var binfo in CallInfo.GetBuiltinInfo(codetype)) { AddMethod(binfo.Name, binfo, predefscope); } scope.Pop(); }
// Compile a scoped expression that returns a typed value DataTypes CompileExpr(PredefScopes predef, NodeListParser nlp) { Logger.WriteLine(2, "CompileExpr {0} <{1}>", predef, nlp); Symbols.PushPredefScope(predef); var codetype = Symbols.PredefScopeDict[predef].CodeType; _gen.EmitEntry(codetype); nlp.Expect(nlp.IsCallable, "callable function"); var sexpr = nlp.GetSexprNode(); nlp.Expect(sexpr.DataType != DataTypes.Void, "typed function"); CompileSexpr(sexpr, nlp); Symbols.PopPredefScope(); _gen.EmitExit(true); return(sexpr.DataType); }
internal void CompileProg(PredefScopes predef, NodeListParser nlp) { Logger.WriteLine(2, "CompileProg {0} <{1}>", predef, nlp); _currentparser = nlp; Symbols.PushPredefScope(predef); if (predef == PredefScopes.GAME) { Symbols.CurrentScope.Push(); } var codetype = Symbols.PredefScopeDict[predef].CodeType; _gen.EmitEntry(codetype); CompileProg(nlp); _gen.EmitExit(false); Symbols.PopPredefScope(); if (predef == PredefScopes.GAME) { Symbols.CurrentScope.Pop(); } }
// Compile and merge nodes from base game and variant internal void CompileGameOrVariant(PredefScopes predef, NodeListParser nlp) { Logger.WriteLine(1, "CompileGameOrVariant {0} <{1}>", predef, nlp); Symbols.PushPredefScope(predef); Symbols.CurrentScope.Push(); // game index will define pieces if (_game_index == null) { _game_index = new GameIndex(); _currentparser = NodeListParser.Create(_game_index.IndexGame(nlp), nlp.Symbols); } else { _currentparser = NodeListParser.Create(_game_index.MergeVariant(nlp), nlp.Symbols); } var codetype = Symbols.PredefScopeDict[predef].CodeType; _gen.EmitEntry(codetype); CompileProg(_currentparser); _gen.EmitExit(false); Symbols.CurrentScope.Pop(); Symbols.PopPredefScope(); }
internal void PushPredefScope(PredefScopes predef) { Logger.WriteLine(4, "Push predef {0} = {1}", _predefscopestack.Count, predef); _predefscopestack.Push(CurrentScope.Parent); CurrentScope.Parent = PredefScopeDict[predef].Scope; }