public Object eval(Env env)
        {
            Object f = fexpr.eval(env);
            Object[] args = new Object[argexprs.Length];
            for(Int32 i=0;i<args.Length;i++)
            args[i] = argexprs[i].eval(env);

            Boolean doTrace = fsym != null &&
                                interpreter.traceList.Contains(fsym);
            try
            {
            if(doTrace)
                {
                interpreter.trace(fsym.name,args);
                Trace.Indent();
                Object ret = Util.InvokeObject(f,args);
                Trace.Unindent();
                return ret;
                }
            else
                return Util.InvokeObject(f,args);
            }
            catch(Exception ex)
            {
            if(fsym != null && !fsym.name.Equals("throw"))
                {
                throw BacktraceException.push(ex,new BacktraceFrame(loc,fsym,args)
                                                        ,interpreter);
                }
            else
                {
                throw ex;
                }
            }
        }
Example #2
0
	public Object eval(Env env)
		{
		DynamicEnv d = DynamicEnv.find(sym);
		if(d != null)
			return d.val;
		return sym.getGlobalValue();
		}
Example #3
0
	internal Closure(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.interpreter = interpreter;
		this.loc = loc;
		ArgSpecs specs = analyzeArgSpec((Cons)args.first,env,loc);
		//create an env expanded by params in which to analyze body
		Env env2 = new Env(specs.parameters, null, env, interpreter);

		this.argSpecs = specs;
		this.body = interpreter.analyze(new Cons(interpreter.BLOCK,args.rest), env2,loc);
		this.env = env;
		}
 internal ApplyExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
 {
     this.loc = loc;
     this.interpreter = interpreter;
     fexpr = interpreter.analyze(args.first,env,loc);
     if(fexpr is IVar)
     {
     fsym = ((IVar)fexpr).getSymbol();
     }
     Int32 len = Cons.Length(args.rest);
     argexprs = new IExpression[len];
     args = args.rest;
     for(Int32 i=0;i<argexprs.Length;i++,args = args.rest)
     {
     argexprs[i] = interpreter.analyze(args.first,env,loc);
     }
 }
Example #5
0
    public Interpreter(Interpreter parent)
		{
        this.Parent = parent;
		globalenv = new Env(null,null,null,this);
		reader = new Reader(this);
        symbolTable = new SymbolTable(this);

		Assembly[] asm = AppDomain.CurrentDomain.GetAssemblies();
		foreach(Assembly a in asm)
			{
			addTypesFrom(a);
			}
        addTypesFrom(Assembly.LoadWithPartialName("System.Web"));
		internBuiltins();
		Primitives.internAll(this);
		// MEH: EX was not set to null
		EX.setGlobalValue(null);
		LASTVAL.setGlobalValue(null);
		NEXTLASTVAL.setGlobalValue(null);
		THIRDLASTVAL.setGlobalValue(null);

		//these primitives are here, rather than in Primitives, because their implementation
		//requires calls to gfs bound to symbols		
		Intern("intern",new Function(internf));
		Intern("eval",new Function(evalf));
		Intern("load",new Function(loadf));
		Intern("map->list",new Function(map_to_list));
		Intern("apply",new Function(apply));
		Intern("<",new Function(lt));
		Intern("<=",new Function(lteq));
		Intern(">",new Function(gt));
		Intern(">=",new Function(gteq));
		Intern("==",new Function(eqeq));
		Intern("!=",new Function(noteq));

		strgf = (GenericFunction)intern("str").getGlobalValue();
		get_enum_gf = (GenericFunction)intern("get-enum").getGlobalValue();
		compare_gf = (BinOp)intern("compare").getGlobalValue();

		Intern("interpreter",this);
		}
