From 5138ada81685ca0e241a4c7188cf34cfb76514d7 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 19 Apr 2025 15:07:07 +0300 Subject: [PATCH] remove obsolete code --- src/lib.rs | 2 - src/run.rs | 296 --------------------------------------------------- src/scope.rs | 63 ----------- 3 files changed, 361 deletions(-) delete mode 100644 src/run.rs delete mode 100644 src/scope.rs diff --git a/src/lib.rs b/src/lib.rs index 0253397..5b7061a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ pub mod ast; -pub mod run; -pub mod scope; pub mod twopass; pub mod types; diff --git a/src/run.rs b/src/run.rs deleted file mode 100644 index 5707c67..0000000 --- a/src/run.rs +++ /dev/null @@ -1,296 +0,0 @@ -use std::{collections::HashMap, fmt::Debug, rc::Rc}; - -use crate::{ - ast::{Call, Constant, Expression, Location, Statement}, - types::{Value, ValueInner}, -}; - -#[derive(Clone)] -struct Function { - name: String, - inner: Rc) -> Value>, -} - -impl Debug for Function { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "", self.name) - } -} - -#[derive(Debug, Clone, Default)] -pub struct Scope { - variables: HashMap, - functions: HashMap, -} - -impl Scope { - pub fn get(&self, name: impl AsRef) -> Value { - self.variables.get(name.as_ref()).cloned() - } - - pub fn rawset(&mut self, name: String, value: Value) { - if let Some(value) = value { - self.variables.insert(name, value); - } else { - self.variables.remove(&name); - } - } - - pub fn set(&mut self, name: impl AsRef, value: &(impl Clone + Into)) { - self.variables - .insert(name.as_ref().to_string(), value.clone().into()); - } - - pub fn add_fn( - &mut self, - name: impl Into, - f: impl Fn(&mut Scope, Vec) -> Value + 'static, - ) { - let name = name.into(); - self.functions.insert( - name.clone(), - Function { - name, - inner: Rc::new(f), - }, - ); - } -} - -pub trait Eval { - fn eval(&self, scope: &mut Scope) -> Value; -} - -impl Eval for Constant { - fn eval(&self, _scope: &mut Scope) -> Value { - match self { - Constant::Nil => None, - Constant::Boolean(value) => Some(ValueInner::Boolean(*value)), - Constant::Number(value) => Some(ValueInner::Number(*value)), - Constant::String(value) => Some(ValueInner::String(value.clone())), - } - } -} - -impl Eval for Location { - fn eval(&self, scope: &mut Scope) -> Value { - match self { - Location::Variable { name } => scope.get(name), - Location::Field { table, index } => { - let table = table.eval(scope); - let Some(ValueInner::Table(table)) = table else { - panic!("attempt to index non-table value {table:?}") - }; - let index = index.eval(scope); - let Some(index) = index else { - panic!("attempt to index with a nil value") - }; - table.get(index) - } - } - } -} - -impl Eval for Call { - fn eval(&self, scope: &mut Scope) -> Value { - let Self { callee, args } = self; - let Some(function) = scope.functions.get(callee.as_str()).cloned() else { - panic!("attempt to call non-existent function {callee}") - }; - let args = args.iter().map(|arg| arg.eval(scope)).collect(); - (function.inner)(scope, args) - } -} - -impl Eval for Expression { - fn eval(&self, scope: &mut Scope) -> Value { - match self { - Expression::Constant(inner) => inner.eval(scope), - Expression::Variable(inner) => inner.eval(scope), - Expression::Call(inner) => inner.eval(scope), - Expression::Function { .. } => todo!(), - } - } -} - -pub trait Exec { - fn exec(&self, scope: &mut Scope); -} - -impl Exec for Statement { - fn exec(&self, scope: &mut Scope) { - match self { - Statement::Assign { target, source } => { - let value = source.eval(scope); - match target { - Location::Variable { name } => { - scope.rawset(name.into(), value); - } - Location::Field { table, index } => { - let table = table.eval(scope); - let Some(ValueInner::Table(table)) = table else { - panic!("attempt to index non-table value {table:?}") - }; - let index = index.eval(scope); - let Some(index) = index else { - panic!("attempt to index with a nil value") - }; - table.set(index, value); - } - }; - } - Statement::Call(call) => { - call.eval(scope); - } - Statement::Local { .. } => todo!(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ast, types}; - - #[test] - fn test_consts() { - let mut scope = Scope::default(); - assert_eq!(ast::Constant::Nil.eval(&mut scope), None); - assert_eq!( - ast::Constant::Boolean(true).eval(&mut scope), - Some(true.into()) - ); - assert_eq!(ast::Constant::Number(42).eval(&mut scope), Some(42.into())); - assert_eq!( - ast::Constant::String("foobar".into()).eval(&mut scope), - Some("foobar".into()) - ); - } - - #[test] - fn test_vars() { - let mut scope = Scope::default(); - let foo = ast::Location::Variable { name: "foo".into() }; - let bar = ast::Location::Variable { name: "bar".into() }; - assert_eq!(foo.eval(&mut scope), None); - assert_eq!(bar.eval(&mut scope), None); - scope.set("bar", &42); - assert_eq!(foo.eval(&mut scope), None); - assert_eq!(bar.eval(&mut scope), Some(42.into())); - } - - #[test] - fn test_fields() { - let mut scope = Scope::default(); - let loc = ast::Location::Field { - table: Box::new(ast::Expression::Variable(ast::Location::Variable { - name: "foo".into(), - })), - index: Box::new(ast::Expression::Constant(ast::Constant::String( - "bar".into(), - ))), - }; - let foo = types::Table::default(); - let bar = types::Table::default(); - scope.set("foo", &foo); - assert_eq!(loc.eval(&mut scope), None); - scope.set("bar", &bar); - assert_eq!(loc.eval(&mut scope), None); - bar.set("foo".into(), Some(666.into())); - assert_eq!(loc.eval(&mut scope), None); - foo.set("bar".into(), Some(42.into())); - assert_eq!(loc.eval(&mut scope), Some(42.into())); - } - - #[test] - fn test_call() { - let mut scope = Scope::default(); - scope.add_fn("sqr", |_, args| { - let [arg] = args.as_slice() else { - panic!("exactly one argument expected"); - }; - let Some(ValueInner::Number(arg)) = arg else { - panic!("number expected"); - }; - Some(ValueInner::Number(arg * arg)) - }); - assert_eq!( - ast::Expression::Call(ast::Call { - callee: "sqr".into(), - args: vec![ast::Expression::Constant(ast::Constant::Number(7))], - }) - .eval(&mut scope), - Some(49.into()) - ); - } - - #[test] - fn test_var_assign() { - let mut scope = Scope::default(); - assert_eq!(scope.get("foo"), None); - assert_eq!(scope.get("bar"), None); - ast::Statement::Assign { - target: ast::Location::Variable { name: "foo".into() }, - source: Box::new(ast::Expression::Constant(ast::Constant::Number(42))), - } - .exec(&mut scope); - assert_eq!(scope.get("foo"), Some(42.into())); - assert_eq!(scope.get("bar"), None); - } - - #[test] - fn test_table_assign() { - let mut scope = Scope::default(); - let foo = types::Table::default(); - let bar = types::Table::default(); - scope.set("foo", &foo); - scope.set("bar", &bar); - assert_eq!(foo.get("foo".into()), None); - assert_eq!(foo.get("bar".into()), None); - assert_eq!(bar.get("foo".into()), None); - assert_eq!(bar.get("bar".into()), None); - ast::Statement::Assign { - target: ast::Location::Field { - table: Box::new(ast::Expression::Variable(ast::Location::Variable { - name: "foo".into(), - })), - index: Box::new(ast::Expression::Constant(ast::Constant::String( - "bar".into(), - ))), - }, - source: Box::new(ast::Expression::Constant(ast::Constant::Number(42))), - } - .exec(&mut scope); - assert_eq!(foo.get("foo".into()), None); - assert_eq!(foo.get("bar".into()), Some(42.into())); - assert_eq!(bar.get("foo".into()), None); - assert_eq!(bar.get("bar".into()), None); - } - - #[test] - fn test_call_statement() { - let mut scope = Scope::default(); - scope.add_fn("set", |scope, args| { - let [key, value] = args.as_slice() else { - panic!("exactly two arguments expected"); - }; - let Some(ValueInner::String(key)) = key else { - panic!("string expected"); - }; - scope.rawset(key.clone(), value.clone()); - None - }); - assert_eq!(scope.get("foo"), None); - assert_eq!(scope.get("bar"), None); - ast::Statement::Call(ast::Call { - callee: "set".into(), - args: vec![ - ast::Expression::Constant(ast::Constant::String("foo".into())), - ast::Expression::Constant(ast::Constant::Number(42)), - ], - }) - .exec(&mut scope); - assert_eq!(scope.get("foo"), Some(42.into())); - assert_eq!(scope.get("bar"), None); - } -} diff --git a/src/scope.rs b/src/scope.rs deleted file mode 100644 index 13cc202..0000000 --- a/src/scope.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::{ - cell::RefCell, - collections::{hash_map::Entry, HashMap}, - rc::Rc, -}; - -use crate::types::Value; - -#[derive(Debug, Clone, Default)] -pub struct Variable(Rc>); - -impl Variable { - pub fn get(&self) -> Value { - self.0.borrow().clone() - } - - pub fn set(&self, value: Value) { - *self.0.borrow_mut() = value; - } -} - -#[derive(Debug, Clone, Default)] -struct ScopeInner { - parent: Option, - locals: HashMap, -} - -#[derive(Debug, Clone, Default)] -pub struct Scope(Rc>); - -impl Scope { - pub fn new() -> Self { - Self::default() - } - - pub fn nested(&self) -> Self { - Self(Rc::new(RefCell::new(ScopeInner { - parent: Some(self.clone()), - ..Default::default() - }))) - } - - pub fn add(&self, name: String) { - self.0.borrow_mut().locals.insert(name, Variable::default()); - } - - pub fn get(&self, name: String) -> Variable { - let mut this = self.0.borrow_mut(); - let parent = this.parent.clone(); - match this.locals.entry(name) { - Entry::Occupied(var) => var.get().clone(), - Entry::Vacant(var) => { - if let Some(parent) = parent { - let name = var.into_key(); - drop(this); - parent.get(name) - } else { - var.insert(Variable::default()).clone() - } - } - } - } -}