Skip to content

Commit

Permalink
More fixes and code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
doonv committed Jan 5, 2024
1 parent 5a8de88 commit 6283224
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 54 deletions.
6 changes: 3 additions & 3 deletions examples/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ enum MyEnum {
#[derive(Resource, Reflect, Default, Debug)]
struct MyStruct {
number1: f64,
number2: f64,
number2: i16,
number3: f32,
string: String,
}
Expand All @@ -29,13 +29,13 @@ fn main() {
App::new()
.register_type::<MyEnum>()
.init_resource::<MyEnum>()
.register_type::<MyStruct>()
.insert_resource(MyStruct {
number1: 52138.0,
number2: -123.8,
number2: -123,
number3: 0.0,
string: "hi there :)".to_string(),
})
.register_type::<MyStruct>()
.add_plugins((
ConsoleLogPlugin::default(),
DefaultPlugins.build().disable::<LogPlugin>(),
Expand Down
24 changes: 19 additions & 5 deletions src/builtin_parser/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,18 @@ pub enum Number {
u32(u32),
u64(u64),
usize(usize),

i8(i8),
i16(i16),
i32(i32),
i64(i64),
isize(isize),

f32(f32),
f64(f64),
}

impl Number {
/// Converts this into a [`Box<dyn Reflect>`](Reflect).
pub fn reflect(self) -> Box<dyn Reflect> {
pub fn reflect(self, ty: &str) -> Box<dyn Reflect> {
match self {
Number::u8(number) => Box::new(number),
Number::u16(number) => Box::new(number),
Expand All @@ -51,8 +49,24 @@ impl Number {
Number::isize(number) => Box::new(number),
Number::f32(number) => Box::new(number),
Number::f64(number) => Box::new(number),
Number::Integer(_) => todo!(),
Number::Float(_) => todo!(),
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:?}"),
},
Number::Float(number) => match ty {
"f32" => Box::new(number as f32),
"f64" => Box::new(number),
ty => todo!("{ty:?}"),
},
}
}

Expand Down
20 changes: 10 additions & 10 deletions src/builtin_parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ use super::{
pub type Ast = Vec<Spanned<Expression>>;

macro_rules! expect {
($tokens:ident, $token:pat, $tokenexpr:expr) => {
($tokens:ident, $($token:tt)+) => {
match $tokens.next() {
Some(Ok($token)) => $tokenexpr,
Some(Ok($($token)+)) => ($($token)+) ,
Some(Ok(token)) => {
return Err(ParseError::ExpectedTokenButGot {
expected: $tokenexpr,
expected: $($token)+,
got: token,
span: $tokens.span(),
})
Expand Down Expand Up @@ -171,9 +171,9 @@ fn parse_expression(
})
}
fn parse_block(tokens: &mut TokenStream, environment: &Environment) -> Result<Ast, ParseError> {
expect!(tokens, Token::LeftBracket, Token::LeftBracket);
expect!(tokens, Token::LeftBracket);
let ast = parse(tokens, environment)?;
expect!(tokens, Token::RightBracket, Token::RightBracket);
expect!(tokens, Token::RightBracket);
Ok(ast)
}
fn parse_additive(
Expand Down Expand Up @@ -246,15 +246,15 @@ fn parse_primary(
})
} else {
let expr = parse_expression(tokens, environment)?;
expect!(tokens, Token::RightParen, Token::RightParen);
expect!(tokens, Token::RightParen);
Ok(expr)
}
}
Some(Ok(Token::Identifer)) => match tokens.peek() {
Some(Ok(Token::LeftBracket)) => {
let name = tokens.slice().to_string();

expect!(tokens, Token::LeftBracket, Token::LeftBracket);
expect!(tokens, Token::LeftBracket);
let map = parse_object(tokens, environment)?;

Ok(Spanned {
Expand Down Expand Up @@ -386,7 +386,7 @@ fn parse_primary(
// If theres a dot after the expression, do a member expression:
while let Some(Ok(Token::Dot)) = tokens.peek() {
tokens.next(); // skip the dot
expect!(tokens, Token::Identifer, Token::Identifer);
expect!(tokens, Token::Identifer);
let right = tokens.slice().to_string();
expr = Spanned {
span: expr.span.start..tokens.span().end,
Expand Down Expand Up @@ -430,7 +430,7 @@ fn parse_object(
while let Some(Ok(Token::Identifer)) = tokens.peek() {
tokens.next();
let ident = tokens.slice().to_string();
expect!(tokens, Token::Colon, Token::Colon);
expect!(tokens, Token::Colon);
let expr = parse_expression(tokens, environment)?;
map.insert(ident, expr);
match tokens.peek() {
Expand All @@ -441,7 +441,7 @@ fn parse_object(
token => todo!("{token:?}"),
}
}
expect!(tokens, Token::RightBracket, Token::RightBracket);
expect!(tokens, Token::RightBracket);
Ok(map)
}

Expand Down
65 changes: 41 additions & 24 deletions src/builtin_parser/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ use super::{
};
use bevy::{
prelude::*,
reflect::{DynamicEnum, Enum, ReflectMut, TypeInfo, TypeRegistration},
reflect::{
DynamicEnum, DynamicStruct, Enum, ReflectMut, ReflectRef, TypeInfo, TypeRegistration,
VariantInfo,
},
};

pub mod environment;
Expand Down Expand Up @@ -199,38 +202,51 @@ fn eval_expression(
if enum_info.contains_variant(&variable) {
let new_enum = DynamicEnum::new(variable, ());

dyn_enum.set(Box::new(new_enum)).map_err(|new_enum| {
RunError::IncompatibleReflectTypes {
span,
expected: dyn_enum.variant_name().to_string(),
actual: new_enum
.downcast::<DynamicEnum>()
.unwrap()
.variant_name()
.to_string(),
}
})
dyn_enum.apply(&new_enum);
} else {
Err(RunError::EnumVariantNotFound {
name: variable,
span,
})
}?
})?
}
}
Expression::StructObject { name, map } => {
let map: HashMap<String, Value> = map
let variant_info = enum_info.variant(&name).ok_or(
RunError::EnumVariantNotFound {
name: name.clone(),
span: span.clone(),
},
)?;
let VariantInfo::Struct(variant_info) = variant_info else {
return todo_error!("{variant_info:?}");
};

let map: HashMap<_, _> = map
.into_iter()
.map(|(k, v)| {
let ty = variant_info
.field(&k)
.ok_or(RunError::EnumVariantStructFieldNotFound {
field_name: k.clone(),
variant_name: name.clone(),
span: span.clone(),
})?
.type_path_table()
.short_path()
.to_owned();
Ok((
k,
eval_expression(
v,
EvalParams {
world,
environment,
registrations,
},
)?,
(
eval_expression(
v,
EvalParams {
world,
environment,
registrations,
},
)?,
ty,
),
))
})
.collect::<Result<_, _>>()?;
Expand All @@ -251,6 +267,7 @@ fn eval_expression(
}
_ => {
let span = value_expr.span.clone();
let ty = reflect.reflect_short_type_path().to_owned();
let value = eval_expression(
*value_expr,
EvalParams {
Expand All @@ -259,7 +276,7 @@ fn eval_expression(
registrations,
},
)?;
let value_reflect = value.reflect();
let value_reflect = value.reflect(&ty);

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

Expand Down
21 changes: 17 additions & 4 deletions src/builtin_parser/runner/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ pub enum RunError {
actual: &'static str,
span: Span,
},
EnumVariantStructFieldNotFound {
field_name: String,
variant_name: String,
span: Span,
},
}

impl RunError {
Expand All @@ -69,6 +74,7 @@ impl RunError {
CannotBorrowValue(span) => vec![span.clone()],
IncompatibleReflectTypes { span, .. } => vec![span.clone()],
EnumVariantNotFound { span, .. } => vec![span.clone()],
EnumVariantStructFieldNotFound { span, .. } => vec![span.clone()],
CannotMoveOutOfResource(Spanned { span, .. }) => vec![span.clone()],
CannotNegateUnsignedInteger(Spanned { span, .. }) => vec![span.clone()],
IncompatibleNumberTypes { span, .. } => vec![span.clone()],
Expand Down Expand Up @@ -105,11 +111,18 @@ impl RunError {
VariableMoved(Spanned { value, .. }) => format!("Variable `{value}` was moved.").into(),
CannotBorrowValue(_) => todo!(),
IncompatibleReflectTypes {
expected,
actual,
span,
} => todo!(),
expected, actual, ..
} => format!(
"Cannot set incompatible reflect types. Expected `{expected}`, got `{actual}`"
)
.into(),
EnumVariantNotFound { name, span } => todo!(),
EnumVariantStructFieldNotFound {
field_name,
variant_name,
..
} => format!("Field `{field_name}` doesn't exist on struct variant `{variant_name}`.")
.into(),
CannotMoveOutOfResource(Spanned { value, .. }) => {
format!("Cannot move out of resource `{value}`, try borrowing it instead.").into()
}
Expand Down
6 changes: 3 additions & 3 deletions src/builtin_parser/runner/reflection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ impl IntoResource {
}
}

pub fn object_to_dynamic_struct(hashmap: HashMap<String, Value>) -> DynamicStruct {
pub fn object_to_dynamic_struct(hashmap: HashMap<String, (Value, String)>) -> DynamicStruct {
let mut dynamic_struct = DynamicStruct::default();
for (key, value) in hashmap {
dynamic_struct.insert_boxed(&key, value.reflect());
for (key, (value, reflect)) in hashmap {
dynamic_struct.insert_boxed(&key, value.reflect(&reflect));
}
dynamic_struct
}
Expand Down
2 changes: 1 addition & 1 deletion src/builtin_parser/runner/unique_rc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
cell::{Cell, Ref, RefCell, RefMut},
cell::{Ref, RefCell, RefMut},
fmt::Debug,
ops::{Deref, DerefMut},
rc::{Rc, Weak},
Expand Down
12 changes: 8 additions & 4 deletions src/builtin_parser/runner/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,23 @@ pub enum Value {

impl Value {
/// Converts this value into a [`Box<dyn Reflect>`].
pub fn reflect(self) -> Box<dyn Reflect> {
///
/// `ty` is used for type inference.
pub fn reflect(self, ty: &str) -> Box<dyn Reflect> {
match self {
Value::None => Box::new(()),
Value::Number(number) => number.reflect(),
Value::Number(number) => number.reflect(ty),
Value::Boolean(boolean) => Box::new(boolean),
Value::String(string) => Box::new(string),
Value::Reference(reference) => todo!(),
Value::Object(object) | Value::StructObject { map: object, .. } => {
let mut dyn_struct = DynamicStruct::default();

for (name, value) in object {
dyn_struct
.insert_boxed(&name, Rc::try_unwrap(value).unwrap().into_inner().reflect());
dyn_struct.insert_boxed(
&name,
Rc::try_unwrap(value).unwrap().into_inner().reflect(ty),
);
}

Box::new(dyn_struct)
Expand Down

0 comments on commit 6283224

Please sign in to comment.