public object Interpret(object exp)
        {
            IASTNode node = ASTCompiler.Compile(null, ListProcess.TransformLibraryForms(exp));

            ReserveGlobalVaraible(SymbolTable.GetGlobalSymbolCount());
            ASTNode_Lambda lambdaNode = new ASTNode_Lambda {
                bodyNode    = node, bodyFreeAddresses = new List <FreeAddress>(), childrenFreeAddresses = new List <FreeAddress>(),
                formalCount = 0, locals = new List <string>(),
            };

            var fileName        = "____test.exe";
            var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName(GenernateUniqueString("assemly")), AssemblyBuilderAccess.RunAndSave);
            var moduleBuilder  = assemblyBuilder.DefineDynamicModule(GenernateUniqueString("module"), fileName, HasSymbolInfo());
            var envTypeBuilder = moduleBuilder.DefineType(GenernateUniqueString("class"));

            var methodBuilder = new ASTNodeVisitor_JITCompiler(null, envTypeBuilder, lambdaNode).MethodBuilder;

            var type = envTypeBuilder.CreateType();

            assemblyBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);
            // assemblyBuilder.Save(fileName);

            return(((Func <object>)type.GetMethod(methodBuilder.Name).CreateDelegate(typeof(Func <object>)))());
        }
예제 #2
0
        public object Interpret(object exp)
        {
            IASTNode node = ASTCompiler.Compile(null, ListProcess.TransformLibraryForms(exp));

            Env.ReserveGlobalVariables(SymbolTable.GetGlobalSymbolCount());

            return(new ASTNodeVisitor_Interpreter(null, node).Value);
        }
예제 #3
0
        static void Main(string[] args)
        {
            var tokens = Parser.Tokenize(new System.IO.StreamReader("../../test.rkt").ReadToEnd());

            while (true)
            {
                object s = Parser.Parse(tokens);
                if (s == null)
                {
                    break;
                }
                object v = JITInterpreter_DS2.Instance().Interpret(s);
                // object v = JITInterpreter_DS.Instance().Interpret(s);
                // object v = ASTInterpreter.Instance().Interpret(s);
                if (v != null)
                {
                    ListProcess.PrintPairExp(v);
                }
            }
        }
        private JITInterpreter_DS()
        {
            Utils.QueryPerformanceCounter(out mTimerStart);
            Utils.QueryPerformanceFrequency(out mTimerFreq);

            Dictionary <string, object> builtinVars = new Dictionary <string, object>()
            {
                { "true", true },
                { "false", false },
                { "else", true },
                { "null", null },
            };
            Dictionary <string, object> builtinProcedures = new Dictionary <string, object>()
            {
                { "not", (Func <object, object>)(a => !(bool)a) },
                { "identity", (Func <object, object>)(a => a) },
                { "sqr", (Func <object, object>)(a => { var v = (INumber)a; return(v.Mul(v)); }) },
                { "+", (Func <object, object, object>)((a, b) => ((INumber)a).Add((INumber)b)) },
                { "-", (Func <object, object, object>)((a, b) => ((INumber)a).Sub((INumber)b)) },
                { "*", (Func <object, object, object>)((a, b) => ((INumber)a).Mul((INumber)b)) },
                { "/", (Func <object, object, object>)((a, b) => ((INumber)a).Div((INumber)b)) },
                { "quotient", (Func <object, object, object>)((a, b) => ((INumber)a).Div((INumber)b).CastToInteger()) },
                { "remainder", (Func <object, object, object>)((a, b) => ((INumber)a).Mod((INumber)b)) },
                { "=", (Func <object, object, object>)((a, b) => ((INumber)a).CompareTo((INumber)b) == 0) },
                { "<", (Func <object, object, object>)((a, b) => ((INumber)a).CompareTo((INumber)b) < 0) },
                { "<=", (Func <object, object, object>)((a, b) => ((INumber)a).CompareTo((INumber)b) <= 0) },
                { ">", (Func <object, object, object>)((a, b) => ((INumber)a).CompareTo((INumber)b) > 0) },
                { ">=", (Func <object, object, object>)((a, b) => ((INumber)a).CompareTo((INumber)b) >= 0) },
                { "eq?", (Func <object, object, object>)((a, b) => object.ReferenceEquals(a, b)) },
                { "equal?", (Func <object, object, object>)((a, b) => object.Equals(a, b)) },

                { "cons", (Func <object, object, object>)((a, b) => new Pair()
                    {
                        Car = a, Cdr = b
                    }) },
                { "car", (Func <object, object>)(a => ((Pair)a).Car) },
                { "cdr", (Func <object, object>)(a => ((Pair)a).Cdr) },
                { "drop", (Func <object, object, object>)((a, b) => {
                        Pair l = (Pair)a; int n = ((NumberInteger)b).value;
                        for (; n > 0; --n)
                        {
                            l = (Pair)l.Cdr;
                        }
                        return(l);
                    }) },
                { "length", (Func <object, object>)(a => {
                        int n = 0;
                        for (Pair l = (Pair)a; l != null; ++n, l = (Pair)l.Cdr)
                        {
                            ;
                        }
                        return(Number.Create(n));
                    }) },
                { "append", (Func <object, object, object>)((a, b) => {
                        var l = ListProcess.PairToList((Pair)a);
                        return(ListProcess.ConcatListAndPairToNewPair(l, (Pair)b));
                    }) },
                { "empty?", (Func <object, object>)(a => a == null) },
                { "void", (Func <object>)(() => null) },

                { "pretty-print", (Func <object, object>)(a => {
                        ListProcess.PrintPairExp(a);
                        return(null);
                    }) },
                { "display", (Func <object, object>)(a => {
                        ListProcess.PrintListExp(ListProcess.PairExpToListExp(a));
                        return(null);
                    }) },
                { "current-inexact-milliseconds", (Func <object>)(() => {
                        long now;
                        Utils.QueryPerformanceCounter(out now);
                        return(Number.Create((decimal)(now - mTimerStart) * 1000 / mTimerFreq));
                    }) },
                { "exit", (Func <object>)(() => {
                        Environment.Exit(0);
                        return(null);
                    }) },
                { "random", (Func <object, object>)(a => Number.Create(mRandom.Next(((NumberInteger)a).value))) },
                { "eval", (Func <object, object>)(a => { return(Instance().Interpret(ListProcess.PairExpToListExp(a))); }) },
            };

            ReserveGlobalVaraible(builtinVars.Count + builtinProcedures.Count);
            foreach (KeyValuePair <string, object> kv in builtinVars)
            {
                mGlobalVariables[SymbolTable.DefineOrGetGlobalSymbol(kv.Key).index] = kv.Value;
            }
            foreach (KeyValuePair <string, object> kv in builtinProcedures)
            {
                mGlobalVariables[SymbolTable.DefineOrGetGlobalSymbol(kv.Key).index] = kv.Value;
            }
        }
