示例#1
0
 public static List<object> PairToList(Pair l)
 {
     List<object> r = new List<object>();
     while (l != null) {
         r.Add(l.Car);
         l = (Pair)l.Cdr;
     }
     return r;
 }
示例#2
0
 public static Pair ListToPair(List<object> l)
 {
     Pair r = null;
     for (int i = l.Count - 1; i >= 0; --i) {
         r = new Pair() {
             Car = l[i], Cdr = r
         };
     }
     return r;
 }
        private ByteCodeInterpreter()
        {
            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, HostProcedure> builtinProcedures = new Dictionary<string, HostProcedure>() {
                {"not", (stack, ret) => stack[ret]=!(bool)stack[ret+1]},
                {"identity", (stack, ret) => stack[ret]=stack[ret+1]},
                {"sqr", (stack, ret) => {var a = (INumber)stack[ret+1]; stack[ret]=a.Mul(a);} },
                {"+", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Add((INumber)stack[ret+2])},
                {"-", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Sub((INumber)stack[ret+2])},
                {"*", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Mul((INumber)stack[ret+2])},
                {"/", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Div((INumber)stack[ret+2])},
                {"quotient", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Div((INumber)stack[ret+2]).CastToInteger()},
                {"remainder", (stack, ret) => stack[ret]=((INumber)stack[ret+1]).Mod((INumber)stack[ret+2])},
                {"=", (stack, ret) => stack[ret]=stack[ret+1].Equals(stack[ret+2])},
                {"<", (stack, ret) => stack[ret]=(stack[ret+1] as IComparable).CompareTo(stack[ret+2]) < 0},
                {"<=", (stack, ret) => stack[ret]=(stack[ret+1] as IComparable).CompareTo(stack[ret+2]) <= 0},
                {">", (stack, ret) => stack[ret]=(stack[ret+1] as IComparable).CompareTo(stack[ret+2]) > 0},
                {">=", (stack, ret) => stack[ret]=(stack[ret+1] as IComparable).CompareTo(stack[ret+2]) >= 0},
                {"eq?", (stack, ret) => stack[ret]=object.ReferenceEquals(stack[ret+1], stack[ret+2])},

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

                {"pretty-print", (stack, ret) => {
                                               ListProcess.PrintPairExp(stack[ret+1]);
                                               stack[ret] = null;
                                           }},
                {"display", (stack, ret) => {
                                          ListProcess.PrintListExp(ListProcess.PairExpToListExp(stack[ret+1]));
                                          stack[ret] = null;
                                      }},
                {"current-inexact-milliseconds", (stack, ret) => {
                                                               long now;
                                                               Utils.QueryPerformanceCounter(out now);
                                                               stack[ret] = Number.Create((decimal)(now - mTimerStart) * 1000 / mTimerFreq);
                                                           }},
                {"exit", (stack, ret) => {
                                       Environment.Exit(0);
                                       stack[ret] = null;
                                   }},
                {"random", (stack, ret) => stack[ret] = Number.Create(mRandom.Next(((NumberInteger)stack[ret+1]).value))},
                {"eval", (stack, ret) => stack[ret] = Interpret(ListProcess.PairExpToListExp(stack[ret+1]))},
            };

            GlobalEnv.Instance().ReserveVariables(builtinVars.Count + builtinProcedures.Count);
            foreach (KeyValuePair<string, object> kv in builtinVars) {
                GlobalEnv.Instance().variables[SymbolTable.DefineOrGetGlobalSymbol(kv.Key).index] = kv.Value;
            }
            foreach (KeyValuePair<string, HostProcedure> kv in builtinProcedures) {
                GlobalEnv.Instance().variables[SymbolTable.DefineOrGetGlobalSymbol(kv.Key).index] = kv.Value;
            }
        }