From bf3e784b423ac948930b8e611f955af8914220dadeb9ce9b4b4ad34780df6fd8 Mon Sep 17 00:00:00 2001 From: Apache Date: Thu, 20 Jun 2024 16:55:21 -0500 Subject: [PATCH] Functionality --- src/executor.rs | 94 ++++++++++++++++++++++++++++++------------------ src/main.rs | 1 + src/parser.rs | 14 ++++---- src/test.lisp | 2 +- src/tokenizer.rs | 2 ++ 5 files changed, 70 insertions(+), 43 deletions(-) diff --git a/src/executor.rs b/src/executor.rs index fa09d70..bc64881 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, fmt}; -use crate::{OpCode, PreLispValue}; +use crate::PreLispValue; pub struct LispState { table: HashMap, @@ -16,8 +16,8 @@ pub enum LispValue { String(String), Integer(i32), Float(f32), - List(Vec), - LispFunction(String, Vec), + List(Vec, bool), + LispFunction(String, Vec), RustFunction(String, fn(Vec) -> Vec), } @@ -329,47 +329,73 @@ impl LispState { } } - fn do_call(&self, opcode: &OpCode) -> Vec { - if let OpCode::Call(func, args) = opcode { - let f = self.table.get(func).unwrap(); + fn handle_prevalues(&self, input: Vec) -> Vec { + let mut out = Vec::new(); - let mut args: Vec = args.clone(); - for i in 0..args.len() { - let arg = &args[i]; - if let LispValue::Eval(OpCode::Exp(opcodes)) = arg { - if opcodes.len() < 1 { - args[i] = LispValue::Nil; - continue; - } + for v in input { + out.push(match v { + PreLispValue::Nil => LispValue::Nil, + PreLispValue::String(str) => LispValue::String(str), + PreLispValue::Integer(num) => LispValue::Integer(num), + PreLispValue::Float(num) => LispValue::Float(num), + PreLispValue::List(list, quoted) => { + LispValue::List(Self::handle_prevalues(self, list), quoted) + }, + PreLispValue::LispFunction(name, instructions) => { + LispValue::LispFunction(name, Self::handle_prevalues(self, instructions)) + }, + PreLispValue::Var(name) => { + self.table.get(&name).unwrap_or(&LispValue::Nil).to_owned() + } + }) + } - let call_opcode = opcodes.last().unwrap(); - let mut res = self.do_call(call_opcode); - args.remove(i); - for j in 0..res.len() { - args.insert(i + j, res.remove(0)); + out + } + + fn eval_list(list: &Vec, quoted: bool) -> (Vec, bool) { + if list.len() < 1 { + return (vec![LispValue::List(Vec::new(), quoted)], false); + } + + let list = &mut list.clone(); + + for i in 0..list.len() { + if let LispValue::List(elements, quoted) = &list[i] { + let (elems, astuple) = Self::eval_list(elements, *quoted); + if astuple { + list[i] = elems.get(0).unwrap_or(&LispValue::Nil).to_owned(); + for j in 1..elems.len() { + list.insert(i, elems[j].to_owned()); } + } else { + list[i] = LispValue::List(elems, *quoted); } } - if let LispValue::RustFunction(_, f) = f { - return f(args.to_vec()); - } else { - todo!(); - } + } + if quoted { + return (list.to_vec(), false); + } + + if let LispValue::RustFunction(_name, f) = &list[0] { + (f(list[1..].to_vec()), true) + } else if let LispValue::LispFunction(_name, ins) = &list[0] { + (Self::call_lisp_func(&list[0], list[1..].to_vec()), true) } else { - panic!("Bad OpCode: expected OpCode::Call") + (list.to_vec(), false) } } - pub fn execute(&self, instructions: Vec) { - for op in instructions { - match op { - OpCode::Call(func, args) => { - self.do_call(&OpCode::Call(func, args)); - }, - OpCode::Exp(ins) => { - self.execute(ins); - } + fn call_lisp_func(f: &LispValue, args: Vec) -> Vec { + todo!() + } + + pub fn execute(&self, instructions: Vec) { + let instructions = Self::handle_prevalues(self, instructions); + for val in instructions { + if let LispValue::List(elements, quoted) = val { + Self::eval_list(&elements, quoted); } } } diff --git a/src/main.rs b/src/main.rs index 3e1bf0c..2493f98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use executor::*; fn main() { let source = std::fs::read_to_string("src/test.lisp").unwrap(); + let mut tokenizer = Tokenizer::new(source); let tokens = match tokenizer.tokenize() { Ok(tokens) => tokens, diff --git a/src/parser.rs b/src/parser.rs index f0de0a8..b443505 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,8 +10,7 @@ pub enum PreLispValue { Integer(i32), Float(f32), List(Vec, bool), // Values, Quoted - LispFunction(String, Vec), - RustFunction(String, fn(Vec) -> Vec), + LispFunction(String, Vec), } impl fmt::Display for PreLispValue { @@ -20,7 +19,6 @@ impl fmt::Display for PreLispValue { PreLispValue::Nil => write!(f, "nil"), PreLispValue::String(str) => write!(f, "{}", str), PreLispValue::LispFunction(name, _) => write!(f, "<'{}': Lisp Function>", name), - PreLispValue::RustFunction(name, _) => write!(f, "<'{}': Rust Function>", name), PreLispValue::Integer(num) => write!(f, "{}", num), PreLispValue::Float(num) => write!(f, "{}", num), _ => todo!() @@ -94,7 +92,7 @@ fn parse_exp(tokens: Vec, quoted: bool) -> PreLispValue { let mut quote_next_list = false; let mut unquote_next_list = false; - let mut i = 1; + let mut i = 0; while i < tokens.len() { let tkn = &tokens[i]; match tkn { @@ -133,15 +131,15 @@ fn parse_exp(tokens: Vec, quoted: bool) -> PreLispValue { PreLispValue::List(values, quoted) } -pub fn parse(tokens: Vec) -> Vec { - let mut opcodes = Vec::new(); +pub fn parse(tokens: Vec) -> Vec { + let mut values = Vec::new(); 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(parse_exp(tkns, false)); + values.push(parse_exp(tkns, false)); i = close_paren_idx; } tkn => { @@ -152,5 +150,5 @@ pub fn parse(tokens: Vec) -> Vec { i += 1; } - opcodes + values } \ No newline at end of file diff --git a/src/test.lisp b/src/test.lisp index d073e67..c1b62fc 100644 --- a/src/test.lisp +++ b/src/test.lisp @@ -11,4 +11,4 @@ ; LispValue::Float(1.0), ; LispValue::Integer(3) ; }) -; }) +; }) \ No newline at end of file diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 53e7703..745b5ab 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -115,6 +115,8 @@ impl Tokenizer { tokens.push(Token::Integer(self.storage.iter().collect::().parse().unwrap())); } + self.is_float = false; + self.storage.clear(); } else { if char == '.' {