예제 #5
0
        static public IASTNode Compile(SymbolTable symTable, object exp)
        {
            if (exp is string)
            {
                return(new ASTNode_GetVar {
                    address = SymbolTable.Lookup(symTable, (string)exp)
                });
            }
            else if (exp is INumber)
            {
                return(new ASTNode_Literal {
                    value = exp
                });
            }

            List <object> form = exp as List <object>;

            switch (form[0] as string)
            {
            case "quote":
                return(new ASTNode_Literal {
                    value = ListProcess.ListExpToPairExp(form[1])
                });

            case "if":
                return(new ASTNode_If {
                    predNode = Compile(symTable, form[1]), thenNode = Compile(symTable, form[2]), elseNode = Compile(symTable, form[3])
                });

            case "begin":
                return(new ASTNode_Begin {
                    nodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList()
                });

            case "lambda": {
                SymbolTable newSymTable = new SymbolTable(symTable);

                var formals = ((List <object>)form[1]).Cast <string>();
                foreach (var name in formals)
                {
                    newSymTable.DefineLocalSymbol(name);
                }

                List <string> defines = new List <string>();
                ListProcess.FindDefinition(defines, (List <object>)form[2], 1);
                foreach (var name in defines)
                {
                    newSymTable.DefineLocalSymbol(name);
                }

                IASTNode body   = Compile(newSymTable, form[2]);
                var      finder = new ASTNodeVisitor_FindFreeAddresses(body);

                return(new ASTNode_Lambda {
                        formalCount = ((List <object>)form[1]).Count,
                        locals = formals.Concat(defines).ToList(),
                        bodyNode = body,
                        bodyFreeAddresses = finder.BodyFreeAddresses.ToList(),
                        childrenFreeAddresses = finder.ChildrenFreeAddresses.ToList(),
                    });
            }

            case "define":
            case "set!":
                return(new ASTNode_SetVar {
                    address = SymbolTable.Lookup(symTable, (string)form[1]), rightNode = Compile(symTable, form[2])
                });

            default:
                return(new ASTNode_Application {
                    procedureNode = Compile(symTable, form[0]),
                    actualNodes = form.Skip(1).Select(e => Compile(symTable, e)).ToList(),
                });
            }
        }
