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); }
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); } }
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); }
public override Expression VisitExpr(ExprParser.ExprContext context) { return(Visit(context.expression())); // Skip this rule }
/// <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) { }