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
|
#include "expression.hpp"
#include "bindings.hpp"
#include <iostream>
// Expression definition
// There are no values to delete so it is just empty
Expression::~Expression()
{}
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
}
int32_t Expression::getPostfixStackPosition(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)
{}
// deletes the two member variables that have been initialized
OperationExpression::~OperationExpression()
{
delete lhs;
delete rhs;
}
// Assignment Expression definition
AssignmentExpression::AssignmentExpression(Expression* _lhs, Expression* _rhs)
: OperationExpression(_lhs, _rhs)
{}
VariableStackBindings AssignmentExpression::printasm(VariableStackBindings bindings) const
{
// the lhs is forced to have a stack position due to it being a function, array or other type of variable
int32_t store_stack_position = lhs->getPostfixStackPosition(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,$2,$3" << 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;
}
// Identifier definition
Identifier::Identifier(const std::string& id)
: m_id(id)
{}
VariableStackBindings Identifier::printasm(VariableStackBindings bindings) const
{
if(bindings.bindingExists(m_id)) {
int32_t stack_position = bindings.getStackPosition(m_id);
std::cout << "\tlw\t$2," << stack_position << "($fp)" << std::endl;
} else
std::cerr << "Can't find identifier '" << m_id << "' in current scope binding" << std::endl;
return bindings;
}
int32_t Identifier::getPostfixStackPosition(VariableStackBindings bindings) const
{
if(bindings.bindingExists(m_id)) {
return bindings.getStackPosition(m_id);
}
return -1;
}
// Constant definition
Constant::Constant(const int32_t& constant)
: m_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," << m_constant << std::endl;
return bindings;
}
|