diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-20 13:11:19 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-20 13:11:19 +0000 |
commit | af8b76d0a83813b3cebac7468db4bd64e534c235 (patch) | |
tree | e387cec775526f4b0eaea5ab333baf0ae5afdb0b | |
parent | b0caad48b1a2c90a03f5d130a50f3fdee1c097a5 (diff) | |
download | Compiler-af8b76d0a83813b3cebac7468db4bd64e534c235.tar.gz Compiler-af8b76d0a83813b3cebac7468db4bd64e534c235.zip |
global vars work and changing to printf
-rw-r--r-- | Notes.org | 14 | ||||
-rw-r--r-- | c_compiler/include/declaration.hpp | 2 | ||||
-rw-r--r-- | c_compiler/include/expression.hpp | 14 | ||||
-rw-r--r-- | c_compiler/src/compiler_main.cpp | 22 | ||||
-rw-r--r-- | c_compiler/src/declaration.cpp | 40 | ||||
-rw-r--r-- | c_compiler/src/expression.cpp | 172 | ||||
-rw-r--r-- | c_compiler/src/function.cpp | 3 | ||||
-rw-r--r-- | c_compiler/src/statement.cpp | 2 | ||||
-rw-r--r-- | c_compiler/src/translation_unit.cpp | 2 | ||||
-rw-r--r-- | c_compiler/test/in/global.c | 6 |
10 files changed, 200 insertions, 77 deletions
@@ -142,8 +142,18 @@ CLOCK: [2017-03-17 Fri 15:44]--[2017-03-17 Fri 16:00] => 0:16 Have to fix type assigment for declaration lists, need to make new pointers of the right type. -**** TODO Load more that 4 bytes into a variable. -**** TODO Fix expressions and temporary variables +**** DONE Load more that 4 bytes into a variable. +**** DONE Fix expressions and temporary variables I have to store the temporary expression in normal registers. +**** TODO Convert cout to printf + + convert all cout to printf + +**** TODO Add global variables + + Change code so that it also prints global variables. This should be done with + the globalAsm function. + + I might have to change the print Asm and the global Asm function in the declarations. diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index ce4faa7..d09faec 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -27,6 +27,8 @@ public: virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + VariableStackBindings localAsm(VariableStackBindings bindings, unsigned& label_count) const; + void linkDeclaration(Declaration* next_declaration); void linkListDeclaration(Declaration* next_list_declaration); diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index 313d678..1563211 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -22,6 +22,7 @@ private: public: virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const = 0; + virtual int constantFold() const; virtual void print() const; virtual void printXml() const; virtual void countArguments(unsigned& argument_count) const; @@ -46,7 +47,7 @@ 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; }; @@ -117,6 +118,7 @@ public: AdditiveExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -129,6 +131,7 @@ public: MultiplicativeExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -140,6 +143,7 @@ public: ShiftExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -151,6 +155,7 @@ public: RelationalExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -162,6 +167,7 @@ public: EqualityExpression(Expression* lhs, const std::string& _operator, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -171,6 +177,7 @@ public: AndExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -180,6 +187,7 @@ public: ExclusiveOrExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -189,6 +197,7 @@ public: InclusiveOrExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -198,6 +207,7 @@ public: LogicalAndExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -207,6 +217,7 @@ public: LogicalOrExpression(Expression* lhs, Expression* rhs); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; @@ -255,6 +266,7 @@ public: Constant(const int32_t& constant); virtual VariableStackBindings printAsm(VariableStackBindings bindings, unsigned& label_count) const; + virtual int constantFold() const; }; diff --git a/c_compiler/src/compiler_main.cpp b/c_compiler/src/compiler_main.cpp index 15276dd..dcc9e09 100644 --- a/c_compiler/src/compiler_main.cpp +++ b/c_compiler/src/compiler_main.cpp @@ -1,19 +1,27 @@ #include "node.hpp" #include "bindings.hpp" -#include <iostream> +#include <cstdio> +#include <string> Node* parseAST(); int main(int argc, char *argv[]) { (void)argc, (void)argv; - std::unique_ptr<Node> ast(parseAST()); - - VariableStackBindings bindings; - unsigned label_count = 0; - - ast->printAsm(bindings, label_count); + + try { + std::unique_ptr<Node> ast(parseAST()); + VariableStackBindings bindings; + unsigned label_count = 0; + ast->printAsm(bindings, label_count); + + } catch(std::string error_msg) { + fprintf(stderr, "%s\n", error_msg.c_str()); + + } catch(...) { + fprintf(stderr, "Error : Exception thrown\n"); + } return 0; } diff --git a/c_compiler/src/declaration.cpp b/c_compiler/src/declaration.cpp index b25ece4..9aa647a 100644 --- a/c_compiler/src/declaration.cpp +++ b/c_compiler/src/declaration.cpp @@ -3,7 +3,7 @@ #include "type.hpp" #include "expression.hpp" -#include <iostream> +#include <cstdio> // Declaration definition @@ -18,7 +18,7 @@ void Declaration::print() const next_declaration_->print(); if(id_ != "") - std::cout << id_ << std::endl; + printf("%s\n", id_.c_str()); } void Declaration::printXml() const @@ -31,41 +31,43 @@ void Declaration::printXml() const } if(id_ != "") - std::cout << "<Variable id=\""<< id_ << "\" />" << std::endl; + printf("<Variable id=\"%s\" />", id_.c_str()); } VariableStackBindings Declaration::printAsm(VariableStackBindings bindings, unsigned& label_count) const { - // if(init == nullptr) - // std::cout << "\t.comm\t" << id << ",4,4" << std::endl; - // else { - // std::cout << "\t.data\n\t.globl\t" << id << std::endl; - // std::cout << id << ":\n\t.word\t" << std::endl; - // } + (void)label_count; + + if(initializer_ == nullptr) + printf("\t.comm\t%s,4,4\n", id_.c_str()); + else + printf("\t.data\n\t.globl\t%s\n%s:\n\t.word\t%d\n", + id_.c_str(), id_.c_str(), initializer_->constantFold()); - // return bindings; + bindings.insertBinding(id_, type_, -1); + return bindings; +} +VariableStackBindings Declaration::localAsm(VariableStackBindings bindings, unsigned& label_count) const +{ if(next_declaration_ != nullptr) - bindings = next_declaration_->printAsm(bindings, label_count); + bindings = next_declaration_->localAsm(bindings, label_count); if(next_list_declaration_ != nullptr) - bindings = next_list_declaration_->printAsm(bindings, label_count); + bindings = next_list_declaration_->localAsm(bindings, label_count); if(id_ != "") { if(initializer_ != nullptr) initializer_->printAsm(bindings, label_count); else - std::cout << "\tmove\t$2,$0" << std::endl; - - int32_t stack_position = bindings.currentStackPosition(); - - std::cout << "\tsw\t$2," << stack_position << "($fp)" << std::endl; + printf("\tmove\t$2,$0\n"); + int stack_position = bindings.currentStackPosition(); + printf("\tsw\t$2,%d($fp)\n", stack_position); bindings.insertBinding(id_, type_, stack_position); - bindings.increaseStackPosition(); } - + return bindings; } diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 98ca018..bd64325 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -1,10 +1,17 @@ #include "expression.hpp" +#include <cstdio> +#include <exception> #include <iostream> #include <vector> // Expression definition +int Expression::constantFold() const +{ + throw std::runtime_error("Error : Cannot constant fold this expression"); +} + void Expression::print() const {} @@ -24,11 +31,8 @@ void Expression::expressionDepth(unsigned& depth_count) const int Expression::postfixStackPosition(VariableStackBindings bindings) const { - // call this if the expression is not a postfix expression - std::cerr << "Error : Can't call 'getPostfixStackPosition(VariableStackBindings " << - "bindings)' on this type of expression" << std::endl; (void)bindings; - return -1; + throw std::runtime_error("Error : Can't call postfixStackExpression() on this type"); } void Expression::setPostfixExpression(Expression *postfix_expression) @@ -61,6 +65,11 @@ OperationExpression::OperationExpression(Expression* lhs, Expression* rhs) : lhs_(lhs), rhs_(rhs) {} +int OperationExpression::constantFold() const +{ + throw std::runtime_error("Error : Cannot constant fold expression\n"); +} + void OperationExpression::expressionDepth(unsigned& depth_count) const { unsigned lhs_depth_count = depth_count; @@ -89,9 +98,8 @@ void OperationExpression::evaluateExpression(VariableStackBindings bindings, uns // now I have them evaluated at two positions in the stack and can load both into registers // $2 and $3 - - std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl; - std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + printf("\tlw\t$2,%d($fp)\n\tlw\t$3,%d($fp)\n", + lhs_stack_position, bindings.currentExpressionStackPosition()); } @@ -138,16 +146,15 @@ VariableStackBindings PostfixFunctionCall::printAsm(VariableStackBindings bindin (*itr)->printAsm(bindings, label_count); if(argument_counter < 4) - std::cout << "\tmove\t$" << 4+argument_counter << ",$2\n"; + printf("\tmove\t$%d,$2\n", 4+argument_counter); else - std::cout << "\tsw\t$2," << 4*argument_counter << "($fp)\n"; + printf("\tsw\t$2,%d($fp)\n", 4*argument_counter); argument_counter++; } - std::cout << "\tjal\t" << postfix_expression_->id() << "\n\tnop\n"; - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\tjal\t%s\n\tnop\n\tsw\t$2,%d($fp)\n", + postfix_expression_->id().c_str(), bindings.currentExpressionStackPosition()); return bindings; } @@ -206,18 +213,25 @@ 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_ == "+") - std::cout << "\tadd\t$2,$2,$3" << std::endl; + printf("\tadd\t$2,$2,$3\n"); else if(operator_ == "-") - std::cout << "\tsub\t$2,$2,$3" << std::endl; + printf("\tsub\t$2,$2,$3\n"); else - std::cerr << "Don't recognize symbol: '" << operator_ << "'" << std::endl; + throw std::runtime_error("Error : '"+operator_+"' not recognized"); // now I have to store it back into the original stack position - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } +int AdditiveExpression::constantFold() const +{ + if(operator_ == "+") + return lhs_->constantFold()+rhs_->constantFold(); + return lhs_->constantFold()-rhs_->constantFold(); +} + // Multiplicative Expression definition @@ -231,23 +245,36 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b evaluateExpression(bindings, label_count); // then perform the right operation - if(operator_ == "*") - std::cout << "\tmul\t$2,$2,$3" << std::endl; - else if(operator_ == "/" || operator_ == "%") { - std::cout << "\tdiv\t$2,$3" << std::endl; + if(operator_ == "*") { + printf("\tmul\t$2,$2,$3\n"); + + } else if(operator_ == "/" || operator_ == "%") { + printf("\tdiv\t$2,$3\n"); if(operator_ == "/") - std::cout << "\tmflo\t$2" << std::endl; + printf("\tmflo\t$2\n"); else - std::cout << "\tmfhi\t$2" << std::endl; - } else - std::cerr << "Error : don't recognize symbol '" << operator_ << "'\n"; + printf("\tmfhi\t$2\n"); + + } else { + throw std::runtime_error("Error : '"+operator_+"' not recognized"); + } + // finally store result back into the stack position - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } +int MultiplicativeExpression::constantFold() const +{ + if(operator_ == "*") + return lhs_->constantFold()*rhs_->constantFold(); + else if(operator_ == "/") + return lhs_->constantFold()/rhs_->constantFold(); + return lhs_->constantFold()%rhs_->constantFold(); +} + // ShiftExpression definition @@ -272,6 +299,13 @@ VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings, return bindings; } +int ShiftExpression::constantFold() const +{ + if(operator_ == "<<") + return lhs_->constantFold()<<rhs_->constantFold(); + return lhs_->constantFold()>>rhs_->constantFold(); +} + // RelationalExpression definition @@ -303,6 +337,17 @@ VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindi return bindings; } +int RelationalExpression::constantFold() const +{ + if(operator_ == "<") + return lhs_->constantFold()<rhs_->constantFold(); + else if(operator_ == ">") + return lhs_->constantFold()>rhs_->constantFold(); + else if(operator_ == "<=") + return lhs_->constantFold()<=rhs_->constantFold(); + return lhs_->constantFold()>=rhs_->constantFold(); +} + // EqualityExpression definition @@ -332,6 +377,13 @@ VariableStackBindings EqualityExpression::printAsm(VariableStackBindings binding return bindings; } +int EqualityExpression::constantFold() const +{ + if(operator_ == "==") + return lhs_->constantFold()==rhs_->constantFold(); + return lhs_->constantFold()!=rhs_->constantFold(); +} + // AndExpression definition @@ -350,6 +402,11 @@ VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings, un return bindings; } +int AndExpression::constantFold() const +{ + return lhs_->constantFold()&rhs_->constantFold(); +} + // ExclusiveOrExpression definition @@ -360,14 +417,15 @@ ExclusiveOrExpression::ExclusiveOrExpression(Expression* lhs, Expression* rhs) VariableStackBindings ExclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { evaluateExpression(bindings, label_count); - - std::cout << "\txor\t$2,$2,$3\n"; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\txor\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } +int ExclusiveOrExpression::constantFold() const +{ + return lhs_->constantFold()^rhs_->constantFold(); +} + // InclusiveOrExpression definition @@ -378,14 +436,15 @@ InclusiveOrExpression::InclusiveOrExpression(Expression* lhs, Expression* rhs) VariableStackBindings InclusiveOrExpression::printAsm(VariableStackBindings bindings, unsigned& label_count) const { evaluateExpression(bindings, label_count); - - std::cout << "\tor\t$2,$2,$3\n"; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)\n"; - + printf("\tor\t$2,$2,$3\n\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } +int InclusiveOrExpression::constantFold() const +{ + return lhs_->constantFold()|rhs_->constantFold(); +} + // LogicalAndExpression definition @@ -398,6 +457,11 @@ VariableStackBindings LogicalAndExpression::printAsm(VariableStackBindings bindi return bindings; } +int LogicalAndExpression::constantFold() const +{ + return lhs_->constantFold()&&rhs_->constantFold(); +} + // LogicalOrExpression definition @@ -410,6 +474,11 @@ VariableStackBindings LogicalOrExpression::printAsm(VariableStackBindings bindin return bindings; } +int LogicalOrExpression::constantFold() const +{ + return lhs_->constantFold()&&rhs_->constantFold(); +} + // ConditionalExpression definition @@ -447,10 +516,10 @@ VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindi rhs_->printAsm(bindings, label_count); // now the result of the rhs will be in that stack position, so we can load it into $2 - std::cout << "\tlw\t$2," << expression_stack_position << "($fp)" << std::endl; + 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 - std::cout << "\tsw\t$2," << store_stack_position << "($fp)" << std::endl; + printf("\tsw\t$2,%d($fp)\n", store_stack_position); return bindings; } @@ -464,13 +533,21 @@ Identifier::Identifier(const std::string& id) VariableStackBindings Identifier::printAsm(VariableStackBindings bindings, unsigned& label_count) const { (void)label_count; + if(bindings.bindingExists(id_)) { - std::cout << "\tlw\t$2," << bindings.stackPosition(id_) << "($fp)" << std::endl; - } else - std::cerr << "Can't find identifier '" << id_ << "' in current scope binding" << std::endl; - - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + 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("\tlw\t$2,%d($fp)\n", bindings.stackPosition(id_)); + } + } else{ + throw std::runtime_error("Error : Can't find '"+id_+"' in current scope binding"); + } + + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } @@ -480,7 +557,7 @@ int Identifier::postfixStackPosition(VariableStackBindings bindings) const return bindings.stackPosition(id_); } - return -1; + throw std::runtime_error("Error : Variable '"+id_+"' not yet declared"); } std::string Identifier::id() const @@ -499,7 +576,12 @@ VariableStackBindings Constant::printAsm(VariableStackBindings bindings, unsigne { (void)label_count; // constant only has to load to $2 because the other expression will take care of the rest - std::cout << "\tli\t$2," << constant_ << std::endl; - std::cout << "\tsw\t$2," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl; + printf("\tli\t$2,%d\n", constant_); + printf("\tsw\t$2,%d($fp)\n", bindings.currentExpressionStackPosition()); return bindings; } + +int Constant::constantFold() const +{ + return constant_; +} diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp index 35e02f4..c1f60cd 100644 --- a/c_compiler/src/function.cpp +++ b/c_compiler/src/function.cpp @@ -47,6 +47,7 @@ void Function::printXml() const VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigned& label_count) const { + VariableStackBindings original_bindings = bindings; // Counting all the variables being declared in the function unsigned variable_count = 0; if(statement_ != nullptr) @@ -90,7 +91,7 @@ VariableStackBindings Function::printAsm(VariableStackBindings bindings, unsigne << memory_needed-8 << "($sp)\n\taddiu\t$sp,$sp," << memory_needed << "\n\tjr\t$31\n\tnop\n"; - return bindings; + return original_bindings; } void Function::printParameterAsm(VariableStackBindings& bindings, unsigned& stack_offset, diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp index 13e779f..77d3854 100644 --- a/c_compiler/src/statement.cpp +++ b/c_compiler/src/statement.cpp @@ -59,7 +59,7 @@ VariableStackBindings CompoundStatement::printAsm(VariableStackBindings bindings next_statement_->printAsm(bindings, label_count); if(declaration_ != nullptr) - bindings = declaration_->printAsm(bindings, label_count); + bindings = declaration_->localAsm(bindings, label_count); if(statement_ != nullptr) statement_->printAsm(bindings, label_count); diff --git a/c_compiler/src/translation_unit.cpp b/c_compiler/src/translation_unit.cpp index cb581d3..0c7815b 100644 --- a/c_compiler/src/translation_unit.cpp +++ b/c_compiler/src/translation_unit.cpp @@ -28,7 +28,7 @@ void TranslationUnit::printXml() const VariableStackBindings TranslationUnit::printAsm(VariableStackBindings bindings, unsigned& label_count) const { for(auto& node : translation_unit_) { - node->printAsm(bindings, label_count); + bindings = node->printAsm(bindings, label_count); } return bindings; diff --git a/c_compiler/test/in/global.c b/c_compiler/test/in/global.c new file mode 100644 index 0000000..da59c9f --- /dev/null +++ b/c_compiler/test/in/global.c @@ -0,0 +1,6 @@ +int x = 3 + 4; + +int main() +{ + return x; +} |