summaryrefslogtreecommitdiff
path: root/src/ArzuParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ArzuParser.cpp')
-rw-r--r--src/ArzuParser.cpp80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/ArzuParser.cpp b/src/ArzuParser.cpp
new file mode 100644
index 0000000..0556a27
--- /dev/null
+++ b/src/ArzuParser.cpp
@@ -0,0 +1,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));
+}