Пример #1
0
        void CompileSexpr(SexprNode sexpr, NodeListParser nlp)
        {
            Logger.WriteLine(4, "CompileSexpr {0} <{1}>", sexpr, nlp);

            var snlp = NodeListParser.Create(sexpr.Args, Symbols);

            _currentparser = snlp;

            // intrinsics with individual parser and code generator
            if (sexpr.Sym.IsControl)
            {
                if (_controllookup.ContainsKey(sexpr.Sym.Keyword))
                {
                    _controllookup[sexpr.Sym.Keyword](sexpr.Sym, snlp, this);
                }
                else
                {
                    nlp.Unexpected("unknown control function");
                }
            }
            else
            {
                CompileBuiltin(sexpr.Sym as BuiltinSymbol, snlp);
            }
        }
Пример #2
0
        // take a list of headed nodes and return as a dictionary
        // note: key is name of head ident
        internal static Dictionary <string, List <List <Node> > > GetDict(IList <Node> nn)
        {
            var dict = new Dictionary <string, List <List <Node> > >();

            foreach (var n in nn)
            {
                NodeListParser nlp = NodeListParser.Create(n);
                //dict.AddMulti(nlp.Current.AsIdent.Ident, nlp.Nodes.ToList()); // breaking!!!
                dict.AddMulti(nlp.GetIdent().Name, nlp.GetTail().ToList());
            }
            return(dict);
        }
Пример #3
0
        // 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();
        }
Пример #4
0
        // Compile an argument of given type
        void CompileArg(Type type, NodeListParser nlp)
        {
            Logger.WriteLine(4, "CompileArg {0} <{1}>", type, nlp);

            var func = _typeactiondict.SafeLookup(type);

            // special for variable assignment and implicit definition
            if (type == typeof(Variable))
            {
                var ident    = nlp.GetIdent();
                var datatype = DataTypes.Bool; // TODO: handle other types
                if (ident.Sym.IsVariable)
                {
                    nlp.Expect(ident.Sym.DataType == datatype, "variable of type {0}", datatype);
                }
                else if (ident.Sym.IsUndef)
                {
                    Symbols.DefineVariable(ident.Name, datatype, BoolValue.False);
                }
                else
                {
                    nlp.Expected("defined variable");
                }
                _gen.EmitRefVar(ident.Sym);

                // handle these separately, could be variable or function
            }
            else if (type.IsSubclassOf(typeof(TypedValue)))
            {
                // TODO: type checking
                CompileValue(type, nlp);
                //var exptype = TypedValue.DataTypeDict.SafeLookup(type);
                //var rettype = CompileValue(type, nlp);
                //nlp.Expect(rettype == exptype, "value of type {0}", exptype);

                // direct lookup gets special cases; else continue
            }
            else if (func != null)
            {
                var value = func(type, nlp, this);
                _gen.EmitLoadValue(value);

                // Array means parse a list of this type
            }
            else if (type.IsArray)
            {
                var nargs = 0;
                for (var nlp2 = nlp.GetParser(); !nlp2.Done; nargs++)
                {
                    CompileArg(type.GetElementType(), nlp2);
                }
                _gen.EmitToArray(type, nargs);

                // List<> means parse a tail of this type
            }
            else if (type.IsGenericType && type.Name.StartsWith("List"))
            {
                var nargs = 0;
                for (; !nlp.Done; ++nargs)
                {
                    CompileArg(type.GetGenericArguments()[0], nlp);
                }
                _gen.EmitToList(type, nargs);

                // Pair<> means parse a pair of arbitrary types
            }
            else if (type.IsGenericType && type.Name.StartsWith("Pair"))
            {
                var nlp2 = nlp.GetParser();
                foreach (var subtype in type.GetGenericArguments())
                {
                    CompileArg(subtype, nlp2);
                }
                _gen.EmitToPair(type);

                // nested prog block
            }
            else if (type.IsSubclassOf(typeof(CodeBase)))
            {
                var info = Symbols.PredefScopeDict.First(kv => kv.Value.CodeType == type).Value;
                CompileProg(info, nlp);
            }
            else if (type == typeof(PositionOrDirection))
            {
                CompilePositionOrDirection(nlp);

                // function call on built in
            }
            else if (nlp.IsSexpr)
            {
                var sexpr    = nlp.GetSexprNode();
                var datatype = TypedValue.DataTypeDict.SafeLookup(type);
                nlp.Expect(sexpr.DataType == datatype, "value of type {0}", datatype);
                CompileBuiltin(sexpr.Sym as BuiltinSymbol, NodeListParser.Create(sexpr.Args, Symbols));
            }
            else
            {
                nlp.Syntax("unknown type {0}", type);
            }
        }
Пример #5
0
 // main entry point, parses all the variants and returns a list
 internal void CompileMenu(IList <Node> nodes)
 {
     Logger.WriteLine(1, "CompileMenu {0} nodes", nodes.Count);
     CompileProg(PredefScopes.MENU, NodeListParser.Create(nodes, Symbols));
 }