diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-17 22:38:08 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-17 22:38:08 +0000 |
commit | a9663b327230e08a6bc5cfe4f20ed8d066f33338 (patch) | |
tree | 4a47654b4fd29300ebee876fa1d9f79dac52499f | |
parent | f35548ee7d4c54558c38d63df7e2572150c28d22 (diff) | |
download | Compiler-a9663b327230e08a6bc5cfe4f20ed8d066f33338.tar.gz Compiler-a9663b327230e08a6bc5cfe4f20ed8d066f33338.zip |
Creating if statement
-rw-r--r-- | Notes.org | 3 | ||||
-rw-r--r-- | c_compiler/include/expression.hpp | 10 | ||||
-rw-r--r-- | c_compiler/include/statement.hpp | 3 | ||||
-rw-r--r-- | c_compiler/src/c_lexer.flex | 4 | ||||
-rw-r--r-- | c_compiler/src/c_parser.y | 13 | ||||
-rw-r--r-- | c_compiler/src/expression.cpp | 132 | ||||
-rw-r--r-- | c_compiler/src/statement.cpp | 11 | ||||
-rw-r--r-- | c_compiler/test/in/IfElse.c | 8 |
8 files changed, 121 insertions, 63 deletions
@@ -128,7 +128,8 @@ - The declaration class should only be in charge of storing it in the right location in the stack and adding that to the bindings. **** TODO Add more expressions - CLOCK: [2017-03-17 Fri 17:08] + CLOCK: [2017-03-17 Fri 20:59] + CLOCK: [2017-03-17 Fri 17:08]--[2017-03-17 Fri 20:59] => 3:51 CLOCK: [2017-03-17 Fri 13:21]--[2017-03-17 Fri 15:43] => 2:22 Expressions like > or < or == etc.. diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 19d2c4f..9a22ce7 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -45,6 +45,8 @@ public: OperationExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0; + + void evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const; }; @@ -130,8 +132,10 @@ public: class ShiftExpression : public OperationExpression { +private: + std::string operator_; public: - ShiftExpression(Expression* lhs, Expression* rhs); + ShiftExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; }; @@ -139,8 +143,10 @@ public: class RelationalExpression : public OperationExpression { +private: + std::string operator_; public: - RelationalExpression(Expression* lhs, Expression* rhs); + RelationalExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; }; diff --git a/c_compiler/include/statement.hpp b/c_compiler/include/statement.hpp index fe0597c..fe509c2 100644 --- a/c_compiler/include/statement.hpp +++ b/c_compiler/include/statement.hpp @@ -51,10 +51,11 @@ public: class SelectionStatement : public Statement { protected: + ExpressionPtr condition_; StatementPtr if_; StatementPtr else_; public: - SelectionStatement(Statement* _if = nullptr, Statement* _else = nullptr); + SelectionStatement(Expression* condition, Statement* _if, Statement* _else = nullptr); virtual void print() const; virtual void printXml() const; diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex index c0ab549..a761343 100644 --- a/c_compiler/src/c_lexer.flex +++ b/c_compiler/src/c_lexer.flex @@ -57,8 +57,8 @@ ALL . [&] { return T_AND; } [=][=] { yylval.string = new std::string(yytext); return T_EQUALITY_OP; } [!][=] { yylval.string = new std::string(yytext); return T_EQUALITY_OP; } -([<>][=])|[<>] { return T_REL_OP; } -[<>][<>] { return T_SHIFT_OP; } +([<>][=])|[<>] { yylval.string = new std::string(yytext); return T_REL_OP; } +[<>][<>] { yylval.string = new std::string(yytext); return T_SHIFT_OP; } [*] { yylval.string = new std::string(yytext); return T_MULT; } [\/] { yylval.string = new std::string(yytext); return T_DIV; } [%] { yylval.string = new std::string(yytext); return T_REM; } diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index 7846e5d..721a6e3 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -69,7 +69,8 @@ void yyerror(const char *); %type <number> T_INT_CONST %type <string> T_IDENTIFIER ASSIGN_OPER T_ASSIGN_OPER T_EQ T_AND T_ADDSUB_OP T_TILDE T_NOT - T_MULT T_DIV T_REM T_EQUALITY_OP MultDivRemOP UnaryOperator DeclarationSpec + T_MULT T_DIV T_REM T_EQUALITY_OP T_REL_OP T_SHIFT_OP MultDivRemOP UnaryOperator + DeclarationSpec %start ROOT @@ -198,8 +199,8 @@ CompoundStatement_2: ; SelectionStatement: - T_IF T_LRB Expression T_RRB Statement { $$ = new SelectionStatement($5); } - | T_IF T_LRB Expression T_RRB Statement T_ELSE Statement { $$ = new SelectionStatement($5, $7); } + T_IF T_LRB Expression T_RRB Statement { $$ = new SelectionStatement($3, $5); } + | T_IF T_LRB Expression T_RRB Statement T_ELSE Statement { $$ = new SelectionStatement($3, $5, $7); } ; ExpressionStatement: @@ -268,12 +269,14 @@ EqualityExpression: RelationalExpression: ShiftExpression { $$ = $1; } - | RelationalExpression T_REL_OP ShiftExpression { $$ = new RelationalExpression($1, $3); } + | RelationalExpression T_REL_OP ShiftExpression + { $$ = new RelationalExpression($1, *$2, $3); delete $2; } ; ShiftExpression: AdditiveExpression { $$ = $1; } - | ShiftExpression T_SHIFT_OP AdditiveExpression { $$ = new ShiftExpression($1, $3); } + | ShiftExpression T_SHIFT_OP AdditiveExpression + { $$ = new ShiftExpression($1, *$2, $3); } ; AdditiveExpression: diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 43230c6..b7965eb 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -56,6 +56,25 @@ OperationExpression::OperationExpression(Expression* lhs, Expression* rhs) : lhs_(lhs), rhs_(rhs) {} +void OperationExpression::evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const +{ + // I can just evaluate the lhs with the same entry stack position + lhs_->printAsm(bindings, label_count); + + // store this stack position + int lhs_stack_position = bindings.currentExpressionStackPosition(); + + // now have to increase the expression stack position for the rhs + bindings.nextExpressionStackPosition(); + rhs_->printAsm(bindings, label_count); + + // now I have them evaluated at two positions in the stack and can load both into registers + // $2 and $3 + + std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl; + std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; +} + // PostfixExpression definition @@ -162,21 +181,7 @@ AdditiveExpression::AdditiveExpression(Expression* lhs, const std::string& _oper VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { - // I can just evaluate the lhs with the same entry stack position - lhs_->printAsm(bindings, label_count); - - // store this stack position - int lhs_stack_position = bindings.currentExpressionStackPosition(); - - // now have to increase the expression stack position for the rhs - bindings.nextExpressionStackPosition(); - rhs_->printAsm(bindings, label_count); - - // now I have them evaluated at two positions in the stack and can load both into registers - // $2 and $3 - - std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl; - std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + evaluateExpression(bindings, label_count); // TODO currently using signed and sub because I only have signed numbers implemented // must update this as I add more types @@ -188,7 +193,7 @@ VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings binding std::cerr << "Don't recognize symbol: '" << operator_ << "'" << std::endl; // now I have to store it back into the original stack position - std::cout << "\tsw\t$2," << lhs_stack_position << "($fp)" << std::endl; + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; return bindings; } @@ -203,18 +208,7 @@ MultiplicativeExpression::MultiplicativeExpression(Expression* lhs, const std::s VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { - // I can just evaluate lhs without increasing stack count - lhs_->printAsm(bindings, label_count); - - // store current stack position - int lhs_stack_position = bindings.currentExpressionStackPosition(); - - // increase stack position to store next result in - bindings.nextExpressionStackPosition(); - rhs_->printAsm(bindings, label_count); - - std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl; - std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + evaluateExpression(bindings, label_count); // then perform the right operation if(operator_ == "*") @@ -226,10 +220,10 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b else std::cout << "\tmfhi\t$2" << std::endl; } else - std::cerr << "Don't recognize symbol '" << operator_ << "'" << std::endl; + std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; // finally store result back into the stack position - std::cout << "\tsw\t$2," << lhs_stack_position << "($fp)" << std::endl; + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; return bindings; } @@ -237,24 +231,55 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b // ShiftExpression definition -ShiftExpression::ShiftExpression(Expression* lhs, Expression* rhs) - : OperationExpression(lhs, rhs) +ShiftExpression::ShiftExpression(Expression* lhs, const std::string& _operator, Expression* rhs) + : OperationExpression(lhs, rhs), operator_(_operator) {} VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + evaluateExpression(bindings, label_count); + + if(operator_ == "<<") { + std::cout << "\tsll\t$2,$2,$3\n"; + } else if(operator_ == ">>") { + std::cout << "\tsra\t$2,$2,$3\n"; + } else { + std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; + } + + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + return bindings; } // RelationalExpression definition -RelationalExpression::RelationalExpression(Expression* lhs, Expression* rhs) - : OperationExpression(lhs, rhs) +RelationalExpression::RelationalExpression(Expression* lhs, const std::string& _operator, Expression* rhs) + : OperationExpression(lhs, rhs), operator_(_operator) {} VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + evaluateExpression(bindings, label_count); + + if(operator_ == "<") { + std::cout << "\tslt\t$2,$2,$3\n"; + } else if(operator_ == ">") { + std::cout << "\tslt\t$2,$3,$2\n"; + } else if(operator_ == "<=") { + std::cout << "\tslt\t$2,$3,$2\n\txori\t$2,$2,0x1\n"; + } else if(operator_ == ">=") { + std::cout << "\tslt\t$2,$2,$3\n\txori\t$2,$2,0x1\n"; + } else { + std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; + } + + // TODO might get rid of this + std::cout << "\tandi\t$2,$2,0x00ff\n"; + + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + return bindings; } @@ -267,19 +292,22 @@ EqualityExpression::EqualityExpression(Expression* lhs, const std::string& _oper VariableStackBindings EqualityExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { - (void)label_count; + evaluateExpression(bindings, label_count); - // I can just evaluate lhs without increasing stack count - lhs_->printAsm(bindings, label_count); + std::cout << "\txor\t$2,$2,$3\n"; - // store current stack position - int lhs_stack_position = bindings.currentExpressionStackPosition(); + if(operator_ == "==") { + std::cout << "\tsltiu\t$2,$2,1\n"; + } else if(operator_ == "!="){ + std::cout << "\tsltu\t$2,$0,$2\n"; + } else { + std::cerr << "Error : no instruction found for operator '" << operator_ << "'\n"; + } - // increase stack position to store next result in - bindings.nextExpressionStackPosition(); - rhs_->printAsm(bindings, label_count); + // TODO Work out why it is necessary to remove bytes 3 and 2. + std::cout << "\tandi\t$2,$2,0x00ff\n"; - std::cout << "\txor\t$2,$2,$3\n"; + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; return bindings; } @@ -293,6 +321,12 @@ AndExpression::AndExpression(Expression* lhs, Expression* rhs) VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + evaluateExpression(bindings, label_count); + + std::cout << "\tand\t$2,$2,$3\n"; + + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + return bindings; } @@ -305,6 +339,12 @@ ExclusiveOrExpression::ExclusiveOrExpression(Expression* lhs, Expression* rhs) VariableStackBindings ExclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + evaluateExpression(bindings, label_count); + + std::cout << "\txor\t$2,$2,$3\n"; + + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + return bindings; } @@ -317,6 +357,12 @@ InclusiveOrExpression::InclusiveOrExpression(Expression* lhs, Expression* rhs) VariableStackBindings InclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + evaluateExpression(bindings, label_count); + + std::cout << "\tor\t$2,$2,$3\n"; + + std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + return bindings; } diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp index 52803c1..23fbc55 100644 --- a/c_compiler/src/statement.cpp +++ b/c_compiler/src/statement.cpp @@ -104,8 +104,8 @@ void CompoundStatement::countArguments(unsigned& argument_count) const // Selection Statement definition -SelectionStatement::SelectionStatement(Statement* _if, Statement* _else) - : Statement(), if_(_if), else_(_else) {} +SelectionStatement::SelectionStatement(Expression* condition, Statement* _if, Statement* _else) + : Statement(), condition_(condition), if_(_if), else_(_else) {} void SelectionStatement::print() const { @@ -127,6 +127,11 @@ void SelectionStatement::printXml() const VariableStackBindings SelectionStatement::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + condition_->printAsm(bindings, label_count); + std::cout << "\tbeq\t$2,$0,$" << label_count++ << "_else\n"; + if_->printAsm(bindings, label_count); + + // TODO insert label for else and then end of statement return bindings; } @@ -222,7 +227,7 @@ VariableStackBindings JumpStatement::printAsm(VariableStackBindings bindings, un if(expression_ != nullptr) expression_->printAsm(bindings, label_count); - std::cout << "\tj\t0f\n"; + std::cout << "\tj\t0f\n\tnop\n"; return bindings; } diff --git a/c_compiler/test/in/IfElse.c b/c_compiler/test/in/IfElse.c index 2d49e2c..9c60a85 100644 --- a/c_compiler/test/in/IfElse.c +++ b/c_compiler/test/in/IfElse.c @@ -1,8 +1,4 @@ -int f(int a) +int main() { - if(a == 2) { - return 3; - } else { - return 2; - } + return 5 != 8; } |