From 6e1d91ecec94870e117042100a82995226a84e04 Mon Sep 17 00:00:00 2001 From: Doonv <58695417+doonv@users.noreply.github.com> Date: Thu, 14 Dec 2023 13:22:25 +0200 Subject: [PATCH] Several small fixes --- src/builtin_parser/lexer.rs | 4 +- src/builtin_parser/parser.rs | 2 + src/builtin_parser/runner.rs | 28 ++++------- src/builtin_parser/runner/environment.rs | 61 ++++++++++++++++++++++-- src/builtin_parser/runner/stdlib.rs | 41 +--------------- src/builtin_parser/runner/value.rs | 2 +- src/prelude.rs | 2 +- src/ui.rs | 7 +-- 8 files changed, 80 insertions(+), 67 deletions(-) diff --git a/src/builtin_parser/lexer.rs b/src/builtin_parser/lexer.rs index a824ce0..ac6f808 100644 --- a/src/builtin_parser/lexer.rs +++ b/src/builtin_parser/lexer.rs @@ -1,3 +1,5 @@ +//! Generates a stream of tokens from a string. + use logos::{Lexer, Logos, Span}; use super::Spanned; @@ -69,7 +71,7 @@ pub enum Token { Number, } -/// A wrapper for the lexer which provides peeking and other helper functions +/// A wrapper for the lexer which provides token peeking and other helper functions #[derive(Debug)] pub struct TokenStream<'a> { lexer: Lexer<'a, Token>, diff --git a/src/builtin_parser/parser.rs b/src/builtin_parser/parser.rs index 0228103..cab421d 100644 --- a/src/builtin_parser/parser.rs +++ b/src/builtin_parser/parser.rs @@ -1,3 +1,5 @@ +//! Generates an abstract syntax tree from a list of tokens. + use logos::Span; use std::collections::HashMap; diff --git a/src/builtin_parser/runner.rs b/src/builtin_parser/runner.rs index 5128927..0f85ebb 100644 --- a/src/builtin_parser/runner.rs +++ b/src/builtin_parser/runner.rs @@ -1,6 +1,8 @@ +//! Executes the abstract syntax tree. + use std::{cell::RefCell, collections::HashMap, rc::Rc}; -use self::environment::Environment; +use environment::Environment; use super::{ parser::{Ast, Expression, Operator}, @@ -31,16 +33,16 @@ pub struct EvalParams<'a, 'b, 'c> { #[derive(Debug)] pub enum RunError { + Basic { text: String, span: Span }, VariableNotFound(Span), ExpectedNumberAfterUnaryOperator(Value), InvalidVariantForResource(String, String), - Basic { text: String, span: Span }, CannotIndexValue(Span), FieldNotFoundInStruct(Span), - CouldntDereferenceValue(std::ops::Range), - ReferenceToMovedData(std::ops::Range), - VariableMoved(std::ops::Range), - CannotBorrowValue(std::ops::Range), + CouldntDereferenceValue(Span), + ReferenceToMovedData(Span), + VariableMoved(Span), + CannotBorrowValue(Span), } pub fn run(ast: Ast, world: &mut World) { @@ -153,25 +155,15 @@ fn eval_expression( Expression::String(string) => Ok(Value::String(string)), Expression::Number(number) => Ok(Value::Number(number)), Expression::Variable(variable) => { - dbg!(&variable); if let Some(registration) = registrations .iter() .find(|v| v.type_info().type_path_table().short_path() == variable) { info!(name: "console_result", "> {}", fancy_debug_print(registration, world)); + Ok(Value::None) } else { - #[allow(clippy::single_match)] - match &*environment.get(&variable, expr.span.clone())?.borrow() { - Value::Number(number) => return Ok(Value::Number(*number)), - _ => {} - } - - // Unwrapping will always succeed due to only the owner of the variable having - // a strong reference. All other references are weak. - let value = Rc::try_unwrap(environment.move_var(&variable, expr.span)?).unwrap(); - - Ok(value.into_inner()) + environment.move_var(&variable, expr.span) } } Expression::BinaryOp { diff --git a/src/builtin_parser/runner/environment.rs b/src/builtin_parser/runner/environment.rs index 0cce672..fe8827c 100644 --- a/src/builtin_parser/runner/environment.rs +++ b/src/builtin_parser/runner/environment.rs @@ -1,3 +1,5 @@ +//! Environment and function registeration + use std::{cell::RefCell, collections::HashMap, rc::Rc}; use bevy::{ecs::world::World, log::warn, reflect::TypeRegistration}; @@ -8,6 +10,43 @@ use super::{ eval_expression, stdlib, EvalParams, RunError, Value, }; +/// Macro for mass registering functions. +/// +/// ``` +/// fn a() {} +/// fn b() {} +/// fn c() {} +/// +/// # let mut environment = bevy_dev_console::builtin_parser::Environment::default(); +/// # use bevy_dev_console::register; +/// register!(environment => { +/// fn a; +/// fn b; +/// fn c; +/// }); +/// ``` +#[macro_export] +macro_rules! register { + { + $environment:expr => fn $fn_name:ident; + } => { + $environment + .register_fn(stringify!($fn_name), $fn_name) + }; + { + $environment:expr => { + $( + fn $fn_name:ident; + )* + } + } => { + $environment + $( + .register_fn(stringify!($fn_name), $fn_name) + )* + }; +} + /// Get around implementation of Result causing stupid errors pub(super) struct ResultContainer(pub Result); @@ -202,8 +241,9 @@ impl Environment { } } - /// "moves" a variable, giving you ownership over it. However it will no longer be able to be used. - pub fn move_var(&mut self, name: &str, span: Span) -> Result>, RunError> { + /// "moves" a variable, giving you ownership over it. However it will no longer be able to be used unless + /// it's a [`Value::None`], [`Value::Boolean`], or [`Value::Number`] in which case it will be copied. + pub fn move_var(&mut self, name: &str, span: Span) -> Result { let (env, span) = self.resolve_mut(name, span)?; match env.variables.get_mut(name) { @@ -213,8 +253,21 @@ impl Environment { let Variable::Unmoved(value) = std::mem::replace(reference, Variable::Moved) else { unreachable!() }; - - Ok(value) + // SAFETY: The reference goes out of scope before it can get borrowed again. + let reference = unsafe { value.try_borrow_unguarded().unwrap() }; + // This is a pretty bad way of handling + match reference { + Value::None => Ok(Value::None), + Value::Boolean(bool) => Ok(Value::Boolean(*bool)), + Value::Number(number) => Ok(Value::Number(*number)), + _ => { + // Unwrapping will always succeed due to only the owner of the variable having + // a strong reference. All other references are weak. + let value = Rc::try_unwrap(value).unwrap(); + + Ok(value.into_inner()) + } + } } None => Err(RunError::VariableNotFound(span)), } diff --git a/src/builtin_parser/runner/stdlib.rs b/src/builtin_parser/runner/stdlib.rs index 5c2fe01..01dc9d4 100644 --- a/src/builtin_parser/runner/stdlib.rs +++ b/src/builtin_parser/runner/stdlib.rs @@ -1,6 +1,6 @@ -use std::{cell::Ref, ops::Range}; - +use crate::register; use bevy::log::info; +use std::{cell::Ref, ops::Range}; use super::{Environment, RunError, Spanned, Value}; @@ -52,43 +52,6 @@ fn ref_depth(Spanned { span, value }: Spanned) -> Result { /// Disposes of a [`Value`]. fn drop(_v: Value) {} -/// Macro for mass registering functions. -/// -/// ``` -/// fn a() {} -/// fn b() {} -/// fn c() {} -/// -/// # let mut environment = bevy_dev_console::builtin_parser::Environment::default(); -/// # use bevy_dev_console::register; -/// register!(environment => { -/// fn a; -/// fn b; -/// fn c; -/// }); -/// ``` -#[macro_export] -macro_rules! register { - { - $environment:expr => fn $fn_name:ident; - } => { - $environment - .register_fn(stringify!($fn_name), $fn_name) - }; - { - $environment:expr => { - $( - fn $fn_name:ident; - )* - } - } => { - $environment - $( - .register_fn(stringify!($fn_name), $fn_name) - )* - }; -} - pub fn register(environment: &mut Environment) { register!(environment => { fn print; diff --git a/src/builtin_parser/runner/value.rs b/src/builtin_parser/runner/value.rs index 3baef6b..dcbc6e3 100644 --- a/src/builtin_parser/runner/value.rs +++ b/src/builtin_parser/runner/value.rs @@ -32,7 +32,7 @@ pub enum Value { /// This isn't partically efficent, so: /// TODO: Create a custom type this! Reference(Weak>), - /// A dynamic [`HashMap]. + /// A dynamic [`HashMap`]. Object(HashMap>>), /// An [`Object`](Value::Object) with a name attached to it. StructObject { diff --git a/src/prelude.rs b/src/prelude.rs index 711660e..86ebf5b 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,4 +1,4 @@ -//! `use bevy_dev_console::prelude::*` to quickly import the required plugins for `bevy_dev_console`. +//! `use bevy_dev_console::prelude::*` to quickly import the required plugins for [`bevy_dev_console`](crate). pub use crate::logging::log_plugin::ConsoleLogPlugin; pub use crate::DevConsolePlugin; diff --git a/src/ui.rs b/src/ui.rs index 754d654..37b6340 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,6 +1,7 @@ //! The module that handles the user interface of the console. //! -//! Made with [`bevy_egui`] +//! Made with [`bevy_egui`]. + use bevy::prelude::*; use bevy::utils::tracing::Level; use bevy_egui::*; @@ -16,7 +17,7 @@ pub struct ConsoleUiState { command: String, } -fn system_time_to_chorno_utc(t: SystemTime) -> chrono::DateTime { +fn system_time_to_chrono_utc(t: SystemTime) -> chrono::DateTime { let dur = t.duration_since(instant::SystemTime::UNIX_EPOCH).unwrap(); let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos()); @@ -107,7 +108,7 @@ fn add_log( const FONT_ID: egui::FontId = egui::FontId::monospace(CONSOLE_FONT_SIZE); ui.push_id(id, |ui| { - let time_utc = system_time_to_chorno_utc(*time); + let time_utc = system_time_to_chrono_utc(*time); let time: chrono::DateTime = time_utc.into(); let res = ui .horizontal_wrapped(|ui| {