コード例 #1
0
ファイル: Parser.cs プロジェクト: mcrabil/myc
        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;
            }
            }
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: mcrabil/myc
        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);
        }
コード例 #3
0
ファイル: Parser.cs プロジェクト: mcrabil/myc
        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);
        }