#include #include #include #include #include "include/parser.h" #include "include/interpreter.h" using namespace std; unordered_map memory; EvalResult eval(Node &ast) { if (ast.index() == 0) { InnerNode node = get(ast); switch (node.type) { case NodeType::Prog: eval(node.children[0]); return eval(node.children[1]); break; case NodeType::Epsilon: return {}; break; case NodeType::Plus: { int e1 = get(eval(node.children[0])); int e2 = get(eval(node.children[1])); return e1 + e2; } break; case NodeType::Minus: { int e1 = get(eval(node.children[0])); int e2 = get(eval(node.children[1])); return e1 - e2; } break; case NodeType::Mult: { int e1 = get(eval(node.children[0])); int e2 = get(eval(node.children[1])); return e1 * e2; } break; case NodeType::Div: { int e1 = get(eval(node.children[0])); int e2 = get(eval(node.children[1])); // if (e2 == 0) return e1 / e2; } break; case NodeType::Mod: { int e1 = get(eval(node.children[0])); int e2 = get(eval(node.children[1])); // if (e2 == 0) return e1 % e2; } break; case NodeType::UnaryPlus: { int e1 = get(eval(node.children[0])); return +e1; } break; case NodeType::UnaryMinus: { int e1 = get(eval(node.children[0])); return -e1; } break; case NodeType::Declaration: { Token typeTok = get(node.children[0]); Token identifierTok = get(node.children[1]); string identifier = get(identifierTok.data); memory[identifier] = 0; return {}; } break; case NodeType::AssignedDeclaration: { Token typeTok = get(node.children[0]); Token identifierTok = get(node.children[1]); string identifier = get(identifierTok.data); int expr = get(eval(node.children[2])); memory[identifier] = expr; return expr; } break; case NodeType::Assignment: { Token identifierTok = get(node.children[0]); string identifier = get(identifierTok.data); int expr = get(eval(node.children[1])); memory[identifier] = expr; return expr; } break; } } else { Token token = get(ast); switch (token.type) { case TokenType::Int: { return get(token.data); } break; case TokenType::Identifier: { string identifier = get(token.data); // if (!memory.contains(identifier)) return; return memory[identifier]; } break; default: throw; break; } } return {}; }