From 190b7a0e5d45367230795ac0bdf6fc2f248ba9e1 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 21 Mar 2017 17:03:38 +0000 Subject: changed type layout to have all necessary information --- Notes.org | 5 + c_compiler/include/declaration.hpp | 1 + c_compiler/include/expression.hpp | 38 +++++--- c_compiler/include/type.hpp | 86 +++++++++++------ c_compiler/src/c_lexer.flex | 31 +++--- c_compiler/src/c_parser.y | 130 +++++++++++++++++-------- c_compiler/src/declaration.cpp | 6 +- c_compiler/src/expression.cpp | 190 +++++++++++++++++++++++-------------- c_compiler/src/type.cpp | 136 ++++++++++++++++++++++++-- c_compiler/test/in/fib.c | 20 ++++ c_compiler/test/in/fib_recusive.c | 24 +++++ c_compiler/test/in/for.c | 5 +- 12 files changed, 491 insertions(+), 181 deletions(-) create mode 100644 c_compiler/test/in/fib.c create mode 100644 c_compiler/test/in/fib_recusive.c diff --git a/Notes.org b/Notes.org index a5e33b7..a3046ae 100644 --- a/Notes.org +++ b/Notes.org @@ -157,3 +157,8 @@ the globalAsm function. I might have to change the print Asm and the global Asm function in the declarations. +**** TODO Add post and pre increment + CLOCK: [2017-03-20 Mon 15:12] + + For post increment I will have a special class that handles that, + for pre increment I will rewrite in terms of addition, which should be possible. diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index d09faec..76f0efc 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -19,6 +19,7 @@ private: ExpressionPtr initializer_; DeclarationPtr next_declaration_; DeclarationPtr next_list_declaration_; + bool extern_declaration; public: Declaration(const std::string& id = "", Expression* initializer = nullptr); diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 1563211..21e5880 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -26,13 +26,11 @@ public: virtual void print() const; virtual void printXml() const; virtual void countArguments(unsigned& argument_count) const; - virtual void expressionDepth(unsigned& depth_count) const; - + virtual void expressionDepth(unsigned& depth_count) const; virtual int postfixStackPosition(VariableStackBindings bindings) const; virtual void setPostfixExpression(Expression* postfix_expression); - virtual std::string id() const; - + void linkExpression(Expression* next_expression); ExpressionPtr nextExpression() const; }; @@ -47,21 +45,14 @@ public: OperationExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0; + virtual int constantFold() const; virtual void expressionDepth(unsigned& depth_count) const; + void evaluateExpression(VariableStackBindings bindings, unsigned& label_count) const; }; -class PostfixExpression : public Expression -{ -public: - PostfixExpression(); - - virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; -}; - - class PostfixArrayElement : public Expression { public: @@ -86,11 +77,28 @@ public: void setPostfixExpression(Expression* postfix_expression); }; +class PostfixPostIncDecExpression : public Expression +{ +private: + std::string operator_; + ExpressionPtr postfix_expression_; + +public: + PostfixPostIncDecExpression(const std::string& _operator, Expression* postfix_expression); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + +}; + -class UnaryExpression : public Expression +class UnaryPreIncDecExpression : public Expression { +private: + std::string operator_; + ExpressionPtr unary_expression_; + public: - UnaryExpression(); + UnaryPreIncDecExpression(const std::string& _operator, Expression* unary_expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; }; diff --git a/c_compiler/include/type.hpp b/c_compiler/include/type.hpp index 9b9bbba..bd9fd4b 100644 --- a/c_compiler/include/type.hpp +++ b/c_compiler/include/type.hpp @@ -8,71 +8,101 @@ #include class Type; - typedef std::shared_ptr TypePtr; - -class Type : public Node { +class Type : public Node +{ public: virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; virtual std::string getType() const = 0; -}; + virtual TypePtr type(); + virtual TypePtr type(Type* type_ptr); + virtual TypePtr type(TypePtr type_ptr); + 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); +}; -class Specifier : public Type { +class Array : public Type +{ public: - virtual std::string getType() const = 0; + Array(); + virtual std::string getType() const; }; - -class Pointer : public Type { -protected: - TypePtr pointer_type_; - +class Pointer : public Type +{ public: - Pointer(Type* pointer_type); - + Pointer(); virtual std::string getType() const; }; - -class Array : public Type { +class TypeContainer : public Type +{ protected: - TypePtr array_type_; - unsigned size_; + TypePtr type_; + int size_; + bool extern_; + bool static_; + bool const_; + bool signed_; public: - Array(Type* array_type, unsigned size = 0); - + TypeContainer(); + virtual std::string getType() const; + virtual TypePtr type(); + virtual TypePtr type(Type* type_ptr); + virtual TypePtr type(TypePtr type_ptr); + 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); }; - -class Void : public Specifier { +class Specifier : public Type +{ public: - Void(); - - virtual std::string getType() const; + virtual std::string getType() const = 0; }; - -class Int : public Specifier { +class Int : public Specifier +{ public: Int(); virtual std::string getType() const; }; +class Void : public Specifier +{ +public: + Void(); + + virtual std::string getType() const; +}; -class Char : public Specifier { +class Char : public Specifier +{ public: Char(); - virtual std::string getType() const; + virtual std::string getType() const; }; +class Float : public Specifier +{ +public: + Float(); + + virtual std::string getType() const; +}; #endif diff --git a/c_compiler/src/c_lexer.flex b/c_compiler/src/c_lexer.flex index a761343..90790b5 100644 --- a/c_compiler/src/c_lexer.flex +++ b/c_compiler/src/c_lexer.flex @@ -28,17 +28,24 @@ ALL . %% -(void) { return T_VOID; } -(char) { return T_CHAR; } -(signed[ ]char) { return T_SCHAR; } -(unsigned[ ]char) { return T_UCHAR; } -((short[ ]int)|(signed[ ]short[ ]int)|short|(signed[ ]short)) { return T_SSINT; } -((unsigned[ ]short[ ]int)|(unsigned[ ]short)) { return T_USINT; } -((signed[ ]long[ ]int)|(signed[ ]long)|(long[ ]int)|long) { return T_LINT; } -((unsigned[ ]long[ ]int)|(unsigned[ ]long)) { return T_ULINT; } -((unsigned[ ]int)|unsigned) { return T_UINT; } -((signed[ ]int)|int|signed) { return T_SINT; } - +(void) { return T_VOID; } +(char) { return T_CHAR; } +(short) { return T_SHORT; } +(int) { return T_INT; } +(long) { return T_LONG; } +(float) { return T_FLOAT; } +(double) { return T_DOUBLE; } +(signed) { return T_SIGNED; } +(unsigned) { return T_UNSIGNED; } + +(typedef) { return T_TYPEDEF; } +(extern) { return T_EXTERN; } +(static) { return T_STATIC; } +(auto) { return T_AUTO; } +(register) { return T_REGISTER; } + +(const) { return T_CONST; } +(volatile) { return T_VOLATILE; } [;] { return T_SC; } [,] { return T_CMA; } @@ -66,7 +73,7 @@ ALL . [!] { return T_NOT; } [.] { return T_DOT; } [-][>] { return T_ARROW; } -[+-][+-] { return T_INCDEC; } +[+-][+-] { 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; } diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index 6375053..1fb2777 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -10,6 +10,7 @@ extern Node* g_root; // A way of getting the AST out +void setTypeInformation(Type* type_ptr, std::string type_str); //! This is to fix problems when generating C++ // We are declaring the functions provided by Flex, so @@ -38,7 +39,11 @@ void yyerror(const char *); T_REM T_TILDE T_NOT T_DOT T_ARROW T_INCDEC T_ADDSUB_OP T_ASSIGN_OPER T_EQ T_SIZEOF T_INT_CONST T_IF T_WHILE T_DO T_FOR T_RETURN - T_VOID T_CHAR T_SCHAR T_UCHAR T_SSINT T_USINT T_LINT T_ULINT T_UINT T_SINT + T_VOID T_CHAR T_SHORT T_INT T_LONG T_FLOAT T_DOUBLE T_SIGNED T_UNSIGNED + + T_TYPEDEF T_EXTERN T_STATIC T_AUTO T_REGISTER + + T_CONST T_VOLATILE %nonassoc T_RRB %nonassoc T_ELSE @@ -66,11 +71,13 @@ void yyerror(const char *); PostfixExpression PostfixExpression2 ArgumentExpressionList PrimaryExpression Constant +%type DeclarationSpecifierList + %type T_INT_CONST %type T_IDENTIFIER ASSIGN_OPER T_ASSIGN_OPER T_EQ T_AND T_ADDSUB_OP T_TILDE T_NOT - T_MULT T_DIV T_REM T_EQUALITY_OP T_REL_OP T_SHIFT_OP MultDivRemOP UnaryOperator - DeclarationSpec + T_MULT T_DIV T_REM T_EQUALITY_OP T_REL_OP T_SHIFT_OP T_INCDEC MultDivRemOP + UnaryOperator DeclarationSpecifier %start ROOT @@ -95,7 +102,7 @@ ExternalDeclaration: // FUNCTION DEFINITION FunctionDefinition: - DeclarationSpec Declarator CompoundStatement + DeclarationSpecifierList Declarator CompoundStatement { $$ = new Function($2->getId(), $3, $2->getNext()); delete $1; } ; @@ -105,7 +112,7 @@ ParameterList: | ParameterList T_CMA Parameter { $3->linkDeclaration($$); $$ = $3; } ; -Parameter: DeclarationSpec T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; } +Parameter: DeclarationSpecifierList T_IDENTIFIER { $$ = new Declaration(*$2); delete $2; delete $1; } ; // Declaration @@ -115,36 +122,48 @@ DeclarationList: | DeclarationList Declaration { $2->linkDeclaration($$); $$ = $2; } ; -Declaration: DeclarationSpec InitDeclaratorList T_SC +Declaration: DeclarationSpecifierList InitDeclaratorList T_SC { $$ = $2; Declaration* tmp_decl = $2; + Type* tmp_type = new TypeContainer(); while(tmp_decl != nullptr) { - if(*$1 == "void") { - tmp_decl->setType(new Void); - } else if(*$1 == "char") { - tmp_decl->setType(new Char); - } else { - tmp_decl->setType(new Int); - } + tmp_type->type($1->type()); tmp_decl = tmp_decl->getNextListItem().get(); } delete $1; }; -DeclarationSpec: +DeclarationSpecifierList: + DeclarationSpecifier + { + $$ = new TypeContainer(); + setTypeInformation($$, *$1); + delete $1; + } + | DeclarationSpecifierList DeclarationSpecifier + { setTypeInformation($$, *$2); delete $2; } + ; + +DeclarationSpecifier: T_VOID { $$ = new std::string("void"); } | T_CHAR { $$ = new std::string("char"); } - | T_SCHAR { $$ = new std::string("char"); } - | T_UCHAR { $$ = new std::string("char"); } - | T_SSINT { $$ = new std::string("int"); } - | T_USINT { $$ = new std::string("int"); } - | T_LINT { $$ = new std::string("int"); } - | T_ULINT { $$ = new std::string("int"); } - | T_UINT { $$ = new std::string("int"); } - | T_SINT { $$ = new std::string("int"); } + | T_SHORT { $$ = new std::string("short"); } + | T_INT { $$ = new std::string("int"); } + | T_LONG { $$ = new std::string("long"); } + | T_FLOAT { $$ = new std::string("float"); } + | T_DOUBLE { $$ = new std::string("double"); } + | T_SIGNED { $$ = new std::string("signed"); } + | T_UNSIGNED { $$ = new std::string("unsigned"); } + | T_TYPEDEF { $$ = new std::string("typedef"); } + | T_EXTERN { $$ = new std::string("extern"); } + | T_STATIC { $$ = new std::string("static"); } + | T_AUTO { $$ = new std::string("auto"); } + | T_REGISTER { $$ = new std::string("register"); } + | T_CONST { $$ = new std::string("const"); } + | T_VOLATILE { $$ = new std::string("volatile"); } ; InitDeclaratorList: @@ -298,26 +317,16 @@ MultDivRemOP: T_MULT { $$ = $1; } ; CastExpression: UnaryExpression { $$ = $1; } - | T_LRB DeclarationSpec T_RRB CastExpression - { - if(*$2 == "int") { - $$ = new CastExpression(new Int, $4); - } else if(*$2 == "char") { - $$ = new CastExpression(new Char, $4); - } else { - $$ = new CastExpression(new Void, $4); - } - - delete $2; - } + | T_LRB DeclarationSpecifierList T_RRB CastExpression + { new CastExpression($2, $4); delete $2; } ; UnaryExpression: PostfixExpression { $$ = $1; } - | T_INCDEC UnaryExpression { $$ = $2; } + | T_INCDEC UnaryExpression { $$ = new UnaryPreIncDecExpression(*$1, $2); delete $1; } | UnaryOperator CastExpression { $$ = $2; } | T_SIZEOF UnaryExpression { $$ = $2; } - | T_SIZEOF T_LRB DeclarationSpec T_RRB { $$ = new Constant(0); delete $3; } + | T_SIZEOF T_LRB DeclarationSpecifierList T_RRB { $$ = new Constant(0); delete $3; } ; UnaryOperator: T_AND { $$ = $1; } @@ -333,7 +342,8 @@ PostfixExpression: | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; $$->setPostfixExpression($1); } | PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; } | PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; } - | PostfixExpression T_INCDEC { $$ = $1; } + | PostfixExpression T_INCDEC + { $$ = new PostfixPostIncDecExpression(*$2, $1); delete $2; } ; PostfixExpression2: @@ -359,8 +369,52 @@ Constant: T_INT_CONST { $$ = new Constant($1); } Node* g_root; // Definition of variable (to match declaration earlier) -Node* parseAST() { +Node* parseAST() +{ g_root = 0; yyparse(); return g_root; } + +void setTypeInformation(Type* type_ptr, std::string type_str) +{ + if(type_str == "void") { + 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); + } else if(type_str == "int") { + type_ptr->type(new Int()); + } else if(type_str == "long") { + type_ptr->type(new Int()); + } else if(type_str == "float") { + type_ptr->type(new Float()); + } else if(type_str == "double") { + type_ptr->type(new Float()); + } else if(type_str == "signed") { + type_ptr->type(new Int()); + type_ptr->setSigned(true); + } else if(type_str == "unsigned") { + type_ptr->type(new Int()); + type_ptr->setSigned(false); + } else if(type_str == "typedef") { + // TODO do typedef + } else if(type_str == "extern") { + type_ptr->setExtern(true); + } else if(type_str == "static") { + 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") { + type_ptr->setConst(true); + } else if(type_str == "volatile") { + // TODO do volatile + } else { + + } +} diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index 9aa647a..417aa84 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -26,9 +26,8 @@ void Declaration::printXml() const if(next_declaration_ != nullptr) next_declaration_->printXml(); - if(next_list_declaration_ != nullptr) { + if(next_list_declaration_ != nullptr) next_list_declaration_->printXml(); - } if(id_ != "") printf("", id_.c_str()); @@ -56,7 +55,8 @@ VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsi if(next_list_declaration_ != nullptr) bindings = next_list_declaration_->localAsm(bindings, label_count); - if(id_ != "") { + if(id_ != "") + { if(initializer_ != nullptr) initializer_->printAsm(bindings, label_count); else diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index bd64325..cdf7d0a 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -2,7 +2,6 @@ #include #include -#include #include // Expression definition @@ -102,18 +101,6 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns lhs_stack_position, bindings.currentExpressionStackPosition()); } - -// PostfixExpression definition - -PostfixExpression::PostfixExpression() -{} - -VariableStackBindings PostfixExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const -{ - return bindings; -} - - // PostfixArrayElement PostfixArrayElement::PostfixArrayElement() @@ -137,12 +124,14 @@ VariableStackBindings PostfixFunctionCall::printAsm(VariableStackBindings bindin ExpressionPtr current_argument = argument_expression_list_; unsigned argument_counter = 0; - while(current_argument != nullptr) { + while(current_argument != nullptr) + { argument_vector.push_back(current_argument); current_argument = current_argument->nextExpression(); } - for(auto itr = argument_vector.rbegin(); itr != argument_vector.rend(); ++itr) { + for(auto itr = argument_vector.rbegin(); itr != argument_vector.rend(); ++itr) + { (*itr)->printAsm(bindings, label_count); if(argument_counter < 4) @@ -164,7 +153,8 @@ void PostfixFunctionCall::countArguments(unsigned int &argument_count) const argument_count = 0; - while(current_argument != nullptr) { + while(current_argument != nullptr) + { argument_count++; current_argument = current_argument->nextExpression(); } @@ -177,13 +167,46 @@ void PostfixFunctionCall::setPostfixExpression(Expression* postfix_expression) } -// UnaryExpression definition +// Post increment and decrement definition -UnaryExpression::UnaryExpression() +PostfixPostIncDecExpression::PostfixPostIncDecExpression(const std::string& _operator, Expression* postfix_expression) + : operator_(_operator), postfix_expression_(postfix_expression) {} -VariableStackBindings UnaryExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const +VariableStackBindings PostfixPostIncDecExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + postfix_expression_->printAsm(bindings, label_count); + if(operator_ == "++") + printf("\taddi\t$3,$2,1\n"); + else if(operator_ == "--") + printf("\tsubi\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)); + return bindings; +} + + +// Pre increment and decrement implementation + +UnaryPreIncDecExpression::UnaryPreIncDecExpression(const std::string& _operator, Expression* unary_expression) + : operator_(_operator), unary_expression_(unary_expression) +{} + +VariableStackBindings UnaryPreIncDecExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const +{ + unary_expression_->printAsm(bindings, label_count); + if(operator_ == "++") + printf("\taddi\t$2,$2,1\n"); + else if(operator_ == "--") + 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)); return bindings; } @@ -245,17 +268,20 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b evaluateExpression(bindings, label_count); // then perform the right operation - if(operator_ == "*") { - printf("\tmul\t$2,$2,$3\n"); - - } else if(operator_ == "/" || operator_ == "%") { + if(operator_ == "*") + { + printf("\tmul\t$2,$2,$3\n"); + } + else if(operator_ == "/" || operator_ == "%") + { printf("\tdiv\t$2,$3\n"); if(operator_ == "/") printf("\tmflo\t$2\n"); else - printf("\tmfhi\t$2\n"); - - } else { + printf("\tmfhi\t$2\n"); + } + else + { throw std::runtime_error("Error : '"+operator_+"' not recognized"); } @@ -286,15 +312,20 @@ VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings, { evaluateExpression(bindings, label_count); - if(operator_ == "<<") { - std::cout << "\tsll\t$2,$2,$3\n"; - } else if(operator_ == ">>") { - std::cout << "\tsra\t$2,$2,$3\n"; - } else { - std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; + if(operator_ == "<<") + { + printf("\tsll\t$2,$2,$3\n"); + } + else if(operator_ == ">>") + { + printf("\tsra\t$2,$2,$3\n"); + } + else + { + throw std::runtime_error("Error : '"+operator_+"' not recognized"); } - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } @@ -317,34 +348,47 @@ VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindi { evaluateExpression(bindings, label_count); - if(operator_ == "<") { - std::cout << "\tslt\t$2,$2,$3\n"; - } else if(operator_ == ">") { - std::cout << "\tslt\t$2,$3,$2\n"; - } else if(operator_ == "<=") { - std::cout << "\tslt\t$2,$3,$2\n\txori\t$2,$2,0x1\n"; - } else if(operator_ == ">=") { - std::cout << "\tslt\t$2,$2,$3\n\txori\t$2,$2,0x1\n"; - } else { - std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; + if(operator_ == "<") + { + printf("\tslt\t$2,$2,$3\n"); + } + else if(operator_ == ">") + { + printf("\tslt\t$2,$3,$2\n"); + } + else if(operator_ == "<=") + { + printf("\tslt\t$2,$3,$2\n\txori\t$2,$2,0x1\n"); + } + else if(operator_ == ">=") + { + printf("\tslt\t$2,$2,$3\n\txori\t$2,$2,0x1\n"); + } + else + { + throw std::runtime_error("Error : '"+operator_+"' not recognized"); } // TODO might get rid of this - std::cout << "\tandi\t$2,$2,0x00ff\n"; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\tandi\t$2,$2,0x00ff\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } int RelationalExpression::constantFold() const { if(operator_ == "<") + { return lhs_->constantFold()constantFold(); + } else if(operator_ == ">") + { return lhs_->constantFold()>rhs_->constantFold(); + } else if(operator_ == "<=") + { return lhs_->constantFold()<=rhs_->constantFold(); + } + return lhs_->constantFold()>=rhs_->constantFold(); } @@ -358,22 +402,23 @@ EqualityExpression::EqualityExpression(Expression* lhs, const std::string& _oper VariableStackBindings EqualityExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { evaluateExpression(bindings, label_count); + printf("\txor\t$2,$2,$3\n"); - std::cout << "\txor\t$2,$2,$3\n"; - - if(operator_ == "==") { - std::cout << "\tsltiu\t$2,$2,1\n"; - } else if(operator_ == "!="){ - std::cout << "\tsltu\t$2,$0,$2\n"; - } else { - std::cerr << "Error : no instruction found for operator '" << operator_ << "'\n"; + if(operator_ == "==") + { + printf("\tsltiu\t$2,$2,1\n"); + } + else if(operator_ == "!=") + { + printf("\tsltu\t$2,$0,$2\n"); + } + else + { + throw std::runtime_error("Error : '"+operator_+"' not recognized"); } // TODO Work out why it is necessary to remove bytes 3 and 2. - std::cout << "\tandi\t$2,$2,0x00ff\n"; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\tandi\t$2,$2,0x00ff\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } @@ -394,11 +439,7 @@ AndExpression::AndExpression(Expression* lhs, Expression* rhs) VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { evaluateExpression(bindings, label_count); - - std::cout << "\tand\t$2,$2,$3\n"; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\tand\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } @@ -534,16 +575,20 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig { (void)label_count; - if(bindings.bindingExists(id_)) { - if(bindings.stackPosition(id_) == -1) { + if(bindings.bindingExists(id_)) + { + if(bindings.stackPosition(id_) == -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("\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_)); } - - } else{ + } + else + { throw std::runtime_error("Error : Can't find '"+id_+"' in current scope binding"); } @@ -553,7 +598,8 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsig int Identifier::postfixStackPosition(VariableStackBindings bindings) const { - if(bindings.bindingExists(id_)) { + if(bindings.bindingExists(id_)) + { return bindings.stackPosition(id_); } diff --git a/c_compiler/src/type.cpp b/c_compiler/src/type.cpp index 44c4ddb..a72807a 100644 --- a/c_compiler/src/type.cpp +++ b/c_compiler/src/type.cpp @@ -1,5 +1,6 @@ #include "type.hpp" +#include #include @@ -15,45 +16,138 @@ void Type::printXml() const VariableStackBindings Type::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + (void)label_count; return bindings; } +TypePtr Type::type() +{ + throw std::runtime_error("Error : does not have a type"); +} + +TypePtr Type::type(Type* type_ptr) +{ + (void) type_ptr; + throw std::runtime_error("Error : cannot assign type"); +} + +TypePtr Type::type(TypePtr type_ptr) +{ + (void)type_ptr; + throw std::runtime_error("Error : cannot assign type"); +} + +void Type::setSigned(bool _signed) +{ + (void)_signed; + throw std::runtime_error("Error : cannot set sign"); +} + +void Type::setExtern(bool _extern) +{ + (void)_extern; + throw std::runtime_error("Error : cannot set extern"); +} + +void Type::setStatic(bool _static) +{ + (void)_static; + throw std::runtime_error("Error : cannot set static"); +} + +void Type::setConst(bool _const) +{ + (void)_const; + throw std::runtime_error("Error : cannot set const"); +} + +void Type::setSize(int _size) +{ + (void)_size; + throw std::runtime_error("Error : cannot set size"); +} + // Pointer definition -Pointer::Pointer(Type* pointer_type) : pointer_type_(pointer_type) +Pointer::Pointer() {} std::string Pointer::getType() const { - return "pointer " + pointer_type_->getType(); + return "pointer"; } // Array definition -Array::Array(Type* array_type, unsigned size) - : array_type_(array_type), size_(size) +Array::Array() {} std::string Array::getType() const { - return "array " + array_type_->getType(); + return "array"; } -// Void definition +// TypeContainer definition -Void::Void() +TypeContainer::TypeContainer() + : type_(nullptr), size_(32), extern_(false), static_(false), const_(false), signed_(true) {} -std::string Void::getType() const +std::string TypeContainer::getType() const { - return "void"; + return type_->getType(); } +TypePtr TypeContainer::type() +{ + return type_; +} + +TypePtr TypeContainer::type(Type* type_ptr) +{ + TypePtr new_type_ptr(type_ptr); + type_ = new_type_ptr; -// Int defintion + return type_; +} + +TypePtr TypeContainer::type(TypePtr type_ptr) +{ + type_ = type_ptr; + + return type_; +} + +void TypeContainer::setSigned(bool _signed) +{ + signed_ = _signed; +} + +void TypeContainer::setExtern(bool _extern) +{ + extern_ = _extern; +} + +void TypeContainer::setStatic(bool _static) +{ + static_ = _static; +} + +void TypeContainer::setConst(bool _const) +{ + const_ = _const; +} + +void TypeContainer::setSize(int size) +{ + size_ = size; +} + + +// Int definition Int::Int() {} @@ -64,6 +158,17 @@ std::string Int::getType() const } +// Void definition + +Void::Void() +{} + +std::string Void::getType() const +{ + return "void"; +} + + // Char definition Char::Char() @@ -73,3 +178,14 @@ std::string Char::getType() const { return "char"; } + + +// Float definition + +Float::Float() +{} + +std::string Float::getType() const +{ + return "float"; +} diff --git a/c_compiler/test/in/fib.c b/c_compiler/test/in/fib.c new file mode 100644 index 0000000..17a3b41 --- /dev/null +++ b/c_compiler/test/in/fib.c @@ -0,0 +1,20 @@ +int main() +{ + int n, first = 0, second = 1, next, c; + + n = 10; + + for ( c = 0 ; c < n ; c++ ) + { + if ( c <= 1 ) + next = c; + else + { + next = first + second; + first = second; + second = next; + } + } + + return next; +} diff --git a/c_compiler/test/in/fib_recusive.c b/c_compiler/test/in/fib_recusive.c new file mode 100644 index 0000000..55abe06 --- /dev/null +++ b/c_compiler/test/in/fib_recusive.c @@ -0,0 +1,24 @@ +int Fibonacci(int n) +{ + if ( n == 0 ) + return 0; + else if ( n == 1 ) + return 1; + else + return ( Fibonacci(n-1) + Fibonacci(n-2) ); +} + +int main() +{ + int n, i = 0, c, res = 0; + + n = 10; + + for ( c = 1 ; c <= n ; c++ ) + { + res = Fibonacci(i); + i++; + } + + return res; +} diff --git a/c_compiler/test/in/for.c b/c_compiler/test/in/for.c index 5163ba5..1f6d104 100644 --- a/c_compiler/test/in/for.c +++ b/c_compiler/test/in/for.c @@ -3,11 +3,10 @@ int main() int x, y, z; y = 0; - for(x = 0; x < 50; x = x+1) { + for(x = 0; x < 50; x++) { y = y + 1; } - z = y + x - 5; - + z = y + x - 6; return z; } -- cgit