Example #6
0
	internal Env(Parameter[] vars, Object[] vals, Env parent)
		{
		this.vars = vars; this.vals = vals; this.parent = parent;
		}
        internal IExpression analyze(Object expr, Env env, Loc enclosingLoc)
        {
            Symbol symbol = expr as Symbol;
            if(symbol != null)
            {
            if(symbol.isDynamic)
                return new DynamicVar(symbol);
            Object var = env.lookup(symbol);
            if(var is LocalVariable)
                return new LocalVar((LocalVariable)var);
            else
                return new GlobalVar((Symbol)var);
            }
            if(!(expr is Cons))	 //must be literal
            return new QuoteExpr(expr);

            Cons exprs = (Cons)expr;

            Loc loc = (Loc)reader.locTable[expr];
            if(loc != null)
            reader.locTable.Remove(expr);
            else
            loc = enclosingLoc;

            Object f = exprs.first;
            Cons args = exprs.rest;

            //see if it's a macro
            Symbol s = f as Symbol;
            if(s != null && s.isDefined() && s.getGlobalValue() is Macro)
            {
            Macro m = (Macro)s.getGlobalValue();
            Object[] argarray = Cons.ToVector(args);
            Object mexprs = null;
            try
                {
                mexprs = m.Invoke(argarray);
                }
            catch(Exception ex)
                {
                BacktraceFrame frame = new BacktraceFrame(loc,s,args);
                throw BacktraceException.push(ex,frame,this);
                }
            try
                {
                return analyze(mexprs,env,loc);
                }
            catch(Exception ex)
                {
                BacktraceFrame frame = new BacktraceFrame(loc,"when expanding ",exprs);
                throw BacktraceException.push(ex,frame,this);
                }
            }
            Int32 numargs = Cons.Length(args);

            if(f == DLET)
            return new DynamicLet(args,env,this,loc);
            else if(f == FN)
            return new Closure(args,env,this,loc);
            else if(f == MACRO)
            return new Macro(args,env,this,loc);
            else if(f == WHILE)
            return new WhileExpression(args,env,this,loc);
            else if(f == BLOCK)
            {
            if(numargs == 0)
                return new QuoteExpr(null);
            //remove block from block of one
            else if(numargs == 1)
                return analyze(args.first,env,loc);
            else
                return new BlockExpression(args,env,this,loc);
            }
            else if(f == OR)
            {
            if(numargs == 0)
                return new QuoteExpr(null);
            else
                return new OrExpression(args,env,this,loc);
            }
            else if(f == IF)
            return new IfExpression(args,env,this,loc);
            else if(f == QUOTE)
            return new QuoteExpr(args.first);
            else if(f == SET)
            return new SetExpression(args,env,this,loc);
            else	//presume funcall
            return new ApplyExpression(exprs,env,this,loc);
        }
Example #8
0
	public Object eval(Env env)
		{
		return env.getValue(var);
		}
Example #9
0
	public Object eval(Env env)
		{
		return sym.getGlobalValue();
		}
 public Object eval(Env env)
 {
     return(sym.getGlobalValue());
 }
Example #11
0
	internal DynamicLet(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.loc = loc;
		this.interpreter = interpreter;
		Cons bindlist = (Cons)args.first;
		Int32 blen = Cons.Length(bindlist);
		if((blen%2) != 0)	//odd
			{
			throw new Exception("Odd number of args in dynamic-let binding list");
			}
		binds = new BindPair[blen/2];
		for(int i = 0;i<binds.Length;i++)
			{
			binds[i].dvar = (DynamicVar)interpreter.analyze(bindlist.first, env,loc);
			bindlist = bindlist.rest;
			binds[i].expr = interpreter.analyze(bindlist.first, env,loc);
			bindlist = bindlist.rest;
			}
		this.body = interpreter.analyze(new Cons(interpreter.BLOCK,args.rest), env,loc);
		}
Example #12
0
 internal Macro(Cons args, Env env, Interpreter interpreter, Loc loc)
     : base(args, env, interpreter, loc)
 {
 }
 public void setval(Object val, Env env)
 {
     env.setValue(var, val);
 }
 public Object eval(Env env)
 {
     return(env.getValue(var));
 }
 public void setval(Object val, Env env)
 {
     sym.setGlobalValue(val);
 }
Example #16
0
	internal Closure copy(Env env)
		{
		Closure c = null;
		try
			{
			c = (Closure)this.MemberwiseClone();
			}
		catch(Exception e)
			{
			throw new Exception("internal error: no clone " + e.Message);
			}
		c.env = env;
		c.argSpecs = argSpecs.copy(env);
		return c;
		}
Example #17
0
	public Object eval(Env env)
		{
		return copy(env);
		}
Example #18
0
	public Object eval(Env env)
		{
		DynamicEnv olddenv = DynamicEnv.current();
		try
			{
			for(int i = 0;i<binds.Length;i++)
				{
				DynamicEnv.extend(binds[i].dvar.sym,
										binds[i].expr.eval(env));
				}
			return body.eval(env);
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"set",null),interpreter);
			}
		finally
			{
			DynamicEnv.restore(olddenv);
			}
		}
Example #19
0
	public Object eval(Env env)
		{
		try
			{
			Object retval = val.eval(env);
			var.setval(retval,env);
			return retval;
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"set",null),interpreter);
			}
		}
Example #20
0
	internal WhileExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.loc = loc;
		this.interpreter = interpreter;
		this.test = interpreter.analyze(args.first,env,loc);
		this.body = interpreter.analyze(new Cons(interpreter.BLOCK,args.rest),env,loc);
		}
