Skip to content

Commit

Permalink
Allow Object indexing and use UniqueRc
Browse files Browse the repository at this point in the history
  • Loading branch information
doonv committed Jan 8, 2024
1 parent 15f0d17 commit 8a30ed8
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 25 deletions.
1 change: 1 addition & 0 deletions src/builtin_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
18 changes: 12 additions & 6 deletions src/builtin_parser/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -597,21 +603,21 @@ fn eval_object(
environment,
registrations,
}: EvalParams,
) -> Result<HashMap<String, Rc<RefCell<Value>>>, RunError> {
) -> Result<HashMap<String, UniqueRc<Value>>, RunError> {
let map = map
.into_iter()
.map(
|(key, expr)| -> Result<(String, Rc<RefCell<Value>>), RunError> {
|(key, expr)| -> Result<(String, UniqueRc<Value>), RunError> {
Ok((
key,
Rc::new(RefCell::new(eval_expression(
UniqueRc::new(eval_expression(
expr,
EvalParams {
world,
environment,
registrations,
},
)?)),
)?),
))
},
)
Expand Down
7 changes: 7 additions & 0 deletions src/builtin_parser/runner/unique_rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ impl<T> UniqueRc<T> {
.into_inner()
}
}
impl<T: ?Sized + Clone> Clone for UniqueRc<T> {
fn clone(&self) -> Self {
let t = self.borrow_inner().clone().into_inner();

Self::new(t)
}
}

impl<T> Deref for UniqueRc<T> {
type Target = RefCell<T>;
Expand Down
37 changes: 18 additions & 19 deletions src/builtin_parser/runner/value.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -41,13 +39,13 @@ pub enum Value {
/// [`Rc::try_unwrap`] to succeed every time)
Reference(WeakRef<Value>),
/// A dynamic [`HashMap`].
Object(HashMap<String, Rc<RefCell<Value>>>),
Object(HashMap<String, UniqueRc<Value>>),
/// 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<String, Rc<RefCell<Value>>>,
map: HashMap<String, UniqueRc<Value>>,
},
/// A reference to a dynamic value. (aka a reference)
Resource(IntoResource),
Expand All @@ -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)
Expand Down Expand Up @@ -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() {
Expand All @@ -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() {
Expand Down Expand Up @@ -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<String, Rc<RefCell<Value>>>: hashmap => Value::Object(hashmap));
from_t!(impl HashMap<String, UniqueRc<Value>>: hashmap => Value::Object(hashmap));
from_t!(impl HashMap<String, Value>: hashmap => Value::Object(
hashmap
.into_iter()
.map(|(k, v)| (k, Rc::new(RefCell::new(v))))
.map(|(k, v)| (k, UniqueRc::new(v)))
.collect(),
));

Expand Down Expand Up @@ -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<String, Rc<RefCell<Value>>>: Value::Object(object) => object);
// impl_function_param_for_value!(impl HashMap<String, UniqueRc<Value>>: Value::Object(object) => object);
impl_function_param_for_value!(impl HashMap<String, Value>: 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>: Value::Reference(reference) => reference.upgrade().unwrap());

Expand Down

0 comments on commit 8a30ed8

Please sign in to comment.