Skip to content

Commit

Permalink
More error fixes and stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
doonv committed Jan 8, 2024
1 parent 268d3d8 commit 891805f
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 52 deletions.
62 changes: 35 additions & 27 deletions src/builtin_parser/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,45 @@ pub enum Number {

impl Number {
/// Converts this into a [`Box<dyn Reflect>`](Reflect).
pub fn reflect(self, ty: &str) -> Box<dyn Reflect> {
pub fn reflect(self, span: Span, ty: &str) -> Result<Box<dyn Reflect>, RunError> {
match self {
Number::u8(number) => Box::new(number),
Number::u16(number) => Box::new(number),
Number::u32(number) => Box::new(number),
Number::u64(number) => Box::new(number),
Number::usize(number) => Box::new(number),
Number::i8(number) => Box::new(number),
Number::i16(number) => Box::new(number),
Number::i32(number) => Box::new(number),
Number::i64(number) => Box::new(number),
Number::isize(number) => Box::new(number),
Number::f32(number) => Box::new(number),
Number::f64(number) => Box::new(number),
Number::u8(number) => Ok(Box::new(number)),
Number::u16(number) => Ok(Box::new(number)),
Number::u32(number) => Ok(Box::new(number)),
Number::u64(number) => Ok(Box::new(number)),
Number::usize(number) => Ok(Box::new(number)),
Number::i8(number) => Ok(Box::new(number)),
Number::i16(number) => Ok(Box::new(number)),
Number::i32(number) => Ok(Box::new(number)),
Number::i64(number) => Ok(Box::new(number)),
Number::isize(number) => Ok(Box::new(number)),
Number::f32(number) => Ok(Box::new(number)),
Number::f64(number) => Ok(Box::new(number)),
Number::Integer(number) => match ty {
"u8" => Box::new(number as u8),
"u16" => Box::new(number as u16),
"u32" => Box::new(number as u32),
"u64" => Box::new(number as u64),
"usize" => Box::new(number as usize),
"i8" => Box::new(number as i8),
"i16" => Box::new(number as i16),
"i32" => Box::new(number as i32),
"i64" => Box::new(number as i64),
"isize" => Box::new(number as isize),
ty => todo!("{ty:?}"),
"u8" => Ok(Box::new(number as u8)),
"u16" => Ok(Box::new(number as u16)),
"u32" => Ok(Box::new(number as u32)),
"u64" => Ok(Box::new(number as u64)),
"usize" => Ok(Box::new(number as usize)),
"i8" => Ok(Box::new(number as i8)),
"i16" => Ok(Box::new(number as i16)),
"i32" => Ok(Box::new(number as i32)),
"i64" => Ok(Box::new(number as i64)),
"isize" => Ok(Box::new(number as isize)),
ty => Err(RunError::IncompatibleReflectTypes {
expected: "integer".to_string(),
actual: ty.to_string(),
span,
}),
},
Number::Float(number) => match ty {
"f32" => Box::new(number as f32),
"f64" => Box::new(number),
ty => todo!("{ty:?}"),
"f32" => Ok(Box::new(number as f32)),
"f64" => Ok(Box::new(number)),
ty => Err(RunError::IncompatibleReflectTypes {
expected: "float".to_string(),
actual: ty.to_string(),
span,
}),
},
}
}
Expand Down
22 changes: 12 additions & 10 deletions src/builtin_parser/runner.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Executes the abstract syntax tree.
use std::collections::HashMap;
use environment::Environment;
use std::collections::HashMap;

use bevy::prelude::*;
use bevy::reflect::{DynamicEnum, ReflectMut, TypeInfo, TypeRegistration, VariantInfo};
Expand Down Expand Up @@ -216,16 +216,17 @@ fn eval_expression(
let map: HashMap<_, _> = map
.into_iter()
.map(|(k, v)| {
let ty = variant_info
.field(&k)
.ok_or(RunError::EnumVariantStructFieldNotFound {
let ty = match variant_info.field(&k) {
Some(field) => Ok(field.type_path_table().short_path()),
None => Err(RunError::EnumVariantStructFieldNotFound {
field_name: k.clone(),
variant_name: name.clone(),
span: span.clone(),
})?
.type_path_table()
.short_path()
.to_owned();
}),
}?;

let span = v.span.clone();

Ok((
k,
(
Expand All @@ -237,13 +238,14 @@ fn eval_expression(
registrations,
},
)?,
span,
ty,
),
))
})
.collect::<Result<_, _>>()?;
let new_enum =
DynamicEnum::new(name, object_to_dynamic_struct(map));
DynamicEnum::new(name, object_to_dynamic_struct(map)?);

let mut dyn_reflect =
resource.mut_dyn_reflect(world, registrations);
Expand All @@ -268,7 +270,7 @@ fn eval_expression(
registrations,
},
)?;
let value_reflect = value.reflect(&ty);
let value_reflect = value.reflect(span.clone(), &ty)?;

let mut dyn_reflect = resource.mut_dyn_reflect(world, registrations);

Expand Down
8 changes: 5 additions & 3 deletions src/builtin_parser/runner/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub enum RunError {
},
VariableNotFound(Spanned<String>),
ExpectedNumberAfterUnaryOperator(Spanned<Value>),
InvalidVariantForResource(String, String),
CannotIndexValue(Span),
FieldNotFoundInStruct(Span),
ReferenceToMovedData(Span),
Expand Down Expand Up @@ -54,6 +53,7 @@ pub enum RunError {
span: Span,
},
ExpectedVariableGotFunction(Spanned<String>),
CannotReflectReference(std::ops::Range<usize>),
}

impl RunError {
Expand All @@ -65,7 +65,6 @@ impl RunError {
Custom { span, .. } => vec![span.clone()],
VariableNotFound(Spanned { span, .. }) => vec![span.clone()],
ExpectedNumberAfterUnaryOperator(Spanned { span, .. }) => vec![span.clone()],
InvalidVariantForResource(_, _) => todo!(),
CannotIndexValue(span) => vec![span.clone()],
FieldNotFoundInStruct(span) => vec![span.clone()],
CannotDereferenceValue(Spanned { span, .. }) => vec![span.clone()],
Expand All @@ -80,6 +79,7 @@ impl RunError {
IncompatibleNumberTypes { span, .. } => vec![span.clone()],
IncompatibleFunctionParameter { span, .. } => vec![span.clone()],
ExpectedVariableGotFunction(Spanned { span, .. }) => vec![span.clone()],
CannotReflectReference(span) => vec![span.clone()],
}
}
/// Returns all the hints for this error.
Expand All @@ -103,7 +103,6 @@ impl RunError {
value.kind()
)
.into(),
InvalidVariantForResource(_, _) => todo!(),
CannotIndexValue(_) => todo!(),
FieldNotFoundInStruct(_) => todo!(),
ReferenceToMovedData(_) => todo!(),
Expand Down Expand Up @@ -148,6 +147,9 @@ impl RunError {
ExpectedVariableGotFunction(Spanned { value, .. }) => {
format!("Expected `{value}` to be a variable, but got a function instead.").into()
}
CannotReflectReference(_) => {
"Cannot reflect a reference. Try dereferencing it instead.".into()
}
}
}
}
15 changes: 11 additions & 4 deletions src/builtin_parser/runner/reflection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use std::collections::HashMap;

