aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-17 22:38:08 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-17 22:38:08 +0000
commita9663b327230e08a6bc5cfe4f20ed8d066f33338 (patch)
tree4a47654b4fd29300ebee876fa1d9f79dac52499f
parentf35548ee7d4c54558c38d63df7e2572150c28d22 (diff)
downloadCompiler-a9663b327230e08a6bc5cfe4f20ed8d066f33338.tar.gz
Compiler-a9663b327230e08a6bc5cfe4f20ed8d066f33338.zip
Creating if statement
-rw-r--r--Notes.org3
-rw-r--r--c_compiler/include/expression.hpp10
-rw-r--r--c_compiler/include/statement.hpp3
-rw-r--r--c_compiler/src/c_lexer.flex4
-rw-r--r--c_compiler/src/c_parser.y13
-rw-r--r--c_compiler/src/expression.cpp132
-rw-r--r--c_compiler/src/statement.cpp11
-rw-r--r--c_compiler/test/in/IfElse.c8
8 files changed, 121 insertions, 63 deletions
diff --git a/Notes.org b/Notes.org
index 7afa97d..c4ef6a5 100644
--- a/Notes.org
+++ b/Notes.org
@@ -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;
}