|
|
|
@ -37,62 +37,65 @@ impl CommandContext {
|
|
|
|
|
assign_type,
|
|
|
|
|
variable,
|
|
|
|
|
value,
|
|
|
|
|
} => match assign_type {
|
|
|
|
|
Define => panic!("define command should not be executed at runtime!"),
|
|
|
|
|
GlobalAssign => {
|
|
|
|
|
if let Token::Keyword(_) = value {
|
|
|
|
|
todo!("assignment variable interpolation isn't implemented");
|
|
|
|
|
}
|
|
|
|
|
let root = self.context.borrow().get_root(&self.context);
|
|
|
|
|
// Don't want to re-borrow if root is self
|
|
|
|
|
let root = if Rc::ptr_eq(&self.context, &root) {
|
|
|
|
|
&self.context
|
|
|
|
|
} else {
|
|
|
|
|
&root
|
|
|
|
|
};
|
|
|
|
|
root.borrow_mut()
|
|
|
|
|
.variables
|
|
|
|
|
.as_ref()
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.insert(variable.clone(), value.clone());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
Let => {
|
|
|
|
|
if let Token::Keyword(_) = value {
|
|
|
|
|
todo!("assignment variable interpolation isn't implemented");
|
|
|
|
|
}
|
|
|
|
|
} => {
|
|
|
|
|
let value = if let Token::Keyword(keyword) = value {
|
|
|
|
|
self.context
|
|
|
|
|
.borrow()
|
|
|
|
|
.variables
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.insert(variable.clone(), value.clone());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
Assign => {
|
|
|
|
|
if let Token::Keyword(_) = value {
|
|
|
|
|
todo!("assignment variable interpolation isn't implemented");
|
|
|
|
|
.get_variables()
|
|
|
|
|
.get(keyword)
|
|
|
|
|
.unwrap_or_else(|| panic!("undefined variable `{keyword}`"))
|
|
|
|
|
.clone()
|
|
|
|
|
} else {
|
|
|
|
|
value.clone()
|
|
|
|
|
};
|
|
|
|
|
match assign_type {
|
|
|
|
|
Define => panic!("define command should not be executed at runtime!"),
|
|
|
|
|
GlobalAssign => {
|
|
|
|
|
let root = self.context.borrow().get_root(&self.context);
|
|
|
|
|
// Don't want to re-borrow if root is self
|
|
|
|
|
let root = if Rc::ptr_eq(&self.context, &root) {
|
|
|
|
|
&self.context
|
|
|
|
|
} else {
|
|
|
|
|
&root
|
|
|
|
|
};
|
|
|
|
|
root.borrow_mut()
|
|
|
|
|
.variables
|
|
|
|
|
.as_ref()
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.insert(variable.clone(), value.clone());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
let mut block_option = Some(self.context.clone());
|
|
|
|
|
let mut modified = false;
|
|
|
|
|
while let Some(block) = block_option {
|
|
|
|
|
let block = block.borrow();
|
|
|
|
|
block
|
|
|
|
|
Let => {
|
|
|
|
|
self.context
|
|
|
|
|
.borrow()
|
|
|
|
|
.variables
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.entry(variable.clone())
|
|
|
|
|
.and_modify(|e| {
|
|
|
|
|
*e = value.clone();
|
|
|
|
|
modified = true;
|
|
|
|
|
});
|
|
|
|
|
if modified {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
block_option = block.parent.clone();
|
|
|
|
|
.insert(variable.clone(), value.clone());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
if !modified {
|
|
|
|
|
panic!("undefined variable `{variable}`");
|
|
|
|
|
Assign => {
|
|
|
|
|
let mut block_option = Some(self.context.clone());
|
|
|
|
|
let mut modified = false;
|
|
|
|
|
while let Some(block) = block_option {
|
|
|
|
|
let block = block.borrow();
|
|
|
|
|
block
|
|
|
|
|
.variables
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.entry(variable.clone())
|
|
|
|
|
.and_modify(|e| {
|
|
|
|
|
*e = value.clone();
|
|
|
|
|
modified = true;
|
|
|
|
|
});
|
|
|
|
|
if modified {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
block_option = block.parent.clone();
|
|
|
|
|
}
|
|
|
|
|
if !modified {
|
|
|
|
|
panic!("undefined variable `{variable}`");
|
|
|
|
|
}
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
Eat { .. } => return None,
|
|
|
|
|