From 2a3ab5c161ac98cb3c6326173e5ed78089a9ed68 Mon Sep 17 00:00:00 2001 From: Mel Date: Sun, 14 Nov 2021 22:31:34 +0100 Subject: Function calling and the ensuing scope shenanigans --- src/interpret/scope.rs | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'src/interpret/scope.rs') diff --git a/src/interpret/scope.rs b/src/interpret/scope.rs index 478b24d..0db34c2 100644 --- a/src/interpret/scope.rs +++ b/src/interpret/scope.rs @@ -3,17 +3,37 @@ use crate::parse::ast::nodes::Identifier; use std::{cell::RefCell, collections::HashMap, rc::Rc}; use thiserror::Error; -pub struct Scope { - scopes: Vec>, -} +type InnerScope = HashMap; + +#[derive(Debug, Clone)] +pub struct Scope(Rc>); impl Scope { + fn new() -> Self { + Scope(Rc::new(RefCell::new(HashMap::new()))) + } + + fn get(&self, ident: &str) -> Option { + self.0.borrow().get(ident).cloned() + } + + fn insert(&self, ident: Identifier, value: AssignedValue) { + self.0.borrow_mut().insert(ident, value); + } +} + +#[derive(Debug, Clone)] +pub struct ScopeChain { + scopes: Vec, +} + +impl ScopeChain { pub fn new() -> Self { - Scope { scopes: Vec::new() } + ScopeChain { scopes: Vec::new() } } pub fn nest(&mut self) { - self.scopes.push(HashMap::new()); + self.scopes.push(Scope::new()); } pub fn unnest(&mut self) { @@ -70,9 +90,21 @@ impl Scope { } Err(ScopeError::UnknownIdentifier(ident.to_string())) } + + // In contrast to set_var sets the var in the most inner scope so that it's always found first. + // This is used when setting parameters. + pub fn set_var_shadowed(&mut self, ident: &str, value: Value) { + let inner_scope = self + .scopes + .last_mut() + .expect("Tried accessing scope after last frame is gone."); + + // Can shadowed values be constant? No idea! + inner_scope.insert(ident.to_string(), AssignedValue::Mutable(value)); + } } -#[derive(Debug)] +#[derive(Debug, Clone)] enum AssignedValue { Constant(Value), Mutable(Value), -- cgit 1.4.1