Compare commits
	
		
			2 Commits
		
	
	
		
			71ee49761e
			...
			1263d84802
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 1263d84802 | ||
|   | 94f496a63d | 
							
								
								
									
										270
									
								
								src/ast/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										270
									
								
								src/ast/mod.rs
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| use pest::{iterators::{Pair, Pairs}, Parser}; | ||||
| use crate::parser::{DeimosParser, Rule}; | ||||
| use pest::{iterators::Pair, Parser}; | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct CompilationUnit { | ||||
| @ -9,7 +9,7 @@ pub struct CompilationUnit { | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Fqn { | ||||
|     identifiers: Vec<Identifier> | ||||
|     identifiers: Vec<Identifier>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| @ -25,7 +25,7 @@ pub enum Declaration { | ||||
|         is_extern: bool, | ||||
|         is_public: bool, | ||||
|         type_declaration: TypeDeclaration, | ||||
|         impl_ctor: Option<ImplCtor> | ||||
|         impl_ctor: Option<ImplCtor>, | ||||
|     }, | ||||
|     Module { | ||||
|         identifier: Identifier, | ||||
| @ -37,92 +37,98 @@ pub enum Declaration { | ||||
|         identifier: Identifier, | ||||
|         is_extern: bool, | ||||
|         is_public: bool, | ||||
|         statement: Statement | ||||
|         parameters: Vec<Parameter>, | ||||
|         declared_type: Option<TypeUse>, | ||||
|         statement: Statement, | ||||
|     }, | ||||
|     Prop(Prop), | ||||
|     Field(Field) | ||||
|     Field(Field), | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct TypeDeclaration { | ||||
|     generics: Vec<GenericParameter>, | ||||
|     extends: Vec<Type>, | ||||
|     extends: Vec<TypeUse>, | ||||
|     declarations: Vec<Declaration>, | ||||
| } | ||||
| 
 | ||||
| impl TypeDeclaration { | ||||
|     pub fn new(generics: Vec<GenericParameter>, extends: Vec<Type>, declarations: Vec<Declaration>) -> TypeDeclaration { | ||||
|     pub fn new( | ||||
|         generics: Vec<GenericParameter>, | ||||
|         extends: Vec<TypeUse>, | ||||
|         declarations: Vec<Declaration>, | ||||
|     ) -> TypeDeclaration { | ||||
|         TypeDeclaration { | ||||
|             generics, | ||||
|             extends, | ||||
|             declarations | ||||
|             declarations, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Identifier { | ||||
|     name: String | ||||
|     name: String, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct GenericParameter { | ||||
|     identifier: Identifier, | ||||
|     bound: Option<GenericBound> | ||||
|     bound: Option<GenericBound>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum GenericBound { | ||||
|     Extends { | ||||
|         fqn: Fqn | ||||
|     }, | ||||
|     Super { | ||||
|         fqn: Fqn | ||||
|     } | ||||
|     Extends { fqn: Fqn }, | ||||
|     Super { fqn: Fqn }, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct GenericArgument { | ||||
|     fqn: Fqn | ||||
|     fqn: Fqn, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Type { | ||||
| pub struct TypeUse { | ||||
|     fqn: Fqn, | ||||
|     generics: Vec<GenericArgument> | ||||
|     generics: Vec<GenericArgument>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct ImplCtor { | ||||
|     args: Vec<ImplCtorArg> | ||||
|     args: Vec<ImplCtorArg>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct ImplCtorArg { | ||||
|     is_field: bool, | ||||
|     identifier: Identifier, | ||||
|     r#type: Option<Type> | ||||
|     r#type: Option<TypeUse>, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Prop { | ||||
|     identifier: Identifier, | ||||
|     r#type: Type | ||||
|     r#type: TypeUse, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Field { | ||||
|     identifier: Identifier, | ||||
|     r#type: Type | ||||
|     r#type: TypeUse, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub enum Statement { | ||||
|     BlockStatement { | ||||
|         statements: Vec<Statement> | ||||
|     }, | ||||
|     BlockStatement { statements: Vec<Statement> }, | ||||
|     CallStatement, | ||||
|     AssignmentStatement | ||||
|     AssignmentStatement, | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| pub struct Parameter { | ||||
|     identifier: Identifier, | ||||
|     declared_type: Option<TypeUse>, | ||||
| } | ||||
| 
 | ||||
| fn build_field(field_pair: Pair<Rule>) -> Declaration { | ||||
| @ -136,27 +142,27 @@ fn build_prop(prop_pair: Pair<Rule>) -> Declaration { | ||||
| fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair<Rule>) -> ImplCtorArg { | ||||
|     let mut is_field = false; | ||||
|     let mut identifier: Option<Identifier> = None; | ||||
|     let mut r#type: Option<Type> = None; | ||||
|     let mut r#type: Option<TypeUse> = None; | ||||
| 
 | ||||
|     for pair in impl_ctor_arg_pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::fld => { | ||||
|                 is_field = true; | ||||
|             }, | ||||
|             } | ||||
|             Rule::identifier => { | ||||
|                 identifier = Some(build_identifier(pair)); | ||||
|             }, | ||||
|             Rule::r#type => { | ||||
|                 r#type = Some(build_type(pair)); | ||||
|             }, | ||||
|             _ => panic!("Unexpected rule: {}", pair) | ||||
|             } | ||||
|             Rule::type_use => { | ||||
|                 r#type = Some(build_type_use(pair)); | ||||
|             } | ||||
|             _ => panic!("Unexpected rule: {}", pair), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ImplCtorArg { | ||||
|         is_field, | ||||
|         identifier: identifier.unwrap(), | ||||
|         r#type | ||||
|         r#type, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -169,30 +175,30 @@ fn build_impl_ctor(impl_ctor_pair: Pair<Rule>) -> ImplCtor { | ||||
|             Rule::impl_ctor_arg => { | ||||
|                 args.push(build_impl_ctor_arg(pair)); | ||||
|             } | ||||
|             _ => panic!("Unexpected rule: {}", pair) | ||||
|             _ => panic!("Unexpected rule: {}", pair), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ImplCtor { | ||||
|         args | ||||
|     } | ||||
|     ImplCtor { args } | ||||
| } | ||||
| 
 | ||||
| fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> GenericArgument { | ||||
|     let fqn_pair = generic_argument_pair.into_inner().next().unwrap(); | ||||
|     GenericArgument { | ||||
|         fqn: build_fqn(fqn_pair) | ||||
|         fqn: build_fqn(fqn_pair), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_generic_arguments_declaration(generic_arguments_declaration_pair: Pair<Rule>) -> Vec<GenericArgument> { | ||||
| fn build_generic_arguments_declaration( | ||||
|     generic_arguments_declaration_pair: Pair<Rule>, | ||||
| ) -> Vec<GenericArgument> { | ||||
|     let mut generic_arguments: Vec<GenericArgument> = vec![]; | ||||
|     for pair in generic_arguments_declaration_pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::generic_argument => { | ||||
|                 generic_arguments.push(build_generic_argument(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only generic_argument rules. Found: {}", pair) | ||||
|             _ => panic!("Expected only generic_argument rules. Found: {}", pair), | ||||
|         } | ||||
|     } | ||||
|     generic_arguments | ||||
| @ -206,7 +212,7 @@ fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParamet | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_type(type_pair: Pair<Rule>) -> Type { | ||||
| fn build_type_use(type_pair: Pair<Rule>) -> TypeUse { | ||||
|     let mut fqn: Option<Fqn> = None; | ||||
|     let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None; | ||||
| 
 | ||||
| @ -218,38 +224,43 @@ fn build_type(type_pair: Pair<Rule>) -> Type { | ||||
|             Rule::generic_arguments_declaration => { | ||||
|                 generic_arguments_declaration = Some(build_generic_arguments_declaration(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only fqn or generic_arguments_declaration rules. Found: {}", pair) | ||||
|             _ => panic!( | ||||
|                 "Expected only fqn or generic_arguments_declaration rules. Found: {}", | ||||
|                 pair | ||||
|             ), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Type { | ||||
|     TypeUse { | ||||
|         fqn: fqn.unwrap(), | ||||
|         generics: generic_arguments_declaration.unwrap_or(vec![]) | ||||
|         generics: generic_arguments_declaration.unwrap_or(vec![]), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_generic_parameters_declaration(generic_parameters_declaration_pair: Pair<Rule>) -> Vec<GenericParameter> { | ||||
| fn build_generic_parameters_declaration( | ||||
|     generic_parameters_declaration_pair: Pair<Rule>, | ||||
| ) -> Vec<GenericParameter> { | ||||
|     let mut parameters: Vec<GenericParameter> = vec![]; | ||||
|     for pair in generic_parameters_declaration_pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::generic_parameter => { | ||||
|                 parameters.push(build_generic_parameter(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only generic_parameter rule. Found: {}", pair) | ||||
|             _ => panic!("Expected only generic_parameter rule. Found: {}", pair), | ||||
|         } | ||||
|     } | ||||
|     parameters | ||||
| } | ||||
| 
 | ||||
| fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<Type> { | ||||
|     let mut extensions: Vec<Type> = vec![]; | ||||
| fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<TypeUse> { | ||||
|     let mut extensions: Vec<TypeUse> = vec![]; | ||||
| 
 | ||||
|     for pair in extends_list_pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::r#type => { | ||||
|                 extensions.push(build_type(pair)); | ||||
|             Rule::type_use => { | ||||
|                 extensions.push(build_type_use(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only type rule. Found: {}", pair) | ||||
|             _ => panic!("Expected only type rule. Found: {}", pair), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -259,7 +270,7 @@ fn build_extends_list(extends_list_pair: Pair<Rule>) -> Vec<Type> { | ||||
| fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) -> Declaration { | ||||
|     let mut identifier: Option<Identifier> = None; | ||||
|     let mut generic_parameters: Option<Vec<GenericParameter>> = None; | ||||
|     let mut extends: Option<Vec<Type>> = None; | ||||
|     let mut extends: Option<Vec<TypeUse>> = None; | ||||
|     let mut declarations: Vec<Declaration> = vec![]; | ||||
| 
 | ||||
|     for pair in interface_pair.into_inner() { | ||||
| @ -290,36 +301,40 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair<Rule>) | ||||
|         type_declaration: TypeDeclaration::new( | ||||
|             generic_parameters.unwrap_or(vec![]), | ||||
|             extends.unwrap_or(vec![]), | ||||
|             declarations | ||||
|         ) | ||||
|             declarations, | ||||
|         ), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: Pair<Rule>) -> Declaration { | ||||
| fn build_implementation( | ||||
|     is_extern: bool, | ||||
|     is_public: bool, | ||||
|     implementation_pair: Pair<Rule>, | ||||
| ) -> Declaration { | ||||
|     let mut identifier: Option<Identifier> = None; | ||||
|     let mut generic_parameters: Option<Vec<GenericParameter>> = None; | ||||
|     let mut impl_ctor: Option<ImplCtor> = None; | ||||
|     let mut extends: Option<Vec<Type>> = None; | ||||
|     let mut extends: Option<Vec<TypeUse>> = None; | ||||
|     let mut declarations: Vec<Declaration> = vec![]; | ||||
| 
 | ||||
|     for pair in implementation_pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::identifier => { | ||||
|                 identifier = Some(build_identifier(pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::generic_parameters_declaration => { | ||||
|                 generic_parameters = Some(build_generic_parameters_declaration(pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::impl_ctor => { | ||||
|                 impl_ctor = Some(build_impl_ctor(pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::extends_list => { | ||||
|                 extends = Some(build_extends_list(pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::declaration => { | ||||
|                 declarations.push(build_declaration(pair)); | ||||
|             } | ||||
|             _ => panic!("Unexpected rule: {}", pair) | ||||
|             _ => panic!("Unexpected rule: {}", pair), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -330,9 +345,9 @@ fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: P | ||||
|         type_declaration: TypeDeclaration::new( | ||||
|             generic_parameters.unwrap_or(vec![]), | ||||
|             extends.unwrap_or(vec![]), | ||||
|             declarations | ||||
|             declarations, | ||||
|         ), | ||||
|         impl_ctor | ||||
|         impl_ctor, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -340,10 +355,88 @@ fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declarati | ||||
|     todo!() | ||||
| } | ||||
| 
 | ||||
| fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration { | ||||
| fn build_parameter(pair: Pair<Rule>) -> Parameter { | ||||
|     let mut identifier: Option<Identifier> = None; | ||||
|     let mut declared_type: Option<TypeUse> = None; | ||||
|     for pair in pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::identifier => { | ||||
|                 identifier = Some(build_identifier(pair)); | ||||
|             } | ||||
|             Rule::type_use => { | ||||
|                 declared_type = Some(build_type_use(pair)); | ||||
|             } | ||||
|             _ => unreachable!(), | ||||
|         } | ||||
|     } | ||||
|     Parameter { | ||||
|         identifier: identifier.unwrap(), | ||||
|         declared_type, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_parameters_list(pair: Pair<Rule>) -> Vec<Parameter> { | ||||
|     let mut parameters: Vec<Parameter> = vec![]; | ||||
|     for pair in pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::parameter => { | ||||
|                 parameters.push(build_parameter(pair)); | ||||
|             } | ||||
|             _ => unreachable!(), | ||||
|         } | ||||
|     } | ||||
|     parameters | ||||
| } | ||||
| 
 | ||||
| fn build_function_body(pair: Pair<Rule>) -> Statement { | ||||
|     todo!() | ||||
| } | ||||
| 
 | ||||
| fn build_function_equals_body(pair: Pair<Rule>) -> Statement { | ||||
|     todo!() | ||||
| } | ||||
| 
 | ||||
| fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration { | ||||
|     let mut generic_parameters: Option<Vec<GenericParameter>> = None; | ||||
|     let mut identifier: Option<Identifier> = None; | ||||
|     let mut parameters: Option<Vec<Parameter>> = None; | ||||
|     let mut return_type: Option<TypeUse> = None; | ||||
|     let mut statement: Option<Statement> = None; | ||||
| 
 | ||||
|     for pair in pair.into_inner() { | ||||
|         match pair.as_rule() { | ||||
|             Rule::generic_parameters_declaration => { | ||||
|                 generic_parameters = Some(build_generic_parameters_declaration(pair)); | ||||
|             } | ||||
|             Rule::identifier => { | ||||
|                 identifier = Some(build_identifier(pair)); | ||||
|             } | ||||
|             Rule::parameters_list => { | ||||
|                 parameters = Some(build_parameters_list(pair)); | ||||
|             } | ||||
|             Rule::type_use => { | ||||
|                 return_type = Some(build_type_use(pair)); | ||||
|             } | ||||
|             Rule::function_body => { | ||||
|                 statement = Some(build_function_body(pair)); | ||||
|             } | ||||
|             Rule::function_equals_body => { | ||||
|                 statement = Some(build_function_equals_body(pair)); | ||||
|             } | ||||
|             _ => unreachable!(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Declaration::Function { | ||||
|         is_extern, | ||||
|         is_public, | ||||
|         identifier: identifier.unwrap(), | ||||
|         parameters: parameters.unwrap(), | ||||
|         declared_type: return_type, | ||||
|         statement: statement.unwrap(), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration { | ||||
|     let mut is_extern = false; | ||||
|     let mut is_public = false; | ||||
| @ -353,29 +446,32 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration { | ||||
|         match pair.as_rule() { | ||||
|             Rule::r#extern => { | ||||
|                 is_extern = true; | ||||
|             }, | ||||
|             } | ||||
|             Rule::r#pub => { | ||||
|                 is_public = true; | ||||
|             } | ||||
|             Rule::interface => { | ||||
|                 declaration = Some(build_interface(is_extern, is_public, pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::implementation => { | ||||
|                 declaration = Some(build_implementation(is_extern, is_public, pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::module => { | ||||
|                 declaration = Some(build_module(is_extern, is_public, pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::function => { | ||||
|                 declaration = Some(build_function(is_extern, is_public, pair)); | ||||
|             }, | ||||
|             } | ||||
|             Rule::prop => { | ||||
|                 declaration = Some(build_prop(pair)); | ||||
|             } | ||||
|             Rule::field => { | ||||
|                 declaration = Some(build_field(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only interface, implementation, module, or function rules; found {}", pair) | ||||
|             _ => panic!( | ||||
|                 "Expected only interface, implementation, module, or function rules; found {}", | ||||
|                 pair | ||||
|             ), | ||||
|         } | ||||
|     } | ||||
|     declaration.expect("Expected declaration.") | ||||
| @ -383,12 +479,10 @@ fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration { | ||||
| 
 | ||||
| fn build_identifier(pair: Pair<Rule>) -> Identifier { | ||||
|     match pair.as_rule() { | ||||
|         Rule::identifier => { | ||||
|             Identifier { | ||||
|                 name: String::from(pair.as_str()) | ||||
|             } | ||||
|         } | ||||
|         _ => panic!("Expected an identifier.") | ||||
|         Rule::identifier => Identifier { | ||||
|             name: String::from(pair.as_str()), | ||||
|         }, | ||||
|         _ => panic!("Expected an identifier."), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -399,12 +493,10 @@ fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn { | ||||
|             Rule::identifier => { | ||||
|                 identifiers.push(build_identifier(pair)); | ||||
|             } | ||||
|             _ => panic!("Expected only identifiers.") | ||||
|             _ => panic!("Expected only identifiers."), | ||||
|         } | ||||
|     } | ||||
|     Fqn { | ||||
|         identifiers | ||||
|     } | ||||
|     Fqn { identifiers } | ||||
| } | ||||
| 
 | ||||
| fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit { | ||||
| @ -421,13 +513,16 @@ fn build_compilation_unit(pair: Pair<Rule>)-> CompilationUnit { | ||||
|                 declarations.push(build_declaration(pair)); | ||||
|             } | ||||
|             Rule::EOI => {} // ignore
 | ||||
|             _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) | ||||
|             _ => panic!( | ||||
|                 "Expected only namespace, declaration, or EOI rules, found: {}", | ||||
|                 pair | ||||
|             ), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     CompilationUnit { | ||||
|         namespace, | ||||
|         declarations | ||||
|         declarations, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -437,10 +532,7 @@ pub fn build_ast(src: &str) -> CompilationUnit { | ||||
|         .next() | ||||
|         .expect("Expcted compilation_unit."); | ||||
|     match pair.as_rule() { | ||||
|         Rule::compilation_unit => { | ||||
|             build_compilation_unit(pair) | ||||
|         }, | ||||
|         _ => panic!("Expected compilation_unit rule.") | ||||
|         Rule::compilation_unit => build_compilation_unit(pair), | ||||
|         _ => panic!("Expected compilation_unit rule."), | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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), | ||||
| @ -56,9 +59,15 @@ fn main() { | ||||
|         }, | ||||
|     ); | ||||
|     
 | ||||
|     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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -11,34 +11,34 @@ extern = { "extern" } | ||||
| pub = { "pub" } | ||||
| 
 | ||||
| interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } | ||||
| extends_list = { ":" ~ type ~ ( "+" ~ type )* } | ||||
| extends_list = { ":" ~ type_use ~ ( "+" ~ type_use )* } | ||||
| 
 | ||||
| implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } | ||||
| impl_ctor = { "(" ~ impl_ctor_args? ~ ")" } | ||||
| impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* } | ||||
| impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type )? } | ||||
| impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type_use )? } | ||||
| fld = { "fld" } | ||||
| 
 | ||||
| module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" } | ||||
| 
 | ||||
| property = { identifier ~ ( ":" ~ type )? } | ||||
| property = { identifier ~ ( ":" ~ type_use )? } | ||||
| 
 | ||||
| function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } | ||||
| function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ parameters_list? ~ ")" ~ ( ":" ~ type_use )? ~ ( function_body | function_equals_body ) } | ||||
| function_equals_body = { "=" ~ expression } | ||||
| function_body = { "{" ~ statement* ~ "}" } | ||||
| 
 | ||||
| type = { fqn ~ generic_arguments_declaration? } | ||||
| type_use = { fqn ~ generic_arguments_declaration? } | ||||
| generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" } | ||||
| generic_parameter = { identifier } | ||||
| 
 | ||||
| generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" } | ||||
| generic_argument = { fqn } | ||||
| 
 | ||||
| args_list = { arg ~ ( "," ~ arg )* } | ||||
| arg = { identifier ~ ( ":" ~ "..."? ~ type )? } | ||||
| parameters_list = { parameter ~ ( "," ~ parameter )* } | ||||
| parameter = { identifier ~ ( ":" ~ "..."? ~ type_use )? } | ||||
| 
 | ||||
| prop = { identifier ~ ":" ~ type } | ||||
| field = { fld ~ identifier ~ ":" ~ type } | ||||
| prop = { identifier ~ ":" ~ type_use } | ||||
| field = { fld ~ identifier ~ ":" ~ type_use } | ||||
| 
 | ||||
| statement = { call_stmt } | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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