Working let statements

main
Elnu 2 years ago
parent 333dde95f7
commit b882ef44c0

@ -1,9 +1,13 @@
# Control testing # Control testing
$ x = "3" if True:
"Bob will be here in [x] seconds." let x = "3"
$ x = "2" "Bob will be here in [x] seconds."
"Bob will be here in [x] seconds." let x = "2"
$ x = "1" "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 will be here in [x] seconds."
"Bob" "I will not say anything, [foo]" "Bob" "I will not say anything, [foo]"
define foo = "bar" define foo = "bar"

@ -14,7 +14,7 @@ pub struct CommandBlock {
control: Option<Control>, control: Option<Control>,
elements: Vec<BlockElement>, elements: Vec<BlockElement>,
next: Option<usize>, next: Option<usize>,
pub variables: Option<Rc<RefCell<HashMap<String, Token>>>>, pub variables: Rc<RefCell<HashMap<String, Token>>>,
} }
pub struct CommandContext { pub struct CommandContext {
@ -46,7 +46,17 @@ impl CommandContext {
root.borrow_mut() root.borrow_mut()
.variables .variables
.as_ref() .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() .borrow_mut()
.insert(variable.clone(), value.clone()); .insert(variable.clone(), value.clone());
return None; return None;
@ -102,18 +112,13 @@ impl CommandBlock {
} }
pub fn get_variables(&self) -> HashMap<String, Token> { pub fn get_variables(&self) -> HashMap<String, Token> {
match &self.variables { let variables = self.variables.borrow().clone();
Some(variables) => { if let Some(parent) = &self.parent {
let variables = variables.borrow().clone(); let mut parent_variables = parent.borrow().get_variables();
if let Some(parent) = &self.parent { parent_variables.extend(variables.into_iter());
let mut parent_variables = parent.borrow().get_variables(); parent_variables
parent_variables.extend(variables.into_iter()); } else {
parent_variables variables
} else {
variables
}
}
None => HashMap::new(),
} }
} }
@ -133,7 +138,7 @@ impl Default for CommandBlock {
control: None, control: None,
elements: Vec::new(), elements: Vec::new(),
next: Some(0), 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 definitions = definitions.unwrap_or(Rc::new(RefCell::new(HashMap::new())));
let block_rc = Rc::new(RefCell::new(CommandBlock { let block_rc = Rc::new(RefCell::new(CommandBlock {
variables: if is_root { variables: if is_root {
Some(definitions.clone()) definitions.clone()
} else { } else {
None Default::default()
}, },
..Default::default() ..Default::default()
})); }));
@ -191,13 +196,7 @@ pub fn parse_block(
let subblock_rc = parse_block(pair, Some(definitions.clone())); let subblock_rc = parse_block(pair, Some(definitions.clone()));
{ {
let mut subblock = subblock_rc.borrow_mut(); let mut subblock = subblock_rc.borrow_mut();
if let Some(control) = control.as_ref() { if control.is_none() {
if control.has_variable_scope() {
// TODO: Sublock-scoped variables
subblock.variables =
Some(Rc::new(RefCell::new(HashMap::new())));
}
} else {
panic!("block should have control"); panic!("block should have control");
} }
subblock.parent = Some(block_rc.clone()); subblock.parent = Some(block_rc.clone());
@ -213,7 +212,7 @@ pub fn parse_block(
elements elements
}; };
if is_root { if is_root {
block.variables = Some(definitions); block.variables = definitions;
} }
} }
block_rc block_rc

@ -11,6 +11,7 @@ pub enum Command {
Eat { food: String, politely: bool }, Eat { food: String, politely: bool },
Define { variable: String, value: Token }, Define { variable: String, value: Token },
Assign { variable: String, value: Token }, Assign { variable: String, value: Token },
Let { variable: String, value: Token },
} }
pub fn parse_command(pair: Pair) -> Command { pub fn parse_command(pair: Pair) -> Command {
@ -47,6 +48,14 @@ pub fn parse_command(pair: Pair) -> Command {
value: value.clone(), 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 { [Keyword(keyword), Str(food), tail @ ..] if keyword.eq("eat") => Eat {
food: food.to_owned(), food: food.to_owned(),
politely: match tail { politely: match tail {

@ -10,14 +10,6 @@ pub enum Control {
If { condition: bool }, If { condition: bool },
} }
impl Control {
pub fn has_variable_scope(&self) -> bool {
match self {
_ => false,
}
}
}
pub fn parse_control(pair: Pair) -> Control { pub fn parse_control(pair: Pair) -> Control {
use Control::*; use Control::*;
use Token::*; use Token::*;

Loading…
Cancel
Save