From 373120d34ec8617ca73a7e85a541e5f08ee0c900 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Wed, 14 May 2025 12:04:07 -0500 Subject: [PATCH] Add class-level declarations and components. --- src/ast/build.rs | 254 ++++++++++++++++++++++++++++++++++++++++- src/ast/mod.rs | 11 +- src/parser/deimos.pest | 1 + 3 files changed, 260 insertions(+), 6 deletions(-) diff --git a/src/ast/build.rs b/src/ast/build.rs index 6884147..40a0489 100644 --- a/src/ast/build.rs +++ b/src/ast/build.rs @@ -1,4 +1,17 @@ -use crate::ast::{ClassDeclaration, CompilationUnit, DelegateOrIdentifier, FullyQualifiedName, FunctionDeclaration, FunctionModifier, FunctionTypeParameters, FunctionTypeUse, GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument, InputArguments, InterfaceDeclaration, InterfaceFunctionDeclaration, InterfaceOperatorFunctionDeclaration, InterfaceOrClassTypeUse, ModuleDeclaration, ModuleLevelDeclaration, OperatorFunctionDeclaration, PlatformFunctionDeclaration, Reference, References, ReturnType, TupleTypeUse, TypeDeclaration, TypeFunctionArguments, TypeGenericArgument, TypeGenericArguments, TypeImplements, TypeImplementsArguments, TypeImplementsList, TypeTupleArgument, TypeTupleArguments, TypeUse, TypeWhereGuard, TypeWhereGuards, VoidOrTypeUse}; +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; @@ -271,6 +284,24 @@ fn build_references(ref_list_pair: Pair) -> References { ) } +fn build_input_parameters(pair: Pair) -> 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) -> 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) -> CompilationUnit { let mut namespace = None; let mut declarations = vec![]; @@ -318,6 +349,55 @@ fn build_module_level_declaration(pair: Pair) -> ModuleLevelDeclaration { } } +fn build_interface_level_declaration(declaration_pair: Pair) -> 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) -> 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) -> ModuleDeclaration { let mut is_public = false; let mut identifier = None; @@ -347,11 +427,94 @@ fn build_module_declaration(module_pair: Pair) -> ModuleDeclaration { } fn build_interface_declaration(interface_pair: Pair) -> InterfaceDeclaration { - todo!() + 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) -> ClassDeclaration { - todo!() + 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) -> TypeDeclaration { @@ -581,7 +744,9 @@ fn build_operator_function_declaration( todo!() } -fn build_platform_function_declaration(platform_function_pair: Pair) -> PlatformFunctionDeclaration { +fn build_platform_function_declaration( + platform_function_pair: Pair, +) -> PlatformFunctionDeclaration { todo!() } @@ -608,3 +773,84 @@ fn build_default_interface_operator_function_declaration( ) -> InterfaceOperatorFunctionDeclaration { todo!() } + +fn build_class_constructor(class_constructor_pair: Pair) -> 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, +) -> ClassConstructorParameter { + ClassConstructorParameter::Property(build_property_declaration(property_pair)) +} + +fn build_field_class_constructor_parameter(field_pair: Pair) -> ClassConstructorParameter { + ClassConstructorParameter::Field(build_field_declaration(field_pair)) +} + +fn build_property_declaration(property_declaration_pair: Pair) -> 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) -> 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(), + } +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index a9c92e5..98a72c8 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -260,6 +260,7 @@ pub enum ClassLevelDeclaration { Function(FunctionDeclaration), OperatorFunction(OperatorFunctionDeclaration), PlatformFunction(PlatformFunctionDeclaration), + Property(PropertyDeclaration), Field(FieldDeclaration), } @@ -425,8 +426,14 @@ pub enum FunctionBody { pub struct ClassConstructor(pub Vec); #[derive(Debug)] -pub struct ClassConstructorParameter { - pub is_field: bool, +pub enum ClassConstructorParameter { + Property(PropertyDeclaration), + Field(FieldDeclaration), +} + +#[derive(Debug)] +pub struct PropertyDeclaration { + pub is_mutable: bool, pub identifier: Identifier, pub declared_type: TypeUse, } diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 1c0fa0a..61cf3ac 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -321,6 +321,7 @@ ClassLevelDeclaration = { | FunctionDefinition | OperatorFunctionDefinition | PlatformFunction + | Property | Field }