|
|
@ -1,7 +1,11 @@
|
|
|
|
use std::{rc::Rc, cell::RefCell, collections::HashMap};
|
|
|
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|
|
|
|
|
|
|
|
|
|
|
use super::{command::{Command, parse_command}, Pair, token::Token, Rule, control::{parse_control, Control}};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use super::{
|
|
|
|
|
|
|
|
command::{parse_command, Command},
|
|
|
|
|
|
|
|
control::{parse_control, Control},
|
|
|
|
|
|
|
|
token::Token,
|
|
|
|
|
|
|
|
Pair, Rule,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct CommandBlock {
|
|
|
|
pub struct CommandBlock {
|
|
|
@ -29,28 +33,22 @@ impl CommandBlock {
|
|
|
|
result = Some(command.clone());
|
|
|
|
result = Some(command.clone());
|
|
|
|
next += 1;
|
|
|
|
next += 1;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
},
|
|
|
|
|
|
|
|
BlockElement::Block(block) => {
|
|
|
|
|
|
|
|
match block.borrow_mut().next() {
|
|
|
|
|
|
|
|
Some(command) => {
|
|
|
|
|
|
|
|
result = Some(command.clone());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
None => {
|
|
|
|
|
|
|
|
next += 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BlockElement::Block(block) => match block.borrow_mut().next() {
|
|
|
|
|
|
|
|
Some(command) => {
|
|
|
|
|
|
|
|
result = Some(command.clone());
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
None => {
|
|
|
|
|
|
|
|
next += 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.next = if count >= next {
|
|
|
|
self.next = if count >= next { Some(next) } else { None };
|
|
|
|
Some(next)
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
result
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn evaluate_control(&self) -> bool {
|
|
|
|
fn evaluate_control(&self) -> bool {
|
|
|
|
use Control::*;
|
|
|
|
use Control::*;
|
|
|
|
self.control.as_ref().map_or(true, |control| match control {
|
|
|
|
self.control.as_ref().map_or(true, |control| match control {
|
|
|
@ -69,7 +67,7 @@ impl CommandBlock {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
variables
|
|
|
|
variables
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
None => HashMap::new(),
|
|
|
|
None => HashMap::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -93,12 +91,19 @@ enum BlockElement {
|
|
|
|
Block(Rc<RefCell<CommandBlock>>),
|
|
|
|
Block(Rc<RefCell<CommandBlock>>),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn parse_block(pair: Pair, definitions: Option<Rc<RefCell<HashMap<String, Token>>>>) -> Rc<RefCell<CommandBlock>> {
|
|
|
|
pub fn parse_block(
|
|
|
|
|
|
|
|
pair: Pair,
|
|
|
|
|
|
|
|
definitions: Option<Rc<RefCell<HashMap<String, Token>>>>,
|
|
|
|
|
|
|
|
) -> Rc<RefCell<CommandBlock>> {
|
|
|
|
//let variables: HashMap<String, Token> = HashMap::new();
|
|
|
|
//let variables: HashMap<String, Token> = HashMap::new();
|
|
|
|
let is_root = definitions.is_none();
|
|
|
|
let is_root = definitions.is_none();
|
|
|
|
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 { Some(definitions.clone()) } else { None },
|
|
|
|
variables: if is_root {
|
|
|
|
|
|
|
|
Some(definitions.clone())
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
},
|
|
|
|
..Default::default()
|
|
|
|
..Default::default()
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -114,7 +119,7 @@ pub fn parse_block(pair: Pair, definitions: Option<Rc<RefCell<HashMap<String, To
|
|
|
|
}
|
|
|
|
}
|
|
|
|
control = Some(parse_control(pair));
|
|
|
|
control = Some(parse_control(pair));
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
},
|
|
|
|
}
|
|
|
|
Rule::Line => BlockElement::Command(match parse_command(pair) {
|
|
|
|
Rule::Line => BlockElement::Command(match parse_command(pair) {
|
|
|
|
Command::Define { variable, value } => {
|
|
|
|
Command::Define { variable, value } => {
|
|
|
|
let mut value = value;
|
|
|
|
let mut value = value;
|
|
|
@ -137,7 +142,8 @@ pub fn parse_block(pair: Pair, definitions: Option<Rc<RefCell<HashMap<String, To
|
|
|
|
if let Some(control) = control.as_ref() {
|
|
|
|
if let Some(control) = control.as_ref() {
|
|
|
|
if control.has_variable_scope() {
|
|
|
|
if control.has_variable_scope() {
|
|
|
|
// TODO: Sublock-scoped variables
|
|
|
|
// TODO: Sublock-scoped variables
|
|
|
|
subblock.variables = Some(Rc::new(RefCell::new(HashMap::new())));
|
|
|
|
subblock.variables =
|
|
|
|
|
|
|
|
Some(Rc::new(RefCell::new(HashMap::new())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
panic!("block should have control");
|
|
|
|
panic!("block should have control");
|
|
|
@ -159,4 +165,4 @@ pub fn parse_block(pair: Pair, definitions: Option<Rc<RefCell<HashMap<String, To
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
block_rc
|
|
|
|
block_rc
|
|
|
|
}
|
|
|
|
}
|
|
|
|