Example #21
0
	public void setval(Object val,Env env)
		{
		sym.setGlobalValue(val);
		}
Example #22
0
	public Object eval(Env env)
		{
		try
			{
			while(Util.isTrue(test.eval(env)))
				{
				body.eval(env);
				}

			return null;
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"set",null),interpreter);
			}
		}
Example #23
0
	public void setval(Object val,Env env)
		{
		env.setValue(var,val);
		}
Example #24
0
	public Object eval(Env env)
		{
		return val;
		}
Example #25
0
	public void setval(Object val,Env env)
		{
		DynamicEnv d = DynamicEnv.find(sym);
		if(d != null)
			d.val = val;
		sym.setGlobalValue(val);
		}
Example #26
0
	public Object eval(Env env)
		{
		try
			{
			for(Int32 i=0;i<exprs.Length-1;i++)
				exprs[i].eval(env);

			return exprs[exprs.Length-1].eval(env);
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"set",null),interpreter);
			}
		}
 internal IExpression analyze(Object expr,Env env)
 {
     return analyze(expr,env,null);
 }
Example #28
0
	internal OrExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.loc = loc;
		this.interpreter = interpreter;
		exprs = new IExpression[Cons.Length(args)];
		for(Int32 i=0;i<exprs.Length;i++,args = args.rest)
			{
			exprs[i] = interpreter.analyze(args.first,env,loc);
			}
		}
 internal Object eval(Object x, Env env)
 {
     IExpression analyzedCode = analyze(x,env);
     return analyzedCode.eval(env);
     //Object analyzedCode = analyze(x,env);
     //return execute(analyzedCode, env);
 }
Example #30
0
	public Object eval(Env env)
		{
		try
			{
			for(Int32 i = 0; i < exprs.Length-1; i++)
				{
				Object result = exprs[i].eval(env);
				if(Util.isTrue(result))	return result;
				}

			return exprs[exprs.Length-1].eval(env);
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"set",null),interpreter);
			}
		}
Example #31
0
	internal IfExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.loc = loc;
		this.interpreter = interpreter;
		Int32 len = Cons.Length(args);
		if(len < 2 || len > 3)
			throw new Exception("Wrong number of args for if");
		test = interpreter.analyze(args.first,env,loc);
		brtrue = interpreter.analyze(Cons.Second(args),env,loc);
		if(len == 3)
			brfalse = interpreter.analyze(Cons.Third(args),env,loc);
		else
			brfalse = new QuoteExpr(null);
		}
Example #32
0
	public Object eval(Env env)
		{
		try
			{
			if(Util.isTrue(test.eval(env)))
				return brtrue.eval(env);
			return brfalse.eval(env);
			}
		catch(BacktraceException bex)
			{
			throw bex;
			}
		catch(Exception ex)
			{
			throw BacktraceException.push(ex,new BacktraceFrame(loc,"if",null),interpreter);
			}
		}
Example #33
0
	//returns an array of evaluated args corresponding to params of argspec,
	//including substitution of default values where none provided, construction of
	//rest list etc
	//suitable for extending the environment prior to evaluating body of closure
	internal Object[] buildParamArray(Object[] code, Int32 offset,
												 Env env//, Boolean evalArgs
												)
		{
		//do nothing if fixed params and matching number
		if(argSpecs.nParams() == argSpecs.numReq  && argSpecs.numReq == code.Length)
			return code;

		Object[] argArray = new Object[nParms()];
		int nargs = code.Length-offset;
		if(nargs < argSpecs.numReq)
			throw new Exception("Too few arguments to procedure, expected at least " + argSpecs.numReq
									  +", but found "+ nargs  +" arguments");

		int i;
		// Fill in the required parameters
		for(i = 0; i < argSpecs.numReq; i++)
			{
			argArray[i] = //evalArgs?Interpreter.execute(code[i+offset], env):
							  code[i+offset];
			}

		//now grab args to satisfy optionals
		if(argSpecs.numOpt > 0)
			{
			for(i = argSpecs.numReq; i < argSpecs.numReq + argSpecs.numOpt; i++)
				{
				if(i<nargs)
					{
					argArray[i] = //evalArgs?Interpreter.execute(code[i+offset], env):
									  code[i+offset];
					//if missing passed to optional, get default
					if(argArray[i] == Missing.Value)
						{
						argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
						}
					}
				else //ran out of args, default the rest
					{
					argArray[i] = getDefaultParamValue(argSpecs.parameters[i]);
					}
				}
			}

		//build a rest list
		Cons rest = null;
		for(int x = code.Length-1;x-offset >= i; --x)
			{
			Object val = //evalArgs?Interpreter.execute(code[x], env):
							 code[x];
			rest = new Cons(val, rest);
			}

		//search for key args in rest
		if(argSpecs.numKey > 0)
			{
			for(i = argSpecs.numReq + argSpecs.numOpt; 
				i < argSpecs.numReq + argSpecs.numOpt + argSpecs.numKey; i++)
				{
				argArray[i] = findKeyParamValue(argSpecs.parameters[i],rest);
				}
			}

		// Add the rest parameter (if there is one)
		if(argSpecs.numRest == 1)
			{
			argArray[i] = rest;
			}

		return argArray;
		}
