diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-22 16:53:48 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-22 16:53:48 +0000 |
commit | 561b76bdebd584d03d4e451375777651a9d74017 (patch) | |
tree | fdab95e056a212a26b65a96ae2af894e8f42b82e | |
parent | f12ccd62ecf08774ce599a2e15d9042500d2760a (diff) | |
download | Compiler-561b76bdebd584d03d4e451375777651a9d74017.tar.gz Compiler-561b76bdebd584d03d4e451375777651a9d74017.zip |
Have to work on case
36 files changed, 270 insertions, 14 deletions
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 21e5880..1377a22 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -30,6 +30,8 @@ public: virtual int postfixStackPosition(VariableStackBindings bindings) const; virtual void setPostfixExpression(Expression* postfix_expression); virtual std::string id() const; + virtual ExpressionPtr getLhs() const; + virtual ExpressionPtr getRhs() const; void linkExpression(Expression* next_expression); ExpressionPtr nextExpression() const; @@ -43,11 +45,14 @@ protected: ExpressionPtr rhs_; public: OperationExpression(Expression* lhs, Expression* rhs); + OperationExpression(ExpressionPtr lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0; virtual int constantFold() const; virtual void expressionDepth(unsigned& depth_count) const; + virtual ExpressionPtr getLhs() const; + virtual ExpressionPtr getRhs() const; void evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const; }; @@ -248,6 +253,7 @@ class AssignmentExpression : public OperationExpression { public: AssignmentExpression(Expression* lhs, Expression* rhs); + AssignmentExpression(ExpressionPtr lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; }; diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex index 4255880..2547c5a 100644 --- a/c_compiler/src/c_lexer.flex +++ b/c_compiler/src/c_lexer.flex @@ -8,7 +8,7 @@ IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -ASSIGNMENT_OPERATOR (([<>][<>]|[*\/%+\-&^|])[=]|[=]) +ASSIGNMENT_OPERATOR (([<>][<>]|[*\/%+\-&^|])[=]) INTEGERSUFFIX ([uU][lL]|[lL][uU]|[uUlL]) @@ -59,6 +59,8 @@ ALL . [}] { return T_RCB; } [[] { return T_LSB; } []] { return T_RSB; } +[=] { yylval.string = new std::string(yytext); return T_EQ; } +{ASSIGNMENT_OPERATOR} { yylval.string = new std::string(yytext); return T_ASSIGN_OPER; } [?] { return T_QU; } [:] { return T_COL; } [|][|] { return T_LOG_OR; } @@ -79,9 +81,6 @@ ALL . [-][>] { return T_ARROW; } [+-][+-] { yylval.string = new std::string(yytext); return T_INCDEC; } [+-] { yylval.string = new std::string(yytext); return T_ADDSUB_OP; } -[=] { yylval.string = new std::string(yytext); return T_EQ; } - -{ASSIGNMENT_OPERATOR} { yylval.string = new std::string(yytext); return T_ASSIGN_OPER; } if { return T_IF; } else { return T_ELSE; } diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index c58bc75..79d8902 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -71,7 +71,7 @@ void yyerror(const char *); AndExpression EqualityExpression RelationalExpression ShiftExpression AdditiveExpression MultiplicativeExpression CastExpression UnaryExpression PostfixExpression PostfixExpression2 ArgumentExpressionList PrimaryExpression - Constant + Constant Initializer InitializerList %type <type> DeclarationSpecifierList @@ -174,7 +174,7 @@ InitDeclaratorList: ; InitDeclarator: Declarator { $$ = $1; } - | Declarator T_EQ AssignmentExpression { $$->setInitializer($3); delete $2; } + | Declarator T_EQ Initializer { $$ = $1; $$->setInitializer($3); delete $2; } ; Declarator: DirectDeclarator { $$ = $1; } @@ -194,6 +194,15 @@ DirectDeclarator: IdentifierList: T_IDENTIFIER { $$ = new Declaration(); } | IdentifierList T_CMA T_IDENTIFIER { $$ = new Declaration(); } +Initializer: AssignmentExpression { $$ = $1; } + | T_LCB InitializerList T_RCB { $$ = $2; } + | T_LCB InitializerList T_CMA T_RCB { $$ = $2; } + ; + +InitializerList: + Initializer { $$ = $1; } + | InitializerList T_CMA Initializer { $3->linkExpression($$); $$ = $3; } + // Statement StatementList: @@ -250,7 +259,45 @@ Expression: AssignmentExpression { $$ = $1; } AssignmentExpression: ConditionalExpression { $$ = $1; } - | UnaryExpression ASSIGN_OPER AssignmentExpression { $$ = new AssignmentExpression($1, $3); delete $2; } + | UnaryExpression ASSIGN_OPER AssignmentExpression + { + Expression* tmp; + if(*$2 == "=") { + $$ = new AssignmentExpression($1, $3); + } else if(*$2 == "+=") { + tmp = new AdditiveExpression($1, "+", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "-=") { + tmp = new AdditiveExpression($1, "-", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "*=") { + tmp = new MultiplicativeExpression($1, "*", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "/=") { + tmp = new MultiplicativeExpression($1, "/", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "%=") { + tmp = new MultiplicativeExpression($1, "%", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "&=") { + tmp = new AndExpression($1, $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "^=") { + tmp = new ExclusiveOrExpression($1, $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "|=") { + tmp = new InclusiveOrExpression($1, $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else if(*$2 == "<<=") { + tmp = new ShiftExpression($1, "<<", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } else { + tmp = new ShiftExpression($1, ">>", $3); + $$ = new AssignmentExpression(tmp->getLhs(), tmp); + } + + delete $2; + } ; ASSIGN_OPER: T_ASSIGN_OPER { ; } diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index cdf7d0a..e00c9b0 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -46,6 +46,16 @@ std::string Expression::id() const return ""; } +ExpressionPtr Expression::getLhs() const +{ + throw std::runtime_error("Error : Cannot get lhs"); +} + +ExpressionPtr Expression::getRhs() const +{ + throw std::runtime_error("Error : Cannot get rhs"); +} + void Expression::linkExpression(Expression *next_expression) { ExpressionPtr expression_ptr(next_expression); @@ -64,6 +74,10 @@ OperationExpression::OperationExpression(Expression* lhs, Expression* rhs) : lhs_(lhs), rhs_(rhs) {} +OperationExpression::OperationExpression(ExpressionPtr lhs, Expression* rhs) + : lhs_(lhs), rhs_(rhs) +{} + int OperationExpression::constantFold() const { throw std::runtime_error("Error : Cannot constant fold expression\n"); @@ -83,6 +97,16 @@ void OperationExpression::expressionDepth(unsigned& depth_count) const depth_count = rhs_depth_count; } +ExpressionPtr OperationExpression::getLhs() const +{ + return lhs_; +} + +ExpressionPtr OperationExpression::getRhs() const +{ + return rhs_; +} + void OperationExpression::evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const { // I can just evaluate the lhs with the same entry stack position @@ -542,6 +566,10 @@ AssignmentExpression::AssignmentExpression(Expression* lhs, Expression* rhs) : OperationExpression(lhs, rhs) {} +AssignmentExpression::AssignmentExpression(ExpressionPtr lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { // TODO add stack and store results in there, also for addition and multiplication. diff --git a/run_test_deliverable.sh b/run_test_deliverable.sh index ae96054..1c6e2ba 100755 --- a/run_test_deliverable.sh +++ b/run_test_deliverable.sh @@ -2,6 +2,7 @@ if [[ -z "$1" ]]; then COMPILER=bin/c_compiler + #COMPILER=test_deliverable/c_compiler_ref.sh else COMPILER=bin/c_compiler make clean @@ -23,37 +24,38 @@ for DRIVER in test_deliverable/testcases/*_driver.c ; do NAME=$(basename $DRIVER _driver.c) TESTCODE=test_deliverable/testcases/$NAME.c - >&2 echo "Test case $NAME" + printf "Test case %-15s :\t" $NAME # Compile driver with normal GCC mips-linux-gnu-gcc -c $DRIVER -o working/${NAME}_driver.o 2> working/${NAME}_driver.compile.stderr if [[ $? -ne 0 ]]; then - >&2 echo "ERROR : Couldn't compile driver program using GCC." + >&2 printf "\e[1;31mError\e[0m : Couldn't compile driver program using GCC.\n" continue fi # Compile test function with compiler under test to assembly cat $TESTCODE | $COMPILER > working/$NAME.s 2> working/${NAME}.compile.stderr if [[ $? -ne 0 ]]; then - >&2 echo "ERROR : Compiler returned error message." + >&2 printf "\e[1;31mError\e[0m : Compiler returned error message.\n" continue fi # Link driver object and assembly into executable mips-linux-gnu-gcc -static working/${NAME}.s working/${NAME}_driver.o -o working/${NAME}.elf 2> working/${NAME}.link.stderr if [[ $? -ne 0 ]]; then - >&2 echo "ERROR : Linker returned error message." + >&2 printf "\e[1;31mError\e[0m : Linker returned error message.\n" continue fi # Run the actual executable qemu-mips working/${NAME}.elf - if [[ $? -ne 0 ]]; then - >&2 echo "ERROR : Testcase returned $?, but expected 0." + RESULT=$? + if [[ "$RESULT" -ne 0 ]]; then + >&2 printf "\e[1;31mError\e[0m : Testcase returned $RESULT, but expected 0.\n" continue fi - echo "pass" + printf "\e[1;32mPass\e[0m\n" PASSED=$(( PASSED+1 )) done diff --git a/test_deliverable/c_compiler_ref.sh b/test_deliverable/c_compiler_ref.sh index a55b56d..a55b56d 100644..100755 --- a/test_deliverable/c_compiler_ref.sh +++ b/test_deliverable/c_compiler_ref.sh diff --git a/test_deliverable/testcases/test_DIV.c b/test_deliverable/testcases/test_DIV.c new file mode 100644 index 0000000..35e81bb --- /dev/null +++ b/test_deliverable/testcases/test_DIV.c @@ -0,0 +1,4 @@ +int div(int a, int b) +{ + return a / b; +} diff --git a/test_deliverable/testcases/test_DIV_driver.c b/test_deliverable/testcases/test_DIV_driver.c new file mode 100644 index 0000000..3ceef28 --- /dev/null +++ b/test_deliverable/testcases/test_DIV_driver.c @@ -0,0 +1,6 @@ +int div(int, int); + +int main() +{ + return !( 4818 == div(4692732, 974) ); +} diff --git a/test_deliverable/testcases/test_GLOBAL.c b/test_deliverable/testcases/test_GLOBAL.c new file mode 100644 index 0000000..7397995 --- /dev/null +++ b/test_deliverable/testcases/test_GLOBAL.c @@ -0,0 +1 @@ +int x = 23992; diff --git a/test_deliverable/testcases/test_GLOBAL_driver.c b/test_deliverable/testcases/test_GLOBAL_driver.c new file mode 100644 index 0000000..6f62195 --- /dev/null +++ b/test_deliverable/testcases/test_GLOBAL_driver.c @@ -0,0 +1,6 @@ +extern int x; + +int main() +{ + return !( x == 23992 ); +} diff --git a/test_deliverable/testcases/test_IFELSEF.c b/test_deliverable/testcases/test_IFELSEF.c new file mode 100644 index 0000000..255926e --- /dev/null +++ b/test_deliverable/testcases/test_IFELSEF.c @@ -0,0 +1,7 @@ +int ifelsef(int a, int b) +{ + if(a) + return a; + else + return b; +} diff --git a/test_deliverable/testcases/test_IFELSEF_driver.c b/test_deliverable/testcases/test_IFELSEF_driver.c new file mode 100644 index 0000000..9c2613b --- /dev/null +++ b/test_deliverable/testcases/test_IFELSEF_driver.c @@ -0,0 +1,6 @@ +int ifelsef(int a, int b); + +int main() +{ + return !( 39 == ifelsef(0, 39) ); +} diff --git a/test_deliverable/testcases/test_IFELSET.c b/test_deliverable/testcases/test_IFELSET.c new file mode 100644 index 0000000..d2c7a17 --- /dev/null +++ b/test_deliverable/testcases/test_IFELSET.c @@ -0,0 +1,7 @@ +int ifelset(int a, int b) +{ + if(a) + return b; + else + return a; +} diff --git a/test_deliverable/testcases/test_IFELSET_driver.c b/test_deliverable/testcases/test_IFELSET_driver.c new file mode 100644 index 0000000..7d79fde --- /dev/null +++ b/test_deliverable/testcases/test_IFELSET_driver.c @@ -0,0 +1,6 @@ +int ifelset(int a, int b); + +int main() +{ + return !( 72 == ifelset(1, 72) ); +} diff --git a/test_deliverable/testcases/test_IFF.c b/test_deliverable/testcases/test_IFF.c new file mode 100644 index 0000000..ddca839 --- /dev/null +++ b/test_deliverable/testcases/test_IFF.c @@ -0,0 +1,6 @@ +int iff(int a, int b) +{ + if(a) + return a; + return b; +} diff --git a/test_deliverable/testcases/test_IFF_driver.c b/test_deliverable/testcases/test_IFF_driver.c new file mode 100644 index 0000000..c544fbe --- /dev/null +++ b/test_deliverable/testcases/test_IFF_driver.c @@ -0,0 +1,6 @@ +int iff(int a, int b); + +int main() +{ + return !( 64 == iff(0, 64) ); +} diff --git a/test_deliverable/testcases/test_IFT.c b/test_deliverable/testcases/test_IFT.c new file mode 100644 index 0000000..4c83e6e --- /dev/null +++ b/test_deliverable/testcases/test_IFT.c @@ -0,0 +1,6 @@ +int ift(int a) +{ + if(a) + return a+5; + return a; +} diff --git a/test_deliverable/testcases/test_IFT_driver.c b/test_deliverable/testcases/test_IFT_driver.c new file mode 100644 index 0000000..707ecae --- /dev/null +++ b/test_deliverable/testcases/test_IFT_driver.c @@ -0,0 +1,6 @@ +int ift(int a); + +int main() +{ + return !( 23 == ift(18) ); +} diff --git a/test_deliverable/testcases/test_MAIN.c b/test_deliverable/testcases/test_MAIN.c new file mode 100644 index 0000000..3f4ad49 --- /dev/null +++ b/test_deliverable/testcases/test_MAIN.c @@ -0,0 +1,6 @@ +int f(int x); + +int main() +{ + return ( 567846 != f(283923) ); +} diff --git a/test_deliverable/testcases/test_MAIN_driver.c b/test_deliverable/testcases/test_MAIN_driver.c new file mode 100644 index 0000000..bc24572 --- /dev/null +++ b/test_deliverable/testcases/test_MAIN_driver.c @@ -0,0 +1,4 @@ +int f(int x) +{ + return 2*x; +} diff --git a/test_deliverable/testcases/test_MULT.c b/test_deliverable/testcases/test_MULT.c new file mode 100644 index 0000000..96d8614 --- /dev/null +++ b/test_deliverable/testcases/test_MULT.c @@ -0,0 +1,4 @@ +int mult(int a, int b) +{ + return a*b; +} diff --git a/test_deliverable/testcases/test_MULT_driver.c b/test_deliverable/testcases/test_MULT_driver.c new file mode 100644 index 0000000..6dbfa85 --- /dev/null +++ b/test_deliverable/testcases/test_MULT_driver.c @@ -0,0 +1,6 @@ +int mult(int, int); + +int main() +{ + return !( 285360 == mult(1230, 232) ); +} diff --git a/test_deliverable/testcases/test_PLUSEQUAL.c b/test_deliverable/testcases/test_PLUSEQUAL.c new file mode 100644 index 0000000..c22813a --- /dev/null +++ b/test_deliverable/testcases/test_PLUSEQUAL.c @@ -0,0 +1,5 @@ +int plusequal(int a, int b) +{ + a += b; + return a; +} diff --git a/test_deliverable/testcases/test_PLUSEQUAL_driver.c b/test_deliverable/testcases/test_PLUSEQUAL_driver.c new file mode 100644 index 0000000..14102eb --- /dev/null +++ b/test_deliverable/testcases/test_PLUSEQUAL_driver.c @@ -0,0 +1,6 @@ +int plusequal(int, int); + +int main() +{ + return !( 27348 == plusequal(12372, 14976) ); +} diff --git a/test_deliverable/testcases/test_RECURSION.c b/test_deliverable/testcases/test_RECURSION.c new file mode 100644 index 0000000..0a27416 --- /dev/null +++ b/test_deliverable/testcases/test_RECURSION.c @@ -0,0 +1,9 @@ +int Fibonacci(int n) +{ + if ( n == 0 ) + return 0; + else if ( n == 1 ) + return 1; + else + return ( Fibonacci(n-1) + Fibonacci(n-2) ); +} diff --git a/test_deliverable/testcases/test_RECURSION_driver.c b/test_deliverable/testcases/test_RECURSION_driver.c new file mode 100644 index 0000000..51af6a2 --- /dev/null +++ b/test_deliverable/testcases/test_RECURSION_driver.c @@ -0,0 +1,6 @@ +int Fibonacci(int n); + +int main() +{ + return !( 144 == Fibonacci(12) ); +} diff --git a/test_deliverable/testcases/test_REMAINDER.c b/test_deliverable/testcases/test_REMAINDER.c new file mode 100644 index 0000000..b995ede --- /dev/null +++ b/test_deliverable/testcases/test_REMAINDER.c @@ -0,0 +1,4 @@ +int rem(int a, int b) +{ + return a%b; +} diff --git a/test_deliverable/testcases/test_REMAINDER_driver.c b/test_deliverable/testcases/test_REMAINDER_driver.c new file mode 100644 index 0000000..de86c7c --- /dev/null +++ b/test_deliverable/testcases/test_REMAINDER_driver.c @@ -0,0 +1,6 @@ +int rem(int, int); + +int main() +{ + return !( 67 == rem(67, 100) ); +} diff --git a/test_deliverable/testcases/test_SHIFTEQ.c b/test_deliverable/testcases/test_SHIFTEQ.c new file mode 100644 index 0000000..90db452 --- /dev/null +++ b/test_deliverable/testcases/test_SHIFTEQ.c @@ -0,0 +1,5 @@ +int shifteq(int a, int b) +{ + a <<= b; + return a; +} diff --git a/test_deliverable/testcases/test_SHIFTEQ_driver.c b/test_deliverable/testcases/test_SHIFTEQ_driver.c new file mode 100644 index 0000000..a1df965 --- /dev/null +++ b/test_deliverable/testcases/test_SHIFTEQ_driver.c @@ -0,0 +1,6 @@ +int shifteq(int, int); + +int main() +{ + return !( 16 == shifteq(2, 3) ); +} diff --git a/test_deliverable/testcases/test_SUB.c b/test_deliverable/testcases/test_SUB.c new file mode 100644 index 0000000..b151ec4 --- /dev/null +++ b/test_deliverable/testcases/test_SUB.c @@ -0,0 +1,4 @@ +int sub(int a, int b) +{ + return a - b; +} diff --git a/test_deliverable/testcases/test_SUB_driver.c b/test_deliverable/testcases/test_SUB_driver.c new file mode 100644 index 0000000..21ed408 --- /dev/null +++ b/test_deliverable/testcases/test_SUB_driver.c @@ -0,0 +1,6 @@ +int sub(int, int); + +int main() +{ + return !( 37355 == sub(61237, 23882) ); +} diff --git a/test_deliverable/testcases/test_WHILE0.c b/test_deliverable/testcases/test_WHILE0.c new file mode 100644 index 0000000..ae0df87 --- /dev/null +++ b/test_deliverable/testcases/test_WHILE0.c @@ -0,0 +1,9 @@ +int while0(int a, int b) +{ + while(0) + { + a = b; + } + + return a; +} diff --git a/test_deliverable/testcases/test_WHILE0_driver.c b/test_deliverable/testcases/test_WHILE0_driver.c new file mode 100644 index 0000000..fc13491 --- /dev/null +++ b/test_deliverable/testcases/test_WHILE0_driver.c @@ -0,0 +1,6 @@ +int while0(int a, int b); + +int main() +{ + return !( 5613266 == while0(5613266, 389) ); +} diff --git a/test_deliverable/testcases/test_WHILEN.c b/test_deliverable/testcases/test_WHILEN.c new file mode 100644 index 0000000..ac6d6aa --- /dev/null +++ b/test_deliverable/testcases/test_WHILEN.c @@ -0,0 +1,9 @@ +int whilen(int a, int b) +{ + while(a <= b) + { + a = a + 1; + } + + return a; +} diff --git a/test_deliverable/testcases/test_WHILEN_driver.c b/test_deliverable/testcases/test_WHILEN_driver.c new file mode 100644 index 0000000..16dc784 --- /dev/null +++ b/test_deliverable/testcases/test_WHILEN_driver.c @@ -0,0 +1,6 @@ +int whilen(int a, int b); + +int main() +{ + return !( 45367294 == whilen(45362000, 45367293) ); +} |