Example #1
0
 public Value this[string key]
 {
     get
     {
         return Get(key);
     }
     set
     {
         mValues = new List(new List(new Word(key), new List(value, List.Nil)), mValues);
     }
 }
Example #2
0
 public void Add(string key, Value val)
 {
     if (ContainsKey(key))
         throw new Exception("'" + key + "' already defined.");
     mValues = new List(new List(new Word(key), new List(val, List.Nil)), mValues);
 }
Example #3
0
 static void AddBuiltinFunctions(Environment top)
 {
     //Missing: cond, atom
     top.Add("+", new BuiltinFunction((env, args) =>
     {
         int accum = 0;
         while (args != List.Nil)
         {
             accum += ((Int)args.Val.Eval(env)).Val;
             args = args.Next;
         }
         return new Int(accum);
     }));
     top.Add("list", new BuiltinFunction((env, args) =>
     {
         return args.Map(v => v.Eval(env));
     }));
     top.Add("cons", new BuiltinFunction((env, args) =>
     {
         return new List(args.Val.Eval(env), (List)args.Next.Val.Eval(env));
     }));
     top.Add("quote", new BuiltinFunction((env, args) =>
     {
         return args.Val;
     }));
     top.Add("car", new BuiltinFunction((env, args) =>
     {
         var l = args.Val.Eval(env) as List;
         return l.Val;
     }));
     top.Add("cdr", new BuiltinFunction((env, args) =>
     {
         var l = args.Val.Eval(env) as List;
         return l.Next;
     }));
     top.Add("print", new BuiltinFunction((env, args) =>
     {
         Value v = args.Val.Eval(env);
         string str;
         if (v is String)
             str = ((String)v).Val;
         else
             str = v.ToString();
         Console.WriteLine(str);
         return List.Nil;
     }));
     top.Add("if", new BuiltinFunction((env, args) =>
     {
         if (args.Val.Eval(env).IsTrue())
             return args.Next.Val.Eval(env);
         else
             return args.Next.Next.Val.Eval(env);
     }));
     top.Add("listp", new BuiltinFunction((env, args) =>
     {
         if (args.Val.Eval(env) is List)
             return True.T;
         else
             return List.Nil;
     }));
     top.Add("lambda", new BuiltinFunction((env, args) =>
     {
         var formalArgs = ((List)args.Val);
         var body = args.Next.Map(v => v.Eval(env));
         var newFun = new UserFunction(formalArgs, body);
         return newFun;
     }));
     top.Add("defmacro", new BuiltinFunction((env, args) =>
     {
         var name = ((Word)args.Val).Val;
         var formalArgs = ((List)args.Next.Val);
         var body = (List)args.Next.Next.Val;
         var newFun = new UserMacro(formalArgs, body);
         top[name] = newFun;
         return newFun;
     }));
     top.Add("exit", new BuiltinFunction((env, args) =>
     {
         var exitArg = args.Val.Eval(env) as Int;
         int exitCode = 0;
         if (exitArg != null)
             exitCode = exitArg.Val;
         System.Environment.Exit(exitCode);
         return List.Nil;
     }));
     top.Add("eq", new BuiltinFunction((env, args) =>
     {
         var v1 = args.Val.Eval(env);
         var v2 = args.Next.Val.Eval(env);
         if (v1.Equals(v2))
             return True.T;
         else
             return List.Nil;
     }));
     top.Add("code", new BuiltinFunction((env, args) =>
     {
         var val = args.Val.Eval(env);
         if (val is UserFunction)
         {
             var fun = args.Val.Eval(env) as UserFunction;
             return new List(fun.mArgNames, new List(fun.mFun, List.Nil));
         }
         else if (val is UserMacro)
         {
             var fun = args.Val.Eval(env) as UserMacro;
             return new List(fun.mArgNames, new List(fun.mFun, List.Nil));
         }
         else
             throw new Exception("Could not find user function.");
     }));
     top.Add("read", new BuiltinFunction((env, args) =>
     {
         var fileName = ((String)args.Val.Eval(env)).Val;
         var values = new Stack<Value>();
         using (var file = new StreamReader(fileName))
         {
             var scan = new Scanner(file);
             while (scan.Peek().Item1 != TokenType.EOF)
             {
                 values.Push(Parse(scan));
             }
         }
         var ret = List.Nil;
         foreach (var v in values)
         {
             ret = new List(v, ret);
         }
         return ret;
     }));
     top.Add("eval", new BuiltinFunction((env, args) =>
     {
         return args.Val.Eval(env).Eval(env);
     }));
     top.Add("env", new BuiltinFunction((env, args) =>
     {
         return env.AsList();
     }));
     top.Add("let", new BuiltinFunction((env, args) =>
     {
         var name = (Word)args.Val;
         var val = args.Next.Val.Eval(env);
         top[name.Val] = val;
         return val;
     }));
     top.Add("save", new BuiltinFunction((env, args) =>
     {
         var fileName = ((String)args.Val.Eval(env)).Val;
         var stuff = args.Next.Val.Eval(env);
         File.WriteAllText(fileName, stuff.ToString());
         return stuff;
     }));
     top.Add("new", new BuiltinFunction((env, args) =>
     {
         string className;
         var nameValue = args.Val.Eval(env);
         if (nameValue is String)
             className = ((String)nameValue).Val;
         else if (nameValue is Word)
             className = ((Word)nameValue).Val;
         else
             throw new Exception(nameValue.ToDotNetValue() + " is not a valid class name.");
         Type type = Type.GetType(className);
         if (type == null)
         {
             foreach (var a in SearchAssemblies)
             {
                 type = a.GetType(className);
                 if (type != null)
                     break;
             }
         }
         if (type == null)
             throw new Exception("Could not find type '" + className + "'.");
         return new DotNetValue(Activator.CreateInstance(type));
     }));
 }
