96 lines
2.6 KiB
Rust
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);
|
|
}
|