Beispiel #1
0
 public void AddEnviroment(EnviromentBlock env)
 {
     envList.Insert(0, env);
 }
Beispiel #2
0
 public EnviromentBlock(EnviromentBlock block)
 {
     if (block != null)
     {
         symbolTable.Clear();
         foreach (var pair in block.symbolTable)
         {
             symbolTable.Add(pair.Key, pair.Value);
         }
     }
 }
Beispiel #3
0
        /*
         * apply parameters to a lambda
         * create a new enviroment block, add all parameter symbol into this enviroment
         * then bind parameters with these symbol
         * for example we have symbols in upper table: TRUE = \(x,y).x; FALSE = \(x,y).y; AND = \(p,q).p q FALSE;
         * then we want to eval "a = AND TRUE FALSE"; we call ApplyToLambda( AND, {TRUE, FALSE}, env)
         * what should be done in ApplyToLambda is
         * 1. create new enviroment block
         * 2. p bind to TRUE; q bind to FALSE
         * 3. call ApplyToLambda(p, {q, FALSE}) which is equal to ApplyToLambda(TRUE, {FALSE, FALSE})
         * do 1-3 until we meet a terminal symbol
         *
         */
        private static EnviromentNode ApplyToLambda(string lambdaSymbol, EnviromentNode[] parameters, Enviroment enviroment, Enviroment closure)
        {
            EnviromentNode lambda = enviroment.LookupSymbol(lambdaSymbol);
            if (lambda == null)
                throw new Exception("unknow symbol: " + lambdaSymbol);

            EvalDelayEvalBlock(lambda);
            // bind parameter to enviroment
            Enviroment newEnviro = new Enviroment(enviroment);
            EnviromentBlock block = new EnviromentBlock();
            newEnviro.AddEnviroment(block);
            ParseNode paramNodes = null;
            if (lambda.GrammerNode.Token.Type != TokenType.LAMBDA)
            {
                paramNodes = lambda.GrammerNode.Nodes[2];
            }
            else
            {
                paramNodes = lambda.GrammerNode;
            }

            BindParameterToEnviroment(parameters, newEnviro, paramNodes.Nodes[0]);
            return EvalDirectFunctionCall(paramNodes.Nodes[1], newEnviro, closure);
        }
Beispiel #4
0
        static void Main(string[] args)
        {
            if (!CheckInput(args))
            {
                Die("Invalid parameters");
            }

            if (args[0] == "-t")
                printGrammerTree = true;
            if (args[0] == "-s")
                printSymbolTable = true;

            Scanner scaner = new Scanner();
            Parser parser = new Parser(scaner);
            ParseTree tree = parser.Parse(GetInput(args[args.Length - 1]));
            tree = SimplyTree(tree);
            if (printGrammerTree)
            {
                Console.WriteLine(tree.PrintTree());
                return;
            }
            EnviromentBlock globalSymbol = new EnviromentBlock();
            globalEnviroment.AddEnviroment(globalSymbol);
            AddIoFunctionToGlobal("return");
            AddIoFunctionToGlobal("print");
            AddIoFunctionToGlobal("readline");
            AddBuildinFunctionToGlobal("==");
            AddBuildinFunctionToGlobal("+");
            AddBuildinFunctionToGlobal("-");
            AddBuildinFunctionToGlobal("*");
            AddBuildinFunctionToGlobal("/");
            AddBuildinFunctionToGlobal("%");
            EvalTree(tree, globalEnviroment);
            if (printSymbolTable)
            {
                Console.WriteLine(globalEnviroment.Print());
            }
            else
            {
                RunMainFunction();
            }
            return;
        }
Beispiel #5
0
        /*
         * when ApplyFunction, do parameter bind like eval lambda, then eval every sentense in function body
         * until we met "return"
         * if every parameter in parameters[] occures in current enviroment, no need to create new enviroment
         */
        static EnviromentNode ApplyFunction(EnviromentNode func, EnviromentNode[] parameters, Enviroment enviroment)
        {
            // nodes[0] == Symbol
            // node[1] == parameters
            // node[2] == function body
            Enviroment newEnviro = null;
            ParseNode paraNode = func.GrammerNode.Nodes[1];

            newEnviro = new Enviroment(globalEnviroment);
            EnviromentBlock block = new EnviromentBlock();
            newEnviro.AddEnviroment(block);
            // bind parameter to enviroment
            BindParameterToEnviroment(parameters, newEnviro, paraNode);

            // eval all body sentense
            ParseNode body = func.GrammerNode.Nodes[2];
            foreach (ParseNode sentense in body.Nodes)
            {
                EnviromentNode ret = EvalSentense(sentense, newEnviro);
                if (ret != null && ret.Terminate)
                {
                    return ret;
                }
            }
            return null;
        }