Functionality laid out
Todo: turn tokens into opcodes!
This commit is contained in:
parent
a875100988
commit
32ba3f38c3
4 changed files with 109 additions and 1 deletions
47
src/executor.rs
Normal file
47
src/executor.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
src/main.rs
11
src/main.rs
|
@ -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
51
src/parser.rs
Normal 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
|
||||
}
|
|
@ -6,7 +6,6 @@ pub enum Token {
|
|||
CloseParen,
|
||||
Identifier(String),
|
||||
String(String),
|
||||
Integer(i32)
|
||||
}
|
||||
|
||||
|
||||
|
|
Reference in a new issue