Skip to content

Commit

Permalink
Several small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
doonv committed Dec 14, 2023
1 parent 4378c35 commit 6e1d91e
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 67 deletions.
4 changes: 3 additions & 1 deletion src/builtin_parser/lexer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Generates a stream of tokens from a string.
use logos::{Lexer, Logos, Span};

use super::Spanned;
Expand Down Expand Up @@ -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>,
Expand Down
2 changes: 2 additions & 0 deletions src/builtin_parser/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Generates an abstract syntax tree from a list of tokens.
use logos::Span;
use std::collections::HashMap;

Expand Down
28 changes: 10 additions & 18 deletions src/builtin_parser/runner.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down Expand Up @@ -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<usize>),
ReferenceToMovedData(std::ops::Range<usize>),
VariableMoved(std::ops::Range<usize>),
CannotBorrowValue(std::ops::Range<usize>),
CouldntDereferenceValue(Span),
ReferenceToMovedData(Span),
VariableMoved(Span),
CannotBorrowValue(Span),
}

pub fn run(ast: Ast, world: &mut World) {
Expand Down Expand Up @@ -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 {
Expand Down
61 changes: 57 additions & 4 deletions src/builtin_parser/runner/environment.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -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<T, E>(pub Result<T, E>);

Expand Down Expand Up @@ -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<Rc<RefCell<Value>>, 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<Value, RunError> {
let (env, span) = self.resolve_mut(name, span)?;

match env.variables.get_mut(name) {
Expand All @@ -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)),
}
Expand Down
41 changes: 2 additions & 39 deletions src/builtin_parser/runner/stdlib.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -52,43 +52,6 @@ fn ref_depth(Spanned { span, value }: Spanned<Value>) -> Result<f64, RunError> {
/// 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;
Expand Down
2 changes: 1 addition & 1 deletion src/builtin_parser/runner/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub enum Value {
/// This isn't partically efficent, so:
/// TODO: Create a custom type this!
Reference(Weak<RefCell<Value>>),
/// A dynamic [`HashMap].
/// A dynamic [`HashMap`].
Object(HashMap<String, Rc<RefCell<Value>>>),
/// An [`Object`](Value::Object) with a name attached to it.
StructObject {
Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
@@ -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;
7 changes: 4 additions & 3 deletions src/ui.rs
Original file line number Diff line number Diff line change
@@ -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::*;
Expand All @@ -16,7 +17,7 @@ pub struct ConsoleUiState {
command: String,
}

fn system_time_to_chorno_utc(t: SystemTime) -> chrono::DateTime<chrono::Utc> {
fn system_time_to_chrono_utc(t: SystemTime) -> chrono::DateTime<chrono::Utc> {
let dur = t.duration_since(instant::SystemTime::UNIX_EPOCH).unwrap();
let (sec, nsec) = (dur.as_secs() as i64, dur.subsec_nanos());

Expand Down Expand Up @@ -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<chrono::Local> = time_utc.into();
let res = ui
.horizontal_wrapped(|ui| {
Expand Down

0 comments on commit 6e1d91e

Please sign in to comment.