Functionality laid out

Todo: turn tokens into opcodes!
This commit is contained in:
Apache 2024-06-10 20:52:15 -05:00
parent a875100988
commit 32ba3f38c3
Signed by: apache
GPG key ID: 6B10F3EAF14F4C77
4 changed files with 109 additions and 1 deletions

47
src/executor.rs Normal file
View file

@ -0,0 +1,47 @@
use std::collections::HashMap;
use crate::{OpCode, LispValue};
pub struct LispState {
table: HashMap<String, LispValue>,
}
impl LispState {
pub fn new() -> LispState {
let mut table = HashMap::new();
table.insert(String::from("print"), LispValue::RustFunction(String::from("print"), |x| {
let mut strings = Vec::new();
for val in x {
strings.push(val.to_string());
}
let str = strings.join(" ");
println!("{}", str);
LispValue::Nil
}));
LispState {
table
}
}
pub fn execute(&self, instructions: Vec<OpCode>) {
for op in instructions {
match op {
OpCode::Call(func, args) => {
let f = self.table.get(&func).unwrap();
if let LispValue::RustFunction(_, f) = f {
f(args);
} else {
todo!();
}
},
OpCode::Eval(ins) => {
self.execute(ins);
}
}
}
}
}

View file

@ -1,6 +1,12 @@
mod tokenizer;
use tokenizer::*;
mod parser;
use parser::*;
mod executor;
use executor::*;
fn main() {
let source = std::fs::read_to_string("src/test.lisp").unwrap();
let mut tokenizer = Tokenizer::new(source);
@ -12,4 +18,9 @@ fn main() {
}
};
println!("{:?}", tokens);
let instructions = parse(tokens);
let state = LispState::new();
state.execute(instructions);
}

51
src/parser.rs Normal file
View file

@ -0,0 +1,51 @@
use std::fmt;
use crate::Token;
pub enum LispValue {
Nil,
String(String),
LispFunction(String, Vec<OpCode>),
RustFunction(String, fn(Vec<LispValue>) -> LispValue)
}
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)
}
}
}
impl From<&str> for LispValue {
fn from(value: &str) -> Self {
LispValue::String(value.to_string())
}
}
impl From<String> for LispValue {
fn from(value: String) -> Self {
LispValue::String(value)
}
}
pub enum OpCode {
Call(String, Vec<LispValue>),
Eval(Vec<OpCode>)
}
pub fn parse(tokens: Vec<Token>) -> Vec<OpCode> {
let mut opcodes = Vec::new();
// TODO:
opcodes.push(OpCode::Call("print".to_string(), vec![
LispValue::from("Hello, World!")
]));
opcodes
}

View file

@ -6,7 +6,6 @@ pub enum Token {
CloseParen,
Identifier(String),
String(String),
Integer(i32)
}