From 38948883e4aedc1700b5c3360ddd8c7a92421b10 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 24 May 2023 09:05:51 -0700 Subject: [PATCH 1/3] Use event system instead of direct commands --- renrs-gui/src/lib.rs | 4 ++-- renrs/src/lib.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/renrs-gui/src/lib.rs b/renrs-gui/src/lib.rs index 19c370a..5b09f76 100644 --- a/renrs-gui/src/lib.rs +++ b/renrs-gui/src/lib.rs @@ -3,7 +3,7 @@ use std::thread; use std::time::Duration; use eframe::egui; -use renrs::{State, Command}; +use renrs::State; use sfml::{ graphics::{Color, RenderTarget, RenderWindow, RectangleShape, Transformable}, @@ -41,7 +41,7 @@ impl App { } fn next(&mut self) { - if let Some(Command::Say { name, text }) = self.state.next_command() { + if let Some(renrs::Event::Say { name, text }) = self.state.next() { self.text = match name { Some(name) => format!("{name}: {text}"), None => text, diff --git a/renrs/src/lib.rs b/renrs/src/lib.rs index c347d82..9b84807 100644 --- a/renrs/src/lib.rs +++ b/renrs/src/lib.rs @@ -31,13 +31,28 @@ use Token::*; // Parsed script commands #[derive(Debug)] -pub enum Command { +#[allow(dead_code)] +enum Command { Say { name: Option, text: String }, Eat { food: String, politely: bool }, } use Command::*; +impl Command { + fn is_blocking(&self) -> bool { + match self { + Say { .. } => true, + _ => false, + } + } +} + +#[derive(Debug)] +pub enum Event { + Say { name: Option, text: String }, +} + // Tokenize raw script string fn tokenize(script: &str) -> Vec> { let file = RpyParser::parse(Rule::file, script) @@ -159,7 +174,19 @@ impl State { } } - pub fn next_command(&mut self) -> Option { + pub fn next(&mut self) -> Option { + while let Some(command) = self.next_command() { + if command.is_blocking() { + return Some(match command { + Say { name, text } => Event::Say { name, text }, + _ => unimplemented!(), + }) + } + } + None + } + + fn next_command(&mut self) -> Option { if self.command_queue.len() == 0 { None } else { From 247ce0ce987f420068a5fcbe74036d7c6121691c Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 24 May 2023 09:23:57 -0700 Subject: [PATCH 2/3] Implement number type --- renrs/src/lib.rs | 3 +++ renrs/src/rpy.pest | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/renrs/src/lib.rs b/renrs/src/lib.rs index 9b84807..d451396 100644 --- a/renrs/src/lib.rs +++ b/renrs/src/lib.rs @@ -14,6 +14,7 @@ pub enum Token { Str(String), Array(Vec), Boolean(bool), + Number(f64), } impl Token { @@ -23,6 +24,7 @@ impl Token { Str(_) => "String", Array(_) => "Array", Boolean(_) => "Boolean", + Number(_) => "Number", } } } @@ -110,6 +112,7 @@ fn parse_pair(pair: pest::iterators::Pair) -> Token { "False" => false, _ => unreachable!(), }), + Rule::number => Token::Number(contents.as_str().parse().unwrap()), Rule::keyword => Token::Keyword(contents.as_str().to_owned()), __ => unreachable!(), } diff --git a/renrs/src/rpy.pest b/renrs/src/rpy.pest index a49b9e2..da8e3c3 100644 --- a/renrs/src/rpy.pest +++ b/renrs/src/rpy.pest @@ -8,7 +8,7 @@ char = { !NEWLINE ~ ANY } // http://pest.rs/book/grammars/syntax.html#atomic inner = @{ char* } -token = { string | array | boolean | keyword } +token = { string | array | boolean | number | keyword } // KEYWORDS // has to be atomic for no implicit separate (spaces) @@ -37,6 +37,13 @@ array = { // BOOLEAN boolean = { "True" | "False" } +// NUMBER +number = @{ + "-"? + ~ ("0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*) + ~ ("." ~ ASCII_DIGIT*)? +} + // comments are a # followed by // any number of non-newline characters COMMENT = _{ "#" ~ char* } From 59f0f8258a487f2d7da2e36df28685685f6dc1a8 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Wed, 24 May 2023 09:30:04 -0700 Subject: [PATCH 3/3] Improve error handling for Eat optional parameter --- renrs/src/lib.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/renrs/src/lib.rs b/renrs/src/lib.rs index d451396..0b6fd56 100644 --- a/renrs/src/lib.rs +++ b/renrs/src/lib.rs @@ -140,6 +140,11 @@ fn parse_file(file_path: PathBuf) -> Vec { let token_lines = tokenize_file(file_path); let mut commands = Vec::new(); for line in token_lines { + macro_rules! unknown { + () => { + panic!("Unknown command {}", describe_line(&line)) + }; + } commands.push(match line.as_slice() { [Str(text)] => Say { name: None, @@ -153,10 +158,10 @@ fn parse_file(file_path: PathBuf) -> Vec { food: food.to_owned(), politely: match tail { [Boolean(politely)] => *politely, - _ => false, + _ => unknown!(), }, }, - _ => panic!("Unknown command {}", describe_line(&line)), + _ => unknown!(), }); } commands