Beispiel #1
0
 public void CopyValueFromNode(EnviromentNode node)
 {
     this.delayEvalBlock = node.delayEvalBlock;
     this.svalue = node.svalue;
     this.ivalue = node.ivalue;
     this.dvalue = node.dvalue;
     this.valueType = node.valueType;
 }
Beispiel #2
0
 public void ClearDelayEvalBlock()
 {
     delayEvalBlock = null;
 }
Beispiel #3
0
 public void AddDelayEvalBlock(DelayEvalBlock block)
 {
     delayEvalBlock = new DelayEvalBlock(block.Node, block.Enviroment);
 }
Beispiel #4
0
 public EnviromentNode(Enviroment env)
 {
     enviroment = new Enviroment(env);
     terminate = false;
     this.delayEvalBlock = null;
     this.valueType = "unknow";
 }
Beispiel #5
0
        private static void EvalVarSentense(ParseNode node, Enviroment enviroment,
            EnviromentNode envNode)
        {
            envNode.Symbol = node.Nodes[1].Token.Text;
            if (node.Nodes[2].Token.Type == TokenType.FUNCTION)
            {
                EnviromentNode resultNode = EvalDirectFunctionCall(node.Nodes[2], enviroment, envNode.Enviroment);

                // before bind function result to a smbol, eval result node first
                EvalDelayEvalBlock(resultNode);
                if (resultNode.GrammerNode != null)
                {
                    ParseNode result = resultNode.GrammerNode;
                    if (resultNode.ValueType != "lambda")
                    {
                        envNode.Type = GetTypeString(result.Nodes[2], null);
                        envNode.Value = GetValueOfLambda(result.Nodes[2]);
                    }
                    envNode.GrammerNode = result;
                }
                envNode.Enviroment = resultNode.Enviroment;
                envNode.CopyValueFromNode(resultNode);
                return;
            }
            else if (node.Nodes[2].Token.Type == TokenType.IFTHENELSE)
            {
                DelayEvalBlock block = new DelayEvalBlock(node.Nodes[2], enviroment);
                envNode.AddDelayEvalBlock(block);
                EvalDelayEvalBlock(envNode);
            }
            else if (node.Nodes[2].Token.Type == TokenType.LAMBDA)
            {
                envNode.GrammerNode = node;
                envNode.Type = GetTypeString(node.Nodes[2], null);
                envNode.Value = GetValueOfLambda(node.Nodes[2]);
                envNode.ValueType = "lambda";
            }
            else if (node.Nodes[2].Token.Type == TokenType.DIGIT)
            {
                envNode.GrammerNode = null;
                envNode.ValueType = "int";
                envNode.IValue = Int32.Parse(node.Nodes[2].Token.Text);
            }
            else if (node.Nodes[2].Token.Type == TokenType.STRINGVAL)
            {
                envNode.GrammerNode = null;
                envNode.ValueType = "string";
                string tmp = node.Nodes[2].Token.Text;
                envNode.SValue = tmp.Substring(1, tmp.Length - 2);
            }
        }
Beispiel #6
0
        /*
         * eval sentense like " AND TRUE FALSE"
         * parameters can be another function call, like AND (AND TRUE TRUE) FALSE
         * currently eval all parameters before apply to functor
         * if parameter ( and after eval function all ) does not exist in enviroment, just leave a symbol in it
         * in order to support IO, add special functor type __io__, which evals special, need to do IOs internally
         * and in order to support function, add special functor type __function__
         * when eval __function__, eval sentenses inside this function until we met a "return"
         * if a lambda like \(x,y).x , say only one element in body, it's a terminal symbol
         * else treate first elememt in body as a functor and eval it
         */
        private static EnviromentNode EvalDirectFunctionCall(ParseNode node, Enviroment enviroment, Enviroment closure)
        {
            // nodes[0] == 'var'
            // nodes[1] == symbol
            // nodes[2] == function body
            if (node.Nodes.Count < 1)
                throw new Exception("invalid direct function call");
            ParseNode funcBody = node;
            string lambdaSymbol = funcBody.Nodes[0].Token.Text;

            EnviromentNode funcNode = closure.LookupSymbol(lambdaSymbol);
            if (funcNode == null)
                funcNode = enviroment.LookupSymbol(lambdaSymbol);

            // before apply parameters to a lambda, eval functor to get a result
            EvalDelayEvalBlock(funcNode);

            /*
             * sentense like
             * var a = \(x,y).x TRUE FALSE
             * FIXME
             */

            EnviromentNode[] parameters = new EnviromentNode[funcBody.Nodes.Count - 1];
            for (int index = 1; index < funcBody.Nodes.Count; index++)
            {

                ParseNode paramNode = funcBody.Nodes[index];
                if (paramNode.Token.Type == TokenType.FUNCTION || paramNode.Token.Type == TokenType.IFTHENELSE )
                {
                    // parameters[index - 1] = EvalDirectFunctionCall(funcBody.Nodes[index], enviroment, null);
                    DelayEvalBlock block = new DelayEvalBlock(funcBody.Nodes[index], enviroment);
                    parameters[index - 1] = new EnviromentNode(enviroment);
                    parameters[index - 1].AddDelayEvalBlock(block);
                }
                else
                {
                    Token token = funcBody.Nodes[index].Token;
                    EnviromentNode tmp = null;
                    if (token.Type == TokenType.DIGIT)
                    {
                        // like foo 12;
                        tmp = new EnviromentNode(enviroment);
                        tmp.IValue = Int32.Parse(token.Text);
                        tmp.ValueType = "int";
                    }
                    else if (token.Type == TokenType.STRINGVAL)
                    {
                        // like foo "hello";
                        tmp = new EnviromentNode(enviroment);
                        tmp.SValue = token.Text.Substring(1, token.Text.Length - 2);
                        tmp.ValueType = "string";
                    }
                    else if (token.Type == TokenType.LAMBDA)
                    {
                        /*
                         * sentense like
                         * return \(x,y).x
                         * foo \(x,y).x FALSE
                         */
                        tmp = new EnviromentNode(enviroment);
                        tmp.Type = GetTypeString(funcBody.Nodes[index], null);
                        tmp.Value = GetValueOfLambda(funcBody.Nodes[index]);
                        tmp.GrammerNode = funcBody.Nodes[index];
                        tmp.ValueType = "lambda";
                    }
                    else
                    {
                        // like foo a b;
                        tmp = enviroment.LookupSymbol(token.Text);
                        if (tmp == null)
                        {
                            tmp = new EnviromentNode(null);
                            tmp.Symbol = token.Text;
                        }
                    }

                    parameters[index - 1] = tmp;
                }
            }
            EnviromentNode result = null;

            if (funcNode.Type == "__io__")
            {
                result = ApplyIO(funcNode, parameters, enviroment);
            }
            else if (funcNode.Type == "__function__")
            {
                result = ApplyFunction(funcNode, parameters, enviroment);
            }
            else if (funcNode.Type == "__buildin__")
            {
                result = ApplyBuildinFunction(funcNode, parameters, enviroment);
            }
            else // lambda
            {
                if (parameters.Length == 0)
                {
                    result = closure.LookupSymbol(lambdaSymbol);
                    if (result == null)
                        result = enviroment.LookupSymbol(lambdaSymbol);
                }
                else
                    result = ApplyToLambda(lambdaSymbol, parameters, enviroment, funcNode.Enviroment);
            }

            return result;
        }