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::function::DvmFunction; | ||||
| use deimos::vm::instruction::{Immediate, Instruction, Location}; | ||||
| @ -16,6 +17,8 @@ fn main() { | ||||
|     // fn main() {
 | ||||
|     //     println "Hello, World!"
 | ||||
|     // }
 | ||||
|     let mut greeter_object_file = DvmObjectFile::new(DvmPath::new("greeter", "greeter.dmo")); | ||||
|     
 | ||||
|     let main_instructions = vec![ | ||||
|         Instruction::MoveImmediate { | ||||
|             destination: Location::Register(0), | ||||
| @ -55,10 +58,16 @@ fn main() { | ||||
|             char: 1, | ||||
|         }, | ||||
|     ); | ||||
|     
 | ||||
|     greeter_object_file.add_function(main_function); | ||||
| 
 | ||||
|     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()); | ||||
|     greeter_object_file.load_to_context(&mut context, &|path| { | ||||
|         todo!() | ||||
|     }); | ||||
|     
 | ||||
|     let exit_code = run_main_function(&mut state, &context); | ||||
| 
 | ||||
|     dump_state(&state, "After main!"); | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| #![allow(warnings)] | ||||
| mod compiler; | ||||
| pub mod parser; | ||||
| mod util; | ||||
| pub mod vm; | ||||
| pub mod ast; | ||||
| pub mod compiler; | ||||
| 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::function::DvmFunction; | ||||
| use crate::vm::interface::DmInterface; | ||||
| use crate::vm::interface::DvmInterface; | ||||
| use crate::vm::method::DvmMethod; | ||||
| use crate::vm::object::DvmObject; | ||||
| use std::collections::HashMap; | ||||
| @ -10,7 +10,7 @@ use std::rc::Rc; | ||||
| #[derive(Debug, Eq)] | ||||
| pub struct DvmImplementation { | ||||
|     fqn: String, | ||||
|     interface: Option<Rc<DmInterface>>, | ||||
|     interface: Option<Rc<DvmInterface>>, | ||||
|     static_functions: HashMap<String, Rc<DvmFunction>>, | ||||
|     methods: HashMap<String, Rc<DvmMethod>>, | ||||
|     fields: HashMap<String, Rc<DvmField>>, | ||||
| @ -23,7 +23,7 @@ impl PartialEq for DvmImplementation { | ||||
| } | ||||
| 
 | ||||
| impl DvmImplementation { | ||||
|     pub fn new(fqn: &str, interface: Option<Rc<DmInterface>>) -> Self { | ||||
|     pub fn new(fqn: &str, interface: Option<Rc<DvmInterface>>) -> Self { | ||||
|         DvmImplementation { | ||||
|             fqn: fqn.to_string(), | ||||
|             interface, | ||||
| @ -59,7 +59,7 @@ impl DvmImplementation { | ||||
|     pub fn find_field(&self, name: &str, self_object: &DvmObject) -> Option<Rc<DvmField>> { | ||||
|         self.fields.get(name).cloned() | ||||
|     } | ||||
|     
 | ||||
| 
 | ||||
|     pub fn field_count(&self) -> usize { | ||||
|         self.fields.len() | ||||
|     } | ||||
|  | ||||
| @ -3,21 +3,21 @@ use crate::vm::virtual_method::DmVirtualMethod; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| #[derive(Debug, Eq)] | ||||
| pub struct DmInterface { | ||||
| pub struct DvmInterface { | ||||
|     fqn: String, | ||||
|     static_functions: Vec<Rc<DvmFunction>>, | ||||
|     virtual_methods: Vec<DmVirtualMethod>, | ||||
| } | ||||
| 
 | ||||
| impl PartialEq for DmInterface { | ||||
| impl PartialEq for DvmInterface { | ||||
|     fn eq(&self, other: &Self) -> bool { | ||||
|         self.fqn == other.fqn | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl DmInterface { | ||||
| impl DvmInterface { | ||||
|     pub fn new(fqn: &str) -> Self { | ||||
|         DmInterface { | ||||
|         DvmInterface { | ||||
|             fqn: fqn.to_string(), | ||||
|             static_functions: Vec::new(), | ||||
|             virtual_methods: Vec::new(), | ||||
|  | ||||
| @ -5,13 +5,13 @@ mod write; | ||||
| 
 | ||||
| use crate::vm::function::DvmFunction; | ||||
| use crate::vm::implementation::DvmImplementation; | ||||
| use crate::vm::interface::DmInterface; | ||||
| use crate::vm::interface::DvmInterface; | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| pub struct DmLib { | ||||
|     name: String, | ||||
|     constants: Vec<DmConstant>, | ||||
|     interfaces: Vec<Rc<DmInterface>>, | ||||
|     interfaces: Vec<Rc<DvmInterface>>, | ||||
|     implementations: Vec<Rc<DvmImplementation>>, | ||||
|     functions: Vec<Rc<DvmFunction>>, | ||||
| } | ||||
| @ -39,11 +39,11 @@ impl DmLib { | ||||
|         self.constants.push(constant); | ||||
|     } | ||||
| 
 | ||||
|     pub fn interfaces(&self) -> &Vec<Rc<DmInterface>> { | ||||
|     pub fn interfaces(&self) -> &Vec<Rc<DvmInterface>> { | ||||
|         &self.interfaces | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_interface(&mut self, interface: DmInterface) { | ||||
|     pub fn add_interface(&mut self, interface: DvmInterface) { | ||||
|         self.interfaces.push(Rc::new(interface)); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| mod array; | ||||
| pub mod array; | ||||
| pub mod constant; | ||||
| mod field; | ||||
| pub mod field; | ||||
| pub mod function; | ||||
| pub mod implementation; | ||||
| pub mod instruction; | ||||
| mod interface; | ||||
| pub mod interface; | ||||
| pub mod lib; | ||||
| mod method; | ||||
| pub mod method; | ||||
| pub mod object; | ||||
| pub mod op_codes; | ||||
| pub mod platform; | ||||
| @ -14,12 +14,14 @@ pub mod source_code_location; | ||||
| pub mod r#type; | ||||
| pub mod util; | ||||
| pub mod value; | ||||
| mod virtual_method; | ||||
| pub mod virtual_method; | ||||
| 
 | ||||
| use crate::object_file::DvmPath; | ||||
| use crate::vm::array::DvmArray; | ||||
| use crate::vm::constant::{DvmConstant, DvmConstantArray}; | ||||
| use crate::vm::implementation::DvmImplementation; | ||||
| use crate::vm::instruction::{Immediate, Instruction, Location}; | ||||
| use crate::vm::interface::DvmInterface; | ||||
| use crate::vm::object::DvmObject; | ||||
| use crate::vm::value::DvmValue; | ||||
| use function::DvmFunction; | ||||
| @ -95,19 +97,23 @@ impl DvmState { | ||||
| } | ||||
| 
 | ||||
| pub struct DvmContext { | ||||
|     main_function: Rc<DvmFunction>, | ||||
|     main_function: String, | ||||
|     interfaces: HashMap<String, Rc<DvmInterface>>, | ||||
|     implementations: HashMap<String, Rc<DvmImplementation>>, | ||||
|     static_functions: HashMap<String, Rc<DvmFunction>>, | ||||
|     platform_functions: HashMap<String, PlatformFunction>, | ||||
|     loaded_object_files: Vec<DvmPath>, | ||||
| } | ||||
| 
 | ||||
| impl DvmContext { | ||||
|     pub fn new(main_function: Rc<DvmFunction>) -> Self { | ||||
|     pub fn new(main_function: &str) -> Self { | ||||
|         DvmContext { | ||||
|             main_function, | ||||
|             main_function: main_function.to_string(), | ||||
|             interfaces: HashMap::new(), | ||||
|             implementations: HashMap::new(), | ||||
|             static_functions: HashMap::new(), | ||||
|             platform_functions: HashMap::new(), | ||||
|             loaded_object_files: vec![], | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -119,6 +125,29 @@ impl DvmContext { | ||||
|             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 { | ||||
| @ -281,7 +310,8 @@ fn immediate_to_value(immediate: &Immediate) -> DvmValue { | ||||
| } | ||||
| 
 | ||||
| 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( | ||||
|         Rc::new(main_function.fqn().to_string()), | ||||
|         main_function.source_code_location().clone(), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jesse Brault
						Jesse Brault