Much work on grammar, AST building and unparsing.

This commit is contained in:
Jesse Brault 2025-05-13 09:46:12 -05:00
parent e8aff842ed
commit 82af6b4dfb
5 changed files with 324 additions and 398 deletions

View File

@ -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<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!()
}
fn build_prop(prop_pair: Pair<Rule>) -> Declaration {
todo!()
}
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_identifier(identifier_pair: Pair<Rule>) -> Identifier {
Identifier {
name: identifier_pair.as_str().to_string(),
}
}
fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
let mut identifiers: Vec<Identifier> = 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<Rule>) -> CompilationUnit {
let mut namespace: Option<Fqn> = None;
let mut declarations: Vec<Declaration> = vec![];
fn build_type_use(type_use_pair: Pair<Rule>) -> 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<Rule>) -> 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<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 => {
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<Rule>) -> GenericArguments {
let mut generic_arguments: Vec<GenericArgument> = 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<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())
}

View File

@ -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<TypeArguments>,
// pub inputs: Option<InputArguments>,
// }
#[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<TypeArguments>,
pub generics: GenericArguments,
}
#[derive(Debug)]
pub struct TupleTypeUse(pub Vec<TypeUse>);
#[derive(Debug)]
pub struct FunctionTypeUse {
pub function_modifier: Option<FunctionModifier>,
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<TypeUse>,
}
@ -133,10 +157,16 @@ pub struct Parameter {
#[derive(Debug)]
pub struct ReturnType {
pub type_use: Box<TypeUse>,
pub declared_type: VoidOrTypeUse,
pub references: References,
}
#[derive(Debug)]
pub enum VoidOrTypeUse {
Void,
TypeUse(Box<TypeUse>),
}
#[derive(Debug)]
pub struct References(pub Vec<Reference>);
@ -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<ClassConstructorParameter>);
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<AssignmentExpression>),
Call(CallExpression),
Literal(Literal)
Literal(Literal),
}
#[derive(Debug)]
@ -494,7 +522,7 @@ pub struct AssignmentExpression {
#[derive(Debug)]
pub struct CallExpression {
pub callee: Box<Expression>,
pub arguments: CallArguments
pub arguments: CallArguments,
}
#[derive(Debug)]

View File

@ -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)
}
}

View File

@ -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);
}

View File

@ -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 = {