public virtual object VisitLocalDeclarationStatement(LocalDeclarationStatement localVariableDeclaration, object data) { stackMap.Push(localVariableDeclaration); localVariableDeclaration.Attributes.AcceptVisitor(this, data); localVariableDeclaration.Type.AcceptVisitor(this, data); localVariableDeclaration.Declarators.AcceptVisitor(this, data); stackMap.Pop(); return(null); }
private void ParseLocalDeclaration() { IdentifierExpression declIdentifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, false, false, false); IType type = (IType)exprStack.Pop(); LocalDeclarationStatement lnode = new LocalDeclarationStatement(curtok); lnode.Identifiers.Expressions.Add(declIdentifier); if (isLocalConst) { lnode.IsConstant = true; } isLocalConst = false; lnode.Type = type; // a using statement can hold a local decl without a semi, thus the rparen while (curtok.ID != TokenID.Eof && curtok.ID != TokenID.Semi && curtok.ID != TokenID.RParen) { while (curtok.ID == TokenID.Comma) { Advance(); // over comma declIdentifier = (IdentifierExpression)ParseIdentifierOrKeyword(false, true, false, false); lnode.Identifiers.Expressions.Add(declIdentifier); } if (curtok.ID == TokenID.Equal) { Advance(); // over equal lnode.RightSide = ParseExpression(TokenID.Comma); if (curtok.ID == TokenID.Comma) { exprStack.Push(lnode); lnode = new LocalDeclarationStatement(curtok); lnode.Type = type; } } } exprStack.Push(lnode); }
public virtual object VisitLocalDeclarationStatement(LocalDeclarationStatement localVariableDeclaration, object data) { stackMap.Push(localVariableDeclaration); localVariableDeclaration.Attributes.AcceptVisitor(this, data); localVariableDeclaration.Type.AcceptVisitor(this, data); localVariableDeclaration.Identifiers.AcceptVisitor(this, data); if (localVariableDeclaration.RightSide != null) { localVariableDeclaration.RightSide.AcceptVisitor(this, data); } stackMap.Pop(); return null; }
private void ParseExpressionSegment() { #region Chart // arraycre new : type : [{ // literal (lit) // simpleName ident // parenExpr LParen : expr // memAccess pexpr : Dot // pdefType : Dot // invoke pexpr : LParen // elemAccess noArrCreExpr: LBracket // thisAccess this // baseAccess base : Dot // base : LBracket // postInc pexpr : ++ // postDec pexpr : -- // objCre new : type : LParen // delgCre new : delgType : LParen // typeof typeof : LParen // checked checked : LParen // unchecked unchecked : LParen #endregion ExpressionNode tempNode = null; TokenID startToken = curtok.ID; switch (curtok.ID) { #region Literals case TokenID.NullLiteral: exprStack.Push(new NullPrimitive(curtok)); Advance(); break; case TokenID.TrueLiteral: exprStack.Push(new BooleanPrimitive(true, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.FalseLiteral: exprStack.Push(new BooleanPrimitive(false, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.IntLiteral: exprStack.Push(new IntegralPrimitive(strings[curtok.Data], IntegralType.Int, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.UIntLiteral: exprStack.Push(new IntegralPrimitive(strings[curtok.Data], IntegralType.UInt, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.LongLiteral: exprStack.Push(new IntegralPrimitive(strings[curtok.Data], IntegralType.Long, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.ULongLiteral: exprStack.Push(new IntegralPrimitive(strings[curtok.Data], IntegralType.ULong, curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.RealLiteral: exprStack.Push(new RealPrimitive(strings[curtok.Data], curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.CharLiteral: exprStack.Push(new CharPrimitive(strings[curtok.Data], curtok)); Advance(); ParseContinuingPrimary(); break; case TokenID.StringLiteral: string sval = strings[curtok.Data]; exprStack.Push(new StringPrimitive(sval, curtok)); Advance(); ParseContinuingPrimary(); break; #endregion #region Predefined Types case TokenID.Bool: case TokenID.Byte: case TokenID.Char: case TokenID.Decimal: case TokenID.Double: case TokenID.Float: case TokenID.Int: case TokenID.Long: case TokenID.Object: case TokenID.SByte: case TokenID.Short: case TokenID.String: case TokenID.UInt: case TokenID.ULong: case TokenID.UShort: exprStack.Push(ParseIdentifierOrKeyword(false, true, false, false)); if (curtok.ID == TokenID.Question) { Advance(); ((INullableType)exprStack.Peek()).IsNullableType = true; } else { if (curtok.ID == TokenID.Star) { Advance(); exprStack.Push(new TypePointerNode(exprStack.Pop())); } } ParseContinuingPrimary(); break; #endregion #region Binary Ops case TokenID.Plus: tempNode = ConsumeBinary(startToken); if (tempNode != null) { exprStack.Push(new UnaryExpression(startToken, tempNode, tempNode.RelatedToken)); // unary } break; case TokenID.Minus: if (exprStack.Count != 0 && exprStack.Peek() is PrimaryExpression) { tempNode = ConsumeBinary(startToken); } else { ConsumeUnary(TokenID.Minus); } if (tempNode != null) { exprStack.Push(new UnaryExpression(startToken, tempNode, tempNode.RelatedToken)); // unary } break; case TokenID.Star: // for this token, we have to control it is not a // pointer type declaration bool isPointer = false; if ( exprStack.Count == 0 || !(exprStack.Peek() is IPointer) && (curTokNode != null && curTokNode.Value.ID == TokenID.Star || curTokNode.Previous.Previous.Value.ID == TokenID.Star)) { // case : // int* p; // *p = x; Advance();//over the '*'; ParseExpressionSegment(); exprStack.Push(new DereferenceExpression(exprStack.Pop(), true )); } else { if (isLocalConst // if const kw -> local/member declaration || exprStack.Peek() is IPointer) { //the expression inherits from IPointer, so this is a type expression //and it might be a pointer isPointer = true; } else { // if the next segment can not be an expression TokenID id = (curTokNode != null) ? curTokNode.Value.ID : TokenID.Eof; if (id == TokenID.Eof || id == TokenID.RCurly || id == TokenID.Semi || id == TokenID.RParen || id == TokenID.Comma || id == TokenID.Colon) { isPointer = true; } } if (isPointer) { Advance(); ExpressionNode e = TagAsPointerType(exprStack.Pop()); exprStack.Push(e); } else { //the next segment is an expression. //at this sage it is impossible to determine if this is a pointer expression ConsumeBinary(startToken); if (curtok.ID == TokenID.Equal) { // the assignment means that the previous expression is not // a binary expression but a local pointer declaration Advance(); // over equal BinaryExpression bin = (BinaryExpression)exprStack.Pop(); LocalDeclarationStatement ldecl = new LocalDeclarationStatement((IType)TagAsPointerType(bin.Left), (IdentifierExpression)bin.Right, ParseExpression(TokenID.Comma) ); exprStack.Push(ldecl); if (curtok.ID == TokenID.Comma)// multiple local declaration { exprStack.Push((ExpressionNode)ldecl.Type); ParseLocalDeclaration(); } } } } break; case TokenID.Is: case TokenID.As: case TokenID.Slash: case TokenID.Percent: case TokenID.ShiftLeft: case TokenID.ShiftRight: case TokenID.Less: case TokenID.Greater: case TokenID.LessEqual: case TokenID.GreaterEqual: case TokenID.EqualEqual: case TokenID.NotEqual: case TokenID.BXor: case TokenID.BOr: case TokenID.And: case TokenID.Or: ConsumeBinary(startToken); break; case TokenID.BAnd: if (exprStack.Count == 0) { //the expression stack is empty, so this is n identifier dereference ParseAddressOfIdentifier(); } else { ConsumeBinary(startToken); } break; #endregion #region Unary Ops case TokenID.Not: case TokenID.Tilde: case TokenID.PlusPlus: case TokenID.MinusMinus: ConsumeUnary(startToken); break; #endregion #region Conditional case TokenID.Question: if (curtok.NullableDeclaration) { Advance(); ExpressionNode expr = TagAsNullableType(exprStack.Pop()); CheckRankSpecifier(expr); exprStack.Push(expr); } else { Advance(); ConditionalExpression conditionalExpression = new ConditionalExpression(exprStack.Pop(), null, null); exprStack.Push(conditionalExpression); ExpressionNode cond1 = ParseExpression(TokenID.Equal); AssertAndAdvance(TokenID.Colon); ExpressionNode cond2 = ParseExpression(); conditionalExpression.Left = cond1; conditionalExpression.Right = cond2; } break; //case TokenID.ColonColon: // Advance(); //break; case TokenID.QuestionQuestion: ExpressionNode left = exprStack.Pop(); Advance(); ExpressionNode right = ParseExpression(TokenID.Semi); exprStack.Push(new NullCoalescingExpression(left, right )); break; #endregion #region Keywords // keywords case TokenID.Ref: Advance(); ParseExpressionSegment(); exprStack.Push(new RefNode(exprStack.Pop())); break; case TokenID.Out: Advance(); ParseExpressionSegment(); exprStack.Push(new OutNode(exprStack.Pop())); break; case TokenID.This: exprStack.Push(ParseIdentifierOrKeyword(false, true, false, false)); ParseContinuingPrimary(); break; case TokenID.Void: // this can happen in typeof(void), nothing can follow exprStack.Push(new VoidPrimitive(curtok)); Advance(); break; case TokenID.Base: Advance(); TokenID newToken = curtok.ID; if (newToken == TokenID.Dot) { Advance();// advance over dot exprStack.Push( new IdentifierExpression(strings[curtok.Data], curtok) ); Advance();//advance over ident } else if (newToken == TokenID.LBracket) { Advance();//advance over left bracket exprStack.Push( ParseExpressionList(TokenID.RBracket) ); } ParseContinuingPrimary(); exprStack.Push(new BaseAccessExpression(exprStack.Pop())); break; case TokenID.Typeof: Advance(); AssertAndAdvance(TokenID.LParen); exprStack.Push(new TypeOfExpression(ParseExpression(TokenID.RParen))); AssertAndAdvance(TokenID.RParen); ParseContinuingPrimary(); break; case TokenID.Checked: Advance(); AssertAndAdvance(TokenID.LParen); //ParseExpressionSegment(); exprStack.Push(new CheckedExpression(ParseExpression(TokenID.RParen))); AssertAndAdvance(TokenID.RParen); ParseContinuingPrimary(); break; case TokenID.Unchecked: Advance(); AssertAndAdvance(TokenID.LParen); ParseExpressionSegment(); exprStack.Push(new UncheckedExpression(exprStack.Pop())); AssertAndAdvance(TokenID.RParen); ParseContinuingPrimary(); break; #endregion #region Assignment case TokenID.Equal: case TokenID.PlusEqual: case TokenID.MinusEqual: case TokenID.StarEqual: case TokenID.SlashEqual: case TokenID.PercentEqual: case TokenID.BAndEqual: case TokenID.BOrEqual: case TokenID.BXorEqual: case TokenID.ShiftLeftEqual: case TokenID.ShiftRightEqual: TokenID op = curtok.ID; Advance(); if (exprStack.Count > 0 && !(exprStack.Peek() is PrimaryExpression) && !(exprStack.Peek() is UnaryCastExpression)) { ReportError("Left hand side of assignment must be a variable."); } ExpressionNode assignVar = exprStack.Pop(); ExpressionNode rightSide = ParseExpression(); exprStack.Push(new AssignmentExpression(op, assignVar, rightSide)); break; #endregion #region Generic case TokenID.Default: Advance(); AssertAndAdvance(TokenID.LParen); ParseTypeParameterNode(false, false, false); AssertAndAdvance(TokenID.RParen); exprStack.Push(new DefaultConstantExpression(curTypeParameters[0] )); curTypeParameters = new List<TypeParameterNode>(); ParseContinuingPrimary(); break; #endregion case TokenID.LCurly: ArrayInitializerExpression aie = new ArrayInitializerExpression(curtok); Advance(); exprStack.Push(aie); aie.Expressions = ParseExpressionList(TokenID.RCurly); break; case TokenID.New: Advance(); isNewStatement = true; // TODO : new int*() is allowed ? IType newType = ParseType(); //ApplyTypeParameters(newType); -> not sure, but a type pointer can not be generic! if (curtok.ID == TokenID.LParen) { Advance(); ExpressionList newList = ParseExpressionList(TokenID.RParen); exprStack.Push(new ObjectCreationExpression(newType, newList, newList.RelatedToken)); } else if (curtok.ID == TokenID.LBracket) { ParseArrayCreation(newType); } ParseContinuingPrimary(); isNewStatement = false; break; case TokenID.Ident: //test for local decl bool isDecl = isAfterType(); if (isDecl) { ParseLocalDeclaration(); } else { ExpressionNode expr = ParseIdentifierOrKeyword(false, true, false, false); exprStack.Push(expr); ParseContinuingPrimary(); } break; case TokenID.LParen: Advance(); ParseCastOrGroup(); break; case TokenID.Delegate://anonymous method Advance(); ParseAnonymousMethod(); break; case TokenID.Sizeof: ParseSizeOf(); break; case TokenID.Stackalloc: ParseStackalloc(); break; case TokenID.MinusGreater: // pointer member access ParseContinuingPrimary(); break; default: if (Lexer.IsKeyWord(curtok.ID)) { // in this case a key word is used like a variable name. goto case TokenID.Ident; } else { RecoverFromError("Unhandled case in ParseExpressionSegment ", curtok.ID); // todo: fill out error report } break; } }
public virtual object VisitLocalDeclarationStatement(LocalDeclarationStatement localVariableDeclaration, object data) { stackMap.Push(localVariableDeclaration); localVariableDeclaration.Attributes.AcceptVisitor(this, data); localVariableDeclaration.Type.AcceptVisitor(this, data); localVariableDeclaration.Declarators.AcceptVisitor(this, data); stackMap.Pop(); return null; }