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) -> Vec { 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::().unwrap(); stream.expect(Token::Eof).unwrap(); dbg!(&chunk); let constants = chunk .find_constants(&mut Default::default()) .into_iter() .collect::>(); 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()); }