Beispiel #1
0
        public void EnterExpr(ExprParser.ExprContext context)
        {
            var funcName    = context.NAME().GetText();
            var exprContext = new ExprContext(funcName, _callStack.Count > 0 ? _callStack.Peek() : null);

            _callStack.Push(exprContext);
        }
Beispiel #2
0
        public void ExitExpr(ExprParser.ExprContext context)
        {
            var currentExpr = _callStack.Pop();

            try
            {
                if (_callStack.Count > 0)
                {
                    var parentExpr = _callStack.Peek();
                    parentExpr.AddArgument(new LazyValue(() =>
                    {
                        try
                        {
                            var func = currentExpr.RetrieveFunctionFromLocalContext(currentExpr.FunctionName)(currentExpr);
                            Func <ExprContext, Value> a = exprContext =>
                            {
                                // HACK for the localContext in recursions
                                var custom = (CustomFunc)func;
                                exprContext.StashLocalContext(custom.FuncDeclContext);
                                var funcReturn = custom.Execute();
                                exprContext.RevertLocalContext(custom.FuncDeclContext);
                                return(funcReturn);
                            };
                            return(a(currentExpr));
                        }
                        catch (UndefinedFunction)
                        {
                            var func = Functions[currentExpr.FunctionName](currentExpr);
                            return(func.Execute());
                        }
                    }));
                }
                else
                {
                    //top level can never be a local function, ne need to check
                    var func = Functions[currentExpr.FunctionName](currentExpr);
                    Console.WriteLine(func.Execute().Val);
                }
            }
            catch (KeyNotFoundException)
            {
                throw new UndefinedFunction(currentExpr.FunctionName);
            }
        }
Beispiel #3
0
        static bool accessAsThisNode = true; // Design alternative: access node can be represented either as a child or this node


        #region Visotor interface

        public override ExprNode VisitExpr(ExprParser.ExprContext context)
        {
            ExprNode n = new ExprNode();

            // Determine the type of expression

            if (context.op != null && context.op.Text.Equals(".")) // Composition (dot) operation
            {
                n.Operation = OperationType.CALL;
                n.Action    = ActionType.READ;

                ExprNode exprNode = Visit(context.expr(0));
                if (exprNode != null)
                {
                    n.AddChild(exprNode);
                }

                ExprNode accessNode = Visit(context.access());
                if (accessAsThisNode)                    // Represent accessor (after dot) by this node
                {
                    if (context.access().name() != null) // Name of the function
                    {
                        n.Name = accessNode.Name;
                    }
                    else // A definition of the function (lambda) is provided instead of name
                    {
                        context.access().scope();
                        n.Name = "lambda"; // Automatically generated name for a unnamed lambda
                    }
                }
                else // Access node as a child (it can be named either by real method name or as a special 'method' with the method described represented elsewhere)
                {
                    n.Name = ".";
                    if (accessNode != null)
                    {
                        n.AddChild(accessNode);
                    }
                }
            }
            else if (context.op != null) // Arithmetic operations
            {
                n.Operation = OperationType.CALL;
                string op = context.op.Text; // Alternatively, context.GetChild(1).GetText()
                n.Name = op;

                if (op.Equals("*"))
                {
                    n.Action = ActionType.MUL;
                }
                else if (op.Equals("/"))
                {
                    n.Action = ActionType.DIV;
                }
                else if (op.Equals("+"))
                {
                    n.Action = ActionType.ADD;
                }
                else if (op.Equals("-"))
                {
                    n.Action = ActionType.SUB;
                }

                else if (op.Equals("<="))
                {
                    n.Action = ActionType.LEQ;
                }
                else if (op.Equals(">="))
                {
                    n.Action = ActionType.GEQ;
                }
                else if (op.Equals(">"))
                {
                    n.Action = ActionType.GRE;
                }
                else if (op.Equals("<"))
                {
                    n.Action = ActionType.LES;
                }

                else if (op.Equals("=="))
                {
                    n.Action = ActionType.EQ;
                }
                else if (op.Equals("!="))
                {
                    n.Action = ActionType.NEQ;
                }

                else if (op.Equals("&&"))
                {
                    n.Action = ActionType.AND;
                }
                else if (op.Equals("||"))
                {
                    n.Action = ActionType.OR;
                }

                else
                {
                    ;
                }

                ExprNode expr1 = Visit(context.GetChild(0));
                if (expr1 != null)
                {
                    n.AddChild(expr1);
                }

                ExprNode expr2 = Visit(context.GetChild(2));
                if (expr2 != null)
                {
                    n.AddChild(expr2);
                }
            }
            else if (context.expr() != null && context.GetChild(0).GetText().Equals("(")) // Priority
            {
                n = Visit(context.expr(0));                                               // Skip
            }
            else if (context.GetChild(0).GetText().Equals("call:"))                       // Native method call
            {
                n.Operation = OperationType.CALL;
                n.Action    = ActionType.PROCEDURE;

                string className = context.className.GetText();
                n.NameSpace = className; // Non-empty name space is an indication of a native method

                string methodName = context.methodName.Text;
                n.Name = methodName;

                int argCount = context.expr().Count();
                for (int i = 0; i < argCount; i++)
                {
                    ExprNode arg = Visit(context.expr(i));
                    if (arg != null)
                    {
                        n.AddChild(arg);
                    }
                }
            }
            else if (context.GetChild(0).GetText().Equals("((") || context.GetChild(0).GetText().Equals("TUPLE")) // Tuple
            {
                n.Operation = OperationType.TUPLE;
                n.Action    = ActionType.READ; // Find

                // Find all members and store them in the tuple node
                int mmbrCount = context.member().Count();
                for (int i = 0; i < mmbrCount; i++)
                {
                    ExprNode mmbr = Visit(context.member(i));
                    if (mmbr != null)
                    {
                        n.AddChild(mmbr);
                    }
                }
            }
            else if (context.literal() != null) // Literal
            {
                n.Operation = OperationType.VALUE;
                n.Action    = ActionType.READ;

                string name = context.literal().GetText();

                if (context.literal().INT() != null)
                {
                }
                else if (context.literal().DECIMAL() != null)
                {
                }
                else if (context.literal().STRING() != null)
                {
                    name = name.Substring(1, name.Length - 2); // Remove quotes
                }
                n.Name = name;
            }
            else if (context.GetChild(0) is ExprParser.AccessContext) // Access/call
            {
                n.Operation = OperationType.CALL;
                n.Action    = ActionType.READ;

                if (context.access().name() != null) // Name of the function - call by-reference
                {
                    n.Name = GetName(context.access().name());
                }
                else // Call by-value using a definition of the function (lambda)
                {
                    context.access().scope();
                    n.Name = "lambda"; // Automatically generated name for a unnamed lambda
                }

                // Find all parameters and store them in the access node
                int paramCount = context.access().param().Count();
                for (int i = 0; i < paramCount; i++)
                {
                    ExprNode param = Visit(context.access().param(i));
                    if (param != null)
                    {
                        n.AddChild(param);
                    }
                }
            }

            return(n);
        }
Beispiel #4
0
 public override Expression VisitExpr(ExprParser.ExprContext context)
 {
     return(Visit(context.expression())); // Skip this rule
 }
Beispiel #5
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="ExprParser.expr"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitExpr([NotNull] ExprParser.ExprContext context)
 {
 }