From e539805d39de73e25eeaa48a48730255c4ae695f Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Fri, 24 Mar 2017 17:32:19 +0000 Subject: Pointers working --- c_compiler/include/expression.hpp | 48 +++++------- c_compiler/src/c_parser.y | 34 +++++---- c_compiler/src/compiler_main.cpp | 4 +- c_compiler/src/expression.cpp | 86 ++++++++++++++-------- qemu_test_POINTER0.elf_20170324-163137_8747.core | Bin 0 -> 8556544 bytes test_deliverable/testcases/test_NESTEQU.c | 7 ++ test_deliverable/testcases/test_NESTEQU_driver.c | 6 ++ test_deliverable/testcases/test_POINTER0.c | 5 ++ test_deliverable/testcases/test_POINTER0_driver.c | 6 ++ test_deliverable/testcases/test_POINTER1.c | 7 ++ test_deliverable/testcases/test_POINTER1_driver.c | 6 ++ test_deliverable/testcases/test_POINTER2.c | 4 + test_deliverable/testcases/test_POINTER2_driver.c | 8 ++ 13 files changed, 145 insertions(+), 76 deletions(-) create mode 100644 qemu_test_POINTER0.elf_20170324-163137_8747.core create mode 100644 test_deliverable/testcases/test_NESTEQU.c create mode 100644 test_deliverable/testcases/test_NESTEQU_driver.c create mode 100644 test_deliverable/testcases/test_POINTER0.c create mode 100644 test_deliverable/testcases/test_POINTER0_driver.c create mode 100644 test_deliverable/testcases/test_POINTER1.c create mode 100644 test_deliverable/testcases/test_POINTER1_driver.c create mode 100644 test_deliverable/testcases/test_POINTER2.c create mode 100644 test_deliverable/testcases/test_POINTER2_driver.c diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 57c24ef..244b2a8 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -10,10 +10,8 @@ #include class Expression; - typedef std::shared_ptr ExpressionPtr; - class Expression : public Node { private: @@ -26,16 +24,13 @@ public: virtual void print() const; virtual void printXml() const; virtual void countArguments(unsigned &argument_count) const; - virtual void expressionDepth(unsigned &depth_count) const; - virtual int postfixStackPosition(VariableStackBindings bindings) const; - virtual void setPostfixExpression(Expression *postfix_expression); + virtual void expressionDepth(unsigned &depth_count) const; virtual std::string id() const; void linkExpression(Expression* next_expression); ExpressionPtr nextExpression() const; }; - class OperationExpression : public Expression { protected: @@ -56,8 +51,15 @@ public: void evaluateExpression(VariableStackBindings bindings, unsigned &label_count) const; }; +class UnaryExpression : public Expression +{ +public: + virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const = 0; -class PostfixArrayElement : public Expression + virtual void stackPosition(VariableStackBindings bindings) const; +}; + +class PostfixArrayElement : public UnaryExpression { public: PostfixArrayElement(); @@ -65,8 +67,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; }; - -class PostfixFunctionCall : public Expression +class PostfixFunctionCall : public UnaryExpression { private: ExpressionPtr postfix_expression_; @@ -81,7 +82,7 @@ public: void setPostfixExpression(Expression *postfix_expression); }; -class PostfixPostIncDecExpression : public Expression +class PostfixPostIncDecExpression : public UnaryExpression { private: std::string operator_; @@ -94,8 +95,7 @@ public: }; - -class UnaryPreIncDecExpression : public Expression +class UnaryPreIncDecExpression : public UnaryExpression { private: std::string operator_; @@ -107,7 +107,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; }; -class OperatorUnaryExpression : public Expression +class OperatorUnaryExpression : public UnaryExpression { private: std::string operator_; @@ -117,6 +117,7 @@ public: OperatorUnaryExpression(const std::string &_operator, Expression *cast_expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; + virtual void stackPosition(VariableStackBindings bindings) const; }; @@ -132,7 +133,6 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; }; - class AdditiveExpression : public OperationExpression { private: @@ -145,7 +145,6 @@ public: virtual int constantFold() const; }; - class MultiplicativeExpression : public OperationExpression { private: @@ -158,7 +157,6 @@ public: virtual int constantFold() const; }; - class ShiftExpression : public OperationExpression { private: @@ -170,7 +168,6 @@ public: virtual int constantFold() const; }; - class RelationalExpression : public OperationExpression { private: @@ -182,7 +179,6 @@ public: virtual int constantFold() const; }; - class EqualityExpression : public OperationExpression { private: @@ -194,7 +190,6 @@ public: virtual int constantFold() const; }; - class AndExpression : public OperationExpression { public: @@ -204,7 +199,6 @@ public: virtual int constantFold() const; }; - class ExclusiveOrExpression : public OperationExpression { public: @@ -214,7 +208,6 @@ public: virtual int constantFold() const; }; - class InclusiveOrExpression : public OperationExpression { public: @@ -224,7 +217,6 @@ public: virtual int constantFold() const; }; - class LogicalAndExpression : public OperationExpression { public: @@ -234,7 +226,6 @@ public: virtual int constantFold() const; }; - class LogicalOrExpression : public OperationExpression { public: @@ -244,7 +235,6 @@ public: virtual int constantFold() const; }; - class ConditionalExpression : public Expression { private: @@ -259,7 +249,6 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; }; - class AssignmentExpression : public OperationExpression { public: @@ -269,8 +258,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; }; - -class Identifier : public Expression +class Identifier : public UnaryExpression { private: std::string id_; @@ -278,12 +266,11 @@ public: Identifier(const std::string &id); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned &label_count) const; - virtual int postfixStackPosition(VariableStackBindings bindings) const; + virtual void stackPosition(VariableStackBindings bindings) const; virtual std::string id() const; }; - -class Constant : public Expression +class Constant : public UnaryExpression { private: int32_t constant_; @@ -294,5 +281,4 @@ public: virtual int constantFold() const; }; - #endif diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index 1bdfe12..c56b4b6 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -109,8 +109,8 @@ ParameterList: | ParameterList T_CMA Parameter { $3->linkDeclaration($$); $$ = $3; } ; -Parameter: DeclarationSpecifierList T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; } - | DeclarationSpecifierList {$$ = new Declaration(""); } +Parameter: DeclarationSpecifierList Declarator { $$ = new Declaration($2->getId()); delete $1; } + | DeclarationSpecifierList {$$ = new Declaration(""); } ; // Declaration @@ -179,24 +179,24 @@ InitDeclarator: Declarator { $$ = $1; } ; Declarator: DirectDeclarator { $$ = $1; } -| Pointer DirectDeclarator { $$ = $2; std::shared_ptr tmp($1); $$->setType(tmp); } + | Pointer DirectDeclarator { $$ = $2; std::shared_ptr tmp($1); $$->setType(tmp); } ; Pointer: -T_MULT { $$ = new Pointer(); delete $1; } -| T_MULT Pointer { $$ = $2; delete $1; } -| T_MULT TypeQualifierList Pointer { $$ = $3; delete $1; delete $2; } -; + T_MULT { $$ = new Pointer(); delete $1; } + | T_MULT Pointer { $$ = $2; delete $1; } + | T_MULT TypeQualifierList Pointer { $$ = $3; delete $1; delete $2; } + ; TypeQualifierList: -TypeQualifier { $$ = $1; } -| TypeQualifierList TypeQualifier { $$ = $2; delete $1; } -; + TypeQualifier { $$ = $1; } + | TypeQualifierList TypeQualifier { $$ = $2; delete $1; } + ; TypeQualifier: -T_CONST { $$ = new std::string("const"); } -| T_VOLATILE { $$ = new std::string("volatile"); } -; + T_CONST { $$ = new std::string("const"); } + | T_VOLATILE { $$ = new std::string("volatile"); } + ; DirectDeclarator: T_IDENTIFIER { $$ = new Declaration(*$1); delete $1; } @@ -417,7 +417,13 @@ UnaryOperator: T_AND { $$ = $1; } PostfixExpression: PrimaryExpression { $$ = $1; } | PostfixExpression T_LSB Expression T_RSB { $$ = new PostfixArrayElement(); } - | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; $$->setPostfixExpression($1); } + | PostfixExpression T_LRB PostfixExpression2 + { + $$ = $3; + PostfixFunctionCall *tmp = dynamic_cast($$); + if(tmp != nullptr) + tmp->setPostfixExpression($1); + } | PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; } | PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; } | PostfixExpression T_INCDEC diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp index e9a12b9..4ac641c 100644 --- a/c_compiler/src/compiler_main.cpp +++ b/c_compiler/src/compiler_main.cpp @@ -15,9 +15,9 @@ int main(int, char**) unsigned label_count = 0; ast->printAsm(bindings, label_count); } - catch(std::string error_msg) + catch(const std::exception& e) { - fprintf(stderr, "%s\n", error_msg.c_str()); + fprintf(stderr, "%s\n", e.what()); } catch(...) { diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index b07a31e..af2687d 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -12,7 +12,12 @@ int Expression::constantFold() const } void Expression::print() const -{} +{ + if(next_expression_ != nullptr) + next_expression_->print(); + + printf("Expression\n"); +} void Expression::printXml() const {} @@ -26,18 +31,6 @@ void Expression::countArguments(unsigned &argument_count) const void Expression::expressionDepth(unsigned &) const {} -int Expression::postfixStackPosition(VariableStackBindings bindings) const -{ - (void)bindings; - throw std::runtime_error("Error : Can't call postfixStackExpression() on this type"); -} - -void Expression::setPostfixExpression(Expression *postfix_expression) -{ - // do nothing if expression isn't a postfix expression - (void)postfix_expression; -} - std::string Expression::id() const { // by default return empty id, which cannot be valid. @@ -68,7 +61,7 @@ OperationExpression::OperationExpression(ExpressionPtr lhs, Expression *rhs) int OperationExpression::constantFold() const { - throw std::runtime_error("Error : Cannot constant fold expression\n"); + throw std::runtime_error("Error : Cannot constant fold expression"); } void OperationExpression::expressionDepth(unsigned &depth_count) const @@ -113,6 +106,15 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns lhs_stack_position, bindings.currentExpressionStackPosition()); } + +// Unary expression definition + +void UnaryExpression::stackPosition(VariableStackBindings) const +{ + throw std::runtime_error("Error : Cannot get stack position of expression"); +} + + // PostfixArrayElement PostfixArrayElement::PostfixArrayElement() @@ -189,14 +191,19 @@ VariableStackBindings PostfixPostIncDecExpression::printAsm(VariableStackBinding { postfix_expression_->printAsm(bindings, label_count); if(operator_ == "++") - printf("\taddi\t$3,$2,1\n"); + printf("\taddiu\t$3,$2,1\n"); else if(operator_ == "--") - printf("\tsubi\t$3,$2,1\n"); + printf("\tsubiu\t$3,$2,1\n"); else throw std::runtime_error("Error : '"+operator_+"' not recognized"); - printf("\tsw\t$2,%d($fp)\n\tsw\t$3,%d($fp)\n", bindings.currentExpressionStackPosition(), - postfix_expression_->postfixStackPosition(bindings)); + std::shared_ptr unary_expression; + unary_expression = std::static_pointer_cast(postfix_expression_); + + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); + unary_expression->stackPosition(bindings); + printf("\tsw\t$3,0($t0)\n"); + return bindings; } @@ -216,9 +223,13 @@ VariableStackBindings UnaryPreIncDecExpression::printAsm(VariableStackBindings b printf("\tsubi\t$2,$2,1\n"); else throw std::runtime_error("Error : '"+operator_+"' not recognized"); - - printf("\tsw\t$2,%d($fp)\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition(), - unary_expression_->postfixStackPosition(bindings)); + + std::shared_ptr unary_expression; + unary_expression = std::static_pointer_cast(unary_expression_); + + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); + unary_expression->stackPosition(bindings); + printf("\tsw\t$2,0($t0)\n"); return bindings; } @@ -242,7 +253,10 @@ VariableStackBindings OperatorUnaryExpression::printAsm(VariableStackBindings bi } else if(operator_ == "&") { - printf("\taddiu\t$2,$fp,%d\n", cast_expression_->postfixStackPosition(bindings)); + std::shared_ptr unary_expression; + unary_expression = std::static_pointer_cast(cast_expression_); + unary_expression->stackPosition(bindings); + printf("\tmove\t$2,$t0\n"); } else if(operator_ == "-") { @@ -258,6 +272,17 @@ VariableStackBindings OperatorUnaryExpression::printAsm(VariableStackBindings bi return bindings; } +void OperatorUnaryExpression::stackPosition(VariableStackBindings bindings) const +{ + if(operator_ == "*") + { + std::shared_ptr unary_expression; + unary_expression = std::static_pointer_cast(cast_expression_); + unary_expression->stackPosition(bindings); + printf("\tlw\t$t0,0($t0)\n"); + } +} + // CastExpression definition @@ -284,9 +309,9 @@ VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings binding // TODO currently using signed and sub because I only have signed numbers implemented // must update this as I add more types if(operator_ == "+") - printf("\tadd\t$2,$2,$3\n"); + printf("\taddu\t$2,$2,$3\n"); else if(operator_ == "-") - printf("\tsub\t$2,$2,$3\n"); + printf("\tsubu\t$2,$2,$3\n"); else throw std::runtime_error("Error : '"+operator_+"' not recognized"); @@ -615,7 +640,8 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi // TODO add stack and store results in there, also for addition and multiplication. // get the current location of lhs in the stack so that I can store result there - int store_stack_position = lhs_->postfixStackPosition(bindings); + std::shared_ptr lhs_postfix; + lhs_postfix = std::static_pointer_cast(lhs_); // get the current available stack position int expression_stack_position = bindings.currentExpressionStackPosition(); @@ -628,7 +654,8 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi printf("\tlw\t$2,%d($fp)\n", expression_stack_position); // we are assigning so we don't have to evaluate the lhs as it will be overwritten anyways - printf("\tsw\t$2,%d($fp)\n", store_stack_position); + lhs_postfix->stackPosition(bindings); + printf("\tsw\t$2,0($t0)\n"); return bindings; } @@ -664,14 +691,15 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig return bindings; } -int Identifier::postfixStackPosition(VariableStackBindings bindings) const +void Identifier::stackPosition(VariableStackBindings bindings) const { if(bindings.bindingExists(id_)) { - return bindings.stackPosition(id_); + printf("\taddiu\t$t0,$fp,%d\n", bindings.stackPosition(id_)); + return; } - throw std::runtime_error("Error : Variable '"+id_+"' not yet declared"); + throw std::runtime_error("Error : '"+id_+"' not yet declared"); } std::string Identifier::id() const diff --git a/qemu_test_POINTER0.elf_20170324-163137_8747.core b/qemu_test_POINTER0.elf_20170324-163137_8747.core new file mode 100644 index 0000000..8e2096d Binary files /dev/null and b/qemu_test_POINTER0.elf_20170324-163137_8747.core differ diff --git a/test_deliverable/testcases/test_NESTEQU.c b/test_deliverable/testcases/test_NESTEQU.c new file mode 100644 index 0000000..698784f --- /dev/null +++ b/test_deliverable/testcases/test_NESTEQU.c @@ -0,0 +1,7 @@ +int nestequ(int a) +{ + int b = 4; + int c; + c = b = a; + return b; +} diff --git a/test_deliverable/testcases/test_NESTEQU_driver.c b/test_deliverable/testcases/test_NESTEQU_driver.c new file mode 100644 index 0000000..02f31a5 --- /dev/null +++ b/test_deliverable/testcases/test_NESTEQU_driver.c @@ -0,0 +1,6 @@ +int nestequ(int); + +int main() +{ + return !( 3091 == nestequ(3091) ); +} diff --git a/test_deliverable/testcases/test_POINTER0.c b/test_deliverable/testcases/test_POINTER0.c new file mode 100644 index 0000000..d0110e3 --- /dev/null +++ b/test_deliverable/testcases/test_POINTER0.c @@ -0,0 +1,5 @@ +int *pointer(int a) +{ + int *b = &a; + return b; +} diff --git a/test_deliverable/testcases/test_POINTER0_driver.c b/test_deliverable/testcases/test_POINTER0_driver.c new file mode 100644 index 0000000..3d7c7aa --- /dev/null +++ b/test_deliverable/testcases/test_POINTER0_driver.c @@ -0,0 +1,6 @@ +int *pointer(int); + +int main() +{ + return !( 67 == *pointer(67) ); +} diff --git a/test_deliverable/testcases/test_POINTER1.c b/test_deliverable/testcases/test_POINTER1.c new file mode 100644 index 0000000..88d6df2 --- /dev/null +++ b/test_deliverable/testcases/test_POINTER1.c @@ -0,0 +1,7 @@ +int pointer1(int a) +{ + int *b = &a; + + a += *b; + return a; +} diff --git a/test_deliverable/testcases/test_POINTER1_driver.c b/test_deliverable/testcases/test_POINTER1_driver.c new file mode 100644 index 0000000..a66a63e --- /dev/null +++ b/test_deliverable/testcases/test_POINTER1_driver.c @@ -0,0 +1,6 @@ +int pointer1(int); + +int main() +{ + return !( 392 == pointer1(392/2) ); +} diff --git a/test_deliverable/testcases/test_POINTER2.c b/test_deliverable/testcases/test_POINTER2.c new file mode 100644 index 0000000..a22d524 --- /dev/null +++ b/test_deliverable/testcases/test_POINTER2.c @@ -0,0 +1,4 @@ +void pointer2(int *a) +{ + *a = 238; +} diff --git a/test_deliverable/testcases/test_POINTER2_driver.c b/test_deliverable/testcases/test_POINTER2_driver.c new file mode 100644 index 0000000..81e298a --- /dev/null +++ b/test_deliverable/testcases/test_POINTER2_driver.c @@ -0,0 +1,8 @@ +void pointer2(int *); + +int main() +{ + int a = 83; + pointer2(&a); + return !( 238 == a ); +} -- cgit