예제 #6
0
        private ASTInterpreter()
        {
            Utils.QueryPerformanceCounter(out sTimerStart);
            Utils.QueryPerformanceFrequency(out sTimerFreq);

            Dictionary <string, object> builtinVars = new Dictionary <string, object>()
            {
                { "true", true },
                { "false", false },
                { "else", true },
                { "null", null },
            };

            Dictionary <string, Procedure> builtinProcedures = new Dictionary <string, Procedure>()
            {
                { "not", (args) => !(bool)args[0] },
                { "identity", (args) => args[0] },
                { "sqr", (args) => { var a = args[0] as INumber; return(a.Mul(a)); } },
                { "+", (args) => ((INumber)args[0]).Add((INumber)args[1]) },
                { "-", (args) => ((INumber)args[0]).Sub((INumber)args[1]) },
                { "*", (args) => ((INumber)args[0]).Mul((INumber)args[1]) },
                { "/", (args) => ((INumber)args[0]).Div((INumber)args[1]) },
                { "quotient", (args) => ((INumber)args[0]).Div((INumber)args[1]).CastToInteger() },
                { "remainder", (args) => ((INumber)args[0]).Mod((INumber)args[1]) },
                { "=", (args) => (args[0].Equals(args[1])) },
                { "<", (args) => (args[0] as IComparable).CompareTo(args[1]) < 0 },
                { "<=", (args) => (args[0] as IComparable).CompareTo(args[1]) <= 0 },
                { ">", (args) => (args[0] as IComparable).CompareTo(args[1]) > 0 },
                { ">=", (args) => (args[0] as IComparable).CompareTo(args[1]) >= 0 },
                { "eq?", (args) => object.ReferenceEquals(args[0], args[1]) },

                { "cons", (args) => new Pair()
                  {
                      Car = args[0], Cdr = args[1]
                  } },
                { "car", (args) => ((Pair)args[0]).Car },
                { "cdr", (args) => ((Pair)args[0]).Cdr },
                { "drop", (args) => {
                      Pair l = (Pair)args[0]; int n = ((NumberInteger)args[1]).value;
                      for (; n > 0; --n)
                      {
                          l = (Pair)l.Cdr;
                      }
                      return(l);
                  } },
                { "length", (args) => {
                      int n = 0;
                      for (Pair l = (Pair)args[0]; l != null; ++n, l = (Pair)l.Cdr)
                      {
                          ;
                      }
                      return(Number.Create(n));
                  } },
                { "append", (args) => {
                      var l = ListProcess.PairToList((Pair)args[0]);
                      l.InsertRange(l.Count, ListProcess.PairToList((Pair)args[1]));
                      return(ListProcess.ListToPair(l));
                  } },
                { "empty?", (args) => args[0] == null },

                { "pretty-print", (args) => {
                      ListProcess.PrintPairExp(args[0]);
                      return(null);
                  } },
                { "display", (args) => {
                      ListProcess.PrintListExp(ListProcess.PairExpToListExp(args[0]));
                      return(null);
                  } },
                { "current-inexact-milliseconds", (args) => {
                      long now;
                      Utils.QueryPerformanceCounter(out now);
                      return(Number.Create((decimal)(now - sTimerStart) * 1000 / sTimerFreq));
                  } },
                { "exit", (args) => {
                      Environment.Exit(0);
                      return(null);
                  } },
                { "random", (args) => Number.Create(sRandom.Next(((NumberInteger)args[0]).value)) },
                { "eval", (args) => Instance().Interpret(ListProcess.PairExpToListExp(args[0])) },
            };

            Env.ReserveGlobalVariables(builtinVars.Count + builtinProcedures.Count);
            foreach (KeyValuePair <string, object> kv in builtinVars)
            {
                Env.DefineBuiltin(SymbolTable.DefineOrGetGlobalSymbol(kv.Key), kv.Value);
            }
            foreach (KeyValuePair <string, Procedure> kv in builtinProcedures)
            {
                Env.DefineBuiltin(SymbolTable.DefineOrGetGlobalSymbol(kv.Key), kv.Value);
            }
        }