2024-01-31 10:54:38 -06:00
|
|
|
pub mod data;
|
|
|
|
pub mod ins;
|
|
|
|
pub mod label;
|
|
|
|
pub mod linker;
|
|
|
|
pub mod object;
|
2023-10-27 20:29:02 -05:00
|
|
|
|
|
|
|
use {
|
|
|
|
object::Object,
|
|
|
|
rhai::{Engine, Module},
|
|
|
|
std::{cell::RefCell, rc::Rc},
|
|
|
|
};
|
|
|
|
|
|
|
|
type SharedObject = Rc<RefCell<Object>>;
|
|
|
|
|
|
|
|
pub fn assembler(
|
|
|
|
linkout: &mut impl std::io::Write,
|
|
|
|
loader: impl FnOnce(&mut Engine) -> Result<(), Box<rhai::EvalAltResult>>,
|
|
|
|
) -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
let mut engine = Engine::new();
|
|
|
|
let mut module = Module::new();
|
|
|
|
let obj = Rc::new(RefCell::new(Object::default()));
|
|
|
|
ins::setup(&mut module, Rc::clone(&obj));
|
|
|
|
label::setup(&mut engine, &mut module, Rc::clone(&obj));
|
|
|
|
|
|
|
|
// Registers
|
2023-11-10 02:51:01 -06:00
|
|
|
for n in 0_u8..=255 {
|
2023-10-27 20:29:02 -05:00
|
|
|
module.set_var(format!("r{n}"), n);
|
|
|
|
}
|
|
|
|
|
|
|
|
module.set_native_fn("reg", |n: i64| {
|
|
|
|
Ok(u8::try_from(n).map_err(|_| {
|
|
|
|
rhai::EvalAltResult::ErrorRuntime("Invalid register value".into(), rhai::Position::NONE)
|
|
|
|
})?)
|
|
|
|
});
|
|
|
|
|
|
|
|
module.set_native_fn("as_i64", |n: u8| Ok(n as i64));
|
|
|
|
|
|
|
|
let datamod = Rc::new(data::module(&mut engine, SharedObject::clone(&obj)));
|
|
|
|
engine.register_global_module(Rc::new(module));
|
|
|
|
engine.register_static_module("data", datamod);
|
|
|
|
engine.register_type_with_name::<object::SymbolRef>("SymbolRef");
|
|
|
|
loader(&mut engine)?;
|
|
|
|
linker::link(obj, linkout)?;
|
|
|
|
Ok(())
|
|
|
|
}
|