aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-24 22:46:06 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-24 22:46:06 +0000
commitb8738b8d582cba01aa1e944426b0251c9c42ff37 (patch)
tree7cebba0d549624fe40ca737178231fb52bd980fb
parent42156b87d0bc78eb8bac2c0e1cb41f105bbfc32b (diff)
downloadCompiler-b8738b8d582cba01aa1e944426b0251c9c42ff37.tar.gz
Compiler-b8738b8d582cba01aa1e944426b0251c9c42ff37.zip
Able to store arrays
-rw-r--r--c_compiler/include/bindings.hpp7
-rw-r--r--c_compiler/include/type.hpp2
-rw-r--r--c_compiler/src/bindings.cpp15
-rw-r--r--c_compiler/src/c_parser.y7
-rw-r--r--c_compiler/src/declaration.cpp42
-rw-r--r--c_compiler/src/expression.cpp12
-rw-r--r--test_deliverable/testcases/test_ARRAY0.c5
-rw-r--r--test_deliverable/testcases/test_ARRAY0_driver.c6
8 files changed, 83 insertions, 13 deletions
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<Array>($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 <cstdio>
+#include <vector>
// 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<ExpressionPtr> 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<Array>(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) );
+}