diff --git a/demo/demo.rpy b/demo/demo.rpy index 59e0d74..d22c671 100644 --- a/demo/demo.rpy +++ b/demo/demo.rpy @@ -1,9 +1,13 @@ # Control testing -$ x = "3" -"Bob will be here in [x] seconds." -$ x = "2" -"Bob will be here in [x] seconds." -$ x = "1" +if True: + let x = "3" + "Bob will be here in [x] seconds." + let x = "2" + "Bob will be here in [x] seconds." + if True: + let x = "213" + let x = "1" + "Bob will be here in [x] seconds." "Bob will be here in [x] seconds." "Bob" "I will not say anything, [foo]" define foo = "bar" diff --git a/renrs/src/parser/block.rs b/renrs/src/parser/block.rs index f79ffd4..3ff889d 100644 --- a/renrs/src/parser/block.rs +++ b/renrs/src/parser/block.rs @@ -14,7 +14,7 @@ pub struct CommandBlock { control: Option, elements: Vec, next: Option, - pub variables: Option>>>, + pub variables: Rc>>, } pub struct CommandContext { @@ -46,7 +46,17 @@ impl CommandContext { root.borrow_mut() .variables .as_ref() - .unwrap() + .borrow_mut() + .insert(variable.clone(), value.clone()); + return None; + }, + Let { variable, value } => { + if let Token::Keyword(_) = value { + todo!("assignment variable interpolation isn't implemented"); + } + self.context + .borrow() + .variables .borrow_mut() .insert(variable.clone(), value.clone()); return None; @@ -102,18 +112,13 @@ impl CommandBlock { } pub fn get_variables(&self) -> HashMap { - match &self.variables { - Some(variables) => { - let variables = variables.borrow().clone(); - if let Some(parent) = &self.parent { - let mut parent_variables = parent.borrow().get_variables(); - parent_variables.extend(variables.into_iter()); - parent_variables - } else { - variables - } - } - None => HashMap::new(), + let variables = self.variables.borrow().clone(); + if let Some(parent) = &self.parent { + let mut parent_variables = parent.borrow().get_variables(); + parent_variables.extend(variables.into_iter()); + parent_variables + } else { + variables } } @@ -133,7 +138,7 @@ impl Default for CommandBlock { control: None, elements: Vec::new(), next: Some(0), - variables: None, + variables: Rc::new(RefCell::new(HashMap::new())), } } } @@ -152,9 +157,9 @@ pub fn parse_block( let definitions = definitions.unwrap_or(Rc::new(RefCell::new(HashMap::new()))); let block_rc = Rc::new(RefCell::new(CommandBlock { variables: if is_root { - Some(definitions.clone()) + definitions.clone() } else { - None + Default::default() }, ..Default::default() })); @@ -191,13 +196,7 @@ pub fn parse_block( let subblock_rc = parse_block(pair, Some(definitions.clone())); { let mut subblock = subblock_rc.borrow_mut(); - if let Some(control) = control.as_ref() { - if control.has_variable_scope() { - // TODO: Sublock-scoped variables - subblock.variables = - Some(Rc::new(RefCell::new(HashMap::new()))); - } - } else { + if control.is_none() { panic!("block should have control"); } subblock.parent = Some(block_rc.clone()); @@ -213,7 +212,7 @@ pub fn parse_block( elements }; if is_root { - block.variables = Some(definitions); + block.variables = definitions; } } block_rc diff --git a/renrs/src/parser/command.rs b/renrs/src/parser/command.rs index 16af242..4026d45 100644 --- a/renrs/src/parser/command.rs +++ b/renrs/src/parser/command.rs @@ -11,6 +11,7 @@ pub enum Command { Eat { food: String, politely: bool }, Define { variable: String, value: Token }, Assign { variable: String, value: Token }, + Let { variable: String, value: Token }, } pub fn parse_command(pair: Pair) -> Command { @@ -47,6 +48,14 @@ pub fn parse_command(pair: Pair) -> Command { value: value.clone(), } } + [Keyword(keyword), Keyword(variable), Keyword(equals), value] + if keyword.eq("let") && equals.eq("=") => + { + Let { + variable: variable.clone(), + value: value.clone(), + } + } [Keyword(keyword), Str(food), tail @ ..] if keyword.eq("eat") => Eat { food: food.to_owned(), politely: match tail { diff --git a/renrs/src/parser/control.rs b/renrs/src/parser/control.rs index deccae2..81811d2 100644 --- a/renrs/src/parser/control.rs +++ b/renrs/src/parser/control.rs @@ -10,14 +10,6 @@ pub enum Control { If { condition: bool }, } -impl Control { - pub fn has_variable_scope(&self) -> bool { - match self { - _ => false, - } - } -} - pub fn parse_control(pair: Pair) -> Control { use Control::*; use Token::*;