diff options
author | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-16 15:14:26 +0000 |
---|---|---|
committer | Yann Herklotz <ymherklotz@gmail.com> | 2017-03-16 15:14:26 +0000 |
commit | 03e21a7ef589fa52d27eab85d669ca854e8ac2b8 (patch) | |
tree | 4dec7c89693c74e268756ce156ea6cdac3a41722 /c_compiler | |
parent | 667a766552e2002ae7cf7969d78aaeba906d3759 (diff) | |
download | Compiler-03e21a7ef589fa52d27eab85d669ca854e8ac2b8.tar.gz Compiler-03e21a7ef589fa52d27eab85d669ca854e8ac2b8.zip |
Still works and added correct frame size
Diffstat (limited to 'c_compiler')
-rw-r--r-- | c_compiler/include/declaration.hpp | 6 | ||||
-rw-r--r-- | c_compiler/include/expression.hpp | 159 | ||||
-rw-r--r-- | c_compiler/include/function.hpp | 6 | ||||
-rw-r--r-- | c_compiler/include/statement.hpp | 16 | ||||
-rw-r--r-- | c_compiler/include/type.hpp | 1 | ||||
-rw-r--r-- | c_compiler/src/c_parser.y | 10 | ||||
-rw-r--r-- | c_compiler/src/expression.cpp | 244 | ||||
-rw-r--r-- | c_compiler/src/function.cpp | 23 | ||||
-rw-r--r-- | c_compiler/src/statement.cpp | 72 |
9 files changed, 482 insertions, 55 deletions
diff --git a/c_compiler/include/declaration.hpp b/c_compiler/include/declaration.hpp index 4fe754a..391438f 100644 --- a/c_compiler/include/declaration.hpp +++ b/c_compiler/include/declaration.hpp @@ -2,15 +2,13 @@ #define AST_DECLARATION_HPP #include "node.hpp" +#include "type.hpp" +#include "expression.hpp" #include <memory> -class Expression; -class Type; class Declaration; -typedef std::shared_ptr<Expression> ExpressionPtr; -typedef std::shared_ptr<Type> TypePtr; typedef std::shared_ptr<Declaration> DeclarationPtr; diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp index dc2b2e9..ba1a556 100644 --- a/c_compiler/include/expression.hpp +++ b/c_compiler/include/expression.hpp @@ -1,8 +1,9 @@ #ifndef EXPRESSION_HPP #define EXPRESSION_HPP -#include "node.hpp" #include "bindings.hpp" +#include "node.hpp" +#include "type.hpp" #include <cstdint> #include <memory> @@ -15,12 +16,21 @@ typedef std::shared_ptr<Expression> ExpressionPtr; class Expression : public Node { +private: + ExpressionPtr next_expression_; + public: virtual VariableStackBindings printAsm(VariableStackBindings bindings) const = 0; virtual void print() const; virtual void printXml() const; + virtual void countArguments(unsigned& argument_count) const; + virtual int postfixStackPosition(VariableStackBindings bindings) const; + virtual void setPostfixExpression(Expression* postfix_expression); + + void linkExpression(Expression* next_expression); + ExpressionPtr nextExpression() const; }; @@ -36,10 +46,57 @@ public: }; -class AssignmentExpression : public OperationExpression +class PostfixExpression : public Expression { public: - AssignmentExpression(Expression* lhs, Expression* rhs); + PostfixExpression(); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class PostfixArrayElement : public Expression +{ +public: + PostfixArrayElement(); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class PostfixFunctionCall : public Expression +{ +private: + ExpressionPtr postfix_expression_; + ExpressionPtr argument_expression_list_; + +public: + PostfixFunctionCall(Expression* argument_expression_list = nullptr); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; + virtual void countArguments(unsigned& argument_count) const; + + void setPostfixExpression(Expression* postfix_expression); +}; + + +class UnaryExpression : public Expression +{ +public: + UnaryExpression(); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class CastExpression : public Expression +{ +private: + TypePtr type_; + ExpressionPtr expression_; + +public: + CastExpression(Type* type, Expression* expression); virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; }; @@ -69,6 +126,102 @@ public: }; +class ShiftExpression : public OperationExpression +{ +public: + ShiftExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class RelationalExpression : public OperationExpression +{ +public: + RelationalExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class EqualityExpression : public OperationExpression +{ +public: + EqualityExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class AndExpression : public OperationExpression +{ +public: + AndExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class ExclusiveOrExpression : public OperationExpression +{ +public: + ExclusiveOrExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class InclusiveOrExpression : public OperationExpression +{ +public: + InclusiveOrExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class LogicalAndExpression : public OperationExpression +{ +public: + LogicalAndExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class LogicalOrExpression : public OperationExpression +{ +public: + LogicalOrExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class ConditionalExpression : public Expression +{ +private: + ExpressionPtr logical_or_; + ExpressionPtr expression_; + ExpressionPtr conditional_expression_; + +public: + ConditionalExpression(Expression* logical_or, Expression* expression, + Expression* conditional_expression); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + +class AssignmentExpression : public OperationExpression +{ +public: + AssignmentExpression(Expression* lhs, Expression* rhs); + + virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; +}; + + class Identifier : public Expression { private: diff --git a/c_compiler/include/function.hpp b/c_compiler/include/function.hpp index dc8640e..f049577 100644 --- a/c_compiler/include/function.hpp +++ b/c_compiler/include/function.hpp @@ -10,14 +10,8 @@ #include <memory> #include <string> -class Declaration; -class Statement; -class Type; class Function; -typedef std::shared_ptr<Declaration> DeclarationPtr; -typedef std::shared_ptr<Statement> StatementPtr; -typedef std::shared_ptr<Type> TypePtr; typedef std::shared_ptr<Function> FunctionPtr; diff --git a/c_compiler/include/statement.hpp b/c_compiler/include/statement.hpp index 76d9303..4d2ffc4 100644 --- a/c_compiler/include/statement.hpp +++ b/c_compiler/include/statement.hpp @@ -10,8 +10,6 @@ class Statement; -typedef std::shared_ptr<Declaration> DeclarationPtr; -typedef std::shared_ptr<Expression> ExpressionPtr; typedef std::shared_ptr<Statement> StatementPtr; @@ -27,6 +25,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings) const = 0; virtual void countVariables(unsigned& var_count) const = 0; + virtual void countArguments(unsigned& argument_count) const = 0; void linkStatement(Statement* next); }; @@ -46,6 +45,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; virtual void countVariables(unsigned& var_count) const; + virtual void countArguments(unsigned& argument_count) const; }; @@ -61,34 +61,37 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; virtual void countVariables(unsigned& var_count) const; + virtual void countArguments(unsigned& argument_count) const; }; class ExpressionStatement : public Statement { protected: - ExpressionPtr expr_; + ExpressionPtr expression_; public: - ExpressionStatement(Expression* expr = nullptr); + ExpressionStatement(Expression* expression = nullptr); virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; virtual void countVariables(unsigned& var_count) const; + virtual void countArguments(unsigned& argument_count) const; }; class JumpStatement : public Statement { protected: - ExpressionPtr expr_; + ExpressionPtr expression_; public: - JumpStatement(Expression* expr = nullptr); + JumpStatement(Expression* expression = nullptr); virtual void print() const; virtual void printXml() const; virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; virtual void countVariables(unsigned& var_count) const; + virtual void countArguments(unsigned& argument_count) const; }; @@ -103,6 +106,7 @@ public: virtual VariableStackBindings printAsm(VariableStackBindings bindings) const; virtual void countVariables(unsigned& var_count) const; + virtual void countArguments(unsigned& argument_count) const; }; diff --git a/c_compiler/include/type.hpp b/c_compiler/include/type.hpp index 80afdfe..9352674 100644 --- a/c_compiler/include/type.hpp +++ b/c_compiler/include/type.hpp @@ -11,6 +11,7 @@ class Type; typedef std::shared_ptr<Type> TypePtr; + class Type : public Node { public: virtual void print() const; diff --git a/c_compiler/src/c_parser.y b/c_compiler/src/c_parser.y index ea21879..852b687 100644 --- a/c_compiler/src/c_parser.y +++ b/c_compiler/src/c_parser.y @@ -302,21 +302,21 @@ UnaryOperator: T_AND { $$ = $1; } PostfixExpression: PrimaryExpression { $$ = $1; } - | PostfixExpression T_LSB Expression T_RSB { $$ = $3; } - | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; } + | PostfixExpression T_LSB Expression T_RSB { $$ = new PostfixArrayElement(); } + | PostfixExpression T_LRB PostfixExpression2 { $$ = $3; $$->setPostfixExpression($1); } | PostfixExpression T_DOT T_IDENTIFIER { $$ = $1; } | PostfixExpression T_ARROW T_IDENTIFIER { $$ = $1; } | PostfixExpression T_INCDEC { $$ = $1; } ; PostfixExpression2: - T_RRB { $$ = new Constant(0); } - | ArgumentExpressionList T_RRB { $$ = new Constant(0); } + T_RRB { $$ = new PostfixFunctionCall(); } + | ArgumentExpressionList T_RRB { $$ = new PostfixFunctionCall($1); } ; ArgumentExpressionList: AssignmentExpression { $$ = $1; } - | ArgumentExpressionList T_CMA AssignmentExpression { $$ = $1; } + | ArgumentExpressionList T_CMA AssignmentExpression { $3->linkExpression($$);$$ = $3; } ; PrimaryExpression: diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp index 31595b1..52f847e 100644 --- a/c_compiler/src/expression.cpp +++ b/c_compiler/src/expression.cpp @@ -14,6 +14,11 @@ void Expression::printXml() const // Does nothing as I do not want it to appear in the xml output } +void Expression::countArguments(unsigned int &argument_count) const +{ + (void)argument_count; +} + int Expression::postfixStackPosition(VariableStackBindings bindings) const { std::cerr << "Error : Can't call 'getPostfixStackPosition(VariableStackBindings " << @@ -22,6 +27,22 @@ int Expression::postfixStackPosition(VariableStackBindings bindings) const return -1; } +void Expression::setPostfixExpression(Expression *postfix_expression) +{ + (void)postfix_expression; +} + +void Expression::linkExpression(Expression *next_expression) +{ + ExpressionPtr expression_ptr(next_expression); + next_expression_ = expression_ptr; +} + +ExpressionPtr Expression::nextExpression() const +{ + return next_expression_; +} + // OperationExpression definition @@ -30,31 +51,82 @@ OperationExpression::OperationExpression(Expression* lhs, Expression* rhs) {} -// Assignment Expression definition +// PostfixExpression definition -AssignmentExpression::AssignmentExpression(Expression* lhs, Expression* rhs) - : OperationExpression(lhs, rhs) +PostfixExpression::PostfixExpression() {} -VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindings) const +VariableStackBindings PostfixExpression::printAsm(VariableStackBindings bindings) const { - // TODO add stack and store results in there, also for addition and multiplication. + + return bindings; +} - // get the current location of lhs in the stack so that I can store result there - int store_stack_position = lhs_->postfixStackPosition(bindings); - // get the current available stack position - int expression_stack_position = bindings.currentExpressionStackPosition(); +// PostfixArrayElement - // evaluate rhs and get the result back at the stack position I assigned - // don't have to change the stack position as there is no lhs to evaluate - rhs_->printAsm(bindings); +PostfixArrayElement::PostfixArrayElement() +{} - // 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; +VariableStackBindings PostfixArrayElement::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} - // 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; + +// PostfixFunctionCall + +PostfixFunctionCall::PostfixFunctionCall(Expression* argument_expression_list) + : argument_expression_list_(argument_expression_list) +{} + +VariableStackBindings PostfixFunctionCall::printAsm(VariableStackBindings bindings) const +{ + if(argument_expression_list_ != nullptr) { + + } + + return bindings; +} + +void PostfixFunctionCall::countArguments(unsigned int &argument_count) const +{ + ExpressionPtr current_argument = argument_expression_list_; + + argument_count = 0; + + while(current_argument != nullptr) { + argument_count++; + current_argument = current_argument->nextExpression(); + } +} + +void PostfixFunctionCall::setPostfixExpression(Expression* postfix_expression) +{ + ExpressionPtr expression_ptr(postfix_expression); + postfix_expression_ = expression_ptr; +} + + +// UnaryExpression definition + +UnaryExpression::UnaryExpression() +{} + +VariableStackBindings UnaryExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// CastExpression definition + +CastExpression::CastExpression(Type* type, Expression* expression) + : type_(type), expression_(expression) +{} + +VariableStackBindings CastExpression::printAsm(VariableStackBindings bindings) const +{ return bindings; } @@ -140,6 +212,146 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b } +// ShiftExpression definition + +ShiftExpression::ShiftExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings ShiftExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// RelationalExpression definition + +RelationalExpression::RelationalExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings RelationalExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// EqualityExpression definition + +EqualityExpression::EqualityExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings EqualityExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// AndExpression definition + +AndExpression::AndExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings AndExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// ExclusiveOrExpression definition + +ExclusiveOrExpression::ExclusiveOrExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings ExclusiveOrExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// InclusiveOrExpression definition + +InclusiveOrExpression::InclusiveOrExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings InclusiveOrExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// LogicalAndExpression definition + +LogicalAndExpression::LogicalAndExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings LogicalAndExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// LogicalOrExpression definition + +LogicalOrExpression::LogicalOrExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings LogicalOrExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// ConditionalExpression definition + +ConditionalExpression::ConditionalExpression(Expression* logical_or, + Expression* expression, + Expression* conditional_expression) + : logical_or_(logical_or), expression_(expression), + conditional_expression_(conditional_expression) +{} + +VariableStackBindings ConditionalExpression::printAsm(VariableStackBindings bindings) const +{ + return bindings; +} + + +// Assignment Expression definition + +AssignmentExpression::AssignmentExpression(Expression* lhs, Expression* rhs) + : OperationExpression(lhs, rhs) +{} + +VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindings) const +{ + // 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); + + // get the current available stack position + int expression_stack_position = bindings.currentExpressionStackPosition(); + + // evaluate rhs and get the result back at the stack position I assigned + // don't have to change the stack position as there is no lhs to evaluate + rhs_->printAsm(bindings); + + // 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; + + // 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; + return bindings; +} + + // Identifier definition Identifier::Identifier(const std::string& id) diff --git a/c_compiler/src/function.cpp b/c_compiler/src/function.cpp index 2152c71..24cea4c 100644 --- a/c_compiler/src/function.cpp +++ b/c_compiler/src/function.cpp @@ -49,16 +49,23 @@ void Function::printXml() const VariableStackBindings Function::printAsm(VariableStackBindings bindings) const { // Counting all the variables being declared in the function - unsigned count = 0; + unsigned variable_count = 0; if(statement_ != nullptr) - statement_->countVariables(count); + statement_->countVariables(variable_count); + + unsigned max_argument_count = 0; + // Count the maximum number of arguments + statement_->countArguments(max_argument_count); + + if(max_argument_count < 4) + max_argument_count = 4; - // This includes the space for the old frame counter and (return address)? - unsigned memory_needed = 4*count+8; + // This adds 2 to store the frame pointer and the return address + unsigned memory_needed = 4*(variable_count + max_argument_count + 2); - std::cout << "\t.text\n\t.globl\t" << id_ << std::endl << id_ << ":\n\taddiu\t$sp,$sp,-" - << memory_needed << "\n\tsw\t$fp," << memory_needed-4 << "($sp)\n\tmove\t$fp,$sp" - << std::endl; + std::cout << "\t.text\n\t.globl\t" << id_ << "\n" << id_ << ":\n\taddiu\t$sp,$sp,-" + << memory_needed << "\n\tsw\t$31," << memory_needed-4 << "($sp)\n" << "\tsw\t$fp," + << memory_needed-8 << "($sp)\n\tmove\t$fp,$sp\n"; // TODO print asm for parameters @@ -66,7 +73,7 @@ VariableStackBindings Function::printAsm(VariableStackBindings bindings) const statement_->printAsm(bindings); std::cout << "\tmove\t$sp,$fp\n\tlw\t$fp," << memory_needed-4 << "($sp)\n\taddiu\t$sp,$sp," - << memory_needed << "\n\tjr\t$31\n\tnop" << std::endl; + << memory_needed << "\n\tjr\t$31\n\tnop\n"; return bindings; } diff --git a/c_compiler/src/statement.cpp b/c_compiler/src/statement.cpp index 871043e..e4b30ff 100644 --- a/c_compiler/src/statement.cpp +++ b/c_compiler/src/statement.cpp @@ -92,6 +92,15 @@ void CompoundStatement::countVariables(unsigned& var_count) const } } +void CompoundStatement::countArguments(unsigned& argument_count) const +{ + if(next_statement_ != nullptr) + next_statement_->countArguments(argument_count); + + if(statement_ != nullptr) + statement_->countArguments(argument_count); +} + // Selection Statement definition @@ -133,11 +142,23 @@ void SelectionStatement::countVariables(unsigned& var_count) const else_->countVariables(var_count); } +void SelectionStatement::countArguments(unsigned& argument_count) const +{ + if(next_statement_ != nullptr) + next_statement_->countArguments(argument_count); + + if(if_ != nullptr) + if_->countArguments(argument_count); + + if(else_ != nullptr) + else_->countArguments(argument_count); +} + // Expression Statement definition ExpressionStatement::ExpressionStatement(Expression* expr) - : Statement(), expr_(expr) + : Statement(), expression_(expr) {} void ExpressionStatement::print() const @@ -151,10 +172,10 @@ VariableStackBindings ExpressionStatement::printAsm(VariableStackBindings bindin if(next_statement_ != nullptr) next_statement_->printAsm(bindings); - if(expr_ != nullptr) + if(expression_ != nullptr) { bindings.resetExpressionStack(); - expr_->printAsm(bindings); + expression_->printAsm(bindings); } return bindings; @@ -166,11 +187,25 @@ void ExpressionStatement::countVariables(unsigned& var_count) const next_statement_->countVariables(var_count); } +void ExpressionStatement::countArguments(unsigned& argument_count) const +{ + if(next_statement_ != nullptr) + next_statement_->countArguments(argument_count); + + unsigned tmp_argument_count = argument_count; + + if(expression_ != nullptr) + expression_->countArguments(argument_count); + + if(tmp_argument_count > argument_count) + argument_count = tmp_argument_count; +} + // Jump Statement definition -JumpStatement::JumpStatement(Expression* expr) - : expr_(expr) +JumpStatement::JumpStatement(Expression* expression) + : expression_(expression) {} void JumpStatement::print() const @@ -187,9 +222,9 @@ VariableStackBindings JumpStatement::printAsm(VariableStackBindings bindings) co if(next_statement_ != nullptr) next_statement_->printAsm(bindings); - if(expr_ != nullptr) { + if(expression_ != nullptr) { bindings.resetExpressionStack(); - expr_->printAsm(bindings); + expression_->printAsm(bindings); } return bindings; @@ -201,6 +236,20 @@ void JumpStatement::countVariables(unsigned& var_count) const next_statement_->countVariables(var_count); } +void JumpStatement::countArguments(unsigned& argument_count) const +{ + if(next_statement_ != nullptr) + next_statement_->countArguments(argument_count); + + unsigned tmp_argument_count = argument_count; + + if(expression_ != nullptr) + expression_->countArguments(argument_count); + + if(tmp_argument_count > argument_count) + argument_count = tmp_argument_count; +} + // Iteration Statement definition @@ -233,3 +282,12 @@ void IterationStatement::countVariables(unsigned& var_count) const if(statement_ != nullptr) statement_->countVariables(var_count); } + +void IterationStatement::countArguments(unsigned int &argument_count) const +{ + if(next_statement_ != nullptr) + next_statement_->countArguments(argument_count); + + if(statement_ != nullptr) + statement_->countArguments(argument_count); +} |