Parsing partially done

This commit is contained in:
Apache 2024-06-12 02:45:33 -05:00
parent 32ba3f38c3
commit 102c35d654
Signed by: apache
GPG key ID: 6B10F3EAF14F4C77
4 changed files with 67 additions and 11 deletions

View file

@ -38,7 +38,7 @@ impl LispState {
todo!(); todo!();
} }
}, },
OpCode::Eval(ins) => { OpCode::Exp(ins) => {
self.execute(ins); self.execute(ins);
} }
} }

View file

@ -6,7 +6,8 @@ pub enum LispValue {
Nil, Nil,
String(String), String(String),
LispFunction(String, Vec<OpCode>), LispFunction(String, Vec<OpCode>),
RustFunction(String, fn(Vec<LispValue>) -> LispValue) RustFunction(String, fn(Vec<LispValue>) -> LispValue),
Exp(OpCode)
} }
impl fmt::Display for LispValue { impl fmt::Display for LispValue {
@ -15,7 +16,8 @@ impl fmt::Display for LispValue {
LispValue::Nil => write!(f, "nil"), LispValue::Nil => write!(f, "nil"),
LispValue::String(str) => write!(f, "{}", str), LispValue::String(str) => write!(f, "{}", str),
LispValue::LispFunction(name, _) => write!(f, "<'{}': Lisp Function>", name), 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<String> for LispValue {
pub enum OpCode { pub enum OpCode {
Call(String, Vec<LispValue>), Call(String, Vec<LispValue>),
Eval(Vec<OpCode>) Exp(Vec<OpCode>)
} }
// TODO: Handle failure
fn read_exp(open_paren_idx: usize, tokens: &Vec<Token>) -> Option<(Vec<Token>, usize)> /* Option<tokens, close_paren_idx> */ {
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<Token>) -> Vec<OpCode> {
todo!()
}
pub fn parse(tokens: Vec<Token>) -> Vec<OpCode> { pub fn parse(tokens: Vec<Token>) -> Vec<OpCode> {
let mut opcodes = Vec::new(); let mut opcodes = Vec::new();
// TODO: let mut current_depth = 0;
opcodes.push(OpCode::Call("print".to_string(), vec![ let mut seeking = false;
LispValue::from("Hello, World!")
])); 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 opcodes
} }

View file

@ -1,4 +1,10 @@
; This is a comment ; This is a comment
(print "Hello, World") ; OpenParen, Identifier, String, CloseParen (print "Hello, World") ; OpCode::Call("print", {"Hello, World"})
; (print (add 1 2)) ; OpenParen, Identifier, OpenParen, Identifier, Int, Int, CloseParen, CloseParen
(print (add 1 2))
; OpCode::Call("print", {
; OpCode::Exp({
; OpCode::Call("add", 1, 2)
; })
; })

View file

@ -1,6 +1,6 @@
use std::fmt; use std::fmt;
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum Token { pub enum Token {
OpenParen, OpenParen,
CloseParen, CloseParen,