-
Notifications
You must be signed in to change notification settings - Fork 0
/
CodeGenerator.cpp
119 lines (107 loc) · 2.73 KB
/
CodeGenerator.cpp
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
#include "CodeGenerator.h"
#include <iostream>
using namespace std;
CodeGenerator::CodeGenerator()
{
}
void CodeGenerator::rvalue(VarEntry* entry, int base)
{
Addr addr = entry->addr;
if(entry->PassByValue) {
gen(OP_LV, base - addr.base, addr.offset);
} else {
gen(OP_LV, base - addr.base, addr.offset);
gen(OP_LI);
}
}
void CodeGenerator::lvalue(VarEntry* entry, int base)
{
Addr addr = entry->addr;
if (entry->PassByValue) {
gen(OP_LA, base - addr.base, addr.offset);
} else {
gen(OP_LV, base - addr.base, addr.offset);
}
}
void CodeGenerator::gen(OpCode opCode)
{
Instruction i;
i.Op = opCode;
code.push_back(i);
}
void CodeGenerator::gen(OpCode opCode, int p)
{
Instruction i;
i.Op = opCode;
i.p = p;
code.push_back(i);
}
void CodeGenerator::gen(OpCode opCode, int p, int q)
{
Instruction i;
i.Op = opCode;
i.p = p;
i.q = q;
code.push_back(i);
}
int CodeGenerator::getCodeSize()
{
return code.size();
}
void CodeGenerator::setP(int pos, int p)
{
code[pos].p = p;
}
void CodeGenerator::setOp(int pos, OpCode op)
{
code[pos].Op = op;
}
int CodeGenerator::save(const char* output)
{
FILE *f = fopen(output, "wt");
int len = code.size();
for(int i = 0; i < len; i++) {
switch(code[i].Op) {
case OP_LA: // Load Address:
case OP_LV: // Load Value:
case OP_CALL: // Call
fprintf(f, "%s %d, %d\n", toString[code[i].Op], code[i].p, code[i].q);
break;
case OP_LC: // load Constant
case OP_INT: // Increment t
case OP_DCT: // Decrement t
case OP_J: // Jump
case OP_FJ: // False Jump
fprintf(f, "%s %d\n", toString[code[i].Op], code[i].p);
break;
case OP_HL: // Halt
case OP_ST: // Store
case OP_EP: // Exit Procedure
case OP_EF: // Exit Function
case OP_RC: // Read Char
case OP_RI: // Read Integer
case OP_WRC: // Write Char
case OP_WRI: // Write Int
case OP_WLN: // WriteLN
case OP_ADD: // Add
case OP_SUB: // Substract
case OP_MUL: // Multiple
case OP_DIV: // Divide
case OP_MOD: // Module
case OP_NEG: // Negative
case OP_CV: // Copy Top
case OP_ODD: // Odd
case OP_EQ: // Equal
case OP_NE: // Not Equal
case OP_GT: // Greater
case OP_LT: // Less
case OP_GE: // Greater or Equal
case OP_LE: // Less or Equal
case OP_BP: // Break point.
case OP_LI: // Load Indirect
fprintf(f, "%s\n", toString[code[i].Op]);
break;
}
}
fclose(f);
}