diff --git a/2026a/minibasic/interpreter-blocks/ast.hpp b/2026a/minibasic/interpreter-blocks/ast.hpp
index 3b188ce8..12f5beba 100644
--- a/2026a/minibasic/interpreter-blocks/ast.hpp
+++ b/2026a/minibasic/interpreter-blocks/ast.hpp
@@ -1,7 +1,6 @@
 #ifndef __AST_HPP__
 #define __AST_HPP__
 
-#include <map>
 #include <memory>
 #include <iostream>
 #include <utility>
@@ -53,6 +52,8 @@ class Stmt : public AST {
   virtual void execute() const = 0;
 };
 
+extern std::vector<int> rt_stack;
+
 class Decl : public AST {
  public:
   Decl(char v, std::unique_ptr<Type> t) : var(v), type(*t) {}
@@ -61,6 +62,14 @@ class Decl : public AST {
     st.insert(var, type);
   }
 
+  void allocate() {
+    rt_stack.push_back(0);
+  }
+
+  void deallocate() {
+    rt_stack.pop_back();
+  }
+
   void printAST(std::ostream &out) const override {
     out << "Decl(" << var << ":" << type << ")";
   }
@@ -70,8 +79,6 @@ class Decl : public AST {
   Type type;
 };
 
-extern std::map<char, int> variables;
-
 class BinOp : public Expr {
  public:
   BinOp(std::unique_ptr<Expr> e1, char o, std::unique_ptr<Expr> e2)
@@ -97,6 +104,9 @@ class BinOp : public Expr {
       case '*': return expr1->evaluate() * expr2->evaluate();
       case '/': return expr1->evaluate() / expr2->evaluate();
       case '%': return expr1->evaluate() % expr2->evaluate();
+      case '=': return expr1->evaluate() == expr2->evaluate();
+      case '<': return expr1->evaluate() < expr2->evaluate();
+      case '>': return expr1->evaluate() > expr2->evaluate();
     }
     UNREACHABLE(); return 42;
   }
@@ -120,7 +130,7 @@ class BoolConst : public Expr {
   }
 
   int evaluate() const override {
-    return 42;  // FIXME
+    return bv;
   }
 
   void printAST(std::ostream &out) const override {
@@ -159,10 +169,11 @@ class Id : public Expr {
   void sem_analyze() override {
     SymTabEntry *e = st.lookup(var);
     type = e->type;
+    offset = e->offset;
   }
 
   int evaluate() const override {
-    return variables[var];
+    return rt_stack[offset];
   }
 
   void printAST(std::ostream &out) const override {
@@ -171,6 +182,7 @@ class Id : public Expr {
 
  private:
   char var;
+  int offset;
 };
 
 class Block : public Stmt {
@@ -197,8 +209,9 @@ class Block : public Stmt {
   }
 
   void execute() const override {
-    for (const auto &stmt : stmt_list)
-      stmt->execute();
+    for (const auto &decl : decl_list) decl->allocate();
+    for (const auto &stmt : stmt_list) stmt->execute();
+    for (const auto &decl : decl_list) decl->deallocate();
   }
 
   void printAST(std::ostream &out) const override {
@@ -285,10 +298,11 @@ class Let : public Stmt {
   void sem_analyze() override {
     SymTabEntry *e = st.lookup(var->name());
     expr->check_type(e->type);
+    offset = e->offset;
   }
 
   void execute() const override {
-    variables[var->name()] = expr->evaluate();
+    rt_stack[offset] = expr->evaluate();
   }
 
   void printAST(std::ostream &out) const override {
@@ -298,6 +312,7 @@ class Let : public Stmt {
  private:
   std::unique_ptr<Id> var;
   std::unique_ptr<Expr> expr;
+  int offset;
 };
 
 class Print : public Stmt {
diff --git a/2026a/minibasic/interpreter-blocks/parser.y b/2026a/minibasic/interpreter-blocks/parser.y
index 321072df..0e878779 100644
--- a/2026a/minibasic/interpreter-blocks/parser.y
+++ b/2026a/minibasic/interpreter-blocks/parser.y
@@ -26,7 +26,7 @@ YY_DECL;
 
 static std::unique_ptr<Block> ast;
 SymbolTable st;
-std::map<char, int> variables;
+std::vector<int> rt_stack;
 %}
 
 %define api.value.type variant
diff --git a/2026a/minibasic/interpreter-blocks/symbol.hpp b/2026a/minibasic/interpreter-blocks/symbol.hpp
index 8214ab28..186c6066 100644
--- a/2026a/minibasic/interpreter-blocks/symbol.hpp
+++ b/2026a/minibasic/interpreter-blocks/symbol.hpp
@@ -14,24 +14,29 @@ inline void sem_error(const std::string& m1, char v, const std::string& m2) {
 
 struct SymTabEntry {
   Type type;
+  int offset;
   SymTabEntry() {}
-  SymTabEntry(Type t) : type(t) {}
+  SymTabEntry(Type t, int o) : type(t), offset(o) {}
 };
 
 class Scope {
  public:
-  Scope() {}
+  Scope(int o) : offset(o) {}
   void insert(char v, Type t) {
     if (locals.find(v) != locals.end())
       sem_error("Duplicate variable ", v, " declaration");
-    locals[v] = SymTabEntry(t);
+    locals[v] = SymTabEntry(t, offset++);
   }
   SymTabEntry *lookup(char v) {
     if (locals.find(v) == locals.end()) return nullptr;
     return &(locals[v]);
   }
+  int get_offset() {
+    return offset;
+  }
  private:
   std::map<char, SymTabEntry> locals;
+  int offset;
 };
 
 class SymbolTable {
@@ -48,7 +53,8 @@ class SymbolTable {
     return nullptr;
   }
   void enter_scope() {
-    scopes.push_back(Scope());
+    int o = scopes.empty() ? 0 : scopes.back().get_offset();
+    scopes.push_back(Scope(o));
   }
   void exit_scope() {
     scopes.pop_back();
