857 lines
28 KiB
Rust
857 lines
28 KiB
Rust
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,
|
|
};
|
|
use crate::parser::Rule;
|
|
use pest::iterators::Pair;
|
|
|
|
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 {
|
|
build_compilation_unit(compilation_unit_pair)
|
|
}
|
|
|
|
fn build_identifier(identifier_pair: Pair<Rule>) -> Identifier {
|
|
Identifier {
|
|
name: identifier_pair.as_str().to_string(),
|
|
}
|
|
}
|
|
|
|
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 }
|
|
}
|
|
|
|
fn build_type_use(type_use_pair: Pair<Rule>) -> TypeUse {
|
|
let mut borrow_count = 0;
|
|
let mut result = None;
|
|
for inner_pair in type_use_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;
|
|
}
|
|
Rule::FullyQualifiedName => {
|
|
fqn = Some(build_fqn(inner_pair));
|
|
}
|
|
Rule::GenericArguments => {
|
|
generic_arguments = build_generic_arguments(inner_pair);
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
InterfaceOrClassTypeUse {
|
|
borrow_count,
|
|
is_mut,
|
|
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![];
|
|
for inner_pair in tuple_type_use_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Mut => {
|
|
is_mut = true;
|
|
}
|
|
Rule::TypeUse => {
|
|
type_uses.push(build_type_use(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
TupleTypeUse {
|
|
borrow_count,
|
|
is_mut,
|
|
type_uses,
|
|
}
|
|
}
|
|
|
|
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![]);
|
|
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_type_modifier(inner_pair));
|
|
}
|
|
Rule::Fn => {}
|
|
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::ReturnType => {
|
|
return_type = Some(build_return_type(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
FunctionTypeUse {
|
|
borrow_count,
|
|
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),
|
|
}
|
|
}
|
|
|
|
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_type_parameters(
|
|
function_type_parameters_pair: Pair<Rule>,
|
|
) -> FunctionTypeParameters {
|
|
FunctionTypeParameters(
|
|
function_type_parameters_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()
|
|
.map(|type_use_pair| expect_and_use(type_use_pair, Rule::TypeUse, build_type_use))
|
|
.collect(),
|
|
)
|
|
}
|
|
|
|
fn build_compilation_unit(compilation_unit_pair: Pair<Rule>) -> CompilationUnit {
|
|
let mut namespace = None;
|
|
let mut declarations = vec![];
|
|
|
|
for inner_pair in compilation_unit_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Namespace => {
|
|
namespace = Some(build_namespace(inner_pair));
|
|
}
|
|
Rule::ModuleLevelDeclaration => {
|
|
declarations.push(build_module_level_declaration(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
CompilationUnit {
|
|
namespace,
|
|
declarations,
|
|
}
|
|
}
|
|
|
|
fn build_namespace(namespace_pair: Pair<Rule>) -> FullyQualifiedName {
|
|
let mut inner = namespace_pair.into_inner();
|
|
inner.next(); // ns
|
|
build_fqn(inner.next().unwrap())
|
|
}
|
|
|
|
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))
|
|
}
|
|
Rule::Class => ModuleLevelDeclaration::Class(build_class_declaration(inner_pair)),
|
|
Rule::FunctionDefinition => {
|
|
ModuleLevelDeclaration::Function(build_function_declaration(inner_pair))
|
|
}
|
|
Rule::PlatformFunction => ModuleLevelDeclaration::PlatformFunction(
|
|
build_platform_function_declaration(inner_pair),
|
|
),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
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))
|
|
}
|
|
Rule::Class => InterfaceLevelDeclaration::Class(build_class_declaration(inner_pair)),
|
|
Rule::InterfaceFunction => {
|
|
InterfaceLevelDeclaration::Function(build_interface_function_declaration(inner_pair))
|
|
}
|
|
Rule::InterfaceDefaultFunction => InterfaceLevelDeclaration::Function(
|
|
build_default_interface_function_declaration(inner_pair),
|
|
),
|
|
Rule::InterfaceOperatorFunction => InterfaceLevelDeclaration::OperatorFunction(
|
|
build_interface_operator_function_declaration(inner_pair),
|
|
),
|
|
Rule::InterfaceDefaultOperatorFunction => InterfaceLevelDeclaration::OperatorFunction(
|
|
build_default_interface_operator_function_declaration(inner_pair),
|
|
),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
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))
|
|
}
|
|
Rule::Class => ClassLevelDeclaration::Class(build_class_declaration(inner_pair)),
|
|
Rule::FunctionDefinition => {
|
|
ClassLevelDeclaration::Function(build_function_declaration(inner_pair))
|
|
}
|
|
Rule::OperatorFunctionDefinition => {
|
|
ClassLevelDeclaration::OperatorFunction(build_operator_function_declaration(inner_pair))
|
|
}
|
|
Rule::PlatformFunction => {
|
|
ClassLevelDeclaration::PlatformFunction(build_platform_function_declaration(inner_pair))
|
|
}
|
|
Rule::Property => ClassLevelDeclaration::Property(build_property_declaration(inner_pair)),
|
|
Rule::Field => ClassLevelDeclaration::Field(build_field_declaration(inner_pair)),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
fn build_module_declaration(module_pair: Pair<Rule>) -> ModuleDeclaration {
|
|
let mut is_public = false;
|
|
let mut identifier = None;
|
|
let mut declarations = vec![];
|
|
|
|
for inner_pair in module_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Pub => {
|
|
is_public = true;
|
|
}
|
|
Rule::Mod => {}
|
|
Rule::Identifier => {
|
|
identifier = Some(build_identifier(inner_pair));
|
|
}
|
|
Rule::ModuleLevelDeclaration => {
|
|
declarations.push(build_module_level_declaration(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
ModuleDeclaration {
|
|
is_public,
|
|
identifier: identifier.unwrap(),
|
|
declarations,
|
|
}
|
|
}
|
|
|
|
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 declarations = vec![];
|
|
|
|
for inner_pair in interface_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Pub => {
|
|
is_public = true;
|
|
}
|
|
Rule::Int => {}
|
|
Rule::Identifier => {
|
|
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));
|
|
}
|
|
Rule::ImplementsList => {
|
|
implements = build_implements_list(inner_pair);
|
|
}
|
|
Rule::InterfaceLevelDeclaration => {
|
|
declarations.push(build_interface_level_declaration(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
InterfaceDeclaration {
|
|
is_public,
|
|
identifier: identifier.unwrap(),
|
|
generics,
|
|
inputs,
|
|
return_type,
|
|
implements,
|
|
declarations,
|
|
}
|
|
}
|
|
|
|
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 class_constructor = None;
|
|
let mut implements = ImplementsList(vec![]);
|
|
let mut declarations = vec![];
|
|
|
|
for inner_pair in class_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Pub => {
|
|
is_public = true;
|
|
}
|
|
Rule::ClassKw => {}
|
|
Rule::Identifier => {
|
|
identifier = Some(build_identifier(inner_pair));
|
|
}
|
|
Rule::GenericParameters => {
|
|
generics = build_generic_parameters(inner_pair);
|
|
}
|
|
Rule::ClassConstructor => {
|
|
class_constructor = Some(build_class_constructor(inner_pair));
|
|
}
|
|
Rule::ImplementsList => {
|
|
implements = build_implements_list(inner_pair);
|
|
}
|
|
Rule::ClassLevelDeclaration => {
|
|
declarations.push(build_class_level_declaration(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
ClassDeclaration {
|
|
is_public,
|
|
identifier: identifier.unwrap(),
|
|
generics,
|
|
class_constructor,
|
|
implements,
|
|
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 {
|
|
todo!()
|
|
}
|
|
|
|
fn build_operator_function_declaration(
|
|
operator_function_pair: Pair<Rule>,
|
|
) -> OperatorFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_platform_function_declaration(
|
|
platform_function_pair: Pair<Rule>,
|
|
) -> PlatformFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_interface_function_declaration(
|
|
interface_function_pair: Pair<Rule>,
|
|
) -> InterfaceFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_interface_operator_function_declaration(
|
|
interface_operator_pair: Pair<Rule>,
|
|
) -> InterfaceOperatorFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_default_interface_function_declaration(
|
|
default_interface_function_pair: Pair<Rule>,
|
|
) -> InterfaceFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_default_interface_operator_function_declaration(
|
|
default_interface_operator_pair: Pair<Rule>,
|
|
) -> InterfaceOperatorFunctionDeclaration {
|
|
todo!()
|
|
}
|
|
|
|
fn build_class_constructor(class_constructor_pair: Pair<Rule>) -> ClassConstructor {
|
|
ClassConstructor(
|
|
class_constructor_pair
|
|
.into_inner()
|
|
.map(|data_member_pair| {
|
|
let inner_pair = data_member_pair.into_inner().next().unwrap();
|
|
match inner_pair.as_rule() {
|
|
Rule::Property => build_property_class_constructor_parameter(inner_pair),
|
|
Rule::Field => build_field_class_constructor_parameter(inner_pair),
|
|
_ => unreachable!(),
|
|
}
|
|
})
|
|
.collect(),
|
|
)
|
|
}
|
|
|
|
fn build_property_class_constructor_parameter(
|
|
property_pair: Pair<Rule>,
|
|
) -> ClassConstructorParameter {
|
|
ClassConstructorParameter::Property(build_property_declaration(property_pair))
|
|
}
|
|
|
|
fn build_field_class_constructor_parameter(field_pair: Pair<Rule>) -> ClassConstructorParameter {
|
|
ClassConstructorParameter::Field(build_field_declaration(field_pair))
|
|
}
|
|
|
|
fn build_property_declaration(property_declaration_pair: Pair<Rule>) -> PropertyDeclaration {
|
|
let mut is_mutable = false;
|
|
let mut identifier = None;
|
|
let mut declared_type = None;
|
|
|
|
for inner_pair in property_declaration_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Mut => {
|
|
is_mutable = true;
|
|
}
|
|
Rule::Identifier => {
|
|
identifier = Some(build_identifier(inner_pair));
|
|
}
|
|
Rule::TypeUse => {
|
|
declared_type = Some(build_type_use(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
PropertyDeclaration {
|
|
is_mutable,
|
|
identifier: identifier.unwrap(),
|
|
declared_type: declared_type.unwrap(),
|
|
}
|
|
}
|
|
|
|
fn build_field_declaration(field_pair: Pair<Rule>) -> FieldDeclaration {
|
|
let mut is_mutable = false;
|
|
let mut identifier = None;
|
|
let mut declared_type = None;
|
|
|
|
for inner_pair in field_pair.into_inner() {
|
|
match inner_pair.as_rule() {
|
|
Rule::Mut => {
|
|
is_mutable = true;
|
|
}
|
|
Rule::Fld => {}
|
|
Rule::Identifier => {
|
|
identifier = Some(build_identifier(inner_pair));
|
|
}
|
|
Rule::TypeUse => {
|
|
declared_type = Some(build_type_use(inner_pair));
|
|
}
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
|
|
FieldDeclaration {
|
|
is_mutable,
|
|
identifier: identifier.unwrap(),
|
|
declared_type: declared_type.unwrap(),
|
|
}
|
|
}
|