From b8738b8d582cba01aa1e944426b0251c9c42ff37 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Fri, 24 Mar 2017 22:46:06 +0000 Subject: Able to store arrays --- c_compiler/include/bindings.hpp | 7 +++-- c_compiler/include/type.hpp | 2 +- c_compiler/src/bindings.cpp | 15 +++++++-- c_compiler/src/c_parser.y | 7 ++++- c_compiler/src/declaration.cpp | 42 ++++++++++++++++++++++--- c_compiler/src/expression.cpp | 12 +++++-- test_deliverable/testcases/test_ARRAY0.c | 5 +++ test_deliverable/testcases/test_ARRAY0_driver.c | 6 ++++ 8 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 test_deliverable/testcases/test_ARRAY0.c create mode 100644 test_deliverable/testcases/test_ARRAY0_driver.c diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp index 2559420..9383d5d 100644 --- a/c_compiler/include/bindings.hpp +++ b/c_compiler/include/bindings.hpp @@ -31,12 +31,15 @@ private: public: VariableStackBindings(); - void insertBinding(std::string id, TypePtr type, int stack_position); + void insertBinding(const std::string &id, TypePtr type, const int &stack_position); void increaseStackPosition(); - void setStackPosition(int stack_counter); + void increaseStackPosition(const int &position); + void setStackPosition(const int &stack_counter); void nextExpressionStackPosition(); void setExpressionStackPosition(const int &stack_counter); + TypePtr getType(const std::string &id) const; + std::string breakLabel(); std::string breakLabel(const std::string &label); std::string continueLabel(); diff --git a/c_compiler/include/type.hpp b/c_compiler/include/type.hpp index 8c881c1..8c22ab8 100644 --- a/c_compiler/include/type.hpp +++ b/c_compiler/include/type.hpp @@ -34,7 +34,7 @@ private: int size_; TypePtr type_; public: - Array(const int &size, TypePtr type_); + Array(const int &size, TypePtr type_ = nullptr); virtual void print() const; virtual void printXml() const; diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp index 333f21d..24e1745 100644 --- a/c_compiler/src/bindings.cpp +++ b/c_compiler/src/bindings.cpp @@ -7,7 +7,7 @@ VariableStackBindings::VariableStackBindings() : break_label_(""), continue_label_(""), stack_counter_(0), expression_stack_(16) {} -void VariableStackBindings::insertBinding(std::string id, TypePtr type, int stack_position) +void VariableStackBindings::insertBinding(const std::string &id, TypePtr type, const int &stack_position) { auto binding = bindings_.find(id); @@ -30,7 +30,12 @@ void VariableStackBindings::increaseStackPosition() stack_counter_ += 4; } -void VariableStackBindings::setStackPosition(int stack_counter) +void VariableStackBindings::increaseStackPosition(const int &position) +{ + stack_counter_ += position; +} + +void VariableStackBindings::setStackPosition(const int &stack_counter) { stack_counter_ = stack_counter; } @@ -45,6 +50,12 @@ void VariableStackBindings::setExpressionStackPosition(const int &stack_counter) expression_stack_ = stack_counter; } +TypePtr VariableStackBindings::getType(const std::string &id) const +{ + auto binding = bindings_.find(id); + return (*binding).second.type; +} + std::string VariableStackBindings::breakLabel() { return break_label_; diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index 5c464cd..c2086fd 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -202,7 +202,12 @@ TypeQualifier: DirectDeclarator: T_IDENTIFIER { $$ = new Declaration(*$1); delete $1; } | T_LRB Declarator T_RRB { $$ = $2; } -| DirectDeclarator T_LSB ConditionalExpression T_RSB { $$ = new ArrayDeclaration($1->getId(), $1->getInitializer(), $3->constantFold()); } + | DirectDeclarator T_LSB ConditionalExpression T_RSB + { + $$ = new ArrayDeclaration($1->getId(), $1->getInitializer(), $3->constantFold()); + TypePtr tmp_ptr = std::make_shared($3->constantFold()); + $$->setType(tmp_ptr); + } | DirectDeclarator T_LSB T_RSB { $$ = $1; } | DirectDeclarator T_LRB T_RRB { $$ = $1; $$->setExternDeclaration(true); } | DirectDeclarator T_LRB ParameterList T_RRB { $1->linkDeclaration($3); $$ = $1; $$->setExternDeclaration(true); } diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index c16c6d5..6edf875 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -4,6 +4,7 @@ #include "expression.hpp" #include +#include // Declaration definition @@ -63,13 +64,12 @@ VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsi if(id_ != "") { + int stack_position = bindings.currentStackPosition(); if(initializer_ != nullptr) + { initializer_->printAsm(bindings, label_count); - else - printf("\tmove\t$2,$0\n"); - - int stack_position = bindings.currentStackPosition(); - printf("\tsw\t$2,%d($fp)\n", stack_position); + printf("\tsw\t$2,%d($fp)\n", stack_position); + } bindings.insertBinding(id_, type_, stack_position); bindings.increaseStackPosition(); } @@ -155,6 +155,38 @@ VariableStackBindings ArrayDeclaration::printAsm(VariableStackBindings bindings, VariableStackBindings ArrayDeclaration::localAsm(VariableStackBindings bindings, unsigned &label_count) const { + if(next_declaration_ != nullptr) + bindings = next_declaration_->localAsm(bindings, label_count); + + if(next_list_declaration_ != nullptr) + bindings = next_list_declaration_->localAsm(bindings, label_count); + + if(id_ != "") + { + int stack_position = bindings.currentStackPosition(); + if(initializer_ != nullptr) + { + ExpressionPtr initializer = initializer_; + std::vector initializer_vector; + + while(initializer != nullptr) + { + initializer_vector.push_back(initializer); + initializer = initializer->nextExpression(); + } + + for(auto itr = initializer_vector.rbegin(); itr != initializer_vector.rend(); ++itr) + { + int initializer_count = itr-initializer_vector.rbegin(); + (*itr)->printAsm(bindings, label_count); + printf("\tsw\t$2,%d($fp)\n", stack_position+4*initializer_count); + } + } + + bindings.insertBinding(id_, type_, stack_position); + bindings.increaseStackPosition(size_); + } + return bindings; } diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 5b407d8..4c00c94 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -678,14 +678,22 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig if(bindings.bindingExists(id_)) { - if(bindings.stackPosition(id_) == -1) + int stack_position = bindings.stackPosition(id_); + if(stack_position == -1) { // it's a global variable printf("\tlui\t$2,%%hi(%s)\n\tlw\t$2,%%lo(%s)($2)\n", id_.c_str(), id_.c_str()); } else { - printf("\tlw\t$2,%d($fp)\n", bindings.stackPosition(id_)); + if(std::dynamic_pointer_cast(bindings.getType(id_)) != nullptr) + { + printf("\taddiu\t$2,$fp,%d\n", stack_position); + } + else + { + printf("\tlw\t$2,%d($fp)\n", stack_position); + } } } else diff --git a/test_deliverable/testcases/test_ARRAY0.c b/test_deliverable/testcases/test_ARRAY0.c new file mode 100644 index 0000000..fc70359 --- /dev/null +++ b/test_deliverable/testcases/test_ARRAY0.c @@ -0,0 +1,5 @@ +int array0(int a, int b, int c, int d, int e) +{ + int f[5] = { a, b, c, d, e }; + return *f; +} diff --git a/test_deliverable/testcases/test_ARRAY0_driver.c b/test_deliverable/testcases/test_ARRAY0_driver.c new file mode 100644 index 0000000..7d81cae --- /dev/null +++ b/test_deliverable/testcases/test_ARRAY0_driver.c @@ -0,0 +1,6 @@ +int array0(int, int, int, int, int); + +int main() +{ + return !( 38 == array0(38, 93, 29, 37, 23) ); +} -- cgit