From e09625a0c0165914d3ab135a21e664a6ac8ad86c Mon Sep 17 00:00:00 2001 From: doonv <58695417+doonv@users.noreply.github.com> Date: Sat, 28 Dec 2024 19:21:54 +0200 Subject: [PATCH 1/2] compiling but had to remove some reflection features --- Cargo.toml | 7 +- src/builtin_parser/runner.rs | 316 +++++++++---------- src/builtin_parser/runner/reflection.rs | 11 +- src/builtin_parser/runner/value.rs | 386 ++++++++++++------------ src/ui.rs | 2 +- src/ui/completions.rs | 2 +- 6 files changed, 364 insertions(+), 360 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 88f3db6..6fbaa60 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,19 +23,20 @@ builtin-parser = ["dep:logos"] [dependencies] # This crate by itself doesn't use any bevy features, but `bevy_egui` (dep) uses "bevy_asset". -bevy = { version = "0.14.0", default-features = false, features = [] } -bevy_egui = "0.28.0" +bevy = { version = "0.15.0", default-features = false, features = [] } +bevy_egui = "0.31.1" chrono = "0.4.31" tracing-log = "0.2.0" tracing-subscriber = "0.3.18" web-time = "1.0.0" +winit = "0.30.5" # builtin-parser features logos = { version = "0.14.0", optional = true } fuzzy-matcher = { version = "0.3.7", optional = true } [dev-dependencies] -bevy = "0.14.0" +bevy = "0.15.0" [lints] clippy.useless_format = "allow" diff --git a/src/builtin_parser/runner.rs b/src/builtin_parser/runner.rs index 1146605..e05b943 100644 --- a/src/builtin_parser/runner.rs +++ b/src/builtin_parser/runner.rs @@ -220,164 +220,164 @@ fn eval_expression( .reflect_path_mut(resource.path.as_str()) .unwrap(); - match reflect.reflect_mut() { - ReflectMut::Enum(dyn_enum) => { - let TypeInfo::Enum(enum_info) = registration.type_info() else { - unreachable!() - }; - let Spanned { span, value } = *value_expr; - match value { - Expression::Variable(name) => { - let variant_info = match enum_info.variant(&name) { - Some(variant_info) => variant_info, - None => { - return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - } - }; - let VariantInfo::Unit(_) = variant_info else { - return todo_error!("{variant_info:?}"); - }; - - let new_enum = DynamicEnum::new(name, ()); - - dyn_enum.apply(&new_enum); - } - Expression::StructObject { name, map } => { - let variant_info = match enum_info.variant(&name) { - Some(variant_info) => variant_info, - None => { - return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - } - }; - let VariantInfo::Struct(variant_info) = variant_info else { - return todo_error!("{variant_info:?}"); - }; - - let map: HashMap<_, _> = map - .into_iter() - .map(|(k, v)| { - let ty = match variant_info.field(&k) { - Some(field) => Ok(field.type_path_table().short_path()), - None => { - Err(EvalError::EnumVariantStructFieldNotFound { - field_name: k.clone(), - variant_name: name.clone(), - span: span.clone(), - }) - } - }?; - - let span = v.span.clone(); - - Ok(( - k, - ( - eval_expression( - v, - EvalParams { - world, - environment, - registrations, - }, - )?, - span, - ty, - ), - )) - }) - .collect::>()?; - - let new_enum = - DynamicEnum::new(name, object_to_dynamic_struct(map)?); - - let mut dyn_reflect = - resource.mut_dyn_reflect(world, registrations); - - let dyn_enum = dyn_reflect - .reflect_path_mut(resource.path.as_str()) - .unwrap(); - - dyn_enum.apply(&new_enum); - } - Expression::StructTuple { name, tuple } => { - let variant_info = match enum_info.variant(&name) { - Some(variant_info) => variant_info, - None => { - return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - } - }; - let VariantInfo::Tuple(variant_info) = variant_info else { - return todo_error!("{variant_info:?}"); - }; - - let tuple = eval_tuple( - tuple, - EvalParams { - world, - environment, - registrations, - }, - )?; - - let mut dynamic_tuple = DynamicTuple::default(); - - for (index, element) in tuple.into_vec().into_iter().enumerate() { - let ty = match variant_info.field_at(index) { - Some(field) => Ok(field.type_path_table().short_path()), - None => Err(EvalError::EnumVariantTupleFieldNotFound { - field_index: index, - variant_name: name.clone(), - span: span.clone(), - }), - }?; - - dynamic_tuple.insert_boxed( - element.value.into_inner().reflect(element.span, ty)?, - ); - } - - let new_enum = DynamicEnum::new(name, dynamic_tuple); - - let mut dyn_reflect = - resource.mut_dyn_reflect(world, registrations); - - let dyn_enum = dyn_reflect - .reflect_path_mut(resource.path.as_str()) - .unwrap(); - - dyn_enum.apply(&new_enum); - } - _ => todo_error!(), - } - } - _ => { - let span = value_expr.span.clone(); - let ty = reflect.reflect_short_type_path().to_owned(); - let value = eval_expression( - *value_expr, - EvalParams { - world, - environment, - registrations, - }, - )?; - let value_reflect = value.reflect(span.clone(), &ty)?; - - let mut dyn_reflect = resource.mut_dyn_reflect(world, registrations); - - let reflect = dyn_reflect - .reflect_path_mut(resource.path.as_str()) - .unwrap(); - - reflect.set(value_reflect).map_err(|value_reflect| { - EvalError::IncompatibleReflectTypes { - span, - expected: reflect.reflect_type_path().to_string(), - actual: value_reflect.reflect_type_path().to_string(), - } - })?; - } - } + // match reflect.reflect_mut() { + // ReflectMut::Enum(dyn_enum) => { + // let TypeInfo::Enum(enum_info) = registration.type_info() else { + // unreachable!() + // }; + // let Spanned { span, value } = *value_expr; + // match value { + // Expression::Variable(name) => { + // let variant_info = match enum_info.variant(&name) { + // Some(variant_info) => variant_info, + // None => { + // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + // } + // }; + // let VariantInfo::Unit(_) = variant_info else { + // return todo_error!("{variant_info:?}"); + // }; + + // let new_enum = DynamicEnum::new(name, ()); + + // dyn_enum.apply(&new_enum); + // } + // Expression::StructObject { name, map } => { + // let variant_info = match enum_info.variant(&name) { + // Some(variant_info) => variant_info, + // None => { + // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + // } + // }; + // let VariantInfo::Struct(variant_info) = variant_info else { + // return todo_error!("{variant_info:?}"); + // }; + + // let map: HashMap<_, _> = map + // .into_iter() + // .map(|(k, v)| { + // let ty = match variant_info.field(&k) { + // Some(field) => Ok(field.type_path_table().short_path()), + // None => { + // Err(EvalError::EnumVariantStructFieldNotFound { + // field_name: k.clone(), + // variant_name: name.clone(), + // span: span.clone(), + // }) + // } + // }?; + + // let span = v.span.clone(); + + // Ok(( + // k, + // ( + // eval_expression( + // v, + // EvalParams { + // world, + // environment, + // registrations, + // }, + // )?, + // span, + // ty, + // ), + // )) + // }) + // .collect::>()?; + + // let new_enum = + // DynamicEnum::new(name, object_to_dynamic_struct(map)?); + + // let mut dyn_reflect = + // resource.mut_dyn_reflect(world, registrations); + + // let dyn_enum = dyn_reflect + // .reflect_path_mut(resource.path.as_str()) + // .unwrap(); + + // dyn_enum.apply(&new_enum); + // } + // Expression::StructTuple { name, tuple } => { + // let variant_info = match enum_info.variant(&name) { + // Some(variant_info) => variant_info, + // None => { + // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + // } + // }; + // let VariantInfo::Tuple(variant_info) = variant_info else { + // return todo_error!("{variant_info:?}"); + // }; + + // let tuple = eval_tuple( + // tuple, + // EvalParams { + // world, + // environment, + // registrations, + // }, + // )?; + + // let mut dynamic_tuple = DynamicTuple::default(); + + // for (index, element) in tuple.into_vec().into_iter().enumerate() { + // let ty = match variant_info.field_at(index) { + // Some(field) => Ok(field.type_path_table().short_path()), + // None => Err(EvalError::EnumVariantTupleFieldNotFound { + // field_index: index, + // variant_name: name.clone(), + // span: span.clone(), + // }), + // }?; + + // dynamic_tuple.insert_boxed( + // element.value.into_inner().reflect(element.span, ty)?.into_partial_reflect(), + // ); + // } + + // let new_enum = DynamicEnum::new(name, dynamic_tuple); + + // let mut dyn_reflect = + // resource.mut_dyn_reflect(world, registrations); + + // let dyn_enum = dyn_reflect + // .reflect_path_mut(resource.path.as_str()) + // .unwrap(); + + // dyn_enum.apply(&new_enum); + // } + // _ => todo_error!(), + // } + // } + // _ => { + // let span = value_expr.span.clone(); + // let ty = reflect.reflect_short_type_path().to_owned(); + // let value = eval_expression( + // *value_expr, + // EvalParams { + // world, + // environment, + // registrations, + // }, + // )?; + // let value_reflect = value.reflect(span.clone(), &ty)?; + + // let mut dyn_reflect = resource.mut_dyn_reflect(world, registrations); + + // let reflect = dyn_reflect + // .reflect_path_mut(resource.path.as_str()) + // .unwrap(); + + // reflect.set(value_reflect).map_err(|value_reflect| { + // EvalError::IncompatibleReflectTypes { + // span, + // expected: reflect.reflect_type_path().to_string(), + // actual: value_reflect.reflect_type_path().to_string(), + // } + // })?; + // } + // } Ok(Value::Resource(resource)) } diff --git a/src/builtin_parser/runner/reflection.rs b/src/builtin_parser/runner/reflection.rs index 2114f5d..c107c75 100644 --- a/src/builtin_parser/runner/reflection.rs +++ b/src/builtin_parser/runner/reflection.rs @@ -48,13 +48,14 @@ impl IntoResource { pub fn object_to_dynamic_struct( hashmap: HashMap, ) -> Result { - let mut dynamic_struct = DynamicStruct::default(); + todo!() + // let mut dynamic_struct = DynamicStruct::default(); - for (key, (value, span, reflect)) in hashmap { - dynamic_struct.insert_boxed(&key, value.reflect(span, reflect)?); - } + // for (key, (value, span, reflect)) in hashmap { + // dynamic_struct.insert_boxed(&key, value.reflect(span, reflect)?); + // } - Ok(dynamic_struct) + // Ok(dynamic_struct) } pub fn mut_dyn_reflect<'a>( diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index 711ed3a..791976b 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -65,32 +65,33 @@ impl Value { /// /// `ty` is used for type inference. pub fn reflect(self, span: Span, ty: &str) -> Result, EvalError> { - match self { - Value::None => Ok(Box::new(())), - Value::Number(number) => number.reflect(span, ty), - Value::Boolean(boolean) => Ok(Box::new(boolean)), - Value::String(string) => Ok(Box::new(string)), - Value::Reference(_reference) => Err(EvalError::CannotReflectReference(span)), - Value::Object(object) | Value::StructObject { map: object, .. } => { - let mut dyn_struct = DynamicStruct::default(); - - for (name, value) in object { - dyn_struct.insert_boxed(&name, value.into_inner().reflect(span.clone(), ty)?); - } - - Ok(Box::new(dyn_struct)) - } - Value::Tuple(tuple) | Value::StructTuple { tuple, .. } => { - let mut dyn_tuple = DynamicTuple::default(); - - for element in Vec::from(tuple).into_iter() { - dyn_tuple.insert_boxed(element.value.into_inner().reflect(element.span, ty)?); - } - - Ok(Box::new(dyn_tuple)) - } - Value::Resource(_) => Err(EvalError::CannotReflectResource(span)), - } + todo!() + // match self { + // Value::None => Ok(Box::new(())), + // Value::Number(number) => number.reflect(span, ty), + // Value::Boolean(boolean) => Ok(Box::new(boolean)), + // Value::String(string) => Ok(Box::new(string)), + // Value::Reference(_reference) => Err(EvalError::CannotReflectReference(span)), + // Value::Object(object) | Value::StructObject { map: object, .. } => { + // let mut dyn_struct = DynamicStruct::default(); + + // for (name, value) in object { + // dyn_struct.insert_boxed(&name, value.into_inner().reflect(span.clone(), ty)?); + // } + + // Ok(Box::new(dyn_struct)) + // } + // Value::Tuple(tuple) | Value::StructTuple { tuple, .. } => { + // let mut dyn_tuple = DynamicTuple::default(); + + // for element in Vec::from(tuple).into_iter() { + // dyn_tuple.insert_boxed(element.value.into_inner().reflect(element.span, ty)?); + // } + + // Ok(Box::new(dyn_tuple)) + // } + // Value::Resource(_) => Err(EvalError::CannotReflectResource(span)), + // } } /// Attempts to format this [`Value`]. @@ -240,172 +241,173 @@ fn fancy_debug_print( registrations: &[&TypeRegistration], ) -> String { const TAB: &str = " "; - let registration = registrations.create_registration(resource.id); - let dyn_reflect = resource.ref_dyn_reflect(world, registration); - - let reflect = dyn_reflect.reflect_path(resource.path.as_str()).unwrap(); - - fn debug_subprint(reflect: &dyn Reflect, indentation: usize) -> String { - let mut f = String::new(); - let reflect_ref = reflect.reflect_ref(); - let indentation_string = TAB.repeat(indentation); - match reflect_ref { - ReflectRef::Struct(struct_info) => { - f += "{\n"; - for i in 0..struct_info.field_len() { - let field = struct_info.field_at(i).unwrap(); - let field_name = struct_info.name_at(i).unwrap(); - - let field_value = debug_subprint(field, indentation + 1); - f += &format!( - "{indentation_string}{TAB}{field_name}: {} = {field_value},\n", - field.reflect_short_type_path(), - ); - } - f += &indentation_string; - f += "}"; - } - ReflectRef::TupleStruct(_) => todo!(), - ReflectRef::Tuple(tuple_info) => { - f += "(\n"; - for field in tuple_info.iter_fields() { - let field_value = debug_subprint(field, indentation + 1); - f += &format!("{indentation_string}{TAB}{field_value},\n",); - } - f += &indentation_string; - f += ")"; - } - ReflectRef::List(_) => todo!(), - ReflectRef::Array(_) => todo!(), - ReflectRef::Map(_) => todo!(), - ReflectRef::Enum(variant) => { - // Print out the enum types - f += variant.variant_name(); - - match variant.variant_type() { - VariantType::Struct => { - f += " {\n"; - for field in variant.iter_fields() { - f += &format!( - "{indentation_string}{TAB}{}: {} = {},\n", - field.name().unwrap(), - field.value().reflect_short_type_path(), - debug_subprint(field.value(), indentation + 1) - ); - } - f += &indentation_string; - f += "}"; - } - VariantType::Tuple => { - f += "(\n"; - for field in variant.iter_fields() { - f += &format!( - "{indentation_string}{TAB}{} = {},\n", - field.value().reflect_short_type_path(), - debug_subprint(field.value(), indentation + 1) - ); - } - f += &indentation_string; - f += ")"; - } - VariantType::Unit => {} - } - } - ReflectRef::Value(_) => { - f += &format!("{reflect:?}"); - } - } - - f - } - - let mut f = String::new(); - let reflect_ref = reflect.reflect_ref(); - match reflect_ref { - ReflectRef::Struct(struct_info) => { - f += &format!("struct {} {{\n", struct_info.reflect_short_type_path()); - for i in 0..struct_info.field_len() { - let field = struct_info.field_at(i).unwrap(); - let field_name = struct_info.name_at(i).unwrap(); - - let field_value = debug_subprint(field, 1); - f += &format!( - "{TAB}{}: {} = {},\n", - field_name, - field.reflect_short_type_path(), - field_value - ); - } - f += "}"; - } - ReflectRef::TupleStruct(_) => todo!(), - ReflectRef::Tuple(_) => todo!(), - ReflectRef::List(_) => todo!(), - ReflectRef::Array(_) => todo!(), - ReflectRef::Map(_) => todo!(), - ReflectRef::Enum(set_variant_info) => { - // Print out the enum types - f += &format!("enum {} {{\n", set_variant_info.reflect_short_type_path()); - let TypeInfo::Enum(enum_info) = registration.type_info() else { - unreachable!() - }; - for variant in enum_info.iter() { - f += "\t"; - f += variant.name(); - match variant { - VariantInfo::Struct(variant) => { - f += " {\n"; - for field in variant.iter() { - f += &format!( - "{TAB}{TAB}{}: {},\n", - field.name(), - field.type_path_table().short_path() - ); - } - f += TAB; - f += "}"; - } - VariantInfo::Tuple(variant) => { - f += "("; - let mut iter = variant.iter(); - if let Some(first) = iter.next() { - f += &format!("{}", first.type_path_table().short_path()); - for field in iter { - f += &format!(", {}", field.type_path_table().short_path()); - } - } - f += ")"; - } - VariantInfo::Unit(_) => {} - } - f += ",\n"; - } - // Print out the current value - f += "} = "; - f += set_variant_info.variant_name(); - match set_variant_info.variant_type() { - VariantType::Struct => { - f += " {\n"; - for field in set_variant_info.iter_fields() { - f += &format!("{TAB}{}: {:?},\n", field.name().unwrap(), field.value()); - } - f += "}"; - } - VariantType::Tuple => { - f += "(\n"; - for field in set_variant_info.iter_fields() { - f += &format!("{TAB}{:?},\n", field.value()); - } - f += ")"; - } - VariantType::Unit => {} - } - } - ReflectRef::Value(value) => { - f += &format!("{value:?}"); - } - } - f + todo!() + // let registration = registrations.create_registration(resource.id); + // let dyn_reflect = resource.ref_dyn_reflect(world, registration); + + // let reflect = dyn_reflect.reflect_path(resource.path.as_str()).unwrap(); + + // fn debug_subprint(reflect: &dyn Reflect, indentation: usize) -> String { + // let mut f = String::new(); + // let reflect_ref = reflect.reflect_ref(); + // let indentation_string = TAB.repeat(indentation); + // match reflect_ref { + // ReflectRef::Struct(struct_info) => { + // f += "{\n"; + // for i in 0..struct_info.field_len() { + // let field = struct_info.field_at(i).unwrap(); + // let field_name = struct_info.name_at(i).unwrap(); + + // let field_value = debug_subprint(field, indentation + 1); + // f += &format!( + // "{indentation_string}{TAB}{field_name}: {} = {field_value},\n", + // field.reflect_short_type_path(), + // ); + // } + // f += &indentation_string; + // f += "}"; + // } + // ReflectRef::TupleStruct(_) => todo!(), + // ReflectRef::Tuple(tuple_info) => { + // f += "(\n"; + // for field in tuple_info.iter_fields() { + // let field_value = debug_subprint(field, indentation + 1); + // f += &format!("{indentation_string}{TAB}{field_value},\n",); + // } + // f += &indentation_string; + // f += ")"; + // } + // ReflectRef::List(_) => todo!(), + // ReflectRef::Array(_) => todo!(), + // ReflectRef::Map(_) => todo!(), + // ReflectRef::Enum(variant) => { + // // Print out the enum types + // f += variant.variant_name(); + + // match variant.variant_type() { + // VariantType::Struct => { + // f += " {\n"; + // for field in variant.iter_fields() { + // f += &format!( + // "{indentation_string}{TAB}{}: {} = {},\n", + // field.name().unwrap(), + // field.value().reflect_short_type_path(), + // debug_subprint(field.value(), indentation + 1) + // ); + // } + // f += &indentation_string; + // f += "}"; + // } + // VariantType::Tuple => { + // f += "(\n"; + // for field in variant.iter_fields() { + // f += &format!( + // "{indentation_string}{TAB}{} = {},\n", + // field.value().reflect_short_type_path(), + // debug_subprint(field.value(), indentation + 1) + // ); + // } + // f += &indentation_string; + // f += ")"; + // } + // VariantType::Unit => {} + // } + // } + // ReflectRef::Value(_) => { + // f += &format!("{reflect:?}"); + // } + // } + + // f + // } + + // let mut f = String::new(); + // let reflect_ref = reflect.reflect_ref(); + // match reflect_ref { + // ReflectRef::Struct(struct_info) => { + // f += &format!("struct {} {{\n", struct_info.reflect_short_type_path()); + // for i in 0..struct_info.field_len() { + // let field = struct_info.field_at(i).unwrap(); + // let field_name = struct_info.name_at(i).unwrap(); + + // let field_value = debug_subprint(field, 1); + // f += &format!( + // "{TAB}{}: {} = {},\n", + // field_name, + // field.reflect_short_type_path(), + // field_value + // ); + // } + // f += "}"; + // } + // ReflectRef::TupleStruct(_) => todo!(), + // ReflectRef::Tuple(_) => todo!(), + // ReflectRef::List(_) => todo!(), + // ReflectRef::Array(_) => todo!(), + // ReflectRef::Map(_) => todo!(), + // ReflectRef::Enum(set_variant_info) => { + // // Print out the enum types + // f += &format!("enum {} {{\n", set_variant_info.reflect_short_type_path()); + // let TypeInfo::Enum(enum_info) = registration.type_info() else { + // unreachable!() + // }; + // for variant in enum_info.iter() { + // f += "\t"; + // f += variant.name(); + // match variant { + // VariantInfo::Struct(variant) => { + // f += " {\n"; + // for field in variant.iter() { + // f += &format!( + // "{TAB}{TAB}{}: {},\n", + // field.name(), + // field.type_path_table().short_path() + // ); + // } + // f += TAB; + // f += "}"; + // } + // VariantInfo::Tuple(variant) => { + // f += "("; + // let mut iter = variant.iter(); + // if let Some(first) = iter.next() { + // f += &format!("{}", first.type_path_table().short_path()); + // for field in iter { + // f += &format!(", {}", field.type_path_table().short_path()); + // } + // } + // f += ")"; + // } + // VariantInfo::Unit(_) => {} + // } + // f += ",\n"; + // } + // // Print out the current value + // f += "} = "; + // f += set_variant_info.variant_name(); + // match set_variant_info.variant_type() { + // VariantType::Struct => { + // f += " {\n"; + // for field in set_variant_info.iter_fields() { + // f += &format!("{TAB}{}: {:?},\n", field.name().unwrap(), field.value()); + // } + // f += "}"; + // } + // VariantType::Tuple => { + // f += "(\n"; + // for field in set_variant_info.iter_fields() { + // f += &format!("{TAB}{:?},\n", field.value()); + // } + // f += ")"; + // } + // VariantType::Unit => {} + // } + // } + // ReflectRef::Value(value) => { + // f += &format!("{value:?}"); + // } + // } + // f } impl From<()> for Value { diff --git a/src/ui.rs b/src/ui.rs index aa859d5..fed5d90 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -117,7 +117,7 @@ pub fn render_ui( info!(name: COMMAND_MESSAGE_NAME, "{COMMAND_MESSAGE_PREFIX}{}", command.trim()); // Get the owned command string by replacing it with an empty string let command = std::mem::take(command); - commands.add(ExecuteCommand(command)); + commands.queue(ExecuteCommand(command)); } } diff --git a/src/ui/completions.rs b/src/ui/completions.rs index 208cc13..026a512 100644 --- a/src/ui/completions.rs +++ b/src/ui/completions.rs @@ -60,7 +60,7 @@ pub fn completions( // If not found, the whole substring is a word None => before_cursor, }; - commands.add(UpdateAutoComplete(keyword_before.to_owned())); + commands.queue(UpdateAutoComplete(keyword_before.to_owned())); } else { ui.memory_mut(|mem| { if mem.is_popup_open(text_edit_complete_id) { From 6d41108a2f3373f155bbc9b3a6c2ed8226b2494c Mon Sep 17 00:00:00 2001 From: doonv <58695417+doonv@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:50:55 +0200 Subject: [PATCH 2/2] it works now --- src/builtin_parser/runner.rs | 313 +++++++++--------- src/builtin_parser/runner/environment.rs | 10 +- src/builtin_parser/runner/error.rs | 9 + src/builtin_parser/runner/value.rs | 395 +++++++++++------------ 4 files changed, 365 insertions(+), 362 deletions(-) diff --git a/src/builtin_parser/runner.rs b/src/builtin_parser/runner.rs index e05b943..500efcf 100644 --- a/src/builtin_parser/runner.rs +++ b/src/builtin_parser/runner.rs @@ -220,164 +220,160 @@ fn eval_expression( .reflect_path_mut(resource.path.as_str()) .unwrap(); - // match reflect.reflect_mut() { - // ReflectMut::Enum(dyn_enum) => { - // let TypeInfo::Enum(enum_info) = registration.type_info() else { - // unreachable!() - // }; - // let Spanned { span, value } = *value_expr; - // match value { - // Expression::Variable(name) => { - // let variant_info = match enum_info.variant(&name) { - // Some(variant_info) => variant_info, - // None => { - // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - // } - // }; - // let VariantInfo::Unit(_) = variant_info else { - // return todo_error!("{variant_info:?}"); - // }; - - // let new_enum = DynamicEnum::new(name, ()); - - // dyn_enum.apply(&new_enum); - // } - // Expression::StructObject { name, map } => { - // let variant_info = match enum_info.variant(&name) { - // Some(variant_info) => variant_info, - // None => { - // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - // } - // }; - // let VariantInfo::Struct(variant_info) = variant_info else { - // return todo_error!("{variant_info:?}"); - // }; - - // let map: HashMap<_, _> = map - // .into_iter() - // .map(|(k, v)| { - // let ty = match variant_info.field(&k) { - // Some(field) => Ok(field.type_path_table().short_path()), - // None => { - // Err(EvalError::EnumVariantStructFieldNotFound { - // field_name: k.clone(), - // variant_name: name.clone(), - // span: span.clone(), - // }) - // } - // }?; - - // let span = v.span.clone(); - - // Ok(( - // k, - // ( - // eval_expression( - // v, - // EvalParams { - // world, - // environment, - // registrations, - // }, - // )?, - // span, - // ty, - // ), - // )) - // }) - // .collect::>()?; - - // let new_enum = - // DynamicEnum::new(name, object_to_dynamic_struct(map)?); - - // let mut dyn_reflect = - // resource.mut_dyn_reflect(world, registrations); - - // let dyn_enum = dyn_reflect - // .reflect_path_mut(resource.path.as_str()) - // .unwrap(); - - // dyn_enum.apply(&new_enum); - // } - // Expression::StructTuple { name, tuple } => { - // let variant_info = match enum_info.variant(&name) { - // Some(variant_info) => variant_info, - // None => { - // return Err(EvalError::EnumVariantNotFound(span.wrap(name))) - // } - // }; - // let VariantInfo::Tuple(variant_info) = variant_info else { - // return todo_error!("{variant_info:?}"); - // }; - - // let tuple = eval_tuple( - // tuple, - // EvalParams { - // world, - // environment, - // registrations, - // }, - // )?; - - // let mut dynamic_tuple = DynamicTuple::default(); - - // for (index, element) in tuple.into_vec().into_iter().enumerate() { - // let ty = match variant_info.field_at(index) { - // Some(field) => Ok(field.type_path_table().short_path()), - // None => Err(EvalError::EnumVariantTupleFieldNotFound { - // field_index: index, - // variant_name: name.clone(), - // span: span.clone(), - // }), - // }?; - - // dynamic_tuple.insert_boxed( - // element.value.into_inner().reflect(element.span, ty)?.into_partial_reflect(), - // ); - // } - - // let new_enum = DynamicEnum::new(name, dynamic_tuple); - - // let mut dyn_reflect = - // resource.mut_dyn_reflect(world, registrations); - - // let dyn_enum = dyn_reflect - // .reflect_path_mut(resource.path.as_str()) - // .unwrap(); - - // dyn_enum.apply(&new_enum); - // } - // _ => todo_error!(), - // } - // } - // _ => { - // let span = value_expr.span.clone(); - // let ty = reflect.reflect_short_type_path().to_owned(); - // let value = eval_expression( - // *value_expr, - // EvalParams { - // world, - // environment, - // registrations, - // }, - // )?; - // let value_reflect = value.reflect(span.clone(), &ty)?; - - // let mut dyn_reflect = resource.mut_dyn_reflect(world, registrations); - - // let reflect = dyn_reflect - // .reflect_path_mut(resource.path.as_str()) - // .unwrap(); - - // reflect.set(value_reflect).map_err(|value_reflect| { - // EvalError::IncompatibleReflectTypes { - // span, - // expected: reflect.reflect_type_path().to_string(), - // actual: value_reflect.reflect_type_path().to_string(), - // } - // })?; - // } - // } + match reflect.reflect_mut() { + ReflectMut::Enum(dyn_enum) => { + let TypeInfo::Enum(enum_info) = registration.type_info() else { + unreachable!() + }; + let Spanned { span, value } = *value_expr; + match value { + Expression::Variable(name) => { + let variant_info = match enum_info.variant(&name) { + Some(variant_info) => variant_info, + None => { + return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + } + }; + let VariantInfo::Unit(_) = variant_info else { + return todo_error!("{variant_info:?}"); + }; + + let new_enum = DynamicEnum::new(name, ()); + + dyn_enum.apply(&new_enum); + } + Expression::StructObject { name, map } => { + let variant_info = match enum_info.variant(&name) { + Some(variant_info) => variant_info, + None => { + return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + } + }; + let VariantInfo::Struct(variant_info) = variant_info else { + return todo_error!("{variant_info:?}"); + }; + + let map: HashMap<_, _> = map + .into_iter() + .map(|(k, v)| { + let ty = match variant_info.field(&k) { + Some(field) => Ok(field.type_path_table().short_path()), + None => { + Err(EvalError::EnumVariantStructFieldNotFound { + field_name: k.clone(), + variant_name: name.clone(), + span: span.clone(), + }) + } + }?; + + let span = v.span.clone(); + + Ok(( + k, + ( + eval_expression( + v, + EvalParams { + world, + environment, + registrations, + }, + )?, + span, + ty, + ), + )) + }) + .collect::>()?; + + let new_enum = + DynamicEnum::new(name, object_to_dynamic_struct(map)?); + + let mut dyn_reflect = + resource.mut_dyn_reflect(world, registrations); + + let dyn_enum = dyn_reflect + .reflect_path_mut(resource.path.as_str()) + .unwrap(); + + dyn_enum.apply(&new_enum); + } + Expression::StructTuple { name, tuple } => { + let variant_info = match enum_info.variant(&name) { + Some(variant_info) => variant_info, + None => { + return Err(EvalError::EnumVariantNotFound(span.wrap(name))) + } + }; + let VariantInfo::Tuple(variant_info) = variant_info else { + return todo_error!("{variant_info:?}"); + }; + + let tuple = eval_tuple( + tuple, + EvalParams { + world, + environment, + registrations, + }, + )?; + + let mut dynamic_tuple = DynamicTuple::default(); + + for (index, element) in tuple.into_vec().into_iter().enumerate() { + let ty = match variant_info.field_at(index) { + Some(field) => Ok(field.type_path_table().short_path()), + None => Err(EvalError::EnumVariantTupleFieldNotFound { + field_index: index, + variant_name: name.clone(), + span: span.clone(), + }), + }?; + + dynamic_tuple.insert_boxed( + element.value.into_inner().reflect(element.span, ty)?.into_partial_reflect(), + ); + } + + let new_enum = DynamicEnum::new(name, dynamic_tuple); + + let mut dyn_reflect = + resource.mut_dyn_reflect(world, registrations); + + let dyn_enum = dyn_reflect + .reflect_path_mut(resource.path.as_str()) + .unwrap(); + + dyn_enum.apply(&new_enum); + } + _ => todo_error!(), + } + } + _ => { + let span = value_expr.span.clone(); + let ty = reflect.reflect_short_type_path().to_owned(); + let value = eval_expression( + *value_expr, + EvalParams { + world, + environment, + registrations, + }, + )?; + let value_reflect = value.reflect(span.clone(), &ty)?; + + let mut dyn_reflect = resource.mut_dyn_reflect(world, registrations); + + let reflect = dyn_reflect + .reflect_path_mut(resource.path.as_str()) + .unwrap(); + + reflect.try_apply(value_reflect.as_partial_reflect()).map_err(|apply_error| { + EvalError::ApplyError {apply_error, span} + })?; + } + } Ok(Value::Resource(resource)) } @@ -441,7 +437,6 @@ fn eval_expression( )?; Ok(Value::StructTuple { name, tuple }) } - Expression::BinaryOp { left, operator, diff --git a/src/builtin_parser/runner/environment.rs b/src/builtin_parser/runner/environment.rs index b30d345..4463134 100644 --- a/src/builtin_parser/runner/environment.rs +++ b/src/builtin_parser/runner/environment.rs @@ -246,11 +246,11 @@ impl Environment { let var = env.variables.get_mut(name); let fn_obj = match var { Some(Variable::Function(_)) => { - let Variable::Function(mut fn_obj) = - std::mem::replace(var.unwrap(), Variable::Moved) - else { - unreachable!() - }; + let Variable::Function(mut fn_obj) = + std::mem::replace(var.unwrap(), Variable::Moved) + else { + unreachable!() + }; return_result = function(env, &mut fn_obj); diff --git a/src/builtin_parser/runner/error.rs b/src/builtin_parser/runner/error.rs index 6892de4..99785d5 100644 --- a/src/builtin_parser/runner/error.rs +++ b/src/builtin_parser/runner/error.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use bevy::reflect::ApplyError; use logos::Span; use crate::builtin_parser::number::Number; @@ -75,6 +76,10 @@ pub enum EvalError { field_index: usize, tuple_size: usize, }, + ApplyError { + apply_error: ApplyError, + span: Span + } } impl EvalError { @@ -106,6 +111,7 @@ impl EvalError { E::InvalidOperation { span, .. } => vec![span.clone()], E::IncorrectAccessOperation { span, .. } => vec![span.clone()], E::FieldNotFoundInTuple { span, .. } => vec![span.clone()], + E::ApplyError { span , ..} => vec![span.clone()], } } /// Returns all the hints for this error. @@ -232,6 +238,9 @@ impl std::fmt::Display for EvalError { f, "Field {field_index} is out of bounds for tuple of size {tuple_size}" ), + E::ApplyError { apply_error, span: _} => { + write!(f, "Error while applying value (todo make this error better): {apply_error}") + } } } } diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index 791976b..d86e2d8 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -12,8 +12,7 @@ use super::unique_rc::WeakRef; use bevy::ecs::world::World; use bevy::reflect::{ - DynamicStruct, DynamicTuple, GetPath, Reflect, ReflectRef, TypeInfo, TypeRegistration, - VariantInfo, VariantType, + DynamicStruct, DynamicTuple, GetPath, PartialReflect, Reflect, ReflectRef, TypeInfo, TypeRegistration, VariantInfo, VariantType }; use logos::Span; @@ -61,37 +60,36 @@ pub enum Value { } impl Value { - /// Converts this value into a [`Box`]. + /// Converts this value into a [`Box`]. /// /// `ty` is used for type inference. - pub fn reflect(self, span: Span, ty: &str) -> Result, EvalError> { - todo!() - // match self { - // Value::None => Ok(Box::new(())), - // Value::Number(number) => number.reflect(span, ty), - // Value::Boolean(boolean) => Ok(Box::new(boolean)), - // Value::String(string) => Ok(Box::new(string)), - // Value::Reference(_reference) => Err(EvalError::CannotReflectReference(span)), - // Value::Object(object) | Value::StructObject { map: object, .. } => { - // let mut dyn_struct = DynamicStruct::default(); - - // for (name, value) in object { - // dyn_struct.insert_boxed(&name, value.into_inner().reflect(span.clone(), ty)?); - // } - - // Ok(Box::new(dyn_struct)) - // } - // Value::Tuple(tuple) | Value::StructTuple { tuple, .. } => { - // let mut dyn_tuple = DynamicTuple::default(); - - // for element in Vec::from(tuple).into_iter() { - // dyn_tuple.insert_boxed(element.value.into_inner().reflect(element.span, ty)?); - // } - - // Ok(Box::new(dyn_tuple)) - // } - // Value::Resource(_) => Err(EvalError::CannotReflectResource(span)), - // } + pub fn reflect(self, span: Span, ty: &str) -> Result, EvalError> { + match self { + Value::None => Ok(Box::new(())), + Value::Number(number) => number.reflect(span, ty).map(PartialReflect::into_partial_reflect), + Value::Boolean(boolean) => Ok(Box::new(boolean)), + Value::String(string) => Ok(Box::new(string)), + Value::Reference(_reference) => Err(EvalError::CannotReflectReference(span)), + Value::Object(object) | Value::StructObject { map: object, .. } => { + let mut dyn_struct = DynamicStruct::default(); + + for (name, value) in object { + dyn_struct.insert_boxed(&name, value.into_inner().reflect(span.clone(), ty)?); + } + + Ok(Box::new(dyn_struct)) + } + Value::Tuple(tuple) | Value::StructTuple { tuple, .. } => { + let mut dyn_tuple = DynamicTuple::default(); + + for element in Vec::from(tuple).into_iter() { + dyn_tuple.insert_boxed(element.value.into_inner().reflect(element.span, ty)?); + } + + Ok(Box::new(dyn_tuple)) + } + Value::Resource(_) => Err(EvalError::CannotReflectResource(span)), + } } /// Attempts to format this [`Value`]. @@ -241,173 +239,174 @@ fn fancy_debug_print( registrations: &[&TypeRegistration], ) -> String { const TAB: &str = " "; - todo!() - // let registration = registrations.create_registration(resource.id); - // let dyn_reflect = resource.ref_dyn_reflect(world, registration); - - // let reflect = dyn_reflect.reflect_path(resource.path.as_str()).unwrap(); - - // fn debug_subprint(reflect: &dyn Reflect, indentation: usize) -> String { - // let mut f = String::new(); - // let reflect_ref = reflect.reflect_ref(); - // let indentation_string = TAB.repeat(indentation); - // match reflect_ref { - // ReflectRef::Struct(struct_info) => { - // f += "{\n"; - // for i in 0..struct_info.field_len() { - // let field = struct_info.field_at(i).unwrap(); - // let field_name = struct_info.name_at(i).unwrap(); - - // let field_value = debug_subprint(field, indentation + 1); - // f += &format!( - // "{indentation_string}{TAB}{field_name}: {} = {field_value},\n", - // field.reflect_short_type_path(), - // ); - // } - // f += &indentation_string; - // f += "}"; - // } - // ReflectRef::TupleStruct(_) => todo!(), - // ReflectRef::Tuple(tuple_info) => { - // f += "(\n"; - // for field in tuple_info.iter_fields() { - // let field_value = debug_subprint(field, indentation + 1); - // f += &format!("{indentation_string}{TAB}{field_value},\n",); - // } - // f += &indentation_string; - // f += ")"; - // } - // ReflectRef::List(_) => todo!(), - // ReflectRef::Array(_) => todo!(), - // ReflectRef::Map(_) => todo!(), - // ReflectRef::Enum(variant) => { - // // Print out the enum types - // f += variant.variant_name(); - - // match variant.variant_type() { - // VariantType::Struct => { - // f += " {\n"; - // for field in variant.iter_fields() { - // f += &format!( - // "{indentation_string}{TAB}{}: {} = {},\n", - // field.name().unwrap(), - // field.value().reflect_short_type_path(), - // debug_subprint(field.value(), indentation + 1) - // ); - // } - // f += &indentation_string; - // f += "}"; - // } - // VariantType::Tuple => { - // f += "(\n"; - // for field in variant.iter_fields() { - // f += &format!( - // "{indentation_string}{TAB}{} = {},\n", - // field.value().reflect_short_type_path(), - // debug_subprint(field.value(), indentation + 1) - // ); - // } - // f += &indentation_string; - // f += ")"; - // } - // VariantType::Unit => {} - // } - // } - // ReflectRef::Value(_) => { - // f += &format!("{reflect:?}"); - // } - // } - - // f - // } - - // let mut f = String::new(); - // let reflect_ref = reflect.reflect_ref(); - // match reflect_ref { - // ReflectRef::Struct(struct_info) => { - // f += &format!("struct {} {{\n", struct_info.reflect_short_type_path()); - // for i in 0..struct_info.field_len() { - // let field = struct_info.field_at(i).unwrap(); - // let field_name = struct_info.name_at(i).unwrap(); - - // let field_value = debug_subprint(field, 1); - // f += &format!( - // "{TAB}{}: {} = {},\n", - // field_name, - // field.reflect_short_type_path(), - // field_value - // ); - // } - // f += "}"; - // } - // ReflectRef::TupleStruct(_) => todo!(), - // ReflectRef::Tuple(_) => todo!(), - // ReflectRef::List(_) => todo!(), - // ReflectRef::Array(_) => todo!(), - // ReflectRef::Map(_) => todo!(), - // ReflectRef::Enum(set_variant_info) => { - // // Print out the enum types - // f += &format!("enum {} {{\n", set_variant_info.reflect_short_type_path()); - // let TypeInfo::Enum(enum_info) = registration.type_info() else { - // unreachable!() - // }; - // for variant in enum_info.iter() { - // f += "\t"; - // f += variant.name(); - // match variant { - // VariantInfo::Struct(variant) => { - // f += " {\n"; - // for field in variant.iter() { - // f += &format!( - // "{TAB}{TAB}{}: {},\n", - // field.name(), - // field.type_path_table().short_path() - // ); - // } - // f += TAB; - // f += "}"; - // } - // VariantInfo::Tuple(variant) => { - // f += "("; - // let mut iter = variant.iter(); - // if let Some(first) = iter.next() { - // f += &format!("{}", first.type_path_table().short_path()); - // for field in iter { - // f += &format!(", {}", field.type_path_table().short_path()); - // } - // } - // f += ")"; - // } - // VariantInfo::Unit(_) => {} - // } - // f += ",\n"; - // } - // // Print out the current value - // f += "} = "; - // f += set_variant_info.variant_name(); - // match set_variant_info.variant_type() { - // VariantType::Struct => { - // f += " {\n"; - // for field in set_variant_info.iter_fields() { - // f += &format!("{TAB}{}: {:?},\n", field.name().unwrap(), field.value()); - // } - // f += "}"; - // } - // VariantType::Tuple => { - // f += "(\n"; - // for field in set_variant_info.iter_fields() { - // f += &format!("{TAB}{:?},\n", field.value()); - // } - // f += ")"; - // } - // VariantType::Unit => {} - // } - // } - // ReflectRef::Value(value) => { - // f += &format!("{value:?}"); - // } - // } - // f + let registration = registrations.create_registration(resource.id); + let dyn_reflect = resource.ref_dyn_reflect(world, registration); + + let reflect = dyn_reflect.reflect_path(resource.path.as_str()).unwrap(); + + fn debug_subprint(reflect: &dyn PartialReflect, indentation: usize) -> String { + let mut f = String::new(); + let reflect_ref = reflect.reflect_ref(); + let indentation_string = TAB.repeat(indentation); + match reflect_ref { + ReflectRef::Struct(struct_info) => { + f += "{\n"; + for i in 0..struct_info.field_len() { + let field = struct_info.field_at(i).unwrap(); + let field_name = struct_info.name_at(i).unwrap(); + + let field_value = debug_subprint(field, indentation + 1); + f += &format!( + "{indentation_string}{TAB}{field_name}: {} = {field_value},\n", + field.reflect_short_type_path(), + ); + } + f += &indentation_string; + f += "}"; + } + ReflectRef::TupleStruct(_) => todo!(), + ReflectRef::Tuple(tuple_info) => { + f += "(\n"; + for field in tuple_info.iter_fields() { + let field_value = debug_subprint(field, indentation + 1); + f += &format!("{indentation_string}{TAB}{field_value},\n",); + } + f += &indentation_string; + f += ")"; + } + ReflectRef::List(_) => todo!(), + ReflectRef::Array(_) => todo!(), + ReflectRef::Map(_) => todo!(), + ReflectRef::Enum(variant) => { + // Print out the enum types + f += variant.variant_name(); + + match variant.variant_type() { + VariantType::Struct => { + f += " {\n"; + for field in variant.iter_fields() { + f += &format!( + "{indentation_string}{TAB}{}: {} = {},\n", + field.name().unwrap(), + field.value().reflect_short_type_path(), + debug_subprint(field.value(), indentation + 1) + ); + } + f += &indentation_string; + f += "}"; + } + VariantType::Tuple => { + f += "(\n"; + for field in variant.iter_fields() { + f += &format!( + "{indentation_string}{TAB}{} = {},\n", + field.value().reflect_short_type_path(), + debug_subprint(field.value(), indentation + 1) + ); + } + f += &indentation_string; + f += ")"; + } + VariantType::Unit => {} + } + } + ReflectRef::Opaque(_) => { + f += &format!("{reflect:?}"); + } + ReflectRef::Set(_) => todo!() + } + + f + } + + let mut f = String::new(); + let reflect_ref = reflect.reflect_ref(); + match reflect_ref { + ReflectRef::Struct(struct_info) => { + f += &format!("struct {} {{\n", struct_info.reflect_short_type_path()); + for i in 0..struct_info.field_len() { + let field = struct_info.field_at(i).unwrap(); + let field_name = struct_info.name_at(i).unwrap(); + + let field_value = debug_subprint(field, 1); + f += &format!( + "{TAB}{}: {} = {},\n", + field_name, + field.reflect_short_type_path(), + field_value + ); + } + f += "}"; + } + ReflectRef::TupleStruct(_) => todo!(), + ReflectRef::Tuple(_) => todo!(), + ReflectRef::List(_) => todo!(), + ReflectRef::Array(_) => todo!(), + ReflectRef::Map(_) => todo!(), + ReflectRef::Set(_) => todo!(), + ReflectRef::Enum(set_variant_info) => { + // Print out the enum types + f += &format!("enum {} {{\n", set_variant_info.reflect_short_type_path()); + let TypeInfo::Enum(enum_info) = registration.type_info() else { + unreachable!() + }; + for variant in enum_info.iter() { + f += "\t"; + f += variant.name(); + match variant { + VariantInfo::Struct(variant) => { + f += " {\n"; + for field in variant.iter() { + f += &format!( + "{TAB}{TAB}{}: {},\n", + field.name(), + field.type_path_table().short_path() + ); + } + f += TAB; + f += "}"; + } + VariantInfo::Tuple(variant) => { + f += "("; + let mut iter = variant.iter(); + if let Some(first) = iter.next() { + f += &format!("{}", first.type_path_table().short_path()); + for field in iter { + f += &format!(", {}", field.type_path_table().short_path()); + } + } + f += ")"; + } + VariantInfo::Unit(_) => {} + } + f += ",\n"; + } + // Print out the current value + f += "} = "; + f += set_variant_info.variant_name(); + match set_variant_info.variant_type() { + VariantType::Struct => { + f += " {\n"; + for field in set_variant_info.iter_fields() { + f += &format!("{TAB}{}: {:?},\n", field.name().unwrap(), field.value()); + } + f += "}"; + } + VariantType::Tuple => { + f += "(\n"; + for field in set_variant_info.iter_fields() { + f += &format!("{TAB}{:?},\n", field.value()); + } + f += ")"; + } + VariantType::Unit => {} + } + } + ReflectRef::Opaque(value) => { + f += &format!("{value:?}"); + } + } + f } impl From<()> for Value {