From 102c35d6549319ac035fc5af653015291dfc8007adb11d5df2549aba13874645 Mon Sep 17 00:00:00 2001 From: Apache Date: Wed, 12 Jun 2024 02:45:33 -0500 Subject: [PATCH] Parsing partially done --- src/executor.rs | 2 +- src/parser.rs | 64 ++++++++++++++++++++++++++++++++++++++++++------ src/test.lisp | 10 ++++++-- src/tokenizer.rs | 2 +- 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/executor.rs b/src/executor.rs index a4ffee9..1ac0451 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -38,7 +38,7 @@ impl LispState { todo!(); } }, - OpCode::Eval(ins) => { + OpCode::Exp(ins) => { self.execute(ins); } } diff --git a/src/parser.rs b/src/parser.rs index f790f16..54b3487 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -6,7 +6,8 @@ pub enum LispValue { Nil, String(String), LispFunction(String, Vec), - RustFunction(String, fn(Vec) -> LispValue) + RustFunction(String, fn(Vec) -> LispValue), + Exp(OpCode) } impl fmt::Display for LispValue { @@ -15,7 +16,8 @@ impl fmt::Display for LispValue { 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) + LispValue::RustFunction(name, _) => write!(f, "<'{}': Rust Function>", name), + _ => todo!() } } } @@ -34,18 +36,66 @@ impl From for LispValue { pub enum OpCode { Call(String, Vec), - Eval(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(); - // TODO: - opcodes.push(OpCode::Call("print".to_string(), vec![ - LispValue::from("Hello, World!") - ])); + 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 } \ No newline at end of file diff --git a/src/test.lisp b/src/test.lisp index a9b3370..ace40ce 100644 --- a/src/test.lisp +++ b/src/test.lisp @@ -1,4 +1,10 @@ ; This is a comment -(print "Hello, World") ; OpenParen, Identifier, String, CloseParen -; (print (add 1 2)) ; OpenParen, Identifier, OpenParen, Identifier, Int, Int, CloseParen, CloseParen \ No newline at end of file +(print "Hello, World") ; OpCode::Call("print", {"Hello, World"}) + +(print (add 1 2)) +; OpCode::Call("print", { +; OpCode::Exp({ +; OpCode::Call("add", 1, 2) +; }) +; }) \ No newline at end of file diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 605f09a..dfe80b7 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1,6 +1,6 @@ use std::fmt; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum Token { OpenParen, CloseParen,