Exemplo n.º 1
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);
        }
Exemplo n.º 2
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;
        }