예제 #1
0
파일: Parser.cs 프로젝트: vasilescur/dcc
        private List <Action> ParseBlock()
        {
            List <Action> actions = new List <Action>();

            while (Peek().type != Token.TokenType.BraceClose)
            {
                if (Peek().type == Token.TokenType.Semicolon)
                {
                    Consume(Token.TokenType.Semicolon);
                    continue;
                }

                if (Peek().type == Token.TokenType.BraceOpen)
                {
                    Consume(Token.TokenType.BraceOpen);
                    continue;
                }

                // Instructions
                if (Peek().type == Token.TokenType.FuncName)    // Means we are calling a void function
                {
                    string   fnName = Consume(Token.TokenType.FuncName).content;
                    Function func   = this.program.functions.Find(f => f.name == fnName);

                    List <Expression> arguments = ParseFunctionArguments();
                    Consume(Token.TokenType.Semicolon);

                    actions.Add(new FunctionCall()
                    {
                        function  = func,
                        arguments = arguments
                    });
                }
                else if (Peek().type == Token.TokenType.TypeName)
                {
                    // Declaring a local variable!
                    Token typeName = Consume(Token.TokenType.TypeName);

                    string           newVarName = Consume(Token.TokenType.VarName).content;
                    Variable.VarType newVarType;

                    switch (typeName.content)
                    {
                    case "int": {
                        newVarType = Variable.VarType.Int;
                    } break;

                    case "int*": {
                        newVarType = Variable.VarType.IntPtr;
                    } break;

                    default: {
                        throw new InvalidTypeException(typeName.content);
                    }
                    }

                    Expression initValue;

                    // Are we initializing with a value?
                    if (Peek().type == Token.TokenType.OpAssign)
                    {
                        Consume(Token.TokenType.OpAssign);

                        initValue = ParseExpression();
                    }
                    else
                    {
                        initValue = new LiteralConstant()
                        {
                            value = 0
                        };
                    }

                    Variable newVar = new Variable {
                        name = newVarName,
                        type = newVarType
                    };

                    currentLocals.Add(newVar);
                    actions.Add(new LocalVarDeclaration()
                    {
                        variable  = newVar,
                        initValue = initValue
                    });
                }
                else if (Peek().type == Token.TokenType.VarName)
                {
                    // Variable assignment!
                    Token targetName = Consume(Token.TokenType.VarName);
                    Consume(Token.TokenType.OpAssign);

                    // What value?
                    Expression newVal = ParseExpression();

                    // Is it a global?
                    if (program.globalVars.Any(v => v.name == targetName.content))
                    {
                        actions.Add(new GlobalVarAssignment()
                        {
                            variable = program.globalVars.Find(v => v.name == targetName.content),
                            newValue = newVal
                        });
                    }
                    else
                    {
                        actions.Add(new VarAssignment()
                        {
                            variable = this.currentLocals.Find(v => v.name == targetName.content),
                            newValue = newVal
                        });
                    }
                }
                else if (Peek().type == Token.TokenType.Assembly)
                {
                    Token inlineAsm = Consume(Token.TokenType.Assembly);

                    actions.Add(new InlineAssembly()
                    {
                        code = inlineAsm.content.Split(";").ToList()
                    });
                }
                else if (Peek().type == Token.TokenType.KwIf)
                {
                    Consume(Token.TokenType.KwIf);
                    Consume(Token.TokenType.ParenOpen);

                    Expression condition = ParseExpression();

                    Consume(Token.TokenType.ParenClose);

                    List <Action> body = ParseBlock();

                    if (Peek().type == Token.TokenType.KwElse)
                    {
                        Consume(Token.TokenType.BraceOpen);
                        List <Action> elseBody = ParseBlock();

                        actions.Add(new IfElse()
                        {
                            condition   = condition,
                            ifActions   = body,
                            elseActions = elseBody
                        });
                    }
                    else
                    {
                        actions.Add(new If()
                        {
                            condition = condition,
                            ifActions = body
                        });
                    }
                }
                else if (Peek().type == Token.TokenType.KwWhile)
                {
                    Consume(Token.TokenType.KwWhile);
                    Consume(Token.TokenType.ParenOpen);

                    Expression condition = ParseExpression();

                    List <Action> body = ParseBlock();

                    actions.Add(new While()
                    {
                        condition = condition,
                        actions   = body
                    });
                } //TODO: For
                  //TODO: Goto

                else if (Peek().type == Token.TokenType.KwReturn)
                {
                    Consume(Token.TokenType.KwReturn);

                    if (Peek().type == Token.TokenType.Semicolon)
                    {
                        Consume(Token.TokenType.Semicolon);
                        actions.Add(new ReturnInstruction()
                        {
                            returnValue = null
                        });
                    }
                    else
                    {
                        Expression returnValue = ParseExpression();
                        actions.Add(new ReturnInstruction()
                        {
                            returnValue = returnValue
                        });
                    }
                }
                else
                {
                    throw new UnexpectedTokenException(Consume());
                }
            }

            if (Peek().type == Token.TokenType.BraceClose)
            {
                Consume(Token.TokenType.BraceClose);
            }

            return(actions);
        }
예제 #2
0
파일: Parser.cs 프로젝트: vasilescur/dcc
        private Expression ParseExpression()
        {
            // What's the first token?
            if (Peek().type == Token.TokenType.LiteralInt)
            {
                Expression firstLiteral = new LiteralConstant()
                {
                    value = int.Parse(Consume(Token.TokenType.LiteralInt).content)
                };

                var restOfExpr = RestOfExpr(firstLiteral);

                if (restOfExpr is null)
                {
                    return(firstLiteral);
                }
                else
                {
                    return(restOfExpr);
                }
            }
            else if (Peek().type == Token.TokenType.LiteralChar)
            {
                Expression firstLiteral = new LiteralConstant()
                {
                    value = char.Parse(Consume(Token.TokenType.LiteralChar).content)
                };

                var restOfExpr = RestOfExpr(firstLiteral);

                if (restOfExpr is null)
                {
                    return(firstLiteral);
                }
                else
                {
                    return(restOfExpr);
                }
            }
            else if (Peek().type == Token.TokenType.ParenOpen)
            {
                // Sub-expression
                Consume(Token.TokenType.ParenOpen);
                Expression subExpr = ParseExpression();
                Consume(Token.TokenType.ParenClose);

                var restOfExpr = RestOfExpr(subExpr);

                if (restOfExpr is null)
                {
                    return(subExpr);
                }
                else
                {
                    return(restOfExpr);
                }
            }
            else if (Peek().type == Token.TokenType.VarName)
            {
                Token    varName = Consume(Token.TokenType.VarName);
                Variable var     = this.currentLocals.Find(v => v.name == varName.content);

                var restOfExpr = RestOfExpr(var);

                if (restOfExpr is null)
                {
                    return(var);
                }
                else
                {
                    return(restOfExpr);
                }
            }
            else if (Peek().type == Token.TokenType.FuncName)
            {
                Token    funcName = Consume(Token.TokenType.FuncName);
                Function func     = program.functions.Find(f => f.name == funcName.content);

                List <Expression> ps = ParseFunctionArguments();

                return(new FunctionCall()
                {
                    function = func,
                    arguments = ps
                });
            }

            else
            {
                throw new UnexpectedTokenException(Consume());
            }
        }