Пример #1
0
        public static void Main(string[] args)
        {
            bool refreshEnv = false;
            bool showSexp   = false;
            bool showExpr   = false;

            List <string> files = new List <string>();

            foreach (string arg in args)
            {
                if (arg.Substring(0, 1) == "-")
                {
                    switch (arg)
                    {
                    case "-r":
                    case "--refreshEnv":
                        refreshEnv = true;
                        break;

                    case "-v":
                    case "--verbose":
                        showSexp = true;
                        showExpr = true;
                        break;

                    default:
                        Console.Error.WriteLine("Unrecognized commandline option: " + arg);
                        break;
                    }
                }
                else
                {
                    files.Add(arg);
                }
            }

            Environment env    = GetStartEnv(refreshEnv);
            Val         result = new NumV(-1);

            foreach (string file in files)
            {
                SExpression sexp = new SExpOpenXML(file);
                if (showSexp)
                {
                    Console.WriteLine("Lexical Analyzer Output:");
                    Console.WriteLine(sexp.ToString());
                }

                ExprC prog = Parser.parse(sexp);
                if (showExpr)
                {
                    Console.WriteLine("Parser Output:");
                    Console.WriteLine(prog.ToString());
                }

                result = prog.interp(env);
            }

            Console.WriteLine(result.ToString());
        }
Пример #2
0
        public override Val interp(Environment env)
        {
            Val checkVal = check.interp(env);

            if (checkVal is NumV)
            {
                return((((NumV)checkVal).num > 0) ? t.interp(env) : f.interp(env));
            }
            else if (checkVal is StrV)
            {
                return((((StrV)checkVal).str.Length > 0) ? t.interp(env) : f.interp(env));
            }
            else
            {
                throw new InterpException("Conditional jump on non-numeric, non-string");
            }
        }
Пример #3
0
        public override Val interp(Environment env)
        {
            List <Val>  interpIndices = interpAll(indices, env);
            List <long> castIndices   = new List <long>();

            foreach (Val idx in interpIndices)
            {
                if (idx is NumV)
                {
                    castIndices.Add(((NumV)idx).num);
                }
                else
                {
                    throw new InterpException("Indexing with non-numeric");
                }
            }

            Val interpArr = arr.interp(env);

            if (interpArr is ArrV)
            {
                return(((ArrV)interpArr).GetValue(castIndices));
            }
            else if (interpArr is StrV)
            {
                switch (castIndices.Count)
                {
                case 1:
                    try
                    {
                        return(new StrV(((StrV)interpArr).str.Substring((int)castIndices[0])));
                    }
                    catch (ArgumentOutOfRangeException ex)
                    {
                        return(new StrV(""));
                    }

                case 2:
                    try
                    {
                        return(new StrV(((StrV)interpArr).str.Substring((int)castIndices[0], (int)castIndices[1] - (int)castIndices[0] + 1)));
                    }
                    catch (ArgumentOutOfRangeException ex)
                    {
                        return(new StrV(""));
                    }

                default:
                    throw new InterpException("Indexing string with incorrect number of indices");
                }
            }
            else
            {
                throw new InterpException("Indexing into non-array");
            }
        }
Пример #4
0
        public override Val interp(Environment env)
        {
            NumV inner = num.interp(env) as NumV;

            if (inner == null)
            {
                throw new InterpException("Negating a non-numeric");
            }

            return(new NumV(-inner.num));
        }
Пример #5
0
        public static Environment addArgsToEnv(List <String> parms, List <ExprC> args,
                                               Environment cloEnv, Environment outerEnv)
        {
            if (parms.Count == args.Count)
            {
                Environment newEnv = outerEnv.withLocals(cloEnv); // scope to know all calling vars

                for (int i = 0; i < parms.Count; i++)
                {
                    String param  = parms[i];
                    ExprC  arg    = args[i];
                    Val    argVal = arg.interp(outerEnv);
                    newEnv.SetLocal(param, argVal); // overwrite params if var name exists
                }

                return(newEnv);
            }
            else
            {
                throw new InterpException("Calling mismatched argument count");
            }
        }
Пример #6
0
        public override Val interp(Environment env)
        {
            if (func is IdC && ((IdC)func).sym == "copyArr")
            {
                Console.WriteLine("HERE");
            }

            // Only should be invoked for function calls
            // BindC handles closure definitions
            CloV called = func.interp(env) as CloV;

            if (called != null) // (is a closure)
            {
                Environment callingContext = env;
                Environment cloEnv         = addArgsToEnv(called.parms, args, called.env, env);
                cloEnv.scopeDepth++;
                Val retVal = called.body.interp(cloEnv);
                cloEnv.scopeDepth--;

                // Propogate changes up to caller

                /*foreach (KeyValuePair<string, Val> pair in cloEnv)
                 * {
                 *  // Only for vars originally in scope; don't copy parameters
                 *  if (callingContext.ContainsKey(pair.Key) && !called.parms.Contains(pair.Key))
                 *  {
                 *      callingContext[pair.Key] = pair.Value;
                 *  }
                 * }*/

                return(retVal);
            }
            else
            {
                throw new InterpException("Calling a non-closure");
            }
        }
Пример #7
0
        public override Val interp(Environment env)
        {
            Val result;

            if (lexpr is IdC) // binding a variable
            {
                result = rexpr.interp(env);
                env[((IdC)lexpr).sym] = result;
            }
            else if (lexpr is FuncC) // defining a function
            {
                FuncC lexprFunc = (FuncC)lexpr;

                if (lexprFunc.func is IdC)
                {
                    List <string> parms = new List <string>();
                    foreach (ExprC parm in lexprFunc.args)
                    {
                        if (parm is IdC)
                        {
                            parms.Add(((IdC)parm).sym);
                        }
                        else
                        {
                            throw new InterpException("Malformed function definition params");
                        }
                    }
                    result = new CloV((Environment)env.Clone(), rexpr, parms);
                    ((CloV)result).env.SetLocal(((IdC)lexprFunc.func).sym, result); // allow recursion
                    env[((IdC)lexprFunc.func).sym] = result;
                }
                else
                {
                    throw new InterpException("Malformed function definition name");
                }
            }
            else if (lexpr is IndexC) // defining an array or setting an element
            {
                IndexC lexprArray = (IndexC)lexpr;

                if (lexprArray.arr is IdC)
                {
                    List <long> indices = new List <long>();
                    foreach (ExprC idx in lexprArray.indices)
                    {
                        Val idxVal = idx.interp(env);

                        if (idxVal is NumV)
                        {
                            indices.Add(((NumV)idxVal).num);
                        }
                        else
                        {
                            throw new InterpException("Non-numeric array index");
                        }
                    }

                    if (env.ContainsKey(((IdC)lexprArray.arr).sym)) // setting element
                    {
                        ArrV arr = lexprArray.arr.interp(env) as ArrV;
                        if (arr == null)
                        {
                            throw new InterpException("Indexing non-array");
                        }
                        result = rexpr.interp(env);
                        arr.SetValue(indices, result);
                    }
                    else // defining new array
                    {
                        result = new ArrV(indices, rexpr.interp(env));
                        env[((IdC)lexprArray.arr).sym] = result;
                    }
                }
                else
                {
                    throw new InterpException("Malformed array definition name");
                }
            }
            else
            {
                throw new InterpException("Binding with invalid lvalue");
            }

            return(result);
        }