From c15bba765558e1017ef68f6d319141d4fb0b71fd Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 28 Mar 2017 11:16:55 +0100 Subject: can insert mult dim arrays --- c_compiler/include/bindings.hpp | 4 +- c_compiler/include/declaration.hpp | 3 + c_compiler/include/expression.hpp | 18 +++++- c_compiler/src/bindings.cpp | 22 +++++++- c_compiler/src/c_parser.y | 4 +- c_compiler/src/declaration.cpp | 56 +++++++++++-------- c_compiler/src/expression.cpp | 68 ++++++++++++++++++++++- test.c | 8 +++ test_deliverable/testcases/test_MAINPRINTF.c | 3 +- test_deliverable/testcases/test_MULTARR0.c | 10 ++++ test_deliverable/testcases/test_MULTARR0_driver.c | 6 ++ 11 files changed, 170 insertions(+), 32 deletions(-) create mode 100644 test.c create mode 100644 test_deliverable/testcases/test_MULTARR0.c create mode 100644 test_deliverable/testcases/test_MULTARR0_driver.c diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp index d99d97b..42d52e1 100644 --- a/c_compiler/include/bindings.hpp +++ b/c_compiler/include/bindings.hpp @@ -15,6 +15,7 @@ struct DeclarationData { TypePtr type; int stack_position; + std::vector array_sizes; }; // stores bindings for the current scope and where they are in the stack @@ -31,7 +32,8 @@ private: public: Bindings(); - void insertBinding(const std::string &id, TypePtr type, const int &stack_position); + void insertBinding(const std::string &id, const TypePtr &type, const int &stack_position); + void insertBinding(const std::string &id, const TypePtr &type, const int &stack_position, const std::vector array_sizes); int insertStringLiteral(const std::string &string_literal); void increaseStackPosition(); void increaseStackPosition(const int &position); diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index 9fe4db2..ef45737 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -69,6 +69,9 @@ public: virtual Bindings localAsm(Bindings bindings, int &label_count) const; virtual void countDeclarations(int &declaration_count) const; virtual std::string getId() const; + + int getSize() const; + DeclarationPtr getNextArrayDeclaration() const; }; #endif diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index c784de7..6bade38 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -14,7 +14,7 @@ typedef std::shared_ptr ExpressionPtr; class Expression : public Node { -private: +protected: ExpressionPtr next_expression_; public: @@ -74,6 +74,8 @@ public: virtual void expressionDepth(int &depth_count) const; virtual void stackPosition(Bindings bindings, int &depth_count) const; virtual TypePtr getType(const Bindings &bindings) const; + + ExpressionPtr getIndex() const; }; class PostfixFunctionCall : public UnaryExpression @@ -312,4 +314,18 @@ public: virtual TypePtr getType(const Bindings &bindings) const; }; +class Initializer : public Expression +{ +private: + ExpressionPtr next_initializer_; +public: + Initializer(Expression *next_initializer); + + virtual Bindings printAsm(Bindings bindings, int &label_count) const; + virtual TypePtr getType(const Bindings &bindings) const; + + void printInitializerAsm(Bindings &bindings, int &label_count, int position, const std::vector &iteration_vector, const TypePtr &type) const; + ExpressionPtr getNext() const; +}; + #endif diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp index e91d408..0fe4c2f 100644 --- a/c_compiler/src/bindings.cpp +++ b/c_compiler/src/bindings.cpp @@ -8,7 +8,7 @@ Bindings::Bindings() : break_label_(""), continue_label_(""), stack_counter_(0), expression_stack_(16) {} -void Bindings::insertBinding(const std::string &id, TypePtr type, const int &stack_position) +void Bindings::insertBinding(const std::string &id,const TypePtr &type, const int &stack_position) { auto binding = bindings_.find(id); @@ -26,6 +26,26 @@ void Bindings::insertBinding(const std::string &id, TypePtr type, const int &sta } } +void Bindings::insertBinding(const std::string &id, const TypePtr &type, const int &stack_position, const std::vector array_sizes) +{ + auto binding = bindings_.find(id); + + if(binding == bindings_.end()) + { + DeclarationData decl_data; + decl_data.type = type; + decl_data.stack_position = stack_position; + decl_data.array_sizes = array_sizes; + bindings_.insert(std::make_pair(id, decl_data)); + } + else + { + (*binding).second.stack_position = stack_position; + (*binding).second.type = type; + (*binding).second.array_sizes = array_sizes; + } +} + int Bindings::insertStringLiteral(const std::string &string_literal) { string_literals.push_back(string_literal); diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index feb5d0b..a7f05e0 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -250,8 +250,8 @@ IdentifierList: T_IDENTIFIER { $$ = new IdentifierDeclaration(); } | IdentifierList T_CMA T_IDENTIFIER { $$ = new IdentifierDeclaration(); } Initializer: AssignmentExpression { $$ = $1; } - | T_LCB InitializerList T_RCB { $$ = $2; } - | T_LCB InitializerList T_CMA T_RCB { $$ = $2; } + | T_LCB InitializerList T_RCB { $$ = new Initializer($2); } + | T_LCB InitializerList T_CMA T_RCB { $$ = new Initializer($2); } ; InitializerList: diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index ca8f1f5..149bdab 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -4,6 +4,7 @@ #include "expression.hpp" #include +#include #include @@ -200,27 +201,21 @@ Bindings ArrayDeclaration::localAsm(Bindings bindings, int &label_count) const if(getId() != "") { int stack_position = bindings.currentStackPosition(); - if(initializer_ != nullptr) + std::shared_ptr array_declaration( + std::dynamic_pointer_cast(declarator_)); + std::vector array_sizes = { size_ }; + while(array_declaration != 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); - type_->store(stack_position+type_->getSize()*initializer_count); - } + array_sizes.push_back(array_declaration->getSize()); + array_declaration = std::dynamic_pointer_cast + (array_declaration->getNextArrayDeclaration()); } - + + std::shared_ptr initializer; + initializer = std::static_pointer_cast(initializer_); + initializer->printInitializerAsm(bindings, label_count, array_sizes.size()-1, array_sizes, type_->type()); + bindings.insertBinding(getId(), type_, stack_position); - type_->increaseStackPosition(bindings); } return bindings; @@ -233,15 +228,30 @@ void ArrayDeclaration::countDeclarations(int &declaration_count) const if(next_list_declaration_ != nullptr) next_list_declaration_->countDeclarations(declaration_count); - std::shared_ptr next_array; - next_array = std::dynamic_pointer_cast(declarator_); - if(next_array != nullptr) - next_array->countDeclarations(declaration_count); + std::shared_ptr array_declaration( + std::dynamic_pointer_cast(declarator_)); + int size = size_; + while(array_declaration != nullptr) + { + size *= array_declaration->getSize(); + array_declaration = std::dynamic_pointer_cast( + array_declaration->getNextArrayDeclaration()); + } - declaration_count += size_; + declaration_count += size; } std::string ArrayDeclaration::getId() const { return declarator_->getId(); } + +int ArrayDeclaration::getSize() const +{ + return size_; +} + +DeclarationPtr ArrayDeclaration::getNextArrayDeclaration() const +{ + return declarator_; +} diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 8d2e7cf..3df0a94 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -1,5 +1,6 @@ #include "expression.hpp" +#include #include #include #include @@ -166,8 +167,8 @@ void PostfixArrayElement::stackPosition(Bindings bindings, int &label_count) con unary_expression = std::static_pointer_cast(postfix_expression_); unary_expression->stackPosition(bindings, label_count); - printf("\tli\t$3,%d\n\tmul\t$2,$2,$3\n\taddu\t$t0,$t0,$2\n", - unary_expression->getType(bindings)->getSize()); + printf("\tsll\t$2,$2,%d\n\taddu\t$t0,$t0,$2\n", + unary_expression->getType(bindings)->getSize()/2); } void PostfixArrayElement::expressionDepth(int &depth_count) const @@ -926,3 +927,66 @@ TypePtr Constant::getType(const Bindings &) const { return std::make_shared(); } + +// Initializer definition + +Initializer::Initializer(Expression *next_initializer) + : next_initializer_(next_initializer) +{} + +Bindings Initializer::printAsm(Bindings bindings, int &) const +{ + return bindings; +} + +TypePtr Initializer::getType(const Bindings &bindings) const +{ + return next_initializer_->getType(bindings); +} + +void Initializer::printInitializerAsm(Bindings &bindings, int &label_count, int position, const + std::vector &iteration_vector, const TypePtr &type) const +{ + std::shared_ptr next_initializer + (std::dynamic_pointer_cast(next_initializer_)); + ExpressionPtr current_expression = next_initializer_; + std::vector expression_vector; + + while(current_expression != nullptr) + { + expression_vector.push_back(current_expression); + current_expression = current_expression->nextExpression(); + } + + std::reverse(expression_vector.begin(), expression_vector.end()); + int size = (int)expression_vector.size(); + for(int i = size; i < iteration_vector[position]; ++i) + { + expression_vector.emplace_back(nullptr); + } + + for(int i = 0; i < iteration_vector[position]; ++i) + { + next_initializer = std::dynamic_pointer_cast(expression_vector[i]); + if(next_initializer != nullptr) + { + next_initializer->printInitializerAsm(bindings, label_count, + position-1, iteration_vector, type); + } + else + { + if(expression_vector[i] != nullptr) + { + Bindings temp_bindings = bindings; + expression_vector[i]->printAsm(temp_bindings, label_count); + printf("\tsw\t$2,%d($fp)\n", bindings.currentStackPosition()); + } + type->increaseStackPosition(bindings); + } + } +} + +ExpressionPtr Initializer::getNext() const +{ + return next_initializer_; +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..cb188a3 --- /dev/null +++ b/test.c @@ -0,0 +1,8 @@ +int main() +{ + int x[4][3] = { + { 1, 2 }, + { 3, 4, 5}, + { 6, 7, 8 } + }; +} diff --git a/test_deliverable/testcases/test_MAINPRINTF.c b/test_deliverable/testcases/test_MAINPRINTF.c index 62ddab6..de94817 100644 --- a/test_deliverable/testcases/test_MAINPRINTF.c +++ b/test_deliverable/testcases/test_MAINPRINTF.c @@ -2,7 +2,6 @@ int printf(const char *format, ...); int main() { - char input[50] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', }; - printf(input); + printf("Hello World\n"); return 0; } diff --git a/test_deliverable/testcases/test_MULTARR0.c b/test_deliverable/testcases/test_MULTARR0.c new file mode 100644 index 0000000..c2072fc --- /dev/null +++ b/test_deliverable/testcases/test_MULTARR0.c @@ -0,0 +1,10 @@ +int multarr0(int a, int b, int c, int d, int e, int f) +{ + int x[3][2] = { + { a, b, }, + { c, d, }, + { e, f, }, + }; + + return x[1][0]; +} diff --git a/test_deliverable/testcases/test_MULTARR0_driver.c b/test_deliverable/testcases/test_MULTARR0_driver.c new file mode 100644 index 0000000..78672f9 --- /dev/null +++ b/test_deliverable/testcases/test_MULTARR0_driver.c @@ -0,0 +1,6 @@ +int multarr0(int, int, int, int, int, int); + +int main() +{ + return !( 21983 == multarr0(1298, 549, 21983, 39, 9035, 23944) ); +} -- cgit