public MacroVar(ParseInfo parseInfo, Scope objectScope, Scope staticScope, DeltinScriptParser.Define_macroContext macroContext, CodeType returnType) { _context = macroContext; Name = macroContext.name.Text; // Get the attributes. FunctionAttributesGetter attributeResult = new MacroAttributesGetter(macroContext, new MacroVarAttribute(this)); attributeResult.GetAttributes(parseInfo.Script.Diagnostics); ContainingType = (Static ? staticScope : objectScope).This; DefinedAt = new Location(parseInfo.Script.Uri, DocRange.GetRange(macroContext.name)); _recursiveCallHandler = new RecursiveCallHandler(this); CallInfo = new CallInfo(_recursiveCallHandler, parseInfo.Script); ReturnType = returnType; _expressionToParse = macroContext.expr(); _scope = Static ? staticScope : objectScope; this._parseInfo = parseInfo; _scope.AddMacro(this, parseInfo.Script.Diagnostics, DocRange.GetRange(macroContext.name), !Override); parseInfo.TranslateInfo.GetComponent <SymbolLinkComponent>().AddSymbolLink(this, DefinedAt, true); parseInfo.Script.AddHover(DocRange.GetRange(macroContext.name), GetLabel(true)); parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, CodeLensSourceType.Variable, DefinedAt.range)); DocRange nameRange = DocRange.GetRange(_context.name); if (Override) { MacroVar overriding = (MacroVar)objectScope.GetMacroOverload(Name, DefinedAt); if (overriding == this) { parseInfo.Script.Diagnostics.Error("Overriding itself!", nameRange); } // No method with the name and parameters found. if (overriding == null) { parseInfo.Script.Diagnostics.Error("Could not find a macro to override.", nameRange); } else if (!overriding.IsOverridable) { parseInfo.Script.Diagnostics.Error("The specified macro is not marked as virtual.", nameRange); } else { overriding.Overriders.Add(this); } if (overriding != null && overriding.DefinedAt != null) { // Make the override keyword go to the base method. parseInfo.Script.AddDefinitionLink( attributeResult.ObtainedAttributes.First(at => at.Type == MethodAttributeType.Override).Range, overriding.DefinedAt ); } } }
public ExpressionTreeNode(DeltinScriptParser.ExprContext context, BuildAstVisitor visitor) : base(new Location(visitor.file, Range.GetRange(context))) { Tree = new Node[context.expr().Length]; for (int i = 0; i < Tree.Length; i++) { Tree[i] = visitor.VisitExpr(context.expr(i)); } }
public override Node VisitExpr(DeltinScriptParser.ExprContext context) { Node node; // Operations if (context.ChildCount == 3 && Constants.AllOperations.Contains(context.GetChild(1).GetText())) { IExpressionNode left = (IExpressionNode)Visit(context.GetChild(0)); string operation = context.GetChild(1).GetText(); IExpressionNode right = (IExpressionNode)Visit(context.GetChild(2)); node = new OperationNode(left, operation, right, Range.GetRange(context)); } // Getting values in arrays else if (context.ChildCount == 4 && context.GetChild(0) is DeltinScriptParser.ExprContext && context.GetChild(1).GetText() == "[" && context.GetChild(2) is DeltinScriptParser.ExprContext && context.GetChild(3).GetText() == "]") { IExpressionNode value = (IExpressionNode)Visit(context.GetChild(0)); IExpressionNode index = (IExpressionNode)Visit(context.GetChild(2)); node = new ValueInArrayNode(value, index, Range.GetRange(context)); } // Seperator else if (context.ChildCount == 3 && context.GetChild(0) is DeltinScriptParser.ExprContext && context.GetChild(1).GetText() == "." && context.GetChild(2) is DeltinScriptParser.VariableContext) { string name = context.GetChild(2).GetText(); IExpressionNode target = (IExpressionNode)Visit(context.GetChild(0)); node = new VariableNode(name, target, Range.GetRange(context)); } // Not else if (context.ChildCount == 2 && context.GetChild(0).GetText() == "!" && context.GetChild(1) is DeltinScriptParser.ExprContext) { IExpressionNode value = (IExpressionNode)Visit(context.GetChild(1)); node = new NotNode(value, Range.GetRange(context)); } else { return(Visit(context.GetChild(0))); } CheckRange(node); return(node); }
public static IExpression GetExpression(ParseInfo parseInfo, Scope scope, DeltinScriptParser.ExprContext exprContext, bool selfContained = true, bool usedAsValue = true, Scope getter = null) { if (getter == null) { getter = scope; } switch (exprContext) { case DeltinScriptParser.E_numberContext number: return(new NumberAction(parseInfo.Script, number.number())); case DeltinScriptParser.E_trueContext @true: return(new BoolAction(parseInfo.Script, true)); case DeltinScriptParser.E_falseContext @false: return(new BoolAction(parseInfo.Script, false)); case DeltinScriptParser.E_nullContext @null: return(new NullAction()); case DeltinScriptParser.E_stringContext @string: return(new StringAction(parseInfo.Script, @string.@string())); case DeltinScriptParser.E_formatted_stringContext formattedString: return(new StringAction(parseInfo, scope, formattedString.formatted_string())); case DeltinScriptParser.E_variableContext variable: return(GetVariable(parseInfo, scope, variable.variable(), selfContained)); case DeltinScriptParser.E_methodContext method: return(new CallMethodAction(parseInfo, scope, method.method(), usedAsValue, getter)); case DeltinScriptParser.E_new_objectContext newObject: return(new CreateObjectAction(parseInfo, scope, newObject.create_object())); case DeltinScriptParser.E_expr_treeContext exprTree: return(new ExpressionTree(parseInfo, scope, exprTree, usedAsValue)); case DeltinScriptParser.E_array_indexContext arrayIndex: return(new ValueInArrayAction(parseInfo, scope, arrayIndex)); case DeltinScriptParser.E_create_arrayContext createArray: return(new CreateArrayAction(parseInfo, scope, createArray.createarray())); case DeltinScriptParser.E_expr_groupContext group: return(GetExpression(parseInfo, scope, group.exprgroup().expr())); case DeltinScriptParser.E_type_convertContext typeConvert: return(new TypeConvertAction(parseInfo, scope, typeConvert.typeconvert())); case DeltinScriptParser.E_notContext not: return(new NotAction(parseInfo, scope, not.expr())); case DeltinScriptParser.E_inverseContext inverse: return(new InverseAction(parseInfo, scope, inverse.expr())); case DeltinScriptParser.E_op_1Context op1: return(new OperatorAction(parseInfo, scope, op1)); case DeltinScriptParser.E_op_2Context op2: return(new OperatorAction(parseInfo, scope, op2)); case DeltinScriptParser.E_op_boolContext opBool: return(new OperatorAction(parseInfo, scope, opBool)); case DeltinScriptParser.E_op_compareContext opCompare: return(new OperatorAction(parseInfo, scope, opCompare)); case DeltinScriptParser.E_ternary_conditionalContext ternary: return(new TernaryConditionalAction(parseInfo, scope, ternary)); case DeltinScriptParser.E_rootContext root: return(new RootAction(parseInfo.TranslateInfo)); default: throw new Exception($"Could not determine the expression type '{exprContext.GetType().Name}'."); } }
public Var(VarInfo varInfo) { Name = varInfo.Name; DefinedAt = varInfo.DefinedAt; parseInfo = varInfo.ParseInfo; AccessLevel = varInfo.AccessLevel; DefinedAt = varInfo.DefinedAt; WholeContext = varInfo.WholeContext; CodeType = varInfo.Type; VariableType = varInfo.VariableType; StoreType = varInfo.StoreType; InExtendedCollection = varInfo.InExtendedCollection; ID = varInfo.ID; Static = varInfo.Static; Recursive = varInfo.Recursive; BridgeInvocable = varInfo.BridgeInvocable; _tokenType = varInfo.TokenType; _tokenModifiers = varInfo.TokenModifiers.ToArray(); _handleRestrictedCalls = varInfo.HandleRestrictedCalls; _initalValueContext = varInfo.InitialValueContext; _initialValueResolve = varInfo.InitialValueResolve; _operationalScope = varInfo.OperationalScope; if (ID != -1) { if (VariableType == VariableType.Global) { parseInfo.TranslateInfo.VarCollection.Reserve(ID, true, parseInfo.Script.Diagnostics, DefinedAt.range); } else if (VariableType == VariableType.Player) { parseInfo.TranslateInfo.VarCollection.Reserve(ID, false, parseInfo.Script.Diagnostics, DefinedAt.range); } } // Add the variable to the scope. _operationalScope.AddVariable(this, parseInfo.Script.Diagnostics, DefinedAt.range); parseInfo.Script.AddToken(DefinedAt.range, _tokenType, _tokenModifiers); parseInfo.Script.AddHover(DefinedAt.range, GetLabel(true)); parseInfo.TranslateInfo.GetComponent <SymbolLinkComponent>().AddSymbolLink(this, DefinedAt, true); if (_initialValueResolve == InitialValueResolve.Instant) { GetInitialValue(); } else { parseInfo.TranslateInfo.ApplyBlock(this); } parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, varInfo.CodeLensType, DefinedAt.range)); }
public Var(VarInfo varInfo) { Name = varInfo.Name; DefinedAt = varInfo.DefinedAt; parseInfo = varInfo.ParseInfo; AccessLevel = varInfo.AccessLevel; DefinedAt = varInfo.DefinedAt; WholeContext = varInfo.WholeContext; CodeType = varInfo.Type; VariableType = varInfo.VariableType; StoreType = varInfo.StoreType; InExtendedCollection = varInfo.InExtendedCollection; ID = varInfo.ID; Static = varInfo.Static; _initalValueContext = varInfo.InitialValueContext; _initialValueResolve = varInfo.InitialValueResolve; _operationalScope = varInfo.OperationalScope; if (ID != -1) { if (VariableType == VariableType.Global) { parseInfo.TranslateInfo.VarCollection.Reserve(ID, true, parseInfo.Script.Diagnostics, DefinedAt.range); } else if (VariableType == VariableType.Player) { parseInfo.TranslateInfo.VarCollection.Reserve(ID, false, parseInfo.Script.Diagnostics, DefinedAt.range); } } // Add the variable to the scope. _operationalScope.AddVariable(this, parseInfo.Script.Diagnostics, DefinedAt.range); _finalized = true; parseInfo.Script.AddHover(DefinedAt.range, GetLabel(true)); parseInfo.TranslateInfo.AddSymbolLink(this, DefinedAt, true); if (_initialValueResolve == InitialValueResolve.Instant) { GetInitialValue(); } else { parseInfo.TranslateInfo.ApplyBlock(this); } parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, varInfo.CodeLensType, DefinedAt.range)); }
public DefinedMacro(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Define_macroContext context) : base(parseInfo, scope, context.name.Text, new LanguageServer.Location(parseInfo.Script.Uri, DocRange.GetRange(context.name))) { AccessLevel = context.accessor().GetAccessLevel(); SetupParameters(context.setParameters()); if (context.TERNARY_ELSE() == null) { parseInfo.Script.Diagnostics.Error("Expected :", DocRange.GetRange(context).end.ToRange()); } else { ExpressionToParse = context.expr(); if (ExpressionToParse == null) { parseInfo.Script.Diagnostics.Error("Expected expression.", DocRange.GetRange(context.TERNARY_ELSE())); } } parseInfo.Script.AddHover(DocRange.GetRange(context.name), GetLabel(true)); }
private void GetParts(ParseInfo parseInfo, Scope scope, DeltinScriptParser.ExprContext left, string op, DocRange opRange, DeltinScriptParser.ExprContext right) { // Left operator. if (left == null) { parseInfo.Script.Diagnostics.Error("Missing left operator.", opRange); } else { Left = DeltinScript.GetExpression(parseInfo, scope, left); } // Right operator. if (right == null) { parseInfo.Script.Diagnostics.Error("Missing right operator.", opRange); } else { Right = DeltinScript.GetExpression(parseInfo, scope, right); } Operator = op; }
private void GetRuleSettings(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Ow_ruleContext ruleContext) { DeltinScriptParser.ExprContext eventContext = null; DeltinScriptParser.ExprContext teamContext = null; DeltinScriptParser.ExprContext playerContext = null; foreach (var exprContext in ruleContext.expr()) { missingBlockRange = DocRange.GetRange(exprContext); EnumValuePair enumSetting = (ExpressionTree.ResultingExpression(parseInfo.GetExpression(scope, exprContext)) as CallVariableAction)?.Calling as EnumValuePair; EnumData enumData = enumSetting?.Member.Enum; if (enumData == null || !ValidRuleEnums.Contains(enumData)) { parseInfo.Script.Diagnostics.Error("Expected enum of type " + string.Join(", ", ValidRuleEnums.Select(vre => vre.CodeName)) + ".", DocRange.GetRange(exprContext)); } else { var alreadySet = new Diagnostic("The " + enumData.CodeName + " rule setting was already set.", DocRange.GetRange(exprContext), Diagnostic.Error); // Get the Event option. if (enumData == EnumData.GetEnum <RuleEvent>()) { if (_setEventType) { parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet); } EventType = (RuleEvent)enumSetting.Member.Value; _setEventType = true; eventContext = exprContext; } // Get the Team option. if (enumData == EnumData.GetEnum <Team>()) { if (_setTeam) { parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet); } Team = (Team)enumSetting.Member.Value; _setTeam = true; teamContext = exprContext; } // Get the Player option. if (enumData == EnumData.GetEnum <PlayerSelector>()) { if (_setPlayer) { parseInfo.Script.Diagnostics.AddDiagnostic(alreadySet); } Player = (PlayerSelector)enumSetting.Member.Value; _setPlayer = true; playerContext = exprContext; } } } // Syntax error if changing the Team type when the Event type is set to Global. if (_setEventType && EventType == RuleEvent.OngoingGlobal) { if (Team != Team.All) { parseInfo.Script.Diagnostics.Error("Can't change rule Team type with an event type of Ongoing Global.", DocRange.GetRange(teamContext)); } if (Player != PlayerSelector.All) { parseInfo.Script.Diagnostics.Error("Can't change rule Player type with an event type of Ongoing Global.", DocRange.GetRange(playerContext)); } } }
public TreeContextPart(DeltinScriptParser.ExprContext expression) { this.expression = expression ?? throw new ArgumentNullException(nameof(expression)); Range = DocRange.GetRange(expression); CompletionRange = Range; }
object ParseParameter(DeltinScriptParser.ExprContext context, string methodName, Parameter parameterData) { object value = null; if (context.GetChild(0) is DeltinScriptParser.EnumContext) { if (parameterData.ParameterType != ParameterType.Enum) { throw new SyntaxErrorException($"Expected value type \"{parameterData.ValueType.ToString()}\" on {methodName}'s parameter \"{parameterData.Name}\"." , context.start); } string type = context.GetText().Split('.').ElementAtOrDefault(0); string enumValue = context.GetText().Split('.').ElementAtOrDefault(1); if (type != parameterData.EnumType.Name) { throw new SyntaxErrorException($"Expected enum type \"{parameterData.EnumType.ToString()}\" on {methodName}'s parameter \"{parameterData.Name}\"." , context.start); } try { value = Enum.Parse(parameterData.EnumType, enumValue); } catch (Exception ex) when(ex is ArgumentNullException || ex is ArgumentException || ex is OverflowException) { throw new SyntaxErrorException($"The value {enumValue} does not exist in the enum {type}."); } if (value == null) { throw new SyntaxErrorException($"Could not parse enum parameter {context.GetText()}." , context.start); } } else { if (parameterData.ParameterType != ParameterType.Value) { throw new SyntaxErrorException($"Expected enum type \"{parameterData.EnumType.Name}\" on {methodName}'s parameter \"{parameterData.Name}\"." , context.start); } value = ParseExpression(context); Element element = value as Element; ElementData elementData = element.GetType().GetCustomAttribute <ElementData>(); if (elementData.ValueType != Elements.ValueType.Any && !parameterData.ValueType.HasFlag(elementData.ValueType)) { throw new SyntaxErrorException($"Expected value type \"{parameterData.ValueType.ToString()}\" on {methodName}'s parameter \"{parameterData.Name}\", got \"{elementData.ValueType.ToString()}\" instead." , context.start); } } if (value == null) { throw new SyntaxErrorException("Could not parse parameter.", context.start); } return(value); }
Element ParseExpression(DeltinScriptParser.ExprContext context) { // If the expression is a(n)... #region Operation // 0 1 2 // (expr operation expr) // count == 3 if (context.ChildCount == 3 && (Constants.MathOperations.Contains(context.GetChild(1).GetText()) || Constants.CompareOperations.Contains(context.GetChild(1).GetText()) || Constants.BoolOperations.Contains(context.GetChild(1).GetText()))) { Element left = ParseExpression(context.GetChild(0) as DeltinScriptParser.ExprContext); string operation = context.GetChild(1).GetText(); Element right = ParseExpression(context.GetChild(2) as DeltinScriptParser.ExprContext); if (Constants.BoolOperations.Contains(context.GetChild(1).GetText())) { if (left.ElementData.ValueType != Elements.ValueType.Any && left.ElementData.ValueType != Elements.ValueType.Boolean) { throw new SyntaxErrorException($"Expected boolean datatype, got {left .ElementData.ValueType.ToString()} instead.", context.start); } if (right.ElementData.ValueType != Elements.ValueType.Any && right.ElementData.ValueType != Elements.ValueType.Boolean) { throw new SyntaxErrorException($"Expected boolean datatype, got {right.ElementData.ValueType.ToString()} instead.", context.start); } } switch (operation) { case "^": return(Element.Part <V_RaiseToPower>(left, right)); case "*": return(Element.Part <V_Multiply>(left, right)); case "/": return(Element.Part <V_Divide>(left, right)); case "+": return(Element.Part <V_Add>(left, right)); case "-": return(Element.Part <V_Subtract>(left, right)); case "%": return(Element.Part <V_Modulo>(left, right)); // COMPARE : '<' | '<=' | '==' | '>=' | '>' | '!='; case "&": return(Element.Part <V_And>(left, right)); case "|": return(Element.Part <V_Or>(left, right)); case "<": return(Element.Part <V_Compare>(left, Operators.LessThan, right)); case "<=": return(Element.Part <V_Compare>(left, Operators.LessThanOrEqual, right)); case "==": return(Element.Part <V_Compare>(left, Operators.Equal, right)); case ">=": return(Element.Part <V_Compare>(left, Operators.GreaterThanOrEqual, right)); case ">": return(Element.Part <V_Compare>(left, Operators.GreaterThan, right)); case "!=": return(Element.Part <V_Compare>(left, Operators.NotEqual, right)); } } #endregion #region Not if (context.GetChild(0) is DeltinScriptParser.NotContext) { return(Element.Part <V_Not>(ParseExpression(context.GetChild(1) as DeltinScriptParser.ExprContext))); } #endregion #region Number if (context.GetChild(0) is DeltinScriptParser.NumberContext) { var number = context.GetChild(0); double num = double.Parse(number.GetChild(0).GetText()); /* * // num will have the format expr(number(X)) if positive, expr(number(neg(X))) if negative. * if (number.GetChild(0) is DeltinScriptParser.NegContext) * // Is negative, use '-' before int.parse to make it negative. * num = -double.Parse(number.GetChild(0).GetText()); * else * // Is positive * num = double.Parse(number.GetChild(0).GetText()); */ return(new V_Number(num)); } #endregion #region Boolean // True if (context.GetChild(0) is DeltinScriptParser.TrueContext) { return(new V_True()); } // False if (context.GetChild(0) is DeltinScriptParser.FalseContext) { return(new V_False()); } #endregion #region String if (context.GetChild(0) is DeltinScriptParser.StringContext) { return(V_String.ParseString( context.start, // String will look like "hey this is the contents", trim the quotes. (context.GetChild(0) as DeltinScriptParser.StringContext).STRINGLITERAL().GetText().Trim('\"'), null )); } #endregion #region Formatted String if (context.GetChild(1) is DeltinScriptParser.StringContext) { Element[] values = context.expr().Select(expr => ParseExpression(expr)).ToArray(); return(V_String.ParseString( context.start, (context.GetChild(1) as DeltinScriptParser.StringContext).STRINGLITERAL().GetText().Trim('\"'), values )); } #endregion #region null if (context.GetChild(0) is DeltinScriptParser.NullContext) { return(new V_Null()); } #endregion #region Group ( expr ) if (context.ChildCount == 3 && context.GetChild(0).GetText() == "(" && context.GetChild(1) is DeltinScriptParser.ExprContext && context.GetChild(2).GetText() == ")") { Console.WriteLine("Group type:" + context.GetChild(0).GetType()); return(ParseExpression(context.GetChild(1) as DeltinScriptParser.ExprContext)); } #endregion #region Method if (context.GetChild(0) is DeltinScriptParser.MethodContext) { return(ParseMethod(context.GetChild(0) as DeltinScriptParser.MethodContext, true)); } #endregion #region Variable if (context.GetChild(0) is DeltinScriptParser.VariableContext) { return(DefinedVar.GetVar((context.GetChild(0) as DeltinScriptParser.VariableContext).PART().GetText(), context.start).GetVariable(new V_EventPlayer())); } #endregion #region Array if (context.ChildCount == 4 && context.GetChild(1).GetText() == "[" && context.GetChild(3).GetText() == "]") { return(Element.Part <V_ValueInArray>( ParseExpression(context.expr(0) as DeltinScriptParser.ExprContext), ParseExpression(context.expr(1) as DeltinScriptParser.ExprContext))); } #endregion #region Create Array if (context.ChildCount >= 4 && context.GetChild(0).GetText() == "[") { var expressions = context.expr(); V_Append prev = null; V_Append current = null; for (int i = 0; i < expressions.Length; i++) { current = new V_Append() { ParameterValues = new object[2] }; if (prev != null) { current.ParameterValues[0] = prev; } else { current.ParameterValues[0] = new V_EmptyArray(); } current.ParameterValues[1] = ParseExpression(expressions[i]); prev = current; } return(current); } #endregion #region Empty Array if (context.ChildCount == 2 && context.GetText() == "[]") { return(Element.Part <V_EmptyArray>()); } #endregion #region Seperator/enum if (context.ChildCount == 3 && context.GetChild(1).GetText() == ".") { Element left = ParseExpression(context.GetChild(0) as DeltinScriptParser.ExprContext); string variableName = context.GetChild(2).GetChild(0).GetText(); DefinedVar var = DefinedVar.GetVar(variableName, context.start); return(var.GetVariable(left)); } #endregion throw new Exception($"What's a {context.GetType().Name}?"); }
public InverseAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.ExprContext exprContext) { Expression = DeltinScript.GetExpression(parseInfo, scope, exprContext); }
public InitialValueAttribute(DeltinScriptParser.ExprContext exprContext) : base(AttributeType.Initial, DocRange.GetRange(exprContext)) { ExprContext = exprContext; }
public NotAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.ExprContext exprContext) { Expression = parseInfo.GetExpression(scope, exprContext); }
public override Node VisitExpr(DeltinScriptParser.ExprContext context) { Node node; // Operations if (context.ChildCount == 3 && Constants.AllOperations.Contains(context.GetChild(1).GetText())) { Node left = Visit(context.GetChild(0)); string operation = context.GetChild(1).GetText(); Node right = Visit(context.GetChild(2)); node = new OperationNode(left, operation, right, new Location(file, Range.GetRange(context))); } // Getting values in arrays else if (context.ChildCount == 4 && context.GetChild(0) is DeltinScriptParser.ExprContext && context.GetChild(1).GetText() == "[" && context.GetChild(2) is DeltinScriptParser.ExprContext && context.GetChild(3).GetText() == "]") { Node value = Visit(context.GetChild(0)); Node index = Visit(context.GetChild(2)); node = new ValueInArrayNode(value, index, new Location(file, Range.GetRange(context))); } // Seperator else if (context.SEPERATOR() != null && context.expr().Length >= 2) { node = new ExpressionTreeNode(context, this); } // Not else if (context.ChildCount == 2 && context.GetChild(0).GetText() == "!" && context.GetChild(1) is DeltinScriptParser.ExprContext) { Node value = Visit(context.GetChild(1)); node = new NotNode(value, new Location(file, Range.GetRange(context))); } // Ternary Condition else if (context.ChildCount == 5 && context.GetChild(0) is DeltinScriptParser.ExprContext && context.GetChild(1).GetText() == "?" && context.GetChild(2) is DeltinScriptParser.ExprContext && context.GetChild(3).GetText() == ":" && context.GetChild(4) is DeltinScriptParser.ExprContext) { Node condition = VisitExpr(context.expr(0)); Node consequent = VisitExpr(context.expr(1)); Node alternative = VisitExpr(context.expr(2)); node = new TernaryConditionalNode(condition, consequent, alternative, new Location(file, Range.GetRange(context))); } // This else if (context.THIS() != null) { node = new ThisNode(new Location(file, Range.GetRange(context))); } else { return(Visit(context.GetChild(0))); } return(node); }