diff --git a/src/executor.rs b/src/executor.rs index f50de47..473a0f4 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -1,328 +0,0 @@ -use std::collections::HashMap; - -use crate::{OpCode, LispValue}; - -pub struct LispState { - table: HashMap, -} - -fn add_function + Clone>(table: &mut HashMap, name: T, func: fn(Vec) -> Vec) { - table.insert(name.clone().into(), LispValue::RustFunction(name.into(), func)); -} - -impl LispState { - pub fn new() -> LispState { - let mut table = HashMap::new(); - - add_function(&mut table, "print", |x| { - let mut strings = Vec::new(); - for val in x { - strings.push(val.to_string()); - } - - let str = strings.join(" "); - println!("{}", str); - - vec![LispValue::Nil] - }); - - add_function(&mut table, "concat", |x| { - let mut strings = Vec::new(); - for val in x { - strings.push(val.to_string()); - } - - let str = strings.concat(); - vec![LispValue::String(str)] - }); - - add_function(&mut table, "add", |x| { - if x.len() < 1 { - return vec![LispValue::Nil] - } else if x.len() == 1 { - return vec![x[0].clone()]; - } - - let mut t = "int"; - for v in &x { - match v { - LispValue::Float(_) => t = "float", - LispValue::Integer(_) => (), - _ => return vec![LispValue::Nil] - } - } - - match t { - "int" => { - let mut sum = 0; - for v in &x { - if let LispValue::Integer(n) = v { - sum += n; - } else { - unreachable!() - } - } - return vec![LispValue::Integer(sum)]; - }, - "float" => { - let mut sum = 0.0 as f32; - for v in &x { - if let LispValue::Float(n) = v { - sum += n; - } else if let LispValue::Integer(n) = v{ - sum += *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(sum)]; - }, - _ => unreachable!() - } - }); - - add_function(&mut table, "sub", |x| { - if x.len() < 1 { - return vec![LispValue::Nil] - } else if x.len() == 1 { - return vec![x[0].clone()]; - } - - let mut t = "int"; - for v in &x { - match v { - LispValue::Float(_) => t = "float", - LispValue::Integer(_) => (), - _ => return vec![LispValue::Nil] - } - } - - match t { - "int" => { - if let LispValue::Integer(n) = x[0] { - let mut sum = n; - for i in 1..x.len() { - if let LispValue::Integer(n) = &x[i] { - sum -= n; - } else { - unreachable!() - } - } - return vec![LispValue::Integer(sum)]; - } else { - unreachable!() - } - }, - "float" => { - if let LispValue::Float(n) = x[0] { - let mut sum = n; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - sum -= *n; - } else if let LispValue::Integer(n) = &x[i] { - sum -= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(sum)]; - } else if let LispValue::Integer(n) = x[0] { - let mut sum = n as f32; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - sum -= *n; - } else if let LispValue::Integer(n) = &x[i] { - sum -= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(sum)]; - } { - unreachable!() - } - }, - _ => unreachable!() - } - }); - - add_function(&mut table, "mul", |x| { - if x.len() < 1 { - return vec![LispValue::Nil] - } else if x.len() == 1 { - return vec![x[0].clone()]; - } - - let mut t = "int"; - for v in &x { - match v { - LispValue::Float(_) => t = "float", - LispValue::Integer(_) => (), - _ => return vec![LispValue::Nil] - } - } - - match t { - "int" => { - if let LispValue::Integer(n) = x[0] { - let mut sum = n; - for i in 1..x.len() { - if let LispValue::Integer(n) = &x[i] { - sum *= n; - } else { - unreachable!() - } - } - return vec![LispValue::Integer(sum)]; - } else { - unreachable!() - } - }, - "float" => { - if let LispValue::Float(n) = x[0] { - let mut product = n; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - product *= *n; - } else if let LispValue::Integer(n) = &x[i] { - product *= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(product)]; - } else if let LispValue::Integer(n) = x[0] { - let mut product = n as f32; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - product *= *n; - } else if let LispValue::Integer(n) = &x[i] { - product *= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(product)]; - } { - unreachable!() - } - }, - _ => unreachable!() - } - }); - - add_function(&mut table, "div", |x| { - if x.len() < 1 { - return vec![LispValue::Nil] - } else if x.len() == 1 { - return vec![x[0].clone()]; - } - - let mut t = "int"; - for v in &x { - match v { - LispValue::Float(_) => t = "float", - LispValue::Integer(_) => (), - _ => return vec![LispValue::Nil] - } - } - - match t { - "int" => { - if let LispValue::Integer(n) = x[0] { - let mut sum = n; - for i in 1..x.len() { - if let LispValue::Integer(n) = &x[i] { - sum /= n; - } else { - unreachable!() - } - } - return vec![LispValue::Integer(sum)]; - } else { - unreachable!() - } - }, - "float" => { - if let LispValue::Float(n) = x[0] { - let mut product = n; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - product /= *n; - } else if let LispValue::Integer(n) = &x[i] { - product /= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(product)]; - } else if let LispValue::Integer(n) = x[0] { - let mut product = n as f32; - for i in 1..x.len() { - if let LispValue::Float(n) = &x[i] { - product /= *n; - } else if let LispValue::Integer(n) = &x[i] { - product /= *n as f32; - } else { - unreachable!() - } - } - return vec![LispValue::Float(product)]; - } { - unreachable!() - } - }, - _ => unreachable!() - } - }); - - LispState { - table - } - } - - fn do_call(&self, opcode: &OpCode) -> Vec { - if let OpCode::Call(func, args) = opcode { - let f = self.table.get(func).unwrap(); - - 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; - } - - 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)); - } - } - } - if let LispValue::RustFunction(_, f) = f { - return f(args.to_vec()); - } else { - todo!(); - } - - } else { - panic!("Bad OpCode: expected OpCode::Call") - } - } - - 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); - } - } - } - } -} diff --git a/src/parser.rs b/src/parser.rs index 822a42e..473a0f4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,151 +0,0 @@ -use std::fmt; - -use crate::Token; - -#[derive(Debug, Clone)] -pub enum LispValue { - Nil, - String(String), - Integer(i32), - Float(f32), - LispFunction(String, Vec), - RustFunction(String, fn(Vec) -> Vec), - Ref(String), - Eval(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), - LispValue::Integer(num) => write!(f, "{}", num), - LispValue::Float(num) => write!(f, "{}", num), - LispValue::Ref(name) => write!(f, "<'{}': Reference>", 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) - } -} - -impl From for LispValue { - fn from(value: i32) -> Self { - LispValue::Integer(value) - } -} - -#[derive(Debug, Clone)] -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() { - 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)); - } else { - tkns.push(Token::CloseParen) - } - } - token => { - tkns.push(token.clone()); - } - } - } - - None -} - -fn parse_exp(tokens: Vec) -> Vec { - let mut opcodes = Vec::new(); - - if tokens.len() < 1 { - return opcodes; - } - - if let Token::Identifier(name) = &tokens[0] { - let mut args = Vec::new(); - - let mut i = 1; - while i < tokens.len() { - let tkn = &tokens[i]; - match tkn { - Token::OpenParen => { - let (tkns, close_paren_idx) = read_exp(i, &tokens).unwrap(); - args.push(LispValue::Eval(OpCode::Exp(parse_exp(tkns)))); - i = close_paren_idx; - }, - Token::Identifier(name) => { - args.push(LispValue::Ref(name.to_owned())); - }, - Token::Integer(num) => { - args.push(LispValue::Integer(*num)); - }, - Token::Float(num) => { - args.push(LispValue::Float(*num)); - }, - Token::String(str) => { - args.push(LispValue::String(str.to_owned())); - }, - Token::CloseParen => { - panic!("Unexpected closing parenthesis"); - }, - } - - i += 1; - } - - opcodes.push(OpCode::Call(name.to_owned(), args)) - } - - opcodes -} - -pub fn parse(tokens: Vec) -> Vec { - let mut opcodes = 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(OpCode::Exp(parse_exp(tkns))); - i = close_paren_idx; - } - tkn => { - // TODO: Include more error data - panic!("Unexpected token {:?}", tkn); - } - } - i += 1; - } - - opcodes -} \ No newline at end of file diff --git a/src/tokenizer.rs b/src/tokenizer.rs index e3385f6..53e7703 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -4,6 +4,8 @@ use std::fmt; pub enum Token { OpenParen, CloseParen, + Quote, + Unquote, Identifier(String), String(String), Integer(i32), @@ -164,6 +166,8 @@ impl Tokenizer { self.reading_string = true; self.storage.clear(); }, + '\'' => tokens.push(Token::Quote), + ',' => tokens.push(Token::Unquote), c => { if c.is_alphabetic() { self.reading_identifier = true;