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