Restructure assignment commands into one command

main
Elnu 2 years ago
parent 9686884c62
commit c72bd94291

@ -2,7 +2,7 @@ use debug_cell::RefCell;
use std::{collections::HashMap, rc::Rc}; use std::{collections::HashMap, rc::Rc};
use super::{ use super::{
command::{parse_command, Command}, command::{parse_command, Command, AssignType},
control::{parse_control, Control}, control::{parse_control, Control},
event::Event, event::Event,
token::Token, token::Token,
@ -25,41 +25,50 @@ pub struct CommandContext {
impl CommandContext { impl CommandContext {
pub fn execute(&self) -> Option<Event> { pub fn execute(&self) -> Option<Event> {
use Command::*; use Command::*;
use AssignType::*;
Some( Some(
match &self.command { match &self.command {
Say { name, text } => Event::Say { Say { name, text } => Event::Say {
name: name.clone(), name: name.clone(),
text: text.clone(), text: text.clone(),
}, },
Define { .. } => panic!("define command should not be executed at runtime!"), Command::Assign { assign_type, variable, value } => match assign_type {
Assign { variable, value } => { Define => panic!("define command should not be executed at runtime!"),
if let Token::Keyword(_) = value { GlobalAssign => {
todo!("assignment variable interpolation isn't implemented"); 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 = self.context.borrow().get_root(&self.context);
let root = if Rc::ptr_eq(&self.context, &root) { // Don't want to re-borrow if root is self
&self.context let root = if Rc::ptr_eq(&self.context, &root) {
} else { &self.context
&root } else {
}; &root
root.borrow_mut() };
.variables root.borrow_mut()
.as_ref() .variables
.borrow_mut() .as_ref()
.insert(variable.clone(), value.clone()); .borrow_mut()
return None; .insert(variable.clone(), value.clone());
}, return None;
Let { variable, value } => { },
if let Token::Keyword(_) = value { Let => {
todo!("assignment variable interpolation isn't implemented"); if let Token::Keyword(_) = value {
} todo!("assignment variable interpolation isn't implemented");
self.context }
.borrow() self.context
.variables .borrow()
.borrow_mut() .variables
.insert(variable.clone(), value.clone()); .borrow_mut()
return None; .insert(variable.clone(), value.clone());
return None;
},
Assign => {
if let Token::Keyword(_) = value {
todo!("assignment variable interpolation isn't implemented");
}
todo!("local variable assignment isn't implemented")
},
} }
Eat { .. } => return None, Eat { .. } => return None,
} }
@ -178,7 +187,7 @@ pub fn parse_block(
continue; continue;
} }
Rule::Line => BlockElement::Command(match parse_command(pair) { Rule::Line => BlockElement::Command(match parse_command(pair) {
Command::Define { variable, value } => { Command::Assign { variable, value, assign_type: AssignType::Define } => {
let mut value = value; let mut value = value;
if let Token::Keyword(keyword) = value { if let Token::Keyword(keyword) = value {
value = definitions value = definitions

@ -1,3 +1,5 @@
use std::str::FromStr;
use super::{ use super::{
token::Token, token::Token,
utils::{describe_line, parse_line}, utils::{describe_line, parse_line},
@ -7,11 +9,41 @@ use super::{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(dead_code)] #[allow(dead_code)]
pub enum Command { pub enum Command {
Say { name: Option<String>, text: String }, Say {
Eat { food: String, politely: bool }, name: Option<String>,
Define { variable: String, value: Token }, text: String,
Assign { variable: String, value: Token }, },
Let { variable: String, value: Token }, Eat {
food: String,
politely: bool,
},
Assign {
assign_type: AssignType,
variable: String,
value: Token,
},
}
#[derive(Debug, Clone)]
pub enum AssignType {
Define,
GlobalAssign,
Let,
Assign,
}
impl FromStr for AssignType {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
use AssignType::*;
Ok(match s {
"define" => Define,
"$" => GlobalAssign,
"let" => Let,
_ => return Err(()),
})
}
} }
pub fn parse_command(pair: Pair) -> Command { pub fn parse_command(pair: Pair) -> Command {
@ -32,26 +64,15 @@ pub fn parse_command(pair: Pair) -> Command {
name: Some(name.clone()), name: Some(name.clone()),
text: text.clone(), text: text.clone(),
}, },
// https://github.com/rust-lang/rust/issues/51114
[Keyword(keyword), Keyword(variable), Keyword(equals), value] [Keyword(keyword), Keyword(variable), Keyword(equals), value]
if keyword.eq("define") && equals.eq("=") => if equals.eq("=") =>
{
Define {
variable: variable.clone(),
value: value.clone(),
}
}
[Keyword(keyword), Keyword(variable), Keyword(equals), value]
if keyword.eq("$") && equals.eq("=") =>
{ {
Assign { Assign {
variable: variable.clone(), assign_type: match keyword.parse() {
value: value.clone(), Ok(assign_type) => assign_type,
} Err(_) => unknown!(),
} },
[Keyword(keyword), Keyword(variable), Keyword(equals), value]
if keyword.eq("let") && equals.eq("=") =>
{
Let {
variable: variable.clone(), variable: variable.clone(),
value: value.clone(), value: value.clone(),
} }

@ -78,6 +78,6 @@ pub fn parse_token(pair: Pair) -> Token {
}), }),
Rule::Number => Token::Number(pair.as_str().parse().unwrap()), Rule::Number => Token::Number(pair.as_str().parse().unwrap()),
Rule::Keyword => Token::Keyword(pair.as_str().to_owned()), Rule::Keyword => Token::Keyword(pair.as_str().to_owned()),
__ => unreachable!(), _ => unreachable!(),
} }
} }

Loading…
Cancel
Save