diff --git a/src/terminal.rs b/src/terminal.rs index d0e3fad..1bc56e4 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -3,6 +3,7 @@ use bevy::prelude::*; #[derive(Component)] pub struct TerminalSystem; +#[derive(Clone)] enum Token { Identifier(String), Integer(i32), @@ -12,10 +13,22 @@ enum Token { RParen } +enum CallArg { + Identifier(String), + Integer(i32) +} + +struct CallNode { + target: Option, + method: String, + args: Vec +} + impl TerminalSystem { pub fn parse(&mut self, input: String) { let tokens = self.lex(input); - self.parse_tokens(tokens); + let nodes = self.parse_tokens(tokens); + self.interpret(nodes); } fn lex(&mut self, input: String) -> Vec { @@ -88,7 +101,152 @@ impl TerminalSystem { tokens } - fn parse_tokens(&mut self, tokens: Vec) { - + fn parse_tokens(&mut self, tokens: Vec) -> Vec { + let mut nodes = Vec::new(); + let mut iter = 0; + + let consume = |tokens: &Vec, mut iter: &mut usize, expected_type: Option| -> Token { + let token = { + if *iter < tokens.len() { + Some(&tokens[*iter]) + } else { + None + } + }; + + if let Some(exp_type) = expected_type { + if let Some(Token::Identifier(_)) = token { + if let Token::Identifier(_) = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else if let Some(Token::Integer(_)) = token { + if let Token::Integer(_) = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else if let Some(Token::LParen) = token { + if let Token::LParen = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else if let Some(Token::Period) = token { + if let Token::Period = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else if let Some(Token::RParen) = token { + if let Token::RParen = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else if let Some(Token::Semicolon) = token { + if let Token::Semicolon = exp_type { + (*iter) += 1; + (*token.unwrap()).clone() + } else { + panic!("Expected type not found"); + } + } else { + panic!("Not sure why this would happen"); + } + } else { + (*iter) += 1; + (*token.unwrap()).clone() + } + }; + + let parse_call = |nodes: &mut Vec, tokens: &Vec, mut iter: &mut usize| { + let first_id = consume(tokens, iter, Some(Token::Identifier(String::new()))); + let mut target: Option = None; + let mut method = first_id.clone(); + + if matches!(tokens[*iter], Token::Period) { + consume(tokens, iter, Some(Token::Period)); + target = Some(first_id.clone()); + method = consume(tokens, iter, Some(Token::Identifier(String::new()))) + } + + consume(tokens, iter, Some(Token::LParen)); + let mut args: Vec = Vec::new(); + let mut current_token = { + if *iter < tokens.len() { + Some(&tokens[*iter]) + } else { + None + } + }; + + while matches!(current_token, Some(_)) && !matches!(current_token, Some(Token::RParen)) { + let arg_token = consume(tokens, iter, None); + + match arg_token { + Token::Integer(val) => { + args.push(CallArg::Integer(val)); + }, + _ => panic!("invalid") + } + + current_token = { + if *iter < tokens.len() { + Some(&tokens[*iter]) + } else { + None + } + }; + } + + consume(tokens, iter, Some(Token::RParen)); + + nodes.push(CallNode{ + target: { + match target { + Some(Token::Identifier(id)) => { + Some(id.to_owned()) + }, + Some(_) => panic!("invalid"), + None => None + } + }, + method: match method { + Token::Identifier(id) => { + id.to_owned() + }, + _ => panic!("invalid") + }, + args + }); + }; + + while iter < tokens.len() { + parse_call(&mut nodes, &tokens, &mut iter); + let current_token = { + if iter < tokens.len() { + Some(&tokens[iter]) + } else { + None + } + }; + + if matches!(current_token, Some(Token::Semicolon)) { + consume(&tokens, &mut iter, Some(Token::Semicolon)); + } + } + + nodes + } + + fn interpret(&mut self, nodes: Vec) { + } } \ No newline at end of file