use std::collections::{HashMap, HashSet}; use crate::ast::*; use crate::tokeniser::Keyword; use crate::tokeniser::Token; fn parse_math(tokens: &Vec) -> ValueNode { let mut prioritizing_order: HashMap> = HashMap::new(); prioritizing_order.insert(0, HashSet::from([Token::Plus, Token::Minus])); let mut ordered_binops: Vec = Vec::new(); let mut ordered_binops_indexes: Vec = Vec::new(); if tokens.len() == 1 { return match &tokens[0] { Token::Number(n) => ValueNode::Literal(Literal::Int(n.parse::().unwrap())), Token::Identifier(identifier) => ValueNode::Variable(identifier.to_owned()), _ => todo!(), }; } for j in prioritizing_order.keys() { let mut i = 0; let current_order_binops = prioritizing_order.get(j).unwrap(); while i < tokens.len() { for binop in current_order_binops { if &tokens[i] == binop { ordered_binops.push(binop.to_owned()); ordered_binops_indexes.push(i); } } i += 1; } } let binop = ordered_binops.pop().unwrap(); let binop_index = ordered_binops_indexes.pop().unwrap(); let mut a: Vec = Vec::new(); let mut b: Vec = Vec::new(); let mut i = 0; while i < tokens.len() { if i < binop_index { a.push(tokens[i].clone()); } if i > binop_index { b.push(tokens[i].clone()); } i += 1; } return match binop { Token::Plus => ValueNode::Operator(Operator::Add( Box::new(parse_math(&a)), Box::new(parse_math(&b)), )), Token::Minus => ValueNode::Operator(Operator::Sub( Box::new(parse_math(&a)), Box::new(parse_math(&b)), )), _ => todo!(), }; } fn parse_statements(tokens: &Vec, starting_i: usize) -> (Vec, usize) { let mut i = starting_i; let mut statements = Vec::new(); while i < tokens.len() { statements.push(match &tokens[i] { Token::OpenSquiglyBracket => { let (statements, added_to_i) = parse_statements(tokens, i + 1); i = added_to_i + 1; Statement::Scope(statements) } Token::Keyword(Keyword::Let) => { i += 1; let name = match tokens[i].clone() { Token::Identifier(identifier) => identifier, _ => todo!(), }; i += 1; match tokens[i].clone() { Token::Equals => {} _ => todo!(), }; i += 1; let mut declaration_tokens: Vec = Vec::new(); while tokens[i] != Token::Semi { declaration_tokens.push(tokens[i].clone()); i += 1; } Statement::VariableDeclaration(name, parse_math(&declaration_tokens)) } Token::Keyword(Keyword::Assign) => { i += 1; let name = match tokens[i].clone() { Token::Identifier(identifier) => identifier, _ => todo!(), }; i += 1; match tokens[i].clone() { Token::Equals => {} _ => todo!(), }; i += 1; let mut declaration_tokens: Vec = Vec::new(); while tokens[i] != Token::Semi { declaration_tokens.push(tokens[i].clone()); i += 1; } Statement::VariableAssignment(name, parse_math(&declaration_tokens)) } Token::Identifier(identifier) => { i += 1; let mut declaration_tokens: Vec> = Vec::new(); i += 1; while tokens[i] != Token::CloseParanthesis { let mut argument_tokens: Vec = Vec::new(); while tokens[i] != Token::Comma { argument_tokens.push(tokens[i].clone()); i += 1; } declaration_tokens.push(argument_tokens); i += 1; } i += 1; let mut arguments: Vec = Vec::new(); for token_vec in &declaration_tokens { if token_vec == &Vec::new() { continue; } arguments.push(parse_math(token_vec)); } Statement::FunctionCall(identifier.to_owned(), arguments) } Token::CloseSquiglyBracket => { return (statements, i); } Token::Semi => { i += 1; continue; } _other => { dbg!(_other); todo!() } }); } (statements, i) } pub fn ast(tokens: Vec) -> Vec { let mut functions: Vec = Vec::new(); let mut i = 0; while i < tokens.len() { match &tokens[i] { Token::Keyword(Keyword::Function) => { let (statements, added_to_i) = parse_statements(&tokens, i + 4); let statements = vec![Statement::Scope(statements)]; let function_name = match &tokens[i + 1] { Token::Identifier(identifier) => identifier.to_owned(), _ => todo!(), }; let n_args = match &tokens[i + 2] { Token::Number(num) => num.parse::().unwrap(), _ => todo!(), }; i += added_to_i; functions.push(Function::new(function_name, n_args, statements)); } _other => { dbg!(&functions); dbg!(i); dbg!(_other); todo!(); } }; i += 1; } functions }