ferrite-lua/src/main.rs

80 lines
1.9 KiB
Rust

use std::{cell::RefCell, path::PathBuf, rc::Rc};
use crate::{
ast::{Block, Function, LuaNumber},
token_stream::{
TokenStream,
lexer::{Token, tokenize},
},
vm::{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>) -> Vec<vm::Value> {
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);
vec![if res > 0. { rhs } else { lhs }]
}
_ => vec![vm::Value::Nil],
}
}
}
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 instructions = chunk.compile(
&mut compile::State {
constants: constants.clone(),
},
&mut Default::default(),
);
dbg!(&instructions);
let mut vm = VirtualMachine {
environment: Default::default(),
constants,
prototypes: Default::default(),
};
vm.prototypes.insert(0, instructions);
vm.environment.borrow_mut().globals.insert(
vm::Constant::String("max".to_owned()),
vm::Value::RustFunction(Rc::new(RefCell::new(Max))),
);
let closure = vm.create_closure(0);
let mut run = closure.run();
while run.next() {}
dbg!(vm.environment.borrow());
}