aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-03-15 17:39:50 +0000
committerYann Herklotz <ymherklotz@gmail.com>2017-03-15 17:39:50 +0000
commit667a766552e2002ae7cf7969d78aaeba906d3759 (patch)
tree2d9fc3ffae5485cbf8ff250eb6e77ba01e653f60
parent10a1fc0bc485cb0ac20aff586182a66932d3be64 (diff)
downloadCompiler-667a766552e2002ae7cf7969d78aaeba906d3759.tar.gz
Compiler-667a766552e2002ae7cf7969d78aaeba906d3759.zip
Working with stack
-rw-r--r--c_compiler/include/bindings.hpp4
-rw-r--r--c_compiler/include/expression.hpp4
-rw-r--r--c_compiler/src/bindings.cpp2
-rw-r--r--c_compiler/src/expression.cpp64
-rw-r--r--c_compiler/test/in/AddMult.c3
5 files changed, 52 insertions, 25 deletions
diff --git a/c_compiler/include/bindings.hpp b/c_compiler/include/bindings.hpp
index 512e426..367986d 100644
--- a/c_compiler/include/bindings.hpp
+++ b/c_compiler/include/bindings.hpp
@@ -24,7 +24,7 @@ class VariableStackBindings
private:
std::map<std::string, DeclarationData> bindings_;
int stack_counter_;
- unsigned expression_stack_;
+ int expression_stack_;
public:
VariableStackBindings();
@@ -37,7 +37,7 @@ public:
int currentStackPosition() const;
int stackPosition(const std::string& id) const;
- unsigned currentExpressionStackPosition() const;
+ int currentExpressionStackPosition() const;
bool bindingExists(const std::string& id) const;
};
diff --git a/c_compiler/include/expression.hpp b/c_compiler/include/expression.hpp
index ae186d1..dc2b2e9 100644
--- a/c_compiler/include/expression.hpp
+++ b/c_compiler/include/expression.hpp
@@ -1,5 +1,5 @@
-#ifndef AST_EXPRESSION_HPP
-#define AST_EXPRESSION_HPP
+#ifndef EXPRESSION_HPP
+#define EXPRESSION_HPP
#include "node.hpp"
#include "bindings.hpp"
diff --git a/c_compiler/src/bindings.cpp b/c_compiler/src/bindings.cpp
index ba3fdfd..7be0173 100644
--- a/c_compiler/src/bindings.cpp
+++ b/c_compiler/src/bindings.cpp
@@ -48,7 +48,7 @@ int VariableStackBindings::stackPosition(const std::string &id) const
else return 0;
}
-unsigned VariableStackBindings::currentExpressionStackPosition() const
+int VariableStackBindings::currentExpressionStackPosition() const
{
return expression_stack_;
}
diff --git a/c_compiler/src/expression.cpp b/c_compiler/src/expression.cpp
index 7c0bd8b..31595b1 100644
--- a/c_compiler/src/expression.cpp
+++ b/c_compiler/src/expression.cpp
@@ -38,19 +38,23 @@ AssignmentExpression::AssignmentExpression(Expression* lhs, Expression* rhs)
VariableStackBindings AssignmentExpression::printAsm(VariableStackBindings bindings) const
{
- // TODO
- // the lhs is forced to have a stack position due to it being a function, array or other type of variable
- // unsigned current_stack = bindings.currentRegister();
- // std::cout << "Current Register: " << current_reg << std::endl;
- // bindings.increaseRegister();
-
+ // 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;
+ std::cout << "\tsw\t$2," << store_stack_position << "($fp)" << std::endl;
return bindings;
}
@@ -63,24 +67,34 @@ AdditiveExpression::AdditiveExpression(Expression* lhs, const std::string& opera
VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings bindings) const
{
+ // I can just evaluate the lhs with the same entry stack position
lhs_->printAsm(bindings);
- // move the rhs out of the way to be able to evaluate the lhs
- std::cout << "\tmove\t$3,$2" << std::endl;
+ // store this stack position
+ int lhs_stack_position = bindings.currentExpressionStackPosition();
+ // now have to increase the expression stack position for the rhs
+ bindings.nextExpressionStackPosition();
rhs_->printAsm(bindings);
- // then perform the right operation
+ // 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;
- // currently using signed and sub because I only have signed numbers implemented
+ // TODO currently using signed and sub because I only have signed numbers implemented
// must update this as I add more types
if(operation_ == "+")
- std::cout << "\tadd\t$2,$3,$2" << std::endl;
+ std::cout << "\tadd\t$2,$2,$3" << std::endl;
else if(operation_ == "-")
- std::cout << "\tsub\t$2,$3,$2" << std::endl;
+ std::cout << "\tsub\t$2,$2,$3" << std::endl;
else
std::cerr << "Don't recognize symbol: '" << operation_ << "'" << std::endl;
+ // now I have to store it back into the original stack position
+ std::cout << "\tsw\t$2," << lhs_stack_position << "($fp)" << std::endl;
+
return bindings;
}
@@ -94,17 +108,24 @@ MultiplicativeExpression::MultiplicativeExpression(Expression* lhs, const std::s
VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings bindings) const
{
+ // I can just evaluate lhs without increasing stack count
lhs_->printAsm(bindings);
- std::cout << "\tmove\t$3,$2" << std::endl;
+ // store current stack position
+ int lhs_stack_position = bindings.currentExpressionStackPosition();
+ // increase stack position to store next result in
+ bindings.nextExpressionStackPosition();
rhs_->printAsm(bindings);
+ std::cout << "\tlw\t$2," << lhs_stack_position << "($fp)" << std::endl;
+ std::cout << "\tlw\t$3," << bindings.currentExpressionStackPosition() << "($fp)" << std::endl;
+
// then perform the right operation
if(operation_ == "*")
- std::cout << "\tmul\t$2,$3,$2" << std::endl;
+ std::cout << "\tmul\t$2,$2,$3" << std::endl;
else if(operation_ == "/" || operation_ == "%") {
- std::cout << "\tdiv\t$3,$2" << std::endl;
+ std::cout << "\tdiv\t$2,$3" << std::endl;
if(operation_ == "/")
std::cout << "\tmflo\t$2" << std::endl;
else
@@ -112,6 +133,9 @@ VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings b
} else
std::cerr << "Don't recognize symbol '" << operation_ << "'" << std::endl;
+ // finally store result back into the stack position
+ std::cout << "\tsw\t$2," << lhs_stack_position << "($fp)" << std::endl;
+
return bindings;
}
@@ -128,6 +152,8 @@ VariableStackBindings Identifier::printAsm(VariableStackBindings bindings) const
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;
return bindings;
}
@@ -152,7 +178,7 @@ VariableStackBindings Constant::printAsm(VariableStackBindings bindings) const
{
// 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;
return bindings;
}
diff --git a/c_compiler/test/in/AddMult.c b/c_compiler/test/in/AddMult.c
index a8fa566..92403bc 100644
--- a/c_compiler/test/in/AddMult.c
+++ b/c_compiler/test/in/AddMult.c
@@ -4,7 +4,8 @@ int main() {
int b = 5;
int c = 7;
int d = 3;
- x = a * b + c * d;
+ x = a * b + c * d - d / 3 + 2;
+ x = c - 2 * b + 3 / d - 5 * d;
return x;
}