From 6c3eb9c159db4919e1aa2326d3052f3df288c3d8 Mon Sep 17 00:00:00 2001 From: Daniel Zhu Date: Mon, 9 Nov 2020 20:21:30 -0800 Subject: [PATCH] Added activation records! --- Interpreter/Stack.h | 38 ++++++++++++++++++++++++++++++++++++++ Interpreter/interpreter.h | 26 +++++++++++++++++--------- 2 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 Interpreter/Stack.h diff --git a/Interpreter/Stack.h b/Interpreter/Stack.h new file mode 100644 index 0000000..c19d9f6 --- /dev/null +++ b/Interpreter/Stack.h @@ -0,0 +1,38 @@ +#pragma once +#include +#include +#include +#include +enum class ARType { + PROGRAM +}; +using value = std::variant; +class ActivationRecord { +public: + std::string name; + ARType type; + int nesting_level; + std::map members; + ActivationRecord(ARType type, int nesting_level, std::string name = "") { + this->name = name; + this->type = type; + this->nesting_level = nesting_level; + this->members = members; + } + value& operator [] (std::string index) { + return members[index]; + } +}; +class CallStack { +public: + std::vector records; + void push(ActivationRecord& ar) { + records.push_back(ar); + } + void pop() { + records.pop_back(); + } + ActivationRecord& peek() { + return records.back(); + } +}; \ No newline at end of file diff --git a/Interpreter/interpreter.h b/Interpreter/interpreter.h index 7b817c1..4fbec4e 100644 --- a/Interpreter/interpreter.h +++ b/Interpreter/interpreter.h @@ -7,6 +7,7 @@ #include #include #include +#include "./Stack.h" namespace interpreter { class Interpreter { @@ -15,7 +16,7 @@ namespace interpreter { ScopedSymbolTable symTab; ScopedSymbolTable& currentSymTab = symTab; public: - std::map> GLOBAL_SCOPE; + CallStack stack; Interpreter(std::string input) : parser(input), symTab("global", 1) { } @@ -192,16 +193,18 @@ namespace interpreter { void visit_Assign(class Assign assign) { std::string var_name = assign.var.value; std::string type = symTab.lookup(var_name)->type->name; + ActivationRecord& ar = stack.peek(); if (type == "int") { - GLOBAL_SCOPE[var_name] = visit(assign.right); + ar[var_name] = visit(assign.right); return; } else if (type == "real") { - GLOBAL_SCOPE[var_name] = visit(assign.right); + ar[var_name] = visit(assign.right); return; } else if (type == "string") { - GLOBAL_SCOPE[var_name] = visit_String(*static_cast(assign.right)); + ar[var_name] = visit_String(*static_cast(assign.right)); + return; } else { std::string error("Var type not supported"); @@ -210,10 +213,11 @@ namespace interpreter { } template T visit_Var(Var var) { - if (GLOBAL_SCOPE.find(var.value) != GLOBAL_SCOPE.end()) { + ActivationRecord& ar = stack.peek(); + if (ar.members.find(var.value) != ar.members.end()) { if constexpr (std::is_same_v) { std::string type = symTab.lookup(var.value)->type->name; - if (type == "int") return (T)std::get(GLOBAL_SCOPE[var.value]); + if (type == "int") return (T)std::get(ar[var.value]); else { std::string error("Wanted integer, got " + type); throw error; @@ -221,9 +225,9 @@ namespace interpreter { } else if constexpr (std::is_same_v) { std::string type = symTab.lookup(var.value)->type->name; - if (type == "real") return (T)std::get(GLOBAL_SCOPE[var.value]); + if (type == "real") return (T)std::get(ar[var.value]); else if (type == "int") { - return (T)std::get(GLOBAL_SCOPE[var.value]); + return (T)std::get(ar[var.value]); } else { std::string error("Wanted real, got " + type); @@ -232,7 +236,7 @@ namespace interpreter { } else if constexpr (std::is_same_v) { std::string type = symTab.lookup(var.value)->type->name; - if (type == "string") return std::get(GLOBAL_SCOPE[var.value]); + if (type == "string") return std::get(ar[var.value]); else { std::string error("Wanted string, got " + type); throw error; @@ -270,7 +274,11 @@ namespace interpreter { //std::cout << "Finished building symtab...\n"; symTab = symtabBuilder.currentScope; //std::cout << "Interpreting...\n"; + ARType t = ARType::PROGRAM; + ActivationRecord ar(t, 1); + stack.push(ar); visit_Block(p.block); + stack.pop(); } }; } \ No newline at end of file