Example #34
0
	internal SetExpression(Cons args,Env env,Interpreter interpreter,Loc loc)
		{
		this.loc = loc;
		this.interpreter = interpreter;
		Int32 len = Cons.Length(args);
		if(len != 2)
			throw new Exception("Wrong number of args for set");
		var = (IVar)interpreter.analyze(args.first,env,loc);
		val = interpreter.analyze(Cons.Second(args),env,loc);
		}
Example #35
0
	//parse out params from spec (which may contain &optional, &key, &rest, initforms etc

	internal ArgSpecs analyzeArgSpec(Cons arglist, Env env,Loc loc)
		{
		//count the params
		int nParams = 0;
		Cons a = arglist;
		while(a!=null)
			{
			Object p = a.first;
			if(p!=interpreter.AMPOPT && p!=interpreter.AMPKEY && p!=interpreter.AMPREST)
				++nParams;
			a = a.rest;
			}

		ArgSpecs ret = new ArgSpecs(env);
		ret.parameters = new Parameter[nParams];
		Parameter.Spec state = Parameter.Spec.REQ;

		int param = 0;
		a = arglist;
		while(a!=null)
			{
			Object p = a.first;
			switch(state)
				{
				case Parameter.Spec.REQ:
					if(p==interpreter.AMPOPT)
						state = Parameter.Spec.OPT;
					else if(p==interpreter.AMPKEY)
						state = Parameter.Spec.KEY;
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.REQ,null);
							++ret.numReq;
							}
						else if(p is Cons)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.REQ,null);
							ret.parameters[param].typeSpec = interpreter.eval(Cons.Second((Cons)p),env);
							++param;
							++ret.numReq;
							}
						}
					break;
				case Parameter.Spec.OPT:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional can appear only once in arg list");
					else if(p==interpreter.AMPKEY)
						state = Parameter.Spec.KEY;
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.OPT,null);
							++ret.numOpt;
							}
						else if(p is Cons)
							{
							ret.parameters[param++] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.OPT,
											  interpreter.analyze(Cons.Second((Cons)p),env,loc));
							++ret.numOpt;
							}
						else
							throw	new Exception("&optional parameters must be symbols or (symbol init-form)");
						}
					break;
				case Parameter.Spec.KEY:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional must appear before &key in arg list");
					else if(p==interpreter.AMPKEY)
						throw new Exception("&key can appear only once in arg list");
					else if(p==interpreter.AMPREST)
						state = Parameter.Spec.REST;
					else
						{
						if(p is Symbol)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)p,Parameter.Spec.KEY,null);
							ret.parameters[param].key = interpreter.intern(":" + ((Symbol)p).name);
							++param;
							++ret.numKey;
							}
						else if(p is Cons)
							{
							ret.parameters[param] = 
							new Parameter((Symbol)((Cons)p).first,Parameter.Spec.KEY,
											  interpreter.analyze(Cons.Second((Cons)p),env,loc));
							ret.parameters[param].key = 
							interpreter.intern(":" + ((Symbol)((Cons)p).first).name);
							++param;
							++ret.numKey;
							}
						else
							throw	new Exception("&key parameters must be symbols or (symbol init-form)");
						}
					break;
				case Parameter.Spec.REST:
					if(p==interpreter.AMPOPT)
						throw new Exception("&optional must appear before &rest in arg list");
					else if(p==interpreter.AMPKEY)
						throw new Exception("&key must appear before &rest in arg list");
					else if(p==interpreter.AMPREST)
						throw new Exception("&rest can appear only once in arg list");
					else
						{
						if(!(p is Symbol))
							throw new Exception("&rest parameter must be a symbol");
						else
							{
							if(ret.numRest > 0) //already got a rest param
								throw new Exception("Only one &rest arg can be specified");
							ret.parameters[param++] = 
							new Parameter((Symbol)p,Parameter.Spec.REST,null);
							++ret.numRest;
							}
						}
					break;
				}

			a = a.rest;
			}

		return ret;
		}
 public Object eval(Env env)
 {
     return(val);
 }