|
|
|
@ -14,7 +14,7 @@ pub struct CommandBlock {
|
|
|
|
|
control: Option<Control>,
|
|
|
|
|
elements: Vec<BlockElement>,
|
|
|
|
|
next: Option<usize>,
|
|
|
|
|
pub variables: Option<Rc<RefCell<HashMap<String, Token>>>>,
|
|
|
|
|
pub variables: Rc<RefCell<HashMap<String, Token>>>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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<String, Token> {
|
|
|
|
|
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
|
|
|
|
|