/// <summary> /// Constructs an AST that represents a root namespace with a single class, Test, containing a single /// method, Main, which contains a single statement that writes "hello" to the console. /// </summary> private RootNamespaceDeclaration ConstructRootNamespace() { //Normally this routine will use a parser to parse the contents of this.SourceLocation. //However, this sample just illustrates how an AST can be constructed and then compiled to a PE file, //so parsing is not necessary. var nameTable = this.Helper.Compilation.NameTable; //Note that this is top down constrution, exploiting the mutability of the member lists. //Some parsers may need to do bottom up construction, which is also supported. var namespaceMembers = new List <INamespaceDeclarationMember>(1); var result = new RootNamespaceDeclaration(this, null, namespaceMembers, this.sourceLocation); var typeName = nameTable.GetNameFor("Test"); var typeNameDeclaration = new NameDeclaration(typeName, this.sourceLocation); var baseTypes = new List <TypeExpression>(0); var typeMembers = new List <ITypeDeclarationMember>(1); var classDeclaration = new NamespaceClassDeclaration(null, TypeDeclaration.Flags.None, typeNameDeclaration, null, baseTypes, typeMembers, this.sourceLocation); namespaceMembers.Add(classDeclaration); var voidExpr = TypeExpression.For(this.Helper.Compilation.PlatformType.SystemVoid); var methodName = nameTable.GetNameFor("Main"); var methodNameDeclaration = new NameDeclaration(methodName, this.sourceLocation); var statements = new List <Statement>(1); var body = new BlockStatement(statements, this.sourceLocation); var methodDeclaration = new MethodDeclaration(null, MethodDeclaration.Flags.Static, TypeMemberVisibility.Public, voidExpr, null, methodNameDeclaration, null, null, null, body, this.sourceLocation); typeMembers.Add(methodDeclaration); var system = new SimpleName(nameTable.GetNameFor("System"), this.sourceLocation, false); var console = new SimpleName(nameTable.GetNameFor("Console"), this.sourceLocation, false); var systemConsole = new QualifiedName(system, console, this.sourceLocation); var writeLine = new SimpleName(nameTable.GetNameFor("WriteLine"), this.sourceLocation, false); var methodToCall = new QualifiedName(systemConsole, writeLine, this.sourceLocation); var arguments = new List <Expression>(1); arguments.Add(new CompileTimeConstant("hello", this.sourceLocation)); var methodCall = new MethodCall(methodToCall, arguments, this.sourceLocation); var callStatement = new ExpressionStatement(methodCall, this.sourceLocation.SourceDocument.GetSourceLocation(0, 5)); statements.Add(callStatement); //The statements above do only the first phase initialization of the AST. The second phase //occurs as the AST is traversed from the top down. return(result); }
private void ParseNamespaceClassDeclaration(List<INamespaceDeclarationMember> namespaceMembers, List<SourceCustomAttribute>/*?*/ attributes, TypeDeclaration.Flags flags, SourceLocationBuilder sctx, TokenSet followers) //^ requires this.currentToken == Token.Class; //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { this.GetNextToken(); if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.HandleError(Error.ExpectedIdentifier); NameDeclaration name = this.ParseNameDeclaration(); List<Ast.GenericTypeParameterDeclaration> genericParameters = new List<Ast.GenericTypeParameterDeclaration>(); List<TypeExpression> baseTypes = new List<TypeExpression>(); List<ITypeDeclarationMember> members = new List<ITypeDeclarationMember>(); NamespaceClassDeclaration type = new NamespaceClassDeclaration(attributes, flags, name, genericParameters, baseTypes, members, sctx); namespaceMembers.Add(type); this.ParseRestOfTypeDeclaration(sctx, type, genericParameters, baseTypes, members, followers); }