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
|
# 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,9 +112,7 @@ 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) => {
|
|
||||||
let variables = variables.borrow().clone();
|
|
||||||
if let Some(parent) = &self.parent {
|
if let Some(parent) = &self.parent {
|
||||||
let mut parent_variables = parent.borrow().get_variables();
|
let mut parent_variables = parent.borrow().get_variables();
|
||||||
parent_variables.extend(variables.into_iter());
|
parent_variables.extend(variables.into_iter());
|
||||||
|
@ -113,9 +121,6 @@ impl CommandBlock {
|
||||||
variables
|
variables
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_root(&self, self_rc: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>> {
|
pub fn get_root(&self, self_rc: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>> {
|
||||||
if let Some(parent) = &self.parent {
|
if let Some(parent) = &self.parent {
|
||||||
|
@ -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…
Add table
Reference in a new issue