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
|
#include "ArzuParser.h"
#include "PolishNotationParser.h"
#include "Memory.h"
bool isDigit(char ch) {
return '0' <= ch && ch <= '9';
}
bool isName(char ch) {
return ch == '$';
}
bool isSeparator(char ch) {
return ch == ' ' || ch == '\t' || ch == '\n' || ch == EOF;
}
void _arzuIntOp(char op, Memory& mem) {
Int* right = static_cast<Int*>(mem.work.top());
mem.work.pop();
Int* left = static_cast<Int*>(mem.work.top());
switch (op) {
case '+': left->value += right->value; break;
case '-': left->value -= right->value; break;
case '*': left->value *= right->value; break;
case '/': left->value /= right->value; break;
default: throw "Bad op";
}
delete right;
}
void arzu_sum(Memory& mem) {
_arzuIntOp('+', mem);
}
void arzu_sub(Memory& mem) {
_arzuIntOp('-', mem);
}
void arzu_mult(Memory& mem) {
_arzuIntOp('*', mem);
}
void arzu_div(Memory& mem) {
_arzuIntOp('/', mem);
}
void arzu_devar(Memory& mem) {
MemoryData* val = mem.work.top();
mem.work.pop();
Name* name = static_cast<Name*>(mem.work.top());
mem.work.pop();
mem.vars.push_back(name);
mem.vars.push_back(val);
mem.scopeVars.top()++;
}
MemoryData* arzu_Int_absorb(ifstream& inFile) {
Int* num = new Int(0);
while (!isSeparator(inFile.peek())) {
num->value = (num->value * 10) + (inFile.peek() - '0');
inFile.get();
}
return num;
}
MemoryData* arzu_Name_absorb(ifstream& inFile) {
Name* name = new Name();
while (isDigit(inFile.peek()) || ('0' <= inFile.peek() && inFile.peek() <= 'z'))
name->value.push_back(inFile.get());
return name;
}
ArzuParser::ArzuParser() : PNParser() {
this->addInstr(Instruction("+", 2, arzu_sum));
this->addInstr(Instruction("-", 2, arzu_sub));
this->addInstr(Instruction("*", 2, arzu_mult));
this->addInstr(Instruction("/", 2, arzu_div));
this->addInstr(Instruction("devar", 2, arzu_devar));
this->addAtom(Atom(isDigit, arzu_Int_absorb));
this->addAtom(Atom(isName, arzu_Name_absorb));
}
|