Beispiel #1
0
        private IEnumerable <ExecutionMessage> SLet(List <SExpression> args, Environment e)
        {
            Environment local = new Environment(e); //TODO BUG: (let () ...) parses the name name bindings that are the pair <EmptyList,NULL>

            if (args[0] is SPair)
            {
                SPair nameBindings = (SPair)args[0];
                if (!nameBindings.isProperList())
                {
                    throw new Exception("Can't use impro per list in a let");
                }

                List <SExpression> names = nameBindings.flatten();
                for (int i = 0; i < names.Count - 1; i++)
                {
                    String      name = ((SID)((SPair)names[i]).getHead()).identifier;
                    SExpression val  = ((SPair)((SPair)names[i]).getTail()).getHead();

                    //Cycle through the yields until done
                    var         elmEnum = evaluate(val, e).GetEnumerator();
                    SExpression elm     = null;
                    while (elmEnum.MoveNext())
                    {
                        ExecutionMessage current = elmEnum.Current;
                        if (current.status == ExecStatus.DONE)
                        {
                            elm = current.returnVal; break;
                        }
                        yield return(current);
                    }
                    local.addVal(name, elm);
                }
            }
            else if (args[0] is SEmptyList)
            {
            }
            else
            {
                throw new Exception("Name bindings section of let must be a list");
            }

            //Lets can have an arbitrary number of statements after the name bindings, execute them for stateful effects
            ExecutionMessage msg = null;

            for (int i = 1; i < args.Count; i++)
            {
                foreach (var tmsg in evaluate(args[i], local))
                {
                    msg = tmsg;
                    if (msg.status == ExecStatus.DONE)
                    {
                        continue;
                    }
                    yield return(msg);
                }
            }

            //yield final message
            yield return(msg);
        }
        public SFunc(SID arglst, SExpression body, Environment e)
        {
            arglist = arglst;
            names   = null;

            //our starting environment is the env we were defined in
            env = new Environment(e);
            env.addVal(arglist.identifier, new SNone()); //add bound variables to environment with default None value
            fixedArgCount = false;

            this.body = body;
        }
        public SExpression body; //body of execution

        public SFunc(List <SID> names, SExpression body, Environment e)
        {
            //our starting environment is the env we were defined in
            arglist = null;
            env     = new Environment(e);
            foreach (SID id in names)
            {
                env.addVal(id.identifier, new SNone()); //add bound variables to environment with default None value
            }
            this.names    = names;
            this.body     = body;
            fixedArgCount = true;
            argCount      = names.Count;
        }
Beispiel #4
0
        private IEnumerable <ExecutionMessage> SDefine(List <SExpression> args, Environment e)
        {
            if (e.hasParent())
            {
                throw new Exception("Define only allowed at global scope");
            }

            SID name             = (SID)args[0];
            ExecutionMessage msg = null;

            foreach (var tmsg in evaluate(args[1], e))
            {
                msg = tmsg;
                if (msg.status == ExecStatus.DONE)
                {
                    break;
                }
                yield return(msg);
            }
            e.addVal(name.identifier, msg.returnVal);

            yield return(new ExecutionMessage(ExecStatus.DONE, new SNone()));
        }
Beispiel #5
0
        public DerpInterpreter()
        {
            callStack = new List <SExpression>();
            e         = new Environment();
            parser    = new DerpParser("");

            e.addVal("+", new SPrimitive(SAdd, false, 0));
            e.addVal("*", new SPrimitive(SMult, false, 0));
            e.addVal("/", new SPrimitive(SDiv, true, 2));
            e.addVal("-", new SPrimitive(SSub, false, 0));
            e.addVal("mod", new SPrimitive(SMod, true, 2));
            e.addVal("if", new SPrimitive(SIf, true, 3, false));
            e.addVal("let", new SPrimitive(SLet, false, 0, false));
            e.addVal("define", new SPrimitive(SDefine, true, 2, false));
            e.addVal("lambda", new SPrimitive(SLambda, true, 2, false));
            e.addVal("debug", new SPrimitive(SDebug, true, 1));
            e.addVal("list", new SPrimitive(SList, false, 0));
            e.addVal("cons", new SPrimitive(SCons, true, 2));
            e.addVal("car", new SPrimitive(SCar, true, 1));
            e.addVal("cdr", new SPrimitive(SCdr, true, 1));
            e.addVal("null?", new SPrimitive(SNullList, true, 1));
            e.addVal("=", new SPrimitive(SEq, true, 2));
            e.addVal(">", new SPrimitive(SGt, true, 2));
            e.addVal("<", new SPrimitive(SLt, true, 2));
            e.addVal("begin", new SPrimitive(SBegin, false, 0));
            e.addVal("typeof", new SPrimitive(TypeOf, false, 1));
            e.addVal("eval", new SPrimitive(Eval, false, 1));
        }