public void PrettyPrintAST(ASTNode node) { switch (node.type) { case ASTType.Program: { PrettyPrintAST(node.child); break; } case ASTType.Function: { Console.WriteLine("FUN INT " + node.tokValue.strval + ":"); Console.WriteLine(" " + "params: ()"); Console.WriteLine(" " + "body:"); PrettyPrintAST(node.child); Console.WriteLine(); break; } case ASTType.Return: { Console.Write(" " + " " + "RETURN "); PrettyPrintAST(node.child); break; } case ASTType.Constant: { Console.Write("Int<" + node.tokValue.value.ToString() + ">"); break; } case ASTType.UnOp: { if (node.tokValue.type == TokenType.Minus) { Console.Write("NEG<"); PrettyPrintAST(node.child); Console.Write(">"); } else if (node.tokValue.type == TokenType.BitwiseComp) { Console.Write("NOT<"); PrettyPrintAST(node.child); Console.Write(">"); } else if (node.tokValue.type == TokenType.LogicalNeg) { Console.Write("LOG<"); PrettyPrintAST(node.child); Console.Write(">"); } break; } default: { Console.WriteLine("PrettyPrint: Unsupported AST Type!!!" + Environment.NewLine); break; } } }
private ASTNode FunctionDeclaration() { ScopeBegin(); bool hasReturn = false; ASTNode node = new ASTNode(); node.type = ASTType.Function; Expect(TokenType.IntKeyword); Token currentToken = Expect(TokenType.Main); Token.CopyToken(node.tokValue, currentToken); Expect(TokenType.LParen); Expect(TokenType.RParen); Expect(TokenType.LBrace); node.block_items = new List <ASTNode>(); Token next = lexer.PeekNextToken(); while (next.type != TokenType.RBrace) { ASTNode stmt = BlockItem(); node.block_items.Add(stmt); if (stmt.type == ASTType.Declare) { if (Program.varmap[Program.scopeidx].ContainsKey(stmt.ident.strval)) { Program.Error("There was already a variable declared " + stmt.ident.strval); } Program.varmap[Program.scopeidx].Add(stmt.ident.strval, Program.NextVarMapIdx()); } else if (stmt.type == ASTType.Assign) { if (!Program.VarMapContainsVar(stmt.ident.strval)) { Program.Error("Variable has not been declared " + stmt.ident.strval); } } else if (stmt.type == ASTType.Return) { hasReturn = true; } next = lexer.PeekNextToken(); } //Add in a return for main if one doesn't exist if (!hasReturn && node.tokValue.type == TokenType.Main) { ASTNode retNode = new ASTNode(); retNode.type = ASTType.Return; retNode.tokValue = new Token(); retNode.tokValue.type = TokenType.Ret; retNode.child = new ASTNode(); retNode.child.type = ASTType.Constant; retNode.child.tokValue = new Token(); retNode.child.tokValue.type = TokenType.IntLiteral; retNode.child.tokValue.value = 0; node.block_items.Add(retNode); } Expect(TokenType.RBrace); ScopeEnd(); return(node); }
private ASTNode Statement() { Token next = lexer.PeekNextToken(); ASTNode node = new ASTNode(); if (next.type == TokenType.Ret) { Expect(TokenType.Ret); node.type = ASTType.Return; Token.CopyToken(node.tokValue, next); node.child = Exp(); Expect(TokenType.Semi); } else if (next.type == TokenType.IfKeyword) { Expect(TokenType.IfKeyword); Expect(TokenType.LParen); node.type = ASTType.ConditionalStatement; node.child = Exp(); Expect(TokenType.RParen); node.ifStatement = Statement(); next = lexer.PeekNextToken(); if (next.type == TokenType.ElseKeyword) { Expect(TokenType.ElseKeyword); node.elseStatement = Statement(); } } else if (next.type == TokenType.LBrace) { ScopeBegin(); Expect(TokenType.LBrace); node.type = ASTType.Compound; node.block_items = new List <ASTNode>(); next = lexer.PeekNextToken(); while (next.type != TokenType.RBrace) { ASTNode stmt = BlockItem(); node.block_items.Add(stmt); if (stmt.type == ASTType.Declare) { if (Program.varmap[Program.scopeidx].ContainsKey(stmt.ident.strval)) { Program.Error("There was already a variable declared " + stmt.ident.strval); } Program.varmap[Program.scopeidx].Add(stmt.ident.strval, Program.NextVarMapIdx()); } else if (stmt.type == ASTType.Assign) { if (!Program.VarMapContainsVar(stmt.ident.strval)) { Program.Error("Variable has not been declared " + stmt.ident.strval); } } next = lexer.PeekNextToken(); } Expect(TokenType.RBrace); ScopeEnd(); } else if (next.type == TokenType.ForKeyword) { ScopeBegin(); Expect(TokenType.ForKeyword); Expect(TokenType.LParen); node.type = ASTType.ForStatement; //Initial exp/decl next = lexer.PeekNextToken(); if (next.type == TokenType.IntKeyword) { node.type = ASTType.ForStatement; node.forInitial = VarDeclaration(); } else if (next.type == TokenType.Semi) { ASTNode constNode = new ASTNode(); constNode.type = ASTType.Constant; constNode.tokValue = new Token(); constNode.tokValue.value = 1; node.forInitial = constNode; Expect(TokenType.Semi); } else { node.forInitial = Exp(); Expect(TokenType.Semi); } if (node.forInitial.type == ASTType.Declare) { if (Program.varmap[Program.scopeidx].ContainsKey(node.forInitial.ident.strval)) { Program.Error("There was already a variable declared " + node.forInitial.ident.strval); } Program.varmap[Program.scopeidx].Add(node.forInitial.ident.strval, Program.NextVarMapIdx()); } else if (node.forInitial.type == ASTType.Assign) { if (!Program.VarMapContainsVar(node.forInitial.ident.strval)) { Program.Error("Variable has not been declared " + node.forInitial.ident.strval); } } //For loop condition next = lexer.PeekNextToken(); if (next.type == TokenType.Semi) { ASTNode constNode = new ASTNode(); constNode.type = ASTType.Constant; constNode.tokValue = new Token(); constNode.tokValue.value = 1; node.forCondition = constNode; Expect(TokenType.Semi); } else { node.forCondition = Exp(); Expect(TokenType.Semi); } //For loop post expr next = lexer.PeekNextToken(); if (next.type == TokenType.RParen) { ASTNode constNode = new ASTNode(); constNode.type = ASTType.Constant; constNode.tokValue = new Token(); constNode.tokValue.value = 1; node.forPostExpr = constNode; Expect(TokenType.RParen); } else { node.forPostExpr = Exp(); Expect(TokenType.RParen); } node.forBody = Statement(); ScopeEnd(); } else if (next.type == TokenType.WhileKeyword) { Expect(TokenType.WhileKeyword); Expect(TokenType.LParen); node.type = ASTType.WhileStatement; //While loop condition node.whileCondition = Exp(); Expect(TokenType.RParen); node.whileBody = Statement(); } else if (next.type == TokenType.DoKeyword) { Expect(TokenType.DoKeyword); node.doBody = Statement(); node.type = ASTType.DoStatement; Expect(TokenType.WhileKeyword); node.doCondition = Exp(); Expect(TokenType.Semi); } else if (next.type == TokenType.BreakKeyword) { Expect(TokenType.BreakKeyword); Expect(TokenType.Semi); node.type = ASTType.Break; } else if (next.type == TokenType.ContinueKeyword) { Expect(TokenType.ContinueKeyword); Expect(TokenType.Semi); node.type = ASTType.Continue; } else if (next.type == TokenType.Semi) { node.type = ASTType.NullStatement; Expect(TokenType.Semi); } else { node = Exp(); Expect(TokenType.Semi); } return(node); }