use bevy::prelude::*;
use bevy::reflect::{DynamicStruct, ReflectFromPtr, TypeRegistration};
use logos::Span;

use crate::builtin_parser::RunError;

use super::Value;

Expand Down Expand Up @@ -40,12 +43,16 @@ impl IntoResource {
}
}

pub fn object_to_dynamic_struct(hashmap: HashMap<String, (Value, String)>) -> DynamicStruct {
pub fn object_to_dynamic_struct(
hashmap: HashMap<String, (Value, Span, &'static str)>,
) -> Result<DynamicStruct, RunError> {
let mut dynamic_struct = DynamicStruct::default();
for (key, (value, reflect)) in hashmap {
dynamic_struct.insert_boxed(&key, value.reflect(&reflect));

for (key, (value, span, reflect)) in hashmap {
dynamic_struct.insert_boxed(&key, value.reflect(span, &reflect)?);
}
dynamic_struct

Ok(dynamic_struct)
}

pub fn mut_dyn_reflect<'a>(
Expand Down
16 changes: 8 additions & 8 deletions src/builtin_parser/runner/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,21 @@ impl Value {
/// Converts this value into a [`Box<dyn Reflect>`].
///
/// `ty` is used for type inference.
pub fn reflect(self, ty: &str) -> Box<dyn Reflect> {
pub fn reflect(self, span: Span, ty: &str) -> Result<Box<dyn Reflect>, RunError> {
match self {
Value::None => Box::new(()),
Value::Number(number) => number.reflect(ty),
Value::Boolean(boolean) => Box::new(boolean),
Value::String(string) => Box::new(string),
Value::Reference(reference) => todo!(),
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(RunError::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(ty));
dyn_struct.insert_boxed(&name, value.into_inner().reflect(span.clone(), ty)?);
}

Box::new(dyn_struct)
Ok(Box::new(dyn_struct))
}
Value::Resource(_) => todo!(),
}
Expand Down

0 comments on commit 891805f

Please sign in to comment.