VariableVisit IVariableVisitor <VariableVisit> .Visit(Variable.MemberExpr variable) { return(VariableVisit.CreateMemberExpr( variable.Prefix.Visit(this), variable.Member.Visit(this))); }
/* Parses prefixExpression * variable | functionCall | '(' expression ')' */ PrefixExpression PrefixExpression() { /* prefixexpr -> NAME | '(' expr ')' */ // Parse the terminal/first symbol of the prefixExpression PrefixExpression left; switch (Current.Symbol) { case Symbol.LeftParen: var leftSpan = Expect(Symbol.LeftParen).Span; var expr = Expression(); var rightSpan = ExpectMatch(Symbol.RightParen, Symbol.LeftParen, leftSpan.Start).Span; left = new PrefixExpression.Expression(expr, new SourceSpan(leftSpan.Start, rightSpan.End)); break; case Symbol.Identifier: var identifier = Consume(); var idVar = new Variable.Identifier(identifier.Lexeme) { Span = identifier.Span }; left = new PrefixExpression.Variable(idVar); break; default: throw ReportSyntaxErrorNear("unexpected symbol"); } /* primaryexpr -> prefixexpr { `.' NAME | `[' expr `]' | `:' NAME funcargs | funcargs } */ while (true) { Token identifier; switch (Current.Symbol) { case Symbol.LeftBrack: var leftSpan = Expect(Symbol.LeftBrack).Span; var expr = Expression(); var rightSpan = ExpectMatch(Symbol.RightBrack, Symbol.LeftBrack, leftSpan.Start).Span; var memberExpr = new Variable.MemberExpr(left, expr) { Span = new SourceSpan(left.Span.Start, rightSpan.End) }; left = new PrefixExpression.Variable(memberExpr); break; case Symbol.Dot: Consume(); identifier = Expect(Symbol.Identifier); var memberId = new Variable.MemberId(left, identifier.Lexeme) { Span = new SourceSpan(left.Span.Start, identifier.Span.End) }; left = new PrefixExpression.Variable(memberId); break; case Symbol.Colon: Consume(); identifier = Expect(Symbol.Identifier); var arguments = Arguments(); left = new PrefixExpression.FunctionCall(new FunctionCall.Table(left, identifier.Lexeme, arguments) { Span = new SourceSpan(left.Span.Start, arguments.Span.End) }); break; case Symbol.LeftParen: case Symbol.LeftBrace: case Symbol.String: var args = Arguments(); left = new PrefixExpression.FunctionCall(new FunctionCall.Normal(left, args) { Span = new SourceSpan(left.Span.Start, args.Span.End) }); break; // Unrecognized symbol, return what we have so far default: return left; } } }