Implement vec based scopes
- Replaced vartable hashmap with vec - Use linear search in reverse to find the variables by name - This is really fast with a small number of variables but tanks fast with more vars due to O(n) lookup times - Implemented scopes by dropping all elements from the vartable at the end of a scope
This commit is contained in:
parent
588b3b5b2c
commit
21228ff3d7
@ -1,4 +1,4 @@
|
||||
use std::{collections::HashMap, fmt::Display, rc::Rc};
|
||||
use std::{fmt::Display, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
ast::{Ast, BinOpType, Expression, If, Statement, UnOpType},
|
||||
@ -14,16 +14,32 @@ pub enum Value {
|
||||
|
||||
pub struct Interpreter {
|
||||
// Variable table stores the runtime values of variables
|
||||
vartable: HashMap<String, Value>,
|
||||
vartable: Vec<(String, Value)>,
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
vartable: HashMap::new(),
|
||||
vartable: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_var(&self, name: &str) -> Option<Value> {
|
||||
self.vartable
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|it| it.0 == name)
|
||||
.map(|it| it.1.clone())
|
||||
}
|
||||
|
||||
fn get_var_mut(&mut self, name: &str) -> Option<&mut Value> {
|
||||
self.vartable
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find(|it| it.0 == name)
|
||||
.map(|it| &mut it.1)
|
||||
}
|
||||
|
||||
pub fn run_str(&mut self, code: &str, print_tokens: bool, print_ast: bool) {
|
||||
let tokens = lex(code).unwrap();
|
||||
if print_tokens {
|
||||
@ -39,6 +55,7 @@ impl Interpreter {
|
||||
}
|
||||
|
||||
pub fn run(&mut self, prog: &Ast) {
|
||||
let vartable_len = self.vartable.len();
|
||||
for stmt in &prog.prog {
|
||||
match stmt {
|
||||
Statement::Expr(expr) => {
|
||||
@ -78,6 +95,8 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.vartable.truncate(vartable_len);
|
||||
}
|
||||
|
||||
fn resolve_expr(&mut self, expr: &Expression) -> Value {
|
||||
@ -91,7 +110,7 @@ impl Interpreter {
|
||||
}
|
||||
|
||||
fn resolve_var(&mut self, name: &str) -> Value {
|
||||
match self.vartable.get(name) {
|
||||
match self.get_var(name) {
|
||||
Some(val) => val.clone(),
|
||||
None => panic!("Variable '{}' used but not declared", name),
|
||||
}
|
||||
@ -113,11 +132,11 @@ impl Interpreter {
|
||||
|
||||
match (&bo, &lhs) {
|
||||
(BinOpType::Declare, Expression::Var(name)) => {
|
||||
self.vartable.insert(name.clone(), rhs.clone());
|
||||
self.vartable.push((name.clone(), rhs.clone()));
|
||||
return rhs;
|
||||
}
|
||||
(BinOpType::Assign, Expression::Var(name)) => {
|
||||
match self.vartable.get_mut(name) {
|
||||
match self.get_var_mut(name) {
|
||||
Some(val) => *val = rhs.clone(),
|
||||
None => panic!("Runtime Error: Trying to assign value to undeclared variable"),
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user