public virtual void PostWalk(ParenthesisExpr node) { }
// ParenthesisExpr public virtual bool Walk(ParenthesisExpr node) { return true; }
public override void PostWalk(ParenthesisExpr node) { }
// ParenthesisExpr public override bool Walk(ParenthesisExpr node) { return false; }
private Expr ParsePrimaryExpr() { int start, end, globalStart; Expr ret; // lambda handling List<Parameter> parameters = new List<Parameter>(); Parameter param; bool startBody = false; switch (PeekToken().Kind) { case TokenType.Name: NameToken nameToken = (NameToken)NextToken(); globalStart = GetStart(); if (_sink != null) _sink.StartName(GetSourceSpan(), nameToken.Name); ret = new IdentifierExpr(nameToken.Name); ret.SetLoc(_globalParent, GetStart(), GetEnd()); if (MaybeEat(TokenType.Arrow)) { param = new Parameter(nameToken.Name); param.SetLoc(_globalParent, ret.IndexSpan); parameters.Add(param); startBody = true; goto lambda; } return ret; case TokenType.Constant: ConstantValueToken constantToken = (ConstantValueToken)NextToken(); start = GetStart(); object cv = constantToken.Value; if (cv == null) { ret = new ConstantExpr(null); } else if (cv is bool) { ret = new ConstantExpr((bool)cv); } else if (cv is string) { ret = new ConstantExpr((string)cv); } else if (cv is int) { ret = new ConstantExpr((int)cv); } else if (cv is Uninitialized) { ret = new ConstantExpr(Uninitialized.Instance); } else if (cv is double) { ret = new ConstantExpr((double)cv); } else if (cv is BigInteger) { ret = new ConstantExpr((BigInteger)cv); } else { throw Assert.Unreachable; } ret.SetLoc(_globalParent, GetStart(), GetEnd()); return ret; case TokenType.LeftParenthesis: NextToken(); start = GetStart(); globalStart = GetStart(); if (PeekToken().Kind == TokenType.Name) // may be lambda: (a = 2) => a; { NameToken nt = (NameToken)NextToken(); if (PeekToken().Kind == TokenType.RightParenthesis) { end = GetEnd(); start = GetStart(); NextToken(); if (MaybeEat(TokenType.Arrow)) { param = new Parameter(nt.Name); param.SetLoc(_globalParent, GetStart(), end); parameters.Add(param); startBody = true; goto lambda; } else { ret = new IdentifierExpr(nt.Name); ret.SetLoc(_globalParent, start, end); ret = new ParenthesisExpr(ret); ret.SetLoc(_globalParent, globalStart, GetEnd()); return ret; } } else if (PeekToken().Kind == TokenType.Assign) { end = GetEnd(); start = GetStart(); NextToken(); var left = new IdentifierExpr(nt.Name); left.SetLoc(_globalParent, start, end); var right = ParseExpr(); if (PeekToken().Kind == TokenType.RightParenthesis) { end = GetEnd(); NextToken(); if (MaybeEat(TokenType.Arrow)) { param = new Parameter(nt.Name, right); param.SetLoc(_globalParent, left.StartIndex, right.EndIndex); parameters.Add(param); startBody = true; goto lambda; } else { ret = new AssignExpr(TokenType.Assign, left, right); ret.SetLoc(_globalParent, start, end); ret = new ParenthesisExpr(ret); ret.SetLoc(_globalParent, globalStart, GetEnd()); return ret; } } else if (PeekToken().Kind == TokenType.Comma) { param = new Parameter(nt.Name, right); param.SetLoc(_globalParent, start, GetEnd()); parameters.Add(param); goto lambda; } else { throw Assert.Unreachable; } } else if (PeekToken().Kind == TokenType.Comma) { param = new Parameter(nt.Name); param.SetLoc(_globalParent, GetStart(), GetEnd()); parameters.Add(param); goto lambda; } else { throw Assert.Unreachable; } } else if (PeekToken(TokenType.RightParenthesis)) { goto lambda; } else // not NameToken nor RightParen { ret = new ParenthesisExpr(ParseExpr()); Eat(TokenType.RightParenthesis); ret.SetLoc(_globalParent, globalStart, GetEnd()); return ret; } lambda: // parse the rest of the lambda if (!startBody) { while (MaybeEat(TokenType.Comma)) { if (PeekToken(TokenType.Name)) throw new SyntaxErrorException(); NameToken nt = (NameToken)NextToken(); start = GetStart(); Expr defaultVal = MaybeEat(TokenType.Assign) ? ParseExpr() : null; param = new Parameter(nt.Name, defaultVal); param.SetLoc(_globalParent, start, GetEnd()); parameters.Add(param); } Eat(TokenType.RightParenthesis); Eat(TokenType.Arrow); } return ParseLambdaBody(globalStart, parameters.ToArray()); case TokenType.LeftBracket: return ParseArrayLiteral(); default: return null; // syntax error } }
// ParenthesisExpr public override bool Walk(ParenthesisExpr node) { node.Parent = _currentScope; return base.Walk(node); }