ferrite-lua/src/main.rs
2026-03-16 17:19:16 +02:00

96 lines
2.6 KiB
Rust

use std::{cell::RefCell, path::PathBuf, rc::Rc};
use crate::{
ast::{Block, Function, LuaNumber},
token_stream::{
TokenStream,
lexer::{Token, tokenize},
},
vm::{RuntimeError, RustFunction, VirtualMachine},
};
mod ast;
mod compile;
mod token_stream;
mod vm;
static TEST: &str = include_str!("../examples/test.lua");
#[derive(Debug)]
pub struct Max;
impl RustFunction for Max {
fn execute(&self, parameters: Vec<vm::Value>) -> Result<Vec<vm::Value>, RuntimeError> {
let lhs = parameters.get(0).cloned().unwrap_or(vm::Value::Nil);
let rhs = parameters.get(1).cloned().unwrap_or(vm::Value::Nil);
match lhs.lt(&rhs)? {
vm::Value::Number(value) => {
let res = LuaNumber::from_bits(value);
Ok(vec![if res > 0. { rhs } else { lhs }])
}
_ => Ok(vec![vm::Value::Nil]),
}
}
}
#[derive(Debug)]
pub struct Print;
impl RustFunction for Print {
fn execute(&self, parameters: Vec<vm::Value>) -> Result<Vec<vm::Value>, RuntimeError> {
println!("{:?}", parameters);
Ok(Vec::new())
}
}
fn main() {
let file_path = PathBuf::from("../examples/test.lua");
let tokens = tokenize(TEST).unwrap();
let mut stream = TokenStream::from(&file_path, &tokens);
dbg!(&tokens);
let chunk = stream.parse::<Block>().unwrap();
stream.expect(Token::Eof).unwrap();
dbg!(&chunk);
let constants = chunk
.find_constants(&mut Default::default())
.into_iter()
.collect::<Vec<_>>();
dbg!(&constants);
let mut state = compile::State {
constants: constants.clone(),
prototypes: Vec::new(),
};
let mut scope = Default::default();
let instructions = chunk.compile(&mut state, &mut scope);
let mut vm = VirtualMachine {
environment: Default::default(),
constants,
prototypes: Default::default(),
};
vm.prototypes.insert(0, instructions);
for (i, prototype) in state.prototypes.into_iter().enumerate() {
vm.prototypes.insert((i + 1) as u32, prototype);
}
dbg!(&vm.prototypes);
vm.environment.borrow_mut().globals.insert(
vm::Constant::String("max".to_owned()),
vm::Value::RustFunction(Rc::new(RefCell::new(Max))),
);
vm.environment.borrow_mut().globals.insert(
vm::Constant::String("print".to_owned()),
vm::Value::RustFunction(Rc::new(RefCell::new(Print))),
);
let closure = vm.create_closure(0);
let mut run = closure.run(Vec::new());
while run.next().unwrap().is_none() {}
dbg!(&vm.environment.borrow().globals);
}