/// <summary> /// Given expression statement determines if it defines a function /// and if so, returns the function definition and the variable /// it is assigned to. /// </summary> public static IFunctionDefinition GetVariableOrFunctionDefinition(this IExpressionStatement es, out Variable v) { v = null; if (es == null || es.Expression == null) { return null; } // Tree: // <- // x function(a) // // var c = es.Expression.Children; if (c.Count == 1) { var op = c[0] as IOperator; if (op != null) { if (op.OperatorType == OperatorType.LeftAssign || op.OperatorType == OperatorType.Equals) { v = op.LeftOperand as Variable; if (v != null) { return op.RightOperand as IFunctionDefinition; } } else if (op.OperatorType == OperatorType.RightAssign) { v = op.RightOperand as Variable; } } } return null; }
public override bool Parse(ParseContext context, IAstNode parent) { TokenStream<RToken> tokens = context.Tokens; if (tokens.CurrentToken.IsVariableKind()) { var v = new Variable(); v.Parse(context, this); // Variables don't set parent since during complex // exression parsing parent is determined by the // expression parser based on precedence and grouping. v.Parent = this; this.Variable = v; if (tokens.CurrentToken.IsKeywordText(context.TextProvider, "in")) { this.InOperator = new TokenNode(); this.InOperator.Parse(context, this); this.Expression = new Expression(inGroup: true); if (this.Expression.Parse(context, this)) { return base.Parse(context, parent); } } else { context.AddError(new MissingItemParseError(ParseErrorType.InKeywordExpected, tokens.CurrentToken)); } } else { context.AddError(new MissingItemParseError(ParseErrorType.IndentifierExpected, tokens.PreviousToken)); } return false; }
private static bool GetFunction(AstRoot astRoot, ref int position, out FunctionCall functionCall, out Variable functionVariable) { functionVariable = null; functionCall = astRoot.GetNodeOfTypeFromPosition<FunctionCall>(position); if (functionCall == null && position > 0) { // Retry in case caret is at the very end of function signature // that does not have final close brace yet. functionCall = astRoot.GetNodeOfTypeFromPosition<FunctionCall>(position - 1, includeEnd: true); if(functionCall != null) { // But if signature does have closing brace and caret // is beyond it, we are really otuside of the signature. if(functionCall.CloseBrace != null && position >= functionCall.CloseBrace.End) { return false; } if (position > functionCall.SignatureEnd) { position = functionCall.SignatureEnd; } } } if (functionCall != null && functionCall.Children.Count > 0) { functionVariable = functionCall.Children[0] as Variable; return functionVariable != null; } return false; }
public static IFunctionDefinition FindFunctionDefinition(ITextBuffer textBuffer, AstRoot ast, int position, out Variable v) { v = null; var exp = ast.GetNodeOfTypeFromPosition<IExpressionStatement>(position); return exp?.GetVariableOrFunctionDefinition(out v); }
private OperationType HandleIdentifier(ParseContext context) { Variable variable = new Variable(); variable.Parse(context, null); _operands.Push(variable); return OperationType.Operand; }