Working let statements

main
Elnu 1 year ago
parent 333dde95f7
commit b882ef44c0

@ -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"

@ -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,9 +112,7 @@ impl CommandBlock {
}
pub fn get_variables(&self) -> HashMap<String, Token> {
match &self.variables {
Some(variables) => {
let variables = variables.borrow().clone();
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());
@ -113,9 +121,6 @@ impl CommandBlock {
variables
}
}
None => HashMap::new(),
}
}
pub fn get_root(&self, self_rc: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>> {
if let Some(parent) = &self.parent {
@ -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

@ -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 {

@ -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::*;

Loading…
Cancel
Save