Compare commits
5 Commits
5732c4d197
...
7903c1cfb3
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7903c1cfb3 | ||
![]() |
9bc27b841b | ||
![]() |
919b312d68 | ||
![]() |
0dd58cdfdc | ||
![]() |
b90111dfd5 |
12
dm_lib/std/core/array.dm
Normal file
12
dm_lib/std/core/array.dm
Normal file
@ -0,0 +1,12 @@
|
||||
ns std::core
|
||||
|
||||
decl pub int Array<T> : Monad {
|
||||
length: Int
|
||||
}
|
||||
|
||||
pub mod array {
|
||||
// Usage:
|
||||
// let int_array = array::of(1, 2, 3)
|
||||
// assert_eq(3, int_array.length)
|
||||
decl pub fn of<T>(ts: ...T): Array<T>
|
||||
}
|
4
dm_lib/std/core/monad.dm
Normal file
4
dm_lib/std/core/monad.dm
Normal file
@ -0,0 +1,4 @@
|
||||
pub hkt Monad[T<A>] {
|
||||
fn <B> map(m: fn (from: A) => B): T<B>
|
||||
fn <B> flat_map(m: fn (from: A) => T<B>): T<B>
|
||||
}
|
5
dm_lib/std/core/print.dm
Normal file
5
dm_lib/std/core/print.dm
Normal file
@ -0,0 +1,5 @@
|
||||
ns std::core
|
||||
|
||||
decl pub fn print(message: Any)
|
||||
|
||||
decl pub fn println(message: Any)
|
26
dm_lib/std/core/string.dm
Normal file
26
dm_lib/std/core/string.dm
Normal file
@ -0,0 +1,26 @@
|
||||
ns std::core
|
||||
|
||||
pub int String {
|
||||
bytes: byte[]
|
||||
encoding: Encoding
|
||||
length: Int
|
||||
}
|
||||
|
||||
pub enum Encoding {
|
||||
Utf8, Utf16, Ascii
|
||||
}
|
||||
|
||||
pub impl Utf8String(bytes: byte[]) : String {
|
||||
impl fn get_encoding() = Encoding::Utf8
|
||||
impl fn get_length() = bytes.length
|
||||
}
|
||||
|
||||
pub mod string {
|
||||
|
||||
// Example usage:
|
||||
// let bytes = [0x64, 0x65, 0x69, 0x6d, 0x6f, 0x73]
|
||||
// let s = string::from_utf8_bytes(bytes)
|
||||
// println s // "deimos"
|
||||
fn from_utf8_bytes(bytes: byte[]): String = Utf8String(bytes)
|
||||
|
||||
}
|
@ -5,7 +5,7 @@ fn main() {
|
||||
let mut code: Vec<u8> = Vec::new();
|
||||
add_mov_int(&mut code, 0, 42);
|
||||
add_platform_call_to(&mut code, &String::from("std::core::print"), 0, 1, &vec![0u8]);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&mut code);
|
||||
println!()
|
||||
}
|
78
src/vm/mem.rs
Normal file
78
src/vm/mem.rs
Normal file
@ -0,0 +1,78 @@
|
||||
use crate::vm::types::{DmImplementation, DmProperty, DmType};
|
||||
use crate::vm::values::DmValue;
|
||||
use std::alloc::Layout;
|
||||
|
||||
pub struct DmAllocObject<'a> {
|
||||
pub data: *mut u8,
|
||||
pub size: usize,
|
||||
pub layout: Layout,
|
||||
pub object_type: &'a DmImplementation<'a>,
|
||||
}
|
||||
|
||||
pub unsafe fn get_property_value(dm_property: &DmProperty, dm_property_object: &DmAllocObject) -> DmValue {
|
||||
let mut data: Vec<u8> = Vec::with_capacity(dm_property.dm_type.size_in_bytes());
|
||||
for i in dm_property.data_offset..(dm_property.data_offset + dm_property.dm_type.size_in_bytes()) {
|
||||
data.push(dm_property_object.data.offset(i as isize).read());
|
||||
}
|
||||
match dm_property.dm_type {
|
||||
DmType::Byte => {
|
||||
DmValue::DmByte(data[0])
|
||||
}
|
||||
DmType::Int => {
|
||||
DmValue::DmInt(i32::from_ne_bytes(data[0..4].try_into().unwrap()))
|
||||
}
|
||||
DmType::Long => {
|
||||
DmValue::DmLong(i64::from_ne_bytes(data[0..8].try_into().unwrap()))
|
||||
}
|
||||
DmType::Double => {
|
||||
DmValue::DmDouble(f64::from_ne_bytes(data[0..8].try_into().unwrap()))
|
||||
}
|
||||
DmType::Boolean => {
|
||||
DmValue::DmBoolean(i32::from_ne_bytes(data[0..4].try_into().unwrap()) != 0)
|
||||
}
|
||||
DmType::ObjectPointer(_) => {
|
||||
DmValue::DmPointer(usize::from_ne_bytes(data[0..8].try_into().unwrap()) as *mut DmAllocObject)
|
||||
}
|
||||
DmType::ByteArray(_) => {
|
||||
DmValue::DmByteArray(data)
|
||||
}
|
||||
DmType::IntArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i32::from_ne_bytes(data[(i * 4)..(i * 4 + 4)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmIntArray(result)
|
||||
}
|
||||
DmType::LongArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i64::from_ne_bytes(data[i * 8..(i * 8 + 8)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmLongArray(result)
|
||||
}
|
||||
DmType::DoubleArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(f64::from_ne_bytes(data[i * 8..(i * 8 + 8)].try_into().unwrap()));
|
||||
}
|
||||
DmValue::DmDoubleArray(result)
|
||||
}
|
||||
DmType::BooleanArray(length) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(i32::from_ne_bytes(data[(i * 4)..(i * 4 + 4)].try_into().unwrap()) != 0);
|
||||
}
|
||||
DmValue::DmBooleanArray(result)
|
||||
}
|
||||
DmType::ObjectPointerArray(length, _) => {
|
||||
let mut result = Vec::with_capacity(length);
|
||||
for i in 0..length {
|
||||
result.push(usize::from_ne_bytes(data[(i * 8)..(i * 8 + 8)].try_into().unwrap()) as *mut DmAllocObject);
|
||||
}
|
||||
DmValue::DmPointerArray(result)
|
||||
}
|
||||
DmType::Unit => {
|
||||
DmValue::DmUnit
|
||||
}
|
||||
}
|
||||
}
|
102
src/vm/mod.rs
102
src/vm/mod.rs
@ -2,30 +2,24 @@ pub mod module;
|
||||
pub mod op_codes;
|
||||
pub mod platform;
|
||||
pub mod types;
|
||||
mod util;
|
||||
pub mod util;
|
||||
pub mod values;
|
||||
mod mem;
|
||||
|
||||
use crate::vm::module::DmFunction;
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
use crate::vm::module::DmModule;
|
||||
use crate::vm::platform::init_platform_functions;
|
||||
use crate::vm::types::{DmFn, DmImplementation};
|
||||
use op_codes::*;
|
||||
use std::alloc::{alloc_zeroed, dealloc, Layout};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Index;
|
||||
use types::DmType;
|
||||
use util::{get_32_le, get_64_le};
|
||||
use crate::vm::DmValue::{DmInt, DmLong, DmPointer, DmUnit};
|
||||
use values::DmValue;
|
||||
use values::DmValue::*;
|
||||
|
||||
pub type PlatformFunction = fn(args: Vec<DmValue>, &mut DmVirtualMachine) -> DmValue;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum DmValue {
|
||||
DmInt(i32),
|
||||
DmLong(i64),
|
||||
DmDouble(f64),
|
||||
DmPointer(*mut DmObject),
|
||||
DmUnit,
|
||||
DmException(*mut DmObject)
|
||||
}
|
||||
|
||||
enum CallFrame {
|
||||
PlatformCall(PlatformCallFrame),
|
||||
DeimosCall(DeimosCallFrame)
|
||||
@ -33,15 +27,15 @@ enum CallFrame {
|
||||
|
||||
pub struct PlatformCallFrame {
|
||||
pub name: String,
|
||||
pub args: Vec<u64>,
|
||||
pub arg_types: Vec<DmType>,
|
||||
pub args: Vec<DmValue>,
|
||||
}
|
||||
|
||||
struct DeimosCallFrame {
|
||||
return_address: usize,
|
||||
}
|
||||
|
||||
pub struct DmVirtualMachine {
|
||||
pub struct DmVirtualMachine<'a> {
|
||||
modules: Vec<DmModule<'a>>,
|
||||
platform_functions: HashMap<String, PlatformFunction>,
|
||||
ip: usize,
|
||||
call_stack: Vec<CallFrame>,
|
||||
@ -49,9 +43,10 @@ pub struct DmVirtualMachine {
|
||||
register_state_stack: Vec<Vec<DmValue>>,
|
||||
}
|
||||
|
||||
impl DmVirtualMachine {
|
||||
pub fn new() -> DmVirtualMachine {
|
||||
impl DmVirtualMachine<'_> {
|
||||
pub fn new(modules: Vec<DmModule>) -> DmVirtualMachine {
|
||||
DmVirtualMachine {
|
||||
modules,
|
||||
ip: 0,
|
||||
registers: Vec::new(),
|
||||
platform_functions: init_platform_functions(),
|
||||
@ -62,7 +57,7 @@ impl DmVirtualMachine {
|
||||
|
||||
pub fn call(
|
||||
&mut self,
|
||||
dm_function: &DmFunction,
|
||||
dm_function: &DmFn,
|
||||
args: Vec<DmValue>,
|
||||
) -> DmValue {
|
||||
// save current state
|
||||
@ -77,7 +72,7 @@ impl DmVirtualMachine {
|
||||
|
||||
// push args
|
||||
for i in 0..args.len() {
|
||||
self.registers.insert(i, args[i]);
|
||||
self.registers.insert(i, args[i].clone());
|
||||
}
|
||||
|
||||
// run the byte code
|
||||
@ -118,15 +113,36 @@ impl DmVirtualMachine {
|
||||
i += 3;
|
||||
}
|
||||
ALLOC => {
|
||||
let target_register = code[i + 1] as usize;
|
||||
let size = get_32_le!(code, i, 2, usize);
|
||||
i += 1;
|
||||
let target_register = code[i] as usize;
|
||||
i += 1;
|
||||
let symbol_name_length = get_32_le!(code, i, 0, usize);
|
||||
i += 4;
|
||||
let raw_symbol_name = code[i..(i + symbol_name_length)].to_vec();
|
||||
i += symbol_name_length;
|
||||
let symbol_name = String::from_utf8(raw_symbol_name).unwrap();
|
||||
|
||||
// find implementation
|
||||
let mut implementation_result: Option<&DmImplementation> = None;
|
||||
'module_find: for module in self.modules.iter() {
|
||||
if let Some(dm_implementation) = module.implementations.get(&symbol_name) {
|
||||
implementation_result = Some(dm_implementation);
|
||||
break 'module_find;
|
||||
}
|
||||
}
|
||||
if implementation_result == None {
|
||||
panic!("Implementation {} not found", symbol_name);
|
||||
}
|
||||
|
||||
let dm_implementation = implementation_result.unwrap();
|
||||
let size = dm_implementation.size_in_bytes;
|
||||
let layout = Layout::from_size_align(size, 4).unwrap();
|
||||
let pointer = unsafe { alloc_zeroed(layout) };
|
||||
let dm_object = Box::new(DmObject {
|
||||
let dm_object = Box::new(DmAllocObject {
|
||||
object_type: dm_implementation,
|
||||
data: pointer,
|
||||
size,
|
||||
layout,
|
||||
object_type: todo!(),
|
||||
});
|
||||
let dm_object_pointer = Box::into_raw(dm_object);
|
||||
self.registers.insert(target_register, DmPointer(dm_object_pointer));
|
||||
@ -209,30 +225,6 @@ impl DmVirtualMachine {
|
||||
|
||||
}
|
||||
|
||||
pub struct DmObjectType {
|
||||
name: String,
|
||||
properties: HashMap<String, DmObjectProperty>,
|
||||
fields: HashMap<String, DmObjectField>,
|
||||
methods: HashMap<String, DmFunction>,
|
||||
}
|
||||
|
||||
pub struct DmObject {
|
||||
object_type: Box<DmObjectType>,
|
||||
data: *mut u8,
|
||||
size: usize,
|
||||
layout: Layout,
|
||||
}
|
||||
|
||||
pub struct DmObjectProperty {
|
||||
name: String,
|
||||
property_type: DmType,
|
||||
}
|
||||
|
||||
pub struct DmObjectField {
|
||||
name: String,
|
||||
field_type: DmType,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod dvm_run_tests {
|
||||
use super::*;
|
||||
@ -248,7 +240,7 @@ mod dvm_run_tests {
|
||||
fn mov_1_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 1);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(1), vm.registers.get(0));
|
||||
}
|
||||
@ -257,7 +249,7 @@ mod dvm_run_tests {
|
||||
fn move_65535_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 0xffff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(0xffff), vm.registers.get(0));
|
||||
}
|
||||
@ -266,7 +258,7 @@ mod dvm_run_tests {
|
||||
fn move_int_max_as_int() {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 0, 0x0fff_ffff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(0x0fff_ffff), vm.registers.get(0));
|
||||
}
|
||||
@ -276,7 +268,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_mov_int(&mut code, 1, 1);
|
||||
add_mov_register(&mut code, 0, 1);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.registers.resize(2, DmUnit);
|
||||
vm.run(&code);
|
||||
assert_register!(DmInt(1), vm.registers.get(0));
|
||||
@ -288,7 +280,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_alloc(&mut code, 0, 4);
|
||||
add_mov_int_to(&mut code, 0, 0, 0xff);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
let box_address = vm.registers.get(0).unwrap().clone();
|
||||
match box_address {
|
||||
@ -307,7 +299,7 @@ mod dvm_run_tests {
|
||||
let mut code = Vec::new();
|
||||
add_alloc(&mut code, 0, 4);
|
||||
add_dealloc(&mut code, 0);
|
||||
let mut vm = DmVirtualMachine::new();
|
||||
let mut vm = DmVirtualMachine::new(Vec::new());
|
||||
vm.run(&code);
|
||||
assert_register!(DmUnit, vm.registers.get(0));
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
use crate::get_32_le;
|
||||
use crate::vm::types::{DmFn, DmImplementation, DmInterface};
|
||||
use std::collections::HashMap;
|
||||
use std::io::Read;
|
||||
|
||||
pub const DEIMOS_MAGIC_NUMBER: u64 = 0x00_00_64_65_69_6d_6f_73; // ascii 'deimos'
|
||||
const DEIMOS_MAGIC_STRING: [u8; 6] = [0x64, 0x65, 0x69, 0x6d, 0x6f, 0x73]; // ascii 'deimos'
|
||||
pub const DEIMOS_MAGIC_STRING: [u8; 6] = [0x64, 0x65, 0x69, 0x6d, 0x6f, 0x73]; // ascii 'deimos'
|
||||
|
||||
pub const VERSION_STRING: &str = "0.1.0";
|
||||
pub const COMPILER_VERSION_STRING: &str = "0.1.0";
|
||||
|
||||
pub struct DmModule {
|
||||
name: String,
|
||||
version: String,
|
||||
constants: HashMap<String, DmConstant>,
|
||||
functions: HashMap<String, DmFunction>,
|
||||
pub struct DmModule<'a> {
|
||||
pub compiler_version: String,
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub constants: HashMap<String, DmConstant>,
|
||||
pub interfaces: HashMap<String, DmInterface<'a>>,
|
||||
pub implementations: HashMap<String, DmImplementation<'a>>,
|
||||
pub functions: HashMap<String, DmFn>,
|
||||
}
|
||||
|
||||
pub enum DmConstant {
|
||||
@ -21,12 +24,6 @@ pub enum DmConstant {
|
||||
String(String),
|
||||
}
|
||||
|
||||
pub struct DmFunction {
|
||||
pub name: String,
|
||||
pub byte_code: Vec<u8>,
|
||||
pub num_registers: usize,
|
||||
}
|
||||
|
||||
const CONST_SYMBOL: u8 = 0x01;
|
||||
const FUNCTION_SYMBOL: u8 = 0x02;
|
||||
|
||||
@ -74,10 +71,10 @@ pub fn write_module(module: DmModule) -> Vec<u8> {
|
||||
push_byte_array!(result, DEIMOS_MAGIC_STRING);
|
||||
|
||||
// Push version string
|
||||
push_string!(result, module.version);
|
||||
push_string!(result, module.compiler_version);
|
||||
|
||||
// Push module name length, little endian
|
||||
push_string!(result, module.name);
|
||||
push_string!(result, module.fqn);
|
||||
|
||||
result
|
||||
}
|
||||
|
@ -1,65 +1,61 @@
|
||||
use crate::vm::types::DmType;
|
||||
use crate::vm::DmValue::*;
|
||||
use crate::vm::{DmObject, DmValue, DmVirtualMachine};
|
||||
use DmType::*;
|
||||
use crate::vm::module::DmFunction;
|
||||
|
||||
fn get_method<'a>(ptr: *mut DmObject, name: String) -> Option<&'a DmFunction> {
|
||||
unsafe {
|
||||
(*ptr).object_type.methods.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rust_string_from_dm_object(ptr: *mut DmObject) -> String {
|
||||
unsafe {
|
||||
let dm_object = Box::from_raw(ptr);
|
||||
format!("{}@{:?}", dm_object.object_type.name, dm_object.data)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rust_string_from_dm_string(ptr: *mut DmObject) -> String {
|
||||
unsafe {
|
||||
let dm_string = Box::from_raw(ptr);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
use crate::vm::{mem, DmValue, DmVirtualMachine};
|
||||
|
||||
pub fn dm_print(args: Vec<DmValue>, vm: &mut DmVirtualMachine) -> DmValue {
|
||||
if args.len() != 1 {
|
||||
return DmException(todo!("make an Exception object."))
|
||||
return DmUnit // TODO: make exception
|
||||
}
|
||||
match args[0] {
|
||||
match &args[0] {
|
||||
DmByte(b) => {
|
||||
print!("{}", *b);
|
||||
}
|
||||
DmInt(i) => {
|
||||
print!("{}", i);
|
||||
print!("{}", *i);
|
||||
}
|
||||
DmLong(l) => {
|
||||
print!("{}", l);
|
||||
print!("{}", *l);
|
||||
}
|
||||
DmDouble(d) => {
|
||||
print!("{}", d);
|
||||
print!("{}", *d);
|
||||
}
|
||||
DmPointer(ptr) => {
|
||||
if let Some(to_string) = get_method(ptr, String::from("to_string")) {
|
||||
let call_result = vm.call(&to_string, vec![args[0]]);
|
||||
match call_result {
|
||||
DmPointer(dm_string_ptr) => {
|
||||
let string = get_rust_string_from_dm_string(dm_string_ptr);
|
||||
print!("{}", string);
|
||||
}
|
||||
_ => {
|
||||
// TODO: vm throw or return exception?
|
||||
DmBoolean(b) => {
|
||||
print!("{}", *b);
|
||||
}
|
||||
DmPointer(ptr) => unsafe {
|
||||
let dm_alloc_object = Box::from_raw(*ptr);
|
||||
let dm_object_type = &dm_alloc_object.object_type;
|
||||
if let Some(to_string_method) = dm_object_type.get_method(String::from("std::core::Object::to_string"), &dm_alloc_object) {
|
||||
let call_result = vm.call(to_string_method, vec![args[0].clone()]);
|
||||
if let DmPointer(dm_string_pointer) = call_result {
|
||||
let dm_string_object = Box::from_raw(dm_string_pointer);
|
||||
let bytes_property = dm_string_object.object_type.get_property(String::from("bytes"), &dm_string_object).unwrap();
|
||||
let string_bytes_value = mem::get_property_value(bytes_property, &dm_string_object);
|
||||
if let DmByteArray(raw_string_bytes) = string_bytes_value {
|
||||
// TODO: other encodings
|
||||
print!("{}", String::from_utf8(raw_string_bytes).unwrap());
|
||||
} else {
|
||||
panic!("Expected std::core::String.bytes to be a ByteArray.")
|
||||
}
|
||||
} else {
|
||||
panic!("Expected {} to return a string.", to_string_method.fqn)
|
||||
}
|
||||
} else {
|
||||
print!("{}", get_rust_string_from_dm_object(ptr));
|
||||
println!("{}@{:?}", dm_object_type.get_fqn(), dm_alloc_object.data)
|
||||
}
|
||||
},
|
||||
DmByteArray(bs) => {
|
||||
|
||||
}
|
||||
DmIntArray(is) => {
|
||||
|
||||
}
|
||||
DmLongArray(ls) => {}
|
||||
DmDoubleArray(ds) => {}
|
||||
DmBooleanArray(bs) => {}
|
||||
DmPointerArray(ptrs) => {}
|
||||
DmUnit => {
|
||||
print!("Unit")
|
||||
},
|
||||
DmException(e) => {
|
||||
print!("Exception")
|
||||
}
|
||||
}
|
||||
DmUnit
|
||||
}
|
||||
|
161
src/vm/types.rs
161
src/vm/types.rs
@ -1,9 +1,162 @@
|
||||
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
|
||||
pub enum DmType {
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum DmType<'a> {
|
||||
Byte,
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
Pointer,
|
||||
Boolean,
|
||||
ObjectPointer(&'a dyn DmObjectType),
|
||||
ByteArray(usize),
|
||||
IntArray(usize),
|
||||
LongArray(usize),
|
||||
DoubleArray(usize),
|
||||
BooleanArray(usize),
|
||||
ObjectPointerArray(usize, &'a dyn DmObjectType),
|
||||
Unit,
|
||||
Exception
|
||||
}
|
||||
|
||||
impl DmType<'_> {
|
||||
pub fn size_in_bytes(&self) -> usize {
|
||||
match self {
|
||||
DmType::Byte => 1,
|
||||
DmType::Int => 4,
|
||||
DmType::Long => 8,
|
||||
DmType::Double => 8,
|
||||
DmType::Boolean => 4,
|
||||
DmType::ObjectPointer(_) => 8,
|
||||
DmType::ByteArray(length) => *length,
|
||||
DmType::IntArray(length) => *length * 4,
|
||||
DmType::LongArray(length) => *length * 8,
|
||||
DmType::DoubleArray(length) => *length * 8,
|
||||
DmType::BooleanArray(length) => *length * 4,
|
||||
DmType::ObjectPointerArray(length, _) => length * 8,
|
||||
DmType::Unit => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DmObjectType {
|
||||
fn get_fqn(&self) -> &String;
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn>;
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmFn {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub byte_code: Vec<u8>,
|
||||
pub num_registers: usize,
|
||||
}
|
||||
|
||||
impl PartialEq for DmFn {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmInterface<'a> {
|
||||
fqn: String,
|
||||
short_name: String,
|
||||
properties: HashMap<String, DmProperty<'a>>,
|
||||
virtual_methods: HashMap<String, DmVirtualMethod>,
|
||||
impl_methods: HashMap<String, DmFn>,
|
||||
}
|
||||
|
||||
impl PartialEq for DmInterface<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
impl DmObjectType for DmInterface<'_> {
|
||||
fn get_fqn(&self) -> &String {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn> {
|
||||
if self.impl_methods.contains_key(&name) {
|
||||
self.impl_methods.get(&name)
|
||||
} else if self.virtual_methods.contains_key(&name) {
|
||||
self_object.object_type.get_method(name, &self_object)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty> {
|
||||
self.properties.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmVirtualMethod {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
}
|
||||
|
||||
impl PartialEq for DmVirtualMethod {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmImplementation<'a> {
|
||||
pub fqn: String,
|
||||
pub short_name: String,
|
||||
pub interface: &'a DmInterface<'a>,
|
||||
pub properties: HashMap<String, DmProperty<'a>>,
|
||||
pub fields: HashMap<String, DmField<'a>>,
|
||||
pub size_in_bytes: usize,
|
||||
pub methods: HashMap<String, DmFn>
|
||||
}
|
||||
|
||||
impl PartialEq for DmImplementation<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.fqn == other.fqn
|
||||
}
|
||||
}
|
||||
|
||||
impl DmObjectType for DmImplementation<'_> {
|
||||
fn get_fqn(&self) -> &String {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
fn get_method(&self, name: String, self_object: &DmAllocObject) -> Option<&DmFn> {
|
||||
self.methods.get(&name)
|
||||
}
|
||||
|
||||
fn get_property(&self, name: String, self_object: &DmAllocObject) -> Option<&DmProperty> {
|
||||
self.properties.get(&name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmProperty<'a> {
|
||||
pub name: String,
|
||||
pub data_offset: usize,
|
||||
pub dm_type: DmType<'a>
|
||||
}
|
||||
|
||||
impl PartialEq for DmProperty<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq)]
|
||||
pub struct DmField<'a> {
|
||||
name: String,
|
||||
dm_type: DmType<'a>,
|
||||
}
|
||||
|
||||
impl PartialEq for DmField<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
}
|
||||
}
|
18
src/vm/values.rs
Normal file
18
src/vm/values.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::vm::mem::DmAllocObject;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum DmValue {
|
||||
DmByte(u8),
|
||||
DmInt(i32),
|
||||
DmLong(i64),
|
||||
DmDouble(f64),
|
||||
DmBoolean(bool),
|
||||
DmPointer(*mut DmAllocObject),
|
||||
DmByteArray(Vec<u8>),
|
||||
DmIntArray(Vec<i32>),
|
||||
DmLongArray(Vec<i64>),
|
||||
DmDoubleArray(Vec<f64>),
|
||||
DmBooleanArray(Vec<bool>),
|
||||
DmPointerArray(Vec<*mut DmAllocObject>),
|
||||
DmUnit,
|
||||
}
|
Loading…
Reference in New Issue
Block a user