Example #4
0
        static Value Parse(Scanner scan)
        {
            var tk = scan.Next();

            if (tk.Item1 == TokenType.Word)
                return new Word(tk.Item2);
            else if (tk.Item1 == TokenType.Nil)
                return List.Nil;
            else if (tk.Item1 == TokenType.True)
                return True.T;
            else if (tk.Item1 == TokenType.Number)
                return new Int(int.Parse(tk.Item2));
            else if (tk.Item1 == TokenType.String)
                return new String(tk.Item2);
            else if (tk.Item1 == TokenType.LParen)
            {
                var cons = new Stack<Value>();
                while ((tk = scan.Peek()).Item1 != TokenType.RParen && tk.Item1 != TokenType.EOF)
                {
                    cons.Push(Parse(scan));
                }

                if (tk.Item1 != TokenType.RParen)
                    throw new Exception("Missing RParen.");

                scan.Next();

                List ret = List.Nil;
                while (cons.Count != 0)
                {
                    ret = new List(cons.Pop(), ret);
                }
                return ret;
            }
            else if (tk.Item1 == TokenType.Quote)
                return new Quote(Parse(scan));
            else if (tk.Item1 == TokenType.RParen)
                throw new Exception("Unexpected RParen.");
            else
                throw new Exception("Unknown token type.");
        }
Example #5
0
        public Value Execute(Environment env, List args)
        {
            var oldEnv = env;
            env = new Environment(env);
            var argNames = mArgNames;
            while (argNames != List.Nil && args != List.Nil)
            {
                var name = ((Word)argNames.Val).Val;
                env[name] = args.Val;

                args = args.Next;
                argNames = argNames.Next;
            }
            if (argNames != List.Nil || args != List.Nil)
                throw new Exception("Wrong number of arguments.");

            return mFun.Eval(env).Eval(env);
        }
Example #6
0
 public Value Execute(Environment env, List args)
 {
     var methodName = ((Word)args.Val.Eval(env)).Val;
     var arguments = new List<object>();
     while ((args = args.Next) != List.Nil)
     {
         arguments.Add(args.Val.Eval(env).ToDotNetValue());
     }
     var argTypes = arguments.Select(o => o.GetType()).ToArray();
     var meth = mObj.GetType().GetMethod(methodName, argTypes);
     var ret = meth.Invoke(mObj, arguments.ToArray());
     if (ret == null)
         return List.Nil;
     if (ret is string)
         return new String(ret.ToString());
     else if (ret is int)
         return new Int((int)ret);
     else
         return new DotNetValue(ret);
 }
Example #7
0
 public UserFunction(List args, List fun)
 {
     this.mFun = fun;
     this.mArgNames = args;
 }
Example #8
0
 public UserMacro(List args, List fun)
 {
     this.mFun = fun;
     this.mArgNames = args;
 }
Example #9
0
 public Value Execute(Environment env, List args)
 {
     return Fun(env, args);
 }
Example #10
0
        private static void ToStringInner(List l, StringBuilder sb)
        {
            if (l == Nil)
                return;

            l.Val.ToString(sb);
            if (l.Next != Nil)
                sb.Append(' ');

            ToStringInner(l.Next, sb);
        }
Example #11
0
 private static List Map(List l, Func<Value, Value> f)
 {
     if (l == Nil)
         return Nil;
     return new List(f(l.Val), Map(l.Next, f));
 }
Example #12
0
 private List()
 {
     this.Next = this;
     this.Val = this;
 }
Example #13
0
        public List(Value v, List n)
        {
            if (v == null || n == null)
                throw new ArgumentNullException();

            this.Val = v;
            this.Next = n;
        }