// statements private void ParseStatement(NodeCollection<StatementNode> node) { // label ident : colon // localDecl type : ident // block LCurly // empty Semi // expression // -invoke pexpr : LParen // -objCre new : type // -assign uexpr : assignOp // -postInc pexpr : ++ // -postDec pexpr : -- // -preInc ++ : uexpr // -preDec -- : uexpr // // selection if : LParen // switch : LParen // // iteration while : LParen // do : LParen // for : LParen // foreach : LParen // // jump break : Semi // continue: Semi // goto : ident | case | default // return : expr // throw : expr // // try try : block // checked checked : block // unchecked unchecked : block // lock lock : LParen // using using : LParen switch (curtok.ID) { case TokenID.LCurly: // block BlockStatement newBlock = new BlockStatement(isUnsafe > 0, curtok); newBlock.IsUnsafe = isUnsafe > 0; node.Add(newBlock); ParseBlock(newBlock); break; case TokenID.Semi: // empty statement node.Add(new StatementNode(curtok)); Advance(); break; case TokenID.If: // If statement node.Add(ParseIf()); break; case TokenID.Switch: // Switch statement node.Add(ParseSwitch()); break; case TokenID.While: // While statement node.Add(ParseWhile()); break; case TokenID.Do: // Do statement node.Add(ParseDo()); break; case TokenID.For: // For statement node.Add(ParseFor()); break; case TokenID.Foreach: // Foreach statement node.Add(ParseForEach()); break; case TokenID.Break: // Break statement node.Add(ParseBreak()); break; case TokenID.Continue: // Continue statement node.Add(ParseContinue()); break; case TokenID.Goto: // Goto statement node.Add(ParseGoto()); break; case TokenID.Return: // Return statement node.Add(ParseReturn()); break; case TokenID.Throw: // Throw statement node.Add(ParseThrow()); break; case TokenID.Try: // Try statement node.Add(ParseTry()); break; case TokenID.Checked: // Checked statement node.Add(ParseChecked()); break; case TokenID.Unchecked: // Unchecked statement node.Add(ParseUnchecked()); break; case TokenID.Lock: // Lock statement node.Add(ParseLock()); break; case TokenID.Using: // Using statement node.Add(ParseUsing()); break; case TokenID.Const: isLocalConst = true; Advance(); break; case TokenID.Yield: node.Add(ParseYieldStatement()); break; case TokenID.Void: 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: case TokenID.StringLiteral: case TokenID.HexLiteral: case TokenID.IntLiteral: case TokenID.UIntLiteral: case TokenID.LongLiteral: case TokenID.ULongLiteral: case TokenID.TrueLiteral: case TokenID.FalseLiteral: case TokenID.NullLiteral: case TokenID.LParen: case TokenID.DecimalLiteral: case TokenID.RealLiteral: case TokenID.CharLiteral: case TokenID.PlusPlus: // PreInc statement case TokenID.MinusMinus:// PreDec statement case TokenID.This: case TokenID.Base: case TokenID.New: // creation statement ExpressionNode rexpr = ParseExpression(); if (rexpr is LocalDeclarationStatement ) { PopLocalDeclaration(rexpr); } else { ExpressionStatement enode = new ExpressionStatement(rexpr ); node.Add(enode); } if (curtok.ID == TokenID.Semi) { Advance(); } break; case TokenID.Ident: if (curTokNode != null && curTokNode.Next != null && curTokNode.Value.ID == TokenID.Colon) { LabeledStatement lsnode = new LabeledStatement(curtok); lsnode.Name = (IdentifierExpression)ParseIdentifierOrKeyword(false, true, false, false); AssertAndAdvance(TokenID.Colon); ParseStatement(lsnode.Statements); node.Add(lsnode); } else { rexpr = ParseExpression(); if (rexpr is LocalDeclarationStatement) { PopLocalDeclaration(rexpr); } else { ExpressionStatement enode = new ExpressionStatement(rexpr ); node.Add(enode); } } if (curtok.ID == TokenID.Semi) { Advance(); } break; case TokenID.Unsafe: // preprocessor directives node.Add(ParseUnsafeCode()); break; case TokenID.Fixed: // preprocessor directives node.Add(ParseFixedStatement()); break; case TokenID.Star: // dereference variable // introduced because of the mono file test-406.cs //private static uint DoOp2 (uint *u) { // *(u) += 100; // return *u; //} node.Add(new ExpressionStatement(ParseExpression())); break; default: if (Lexer.IsKeyWord(curtok.ID)) { // in this case a key word is used like a variable name. goto case TokenID.Ident; } else { Console.WriteLine("Unhandled case in statement parsing: \"" + curtok.ID + "\" in line: " + lineCount); // this is almost always an expression ExpressionStatement dnode = new ExpressionStatement(ParseExpression()); node.Add(dnode); if (curtok.ID == TokenID.Semi) { Advance(); } } break; } }
// statements private StatementNode ParseStatement() { // label ident : colon // localDecl type : ident // block LCurly // empty Semi // expression // -invoke pexpr : LParen // -objCre new : type // -assign uexpr : assignOp // -postInc pexpr : ++ // -postDec pexpr : -- // -preInc ++ : uexpr // -preDec -- : uexpr // // selection if : LParen // switch : LParen // // iteration while : LParen // do : LParen // for : LParen // foreach : LParen // // jump break : Semi // continue: Semi // goto : ident | case | default // return : expr // throw : expr // // try try : block // checked checked : block // unchecked unchecked : block // lock lock : LParen // using using : LParen StatementNode node; mayBeLocalDecl = false; switch (curtok.ID) { case TokenID.LCurly: // block BlockStatement newBlock = new BlockStatement(isUnsafe > 0, curtok); newBlock.IsUnsafe = isUnsafe > 0; node = newBlock; ParseBlock(newBlock); break; case TokenID.Semi: // empty statement node = new StatementNode(curtok); Advance(); // over semi break; case TokenID.If: // If statement node = ParseIf(); break; case TokenID.Switch: // Switch statement node = ParseSwitch(); break; case TokenID.While: // While statement node = ParseWhile(); break; case TokenID.Do: // Do statement node = ParseDo(); break; case TokenID.For: // For statement node = ParseFor(); break; case TokenID.Foreach: // Foreach statement node = ParseForEach(); break; case TokenID.Break: // Break statement node = ParseBreak(); break; case TokenID.Continue: // Continue statement node = ParseContinue(); break; case TokenID.Goto: // Goto statement node = ParseGoto(); break; case TokenID.Return: // Return statement node = ParseReturn(); break; case TokenID.Throw: // Throw statement node = ParseThrow(); break; case TokenID.Try: // Try statement node = ParseTry(); break; case TokenID.Checked: // Checked statement node = ParseChecked(); break; case TokenID.Unchecked: // Unchecked statement node = ParseUnchecked(); break; case TokenID.Lock: // Lock statement node = ParseLock(); break; case TokenID.Using: // Using statement node = ParseUsing(); break; case TokenID.Const: node = null; isLocalConst = true; Advance(); // over const break; case TokenID.StringLiteral: case TokenID.HexLiteral: case TokenID.IntLiteral: case TokenID.UIntLiteral: case TokenID.LongLiteral: case TokenID.ULongLiteral: case TokenID.True: case TokenID.False: case TokenID.Null: case TokenID.LParen: case TokenID.DecimalLiteral: case TokenID.RealLiteral: case TokenID.CharLiteral: case TokenID.PlusPlus: // PreInc statement case TokenID.MinusMinus:// PreDec statement case TokenID.This: case TokenID.Base: case TokenID.New: // creation statement node = new ExpressionStatement(ParseExpression()); AssertAndAdvance(TokenID.Semi); break; case TokenID.Void: // TODO: Special case void 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: { TypeNode type = new PredefinedTypeNode(curtok.ID, curtok); Advance(); bool mustBeDecl = false; if (curtok.ID == TokenID.Question) { Advance(); type.IsNullableType = true; mustBeDecl = true; } else if (curtok.ID == TokenID.Star) { do { Advance(); type = new TypePointerNode(type); } while (curtok.ID == TokenID.Star); mustBeDecl = true; } if (curtok.ID == TokenID.LBracket) { do { Advance(); // over lbracket int commaCount = 0; while (curtok.ID == TokenID.Comma) { Advance(); commaCount++; } type.RankSpecifiers.Add(commaCount); AssertAndAdvance(TokenID.RBracket); } while (curtok.ID == TokenID.LBracket); mustBeDecl = true; } if (curtok.ID == TokenID.Ident) { node = ParseLocalDeclarationStatement(type); } else if (mustBeDecl) { RecoverFromError(TokenID.Ident); node = new StatementNode(curtok); } else { ExpressionNode expr = ParseSubexpression(1, type); if (!(expr is InvocationExpression)) { ReportError("Statement must be an invocation", expr.RelatedToken); } node = new ExpressionStatement(expr); } AssertAndAdvance(TokenID.Semi); break; } case TokenID.Ident: { if (strings[curtok.Data] == "yield") { node = ParseYieldStatement(); break; } ExpressionNode expr = ParseExpressionOrType(true); if (expr is IdentifierExpression && curtok.ID == TokenID.Colon) { Advance(); // advance over colon LabeledStatement lsnode = new LabeledStatement(curtok); lsnode.Name = (IdentifierExpression)expr; lsnode.Statement = ParseStatement(); node = lsnode; } else { if (expr is TypeNode) node = ParseLocalDeclarationStatement((IType)expr); else node = new ExpressionStatement(expr); AssertAndAdvance(TokenID.Semi); } /* ExpressionNode expr = ParseIdentifierOrKeyword(false, true, false, false); IdentifierExpression idExpr = expr as IdentifierExpression; if(idExpr != null && curtok.ID == TokenID.Colon) { Advance(); // advance over colon LabeledStatement lsnode = new LabeledStatement(curtok); lsnode.Name = idExpr; lsnode.Statement = ParseStatement(); node = lsnode; } else { mayBeLocalDecl = true; if(curtok.ID == TokenID.ColonColon) { Advance(); if(curtok.ID != TokenID.Ident) { RecoverFromError(TokenID.Ident); node = null; break; } expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.ColonColon); Advance(); // over ident } while(curtok.ID == TokenID.Dot) { Advance(); if(curtok.ID != TokenID.Ident) { RecoverFromError(TokenID.Ident); node = null; break; } expr = new MemberAccessExpression(expr, new IdentifierExpression(strings[curtok.Data], curtok), TokenID.Dot); Advance(); // over ident } if(ParsePossibleTypeParameterNode(false, false, false)) { expr = new TypeNode(expr); ApplyTypeParameters((TypeNode) expr); } if(curtok.ID == TokenID.LBracket) { Advance(); if(curtok.ID == TokenID.Comma || curtok.ID == TokenID.RBracket) { TypeNode typeNode = expr as TypeNode; if(typeNode == null) expr = typeNode = new TypeNode(expr); while(true) { int numCommas = 0; while(curtok.ID == TokenID.Comma) { Advance(); numCommas++; } AssertAndAdvance(TokenID.RBracket); typeNode.RankSpecifiers.Add(numCommas); if(curtok.ID != TokenID.LBracket) break; Advance(); } } else { ExpressionList exprList = ParseExpressionList(); expr = new ElementAccessExpression(expr, exprList); AssertAndAdvance(TokenID.RBracket); } } if(curtok.ID == TokenID.Question) { Advance(); TypeNode typeNode = expr as TypeNode; if(typeNode == null) expr = typeNode = new TypeNode(expr); typeNode.IsNullableType = true; } else { while(curtok.ID == TokenID.Star) { Advance(); expr = new TypePointerNode(expr); } }*/ // expr = ParseSubexpression(PRECEDENCE_PRIMARY, expr); /* exprStack.Push(expr); ParseContinuingPrimary(); expr = exprStack.Pop();*/ /* if((expr is IdentifierExpression || expr is MemberAccessExpression || expr is TypeNode) && (curtok.ID == TokenID.Ident || curtok.ID == TokenID.Star || curtok.ID == TokenID.Question)) { node = ParseLocalDeclarationStatement((IType) expr); } else node = new ExpressionStatement(ParseSubexpression(1, expr)); AssertAndAdvance(TokenID.Semi); }*/ break; } case TokenID.Unsafe: // preprocessor directives node = ParseUnsafeCode(); break; case TokenID.Fixed: // preprocessor directives node = ParseFixedStatement(); break; case TokenID.Star: // dereference variable // introduced because of the mono file test-406.cs //private static uint DoOp2 (uint *u) { // *(u) += 100; // return *u; //} node = new ExpressionStatement(ParseExpression()); AssertAndAdvance(TokenID.Semi); break; case TokenID.SingleComment: case TokenID.MultiComment: case TokenID.DocComment: node = new CommentStatement(curtok, strings[curtok.Data], curtok.ID != TokenID.SingleComment); Advance(); // over comment token break; default: { Console.WriteLine("Unhandled case in statement parsing: \"" + curtok.ID + "\" in line: " + lineCount); // this is almost always an expression ExpressionStatement dnode = new ExpressionStatement(ParseExpression()); node = dnode; if (curtok.ID == TokenID.Semi) { Advance(); } break; } } return node; }
private void BuilderType(InterfaceNode type,NamespaceNode nspace) { DDW.ClassNode cls = new ClassNode(new Token(TokenID.Public)); cls.Modifiers = Modifier.Public; cls.BaseClasses.Add(new TypeNode(new IdentifierExpression("Peanut.Mappings.DataObject", new Token(TokenID.Typeof)))); foreach (AttributeNode attr in type.Attributes) { cls.Attributes.Add(attr); } mTableName = GetTableName(type); mClassName = type.Name.Identifier.Substring(1, type.Name.Identifier.Length - 1); cls.Name = new IdentifierExpression(mClassName, new Token(TokenID.String|TokenID.Public)); cls.IsPartial = true; nspace.Classes.Add(cls); StringBuilder sb = new StringBuilder(); sb.AppendLine("///<summary>"); sb.AppendLine("///Peanut Generator Copyright @ FanJianHan 2010-2013"); sb.AppendLine("///website:http://www.ikende.com"); if (!string.IsNullOrEmpty(type.Comment)) { sb.AppendLine(type.Comment); } StringReader sr = new StringReader(type.DocComment); string value = sr.ReadLine(); while (value != null) { if (value.IndexOf("summary>") == -1) { sb.AppendLine(value); } value = sr.ReadLine(); } sb.AppendLine("///</summary>"); cls.DocComment = sb.ToString(); foreach (InterfacePropertyNode property in type.Properties) { string propertyname = property.Names[0].GenericIdentifier; string fieldname= GetFieldName(property); FieldNode field = new FieldNode(new Token(TokenID.False)); field.Modifiers = Modifier.Private; QualifiedIdentifierExpression name = new QualifiedIdentifierExpression(new Token(TokenID.String)); name.Expressions.Add(new IdentifierExpression("m" + property.Names[0].GenericIdentifier, new Token(TokenID.String))); field.Names.Add(name); field.Type = property.Type; cls.Fields.Add(field); IType fieldtype=new TypeNode(new IdentifierExpression("Peanut.FieldInfo<"+((TypeNode)property.Type).GenericIdentifier+">", new Token(TokenID.Typeof))); field = new FieldNode(new Token(TokenID.False)); field.Modifiers = Modifier.Public| Modifier.Static; NodeCollection<ArgumentNode> args = new NodeCollection<ArgumentNode>(); args.Add(new ArgumentNode(new Token(TokenID.String))); args.Add(new ArgumentNode(new Token(TokenID.String))); args[0].Expression = new StringPrimitive(mTableName, new Token(TokenID.String)); args[1].Expression = new StringPrimitive(fieldname, new Token(TokenID.String)); name = new QualifiedIdentifierExpression(new Token(TokenID.String)); name.Expressions.Add(new AssignmentExpression(TokenID.Equal, new IdentifierExpression(propertyname.Substring(0, 1).ToLower() + propertyname.Substring(1, propertyname.Length - 1) , new Token(TokenID.String)), new ObjectCreationExpression(fieldtype, args, new Token(TokenID.New)))); field.Names.Add(name); field.Type = fieldtype; cls.Fields.Add(field); PropertyNode pn = new PropertyNode(new Token(TokenID.Newline)); foreach (AttributeNode attr in property.Attributes) { pn.Attributes.Add(attr); } pn.Names = property.Names; pn.Modifiers = Modifier.Public | Modifier.Virtual; pn.Type = property.Type; pn.Setter = new AccessorNode(true, new Token(TokenID.Newline)); pn.Setter.Kind = "set"; ExpressionStatement setvalue = new ExpressionStatement( new AssignmentExpression(TokenID.Equal, new IdentifierExpression("m" + property.Names[0].GenericIdentifier, new Token(TokenID.String)) , new IdentifierExpression("value", new Token(TokenID.String))) ); pn.Setter.StatementBlock.Statements.Add(setvalue); args = new NodeCollection<ArgumentNode>(); args.Add(new ArgumentNode(new Token(TokenID.String))); args[0].Expression = new StringPrimitive(propertyname, new Token(TokenID.String)); QualifiedIdentifierExpression invoke = new QualifiedIdentifierExpression(new Token(TokenID.String)); invoke.Expressions.Add(new IdentifierExpression("EntityState", new Token(TokenID.String))); invoke.Expressions.Add(new InvocationExpression(new IdentifierExpression("FieldChange", new Token(TokenID.Default)), args)); setvalue = new ExpressionStatement(invoke); pn.Setter.StatementBlock.Statements.Add(setvalue); pn.Getter = new AccessorNode(true, new Token(TokenID.Newline)); pn.Getter.Kind = "get"; ReturnStatement rs = new ReturnStatement(new Token(TokenID.Return)); rs.ReturnValue = new IdentifierExpression("m" + property.Names[0].GenericIdentifier, new Token(TokenID.String)); pn.Getter.StatementBlock.Statements.Add(rs); sb = new StringBuilder(); sb.AppendLine("///<summary>"); sb.AppendLine("///Type:" + ((TypeNode)property.Type).GenericIdentifier); if (!string.IsNullOrEmpty(property.Comment)) { sb.AppendLine(type.Comment); } sr = new StringReader(property.DocComment); value = sr.ReadLine(); while (value != null) { if (value.IndexOf("summary>") == -1) { sb.AppendLine(value); } value = sr.ReadLine(); } sb.AppendLine("///</summary>"); pn.DocComment = sb.ToString(); cls.Properties.Add(pn); } //CodeTypeDeclaration entity = new CodeTypeDeclaration(mClassName); //CodeCommentStatement comm; //cns.Types.Add(entity); //comm = new CodeCommentStatement("<summary>"); //comm.Comment.DocComment = true; //entity.Comments.Add(comm); //comm = new CodeCommentStatement("Peanut Generator Copyright © FanJianHan 2010-2013"); //comm.Comment.DocComment = true; //entity.Comments.Add(comm); //comm = new CodeCommentStatement("website:http://www.ikende.com"); //comm.Comment.DocComment = true; //entity.Comments.Add(comm); //if (!string.IsNullOrEmpty(type.Comment)) //{ // comm = new CodeCommentStatement(type.Comment); // comm.Comment.DocComment = true; // entity.Comments.Add(comm); //} //StringReader sr = new StringReader(type.DocComment); //string value = sr.ReadLine(); //while (value != null) //{ // if (value.IndexOf("summary>") == -1) // { // comm = new CodeCommentStatement(value.Replace("///", "")); // comm.Comment.DocComment = true; // entity.Comments.Add(comm); // } // value = sr.ReadLine(); //} //comm = new CodeCommentStatement("</summary>"); //comm.Comment.DocComment = true; //entity.Comments.Add(comm); //// } //entity.BaseTypes.Add(new CodeTypeReference("Peanut.Mappings.DataObject")); //entity.BaseTypes.Add(new CodeTypeReference(type.Name.Identifier)); //entity.Attributes = MemberAttributes.Public; //entity.IsPartial = true; //entity.CustomAttributes.Add(new CodeAttributeDeclaration("Serializable")); //entity.IsClass = true; //foreach (AttributeNode aitem in type.Attributes) //{ // CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(aitem.Name.GenericIdentifier); // entity.CustomAttributes.Add(attribute); // if (attribute.Name.ToLower() == "table") // { // if (aitem.Arguments.Count > 0) // { // DDW.StringPrimitive pe = (DDW.StringPrimitive)aitem.Arguments[0].Expression; // if (pe != null) // { // mTableName = pe.Value.ToString(); // } // else // { // mTableName = mClassName; // } // attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(mTableName))); // } // else // { // mTableName = mClassName; // } // } //} //foreach (InterfacePropertyNode mitem in type.Properties) //{ // BuilderProperty(entity, mitem); //} }
public virtual object VisitExpressionStatement(ExpressionStatement expressionStatement, object data) { stackMap.Push(expressionStatement); expressionStatement.Expression.AcceptVisitor(this, data); stackMap.Pop(); return null; }