From d08786b22e454e177e0642b5f9e4b19a12a891b1 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 25 Mar 2017 16:13:33 +0000 Subject: Adding proper support for types --- c_compiler/include/expression.hpp | 13 +- c_compiler/include/type.hpp | 47 ++++++- c_compiler/src/c_parser.y | 19 ++- c_compiler/src/declaration.cpp | 8 +- c_compiler/src/expression.cpp | 56 ++++++++ c_compiler/src/type.cpp | 148 ++++++++++++++++++++- test_deliverable/testcases/test_CHAR0.c | 4 + test_deliverable/testcases/test_CHAR0_driver.c | 6 + test_deliverable/testcases/test_CHARARRAY0.c | 7 + .../testcases/test_CHARARRAY0_driver.c | 12 ++ 10 files changed, 300 insertions(+), 20 deletions(-) create mode 100644 test_deliverable/testcases/test_CHAR0.c create mode 100644 test_deliverable/testcases/test_CHAR0_driver.c create mode 100644 test_deliverable/testcases/test_CHARARRAY0.c create mode 100644 test_deliverable/testcases/test_CHARARRAY0_driver.c diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 5f50b60..f1dd31c 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -26,6 +26,7 @@ public: virtual void countArguments(unsigned &argument_count) const; virtual void expressionDepth(unsigned &depth_count) const; virtual std::string id() const; + virtual TypePtr getType(const VariableStackBindings &bindings) const = 0; void linkExpression(Expression* next_expression); ExpressionPtr nextExpression() const; @@ -44,6 +45,7 @@ public: virtual int constantFold() const; virtual void expressionDepth(unsigned &depth_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; ExpressionPtr getLhs() const; ExpressionPtr getRhs() const; @@ -54,8 +56,6 @@ public: class UnaryExpression : public Expression { public: - virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0; - virtual void stackPosition(VariableStackBindings bindings, unsigned &depth_count) const; }; @@ -71,6 +71,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual void expressionDepth(unsigned &depth_count) const; virtual void stackPosition(VariableStackBindings bindings, unsigned &depth_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; class PostfixFunctionCall : public UnaryExpression @@ -85,6 +86,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual void countArguments(unsigned &argument_count) const; virtual void expressionDepth(unsigned &depth_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; void setPostfixExpression(Expression *postfix_expression); }; @@ -99,6 +101,7 @@ public: PostfixPostIncDecExpression(const std::string &_operator, Expression *postfix_expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; @@ -112,6 +115,7 @@ public: UnaryPreIncDecExpression(const std::string &_operator, Expression *unary_expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; class OperatorUnaryExpression : public UnaryExpression @@ -125,6 +129,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual void stackPosition(VariableStackBindings bindings, unsigned &depth_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; @@ -139,6 +144,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual void expressionDepth(unsigned &depth_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; class AdditiveExpression : public OperationExpression @@ -255,6 +261,7 @@ public: Expression *conditional_expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; class AssignmentExpression : public OperationExpression @@ -276,6 +283,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual void stackPosition(VariableStackBindings bindings, unsigned &depth_count) const; virtual std::string id() const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; class Constant : public UnaryExpression @@ -287,6 +295,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; virtual int constantFold() const; + virtual TypePtr getType(const VariableStackBindings &bindings) const; }; #endif diff --git a/c_compiler/include/type.hpp b/c_compiler/include/type.hpp index 8c22ab8..8f2cf08 100644 --- a/c_compiler/include/type.hpp +++ b/c_compiler/include/type.hpp @@ -20,12 +20,16 @@ public: virtual TypePtr type() = 0; virtual TypePtr type(Type *type_ptr) = 0; virtual TypePtr type(TypePtr type_ptr) = 0; + + virtual void increaseStackPosition(VariableStackBindings &bindings) const = 0; + virtual void load(const int ®, const int &position) const = 0; + virtual void store(const int &position) const = 0; virtual void setSigned(bool _signed); virtual void setExtern(bool _extern); virtual void setStatic(bool _static); virtual void setConst(bool _const); - virtual void setSize(int size); + virtual void setSize(int size); }; class Array : public Type @@ -43,6 +47,10 @@ public: virtual TypePtr type(); virtual TypePtr type(Type *type_ptr); virtual TypePtr type(TypePtr type_ptr); + + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; class Pointer : public Type @@ -59,6 +67,10 @@ public: virtual TypePtr type(); virtual TypePtr type(Type *type_ptr); virtual TypePtr type(TypePtr type_ptr); + + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; class TypeContainer : public Type @@ -81,6 +93,10 @@ public: virtual TypePtr type(); virtual TypePtr type(Type *type_ptr); virtual TypePtr type(TypePtr type_ptr); + + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; virtual void setSigned(bool _signed); virtual void setExtern(bool _extern); @@ -95,6 +111,10 @@ public: virtual void print() const = 0; virtual void printXml() const = 0; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0; + + virtual void increaseStackPosition(VariableStackBindings &bindings) const = 0; + virtual void load(const int ®, const int &position) const = 0; + virtual void store(const int &position) const = 0; virtual TypePtr type(); virtual TypePtr type(Type *type_ptr); @@ -109,6 +129,22 @@ public: virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; +}; + +class Short : public Specifier +{ +public: + Short(); + + virtual void print() const; + virtual void printXml() const; + virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; class Void : public Specifier @@ -119,6 +155,9 @@ public: virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; class Char : public Specifier @@ -129,6 +168,9 @@ public: virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; class Float : public Specifier @@ -139,6 +181,9 @@ public: virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void increaseStackPosition(VariableStackBindings &bindings) const; + virtual void load(const int ®, const int &position) const; + virtual void store(const int &position) const; }; #endif diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index e899467..8f91ff0 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -473,12 +473,11 @@ void setTypeInformation(Type* type_ptr, std::string type_str) type_ptr->type(new Void()); } else if(type_str == "char") { type_ptr->type(new Char()); - type_ptr->setSize(8); } else if(type_str == "short") { - type_ptr->type(new Int()); - type_ptr->setSize(16); + type_ptr->type(new Short()); } else if(type_str == "int") { - type_ptr->type(new Int()); + if(type_ptr->type() == nullptr) + type_ptr->type(new Int()); } else if(type_str == "long") { type_ptr->type(new Int()); } else if(type_str == "float") { @@ -486,22 +485,30 @@ void setTypeInformation(Type* type_ptr, std::string type_str) } else if(type_str == "double") { type_ptr->type(new Float()); } else if(type_str == "signed") { - type_ptr->type(new Int()); + if(type_ptr->type() == nullptr) + type_ptr->type(new Int()); type_ptr->setSigned(true); } else if(type_str == "unsigned") { - type_ptr->type(new Int()); + if(type_ptr->type() == nullptr) + type_ptr->type(new Int()); type_ptr->setSigned(false); } else if(type_str == "typedef") { // TODO do typedef } else if(type_str == "extern") { + if(type_ptr == nullptr) + type_ptr->type(new Int()); type_ptr->setExtern(true); } else if(type_str == "static") { + if(type_ptr == nullptr) + type_ptr->type(new Int()); type_ptr->setStatic(true); } else if(type_str == "auto") { // TODO do auto } else if(type_str == "register") { // TODO do register } else if(type_str == "const") { + if(type_ptr == nullptr) + type_ptr->type(new Int()); type_ptr->setConst(true); } else if(type_str == "volatile") { // TODO do volatile diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index 6edf875..0298fe6 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -68,10 +68,10 @@ VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsi if(initializer_ != nullptr) { initializer_->printAsm(bindings, label_count); - printf("\tsw\t$2,%d($fp)\n", stack_position); + type_->store(stack_position); } bindings.insertBinding(id_, type_, stack_position); - bindings.increaseStackPosition(); + type_->increaseStackPosition(bindings); } return bindings; @@ -179,12 +179,12 @@ VariableStackBindings ArrayDeclaration::localAsm(VariableStackBindings bindings, { int initializer_count = itr-initializer_vector.rbegin(); (*itr)->printAsm(bindings, label_count); - printf("\tsw\t$2,%d($fp)\n", stack_position+4*initializer_count); + type_->store(stack_position+4*initializer_count); } } bindings.insertBinding(id_, type_, stack_position); - bindings.increaseStackPosition(size_); + type_->increaseStackPosition(bindings); } return bindings; diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index e65d2f7..fe5f1cf 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -39,6 +39,12 @@ std::string Expression::id() const return ""; } +TypePtr Expression::getType(const VariableStackBindings &) const +{ + // by default return largest size, which is 32 bits + return std::make_shared(); +} + void Expression::linkExpression(Expression *next_expression) { ExpressionPtr expression_ptr(next_expression); @@ -80,6 +86,11 @@ void OperationExpression::expressionDepth(unsigned &depth_count) const depth_count = rhs_depth_count; } +TypePtr OperationExpression::getType(const VariableStackBindings &bindings) const +{ + return lhs_->getType(bindings); +} + ExpressionPtr OperationExpression::getLhs() const { return lhs_; @@ -151,6 +162,11 @@ void PostfixArrayElement::expressionDepth(unsigned &depth_count) const index_expression_->expressionDepth(depth_count); } +TypePtr PostfixArrayElement::getType(const VariableStackBindings &bindings) const +{ + return postfix_expression_->getType(bindings); +} + // PostfixFunctionCall @@ -212,6 +228,11 @@ void PostfixFunctionCall::expressionDepth(unsigned &depth_count) const argument_expression_list_->expressionDepth(depth_count); } +TypePtr PostfixFunctionCall::getType(const VariableStackBindings &) const +{ + return std::make_shared(); +} + // Post increment and decrement definition @@ -239,6 +260,11 @@ VariableStackBindings PostfixPostIncDecExpression::printAsm(VariableStackBinding return bindings; } +TypePtr PostfixPostIncDecExpression::getType(const VariableStackBindings &bindings) const +{ + return postfix_expression_->getType(bindings); +} + // Pre increment and decrement implementation @@ -265,6 +291,11 @@ VariableStackBindings UnaryPreIncDecExpression::printAsm(VariableStackBindings b return bindings; } +TypePtr UnaryPreIncDecExpression::getType(const VariableStackBindings &bindings) const +{ + return unary_expression_->getType(bindings); +} + // Operator unary definition @@ -315,6 +346,11 @@ void OperatorUnaryExpression::stackPosition(VariableStackBindings bindings, unsi } } +TypePtr OperatorUnaryExpression::getType(const VariableStackBindings &bindings) const +{ + return cast_expression_->getType(bindings); +} + // CastExpression definition @@ -335,6 +371,11 @@ void CastExpression::expressionDepth(unsigned &depth_count) const expression_->expressionDepth(depth_count); } +TypePtr CastExpression::getType(const VariableStackBindings &) const +{ + return type_; +} + // Additive Expression definition @@ -664,6 +705,11 @@ VariableStackBindings ConditionalExpression::printAsm(VariableStackBindings bind return bindings; } +TypePtr ConditionalExpression::getType(const VariableStackBindings &bindings) const +{ + return std::make_shared(); +} + // Assignment Expression definition @@ -754,6 +800,11 @@ std::string Identifier::id() const return id_; } +TypePtr Identifier::getType(const VariableStackBindings &bindings) const +{ + return bindings.getType(id_); +} + // Constant definition @@ -773,3 +824,8 @@ int Constant::constantFold() const { return constant_; } + +TypePtr Constant::getType(const VariableStackBindings &) const +{ + return std::make_shared(); +} diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp index 29b6902..e05a03e 100644 --- a/c_compiler/src/type.cpp +++ b/c_compiler/src/type.cpp @@ -46,7 +46,7 @@ void Array::print() const void Array::printXml() const {} -VariableStackBindings Array::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Array::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } @@ -69,6 +69,24 @@ TypePtr Array::type(TypePtr type_ptr) return type_; } +void Array::increaseStackPosition(VariableStackBindings &bindings) const +{ + for(int i = 0; i < size_; ++i) + { + type_->increaseStackPosition(bindings); + } +} + +void Array::load(const int ®, const int &position) const +{ + type_->load(reg, position); +} + +void Array::store(const int &position) const +{ + type_->store(position); +} + // Pointer definition @@ -83,7 +101,7 @@ void Pointer::print() const void Pointer::printXml() const {} -VariableStackBindings Pointer::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Pointer::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } @@ -106,7 +124,20 @@ TypePtr Pointer::type(TypePtr type_ptr) return type_; } +void Pointer::increaseStackPosition(VariableStackBindings &bindings) const +{ + bindings.increaseStackPosition(4); +} + +void Pointer::load(const int ®, const int &position) const +{ + printf("\tlw\t$%d,%d($fp)\n", reg, position); +} +void Pointer::store(const int &position) const +{ + type_->store(position); +} // TypeContainer definition @@ -124,7 +155,7 @@ void TypeContainer::print() const void TypeContainer::printXml() const {} -VariableStackBindings TypeContainer::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings TypeContainer::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } @@ -149,6 +180,21 @@ TypePtr TypeContainer::type(TypePtr type_ptr) return type_; } +void TypeContainer::increaseStackPosition(VariableStackBindings &bindings) const +{ + type_->increaseStackPosition(bindings); +} + +void TypeContainer::load(const int ®, const int &position) const +{ + type_->load(reg, position); +} + +void TypeContainer::store(const int &position) const +{ + type_->store(position); +} + void TypeContainer::setSigned(bool _signed) { signed_ = _signed; @@ -206,11 +252,26 @@ void Int::print() const void Int::printXml() const {} -VariableStackBindings Int::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Int::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } +void Int::increaseStackPosition(VariableStackBindings &bindings) const +{ + bindings.increaseStackPosition(4); +} + +void Int::load(const int ®, const int &position) const +{ + printf("\tlw\t$%d,%d($fp)\n", reg, position); +} + +void Int::store(const int &position) const +{ + printf("\tsw\t$2,%d($fp)\n", position); +} + // Void definition @@ -225,11 +286,54 @@ void Void::print() const void Void::printXml() const {} -VariableStackBindings Void::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Void::printAsm(VariableStackBindings bindings, unsigned &) const +{ + return bindings; +} + +void Void::increaseStackPosition(VariableStackBindings &) const +{} + +void Void::load(const int &, const int &) const +{} + +void Void::store(const int &) const +{} + + +// Short definition + +Short::Short() +{} + +void Short::print() const +{ + printf("Short\n"); +} + +void Short::printXml() const +{} + +VariableStackBindings Short::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } +void Short::increaseStackPosition(VariableStackBindings &bindings) const +{ + bindings.increaseStackPosition(2); +} + +void Short::load(const int ®, const int &position) const +{ + printf("\tlh\t$%d,%d($fp)\n", reg, position); +} + +void Short::store(const int &position) const +{ + printf("\tsh\t$2,%d($fp)\n", position); +} + // Char definition @@ -244,11 +348,26 @@ void Char::print() const void Char::printXml() const {} -VariableStackBindings Char::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Char::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } +void Char::increaseStackPosition(VariableStackBindings &bindings) const +{ + bindings.increaseStackPosition(1); +} + +void Char::load(const int ®, const int &position) const +{ + printf("\tlb\t$%d,%d($fp)\n", reg, position); +} + +void Char::store(const int &position) const +{ + printf("\tsb\t$2,%d($fp)\n", position); +} + // Float definition @@ -263,7 +382,22 @@ void Float::print() const void Float::printXml() const {} -VariableStackBindings Float::printAsm(VariableStackBindings bindings, unsigned &label_count) const +VariableStackBindings Float::printAsm(VariableStackBindings bindings, unsigned &) const { return bindings; } + +void Float::increaseStackPosition(VariableStackBindings &bindings) const +{ + bindings.increaseStackPosition(4); +} + +void Float::load(const int &, const int &) const +{ + throw std::runtime_error("Error : Cannot load float yet"); +} + +void Float::store(const int &) const +{ + throw std::runtime_error("Error : Cannot store float yet"); +} diff --git a/test_deliverable/testcases/test_CHAR0.c b/test_deliverable/testcases/test_CHAR0.c new file mode 100644 index 0000000..c1dd4c6 --- /dev/null +++ b/test_deliverable/testcases/test_CHAR0.c @@ -0,0 +1,4 @@ +char char0(char a, char b) +{ + return a - b; +} diff --git a/test_deliverable/testcases/test_CHAR0_driver.c b/test_deliverable/testcases/test_CHAR0_driver.c new file mode 100644 index 0000000..ae73678 --- /dev/null +++ b/test_deliverable/testcases/test_CHAR0_driver.c @@ -0,0 +1,6 @@ +char char0(char, char); + +int main() +{ + return ( 'b' == char0('a', 1) ); +} diff --git a/test_deliverable/testcases/test_CHARARRAY0.c b/test_deliverable/testcases/test_CHARARRAY0.c new file mode 100644 index 0000000..1accac3 --- /dev/null +++ b/test_deliverable/testcases/test_CHARARRAY0.c @@ -0,0 +1,7 @@ +char *chararray0(char *array, char a, char b, char c) +{ + array[0] = a; + array[1] = b; + array[2] = c; + return array; +} diff --git a/test_deliverable/testcases/test_CHARARRAY0_driver.c b/test_deliverable/testcases/test_CHARARRAY0_driver.c new file mode 100644 index 0000000..0b68aae --- /dev/null +++ b/test_deliverable/testcases/test_CHARARRAY0_driver.c @@ -0,0 +1,12 @@ +#include + +char *chararray0(char *, char, char, char); + +int main() +{ + char array[3]; + char *test_array = "abc"; + return !( chararray0(array, 'a', 'b', 'c')[0] == test_array[0] && + chararray0(array, 'a', 'b', 'c')[1] == test_array[1] && + chararray0(array, 'a', 'b', 'c')[2] == test_array[2] ); +} -- cgit