diff --git a/src/builtin_parser.rs b/src/builtin_parser.rs index 7d9ad0c..554f094 100644 --- a/src/builtin_parser.rs +++ b/src/builtin_parser.rs @@ -67,6 +67,7 @@ impl CommandParser for BuiltinCommandParser { let ast = parse(&mut tokens, &environment); world.insert_non_send_resource(environment); + dbg!(&ast); match ast { Ok(ast) => { runner::run(ast, world); diff --git a/src/builtin_parser/runner.rs b/src/builtin_parser/runner.rs index 2d0d9fb..0599235 100644 --- a/src/builtin_parser/runner.rs +++ b/src/builtin_parser/runner.rs @@ -476,7 +476,6 @@ fn eval_member_expression( let value = map .remove(&right) .ok_or(RunError::FieldNotFoundInStruct(left_span))?; - let value = Rc::try_unwrap(value).unwrap(); Ok(value.into_inner()) } @@ -546,7 +545,14 @@ fn eval_path( Ok(left.span.wrap(Path::Resource(resource))) } - Value::Object(object) => todo_error!("todo object indexing"), + Value::Object(object) => { + let weak = match object.get(&right) { + Some(rc) => Ok(rc.borrow()), + None => todo_error!(), + }?; + + Ok(left.span.wrap(Path::Variable(weak))) + } value => todo_error!("{value:?}"), }, Path::Resource(mut resource) => { @@ -597,21 +603,21 @@ fn eval_object( environment, registrations, }: EvalParams, -) -> Result>>, RunError> { +) -> Result>, RunError> { let map = map .into_iter() .map( - |(key, expr)| -> Result<(String, Rc>), RunError> { + |(key, expr)| -> Result<(String, UniqueRc), RunError> { Ok(( key, - Rc::new(RefCell::new(eval_expression( + UniqueRc::new(eval_expression( expr, EvalParams { world, environment, registrations, }, - )?)), + )?), )) }, ) diff --git a/src/builtin_parser/runner/unique_rc.rs b/src/builtin_parser/runner/unique_rc.rs index bbb5e84..5e26a5c 100644 --- a/src/builtin_parser/runner/unique_rc.rs +++ b/src/builtin_parser/runner/unique_rc.rs @@ -46,6 +46,13 @@ impl UniqueRc { .into_inner() } } +impl Clone for UniqueRc { + fn clone(&self) -> Self { + let t = self.borrow_inner().clone().into_inner(); + + Self::new(t) + } +} impl Deref for UniqueRc { type Target = RefCell; diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index 8d15b92..e94c4f6 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -1,10 +1,8 @@ -use std::cell::RefCell; use std::collections::HashMap; use std::fmt::Debug; -use std::rc::Rc; use crate::builtin_parser::number::Number; -use crate::builtin_parser::{Environment, StrongRef}; +use crate::builtin_parser::{Environment, StrongRef, UniqueRc}; use super::super::Spanned; use super::environment::FunctionParam; @@ -41,13 +39,13 @@ pub enum Value { /// [`Rc::try_unwrap`] to succeed every time) Reference(WeakRef), /// A dynamic [`HashMap`]. - Object(HashMap>>), + Object(HashMap>), /// An [`Object`](Value::Object) with a name attached to it. StructObject { /// The name of the struct name: String, /// The [`Object`](Value::Object) [`HashMap`]. - map: HashMap>>, + map: HashMap>, }, /// A reference to a dynamic value. (aka a reference) Resource(IntoResource), @@ -68,10 +66,7 @@ impl Value { let mut dyn_struct = DynamicStruct::default(); for (name, value) in object { - dyn_struct.insert_boxed( - &name, - Rc::try_unwrap(value).unwrap().into_inner().reflect(ty), - ); + dyn_struct.insert_boxed(&name, value.into_inner().reflect(ty)); } Box::new(dyn_struct) @@ -107,9 +102,11 @@ impl Value { for (key, value) in map { string += &format!( "\n\t{key}: {},", - value - .borrow() - .try_format(span.clone(), world, registrations)? + value.borrow_inner().borrow().try_format( + span.clone(), + world, + registrations + )? ); } if !map.is_empty() { @@ -124,9 +121,11 @@ impl Value { for (key, value) in map { string += &format!( "\n\t{key}: {},", - value - .borrow() - .try_format(span.clone(), world, registrations)? + value.borrow_inner().borrow().try_format( + span.clone(), + world, + registrations + )? ); } if !map.is_empty() { @@ -347,11 +346,11 @@ from_number!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64); from_t!(impl String: string => Value::String(string)); from_t!(impl bool: bool => Value::Boolean(bool)); from_t!(impl Number: number => Value::Number(number)); -from_t!(impl HashMap>>: hashmap => Value::Object(hashmap)); +from_t!(impl HashMap>: hashmap => Value::Object(hashmap)); from_t!(impl HashMap: hashmap => Value::Object( hashmap .into_iter() - .map(|(k, v)| (k, Rc::new(RefCell::new(v)))) + .map(|(k, v)| (k, UniqueRc::new(v))) .collect(), )); @@ -486,9 +485,9 @@ impl_function_param_for_numbers!(Integer(u8, u16, u32, u64, usize, i8, i16, i32, impl_function_param_for_value!(impl bool: Value::Boolean(boolean) => boolean); impl_function_param_for_value!(impl Number: Value::Number(number) => number); impl_function_param_for_value!(impl String: Value::String(string) => string); -impl_function_param_for_value!(impl HashMap>>: Value::Object(object) => object); +// impl_function_param_for_value!(impl HashMap>: Value::Object(object) => object); impl_function_param_for_value!(impl HashMap: Value::Object(object) => { - object.into_iter().map(|(k, v)| (k, Rc::try_unwrap(v).unwrap().into_inner())).collect() + object.into_iter().map(|(k, v)| (k, v.into_inner())).collect() }); impl_function_param_for_value!(impl StrongRef: Value::Reference(reference) => reference.upgrade().unwrap());