From 82af6b4dfbdccbbf647e82cf6a0725ea05421fae Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Tue, 13 May 2025 09:46:12 -0500 Subject: [PATCH] Much work on grammar, AST building and unparsing. --- src/ast/build.rs | 530 ++++++++++++++--------------------------- src/ast/mod.rs | 58 +++-- src/ast/unparse.rs | 71 +++++- src/compile/mod.rs | 6 +- src/parser/deimos.pest | 57 +++-- 5 files changed, 324 insertions(+), 398 deletions(-) diff --git a/src/ast/build.rs b/src/ast/build.rs index 08d40c5..98d2a62 100644 --- a/src/ast/build.rs +++ b/src/ast/build.rs @@ -1,374 +1,208 @@ -use crate::ast::{ - BlockStatement, CompilationUnit, Declaration, Fqn, FunctionDeclaration, GenericArgument, - GenericParameter, Identifier, ClassConstructor, Parameter, TypeDeclaration, TypeUse, -}; -use crate::parser::{DeimosParser, Rule}; -use crate::vm::source_code_location::SourceCodeLocation; +use crate::ast::{CompilationUnit, DelegateOrIdentifier, Fqn, FunctionModifier, FunctionTypeUse, GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument, InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType, TupleTypeUse, TypeUse, VoidOrTypeUse}; +use crate::parser::Rule; use pest::iterators::Pair; -use pest::Parser; -fn build_field(field_pair: Pair) -> Declaration { +fn expect_and_use(pair: Pair, rule: Rule, f: fn(Pair) -> 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) -> CompilationUnit { todo!() } -fn build_prop(prop_pair: Pair) -> Declaration { - todo!() -} - -fn build_generic_argument(generic_argument_pair: Pair) -> 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, -) -> Vec { - let mut generic_arguments: Vec = 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) -> 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) -> TypeUse { - let mut fqn: Option = None; - let mut generic_arguments_declaration: Option> = 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, -) -> Vec { - let mut parameters: Vec = 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) -> Vec { - let mut extensions: Vec = 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) -> Declaration { - let mut identifier: Option = None; - let mut generic_parameters: Option> = None; - let mut extends: Option> = None; - let mut declarations: Vec = 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) -> ClassConstructor { - todo!() -} - -fn build_implementation( - is_extern: bool, - is_public: bool, - implementation_pair: Pair, -) -> Declaration { - let mut identifier: Option = None; - let mut generic_parameters: Option> = None; - let mut impl_ctor: Option = None; - let mut extends: Option> = None; - let mut declarations: Vec = 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) -> Declaration { - todo!() -} - -fn build_parameter(pair: Pair) -> Parameter { - let mut identifier: Option = None; - let mut declared_type: Option = 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) -> Vec { - let mut parameters: Vec = 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) -> BlockStatement { - todo!() -} - -fn build_function_equals_body(pair: Pair) -> BlockStatement { - todo!() -} - -fn build_function(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { - let mut is_implementation = false; - let mut generic_parameters: Option> = None; - let mut identifier: Option = None; - let mut parameters: Option> = None; - let mut return_type: Option = None; - let mut statement: Option = 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) -> Declaration { - let mut is_extern = false; - let mut is_public = false; - let mut declaration: Option = 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) -> Identifier { - match pair.as_rule() { - Rule::Identifier => Identifier { - name: String::from(pair.as_str()), - }, - _ => unreachable!(), +fn build_identifier(identifier_pair: Pair) -> Identifier { + Identifier { + name: identifier_pair.as_str().to_string(), } } fn build_fqn(fqn_pair: Pair) -> Fqn { let mut identifiers: Vec = vec![]; - for pair in fqn_pair.into_inner() { - match pair.as_rule() { - Rule::Identifier => { - identifiers.push(build_identifier(pair)); - } - _ => unreachable!(), - } + for identifier_pair in fqn_pair.into_inner() { + identifiers.push(expect_and_use( + identifier_pair, + Rule::Identifier, + build_identifier, + )); } Fqn { identifiers } } -fn build_compilation_unit(pair: Pair) -> CompilationUnit { - let mut namespace: Option = None; - let mut declarations: Vec = vec![]; +fn build_type_use(type_use_pair: Pair) -> TypeUse { + let inner_pair = type_use_pair.into_inner().next().unwrap(); + 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() { - match pair.as_rule() { - Rule::Namespace => { - let fqn_pair = pair.into_inner().next().unwrap(); - namespace = Some(build_fqn(fqn_pair)); +fn build_interface_or_class_type_use(pair: Pair) -> InterfaceOrClassTypeUse { + let mut inner = pair.into_inner(); + let fqn = expect_and_use(inner.next().unwrap(), Rule::FullyQualifiedName, build_fqn); + + 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) -> 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) -> FunctionTypeUse { + let mut function_modifier: Option = None; + let mut generics: Option = None; + let mut parameters: Option = None; + let mut inputs: Option = None; + let mut return_type: Option = 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 => { - declarations.push(build_module_level_declaration(pair)); + Rule::Fn => {} + 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!(), } } - CompilationUnit { - namespace, - declarations, + FunctionTypeUse { + function_modifier, + 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 { - let pair = DeimosParser::parse(Rule::CompilationUnit, src) - .expect("Unsuccessful parse.") - .next() - .expect("Expected compilation_unit."); - match pair.as_rule() { - Rule::CompilationUnit => build_compilation_unit(pair), - _ => panic!("Expected compilation_unit rule."), +fn build_generic_arguments(generic_arguments_pair: Pair) -> GenericArguments { + let mut generic_arguments: Vec = vec![]; + for generic_argument_pair in generic_arguments_pair.into_inner() { + generic_arguments.push(expect_and_use( + generic_argument_pair, + Rule::FullyQualifiedName, + build_generic_argument, + )); + } + GenericArguments(generic_arguments) +} + +fn build_generic_argument(fqn_pair: Pair) -> GenericArgument { + GenericArgument { + fqn: build_fqn(fqn_pair), } } + +fn build_function_modifier(function_modifier_pair: Pair) -> 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) -> 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) -> 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) -> 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) -> References { + let mut identifiers: Vec = 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()) +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index f5deaa6..644bf76 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -64,9 +64,7 @@ impl GenericParameters { } #[derive(Debug)] -pub struct GenericParameter { - identifier: Identifier, -} +pub struct GenericParameter(Identifier); // Generic arguments @@ -86,10 +84,36 @@ pub struct GenericArgument { // Type-use and components +// #[derive(Debug)] +// pub struct TypeUse { +// pub fqn: Fqn, +// pub arguments: Option, +// pub inputs: Option, +// } + #[derive(Debug)] -pub struct TypeUse { +pub enum TypeUse { + InterfaceOrClass(InterfaceOrClassTypeUse), + Tuple(TupleTypeUse), + Function(FunctionTypeUse), +} + +#[derive(Debug)] +pub struct InterfaceOrClassTypeUse { pub fqn: Fqn, - pub arguments: Option, + pub generics: GenericArguments, +} + +#[derive(Debug)] +pub struct TupleTypeUse(pub Vec); + +#[derive(Debug)] +pub struct FunctionTypeUse { + pub function_modifier: Option, + pub generics: GenericParameters, + pub parameters: TupleTypeUse, + pub inputs: InputArguments, + pub return_type: ReturnType, } #[derive(Debug)] @@ -110,7 +134,7 @@ impl TupleArguments { #[derive(Debug)] pub struct FunctionTypeArguments { - pub parameters: Parameters, + pub parameters: TupleParameters, pub return_type: Box, } @@ -133,10 +157,16 @@ pub struct Parameter { #[derive(Debug)] pub struct ReturnType { - pub type_use: Box, + pub declared_type: VoidOrTypeUse, pub references: References, } +#[derive(Debug)] +pub enum VoidOrTypeUse { + Void, + TypeUse(Box), +} + #[derive(Debug)] pub struct References(pub Vec); @@ -147,9 +177,7 @@ impl References { } #[derive(Debug)] -pub struct Reference { - pub identifier: Identifier, -} +pub struct Reference(pub Identifier); // Inputs @@ -180,7 +208,7 @@ impl InputArguments { #[derive(Debug)] pub struct InputArgument { pub lhs: DelegateOrIdentifier, - pub rhs: Identifier + pub rhs: Identifier, } // Where guards @@ -197,7 +225,7 @@ impl WhereGuards { #[derive(Debug)] pub struct WhereGuard { pub identifier: Identifier, - pub implements: ImplementsList + pub implements: ImplementsList, } // Implements @@ -389,7 +417,7 @@ pub struct ClassConstructor(pub Vec); pub struct ClassConstructorParameter { pub is_field: bool, pub identifier: Identifier, - pub declared_type: TypeUse + pub declared_type: TypeUse, } #[derive(Debug)] @@ -469,7 +497,7 @@ pub enum Expression { Unary(UnaryExpression), Assignment(Box), Call(CallExpression), - Literal(Literal) + Literal(Literal), } #[derive(Debug)] @@ -494,7 +522,7 @@ pub struct AssignmentExpression { #[derive(Debug)] pub struct CallExpression { pub callee: Box, - pub arguments: CallArguments + pub arguments: CallArguments, } #[derive(Debug)] diff --git a/src/ast/unparse.rs b/src/ast/unparse.rs index c9922ba..36624d2 100644 --- a/src/ast/unparse.rs +++ b/src/ast/unparse.rs @@ -1,3 +1,4 @@ +use std::fmt::write; use crate::ast::*; macro_rules! to_unparse_vec { @@ -161,7 +162,7 @@ impl ListUnparse for GenericParameters { impl Unparse for GenericParameter { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.identifier.unparse(buf) + self.0.unparse(buf) } } @@ -195,10 +196,58 @@ impl Unparse for GenericArgument { impl Unparse for TypeUse { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.fqn.unparse(buf)?; - if let Some(type_arguments) = &self.arguments { - type_arguments.unparse(buf)?; + use TypeUse::*; + match self { + InterfaceOrClass(interface_or_class_type_use) => interface_or_class_type_use.unparse(buf), + Tuple(tuple_type_use) => tuple_type_use.unparse(buf), + Function(function_type_use) => function_type_use.unparse(buf), } + } +} + +impl Unparse for InterfaceOrClassTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + self.fqn.unparse(buf)?; + self.generics.unparse(buf)?; + unparse_ok!() + } +} + +impl ListUnparse for TupleTypeUse { + fn prefix() -> &'static str { + "(" + } + + fn separator() -> &'static str { + ", " + } + + fn suffix() -> &'static str { + ")" + } + + fn inner(&self) -> Vec<&dyn Unparse> { + to_unparse_vec!(self.0) + } +} + +impl Unparse for FunctionTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + if let Some(function_modifier) = &self.function_modifier { + function_modifier.unparse(buf)?; + } + write!(buf, " fn ")?; + if !self.generics.is_empty() { + self.generics.unparse(buf)?; + write!(buf, " ")?; + } + self.parameters.unparse(buf)?; + write!(buf, " ")?; + if !self.inputs.is_empty() { + self.inputs.unparse(buf)?; + write!(buf, " ")?; + } + self.return_type.unparse(buf)?; unparse_ok!() } } @@ -273,7 +322,7 @@ impl Unparse for Parameter { impl Unparse for ReturnType { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { write!(buf, "-> ")?; - self.type_use.unparse(buf)?; + self.declared_type.unparse(buf)?; if !self.references.is_empty() { self.references.unparse(buf)?; } @@ -281,6 +330,16 @@ impl Unparse for ReturnType { } } +impl Unparse for VoidOrTypeUse { + fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { + use VoidOrTypeUse::*; + match self { + Void => write!(buf, "Void"), + TypeUse(type_use) => type_use.unparse(buf), + } + } +} + impl ListUnparse for References { fn prefix() -> &'static str { "ref " @@ -297,7 +356,7 @@ impl ListUnparse for References { impl Unparse for Reference { fn unparse(&self, buf: &mut dyn std::fmt::Write) -> std::fmt::Result { - self.identifier.unparse(buf) + self.0.unparse(buf) } } diff --git a/src/compile/mod.rs b/src/compile/mod.rs index ca44059..76f380a 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -1,6 +1,6 @@ use crate::ast::{ - AssignExpression, BlockStatement, CallExpression, CompilationUnit, Declaration, Expression, - Fqn, FunctionDeclaration, Identifier, LValue, Statement, + AssignExpression, BlockStatement, CallExpression, CompilationUnit, Expression, Fqn, + FunctionDeclaration, Identifier, LValue, ModuleLevelDeclaration, Statement, }; use crate::object_file::{DvmObjectFile, DvmPath}; use crate::vm::function::DvmFunction; @@ -153,7 +153,7 @@ pub fn convert(file_name: &str, ast: CompilationUnit) -> DvmObjectFile { for declaration in ast.declarations() { match declaration { - Declaration::Function(function_declaration) => { + ModuleLevelDeclaration::Function(function_declaration) => { let function = convert_static_function(&state, &context, function_declaration); object_file.add_function(function); } diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 5bbe47c..4e4ff73 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -123,13 +123,39 @@ IdentifierChar = { // Parameters = declaration TypeUse = { + InterfaceOrClassTypeUse + | TupleTypeUse + | FunctionTypeUse +} + +InterfaceOrClassTypeUse = { FullyQualifiedName + ~ GenericArguments? +} + +TupleTypeUse = { + "(" ~ ( - GenericArguments ~ InputArguments? - | TupleGenericArguments - | FunctionGenericArguments ~ FunctionInputArguments? - | InputArguments + TypeUse + ~ ( "," ~ TypeUse )* )? + ~ ")" +} + +FunctionTypeUse = { + FunctionTypeModifier? + ~ Fn + ~ GenericParameters? + ~ TupleTypeUse + ~ FunctionInputArguments? + ~ ReturnType +} + +FunctionTypeModifier = { + Cons + | Mut ~ Ref + | Mut + | Ref } GenericArguments = { @@ -153,27 +179,6 @@ InputArgument = { ~ ( "=" ~ Identifier ) } -TupleGenericArguments = { - "(" - ~ ( - FullyQualifiedName - ~ ( "," ~ FullyQualifiedName )* - )? - ~ ")" -} - -FunctionGenericArguments = { - TupleGenericArguments - ~ ReturnTypeGenericArgument - ~ FunctionInputArguments? -} - -ReturnTypeGenericArgument = { - "->" - ~ ( Void | FullyQualifiedName ) - ~ RefList? -} - RefList = { Ref ~ Identifier @@ -522,7 +527,7 @@ Field = { FunctionModifier = { Static | Cons - | Mut? Ref? + | Mut? ~ Ref? } FunctionDefinition = {