deimos-lang/src/bin/dvm/main.rs

167 lines
4.8 KiB
Rust

use deimos::vm::dm_type::DmType;
use deimos::vm::lib::{DmConstant, DmLib};
use deimos::vm::object_type::{DmField, DmFn, DmImplementation, DmInterface, DmMethod};
use deimos::vm::op_codes::{
add_alloc, add_dealloc, add_invoke_fn, add_mov_const, add_platform_call, add_store,
};
use deimos::vm::platform::init_platform_functions;
use deimos::vm::{call_fn, DvmContext, DvmState};
use std::rc::Rc;
fn main() {
// Goal:
// - write a single lib with a main()
// - call the main fn
// fn main() { println "Hello, World!" }
// std/core/array lib
let mut array_lib = DmLib::new("std/core/array");
// std::core::Array
let array_int = DmInterface::new("std::core::Array", "Array");
array_lib.add_interface(array_int);
let array_int_rc = array_lib
.interfaces()
.iter()
.find(|interface| interface.fqn() == "std::core::Array")
.unwrap();
// std::core::ArrayImpl
let mut array_impl = DmImplementation::new(
"std::core::ArrayImpl",
"ArrayImpl",
Some(array_int_rc.clone()),
);
let array_impl_ptr_address_fld = DmField::new("ptr_address", DmType::USize);
let array_impl_ptr_size_fld = DmField::new("ptr_size", DmType::USize);
let array_impl_length_fld = DmField::new("length", DmType::Long);
array_impl.add_field(array_impl_ptr_address_fld);
array_impl.add_field(array_impl_ptr_size_fld);
array_impl.add_field(array_impl_length_fld);
// std::core::ArrayImpl::_ctor_0(
// r0: self
// r1: USize ptr_address
// r2: USize ptr_size
// r3: Long length
// )
let mut array_impl_ctor_0_bytecode: Vec<u8> = Vec::new();
add_store(&mut array_impl_ctor_0_bytecode, 0, 0, 1);
add_store(&mut array_impl_ctor_0_bytecode, 0, 1, 2);
add_store(&mut array_impl_ctor_0_bytecode, 0, 2, 3);
let array_impl_ctor_0_fn = DmFn::new(
"std::core::ArrayImpl::_ctor_0",
"_ctor_0",
array_impl_ctor_0_bytecode,
4,
None,
);
let array_impl_ctor_0_method = DmMethod::new(array_impl_ctor_0_fn, None);
array_impl.add_method(array_impl_ctor_0_method);
array_lib.add_implementation(array_impl);
// std::core::String
let mut string_lib = DmLib::new("std/core/string");
let string_int = DmInterface::new("std::core::String", "String");
string_lib.add_interface(string_int);
let string_int_rc = string_lib
.interfaces()
.iter()
.find(|interface| interface.fqn() == "std::core::String")
.unwrap();
let mut string_impl = DmImplementation::new(
"std::core::StringImpl",
"StringImpl",
Some(string_int_rc.clone()),
);
let bytes_field = DmField::new("bytes", DmType::Object);
string_impl.add_field(bytes_field);
// std::core::String::_ctor_0(
// r0: self
// r1: Array<Byte> bytes
// )
let mut string_ctor_0_bytecode: Vec<u8> = Vec::new();
add_store(&mut string_ctor_0_bytecode, 0, 0, 1);
let string_ctor_0_fn = DmFn::new(
"std::core::StringImpl::_ctor_0",
"_ctor_0",
string_ctor_0_bytecode,
2,
None,
);
let string_ctor_0_method = DmMethod::new(string_ctor_0_fn, None);
string_impl.add_method(string_ctor_0_method);
string_lib.add_implementation(string_impl);
// greeting lib
let mut greeting_lib = DmLib::new("greeting");
greeting_lib.add_constant(DmConstant::String("Hello, World!".to_string()));
let mut main_byte_code = Vec::new();
// Move greeting
// r0: greeting address
// r1: greeting size
add_mov_const(&mut main_byte_code, 0, 1, "greeting", 0);
// Alloc Array<Byte> greeting bytes
add_alloc(&mut main_byte_code, 2, "std::core::ArrayImpl");
// Call ArrayImpl(ptr_address, ptr_size, length)
add_invoke_fn(
&mut main_byte_code,
"std::core::ArrayImpl::_ctor_0",
3,
&[2, 0, 1, 1],
);
// Alloc StringImpl greeting
add_alloc(&mut main_byte_code, 4, "std::core::StringImpl");
// Call StringImpl(greeting_bytes)
add_invoke_fn(
&mut main_byte_code,
"std::core::StringImpl::_ctor_0",
5,
&[4, 2],
);
// Call println(greeting)
add_platform_call(&mut main_byte_code, "std::core::println", 6, &[4]);
// Dealloc StringImpl
add_dealloc(&mut main_byte_code, 4);
// Dealloc ArrayImpl
add_dealloc(&mut main_byte_code, 2);
let main_dm_fn = DmFn::new("main", "main", main_byte_code, 7, None);
greeting_lib.add_function(main_dm_fn);
let mut state = DvmState::new();
let mut context = DvmContext::new();
context.load_libs(vec![
Rc::new(greeting_lib),
Rc::new(string_lib),
Rc::new(array_lib),
]);
context.load_platform_fns(init_platform_functions());
let main_fn = context.fn_by_fqn("main").unwrap();
call_fn(&mut state, &context, &main_fn, vec![]);
}