Refactoring grammar to be easier to work with.

This commit is contained in:
Jesse Brault 2025-05-14 17:24:57 -05:00
parent 373120d34e
commit 9df681e07c
4 changed files with 289 additions and 765 deletions

View File

@ -1,16 +1,12 @@
use crate::ast::{
ClassConstructor, ClassConstructorParameter, ClassDeclaration, ClassLevelDeclaration,
CompilationUnit, DelegateOrIdentifier, FieldDeclaration, FullyQualifiedName,
FunctionDeclaration, FunctionModifier, FunctionTypeParameters, FunctionTypeUse,
GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier,
ImplementsList, InputArgument, InputArguments, InputParameter, InputParameters,
InterfaceDeclaration, InterfaceFunctionDeclaration, InterfaceLevelDeclaration,
InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse, ModuleDeclaration,
ModuleLevelDeclaration, OperatorFunctionDeclaration, PlatformFunctionDeclaration,
PropertyDeclaration, Reference, References, ReturnType, TupleTypeUse, TypeDeclaration,
TypeFunctionArguments, TypeGenericArgument, TypeGenericArguments, TypeImplements,
TypeImplementsArguments, TypeImplementsList, TypeTupleArgument, TypeTupleArguments, TypeUse,
TypeWhereGuard, TypeWhereGuards, VoidOrTypeUse,
CompilationUnit, FieldDeclaration, FullyQualifiedName, FunctionDefinition,
FunctionTypeModifier, FunctionTypeUse, GenericArguments, GenericParameter, GenericParameters,
Identifier, ImplementsList, InterfaceDeclaration, InterfaceFunctionDeclaration,
InterfaceLevelDeclaration, InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse,
ModuleDeclaration, ModuleLevelDeclaration, OperatorFunctionDefinition, Parameters,
PlatformFunctionDeclaration, PropertyDeclaration, Reference, References, ReturnType,
TupleArguments, TupleTypeUse, TypeUse,
};
use crate::parser::Rule;
use pest::iterators::Pair;
@ -33,60 +29,41 @@ fn build_identifier(identifier_pair: Pair<Rule>) -> Identifier {
}
fn build_fqn(fqn_pair: Pair<Rule>) -> FullyQualifiedName {
let mut identifiers: Vec<Identifier> = vec![];
for identifier_pair in fqn_pair.into_inner() {
identifiers.push(expect_and_use(
identifier_pair,
Rule::Identifier,
build_identifier,
));
}
FullyQualifiedName { identifiers }
FullyQualifiedName(
fqn_pair
.into_inner()
.map(|identifier_pair| {
expect_and_use(identifier_pair, Rule::Identifier, build_identifier)
})
.collect(),
)
}
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!(),
}
}
fn build_interface_or_class_type_use(pair: Pair<Rule>) -> InterfaceOrClassTypeUse {
let mut borrow_count = 0;
let mut result = None;
for inner_pair in type_use_pair.into_inner() {
let mut is_mutable = false;
let mut fqn = None;
let mut generic_arguments = GenericArguments::default();
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::Borrow => {
borrow_count += 1;
}
Rule::InterfaceOrClassTypeUse => {
result = Some(TypeUse::InterfaceOrClass(
build_interface_or_class_type_use(borrow_count, inner_pair),
));
}
Rule::TupleTypeUse => {
result = Some(TypeUse::Tuple(build_tuple_type_use(
borrow_count,
inner_pair,
)));
}
Rule::FunctionTypeUse => {
result = Some(TypeUse::Function(build_function_type_use(
borrow_count,
inner_pair,
)));
}
_ => unreachable!(),
}
}
result.unwrap()
}
fn build_interface_or_class_type_use(
borrow_count: usize,
pair: Pair<Rule>,
) -> InterfaceOrClassTypeUse {
let mut is_mut = false;
let mut fqn = None;
let mut generic_arguments = GenericArguments(vec![]);
for inner_pair in pair.into_inner() {
match inner_pair.as_rule() {
Rule::Mut => {
is_mut = true;
is_mutable = true;
}
Rule::FullyQualifiedName => {
fqn = Some(build_fqn(inner_pair));
@ -100,42 +77,51 @@ fn build_interface_or_class_type_use(
InterfaceOrClassTypeUse {
borrow_count,
is_mut,
is_mutable,
fqn: fqn.unwrap(),
generics: generic_arguments,
}
}
fn build_tuple_type_use(borrow_count: usize, tuple_type_use_pair: Pair<Rule>) -> TupleTypeUse {
let mut is_mut = false;
let mut type_uses = vec![];
fn build_tuple_type_use(tuple_type_use_pair: Pair<Rule>) -> TupleTypeUse {
let mut borrow_count = 0;
let mut is_mutable = false;
let mut arguments = None;
for inner_pair in tuple_type_use_pair.into_inner() {
match inner_pair.as_rule() {
Rule::Mut => {
is_mut = true;
Rule::Borrow => {
borrow_count += 1;
}
Rule::TypeUse => {
type_uses.push(build_type_use(inner_pair));
Rule::Mut => {
is_mutable = true;
}
Rule::TupleArguments => {
arguments = Some(build_tuple_arguments(inner_pair));
}
_ => unreachable!(),
}
}
TupleTypeUse {
borrow_count,
is_mut,
type_uses,
is_mutable,
arguments: arguments.unwrap(),
}
}
fn build_function_type_use(borrow_count: usize, function_pair: Pair<Rule>) -> FunctionTypeUse {
let mut function_modifier: Option<FunctionModifier> = None;
let mut generics: GenericParameters = GenericParameters(vec![]);
let mut parameters: Option<FunctionTypeParameters> = None;
let mut inputs: InputArguments = InputArguments(vec![]);
fn build_function_type_use(function_pair: Pair<Rule>) -> FunctionTypeUse {
let mut borrow_count = 0;
let mut function_modifier: Option<FunctionTypeModifier> = None;
let mut generics = GenericParameters::default();
let mut parameters: Option<Parameters> = None;
let mut return_type: Option<ReturnType> = None;
for inner_pair in function_pair.into_inner() {
match inner_pair.as_rule() {
Rule::Borrow => {
borrow_count += 1;
}
Rule::FunctionTypeModifier => {
function_modifier = Some(build_function_type_modifier(inner_pair));
}
@ -143,11 +129,8 @@ fn build_function_type_use(borrow_count: usize, function_pair: Pair<Rule>) -> Fu
Rule::GenericParameters => {
generics = build_generic_parameters(inner_pair);
}
Rule::FunctionTypeParameters => {
parameters = Some(build_function_type_parameters(inner_pair));
}
Rule::FunctionInputArguments => {
inputs = build_function_input_arguments(inner_pair);
Rule::Parameters => {
parameters = Some(build_parameters(inner_pair));
}
Rule::ReturnType => {
return_type = Some(build_return_type(inner_pair));
@ -161,32 +144,24 @@ fn build_function_type_use(borrow_count: usize, function_pair: Pair<Rule>) -> Fu
function_modifier,
generics,
parameters: parameters.unwrap(),
inputs,
return_type: return_type.unwrap(),
}
}
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),
}
let type_use_list_pair = generic_arguments_pair.into_inner().next().unwrap();
GenericArguments(
type_use_list_pair
.into_inner()
.map(|type_use_pair| expect_and_use(type_use_pair, Rule::TypeUse, build_type_use))
.collect(),
)
}
fn build_generic_parameters(generic_parameters_pair: Pair<Rule>) -> GenericParameters {
let identifier_list_pair = generic_parameters_pair.into_inner().next().unwrap();
GenericParameters(
generic_parameters_pair
identifier_list_pair
.into_inner()
.map(|identifier_pair| {
GenericParameter(expect_and_use(
@ -199,101 +174,21 @@ fn build_generic_parameters(generic_parameters_pair: Pair<Rule>) -> GenericParam
)
}
fn build_function_type_parameters(
function_type_parameters_pair: Pair<Rule>,
) -> FunctionTypeParameters {
FunctionTypeParameters(
function_type_parameters_pair
fn build_tuple_arguments(tuple_arguments_pair: Pair<Rule>) -> TupleArguments {
let parentheses_optional_type_use_list_pair = tuple_arguments_pair.into_inner().next().unwrap();
let type_use_list_pair = parentheses_optional_type_use_list_pair
.into_inner()
.next()
.unwrap();
TupleArguments(
type_use_list_pair
.into_inner()
.map(|type_use_pair| expect_and_use(type_use_pair, Rule::TypeUse, build_type_use))
.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_function_type_modifier(function_type_modifier_pair: Pair<Rule>) -> FunctionModifier {
let mut inner = function_type_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_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(),
)
}
fn build_input_parameters(pair: Pair<Rule>) -> InputParameters {
InputParameters(
pair.into_inner()
.map(|type_use_pair| {
InputParameter(expect_and_use(type_use_pair, Rule::TypeUse, build_type_use))
})
.collect(),
)
}
fn build_implements_list(pair: Pair<Rule>) -> ImplementsList {
ImplementsList(
pair.into_inner()
@ -302,6 +197,61 @@ fn build_implements_list(pair: Pair<Rule>) -> ImplementsList {
)
}
fn build_function_type_modifier(pair: Pair<Rule>) -> FunctionTypeModifier {
let mut inner = pair.into_inner();
if inner.len() == 2 {
FunctionTypeModifier::MutRef
} else {
match inner.next().unwrap().as_rule() {
Rule::Cons => FunctionTypeModifier::Cons,
Rule::Mut => FunctionTypeModifier::Mut,
Rule::Ref => FunctionTypeModifier::Ref,
_ => unreachable!(),
}
}
}
fn build_parameters(pair: Pair<Rule>) -> Parameters {
todo!()
}
fn build_parameter(pair: Pair<Rule>) -> Parameters {
todo!()
}
fn build_return_type(return_type_pair: Pair<Rule>) -> ReturnType {
let mut inner = return_type_pair.into_inner();
let declared_type = expect_and_use(inner.next().unwrap(), Rule::TypeUse, build_type_use);
let references = inner
.next()
.map(|ref_list_pair| expect_and_use(ref_list_pair, Rule::RefList, build_references))
.unwrap_or_else(References::default);
ReturnType {
declared_type: Box::new(declared_type),
references,
}
}
fn build_references(ref_list_pair: Pair<Rule>) -> References {
let mut inner = ref_list_pair.into_inner();
inner.next().unwrap(); // ref
References(
inner
.map(|identifier_pair| {
Reference(expect_and_use(
identifier_pair,
Rule::Identifier,
build_identifier,
))
})
.collect(),
)
}
fn build_compilation_unit(compilation_unit_pair: Pair<Rule>) -> CompilationUnit {
let mut namespace = None;
let mut declarations = vec![];
@ -327,13 +277,12 @@ fn build_compilation_unit(compilation_unit_pair: Pair<Rule>) -> CompilationUnit
fn build_namespace(namespace_pair: Pair<Rule>) -> FullyQualifiedName {
let mut inner = namespace_pair.into_inner();
inner.next(); // ns
build_fqn(inner.next().unwrap())
expect_and_use(inner.next().unwrap(), Rule::FullyQualifiedName, build_fqn)
}
fn build_module_level_declaration(pair: Pair<Rule>) -> ModuleLevelDeclaration {
let inner_pair = pair.into_inner().next().unwrap();
match inner_pair.as_rule() {
Rule::Type => ModuleLevelDeclaration::Type(build_type_declaration(inner_pair)),
Rule::Module => ModuleLevelDeclaration::Module(build_module_declaration(inner_pair)),
Rule::Interface => {
ModuleLevelDeclaration::Interface(build_interface_declaration(inner_pair))
@ -352,7 +301,6 @@ fn build_module_level_declaration(pair: Pair<Rule>) -> ModuleLevelDeclaration {
fn build_interface_level_declaration(declaration_pair: Pair<Rule>) -> InterfaceLevelDeclaration {
let inner_pair = declaration_pair.into_inner().next().unwrap();
match inner_pair.as_rule() {
Rule::Type => InterfaceLevelDeclaration::Type(build_type_declaration(inner_pair)),
Rule::Module => InterfaceLevelDeclaration::Module(build_module_declaration(inner_pair)),
Rule::Interface => {
InterfaceLevelDeclaration::Interface(build_interface_declaration(inner_pair))
@ -377,7 +325,6 @@ fn build_interface_level_declaration(declaration_pair: Pair<Rule>) -> InterfaceL
fn build_class_level_declaration(declaration_pair: Pair<Rule>) -> ClassLevelDeclaration {
let inner_pair = declaration_pair.into_inner().next().unwrap();
match inner_pair.as_rule() {
Rule::Type => ClassLevelDeclaration::Type(build_type_declaration(inner_pair)),
Rule::Module => ClassLevelDeclaration::Module(build_module_declaration(inner_pair)),
Rule::Interface => {
ClassLevelDeclaration::Interface(build_interface_declaration(inner_pair))
@ -429,10 +376,8 @@ fn build_module_declaration(module_pair: Pair<Rule>) -> ModuleDeclaration {
fn build_interface_declaration(interface_pair: Pair<Rule>) -> InterfaceDeclaration {
let mut is_public = false;
let mut identifier = None;
let mut generics = GenericParameters(vec![]);
let mut inputs = InputParameters(vec![]);
let mut return_type = None;
let mut implements = ImplementsList(vec![]);
let mut generics = None;
let mut implements = None;
let mut declarations = vec![];
for inner_pair in interface_pair.into_inner() {
@ -445,16 +390,10 @@ fn build_interface_declaration(interface_pair: Pair<Rule>) -> InterfaceDeclarati
identifier = Some(build_identifier(inner_pair));
}
Rule::GenericParameters => {
generics = build_generic_parameters(inner_pair);
}
Rule::InputParameters => {
inputs = build_input_parameters(inner_pair);
}
Rule::ReturnType => {
return_type = Some(build_return_type(inner_pair));
generics = Some(build_generic_parameters(inner_pair));
}
Rule::ImplementsList => {
implements = build_implements_list(inner_pair);
implements = Some(build_implements_list(inner_pair));
}
Rule::InterfaceLevelDeclaration => {
declarations.push(build_interface_level_declaration(inner_pair));
@ -466,10 +405,8 @@ fn build_interface_declaration(interface_pair: Pair<Rule>) -> InterfaceDeclarati
InterfaceDeclaration {
is_public,
identifier: identifier.unwrap(),
generics,
inputs,
return_type,
implements,
generics: generics.unwrap_or_else(GenericParameters::default),
implements: implements.unwrap_or_else(ImplementsList::default),
declarations,
}
}
@ -477,9 +414,9 @@ fn build_interface_declaration(interface_pair: Pair<Rule>) -> InterfaceDeclarati
fn build_class_declaration(class_pair: Pair<Rule>) -> ClassDeclaration {
let mut is_public = false;
let mut identifier = None;
let mut generics = GenericParameters(vec![]);
let mut generics = None;
let mut class_constructor = None;
let mut implements = ImplementsList(vec![]);
let mut implements = None;
let mut declarations = vec![];
for inner_pair in class_pair.into_inner() {
@ -492,13 +429,13 @@ fn build_class_declaration(class_pair: Pair<Rule>) -> ClassDeclaration {
identifier = Some(build_identifier(inner_pair));
}
Rule::GenericParameters => {
generics = build_generic_parameters(inner_pair);
generics = Some(build_generic_parameters(inner_pair));
}
Rule::ClassConstructor => {
class_constructor = Some(build_class_constructor(inner_pair));
}
Rule::ImplementsList => {
implements = build_implements_list(inner_pair);
implements = Some(build_implements_list(inner_pair));
}
Rule::ClassLevelDeclaration => {
declarations.push(build_class_level_declaration(inner_pair));
@ -510,237 +447,20 @@ fn build_class_declaration(class_pair: Pair<Rule>) -> ClassDeclaration {
ClassDeclaration {
is_public,
identifier: identifier.unwrap(),
generics,
generics: generics.unwrap_or_else(GenericParameters::default),
class_constructor,
implements,
implements: implements.unwrap_or_else(ImplementsList::default),
declarations,
}
}
fn build_type_declaration(type_pair: Pair<Rule>) -> TypeDeclaration {
let mut is_public = false;
let mut identifier = None;
let mut lhs = None;
let mut where_guards = TypeWhereGuards(vec![]);
let mut rhs = None;
for inner_pair in type_pair.into_inner() {
match inner_pair.as_rule() {
Rule::Pub => is_public = true,
Rule::TypeKw => {}
Rule::Identifier => {
identifier = Some(build_identifier(inner_pair));
}
Rule::TypeUse => {
if lhs.is_none() {
lhs = Some(build_type_use(inner_pair));
} else {
rhs = Some(build_type_use(inner_pair));
}
}
Rule::TypeWhereGuards => {
where_guards = build_type_where_guards(inner_pair);
}
_ => unreachable!(),
}
}
TypeDeclaration {
is_public,
identifier: identifier.unwrap(),
lhs: lhs.unwrap(),
where_guards,
rhs: rhs.unwrap(),
}
}
fn build_type_where_guards(type_where_guards_pair: Pair<Rule>) -> TypeWhereGuards {
let mut inner = type_where_guards_pair.into_inner();
inner.next(); // where
TypeWhereGuards(
inner
.map(|type_where_guard_pair| {
expect_and_use(
type_where_guard_pair,
Rule::TypeWhereGuard,
build_type_where_guard,
)
})
.collect(),
)
}
fn build_type_where_guard(type_where_guard_pair: Pair<Rule>) -> TypeWhereGuard {
let mut inner = type_where_guard_pair.into_inner();
let identifier = expect_and_use(inner.next().unwrap(), Rule::Identifier, build_identifier);
let implements = expect_and_use(
inner.next().unwrap(),
Rule::TypeImplementsList,
build_type_implements_list,
);
TypeWhereGuard {
identifier,
implements,
}
}
fn build_type_implements_list(type_implements_list_pair: Pair<Rule>) -> TypeImplementsList {
TypeImplementsList(
type_implements_list_pair
.into_inner()
.map(|type_implements_pair| {
expect_and_use(
type_implements_pair,
Rule::TypeImplements,
build_type_implements,
)
})
.collect(),
)
}
fn build_type_implements(type_implements_pair: Pair<Rule>) -> TypeImplements {
let mut inner = type_implements_pair.into_inner();
let fqn = expect_and_use(inner.next().unwrap(), Rule::FullyQualifiedName, build_fqn);
let arguments = expect_and_use(
inner.next().unwrap(),
Rule::TypeImplementsArguments,
build_type_implements_arguments,
);
TypeImplements { fqn, arguments }
}
fn build_type_implements_arguments(
type_implements_arguments_pair: Pair<Rule>,
) -> TypeImplementsArguments {
let inner_pair = type_implements_arguments_pair.into_inner().next().unwrap();
match inner_pair.as_rule() {
Rule::TypeGenericArguments => {
TypeImplementsArguments::Generic(build_type_generic_arguments(inner_pair))
}
Rule::TypeTupleArguments => {
TypeImplementsArguments::Tuple(build_type_tuple_arguments(inner_pair))
}
Rule::TypeFunctionArguments => {
TypeImplementsArguments::Function(build_type_function_arguments(inner_pair))
}
_ => unreachable!(),
}
}
fn build_type_generic_arguments(type_generic_arguments_pair: Pair<Rule>) -> TypeGenericArguments {
TypeGenericArguments(
type_generic_arguments_pair
.into_inner()
.map(|type_generic_argument_pair| {
expect_and_use(
type_generic_argument_pair,
Rule::TypeGenericArgument,
build_type_generic_argument,
)
})
.collect(),
)
}
fn build_type_generic_argument(type_generic_argument_pair: Pair<Rule>) -> TypeGenericArgument {
let mut inner = type_generic_argument_pair.into_inner();
if inner.len() == 2 {
inner.next(); // infer
TypeGenericArgument::Infer(expect_and_use(
inner.next().unwrap(),
Rule::Identifier,
build_identifier,
))
} else {
let inner_pair = inner.next().unwrap();
match inner_pair.as_rule() {
Rule::Underscore => TypeGenericArgument::Underscore,
Rule::FullyQualifiedName => {
TypeGenericArgument::FullyQualifiedName(build_fqn(inner_pair))
}
_ => unreachable!(),
}
}
}
fn build_type_tuple_arguments(type_tuple_arguments_pair: Pair<Rule>) -> TypeTupleArguments {
TypeTupleArguments(
type_tuple_arguments_pair
.into_inner()
.map(|type_tuple_argument_pair| {
expect_and_use(
type_tuple_argument_pair,
Rule::TypeTupleArgument,
build_type_tuple_argument,
)
})
.collect(),
)
}
fn build_type_tuple_argument(type_tuple_argument_pair: Pair<Rule>) -> TypeTupleArgument {
let mut inner = type_tuple_argument_pair.into_inner();
let first = inner.next().unwrap();
match first.as_rule() {
Rule::Underscore => TypeTupleArgument::Underscore,
Rule::FullyQualifiedName => TypeTupleArgument::FullyQualifiedName(build_fqn(first)),
Rule::Infer => {
let second = inner.next().unwrap();
TypeTupleArgument::Infer(expect_and_use(second, Rule::Identifier, build_identifier))
}
Rule::Ellipsis => {
let second = inner.next().unwrap();
match second.as_rule() {
Rule::Underscore => TypeTupleArgument::EllipsisUnderscore,
Rule::Infer => TypeTupleArgument::EllipsisInfer(expect_and_use(
inner.next().unwrap(),
Rule::Identifier,
build_identifier,
)),
_ => unreachable!(),
}
}
_ => unreachable!(),
}
}
fn build_type_function_arguments(
type_function_arguments_pair: Pair<Rule>,
) -> TypeFunctionArguments {
let mut generics = TypeGenericArguments(vec![]);
let mut parameters = None;
let mut return_type = None;
for inner_pair in type_function_arguments_pair.into_inner() {
match inner_pair.as_rule() {
Rule::TypeGenericArguments => {
generics = build_type_generic_arguments(inner_pair);
}
Rule::TypeTupleArguments => {
parameters = Some(build_type_tuple_arguments(inner_pair));
}
Rule::ReturnType => {
return_type = Some(build_return_type(inner_pair));
}
_ => unreachable!(),
}
}
TypeFunctionArguments {
generics,
parameters: parameters.unwrap(),
return_type: return_type.unwrap(),
}
}
fn build_function_declaration(function_definition_pair: Pair<Rule>) -> FunctionDeclaration {
fn build_function_declaration(function_definition_pair: Pair<Rule>) -> FunctionDefinition {
todo!()
}
fn build_operator_function_declaration(
operator_function_pair: Pair<Rule>,
) -> OperatorFunctionDeclaration {
) -> OperatorFunctionDefinition {
todo!()
}

View File

@ -54,9 +54,7 @@ pub struct Identifier {
}
#[derive(Debug)]
pub struct FullyQualifiedName {
pub identifiers: Vec<Identifier>,
}
pub struct FullyQualifiedName(pub Vec<Identifier>);
/* Type Use */
@ -70,7 +68,7 @@ pub enum TypeUse {
#[derive(Debug)]
pub struct InterfaceOrClassTypeUse {
pub borrow_count: usize,
pub is_mut: bool,
pub is_mutable: bool,
pub fqn: FullyQualifiedName,
pub generics: GenericArguments,
}
@ -78,24 +76,23 @@ pub struct InterfaceOrClassTypeUse {
#[derive(Debug)]
pub struct TupleTypeUse {
pub borrow_count: usize,
pub is_mut: bool,
pub type_uses: Vec<TypeUse>,
pub is_mutable: bool,
pub arguments: TupleArguments,
}
#[derive(Debug)]
pub struct FunctionTypeUse {
pub borrow_count: usize,
pub function_modifier: Option<FunctionModifier>,
pub function_modifier: Option<FunctionTypeModifier>,
pub generics: GenericParameters,
pub parameters: FunctionTypeParameters,
pub inputs: InputArguments,
pub parameters: Parameters,
pub return_type: ReturnType,
}
// Generic arguments
#[derive(Debug)]
pub struct GenericArguments(pub Vec<GenericArgument>);
pub struct GenericArguments(pub Vec<TypeUse>);
impl GenericArguments {
pub fn is_empty(&self) -> bool {
@ -103,20 +100,10 @@ impl GenericArguments {
}
}
#[derive(Debug)]
pub struct GenericArgument {
pub fqn: FullyQualifiedName,
}
/* Function Modifier */
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
impl Default for GenericArguments {
fn default() -> Self {
GenericArguments(Vec::new())
}
}
/* Generic parameters */
@ -130,38 +117,48 @@ impl GenericParameters {
}
}
#[derive(Debug)]
pub struct GenericParameter(Identifier);
/* Function Type Parameters */
impl Default for GenericParameters {
fn default() -> Self {
GenericParameters(Vec::new())
}
}
#[derive(Debug)]
pub struct FunctionTypeParameters(pub Vec<TypeUse>);
pub struct GenericParameter(pub Identifier);
/* Input Arguments */
/* Tuple Arguments */
#[derive(Debug)]
pub struct InputArguments(pub Vec<InputArgument>);
pub struct TupleArguments(pub Vec<TypeUse>);
impl InputArguments {
/* Implements List */
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
impl ImplementsList {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArgument {
pub lhs: DelegateOrIdentifier,
pub rhs: Identifier,
impl Default for ImplementsList {
fn default() -> Self {
ImplementsList(Vec::new())
}
}
/* Function Type Modifier and Function Modifier */
#[derive(Debug)]
pub enum DelegateOrIdentifier {
Delegate,
Identifier(Identifier),
pub enum FunctionTypeModifier {
Cons,
MutRef,
Mut,
Ref,
}
// Function components
/* Function Parameters */
#[derive(Debug)]
pub struct Parameters(pub Vec<Parameter>);
@ -172,22 +169,24 @@ impl Parameters {
}
}
impl Default for Parameters {
fn default() -> Self {
Parameters(Vec::new())
}
}
#[derive(Debug)]
pub struct Parameter {
identifier: Identifier,
type_use: TypeUse,
}
#[derive(Debug)]
pub struct ReturnType {
pub declared_type: VoidOrTypeUse,
pub references: References,
}
/* Return Type */
#[derive(Debug)]
pub enum VoidOrTypeUse {
Void,
TypeUse(Box<TypeUse>),
pub struct ReturnType {
pub declared_type: Box<TypeUse>,
pub references: References,
}
#[derive(Debug)]
@ -199,29 +198,16 @@ impl References {
}
}
#[derive(Debug)]
pub struct Reference(pub Identifier);
/* Input Parameters */
#[derive(Debug)]
pub struct InputParameters(pub Vec<InputParameter>);
#[derive(Debug)]
pub struct InputParameter(pub TypeUse);
// Implements
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
impl ImplementsList {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
impl Default for References {
fn default() -> Self {
References(Vec::new())
}
}
// Top-level construct
#[derive(Debug)]
pub struct Reference(pub Identifier);
/* Top-level construct */
#[derive(Debug)]
pub struct CompilationUnit {
@ -233,17 +219,15 @@ pub struct CompilationUnit {
#[derive(Debug)]
pub enum ModuleLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDeclaration),
Function(FunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
}
#[derive(Debug)]
pub enum InterfaceLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
@ -253,12 +237,11 @@ pub enum InterfaceLevelDeclaration {
#[derive(Debug)]
pub enum ClassLevelDeclaration {
Type(TypeDeclaration),
Module(ModuleDeclaration),
Interface(InterfaceDeclaration),
Class(ClassDeclaration),
Function(FunctionDeclaration),
OperatorFunction(OperatorFunctionDeclaration),
Function(FunctionDefinition),
OperatorFunction(OperatorFunctionDefinition),
PlatformFunction(PlatformFunctionDeclaration),
Property(PropertyDeclaration),
Field(FieldDeclaration),
@ -266,15 +249,6 @@ pub enum ClassLevelDeclaration {
// Declarations
#[derive(Debug)]
pub struct TypeDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub lhs: TypeUse,
pub where_guards: TypeWhereGuards,
pub rhs: TypeUse,
}
#[derive(Debug)]
pub struct ModuleDeclaration {
pub is_public: bool,
@ -287,8 +261,6 @@ pub struct InterfaceDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
pub inputs: InputParameters,
pub return_type: Option<ReturnType>,
pub implements: ImplementsList,
pub declarations: Vec<InterfaceLevelDeclaration>,
}
@ -303,83 +275,27 @@ pub struct ClassDeclaration {
pub declarations: Vec<ClassLevelDeclaration>,
}
// Type components
#[derive(Debug)]
pub struct TypeWhereGuards(pub Vec<TypeWhereGuard>);
#[derive(Debug)]
pub struct TypeWhereGuard {
pub identifier: Identifier,
pub implements: TypeImplementsList,
}
#[derive(Debug)]
pub struct TypeImplementsList(pub Vec<TypeImplements>);
#[derive(Debug)]
pub struct TypeImplements {
pub fqn: FullyQualifiedName,
pub arguments: TypeImplementsArguments,
}
#[derive(Debug)]
pub enum TypeImplementsArguments {
Generic(TypeGenericArguments),
Tuple(TypeTupleArguments),
Function(TypeFunctionArguments),
}
#[derive(Debug)]
pub struct TypeGenericArguments(pub Vec<TypeGenericArgument>);
#[derive(Debug)]
pub enum TypeGenericArgument {
Underscore,
FullyQualifiedName(FullyQualifiedName),
Infer(Identifier),
}
#[derive(Debug)]
pub struct TypeTupleArguments(pub Vec<TypeTupleArgument>);
#[derive(Debug)]
pub enum TypeTupleArgument {
Underscore,
FullyQualifiedName(FullyQualifiedName),
Infer(Identifier),
EllipsisUnderscore,
EllipsisInfer(Identifier),
}
#[derive(Debug)]
pub struct TypeFunctionArguments {
pub generics: TypeGenericArguments,
pub parameters: TypeTupleArguments,
pub return_type: ReturnType,
}
// Function declarations and components
#[derive(Debug)]
pub struct FunctionDeclaration {
pub struct FunctionDefinition {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: Option<ReturnType>,
pub return_type: ReturnType,
pub body: FunctionBody,
}
#[derive(Debug)]
pub struct OperatorFunctionDeclaration {
pub struct OperatorFunctionDefinition {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub operator: Operator,
pub parameters: Parameters,
pub return_type: Option<ReturnType>,
pub return_type: ReturnType,
pub body: FunctionBody,
}
@ -390,7 +306,7 @@ pub struct PlatformFunctionDeclaration {
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: TypeUse,
pub return_type: ReturnType,
}
#[derive(Debug)]
@ -413,6 +329,15 @@ pub struct InterfaceOperatorFunctionDeclaration {
pub body: Option<FunctionBody>,
}
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
}
#[derive(Debug)]
pub enum FunctionBody {
Equals(Expression),

View File

@ -114,7 +114,7 @@ Operator = {
| Star
}
// Commonly shared constructs
// Names
Identifier = @{
( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar )
@ -139,41 +139,59 @@ FullyQualifiedName = {
~ ( "::" ~ Identifier )*
}
// Common lists
TypeUseList = {
TypeUse
~ ( "," ~ TypeUse )*
}
IdentifierList = {
Identifier
~ ( "," ~ Identifier )*
}
ParenthesesTypeUseList = {
"("
~ TypeUseList
~ ")"
}
ParenthesesOptionalTypeUseList = {
"("
~ TypeUseList?
~ ")"
}
// In general:
// Arguments = usage
// Parameters = declaration
TypeUse = {
Borrow*
~ (
InterfaceOrClassTypeUse
| TupleTypeUse
| FunctionTypeUse
)
InterfaceOrClassTypeUse
| TupleTypeUse
| FunctionTypeUse
}
InterfaceOrClassTypeUse = {
Mut?
Borrow*
~ Mut?
~ FullyQualifiedName
~ GenericArguments?
}
TupleTypeUse = {
Mut?
~ "("
~ (
TypeUse
~ ( "," ~ TypeUse )*
)?
~ ")"
Borrow*
~ Mut?
~ TupleArguments
}
FunctionTypeUse = {
FunctionTypeModifier?
Borrow*
~ FunctionTypeModifier?
~ Fn
~ GenericParameters?
~ FunctionTypeParameters
~ FunctionInputArguments?
~ Parameters
~ ReturnType
}
@ -181,8 +199,7 @@ FunctionTypeUse = {
GenericArguments = {
"<"
~ FullyQualifiedName
~ ( "," ~ FullyQualifiedName )*
~ TypeUseList
~ ">"
}
@ -190,39 +207,25 @@ GenericArguments = {
GenericParameters = {
"<"
~ Identifier
~ ( "," ~ Identifier )*
~ IdentifierList
~ ">"
}
// Function Type Parameters
// Tuple Arguments
FunctionTypeParameters = {
"("
~ (
TypeUse
~ ( "," ~ TypeUse )*
)?
~ ")"
TupleArguments = {
ParenthesesOptionalTypeUseList
}
// Function Input Arguments
// Implements list
FunctionInputArguments = {
"|"
~ (
FunctionInputArgument
~ ( "," ~ FunctionInputArgument )*
)?
~ "|"
ImplementsList = {
":"
~ TypeUse
~ ( "+" ~ TypeUse )*
}
FunctionInputArgument = {
( Delegate ~ "=" ~ Identifier )
| Identifier
}
// Function type components
// Function type modifier
FunctionTypeModifier = {
Cons
@ -231,6 +234,8 @@ FunctionTypeModifier = {
| Ref
}
// Parameters
Parameters = {
"("
~ (
@ -246,35 +251,18 @@ Parameter = {
~ TypeUse
}
// Return type
ReturnType = {
"->"
~ ( Void | TypeUse )
~ TypeUse
~ RefList?
}
RefList = {
Ref
~ Identifier
~ ( "," ~ Identifier )*
}
// Input Parameters
InputParameters = {
"("
~ (
TypeUse
~ ( "," ~ TypeUse )*
)?
~ ")"
}
// Implements list
ImplementsList = {
":"
~ TypeUse
~ ( "+" ~ TypeUse )*
~ ( "," ~ Identifier )
}
// Top-level constructs
@ -294,8 +282,7 @@ Namespace = {
// Organizational declarations
ModuleLevelDeclaration = {
Type
| Module
Module
| Interface
| Class
| FunctionDefinition
@ -303,8 +290,7 @@ ModuleLevelDeclaration = {
}
InterfaceLevelDeclaration = {
Type
| Module
Module
| Interface
| Class
| InterfaceFunction
@ -314,8 +300,7 @@ InterfaceLevelDeclaration = {
}
ClassLevelDeclaration = {
Type
| Module
Module
| Interface
| Class
| FunctionDefinition
@ -327,16 +312,6 @@ ClassLevelDeclaration = {
// Main organizational constructs
Type = {
Pub?
~ TypeKw
~ Identifier
~ TypeUse
~ TypeWhereGuards?
~ "="
~ TypeUse
}
Module = {
Pub?
~ Mod
@ -349,8 +324,6 @@ Interface = {
~ Int
~ Identifier
~ GenericParameters?
~ InputParameters?
~ ReturnType?
~ ImplementsList?
~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )?
}
@ -365,77 +338,11 @@ Class = {
~ ( "{" ~ ClassLevelDeclaration* ~ "}" )?
}
// Type
TypeWhereGuards = {
Where
~ TypeWhereGuard
~ ( "," ~ TypeWhereGuard )*
}
TypeWhereGuard = {
Identifier
~ ":"
~ TypeImplementsList
}
TypeImplementsList = {
TypeImplements
~ ( "+" ~ TypeImplements )*
}
TypeImplements = {
FullyQualifiedName
~ TypeImplementsArguments?
}
TypeImplementsArguments = {
TypeGenericArguments
| TypeTupleArguments
| TypeFunctionArguments
}
TypeGenericArguments = {
"<"
~ TypeGenericArgument
~ ( "," ~ TypeGenericArgument )*
~ ">"
}
TypeGenericArgument = {
Underscore
| FullyQualifiedName
| ( Infer ~ Identifier )
}
TypeTupleArguments = {
"("
~ (
TypeTupleArgument
~ ( "," ~ TypeTupleArgument )*
)?
~ ")"
}
TypeTupleArgument = {
Underscore
| FullyQualifiedName
| ( Infer ~ Identifier )
| ( Ellipsis ~ Underscore )
| ( Ellipsis ~ Infer ~ Identifier )
}
TypeFunctionArguments = {
TypeGenericArguments?
~ TypeTupleArguments
~ ReturnType
}
// Function constructs
FunctionDefinition = {
Pub?
~ FunctionModifier
~ FunctionModifier?
~ Fn
~ GenericParameters?
~ Identifier
@ -446,8 +353,9 @@ FunctionDefinition = {
OperatorFunctionDefinition = {
Pub?
~ FunctionModifier
~ FunctionModifier?
~ Op
~ GenericParameters?
~ Operator
~ Parameters
~ ReturnType?
@ -456,21 +364,17 @@ OperatorFunctionDefinition = {
PlatformFunction = {
Pub?
~ FunctionModifier
~ FunctionModifier?
~ Platform
~ Fn
~ GenericParameters
~ GenericParameters?
~ Identifier
~ Parameters
~ ReturnType
}
InterfaceFunction = {
(
Static
| Cons
| ( Mut ~ Ref? )
)?
FunctionModifier?
~ Fn
~ GenericParameters?
~ Identifier
@ -480,11 +384,7 @@ InterfaceFunction = {
InterfaceDefaultFunction = {
Def
~ (
Static
| Cons
| ( Mut ~ Ref? )
)?
~ FunctionModifier?
~ Fn
~ GenericParameters?
~ Identifier
@ -494,11 +394,9 @@ InterfaceDefaultFunction = {
}
InterfaceOperatorFunction = {
(
Cons
| ( Mut ~ Ref? )
)?
FunctionModifier?
~ Op
~ GenericParameters?
~ Operator
~ Parameters
~ ReturnType
@ -506,10 +404,7 @@ InterfaceOperatorFunction = {
InterfaceDefaultOperatorFunction = {
Def
~ (
Cons
| ( Mut ~ Ref? )
)?
~ FunctionModifier?
~ Op
~ Operator
~ Parameters
@ -521,7 +416,9 @@ InterfaceDefaultOperatorFunction = {
FunctionModifier = {
Static
| Cons
| Mut? ~ Ref?
| Mut ~ Ref
| Mut
| Ref
}
FunctionBody = {

View File

@ -8,7 +8,7 @@ pub struct DeimosParser;
mod deimos_parser_tests {
use crate::parser::{DeimosParser, Rule};
use pest::iterators::Pair;
use pest::Parser;
use pest::{parses_to, Parser};
macro_rules! fail_rule {
($pair: expr; $rule:path) => {{
@ -77,25 +77,7 @@ mod deimos_parser_tests {
#[test]
fn identifier_call_as_expression() {
let pair = parse(Rule::Expression, "foo()");
match_inner_rules!(pair; Rule::Expression, Rule::OrExpression, Rule::AndExpression, Rule::EqualityExpression, Rule::ComparisonExpression, Rule::AdditiveExpression, Rule::MultiplicativeExpression, Rule::UnaryExpression; |unary_expression: Pair<Rule>| {
let mut unary_pairs = unary_expression.into_inner();
let primary_expression = unary_pairs.next().unwrap();
match_rule!(primary_expression; Rule::PrimaryExpression);
let call = unary_pairs.next().unwrap();
match_rule!(call; Rule::Call);
});
}
#[test]
fn identifier_call_as_call_expression() {
let pair = parse(Rule::CallExpression, "foo()");
match_rule!(pair; Rule::CallExpression);
let mut call_expression_pairs = pair.into_inner();
let primary_expression = call_expression_pairs.next().unwrap();
match_rule!(primary_expression; Rule::PrimaryExpression);
let call = call_expression_pairs.next().unwrap();
match_rule!(call; Rule::Call);
parse(Rule::Expression, "foo()");
}
mod smoke_screen_tests {