Sketch DvmObjectFile type and related functions.
This commit is contained in:
parent
71ee49761e
commit
94f496a63d
@ -1,3 +1,4 @@
|
|||||||
|
use deimos::object_file::{DvmObjectFile, DvmPath};
|
||||||
use deimos::vm::constant::DvmConstant;
|
use deimos::vm::constant::DvmConstant;
|
||||||
use deimos::vm::function::DvmFunction;
|
use deimos::vm::function::DvmFunction;
|
||||||
use deimos::vm::instruction::{Immediate, Instruction, Location};
|
use deimos::vm::instruction::{Immediate, Instruction, Location};
|
||||||
@ -16,6 +17,8 @@ fn main() {
|
|||||||
// fn main() {
|
// fn main() {
|
||||||
// println "Hello, World!"
|
// println "Hello, World!"
|
||||||
// }
|
// }
|
||||||
|
let mut greeter_object_file = DvmObjectFile::new(DvmPath::new("greeter", "greeter.dmo"));
|
||||||
|
|
||||||
let main_instructions = vec![
|
let main_instructions = vec![
|
||||||
Instruction::MoveImmediate {
|
Instruction::MoveImmediate {
|
||||||
destination: Location::Register(0),
|
destination: Location::Register(0),
|
||||||
@ -55,10 +58,16 @@ fn main() {
|
|||||||
char: 1,
|
char: 1,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
greeter_object_file.add_function(main_function);
|
||||||
|
|
||||||
let mut state = DvmState::new();
|
let mut state = DvmState::new();
|
||||||
let mut context = DvmContext::new(Rc::new(main_function));
|
let mut context = DvmContext::new("greeter::main");
|
||||||
context.add_platform_functions(get_std_lib_platform_functions());
|
context.add_platform_functions(get_std_lib_platform_functions());
|
||||||
|
greeter_object_file.load_to_context(&mut context, &|path| {
|
||||||
|
todo!()
|
||||||
|
});
|
||||||
|
|
||||||
let exit_code = run_main_function(&mut state, &context);
|
let exit_code = run_main_function(&mut state, &context);
|
||||||
|
|
||||||
dump_state(&state, "After main!");
|
dump_state(&state, "After main!");
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
#![allow(warnings)]
|
#![allow(warnings)]
|
||||||
mod compiler;
|
|
||||||
pub mod parser;
|
|
||||||
mod util;
|
|
||||||
pub mod vm;
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
|
pub mod compiler;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
|
pub mod object_file;
|
||||||
|
pub mod parser;
|
||||||
|
pub mod util;
|
||||||
|
pub mod vm;
|
||||||
|
76
src/object_file/mod.rs
Normal file
76
src/object_file/mod.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use crate::vm::function::DvmFunction;
|
||||||
|
use crate::vm::implementation::DvmImplementation;
|
||||||
|
use crate::vm::interface::DvmInterface;
|
||||||
|
use crate::vm::DvmContext;
|
||||||
|
|
||||||
|
pub struct DvmObjectFile {
|
||||||
|
path: DvmPath,
|
||||||
|
dependencies: Vec<DvmPath>,
|
||||||
|
interfaces: Vec<DvmInterface>,
|
||||||
|
implementations: Vec<DvmImplementation>,
|
||||||
|
functions: Vec<DvmFunction>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DvmPath {
|
||||||
|
base_fqn: String,
|
||||||
|
file_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DvmPath {
|
||||||
|
pub fn new(base_fqn: &str, file_name: &str) -> Self {
|
||||||
|
DvmPath {
|
||||||
|
base_fqn: base_fqn.to_string(),
|
||||||
|
file_name: file_name.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DvmObjectFile {
|
||||||
|
pub fn new(path: DvmPath) -> Self {
|
||||||
|
DvmObjectFile {
|
||||||
|
path,
|
||||||
|
dependencies: vec![],
|
||||||
|
interfaces: vec![],
|
||||||
|
implementations: vec![],
|
||||||
|
functions: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_function(&mut self, function: DvmFunction) {
|
||||||
|
self.functions.push(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_dependency(&mut self, path: DvmPath) {
|
||||||
|
self.dependencies.push(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_to_context(
|
||||||
|
self,
|
||||||
|
context: &mut DvmContext,
|
||||||
|
linker: &impl Fn(&DvmPath) -> DvmObjectFile,
|
||||||
|
) {
|
||||||
|
if context.is_object_file_loaded(&self.path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offload our own declarations
|
||||||
|
for interface in self.interfaces {
|
||||||
|
context.add_interface(interface);
|
||||||
|
}
|
||||||
|
for implementation in self.implementations {
|
||||||
|
context.add_implementation(implementation);
|
||||||
|
}
|
||||||
|
for function in self.functions {
|
||||||
|
context.add_static_function(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.mark_object_file_as_loaded(self.path);
|
||||||
|
|
||||||
|
// Recursively load dependencies
|
||||||
|
for dependency in &self.dependencies {
|
||||||
|
let dependency_object_file = linker(dependency);
|
||||||
|
dependency_object_file.load_to_context(context, linker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
use crate::vm::field::DvmField;
|
use crate::vm::field::DvmField;
|
||||||
use crate::vm::function::DvmFunction;
|
use crate::vm::function::DvmFunction;
|
||||||
use crate::vm::interface::DmInterface;
|
use crate::vm::interface::DvmInterface;
|
||||||
use crate::vm::method::DvmMethod;
|
use crate::vm::method::DvmMethod;
|
||||||
use crate::vm::object::DvmObject;
|
use crate::vm::object::DvmObject;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@ -10,7 +10,7 @@ use std::rc::Rc;
|
|||||||
#[derive(Debug, Eq)]
|
#[derive(Debug, Eq)]
|
||||||
pub struct DvmImplementation {
|
pub struct DvmImplementation {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
interface: Option<Rc<DmInterface>>,
|
interface: Option<Rc<DvmInterface>>,
|
||||||
static_functions: HashMap<String, Rc<DvmFunction>>,
|
static_functions: HashMap<String, Rc<DvmFunction>>,
|
||||||
methods: HashMap<String, Rc<DvmMethod>>,
|
methods: HashMap<String, Rc<DvmMethod>>,
|
||||||
fields: HashMap<String, Rc<DvmField>>,
|
fields: HashMap<String, Rc<DvmField>>,
|
||||||
@ -23,7 +23,7 @@ impl PartialEq for DvmImplementation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DvmImplementation {
|
impl DvmImplementation {
|
||||||
pub fn new(fqn: &str, interface: Option<Rc<DmInterface>>) -> Self {
|
pub fn new(fqn: &str, interface: Option<Rc<DvmInterface>>) -> Self {
|
||||||
DvmImplementation {
|
DvmImplementation {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
interface,
|
interface,
|
||||||
@ -59,7 +59,7 @@ impl DvmImplementation {
|
|||||||
pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DvmField>> {
|
pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DvmField>> {
|
||||||
self.fields.get(name).cloned()
|
self.fields.get(name).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field_count(&self) -> usize {
|
pub fn field_count(&self) -> usize {
|
||||||
self.fields.len()
|
self.fields.len()
|
||||||
}
|
}
|
||||||
|
@ -3,21 +3,21 @@ use crate::vm::virtual_method::DmVirtualMethod;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Eq)]
|
#[derive(Debug, Eq)]
|
||||||
pub struct DmInterface {
|
pub struct DvmInterface {
|
||||||
fqn: String,
|
fqn: String,
|
||||||
static_functions: Vec<Rc<DvmFunction>>,
|
static_functions: Vec<Rc<DvmFunction>>,
|
||||||
virtual_methods: Vec<DmVirtualMethod>,
|
virtual_methods: Vec<DmVirtualMethod>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for DmInterface {
|
impl PartialEq for DvmInterface {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.fqn == other.fqn
|
self.fqn == other.fqn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DmInterface {
|
impl DvmInterface {
|
||||||
pub fn new(fqn: &str) -> Self {
|
pub fn new(fqn: &str) -> Self {
|
||||||
DmInterface {
|
DvmInterface {
|
||||||
fqn: fqn.to_string(),
|
fqn: fqn.to_string(),
|
||||||
static_functions: Vec::new(),
|
static_functions: Vec::new(),
|
||||||
virtual_methods: Vec::new(),
|
virtual_methods: Vec::new(),
|
||||||
|
@ -5,13 +5,13 @@ mod write;
|
|||||||
|
|
||||||
use crate::vm::function::DvmFunction;
|
use crate::vm::function::DvmFunction;
|
||||||
use crate::vm::implementation::DvmImplementation;
|
use crate::vm::implementation::DvmImplementation;
|
||||||
use crate::vm::interface::DmInterface;
|
use crate::vm::interface::DvmInterface;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct DmLib {
|
pub struct DmLib {
|
||||||
name: String,
|
name: String,
|
||||||
constants: Vec<DmConstant>,
|
constants: Vec<DmConstant>,
|
||||||
interfaces: Vec<Rc<DmInterface>>,
|
interfaces: Vec<Rc<DvmInterface>>,
|
||||||
implementations: Vec<Rc<DvmImplementation>>,
|
implementations: Vec<Rc<DvmImplementation>>,
|
||||||
functions: Vec<Rc<DvmFunction>>,
|
functions: Vec<Rc<DvmFunction>>,
|
||||||
}
|
}
|
||||||
@ -39,11 +39,11 @@ impl DmLib {
|
|||||||
self.constants.push(constant);
|
self.constants.push(constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interfaces(&self) -> &Vec<Rc<DmInterface>> {
|
pub fn interfaces(&self) -> &Vec<Rc<DvmInterface>> {
|
||||||
&self.interfaces
|
&self.interfaces
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_interface(&mut self, interface: DmInterface) {
|
pub fn add_interface(&mut self, interface: DvmInterface) {
|
||||||
self.interfaces.push(Rc::new(interface));
|
self.interfaces.push(Rc::new(interface));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
mod array;
|
pub mod array;
|
||||||
pub mod constant;
|
pub mod constant;
|
||||||
mod field;
|
pub mod field;
|
||||||
pub mod function;
|
pub mod function;
|
||||||
pub mod implementation;
|
pub mod implementation;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
mod interface;
|
pub mod interface;
|
||||||
pub mod lib;
|
pub mod lib;
|
||||||
mod method;
|
pub mod method;
|
||||||
pub mod object;
|
pub mod object;
|
||||||
pub mod op_codes;
|
pub mod op_codes;
|
||||||
pub mod platform;
|
pub mod platform;
|
||||||
@ -14,12 +14,14 @@ pub mod source_code_location;
|
|||||||
pub mod r#type;
|
pub mod r#type;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
mod virtual_method;
|
pub mod virtual_method;
|
||||||
|
|
||||||
|
use crate::object_file::DvmPath;
|
||||||
use crate::vm::array::DvmArray;
|
use crate::vm::array::DvmArray;
|
||||||
use crate::vm::constant::{DvmConstant, DvmConstantArray};
|
use crate::vm::constant::{DvmConstant, DvmConstantArray};
|
||||||
use crate::vm::implementation::DvmImplementation;
|
use crate::vm::implementation::DvmImplementation;
|
||||||
use crate::vm::instruction::{Immediate, Instruction, Location};
|
use crate::vm::instruction::{Immediate, Instruction, Location};
|
||||||
|
use crate::vm::interface::DvmInterface;
|
||||||
use crate::vm::object::DvmObject;
|
use crate::vm::object::DvmObject;
|
||||||
use crate::vm::value::DvmValue;
|
use crate::vm::value::DvmValue;
|
||||||
use function::DvmFunction;
|
use function::DvmFunction;
|
||||||
@ -95,19 +97,23 @@ impl DvmState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct DvmContext {
|
pub struct DvmContext {
|
||||||
main_function: Rc<DvmFunction>,
|
main_function: String,
|
||||||
|
interfaces: HashMap<String, Rc<DvmInterface>>,
|
||||||
implementations: HashMap<String, Rc<DvmImplementation>>,
|
implementations: HashMap<String, Rc<DvmImplementation>>,
|
||||||
static_functions: HashMap<String, Rc<DvmFunction>>,
|
static_functions: HashMap<String, Rc<DvmFunction>>,
|
||||||
platform_functions: HashMap<String, PlatformFunction>,
|
platform_functions: HashMap<String, PlatformFunction>,
|
||||||
|
loaded_object_files: Vec<DvmPath>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DvmContext {
|
impl DvmContext {
|
||||||
pub fn new(main_function: Rc<DvmFunction>) -> Self {
|
pub fn new(main_function: &str) -> Self {
|
||||||
DvmContext {
|
DvmContext {
|
||||||
main_function,
|
main_function: main_function.to_string(),
|
||||||
|
interfaces: HashMap::new(),
|
||||||
implementations: HashMap::new(),
|
implementations: HashMap::new(),
|
||||||
static_functions: HashMap::new(),
|
static_functions: HashMap::new(),
|
||||||
platform_functions: HashMap::new(),
|
platform_functions: HashMap::new(),
|
||||||
|
loaded_object_files: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +125,29 @@ impl DvmContext {
|
|||||||
self.platform_functions.insert(fqn, platform_function);
|
self.platform_functions.insert(fqn, platform_function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_object_file_loaded(&self, path: &DvmPath) -> bool {
|
||||||
|
self.loaded_object_files.contains(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_interface(&mut self, interface: DvmInterface) {
|
||||||
|
self.interfaces
|
||||||
|
.insert(interface.fqn().to_string(), Rc::new(interface));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_implementation(&mut self, implementation: DvmImplementation) {
|
||||||
|
self.implementations
|
||||||
|
.insert(implementation.fqn().to_string(), Rc::new(implementation));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_static_function(&mut self, function: DvmFunction) {
|
||||||
|
self.static_functions
|
||||||
|
.insert(function.fqn().to_string(), Rc::new(function));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mark_object_file_as_loaded(&mut self, path: DvmPath) {
|
||||||
|
self.loaded_object_files.push(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DvmCall {
|
pub struct DvmCall {
|
||||||
@ -281,7 +310,8 @@ fn immediate_to_value(immediate: &Immediate) -> DvmValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_main_function(state: &mut DvmState, context: &DvmContext) -> i32 {
|
pub fn run_main_function(state: &mut DvmState, context: &DvmContext) -> i32 {
|
||||||
let main_function = context.main_function.clone();
|
let main_function = context.static_functions.get(&context.main_function)
|
||||||
|
.expect(&format!("No such main function: {}", context.main_function));
|
||||||
push_call_frame(
|
push_call_frame(
|
||||||
Rc::new(main_function.fqn().to_string()),
|
Rc::new(main_function.fqn().to_string()),
|
||||||
main_function.source_code_location().clone(),
|
main_function.source_code_location().clone(),
|
||||||
|
Loading…
Reference in New Issue
Block a user