1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#include "expression.hpp"
#include <iostream>
// Expression definition
void Expression::print() const
{
std::cerr << "This expression has not been implemented yet" << std::endl;
}
void Expression::printXml() const
{
// Does nothing as I do not want it to appear in the xml output
}
int Expression::postfixStackPosition(VariableStackBindings bindings) const
{
std::cerr << "Error : Can't call 'getPostfixStackPosition(VariableStackBindings " <<
"bindings)' on this type of expression" << std::endl;
(void)bindings;
return -1;
}
// OperationExpression definition
OperationExpression::OperationExpression(Expression* lhs, Expression* rhs)
: lhs_(lhs), rhs_(rhs)
{}
// Assignment Expression definition
AssignmentExpression::AssignmentExpression(Expression* lhs, Expression* rhs)
: OperationExpression(lhs, 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();
int store_stack_position = lhs_->postfixStackPosition(bindings);
rhs_->printAsm(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;
return bindings;
}
// Additive Expression definition
AdditiveExpression::AdditiveExpression(Expression* lhs, const std::string& operation, Expression* rhs)
: OperationExpression(lhs, rhs), operation_(operation)
{}
VariableStackBindings AdditiveExpression::printAsm(VariableStackBindings bindings) const
{
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;
rhs_->printAsm(bindings);
// then perform the right operation
// 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;
else if(operation_ == "-")
std::cout << "\tsub\t$2,$3,$2" << std::endl;
else
std::cerr << "Don't recognize symbol: '" << operation_ << "'" << std::endl;
return bindings;
}
// Multiplicative Expression definition
MultiplicativeExpression::MultiplicativeExpression(Expression* lhs, const std::string& operation, Expression* rhs)
: OperationExpression(lhs, rhs), operation_(operation)
{}
VariableStackBindings MultiplicativeExpression::printAsm(VariableStackBindings bindings) const
{
lhs_->printAsm(bindings);
std::cout << "\tmove\t$3,$2" << std::endl;
rhs_->printAsm(bindings);
// then perform the right operation
if(operation_ == "*")
std::cout << "\tmul\t$2,$3,$2" << std::endl;
else if(operation_ == "/" || operation_ == "%") {
std::cout << "\tdiv\t$3,$2" << std::endl;
if(operation_ == "/")
std::cout << "\tmflo\t$2" << std::endl;
else
std::cout << "\tmfhi\t$2" << std::endl;
} else
std::cerr << "Don't recognize symbol '" << operation_ << "'" << std::endl;
return bindings;
}
// Identifier definition
Identifier::Identifier(const std::string& id)
: id_(id)
{}
VariableStackBindings Identifier::printAsm(VariableStackBindings bindings) const
{
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;
return bindings;
}
int Identifier::postfixStackPosition(VariableStackBindings bindings) const
{
if(bindings.bindingExists(id_)) {
return bindings.stackPosition(id_);
}
return -1;
}
// Constant definition
Constant::Constant(const int32_t& constant)
: constant_(constant)
{}
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;
return bindings;
}
|