-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJITSupport.cxx
139 lines (122 loc) · 3.77 KB
/
JITSupport.cxx
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
#include "APInt.hxx"
#include <iostream>
#include <limits>
#include <vector>
#include <cctype>
extern "C" {
void PushInstr(JITAPInt value);
JITAPInt PopInstr();
void StoreInstr(JITAPInt address,JITAPInt value);
JITAPInt RetriveInstr(JITAPInt address);
JITAPInt AddInstr(JITAPInt value1,JITAPInt value2);
JITAPInt MinusInstr(JITAPInt value1,JITAPInt value2);
JITAPInt TimesInstr(JITAPInt value1,JITAPInt value2);
bool CmpEqualInstr(JITAPInt value1,JITAPInt value2);
void OutputNumInstr(JITAPInt value);
void OutputCharInstr(JITAPInt value);
JITAPInt ReadCharInstr();
JITAPInt ReadNumInstr();
}
void inline error(std::string msg) {
std::cerr << msg << std::endl;
exit(1);
}
std::vector<JITAPInt> stack;
void PushInstr(JITAPInt value) {
//std::cerr << "push " << (std::string) APInt(&value) << std::endl;
stack.push_back(value);
}
JITAPInt PopInstr() {
if (stack.size() == 0) error("can't pop empty stack");
JITAPInt item = stack.back();
stack.pop_back();
//std::cerr << "pop " << (std::string) APInt(&item) << std::endl;
return item;
}
std::map<APInt,APInt> heap;
void StoreInstr(JITAPInt structaddress,JITAPInt value){
APInt address = APInt(&structaddress);
//std::cerr << "store " << (std::string) APInt(&value) << " at address "<< (std::string) address << std::endl;
heap.erase(address);
heap.insert(std::pair<APInt,APInt>(address,APInt(&value)));
}
JITAPInt RetriveInstr(JITAPInt structaddress){
APInt address(&structaddress);
//std::cerr << "retrive from " << (std::string) address << std::endl;
//returns 0 (false) when there is no item present
if (!heap.count(address)) {
//return {0,nullptr};
error(((std::string)"no value at address ").append(address));
}
return heap.at(address).GetJITAPInt();
}
JITAPInt AddInstr(JITAPInt value1,JITAPInt value2) {
if (!value1.next && !value2.next) {
if(value1.value >= 0 && value2.value >= 0 && STD_LONG_LONG_MAX - value1.value >= value2.value) {
return {value1.value + value2.value,nullptr};
} else {
error("num to large in add");
}
} else {
//TODO: dosomething about overflows
error("num to large in add");
}
}
JITAPInt MinusInstr(JITAPInt value1,JITAPInt value2) {
if (!value1.next && !value2.next) {
//by adding value 2 to the minium you get the smallest number
//that value 2 can be subtracted from
if(value2.value >= 0 && value1.value >= ((-STD_LONG_LONG_MAX)-1)+ value2.value) {
return {value1.value - value2.value,nullptr};
} else if (value2.value < 0){
return AddInstr(value1,JITAPInt({-value2.value,nullptr}));
} else {
error("num to large in minus (single)");
}
} else {
//TODO: dosomething about overflows
error("num to large in minus (pointer)");
}
}
JITAPInt TimesInstr(JITAPInt value1,JITAPInt value2) {
return JITAPIntTimes(value1,value2);
}
bool CmpEqualInstr(JITAPInt value1,JITAPInt value2) {
return !JITAPIntlessthan(&value1,& value2) && !JITAPIntlessthan(& value2,&value1);
}
void OutputNumInstr(JITAPInt value) {
if (!value.next) {
std::cout << std::to_string(value.value);
} else {
//TODO: dosomething
if (value.next) error("num to large");
}
}
void OutputCharInstr(JITAPInt value) {
if (value.next) error("Char to large");
if (value.value > (long long int) std::numeric_limits<char>::max()) error("Char to large");
std::cout << (char) value.value;
}
JITAPInt ReadCharInstr(){
char ch;
std::cin >> ch;
return {ch,nullptr};
}
JITAPInt ReadNumInstr(){
char ch;
APIntBuilder builder;
//eat white space
std::cin >> std::ws;
if (std::cin.peek() == '-') {
std::cin >> ch;
builder.makeNegative();
}
if (std::cin.peek() < '0' || std::cin.peek() > '9') error("not a num");
while ((std::cin).peek() >= '0' && (std::cin).peek() <= '9') {
builder.multiplyby10();
std::cin >> std::ws >> ch;
ch -= '0';
builder.add(ch);
}
return ((APInt)builder).GetJITAPInt();
}