use std::fmt; use crate::Token; pub enum LispValue { Nil, String(String), LispFunction(String, Vec), RustFunction(String, fn(Vec) -> LispValue), Exp(OpCode) } impl fmt::Display for LispValue { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { LispValue::Nil => write!(f, "nil"), LispValue::String(str) => write!(f, "{}", str), LispValue::LispFunction(name, _) => write!(f, "<'{}': Lisp Function>", name), LispValue::RustFunction(name, _) => write!(f, "<'{}': Rust Function>", name), _ => todo!() } } } impl From<&str> for LispValue { fn from(value: &str) -> Self { LispValue::String(value.to_string()) } } impl From for LispValue { fn from(value: String) -> Self { LispValue::String(value) } } pub enum OpCode { Call(String, Vec), Exp(Vec) } // TODO: Handle failure fn read_exp(open_paren_idx: usize, tokens: &Vec) -> Option<(Vec, usize)> /* Option */ { let mut tkns = Vec::new(); let mut depth = 0; for i in open_paren_idx..tokens.len() - 1 { match &tokens[i] { Token::OpenParen => { if depth != 0 { tkns.push(Token::OpenParen); } depth += 1; } Token::CloseParen => { depth -= 1; if depth == 0 { return Some((tkns, i)); } } token => { tkns.push(token.clone()); } } } None } fn parse_exp(tokens: Vec) -> Vec { todo!() } pub fn parse(tokens: Vec) -> Vec { let mut opcodes = Vec::new(); let mut current_depth = 0; let mut seeking = false; let mut i = 0; while i < tokens.len() { match &tokens[i] { Token::OpenParen => { let (tkns, close_paren_idx) = read_exp(i, &tokens).unwrap(); opcodes.push(OpCode::Exp(parse_exp(tkns))); i = close_paren_idx; } tkn => { panic!("Unexpected token {:?}", tkn); } } i += 1; } // opcodes.push(OpCode::Call("print".to_string(), vec![ // LispValue::from("Hello, World!") // ])); opcodes }