generated from ElnuDev/rust-project
Working let statements
This commit is contained in:
parent
333dde95f7
commit
b882ef44c0
4 changed files with 42 additions and 38 deletions
|
@ -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,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
|
||||
|
|
|
@ -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…
Add table
Reference in a new issue