Compare commits
	
		
			3 Commits
		
	
	
		
			68de104595
			...
			82af6b4dfb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 82af6b4dfb | ||
|   | e8aff842ed | ||
|   | 1a365481ab | 
							
								
								
									
										16
									
								
								sketching/april_2025/closure_inputs.dm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								sketching/april_2025/closure_inputs.dm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | class Counter { | ||||||
|  |     fld count: Int | ||||||
|  | 
 | ||||||
|  |     mut getAndIncrement() -> Int { | ||||||
|  |         let result = count | ||||||
|  |         count++ | ||||||
|  |         result | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Synthetic | ||||||
|  | class MyClosure(delegate: Counter) : MutClosure(Int, Int) -> Int |delegate| { | ||||||
|  |     mut fn call(x: Int, y: Int) -> Int { | ||||||
|  |         x + y + delegate.getAndIncrement() | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								sketching/april_2025/iterator.dm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								sketching/april_2025/iterator.dm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | pub type Iterator<T> |backing: &Any| = mut fn () -> Option<&T ref backing> | ||||||
|  | 
 | ||||||
|  | pub int Iterable<T> { | ||||||
|  |     ref fn iterator() -> Iterator<T>(&self) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn main() { | ||||||
|  |     let nums: List<Int> = [1, 2, 3] | ||||||
|  |     let iterator: Iterator<Int> |backing = nums| = nums.iterator() | ||||||
|  |     let first: &Int ref nums = iterator().unwrap() | ||||||
|  |     let second: &Int ref nums = iterator().unwrap() | ||||||
|  |     let third: &Int ref nums = iterator().unwrap() | ||||||
|  |     println "${*first}, ${*second}, ${*third}" | ||||||
|  | } | ||||||
							
								
								
									
										530
									
								
								src/ast/build.rs
									
									
									
									
									
								
							
							
						
						
									
										530
									
								
								src/ast/build.rs
									
									
									
									
									
								
							| @ -1,374 +1,208 @@ | |||||||
| use crate::ast::{ | use crate::ast::{CompilationUnit, DelegateOrIdentifier, Fqn, FunctionModifier, FunctionTypeUse, GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument, InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType, TupleTypeUse, TypeUse, VoidOrTypeUse}; | ||||||
|     BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument, | use crate::parser::Rule; | ||||||
|     GenericParameter, Identifier, ClassConstructor, Parameter, TypeDeclaration, TypeUse, |  | ||||||
| }; |  | ||||||
| use crate::parser::{DeimosParser, Rule}; |  | ||||||
| use crate::vm::source_code_location::SourceCodeLocation; |  | ||||||
| use pest::iterators::Pair; | use pest::iterators::Pair; | ||||||
| use pest::Parser; |  | ||||||
| 
 | 
 | ||||||
| fn build_field(field_pair: Pair<Rule>) -> Declaration { | fn expect_and_use<T>(pair: Pair<Rule>, rule: Rule, f: fn(Pair<Rule>) -> T) -> T { | ||||||
|  |     if pair.as_rule() != rule { | ||||||
|  |         panic!("Expected rule {:?} but found {:?}", rule, pair.as_rule()) | ||||||
|  |     } | ||||||
|  |     f(pair) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn build_ast(compilation_unit_pair: Pair<Rule>) -> CompilationUnit { | ||||||
|     todo!() |     todo!() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn build_prop(prop_pair: Pair<Rule>) -> Declaration { | fn build_identifier(identifier_pair: Pair<Rule>) -> Identifier { | ||||||
|     todo!() |     Identifier { | ||||||
| } |         name: identifier_pair.as_str().to_string(), | ||||||
| 
 |  | ||||||
| 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), |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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::GenericArguments => { |  | ||||||
|                 generic_arguments.push(build_generic_argument(pair)); |  | ||||||
|             } |  | ||||||
|             _ => panic!("Expected only generic_argument rules. Found: {}", pair), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     generic_arguments |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_generic_parameter(generic_parameter_pair: Pair<Rule>) -> GenericParameter { |  | ||||||
|     let identifier_pair = generic_parameter_pair.into_inner().next().unwrap(); |  | ||||||
|     GenericParameter { |  | ||||||
|         identifier: build_identifier(identifier_pair), |  | ||||||
|         bound: None, |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_type_use(type_pair: Pair<Rule>) -> TypeUse { |  | ||||||
|     let mut fqn: Option<Fqn> = None; |  | ||||||
|     let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = None; |  | ||||||
| 
 |  | ||||||
|     for pair in type_pair.into_inner() { |  | ||||||
|         match pair.as_rule() { |  | ||||||
|             Rule::FullyQualifiedName => { |  | ||||||
|                 fqn = Some(build_fqn(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::GenericArguments => { |  | ||||||
|                 generic_arguments_declaration = Some(build_generic_arguments_declaration(pair)); |  | ||||||
|             } |  | ||||||
|             _ => panic!( |  | ||||||
|                 "Expected only fqn or generic_arguments_declaration rules. Found: {}", |  | ||||||
|                 pair |  | ||||||
|             ), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     TypeUse { |  | ||||||
|         fqn: fqn.unwrap(), |  | ||||||
|         generics: generic_arguments_declaration.unwrap_or(vec![]), |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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::Identifier => { |  | ||||||
|                 parameters.push(build_generic_parameter(pair)); |  | ||||||
|             } |  | ||||||
|             _ => panic!("Expected only generic_parameter rule. Found: {}", pair), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     parameters |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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::TypeUse => { |  | ||||||
|                 extensions.push(build_type_use(pair)); |  | ||||||
|             } |  | ||||||
|             _ => panic!("Expected only type rule. Found: {}", pair), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     extensions |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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<TypeUse>> = None; |  | ||||||
|     let mut declarations: Vec<Declaration> = vec![]; |  | ||||||
| 
 |  | ||||||
|     for pair in interface_pair.into_inner() { |  | ||||||
|         match pair.as_rule() { |  | ||||||
|             Rule::Identifier => { |  | ||||||
|                 identifier = Some(build_identifier(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::GenericParameters => { |  | ||||||
|                 generic_parameters = Some(build_generic_parameters_declaration(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::ExtendsList => { |  | ||||||
|                 extends = Some(build_extends_list(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::InterfaceLevelDeclaration => { |  | ||||||
|                 declarations.push(build_module_level_declaration(pair)); |  | ||||||
|             }, |  | ||||||
|             _ => panic!( |  | ||||||
|                 "Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}", |  | ||||||
|                 pair |  | ||||||
|             ) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Declaration::Interface { |  | ||||||
|         identifier: identifier.unwrap(), |  | ||||||
|         is_extern, |  | ||||||
|         is_public, |  | ||||||
|         type_declaration: TypeDeclaration::new( |  | ||||||
|             generic_parameters.unwrap_or(vec![]), |  | ||||||
|             extends.unwrap_or(vec![]), |  | ||||||
|             declarations, |  | ||||||
|         ), |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_class_constructor(class_constructor_pair: Pair<Rule>) -> ClassConstructor { |  | ||||||
|     todo!() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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<ClassConstructor> = 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::GenericParameters => { |  | ||||||
|                 generic_parameters = Some(build_generic_parameters_declaration(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::ClassConstructor => { |  | ||||||
|                 impl_ctor = Some(build_class_constructor(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::ExtendsList => { |  | ||||||
|                 extends = Some(build_extends_list(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::ClassLevelDeclaration => { |  | ||||||
|                 declarations.push(build_module_level_declaration(pair)); |  | ||||||
|             } |  | ||||||
|             _ => panic!("Unexpected rule: {}", pair), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Declaration::Implementation { |  | ||||||
|         identifier: identifier.unwrap(), |  | ||||||
|         is_extern, |  | ||||||
|         is_public, |  | ||||||
|         type_declaration: TypeDeclaration::new( |  | ||||||
|             generic_parameters.unwrap_or(vec![]), |  | ||||||
|             extends.unwrap_or(vec![]), |  | ||||||
|             declarations, |  | ||||||
|         ), |  | ||||||
|         impl_ctor, |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration { |  | ||||||
|     todo!() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 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::TypeAnnotation => { |  | ||||||
|                 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_block_statement(pair: Pair<Rule>) -> BlockStatement { |  | ||||||
|     todo!() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_function_equals_body(pair: Pair<Rule>) -> BlockStatement { |  | ||||||
|     todo!() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration { |  | ||||||
|     let mut is_implementation = false; |  | ||||||
|     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<BlockStatement> = None; |  | ||||||
| 
 |  | ||||||
|     let (line, col) = pair.line_col(); |  | ||||||
| 
 |  | ||||||
|     for pair in pair.into_inner() { |  | ||||||
|         match pair.as_rule() { |  | ||||||
|             Rule::Implementation => { |  | ||||||
|                 is_implementation = true; |  | ||||||
|             } |  | ||||||
|             Rule::Identifier => { |  | ||||||
|                 identifier = Some(build_identifier(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::GenericParameters => { |  | ||||||
|                 generic_parameters = Some(build_generic_parameters_declaration(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::Parameters => { |  | ||||||
|                 parameters = Some(build_parameters_list(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::TypeUse => { |  | ||||||
|                 return_type = Some(build_type_use(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::BlockStatement => { |  | ||||||
|                 statement = Some(build_block_statement(pair)); |  | ||||||
|             } |  | ||||||
|             Rule::FunctionEqualsBody => { |  | ||||||
|                 statement = Some(build_function_equals_body(pair)); |  | ||||||
|             } |  | ||||||
|             _ => unreachable!(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     Declaration::Function(FunctionDeclaration { |  | ||||||
|         is_extern, |  | ||||||
|         is_public, |  | ||||||
|         identifier: identifier.unwrap(), |  | ||||||
|         parameters: parameters.unwrap(), |  | ||||||
|         declared_type: return_type, |  | ||||||
|         block_statement: statement.unwrap(), |  | ||||||
|         source_code_location: SourceCodeLocation { |  | ||||||
|             source_file_name: "TODO".to_string(), |  | ||||||
|             line, |  | ||||||
|             col, |  | ||||||
|         }, |  | ||||||
|     }) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_module_level_declaration(declaration_pair: Pair<Rule>) -> Declaration { |  | ||||||
|     let mut is_extern = false; |  | ||||||
|     let mut is_public = false; |  | ||||||
|     let mut declaration: Option<Declaration> = None; |  | ||||||
| 
 |  | ||||||
|     for pair in declaration_pair.into_inner() { |  | ||||||
|         match pair.as_rule() { |  | ||||||
|             Rule::Declare => { |  | ||||||
|                 is_extern = true; |  | ||||||
|             } |  | ||||||
|             Rule::Public => { |  | ||||||
|                 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)); |  | ||||||
|             } |  | ||||||
|             _ => unreachable!(), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     declaration.expect("Expected declaration.") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_identifier(pair: Pair<Rule>) -> Identifier { |  | ||||||
|     match pair.as_rule() { |  | ||||||
|         Rule::Identifier => Identifier { |  | ||||||
|             name: String::from(pair.as_str()), |  | ||||||
|         }, |  | ||||||
|         _ => unreachable!(), |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn { | fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn { | ||||||
|     let mut identifiers: Vec<Identifier> = vec![]; |     let mut identifiers: Vec<Identifier> = vec![]; | ||||||
|     for pair in fqn_pair.into_inner() { |     for identifier_pair in fqn_pair.into_inner() { | ||||||
|         match pair.as_rule() { |         identifiers.push(expect_and_use( | ||||||
|             Rule::Identifier => { |             identifier_pair, | ||||||
|                 identifiers.push(build_identifier(pair)); |             Rule::Identifier, | ||||||
|             } |             build_identifier, | ||||||
|             _ => unreachable!(), |         )); | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|     Fqn { identifiers } |     Fqn { identifiers } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn build_compilation_unit(pair: Pair<Rule>) -> CompilationUnit { | fn build_type_use(type_use_pair: Pair<Rule>) -> TypeUse { | ||||||
|     let mut namespace: Option<Fqn> = None; |     let inner_pair = type_use_pair.into_inner().next().unwrap(); | ||||||
|     let mut declarations: Vec<Declaration> = vec![]; |     match inner_pair.as_rule() { | ||||||
|  |         Rule::InterfaceOrClassTypeUse => { | ||||||
|  |             TypeUse::InterfaceOrClass(build_interface_or_class_type_use(inner_pair)) | ||||||
|  |         } | ||||||
|  |         Rule::TupleTypeUse => TypeUse::Tuple(build_tuple_type_use(inner_pair)), | ||||||
|  |         Rule::FunctionTypeUse => TypeUse::Function(build_function_type_use(inner_pair)), | ||||||
|  |         _ => unreachable!(), | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     for pair in pair.into_inner() { | fn build_interface_or_class_type_use(pair: Pair<Rule>) -> InterfaceOrClassTypeUse { | ||||||
|         match pair.as_rule() { |     let mut inner = pair.into_inner(); | ||||||
|             Rule::Namespace => { |     let fqn = expect_and_use(inner.next().unwrap(), Rule::FullyQualifiedName, build_fqn); | ||||||
|                 let fqn_pair = pair.into_inner().next().unwrap(); | 
 | ||||||
|                 namespace = Some(build_fqn(fqn_pair)); |     let generics = inner | ||||||
|  |         .next() | ||||||
|  |         .map(|inner_pair| { | ||||||
|  |             expect_and_use(inner_pair, Rule::GenericArguments, build_generic_arguments) | ||||||
|  |         }) | ||||||
|  |         .unwrap_or(GenericArguments(vec![])); | ||||||
|  | 
 | ||||||
|  |     InterfaceOrClassTypeUse { fqn, generics } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_tuple_type_use(tuple_type_use_pair: Pair<Rule>) -> TupleTypeUse { | ||||||
|  |     TupleTypeUse( | ||||||
|  |         tuple_type_use_pair | ||||||
|  |             .into_inner() | ||||||
|  |             .map(|type_use_pair| expect_and_use(type_use_pair, Rule::TypeUse, build_type_use)) | ||||||
|  |             .collect(), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_function_type_use(function_pair: Pair<Rule>) -> FunctionTypeUse { | ||||||
|  |     let mut function_modifier: Option<FunctionModifier> = None; | ||||||
|  |     let mut generics: Option<GenericParameters> = None; | ||||||
|  |     let mut parameters: Option<TupleTypeUse> = None; | ||||||
|  |     let mut inputs: Option<InputArguments> = None; | ||||||
|  |     let mut return_type: Option<ReturnType> = None; | ||||||
|  | 
 | ||||||
|  |     for inner_pair in function_pair.into_inner() { | ||||||
|  |         match inner_pair.as_rule() { | ||||||
|  |             Rule::FunctionTypeModifier => { | ||||||
|  |                 function_modifier = Some(build_function_modifier(inner_pair)); | ||||||
|             } |             } | ||||||
|             Rule::ModuleLevelDeclaration => { |             Rule::Fn => {} | ||||||
|                 declarations.push(build_module_level_declaration(pair)); |             Rule::GenericParameters => { | ||||||
|  |                 generics = Some(build_generic_parameters(inner_pair)); | ||||||
|             } |             } | ||||||
|             Rule::EOI => {} // ignore
 |             Rule::TupleTypeUse => { | ||||||
|  |                 parameters = Some(build_tuple_type_use(inner_pair)); | ||||||
|  |             } | ||||||
|  |             Rule::FunctionInputArguments => { | ||||||
|  |                 inputs = Some(build_function_input_arguments(inner_pair)); | ||||||
|  |             } | ||||||
|  |             Rule::ReturnType => { | ||||||
|  |                 return_type = Some(build_return_type(inner_pair)); | ||||||
|  |             }, | ||||||
|             _ => unreachable!(), |             _ => unreachable!(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     CompilationUnit { |     FunctionTypeUse { | ||||||
|         namespace, |         function_modifier, | ||||||
|         declarations, |         generics: generics.unwrap_or(GenericParameters(vec![])), | ||||||
|  |         parameters: parameters.unwrap(), | ||||||
|  |         inputs: inputs.unwrap_or(InputArguments(vec![])), | ||||||
|  |         return_type: return_type.unwrap(), | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn build_ast(src: &str) -> CompilationUnit { | fn build_generic_arguments(generic_arguments_pair: Pair<Rule>) -> GenericArguments { | ||||||
|     let pair = DeimosParser::parse(Rule::CompilationUnit, src) |     let mut generic_arguments: Vec<GenericArgument> = vec![]; | ||||||
|         .expect("Unsuccessful parse.") |     for generic_argument_pair in generic_arguments_pair.into_inner() { | ||||||
|         .next() |         generic_arguments.push(expect_and_use( | ||||||
|         .expect("Expected compilation_unit."); |             generic_argument_pair, | ||||||
|     match pair.as_rule() { |             Rule::FullyQualifiedName, | ||||||
|         Rule::CompilationUnit => build_compilation_unit(pair), |             build_generic_argument, | ||||||
|         _ => panic!("Expected compilation_unit rule."), |         )); | ||||||
|  |     } | ||||||
|  |     GenericArguments(generic_arguments) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_generic_argument(fqn_pair: Pair<Rule>) -> GenericArgument { | ||||||
|  |     GenericArgument { | ||||||
|  |         fqn: build_fqn(fqn_pair), | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | fn build_function_modifier(function_modifier_pair: Pair<Rule>) -> FunctionModifier { | ||||||
|  |     let mut inner = function_modifier_pair.into_inner(); | ||||||
|  |     if inner.len() == 2 { | ||||||
|  |         FunctionModifier::MutRef | ||||||
|  |     } else { | ||||||
|  |         match inner.next().unwrap().as_rule() { | ||||||
|  |             Rule::Cons => FunctionModifier::Cons, | ||||||
|  |             Rule::Mut => FunctionModifier::Mut, | ||||||
|  |             Rule::Ref => FunctionModifier::Ref, | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_generic_parameters(generic_parameters_pair: Pair<Rule>) -> GenericParameters { | ||||||
|  |     GenericParameters( | ||||||
|  |         generic_parameters_pair | ||||||
|  |             .into_inner() | ||||||
|  |             .map(|identifier_pair| { | ||||||
|  |                 GenericParameter(expect_and_use( | ||||||
|  |                     identifier_pair, | ||||||
|  |                     Rule::Identifier, | ||||||
|  |                     build_identifier, | ||||||
|  |                 )) | ||||||
|  |             }) | ||||||
|  |             .collect(), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_function_input_arguments(pair: Pair<Rule>) -> InputArguments { | ||||||
|  |     InputArguments( | ||||||
|  |         pair.into_inner() | ||||||
|  |             .map(|function_input_argument_pair| { | ||||||
|  |                 let mut inner = function_input_argument_pair.into_inner(); | ||||||
|  |                 let lhs_pair = inner.next().unwrap(); | ||||||
|  |                 let lhs = match lhs_pair.as_rule() { | ||||||
|  |                     Rule::Delegate => DelegateOrIdentifier::Delegate, | ||||||
|  |                     Rule::Identifier => { | ||||||
|  |                         DelegateOrIdentifier::Identifier(build_identifier(lhs_pair)) | ||||||
|  |                     } | ||||||
|  |                     _ => unreachable!(), | ||||||
|  |                 }; | ||||||
|  |                 let rhs = build_identifier(inner.next().unwrap()); | ||||||
|  |                 InputArgument { lhs, rhs } | ||||||
|  |             }) | ||||||
|  |             .collect(), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_return_type(return_type_pair: Pair<Rule>) -> ReturnType { | ||||||
|  |     let mut inner = return_type_pair.into_inner(); | ||||||
|  |     
 | ||||||
|  |     let declared_type_pair = inner.next().unwrap(); | ||||||
|  |     let declared_type = match declared_type_pair.as_rule() { | ||||||
|  |         Rule::Void => VoidOrTypeUse::Void, | ||||||
|  |         Rule::TypeUse => VoidOrTypeUse::TypeUse(Box::new( | ||||||
|  |             build_type_use(declared_type_pair) | ||||||
|  |         )), | ||||||
|  |         _ => unreachable!(), | ||||||
|  |     }; | ||||||
|  |     
 | ||||||
|  |     let references = inner.next().map(|ref_list_pair| { | ||||||
|  |         expect_and_use(ref_list_pair, Rule::RefList, build_references) | ||||||
|  |     }).unwrap_or(References(vec![])); | ||||||
|  |     
 | ||||||
|  |     ReturnType { | ||||||
|  |         declared_type, | ||||||
|  |         references, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_references(ref_list_pair: Pair<Rule>) -> References { | ||||||
|  |     let mut identifiers: Vec<Identifier> = vec![]; | ||||||
|  |     for pair in ref_list_pair.into_inner() { | ||||||
|  |         match pair.as_rule() { | ||||||
|  |             Rule::Ref => {}, | ||||||
|  |             Rule::Identifier => { | ||||||
|  |                 identifiers.push(build_identifier(pair)); | ||||||
|  |             }, | ||||||
|  |             _ => unreachable!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     References(identifiers.into_iter().map(|identifier| Reference(identifier)).collect()) | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										647
									
								
								src/ast/mod.rs
									
									
									
									
									
								
							
							
						
						
									
										647
									
								
								src/ast/mod.rs
									
									
									
									
									
								
							| @ -1,256 +1,535 @@ | |||||||
| use crate::vm::source_code_location::SourceCodeLocation; |  | ||||||
| use pest::Parser; | use pest::Parser; | ||||||
| 
 | 
 | ||||||
| pub mod build; | pub mod build; | ||||||
|  | pub mod unparse; | ||||||
|  | 
 | ||||||
|  | // Operators
 | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct CompilationUnit { | pub enum Operator { | ||||||
|     namespace: Option<Fqn>, |     Binary(BinaryOperator), | ||||||
|     declarations: Vec<Declaration>, |     Unary(UnaryOperator), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl CompilationUnit { | #[derive(Debug)] | ||||||
|     pub fn namespace(&self) -> &Option<Fqn> { | pub enum BinaryOperator { | ||||||
|         &self.namespace |     Or, | ||||||
|     } |     And, | ||||||
|  |     EqualTo, | ||||||
|  |     NotEqualTo, | ||||||
|  |     Greater, | ||||||
|  |     Less, | ||||||
|  |     GreaterEqual, | ||||||
|  |     LessEqual, | ||||||
|  |     Add, | ||||||
|  |     Subtract, | ||||||
|  |     Multiply, | ||||||
|  |     Divide, | ||||||
|  |     Modulo, | ||||||
|  |     LeftShift, | ||||||
|  |     RightShift, | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     pub fn declarations(&self) -> &Vec<Declaration> { | #[derive(Debug)] | ||||||
|         &self.declarations | pub enum UnaryOperator { | ||||||
|     } |     Not, | ||||||
|  |     Negative, | ||||||
|  |     PlusPlus, | ||||||
|  |     MinusMinus, | ||||||
|  |     CallOp, | ||||||
|  |     Spread, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Names
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub struct Identifier { | ||||||
|  |     pub name: String, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Fqn { | pub struct Fqn { | ||||||
|     identifiers: Vec<Identifier>, |     pub identifiers: Vec<Identifier>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Fqn { | // Generic parameters
 | ||||||
|     pub fn new(identifiers: Vec<Identifier>) -> Self { |  | ||||||
|         Fqn { identifiers } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     pub fn identifiers(&self) -> &Vec<Identifier> { | #[derive(Debug)] | ||||||
|         &self.identifiers | pub struct GenericParameters(pub Vec<GenericParameter>); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     pub fn push_identifier(&mut self, identifier: Identifier) { | impl GenericParameters { | ||||||
|         self.identifiers.push(identifier); |     pub fn is_empty(&self) -> bool { | ||||||
|     } |         self.0.is_empty() | ||||||
| 
 |  | ||||||
|     pub fn pop_identifier(&mut self) { |  | ||||||
|         self.identifiers.pop(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum Declaration { | pub struct GenericParameter(Identifier); | ||||||
|     Interface { | 
 | ||||||
|         identifier: Identifier, | // Generic arguments
 | ||||||
|         is_extern: bool, |  | ||||||
|         is_public: bool, |  | ||||||
|         type_declaration: TypeDeclaration, |  | ||||||
|     }, |  | ||||||
|     Implementation { |  | ||||||
|         identifier: Identifier, |  | ||||||
|         is_extern: bool, |  | ||||||
|         is_public: bool, |  | ||||||
|         type_declaration: TypeDeclaration, |  | ||||||
|         impl_ctor: Option<ClassConstructor>, |  | ||||||
|     }, |  | ||||||
|     Module { |  | ||||||
|         identifier: Identifier, |  | ||||||
|         is_extern: bool, |  | ||||||
|         is_public: bool, |  | ||||||
|         declarations: Vec<Declaration>, |  | ||||||
|     }, |  | ||||||
|     Function(FunctionDeclaration), |  | ||||||
|     Prop(Prop), |  | ||||||
|     Field(Field), |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct FunctionDeclaration { | pub struct GenericArguments(pub Vec<GenericArgument>); | ||||||
|     source_code_location: SourceCodeLocation, |  | ||||||
|     identifier: Identifier, |  | ||||||
|     is_extern: bool, |  | ||||||
|     is_public: bool, |  | ||||||
|     parameters: Vec<Parameter>, |  | ||||||
|     declared_type: Option<TypeUse>, |  | ||||||
|     block_statement: BlockStatement, |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| impl FunctionDeclaration { | impl GenericArguments { | ||||||
|     pub fn source_code_location(&self) -> &SourceCodeLocation { |     pub fn is_empty(&self) -> bool { | ||||||
|         &self.source_code_location |         self.0.is_empty() | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     pub fn identifier(&self) -> &Identifier { |  | ||||||
|         &self.identifier |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn block_statement(&self) -> &BlockStatement { |  | ||||||
|         &self.block_statement |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct TypeDeclaration { |  | ||||||
|     generics: Vec<GenericParameter>, |  | ||||||
|     extends: Vec<TypeUse>, |  | ||||||
|     declarations: Vec<Declaration>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl TypeDeclaration { |  | ||||||
|     pub fn new( |  | ||||||
|         generics: Vec<GenericParameter>, |  | ||||||
|         extends: Vec<TypeUse>, |  | ||||||
|         declarations: Vec<Declaration>, |  | ||||||
|     ) -> TypeDeclaration { |  | ||||||
|         TypeDeclaration { |  | ||||||
|             generics, |  | ||||||
|             extends, |  | ||||||
|             declarations, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Clone)] |  | ||||||
| pub struct Identifier { |  | ||||||
|     name: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Identifier { |  | ||||||
|     pub fn name(&self) -> &str { |  | ||||||
|         &self.name |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct GenericParameter { |  | ||||||
|     identifier: Identifier, |  | ||||||
|     bound: Option<GenericBound>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub enum GenericBound { |  | ||||||
|     Extends { fqn: Fqn }, |  | ||||||
|     Super { fqn: Fqn }, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct GenericArgument { | pub struct GenericArgument { | ||||||
|     fqn: Fqn, |     pub fqn: Fqn, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Type-use and components
 | ||||||
|  | 
 | ||||||
|  | // #[derive(Debug)]
 | ||||||
|  | // pub struct TypeUse {
 | ||||||
|  | //     pub fqn: Fqn,
 | ||||||
|  | //     pub arguments: Option<TypeArguments>,
 | ||||||
|  | //     pub inputs: Option<InputArguments>,
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum TypeUse { | ||||||
|  |     InterfaceOrClass(InterfaceOrClassTypeUse), | ||||||
|  |     Tuple(TupleTypeUse), | ||||||
|  |     Function(FunctionTypeUse), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct TypeUse { | pub struct InterfaceOrClassTypeUse { | ||||||
|     fqn: Fqn, |     pub fqn: Fqn, | ||||||
|     generics: Vec<GenericArgument>, |     pub generics: GenericArguments, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct ClassConstructor { | pub struct TupleTypeUse(pub Vec<TypeUse>); | ||||||
|     args: Vec<ClassMember>, | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct FunctionTypeUse { | ||||||
|  |     pub function_modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub parameters: TupleTypeUse, | ||||||
|  |     pub inputs: InputArguments, | ||||||
|  |     pub return_type: ReturnType, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ClassConstructor { | #[derive(Debug)] | ||||||
|     pub fn new(args: Vec<ClassMember>) -> Self { | pub enum TypeArguments { | ||||||
|         ClassConstructor { args } |     Generics(GenericArguments), | ||||||
|  |     Tuple(TupleArguments), | ||||||
|  |     Function(FunctionTypeArguments), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct TupleArguments(pub Vec<Fqn>); | ||||||
|  | 
 | ||||||
|  | impl TupleArguments { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct ClassMember { | pub struct FunctionTypeArguments { | ||||||
|     is_field: bool, |     pub parameters: TupleParameters, | ||||||
|     identifier: Identifier, |     pub return_type: Box<TypeUse>, | ||||||
|     type_use: Option<TypeUse> |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ClassMember { | // Function components
 | ||||||
|     pub fn new(is_field: bool, identifier: Identifier, type_use: Option<TypeUse>) -> Self { | 
 | ||||||
|         ClassMember { | #[derive(Debug)] | ||||||
|             is_field, | pub struct Parameters(pub Vec<Parameter>); | ||||||
|             identifier, | 
 | ||||||
|             type_use | impl Parameters { | ||||||
|         } |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct ImplCtorArg { | pub struct Parameter { | ||||||
|     is_field: bool, |  | ||||||
|     identifier: Identifier, |     identifier: Identifier, | ||||||
|     r#type: Option<TypeUse>, |     type_use: TypeUse, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Prop { | pub struct ReturnType { | ||||||
|     identifier: Identifier, |     pub declared_type: VoidOrTypeUse, | ||||||
|     r#type: TypeUse, |     pub references: References, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Field { | pub enum VoidOrTypeUse { | ||||||
|     identifier: Identifier, |     Void, | ||||||
|     r#type: TypeUse, |     TypeUse(Box<TypeUse>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct BlockStatement { | pub struct References(pub Vec<Reference>); | ||||||
|     statements: Vec<Statement>, |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| impl BlockStatement { | impl References { | ||||||
|     pub fn statements(&self) -> &Vec<Statement> { |     pub fn is_empty(&self) -> bool { | ||||||
|         &self.statements |         self.0.is_empty() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct Reference(pub Identifier); | ||||||
|  | 
 | ||||||
|  | // Inputs
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum DelegateOrIdentifier { | ||||||
|  |     Delegate, | ||||||
|  |     Identifier(Identifier), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InputParameters(pub Vec<DelegateOrIdentifier>); | ||||||
|  | 
 | ||||||
|  | impl InputParameters { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InputArguments(pub Vec<InputArgument>); | ||||||
|  | 
 | ||||||
|  | impl InputArguments { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InputArgument { | ||||||
|  |     pub lhs: DelegateOrIdentifier, | ||||||
|  |     pub rhs: Identifier, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Where guards
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct WhereGuards(pub Vec<WhereGuard>); | ||||||
|  | 
 | ||||||
|  | impl WhereGuards { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct WhereGuard { | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub implements: ImplementsList, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Implements
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ImplementsList(pub Vec<TypeUse>); | ||||||
|  | 
 | ||||||
|  | impl ImplementsList { | ||||||
|  |     pub fn is_empty(&self) -> bool { | ||||||
|  |         self.0.is_empty() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Top-level construct
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct CompilationUnit { | ||||||
|  |     pub namespace: Option<Fqn>, | ||||||
|  |     pub declarations: Vec<ModuleLevelDeclaration>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Declarations allowed in each level
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum ModuleLevelDeclaration { | ||||||
|  |     Type(TypeDeclaration), | ||||||
|  |     Module(ModuleDeclaration), | ||||||
|  |     Interface(InterfaceDeclaration), | ||||||
|  |     Class(ClassDeclaration), | ||||||
|  |     Function(FunctionDeclaration), | ||||||
|  |     PlatformFunction(PlatformFunctionDeclaration), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum InterfaceLevelDeclaration { | ||||||
|  |     Type(TypeDeclaration), | ||||||
|  |     Module(ModuleDeclaration), | ||||||
|  |     Interface(InterfaceDeclaration), | ||||||
|  |     Class(ClassDeclaration), | ||||||
|  |     Function(InterfaceFunctionDeclaration), | ||||||
|  |     OperatorFunction(InterfaceOperatorFunctionDeclaration), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum ClassLevelDeclaration { | ||||||
|  |     Type(TypeDeclaration), | ||||||
|  |     Module(ModuleDeclaration), | ||||||
|  |     Interface(InterfaceDeclaration), | ||||||
|  |     Class(ClassDeclaration), | ||||||
|  |     Function(FunctionDeclaration), | ||||||
|  |     OperatorFunction(OperatorFunctionDeclaration), | ||||||
|  |     PlatformFunction(PlatformFunctionDeclaration), | ||||||
|  |     Field(FieldDeclaration), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Declarations
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct TypeDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub parameters: Option<TypeParameters>, | ||||||
|  |     pub where_guards: WhereGuards, | ||||||
|  |     pub rhs: TypeUse, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ModuleDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub declarations: Vec<ModuleLevelDeclaration>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InterfaceDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub inputs: InputParameters, | ||||||
|  |     pub implements: ImplementsList, | ||||||
|  |     pub where_guards: WhereGuards, | ||||||
|  |     pub declarations: Vec<InterfaceLevelDeclaration>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ClassDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub class_constructor: Option<ClassConstructor>, | ||||||
|  |     pub inputs: InputArguments, | ||||||
|  |     pub implements: ImplementsList, | ||||||
|  |     pub where_guards: WhereGuards, | ||||||
|  |     pub declarations: Vec<ClassLevelDeclaration>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Function declarations and components
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum FunctionModifier { | ||||||
|  |     Static, | ||||||
|  |     Cons, | ||||||
|  |     Mut, | ||||||
|  |     Ref, | ||||||
|  |     MutRef, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum FunctionBody { | ||||||
|  |     EqualsBody(Expression), | ||||||
|  |     BlockBody(BlockStatement), | ||||||
|  |     AliasBody(Identifier), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct FunctionDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: Option<ReturnType>, | ||||||
|  |     pub body: FunctionBody, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct OperatorFunctionDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub operator: Operator, | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: Option<ReturnType>, | ||||||
|  |     pub body: FunctionBody, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct PlatformFunctionDeclaration { | ||||||
|  |     pub is_public: bool, | ||||||
|  |     pub modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: TypeUse, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InterfaceFunctionDeclaration { | ||||||
|  |     pub modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: ReturnType, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct InterfaceOperatorFunctionDeclaration { | ||||||
|  |     pub modifier: Option<FunctionModifier>, | ||||||
|  |     pub generics: GenericParameters, | ||||||
|  |     pub operator: Operator, | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: ReturnType, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Type components
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum TypeParameters { | ||||||
|  |     Generic(GenericParameters), | ||||||
|  |     Tuple(TupleParameters), | ||||||
|  |     Function(FunctionTypeParameters), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct TupleParameters(pub Vec<Identifier>); | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct FunctionTypeParameters { | ||||||
|  |     pub parameters: Parameters, | ||||||
|  |     pub return_type: TypeUse, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Class components
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ClassConstructor(pub Vec<ClassConstructorParameter>); | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ClassConstructorParameter { | ||||||
|  |     pub is_field: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub declared_type: TypeUse, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct FieldDeclaration { | ||||||
|  |     pub is_mutable: bool, | ||||||
|  |     pub identifier: Identifier, | ||||||
|  |     pub declared_type: TypeUse, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Statements
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct BlockStatement(pub Vec<Statement>); | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum Statement { | pub enum Statement { | ||||||
|  |     BlockStatement(BlockStatement), | ||||||
|     CallStatement(CallExpression), |     CallStatement(CallExpression), | ||||||
|     AssignStatement(AssignExpression), |     VariableDeclarationStatement(VariableDeclarationStatement), | ||||||
|  |     AssignStatement(AssignStatement), | ||||||
|  |     ReturnStatement(ReturnStatement), | ||||||
|  |     IfStatement(IfStatement), | ||||||
|  |     IfElseStatement(IfElseStatement), | ||||||
|  |     WhileStatement(WhileStatement), | ||||||
|  |     ForStatement(ForStatement), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct VariableDeclarationStatement { | ||||||
|  |     is_mutable: bool, | ||||||
|  |     identifier: Identifier, | ||||||
|  |     declared_type: Option<TypeUse>, | ||||||
|  |     initializer: Option<Expression>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct AssignStatement(pub AssignmentExpression); | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ReturnStatement(pub Option<Expression>); | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct IfStatement { | ||||||
|  |     pub condition: Expression, | ||||||
|  |     pub then_branch: BlockStatement, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct IfElseStatement { | ||||||
|  |     pub condition: Expression, | ||||||
|  |     pub then_branch: BlockStatement, | ||||||
|  |     pub else_ifs: ElseIfs, | ||||||
|  |     pub else_branch: BlockStatement, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ElseIfs(pub Vec<IfStatement>); | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct WhileStatement { | ||||||
|  |     pub condition: Expression, | ||||||
|  |     pub body: BlockStatement, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct ForStatement { | ||||||
|  |     pub variable: Identifier, | ||||||
|  |     pub iterator: Expression, | ||||||
|  |     pub body: BlockStatement, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Expressions
 | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub enum Expression { | ||||||
|  |     Binary(BinaryExpression), | ||||||
|  |     Unary(UnaryExpression), | ||||||
|  |     Assignment(Box<AssignmentExpression>), | ||||||
|  |     Call(CallExpression), | ||||||
|  |     Literal(Literal), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct BinaryExpression { | ||||||
|  |     pub left: Box<Expression>, | ||||||
|  |     pub operator: BinaryOperator, | ||||||
|  |     pub right: Box<Expression>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct UnaryExpression { | ||||||
|  |     pub operator: UnaryOperator, | ||||||
|  |     pub expression: Box<Expression>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct AssignmentExpression { | ||||||
|  |     identifier: Identifier, | ||||||
|  |     expression: Expression, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct CallExpression { | pub struct CallExpression { | ||||||
|     receiver: Expression, |     pub callee: Box<Expression>, | ||||||
|     actuals_list: Vec<Expression>, |     pub arguments: CallArguments, | ||||||
|     source_code_location: SourceCodeLocation, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl CallExpression { |  | ||||||
|     pub fn receiver(&self) -> &Expression { |  | ||||||
|         &self.receiver |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn actuals_list(&self) -> &Vec<Expression> { |  | ||||||
|         &self.actuals_list |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn source_code_location(&self) -> &SourceCodeLocation { |  | ||||||
|         &self.source_code_location |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct AssignExpression { | pub struct CallArguments(pub Vec<CallArgument>); | ||||||
|     left: LValue, |  | ||||||
|     right: Expression, |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum Expression { | pub struct CallArgument(pub Box<Expression>); | ||||||
|     CallExpression(Box<CallExpression>), |  | ||||||
|     AssignExpression(Box<AssignExpression>), |  | ||||||
|     LValue(Box<LValue>), |  | ||||||
|     Literal(Box<Literal>), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub enum LValue { |  | ||||||
|     Fqn(Fqn), |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub enum Literal { | pub enum Literal { | ||||||
| @ -261,9 +540,3 @@ pub enum Literal { | |||||||
|     StringLiteral(String), |     StringLiteral(String), | ||||||
|     BooleanLiteral(bool), |     BooleanLiteral(bool), | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #[derive(Debug)] |  | ||||||
| pub struct Parameter { |  | ||||||
|     identifier: Identifier, |  | ||||||
|     declared_type: Option<TypeUse>, |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										1018
									
								
								src/ast/unparse.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1018
									
								
								src/ast/unparse.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,6 +1,6 @@ | |||||||
| use crate::ast::{ | use crate::ast::{ | ||||||
|     AssignExpression, BlockStatement, CallExpression, CompilationUnit, Declaration, Expression, |     AssignExpression, BlockStatement, CallExpression, CompilationUnit, Expression, Fqn, | ||||||
|     Fqn, FunctionDeclaration, Identifier, LValue, Statement, |     FunctionDeclaration, Identifier, LValue, ModuleLevelDeclaration, Statement, | ||||||
| }; | }; | ||||||
| use crate::object_file::{DvmObjectFile, DvmPath}; | use crate::object_file::{DvmObjectFile, DvmPath}; | ||||||
| use crate::vm::function::DvmFunction; | use crate::vm::function::DvmFunction; | ||||||
| @ -153,7 +153,7 @@ pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile { | |||||||
| 
 | 
 | ||||||
|     for declaration in ast.declarations() { |     for declaration in ast.declarations() { | ||||||
|         match declaration { |         match declaration { | ||||||
|             Declaration::Function(function_declaration) => { |             ModuleLevelDeclaration::Function(function_declaration) => { | ||||||
|                 let function = convert_static_function(&state, &context, function_declaration); |                 let function = convert_static_function(&state, &context, function_declaration); | ||||||
|                 object_file.add_function(function); |                 object_file.add_function(function); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -1,140 +1,780 @@ | |||||||
| // Top-level constructs | // Keywords | ||||||
| CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI } | Ns = { "ns" } | ||||||
| Namespace = { "ns" ~ FullyQualifiedName } | TypeKw = { "type" } | ||||||
|  | Mod = { "mod" } | ||||||
|  | Int = { "int" } | ||||||
|  | ClassKw = { "class" } | ||||||
|  | Platform = { "platform" } | ||||||
|  | Pub = { "pub" } | ||||||
|  | Fld = { "fld" } | ||||||
|  | Impl = { "impl" } | ||||||
|  | Mut = { "mut" } | ||||||
|  | Cons = { "cons" } | ||||||
|  | Static = { "static" } | ||||||
|  | Ref = { "ref" } | ||||||
|  | Def = { "def" } | ||||||
|  | Where = { "where" } | ||||||
|  | Infer = { "infer" } | ||||||
|  | Void = { "Void" } | ||||||
|  | Delegate = { "delegate" } | ||||||
|  | Let = { "let" } | ||||||
|  | Fn = { "fn" } | ||||||
|  | Op = { "op" } | ||||||
| 
 | 
 | ||||||
| CommonDeclaration = { Interface | Class | Module | Function }  | // Keywords as a rule (for preventing identifiers with keywords, etc.) | ||||||
| ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration } | Keyword = { | ||||||
| InterfaceLevelDeclaration = { CommonDeclaration } |       Ns | ||||||
| ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) } |     | TypeKw | ||||||
| 
 |     | Mod | ||||||
| // Module |     | Int | ||||||
| Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" } |     | ClassKw | ||||||
| 
 |     | Platform | ||||||
| // Interface |     | Pub | ||||||
| Interface = { "int" ~ Identifier ~ GenericParameters? ~  ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? } |     | Fld | ||||||
| 
 |     | Impl | ||||||
| // Class |     | Mut | ||||||
| Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? } |     | Cons | ||||||
| ClassMember = { Field? ~ Identifier ~ TypeAnnotation? } |     | Static | ||||||
| 
 |     | Ref | ||||||
| // Class Constructor |     | Def | ||||||
| ClassConstructor = { "(" ~ ClassMemberList? ~ ")" } |     | Where | ||||||
| ClassMemberList = { ClassMember ~ ( "," ~ ClassMember )* } |     | Infer | ||||||
| 
 |     | Void | ||||||
| // Various Keywords |     | Delegate | ||||||
| Declare = { "decl" } |     | Let | ||||||
| Public = { "pub" } |     | Fn | ||||||
| Field = { "fld" } |     | Op | ||||||
| Implementation = { "impl" } |  | ||||||
| Mutable = { "mut" } |  | ||||||
| 
 |  | ||||||
| // Fqn and identifier |  | ||||||
| FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* } |  | ||||||
| 
 |  | ||||||
| Identifier = @{ IdentifierStartChar ~ IdentifierChar* } |  | ||||||
| IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" } |  | ||||||
| IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } |  | ||||||
| 
 |  | ||||||
| // Type constructs |  | ||||||
| ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* } |  | ||||||
| TypeAnnotation = { ":" ~ TypeUse } |  | ||||||
| TypeUse = { FullyQualifiedName ~ GenericArguments? } |  | ||||||
| 
 |  | ||||||
| // Generic arguments given to a TypeUse or function calls |  | ||||||
| GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" } |  | ||||||
| 
 |  | ||||||
| // Generic parameters (for when types are declared) |  | ||||||
| GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" } |  | ||||||
| 
 |  | ||||||
| // Function |  | ||||||
| Function = { Implementation? |  | ||||||
|     ~ "fn" |  | ||||||
|     ~ Identifier |  | ||||||
|     ~ GenericParameters? |  | ||||||
|     ~ "(" ~ Parameters? ~ ")" |  | ||||||
|     ~ TypeAnnotation? ~ ( FunctionEqualsBody | BlockStatement ) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Parameters = { Parameter ~ ( "," ~ Parameter )* } | // Symbols | ||||||
| Parameter = { Identifier ~ TypeAnnotation? } | Ellipsis = { "..." } | ||||||
|  | Underscore = { "_" } | ||||||
| 
 | 
 | ||||||
| FunctionEqualsBody = { "=" ~ Expression } | // Operators | ||||||
| 
 | Or = { "||" } | ||||||
| // Statements | And = { "&&" } | ||||||
| BlockStatement = { "{" ~ Statement* ~ "}" } |  | ||||||
| Statement = { VariableDeclaration | CallExpression | AssignmentExpression } |  | ||||||
| 
 |  | ||||||
| VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? } |  | ||||||
| 
 |  | ||||||
| // Expressions |  | ||||||
| Expression = { OrExpression } |  | ||||||
| 
 |  | ||||||
| OrExpression = { AndExpression ~ ( "||" ~ AndExpression )* } |  | ||||||
| AndExpression = { EqualityExpression ~ ( "&&" ~ EqualityExpression )* } |  | ||||||
| 
 |  | ||||||
| EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* } |  | ||||||
| EqualTo = { "==" } | EqualTo = { "==" } | ||||||
| NotEqualTo = { "!=" } | NotEqualTo = { "!=" } | ||||||
| 
 |  | ||||||
| ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ AdditiveExpression )* } |  | ||||||
| Greater = { ">" } | Greater = { ">" } | ||||||
| Less = { "<" } | Less = { "<" } | ||||||
| GreaterEqual = { ">=" } | GreaterEqual = { ">=" } | ||||||
| LessEqual = { "<=" } | LessEqual = { "<=" } | ||||||
| 
 |  | ||||||
| AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ MultiplicativeExpression )* } |  | ||||||
| Add = { "+" } | Add = { "+" } | ||||||
| Subtract = { "-" } | Subtract = { "-" } | ||||||
| 
 |  | ||||||
| MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ UnaryExpression )* } |  | ||||||
| Multiply = { "*" } | Multiply = { "*" } | ||||||
| Divide = { "/" } | Divide = { "/" } | ||||||
| Modulo = { "%" } | Modulo = { "%" } | ||||||
| 
 |  | ||||||
| UnaryExpression = { ( Not | Negative )* ~ PrimaryExpression ~ ( Call | ( PlusPlus | MinusMinus ) )* } |  | ||||||
| Not = { "!" } | Not = { "!" } | ||||||
| Negative = { "-" } | Negative = { "-" } | ||||||
| PlusPlus = { "++" } | PlusPlus = { "++" } | ||||||
| MinusMinus = { "--" } | MinusMinus = { "--" } | ||||||
|  | CallOp = { "()" } | ||||||
|  | Spread = { Ellipsis } | ||||||
| 
 | 
 | ||||||
| PrimaryExpression = { Literal | ObjectAccess | ParenthesizedExpression } | Operator = { | ||||||
| ParenthesizedExpression = { "(" ~ Expression ~ ")" } |       Or | ||||||
|  |     | And | ||||||
|  |     | EqualTo | ||||||
|  |     | NotEqualTo | ||||||
|  |     | Greater | ||||||
|  |     | Less | ||||||
|  |     | GreaterEqual | ||||||
|  |     | LessEqual | ||||||
|  |     | Add | ||||||
|  |     | Subtract | ||||||
|  |     | Multiply | ||||||
|  |     | Divide | ||||||
|  |     | Modulo | ||||||
|  |     | Not | ||||||
|  |     | Negative | ||||||
|  |     | PlusPlus | ||||||
|  |     | MinusMinus | ||||||
|  |     | CallOp | ||||||
|  |     | Spread | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | // Commonly shared constructs | ||||||
| 
 | 
 | ||||||
| // Call | FullyQualifiedName = { | ||||||
| CallExpression = { PrimaryExpression ~ Call+ } |       Identifier | ||||||
| Call = { GenericArguments? ~ CallArguments } |     ~ ( "::" ~ Identifier )* | ||||||
| ExpressionList = { Expression ~ ( "," ~ Expression )* } | } | ||||||
| CallArguments = { | 
 | ||||||
|     ( "(" ~ ExpressionList? ~ ")" ) | Identifier = @{ | ||||||
|     | ExpressionList |       ( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar ) | ||||||
|  |     ~ IdentifierChar* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IdentifierStartChar = { | ||||||
|  |       'a'..'z' | ||||||
|  |     | 'A'..'Z' | ||||||
|  |     | "_" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | IdentifierChar = { | ||||||
|  |       'a'..'z' | ||||||
|  |     | 'A'..'Z' | ||||||
|  |     | '0'..'9' | ||||||
|  |     | "_" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // In general: | ||||||
|  | // Arguments = usage | ||||||
|  | // Parameters = declaration | ||||||
|  | 
 | ||||||
|  | TypeUse = { | ||||||
|  |       InterfaceOrClassTypeUse | ||||||
|  |     | TupleTypeUse | ||||||
|  |     | FunctionTypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceOrClassTypeUse = { | ||||||
|  |       FullyQualifiedName | ||||||
|  |     ~ GenericArguments? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TupleTypeUse = { | ||||||
|  |       "(" | ||||||
|  |     ~ ( | ||||||
|  |         TypeUse | ||||||
|  |         ~ ( "," ~ TypeUse )* | ||||||
|  |       )? | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionTypeUse = { | ||||||
|  |       FunctionTypeModifier? | ||||||
|  |     ~ Fn | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ TupleTypeUse | ||||||
|  |     ~ FunctionInputArguments? | ||||||
|  |     ~ ReturnType | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionTypeModifier = { | ||||||
|  |       Cons | ||||||
|  |     | Mut ~ Ref | ||||||
|  |     | Mut | ||||||
|  |     | Ref | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | GenericArguments = { | ||||||
|  |       "<" | ||||||
|  |     ~ FullyQualifiedName | ||||||
|  |     ~ ( "," ~ FullyQualifiedName )* | ||||||
|  |     ~ ">" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InputArguments = { | ||||||
|  |       "|" | ||||||
|  |     ~ ( | ||||||
|  |           InputArgument | ||||||
|  |         ~ ( "," ~ InputArgument )* | ||||||
|  |       )? | ||||||
|  |     ~ "|" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InputArgument = { | ||||||
|  |       Identifier | ||||||
|  |     ~ ( "=" ~ Identifier ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | RefList = { | ||||||
|  |       Ref | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ ( "," ~ Identifier )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionInputArguments = { | ||||||
|  |       "|" | ||||||
|  |     ~ ( | ||||||
|  |           FunctionInputArgument | ||||||
|  |         ~ ( "," ~ FunctionInputArgument )* | ||||||
|  |       )? | ||||||
|  |     ~ "|" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionInputArgument = { | ||||||
|  |       ( Delegate | Identifier ) | ||||||
|  |     ~ ( "=" ~ Identifier ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Generic Parameters | ||||||
|  | 
 | ||||||
|  | GenericParameters = { | ||||||
|  |       "<" | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ ( "," ~ Identifier )* | ||||||
|  |     ~ ">" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InputParameters = { | ||||||
|  |       "|" | ||||||
|  |     ~ InputParameter | ||||||
|  |     ~ ( "," ~ InputParameter )* | ||||||
|  |     ~ "|" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InputParameter = { | ||||||
|  |       Identifier | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TupleGenericParameters = { | ||||||
|  |       "(" | ||||||
|  |     ~ ( | ||||||
|  |           Identifier | ||||||
|  |         ~ ( "," ~ Identifier )* | ||||||
|  |       )? | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionGenericParameters = { | ||||||
|  |       TupleGenericParameters | ||||||
|  |     ~ FunctionGenericParameterReturnType | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionGenericParameterReturnType = { | ||||||
|  |       "->" | ||||||
|  |     ~ ( Void | Identifier ) | ||||||
|  |     ~ RefList? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionInputParameters = { | ||||||
|  |       "|" | ||||||
|  |     ~ FunctionInputParameter | ||||||
|  |     ~ ( "," ~ FunctionInputParameter )* | ||||||
|  |     ~ "|" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionInputParameter = { | ||||||
|  |       ( Delegate | Identifier ) | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ImplementsList = { | ||||||
|  |       ":" | ||||||
|  |     ~ TypeUse | ||||||
|  |     ~ ( "+" ~ TypeUse ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WhereGuards = { | ||||||
|  |       Where | ||||||
|  |     ~ WhereGuard | ||||||
|  |     ~ ( "," ~ WhereGuard )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | WhereGuard = { | ||||||
|  |       Identifier | ||||||
|  |     ~ ImplementsList | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Top-level constructs | ||||||
|  | 
 | ||||||
|  | CompilationUnit = { | ||||||
|  |       SOI | ||||||
|  |     ~ Namespace? | ||||||
|  |     ~ ModuleLevelDeclaration* | ||||||
|  |     ~ EOI | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Namespace = { | ||||||
|  |       Ns | ||||||
|  |     ~ FullyQualifiedName | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Organizational declarations | ||||||
|  | 
 | ||||||
|  | ModuleLevelDeclaration = { | ||||||
|  |       Type | ||||||
|  |     | Module | ||||||
|  |     | Interface | ||||||
|  |     | Class | ||||||
|  |     | FunctionDefinition | ||||||
|  |     | PlatformFunction | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceLevelDeclaration = { | ||||||
|  |       Type | ||||||
|  |     | Module | ||||||
|  |     | Interface | ||||||
|  |     | Class | ||||||
|  |     | InterfaceFunction | ||||||
|  |     | InterfaceDefaultFunction | ||||||
|  |     | InterfaceOperatorFunction | ||||||
|  |     | InterfaceDefaultOperatorFunction | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ClassLevelDeclaration = { | ||||||
|  |       Type | ||||||
|  |     | Module | ||||||
|  |     | Interface | ||||||
|  |     | Class | ||||||
|  |     | FunctionDefinition | ||||||
|  |     | OperatorFunctionDefinition | ||||||
|  |     | PlatformFunction | ||||||
|  |     | Field | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Main organizational constructs | ||||||
|  | 
 | ||||||
|  | Type = { | ||||||
|  |       Pub? | ||||||
|  |     ~ TypeKw | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ TypeWhereGuards? | ||||||
|  |     ~ "=" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Module = { | ||||||
|  |       Pub? | ||||||
|  |     ~ Mod | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ "{" ~ ModuleLevelDeclaration* ~ "}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Interface = { | ||||||
|  |       Pub? | ||||||
|  |     ~ Int | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ InterfaceGenericParametersAndInputs? | ||||||
|  |     ~ ImplementsList? | ||||||
|  |     ~ WhereGuards? | ||||||
|  |     ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Class = { | ||||||
|  |       Pub? | ||||||
|  |     ~ ClassKw | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ ClassConstructor? | ||||||
|  |     ~ ImplementsList? | ||||||
|  |     ~ InputArguments? | ||||||
|  |     ~ WhereGuards? | ||||||
|  |     ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Type | ||||||
|  | 
 | ||||||
|  | TypeWhereGuards = { | ||||||
|  |       Where | ||||||
|  |     ~ TypeWhereGuard | ||||||
|  |     ~ ( "," ~ TypeWhereGuard )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeWhereGuard = { | ||||||
|  |       Identifier | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeTypeUse | ||||||
|  |     ~ ( "+" ~ TypeTypeUse )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeTypeUse = { | ||||||
|  |       FullyQualifiedName | ||||||
|  |     ~ TypeTypeArguments? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeTypeArguments = { | ||||||
|  |       TypeGenericArguments | ||||||
|  |     | TypeGenericFunctionArguments | ||||||
|  |     | TypeGenericTupleArguments | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeGenericArguments = { | ||||||
|  |       "<" | ||||||
|  |     ~ TypeGenericArgument | ||||||
|  |     ~ ( "," ~ TypeGenericArgument )* | ||||||
|  |     ~ ">" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeGenericArgument = { | ||||||
|  |       Underscore | ||||||
|  |     | FullyQualifiedName | ||||||
|  |     | ( Infer ~ Identifier ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeGenericTupleArguments = { | ||||||
|  |       "(" | ||||||
|  |     ~ ( | ||||||
|  |           TypeGenericTupleArgument | ||||||
|  |         ~ ( "," ~ TypeGenericTupleArgument )* | ||||||
|  |       )? | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeGenericTupleArgument = { | ||||||
|  |       Underscore | ||||||
|  |     | FullyQualifiedName | ||||||
|  |     | ( Infer ~ Identifier ) | ||||||
|  |     | ( Ellipsis ~ Underscore ) | ||||||
|  |     | ( Ellipsis ~ Infer ~ Identifier ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeGenericFunctionArguments = { | ||||||
|  |       TypeGenericTupleArguments | ||||||
|  |     ~ TypeGenericArguments? | ||||||
|  |     ~ TypeFunctionReturnType | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TypeFunctionReturnType = { | ||||||
|  |       "->" | ||||||
|  |     ~ ( Void | FullyQualifiedName ) | ||||||
|  |     ~ RefList? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Interface | ||||||
|  | 
 | ||||||
|  | InterfaceGenericParametersAndInputs = { | ||||||
|  |       GenericParameters ~ InputParameters? | ||||||
|  |     | TupleGenericParameters | ||||||
|  |     | FunctionGenericParameters ~ FunctionInputParameters? | ||||||
|  |     | InputParameters | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceFunction = { | ||||||
|  |       ( | ||||||
|  |           Static | ||||||
|  |         | Cons | ||||||
|  |         | ( Mut ~ Ref? ) | ||||||
|  |       )? | ||||||
|  |     ~ Fn | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType | ||||||
|  |     ~ WhereGuards? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceDefaultFunction = { | ||||||
|  |       Def | ||||||
|  |     ~ ( | ||||||
|  |           Static | ||||||
|  |         | Cons | ||||||
|  |         | ( Mut ~ Ref? ) | ||||||
|  |       )? | ||||||
|  |     ~ Fn | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType | ||||||
|  |     ~ WhereGuards? | ||||||
|  |     ~ FunctionBody | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceOperatorFunction = { | ||||||
|  |       ( | ||||||
|  |           Cons | ||||||
|  |         | ( Mut ~ Ref? ) | ||||||
|  |       )? | ||||||
|  |     ~ Op | ||||||
|  |     ~ Operator | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType | ||||||
|  |     ~ RefList? | ||||||
|  |     ~ WhereGuards? // TODO: decide if we want this for interface op functions | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | InterfaceDefaultOperatorFunction = { | ||||||
|  |       Def | ||||||
|  |     ~ ( | ||||||
|  |           Cons | ||||||
|  |         | ( Mut ~ Ref? ) | ||||||
|  |       )? | ||||||
|  |     ~ Op | ||||||
|  |     ~ Operator | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType | ||||||
|  |     ~ RefList? | ||||||
|  |     ~ WhereGuards? | ||||||
|  |     ~ FunctionBody | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Class constructs | ||||||
|  | 
 | ||||||
|  | ClassConstructor = { | ||||||
|  |       "(" | ||||||
|  |     ~ DataMember | ||||||
|  |     ~ ( "," ~ DataMember )* | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | DataMember = { | ||||||
|  |       Property | ||||||
|  |     | Field | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Property = { | ||||||
|  |       Mut? | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Field = { | ||||||
|  |       Mut? | ||||||
|  |     ~ Fld | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Function constructs | ||||||
|  | FunctionModifier = { | ||||||
|  |       Static | ||||||
|  |     | Cons | ||||||
|  |     | Mut? ~ Ref? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionDefinition = { | ||||||
|  |       Pub? | ||||||
|  |     ~ FunctionModifier | ||||||
|  |     ~ Fn | ||||||
|  |     ~ GenericParameters? | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType? | ||||||
|  |     ~ FunctionBody | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | OperatorFunctionDefinition = { | ||||||
|  |       Pub? | ||||||
|  |     ~ FunctionModifier | ||||||
|  |     ~ Op | ||||||
|  |     ~ Operator | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType? | ||||||
|  |     ~ FunctionBody | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PlatformFunction = { | ||||||
|  |       Pub? | ||||||
|  |     ~ FunctionModifier | ||||||
|  |     ~ Platform | ||||||
|  |     ~ Fn | ||||||
|  |     ~ GenericParameters | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ Parameters | ||||||
|  |     ~ ReturnType | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Parameters = { | ||||||
|  |       "(" | ||||||
|  |     ~ ( | ||||||
|  |           Parameter | ||||||
|  |         ~ ( "," ~ Parameter )* | ||||||
|  |       )? | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Parameter = { | ||||||
|  |       Identifier | ||||||
|  |     ~ ":" | ||||||
|  |     ~ TypeUse | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ReturnType = { | ||||||
|  |       "->" | ||||||
|  |     ~ ( Void | TypeUse ) | ||||||
|  |     ~ RefList? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionBody = { | ||||||
|  |       FunctionEqualsBody | ||||||
|  |     | FunctionBlockBody | ||||||
|  |     | FunctionAliasBody | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionEqualsBody = { | ||||||
|  |       "=" | ||||||
|  |     ~ Expression | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionBlockBody = { | ||||||
|  |       "{" | ||||||
|  |     ~ Statement* | ||||||
|  |     ~ "}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FunctionAliasBody = { | ||||||
|  |       "alias" | ||||||
|  |     ~ Identifier | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Statements | ||||||
|  | 
 | ||||||
|  | BlockStatement = { | ||||||
|  |       "{" | ||||||
|  |     ~ Statement* | ||||||
|  |     ~ "}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Statement = { | ||||||
|  |       BlockStatement | ||||||
|  |     | VariableDeclaration | ||||||
|  |     | AssignmentExpression | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | VariableDeclaration = { | ||||||
|  |       Let | ||||||
|  |     ~ Mut? | ||||||
|  |     ~ Identifier | ||||||
|  |     ~ ( ":" ~ TypeUse )? | ||||||
|  |     ~ ( "=" ~ Expression )? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Expressions | ||||||
|  | 
 | ||||||
|  | Expression = { OrExpression } | ||||||
|  | 
 | ||||||
|  | OrExpression = { | ||||||
|  |       AndExpression | ||||||
|  |     ~ ( Or ~ Expression )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AndExpression = { | ||||||
|  |       EqualityExpression | ||||||
|  |     ~ ( And ~ Expression )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | EqualityExpression = { | ||||||
|  |       ComparisonExpression | ||||||
|  |     ~ ( | ||||||
|  |           ( EqualTo | NotEqualTo ) | ||||||
|  |         ~ Expression | ||||||
|  |       )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ComparisonExpression = { | ||||||
|  |       AdditiveExpression | ||||||
|  |     ~ ( | ||||||
|  |           ( Greater | Less | GreaterEqual | LessEqual ) | ||||||
|  |         ~ Expression | ||||||
|  |       )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | AdditiveExpression = { | ||||||
|  |       MultiplicativeExpression | ||||||
|  |     ~ ( | ||||||
|  |           ( Add | Subtract ) | ||||||
|  |         ~ Expression | ||||||
|  |       )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | MultiplicativeExpression = { | ||||||
|  |       SpreadExpression | ||||||
|  |     ~ ( | ||||||
|  |           ( Multiply | Divide | Modulo ) | ||||||
|  |         ~ Expression | ||||||
|  |       )* | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SpreadExpression = { | ||||||
|  |       UnaryExpression | ||||||
|  |     ~ Spread | ||||||
|  |     ~ Expression | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | UnaryExpression = { | ||||||
|  |       ( Not | Negative )* | ||||||
|  |     ~ PrimaryExpression | ||||||
|  |     ~ ( ( NoParenthesesCall | ParenthesesCall )+ | ( PlusPlus | MinusMinus ) )? | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PrimaryExpression = { | ||||||
|  |       Literal | ||||||
|  |     | ObjectAccess | ||||||
|  |     | ParenthesizedExpression | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ParenthesizedExpression = { | ||||||
|  |       "(" | ||||||
|  |     ~ Expression | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Calls | ||||||
|  | 
 | ||||||
|  | ParenthesesCall = { | ||||||
|  |       TurboFish? | ||||||
|  |     ~ "(" | ||||||
|  |     ~ ExpressionList? | ||||||
|  |     ~ ")" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | NoParenthesesCall = { | ||||||
|  |       TurboFish? | ||||||
|  |     ~ ExpressionList | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TurboFish = { | ||||||
|  |       "::" | ||||||
|  |     ~ GenericArguments | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ExpressionList = { | ||||||
|  |       Expression | ||||||
|  |     ~ ( "," ~ Expression )* | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Assignment | // Assignment | ||||||
| AssignmentExpression = { ObjectAccess ~ "=" ~ Expression } | AssignmentExpression = { | ||||||
|  |       ObjectAccess | ||||||
|  |     ~ "=" | ||||||
|  |     ~ Expression | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // Object | // Object | ||||||
| ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* } | ObjectAccess = { | ||||||
|  |       FullyQualifiedName | ||||||
|  |     ~ ( "." ~ Identifier )* | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // Literals | // Literals | ||||||
| Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral } | Literal = { | ||||||
|  |       NumberLiteral | ||||||
|  |     | StringLiteral | ||||||
|  |     | BooleanLiteral | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| NumberLiteral = { LongLiteral | IntLiteral } | NumberLiteral = { | ||||||
|  |       LongLiteral | ||||||
|  |     | IntLiteral | ||||||
|  |     | DoubleLiteral | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| IntLiteral = { NumberBase } | IntLiteral = { NumberBase } | ||||||
|  | 
 | ||||||
| LongLiteral = ${ NumberBase ~ "L" } | LongLiteral = ${ NumberBase ~ "L" } | ||||||
| 
 | 
 | ||||||
| NumberBase = { DecimalBase | BinaryBase | HexadecimalBase } | DoubleLiteral = ${ DecimalBase ~ "." ~ Digit+ } | ||||||
|  | 
 | ||||||
|  | NumberBase = { | ||||||
|  |       DecimalBase | ||||||
|  |     | BinaryBase | ||||||
|  |     | HexadecimalBase | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| DecimalBase = @{ DecimalStartDigit ~ Digit* } | DecimalBase = @{ DecimalStartDigit ~ Digit* } | ||||||
|  | 
 | ||||||
| BinaryBase = @{ "0b" ~ Digit* } | BinaryBase = @{ "0b" ~ Digit* } | ||||||
|  | 
 | ||||||
| DecimalStartDigit = { '1'..'9' } | DecimalStartDigit = { '1'..'9' } | ||||||
|  | 
 | ||||||
| Digit = { '0'..'9'+ } | Digit = { '0'..'9'+ } | ||||||
|  | 
 | ||||||
| HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ } | HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ } | ||||||
|  | 
 | ||||||
| HexadecimalDigit = { '0'..'9' | 'a'..'f' } | HexadecimalDigit = { '0'..'9' | 'a'..'f' } | ||||||
| 
 | 
 | ||||||
| StringLiteral = ${ "\"" ~ StringInner ~ "\"" } | StringLiteral = ${ "\"" ~ StringInner ~ "\"" } | ||||||
|  | 
 | ||||||
| StringInner = @{ StringChar* } | StringInner = @{ StringChar* } | ||||||
|  | 
 | ||||||
| StringChar = { | StringChar = { | ||||||
|     !( "\"" | "\\" ) ~ ANY |     !( "\"" | "\\" ) ~ ANY | ||||||
|     | "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) |     | "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) | ||||||
| @ -143,6 +783,4 @@ StringChar = { | |||||||
| 
 | 
 | ||||||
| BooleanLiteral = { "true" | "false" } | BooleanLiteral = { "true" | "false" } | ||||||
| 
 | 
 | ||||||
| NullLiteral = { "null" } |  | ||||||
| 
 |  | ||||||
| WHITESPACE = _{ " " | "\t" | "\n" | "\r" } | WHITESPACE = _{ " " | "\t" | "\n" | "\r" } | ||||||
|  | |||||||
| @ -51,7 +51,10 @@ mod deimos_parser_tests { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn parse(rule: Rule, input: &str) -> Pair<Rule> { |     fn parse(rule: Rule, input: &str) -> Pair<Rule> { | ||||||
|         let pair = DeimosParser::parse(rule, input).unwrap().next().unwrap(); |         let pair = DeimosParser::parse(rule, input) | ||||||
|  |             .expect("Parsing failed.") | ||||||
|  |             .next() | ||||||
|  |             .unwrap(); | ||||||
|         dbg!(&pair); |         dbg!(&pair); | ||||||
|         pair |         pair | ||||||
|     } |     } | ||||||
| @ -94,4 +97,30 @@ mod deimos_parser_tests { | |||||||
|         let call = call_expression_pairs.next().unwrap(); |         let call = call_expression_pairs.next().unwrap(); | ||||||
|         match_rule!(call; Rule::Call); |         match_rule!(call; Rule::Call); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     mod smoke_screen_tests { | ||||||
|  |         use crate::parser::deimos_parser_tests::parse; | ||||||
|  |         use crate::parser::Rule; | ||||||
|  | 
 | ||||||
|  |         #[test] | ||||||
|  |         fn simple_interface() { | ||||||
|  |             parse(Rule::CompilationUnit, "pub int Simple { fn foo() -> Void }"); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #[test] | ||||||
|  |         fn interface_with_op() { | ||||||
|  |             parse( | ||||||
|  |                 Rule::CompilationUnit, | ||||||
|  |                 "pub int Callable { op () () -> Void }", | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #[test] | ||||||
|  |         fn interface_with_alias() { | ||||||
|  |             parse( | ||||||
|  |                 Rule::CompilationUnit, | ||||||
|  |                 "pub int Callable {\n  fn call() -> Void\n  op () () -> Void alias call\n}", | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user