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
|
#include "expression.hpp"
#include "bindings.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
}
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)
{}
// 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;
}
|