80 lines
1.9 KiB
Rust
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());
|
|
}
|