diff --git a/src/ast/build.rs b/src/ast/build.rs index 1eb2f27..a037a95 100644 --- a/src/ast/build.rs +++ b/src/ast/build.rs @@ -23,6 +23,39 @@ pub fn build_ast( build_compilation_unit(file_name, file_id, compilation_unit_pair) } +fn build_operator(operator_pair: Pair) -> Operator { + match operator_pair.as_rule() { + /* Binary */ + Rule::Or => Operator::Binary(BinaryOperator::Or), + Rule::And => Operator::Binary(BinaryOperator::And), + Rule::EqualTo => Operator::Binary(BinaryOperator::EqualTo), + Rule::NotEqualTo => Operator::Binary(BinaryOperator::NotEqualTo), + Rule::Greater => Operator::Binary(BinaryOperator::Greater), + Rule::Less => Operator::Binary(BinaryOperator::Less), + Rule::GreaterEqual => Operator::Binary(BinaryOperator::GreaterEqual), + Rule::LessEqual => Operator::Binary(BinaryOperator::LessEqual), + Rule::Add => Operator::Binary(BinaryOperator::Add), + Rule::Subtract => Operator::Binary(BinaryOperator::Subtract), + Rule::Multiply => Operator::Binary(BinaryOperator::Multiply), + Rule::Divide => Operator::Binary(BinaryOperator::Divide), + Rule::Modulo => Operator::Binary(BinaryOperator::Modulo), + Rule::LeftShift => Operator::Binary(BinaryOperator::LeftShift), + Rule::RightShift => Operator::Binary(BinaryOperator::RightShift), + /* Unary prefix */ + Rule::Spread => Operator::PrefixUnary(PrefixUnaryOperator::Spread), + Rule::BorrowMut => Operator::PrefixUnary(PrefixUnaryOperator::BorrowMut), + Rule::Borrow => Operator::PrefixUnary(PrefixUnaryOperator::Borrow), + Rule::Not => Operator::PrefixUnary(PrefixUnaryOperator::Not), + Rule::Negative => Operator::PrefixUnary(PrefixUnaryOperator::Negative), + /* Unary suffix */ + Rule::PlusPlus => Operator::SuffixUnary(SuffixUnaryOperator::PlusPlus), + Rule::MinusMinus => Operator::SuffixUnary(SuffixUnaryOperator::MinusMinus), + Rule::CallOp => Operator::SuffixUnary(SuffixUnaryOperator::Call), + Rule::Index => Operator::SuffixUnary(SuffixUnaryOperator::Index), + _ => unreachable!("Unexpected operator {:?}", operator_pair.as_rule()), + } +} + fn build_identifier(file_id: usize, identifier_pair: Pair) -> Identifier { let as_span = identifier_pair.as_span(); Identifier::new( @@ -43,6 +76,7 @@ fn build_fqn(file_id: usize, fqn_pair: Pair) -> FullyQualifiedName { .map(|identifier_pair| { expect_and_use(file_id, identifier_pair, Rule::Identifier, build_identifier) }) + .map(Box::new) .collect(), file_id, Range { @@ -56,21 +90,20 @@ fn build_type_use(file_id: usize, type_use_pair: Pair) -> TypeUse { let inner_pair = type_use_pair.into_inner().next().unwrap(); match inner_pair.as_rule() { Rule::PrimitiveType => { - TypeUse::Primitive(build_primitive_type(file_id, inner_pair)) - }, - Rule::InterfaceOrClassTypeUse => { - TypeUse::InterfaceOrClass(build_interface_or_class_type_use(file_id, inner_pair)) + TypeUse::Primitive(Box::new(build_primitive_type(file_id, inner_pair))) + } + Rule::InterfaceOrClassTypeUse => TypeUse::InterfaceOrClass(Box::new( + build_interface_or_class_type_use(file_id, inner_pair), + )), + Rule::TupleTypeUse => TypeUse::Tuple(Box::new(build_tuple_type_use(file_id, inner_pair))), + Rule::FunctionTypeUse => { + TypeUse::Function(Box::new(build_function_type_use(file_id, inner_pair))) } - Rule::TupleTypeUse => TypeUse::Tuple(build_tuple_type_use(file_id, inner_pair)), - Rule::FunctionTypeUse => TypeUse::Function(build_function_type_use(file_id, inner_pair)), _ => unreachable!(), } } -fn build_primitive_type( - file_id: usize, - primitive_type_pair: Pair, -) -> PrimitiveTypeUse { +fn build_primitive_type(file_id: usize, primitive_type_pair: Pair) -> PrimitiveTypeUse { let mut inner = primitive_type_pair.into_inner(); match inner.next().unwrap().as_rule() { Rule::Byte => PrimitiveTypeUse::Byte, @@ -83,9 +116,10 @@ fn build_primitive_type( Rule::String => PrimitiveTypeUse::String, Rule::Array => { if let Some(generic_arguments_pair) = inner.next() { - PrimitiveTypeUse::Array( - Some(Box::new(build_generic_arguments(file_id, generic_arguments_pair))) - ) + PrimitiveTypeUse::Array(Some(Box::new(build_generic_arguments( + file_id, + generic_arguments_pair, + )))) } else { PrimitiveTypeUse::Array(None) } @@ -120,12 +154,12 @@ fn build_interface_or_class_type_use(file_id: usize, pair: Pair) -> Interf } } - InterfaceOrClassTypeUse { + InterfaceOrClassTypeUse::new( borrow_count, is_mutable, - fqn: fqn.unwrap(), - generics: generic_arguments, - } + Box::new(fqn.unwrap()), + Box::new(generic_arguments), + ) } fn build_tuple_type_use(file_id: usize, tuple_type_use_pair: Pair) -> TupleTypeUse { @@ -148,11 +182,7 @@ fn build_tuple_type_use(file_id: usize, tuple_type_use_pair: Pair) -> Tupl } } - TupleTypeUse { - borrow_count, - is_mutable, - arguments: arguments.unwrap(), - } + TupleTypeUse::new(borrow_count, is_mutable, Box::new(arguments.unwrap())) } fn build_function_type_use(file_id: usize, function_pair: Pair) -> FunctionTypeUse { @@ -168,7 +198,7 @@ fn build_function_type_use(file_id: usize, function_pair: Pair) -> Functio borrow_count += 1; } Rule::FunctionTypeModifier => { - function_modifier = Some(build_function_type_modifier(file_id, inner_pair)); + function_modifier = Some(build_function_type_modifier(inner_pair)); } Rule::Fn => {} Rule::GenericParameters => { @@ -184,23 +214,24 @@ fn build_function_type_use(file_id: usize, function_pair: Pair) -> Functio } } - FunctionTypeUse { + FunctionTypeUse::new( borrow_count, function_modifier, - generics, - parameters: parameters.unwrap(), - return_type: return_type.unwrap(), - } + Box::new(generics), + Box::new(parameters.unwrap()), + Box::new(return_type.unwrap()), + ) } fn build_generic_arguments(file_id: usize, generic_arguments_pair: Pair) -> GenericArguments { let type_use_list_pair = generic_arguments_pair.into_inner().next().unwrap(); - GenericArguments( + GenericArguments::new( type_use_list_pair .into_inner() .map(|type_use_pair| { expect_and_use(file_id, type_use_pair, Rule::TypeUse, build_type_use) }) + .map(Box::new) .collect(), ) } @@ -210,12 +241,13 @@ fn build_generic_parameters( generic_parameters_pair: Pair, ) -> GenericParameters { let identifier_list_pair = generic_parameters_pair.into_inner().next().unwrap(); - GenericParameters( + GenericParameters::new( identifier_list_pair .into_inner() .map(|identifier_pair| { expect_and_use(file_id, identifier_pair, Rule::Identifier, build_identifier) }) + .map(Box::new) .collect(), ) } @@ -227,27 +259,29 @@ fn build_tuple_arguments(file_id: usize, tuple_arguments_pair: Pair) -> Tu .next() .unwrap(); - TupleArguments( + TupleArguments::new( type_use_list_pair .into_inner() .map(|type_use_pair| { expect_and_use(file_id, type_use_pair, Rule::TypeUse, build_type_use) }) + .map(Box::new) .collect(), ) } fn build_implements_list(file_id: usize, pair: Pair) -> ImplementsList { - ImplementsList( + ImplementsList::new( pair.into_inner() .map(|type_use_pair| { expect_and_use(file_id, type_use_pair, Rule::TypeUse, build_type_use) }) + .map(Box::new) .collect(), ) } -fn build_function_type_modifier(file_id: usize, pair: Pair) -> FunctionTypeModifier { +fn build_function_type_modifier(pair: Pair) -> FunctionTypeModifier { let mut inner = pair.into_inner(); if inner.len() == 2 { FunctionTypeModifier::MutRef @@ -262,12 +296,13 @@ fn build_function_type_modifier(file_id: usize, pair: Pair) -> FunctionTyp } fn build_parameters(file_id: usize, parameters_pair: Pair) -> Parameters { - Parameters( + Parameters::new( parameters_pair .into_inner() .map(|parameter_pair| { expect_and_use(file_id, parameter_pair, Rule::Parameter, build_parameter) }) + .map(Box::new) .collect(), ) } @@ -286,10 +321,7 @@ fn build_parameter(file_id: usize, parameter_pair: Pair) -> Parameter { Rule::TypeUse, build_type_use, ); - Parameter { - identifier, - type_use, - } + Parameter::new(Box::new(identifier), Box::new(type_use)) } fn build_return_type(file_id: usize, return_type_pair: Pair) -> ReturnType { @@ -309,21 +341,19 @@ fn build_return_type(file_id: usize, return_type_pair: Pair) -> ReturnType }) .unwrap_or_else(References::default); - ReturnType { - declared_type: Box::new(declared_type), - references, - } + ReturnType::new(Box::new(declared_type), Box::new(references)) } fn build_references(file_id: usize, ref_list_pair: Pair) -> References { let mut inner = ref_list_pair.into_inner(); inner.next().unwrap(); // ref - References( + References::new( inner .map(|identifier_pair| { expect_and_use(file_id, identifier_pair, Rule::Identifier, build_identifier) }) + .map(Box::new) .collect(), ) } @@ -343,23 +373,25 @@ fn build_compilation_unit( namespace = Some(build_namespace(file_id, inner_pair)); } Rule::UseStatement => { - use_statements.push(build_use_statement(file_id, inner_pair)); + use_statements.push(Box::new(build_use_statement(file_id, inner_pair))); } Rule::ModuleLevelDeclaration => { - declarations.push(build_module_level_declaration(file_id, inner_pair)); + declarations.push(Box::new(build_module_level_declaration( + file_id, inner_pair, + ))); } Rule::Semicolon | Rule::EOI => {} _ => unreachable!(), } } - CompilationUnit { - file_name: file_name.to_string(), + CompilationUnit::new( + file_name.to_string(), file_id, - namespace, + namespace.map(Box::new), use_statements, declarations, - } + ) } fn build_namespace(file_id: usize, namespace_pair: Pair) -> FullyQualifiedName { @@ -373,22 +405,77 @@ fn build_namespace(file_id: usize, namespace_pair: Pair) -> FullyQualified ) } +fn build_use_statement(file_id: usize, use_statement_pair: Pair) -> UseStatement { + let as_span = use_statement_pair.as_span(); + let mut inner = use_statement_pair.into_inner(); + let inner_length = inner.len(); + + inner.next().unwrap(); // use + + let mut identifiers = vec![]; + let mut last = None; + + for (i, inner_pair) in inner.into_iter().enumerate() { + if i != inner_length - 2 { + identifiers.push(Box::new(expect_and_use( + file_id, + inner_pair, + Rule::Identifier, + build_identifier, + ))); + } else { + last = Some(Box::new(match inner_pair.as_rule() { + Rule::Identifier => { + UseStatementLast::Identifier(Box::new(build_identifier(file_id, inner_pair))) + } + Rule::Star => UseStatementLast::Star, + Rule::UseList => UseStatementLast::Identifiers( + inner_pair + .into_inner() + .map(|identifier_pair| { + Box::new(expect_and_use( + file_id, + identifier_pair, + Rule::Identifier, + build_identifier, + )) + }) + .collect(), + ), + _ => unreachable!(), + })); + } + } + + UseStatement::new( + identifiers, + last.unwrap(), + file_id, + Range { + start: as_span.start(), + end: as_span.end(), + }, + ) +} + fn build_module_level_declaration(file_id: usize, pair: Pair) -> ModuleLevelDeclaration { let inner_pair = pair.into_inner().next().unwrap(); match inner_pair.as_rule() { Rule::Module => { - ModuleLevelDeclaration::Module(build_module_declaration(file_id, inner_pair)) + ModuleLevelDeclaration::Module(Box::new(build_module_declaration(file_id, inner_pair))) } - Rule::Interface => { - ModuleLevelDeclaration::Interface(build_interface_declaration(file_id, inner_pair)) + Rule::Interface => ModuleLevelDeclaration::Interface(Box::new( + build_interface_declaration(file_id, inner_pair), + )), + Rule::Class => { + ModuleLevelDeclaration::Class(Box::new(build_class_declaration(file_id, inner_pair))) } - Rule::Class => ModuleLevelDeclaration::Class(build_class_declaration(file_id, inner_pair)), - Rule::FunctionDefinition => { - ModuleLevelDeclaration::Function(build_function_definition(file_id, inner_pair)) - } - Rule::PlatformFunction => ModuleLevelDeclaration::PlatformFunction( + Rule::FunctionDefinition => ModuleLevelDeclaration::Function(Box::new( + build_function_definition(file_id, inner_pair), + )), + Rule::PlatformFunction => ModuleLevelDeclaration::PlatformFunction(Box::new( build_platform_function_declaration(file_id, inner_pair), - ), + )), _ => unreachable!(), } } @@ -399,27 +486,29 @@ fn build_interface_level_declaration( ) -> InterfaceLevelDeclaration { let inner_pair = declaration_pair.into_inner().next().unwrap(); match inner_pair.as_rule() { - Rule::Module => { - InterfaceLevelDeclaration::Module(build_module_declaration(file_id, inner_pair)) - } - Rule::Interface => { - InterfaceLevelDeclaration::Interface(build_interface_declaration(file_id, inner_pair)) - } + Rule::Module => InterfaceLevelDeclaration::Module(Box::new(build_module_declaration( + file_id, inner_pair, + ))), + Rule::Interface => InterfaceLevelDeclaration::Interface(Box::new( + build_interface_declaration(file_id, inner_pair), + )), Rule::Class => { - InterfaceLevelDeclaration::Class(build_class_declaration(file_id, inner_pair)) + InterfaceLevelDeclaration::Class(Box::new(build_class_declaration(file_id, inner_pair))) } - Rule::InterfaceFunction => InterfaceLevelDeclaration::Function( + Rule::InterfaceFunction => InterfaceLevelDeclaration::Function(Box::new( build_interface_function_declaration(file_id, inner_pair), - ), - Rule::InterfaceDefaultFunction => InterfaceLevelDeclaration::Function( - build_default_interface_function_declaration(file_id, inner_pair), - ), - Rule::InterfaceOperatorFunction => InterfaceLevelDeclaration::OperatorFunction( + )), + Rule::InterfaceDefaultFunction => InterfaceLevelDeclaration::Function(Box::new( + build_interface_function_declaration(file_id, inner_pair), + )), + Rule::InterfaceOperatorFunction => InterfaceLevelDeclaration::OperatorFunction(Box::new( build_interface_operator_function_declaration(file_id, inner_pair), - ), - Rule::InterfaceDefaultOperatorFunction => InterfaceLevelDeclaration::OperatorFunction( - build_default_interface_operator_function_declaration(file_id, inner_pair), - ), + )), + Rule::InterfaceDefaultOperatorFunction => { + InterfaceLevelDeclaration::OperatorFunction(Box::new( + build_interface_operator_function_declaration(file_id, inner_pair), + )) + } _ => unreachable!(), } } @@ -431,25 +520,29 @@ fn build_class_level_declaration( let inner_pair = declaration_pair.into_inner().next().unwrap(); match inner_pair.as_rule() { Rule::Module => { - ClassLevelDeclaration::Module(build_module_declaration(file_id, inner_pair)) + ClassLevelDeclaration::Module(Box::new(build_module_declaration(file_id, inner_pair))) } - Rule::Interface => { - ClassLevelDeclaration::Interface(build_interface_declaration(file_id, inner_pair)) + Rule::Interface => ClassLevelDeclaration::Interface(Box::new(build_interface_declaration( + file_id, inner_pair, + ))), + Rule::Class => { + ClassLevelDeclaration::Class(Box::new(build_class_declaration(file_id, inner_pair))) } - Rule::Class => ClassLevelDeclaration::Class(build_class_declaration(file_id, inner_pair)), - Rule::FunctionDefinition => { - ClassLevelDeclaration::Function(build_function_definition(file_id, inner_pair)) - } - Rule::OperatorFunctionDefinition => ClassLevelDeclaration::OperatorFunction( + Rule::FunctionDefinition => ClassLevelDeclaration::Function(Box::new( + build_function_definition(file_id, inner_pair), + )), + Rule::OperatorFunctionDefinition => ClassLevelDeclaration::OperatorFunction(Box::new( build_operator_function_declaration(file_id, inner_pair), - ), - Rule::PlatformFunction => ClassLevelDeclaration::PlatformFunction( + )), + Rule::PlatformFunction => ClassLevelDeclaration::PlatformFunction(Box::new( build_platform_function_declaration(file_id, inner_pair), - ), - Rule::Property => { - ClassLevelDeclaration::Property(build_property_declaration(file_id, inner_pair)) + )), + Rule::Property => ClassLevelDeclaration::Property(Box::new(build_property_declaration( + file_id, inner_pair, + ))), + Rule::Field => { + ClassLevelDeclaration::Field(Box::new(build_field_declaration(file_id, inner_pair))) } - Rule::Field => ClassLevelDeclaration::Field(build_field_declaration(file_id, inner_pair)), _ => unreachable!(), } } @@ -466,20 +559,18 @@ fn build_module_declaration(file_id: usize, module_pair: Pair) -> ModuleDe } Rule::Mod => {} Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::ModuleLevelDeclaration => { - declarations.push(build_module_level_declaration(file_id, inner_pair)); + declarations.push(Box::new(build_module_level_declaration( + file_id, inner_pair, + ))); } _ => unreachable!(), } } - ModuleDeclaration { - is_public, - identifier: identifier.unwrap(), - declarations, - } + ModuleDeclaration::new(is_public, identifier.unwrap(), declarations) } fn build_interface_declaration(file_id: usize, interface_pair: Pair) -> InterfaceDeclaration { @@ -496,28 +587,30 @@ fn build_interface_declaration(file_id: usize, interface_pair: Pair) -> In } Rule::IntKw => {} Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::GenericParameters => { - generics = Some(build_generic_parameters(file_id, inner_pair)); + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); } Rule::ImplementsList => { - implements = Some(build_implements_list(file_id, inner_pair)); + implements = Some(Box::new(build_implements_list(file_id, inner_pair))); } Rule::InterfaceLevelDeclaration => { - declarations.push(build_interface_level_declaration(file_id, inner_pair)); + declarations.push(Box::new(build_interface_level_declaration( + file_id, inner_pair, + ))); } _ => unreachable!(), } } - InterfaceDeclaration { + InterfaceDeclaration::new( is_public, - identifier: identifier.unwrap(), - generics: generics.unwrap_or_else(GenericParameters::default), - implements: implements.unwrap_or_else(ImplementsList::default), + identifier.unwrap(), + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + implements.unwrap_or_else(|| Box::new(ImplementsList::default())), declarations, - } + ) } fn build_class_declaration(file_id: usize, class_pair: Pair) -> ClassDeclaration { @@ -535,32 +628,32 @@ fn build_class_declaration(file_id: usize, class_pair: Pair) -> ClassDecla } Rule::ClassKw => {} Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::GenericParameters => { - generics = Some(build_generic_parameters(file_id, inner_pair)); + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); } Rule::ClassConstructor => { - class_constructor = Some(build_class_constructor(file_id, inner_pair)); + class_constructor = Some(Box::new(build_class_constructor(file_id, inner_pair))); } Rule::ImplementsList => { - implements = Some(build_implements_list(file_id, inner_pair)); + implements = Some(Box::new(build_implements_list(file_id, inner_pair))); } Rule::ClassLevelDeclaration => { - declarations.push(build_class_level_declaration(file_id, inner_pair)); + declarations.push(Box::new(build_class_level_declaration(file_id, inner_pair))); } _ => unreachable!(), } } - ClassDeclaration { + ClassDeclaration::new( is_public, - identifier: identifier.unwrap(), - generics: generics.unwrap_or_else(GenericParameters::default), + identifier.unwrap(), + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), class_constructor, - implements: implements.unwrap_or_else(ImplementsList::default), + implements.unwrap_or_else(|| Box::new(ImplementsList::default())), declarations, - } + ) } fn build_function_definition( @@ -581,44 +674,88 @@ fn build_function_definition( is_public = true; } Rule::FunctionModifier => { - modifier = Some(build_function_modifier(file_id, inner_pair)); + modifier = Some(build_function_modifier(inner_pair)); } Rule::Fn => {} Rule::GenericParameters => { - generics = Some(build_generic_parameters(file_id, inner_pair)); + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); } Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::Parameters => { - parameters = Some(build_parameters(file_id, inner_pair)); + parameters = Some(Box::new(build_parameters(file_id, inner_pair))); } Rule::ReturnType => { - return_type = Some(build_return_type(file_id, inner_pair)); + return_type = Some(Box::new(build_return_type(file_id, inner_pair))); } Rule::FunctionBody => { - body = Some(build_function_body(file_id, inner_pair)); + body = Some(Box::new(build_function_body(file_id, inner_pair))); } _ => unreachable!(), } } - FunctionDefinition { + FunctionDefinition::new( is_public, modifier, - generics: generics.unwrap_or_else(GenericParameters::default), - identifier: identifier.unwrap(), - parameters: parameters.unwrap(), - return_type: return_type.unwrap_or_else(ReturnType::void), - body: body.unwrap(), - } + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + identifier.unwrap(), + parameters.unwrap(), + return_type.unwrap_or_else(|| Box::new(ReturnType::void())), + body.unwrap(), + ) } fn build_operator_function_declaration( file_id: usize, operator_function_pair: Pair, ) -> OperatorFunctionDefinition { - todo!() + let mut is_public = false; + let mut modifier = None; + let mut generics = None; + let mut operator = None; + let mut parameters = None; + let mut return_type = None; + let mut body = None; + + for inner_pair in operator_function_pair.into_inner() { + match inner_pair.as_rule() { + Rule::Pub => { + is_public = true; + } + Rule::FunctionModifier => { + modifier = Some(build_function_modifier(inner_pair)); + } + Rule::Op => {} + Rule::GenericParameters => { + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); + } + Rule::Operator => { + operator = Some(build_operator(inner_pair)); + } + Rule::Parameters => { + parameters = Some(Box::new(build_parameters(file_id, inner_pair))); + } + Rule::ReturnType => { + return_type = Some(Box::new(build_return_type(file_id, inner_pair))); + } + Rule::FunctionBody => { + body = Some(Box::new(build_function_body(file_id, inner_pair))); + } + _ => unreachable!(), + } + } + + OperatorFunctionDefinition::new( + is_public, + modifier, + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + operator.unwrap(), + parameters.unwrap(), + return_type.unwrap_or_else(|| Box::new(ReturnType::void())), + body.unwrap(), + ) } fn build_platform_function_declaration( @@ -627,9 +764,9 @@ fn build_platform_function_declaration( ) -> PlatformFunctionDeclaration { let mut is_public = false; let mut modifier = None; - let mut generics = GenericParameters::default(); + let mut generics = None; let mut identifier = None; - let mut parameters = Parameters::default(); + let mut parameters = None; let mut return_type = None; for inner_pair in platform_function_pair.into_inner() { @@ -638,33 +775,33 @@ fn build_platform_function_declaration( is_public = true; } Rule::FunctionModifier => { - modifier = Some(build_function_modifier(file_id, inner_pair)); + modifier = Some(build_function_modifier(inner_pair)); } Rule::Platform | Rule::Fn => {} Rule::GenericParameters => { - generics = build_generic_parameters(file_id, inner_pair); + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); } Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::Parameters => { - parameters = build_parameters(file_id, inner_pair); + parameters = Some(Box::new(build_parameters(file_id, inner_pair))); } Rule::ReturnType => { - return_type = Some(build_return_type(file_id, inner_pair)); + return_type = Some(Box::new(build_return_type(file_id, inner_pair))); } _ => unreachable!(), } } - PlatformFunctionDeclaration { + PlatformFunctionDeclaration::new( is_public, modifier, - generics, - identifier: identifier.unwrap(), - parameters, - return_type: return_type.unwrap(), - } + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + identifier.unwrap(), + parameters.unwrap(), + return_type.unwrap(), + ) } fn build_interface_function_declaration( @@ -672,66 +809,91 @@ fn build_interface_function_declaration( interface_function_pair: Pair, ) -> InterfaceFunctionDeclaration { let mut modifier = None; - let mut generics = GenericParameters::default(); + let mut generics = None; let mut identifier = None; - let mut parameters = Parameters::default(); + let mut parameters = None; let mut return_type = None; let mut body = None; - + for inner_pair in interface_function_pair.into_inner() { match inner_pair.as_rule() { - Rule::Def | Rule::Fn => {}, + Rule::Def | Rule::Fn => {} Rule::FunctionModifier => { - modifier = Some(build_function_modifier(file_id, inner_pair)); - }, + modifier = Some(build_function_modifier(inner_pair)); + } Rule::GenericParameters => { - generics = build_generic_parameters(file_id, inner_pair); + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); } Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::Parameters => { - parameters = build_parameters(file_id, inner_pair); + parameters = Some(Box::new(build_parameters(file_id, inner_pair))); } Rule::ReturnType => { - return_type = Some(build_return_type(file_id, inner_pair)); + return_type = Some(Box::new(build_return_type(file_id, inner_pair))); } Rule::FunctionBody => { - body = Some(build_function_body(file_id, inner_pair)); + body = Some(Box::new(build_function_body(file_id, inner_pair))); } _ => unreachable!(), } } - - InterfaceFunctionDeclaration { + + InterfaceFunctionDeclaration::new( modifier, - generics, - identifier: identifier.unwrap(), - parameters, - return_type: return_type.unwrap(), - body - } + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + identifier.unwrap(), + parameters.unwrap(), + return_type.unwrap(), + body, + ) } fn build_interface_operator_function_declaration( file_id: usize, interface_operator_pair: Pair, ) -> InterfaceOperatorFunctionDeclaration { - todo!() -} + let mut modifier = None; + let mut generics = None; + let mut operator = None; + let mut parameters = None; + let mut return_type = None; + let mut body = None; -fn build_default_interface_function_declaration( - file_id: usize, - default_interface_function_pair: Pair, -) -> InterfaceFunctionDeclaration { - todo!() -} + for inner_pair in interface_operator_pair.into_inner() { + match inner_pair.as_rule() { + Rule::Def | Rule::Op => {} + Rule::FunctionModifier => { + modifier = Some(build_function_modifier(inner_pair)); + } + Rule::GenericParameters => { + generics = Some(Box::new(build_generic_parameters(file_id, inner_pair))); + } + Rule::Operator => { + operator = Some(build_operator(inner_pair)); + } + Rule::Parameters => { + parameters = Some(Box::new(build_parameters(file_id, inner_pair))); + } + Rule::ReturnType => { + return_type = Some(Box::new(build_return_type(file_id, inner_pair))); + } + Rule::FunctionBody => { + body = Some(Box::new(build_function_body(file_id, inner_pair))); + } + _ => unreachable!(), + } + } -fn build_default_interface_operator_function_declaration( - file_id: usize, - default_interface_operator_pair: Pair, -) -> InterfaceOperatorFunctionDeclaration { - todo!() + InterfaceOperatorFunctionDeclaration::new( + modifier, + generics.unwrap_or_else(|| Box::new(GenericParameters::default())), + operator.unwrap(), + parameters.unwrap(), + return_type.unwrap(), + body, + ) } fn build_class_constructor(file_id: usize, class_constructor_pair: Pair) -> ClassConstructor { @@ -748,11 +910,12 @@ fn build_class_constructor(file_id: usize, class_constructor_pair: Pair) - _ => unreachable!(), } }) + .map(Box::new) .collect(), ) } -fn build_function_modifier(file_id: usize, modifier_pair: Pair) -> FunctionModifier { +fn build_function_modifier(modifier_pair: Pair) -> FunctionModifier { let mut inner = modifier_pair.into_inner(); if inner.len() == 2 { FunctionModifier::MutRef @@ -770,22 +933,24 @@ fn build_function_modifier(file_id: usize, modifier_pair: Pair) -> Functio fn build_function_body(file_id: usize, body_pair: Pair) -> FunctionBody { let inner_pair = body_pair.into_inner().next().unwrap(); match inner_pair.as_rule() { - Rule::FunctionEqualsBody => FunctionBody::Equals(expect_and_use( + Rule::FunctionEqualsBody => FunctionBody::Equals(Box::new(expect_and_use( file_id, inner_pair.into_inner().next().unwrap(), Rule::Expression, build_expression, - )), - Rule::BlockStatement => FunctionBody::Block(build_block_statement(file_id, inner_pair)), + ))), + Rule::BlockStatement => { + FunctionBody::Block(Box::new(build_block_statement(file_id, inner_pair))) + } Rule::FunctionAliasBody => { let mut alias_body_pairs = inner_pair.into_inner(); alias_body_pairs.next().unwrap(); // Alias - FunctionBody::Alias(expect_and_use( + FunctionBody::Alias(Box::new(expect_and_use( file_id, alias_body_pairs.next().unwrap(), Rule::Identifier, build_identifier, - )) + ))) } _ => unreachable!(), } @@ -795,14 +960,17 @@ fn build_property_class_constructor_parameter( file_id: usize, property_pair: Pair, ) -> ClassConstructorParameter { - ClassConstructorParameter::Property(build_property_declaration(file_id, property_pair)) + ClassConstructorParameter::Property(Box::new(build_property_declaration( + file_id, + property_pair, + ))) } fn build_field_class_constructor_parameter( file_id: usize, field_pair: Pair, ) -> ClassConstructorParameter { - ClassConstructorParameter::Field(build_field_declaration(file_id, field_pair)) + ClassConstructorParameter::Field(Box::new(build_field_declaration(file_id, field_pair))) } fn build_property_declaration( @@ -819,20 +987,16 @@ fn build_property_declaration( is_mutable = true; } Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::TypeUse => { - declared_type = Some(build_type_use(file_id, inner_pair)); + declared_type = Some(Box::new(build_type_use(file_id, inner_pair))); } _ => unreachable!(), } } - PropertyDeclaration { - is_mutable, - identifier: identifier.unwrap(), - declared_type: declared_type.unwrap(), - } + PropertyDeclaration::new(is_mutable, identifier.unwrap(), declared_type.unwrap()) } fn build_field_declaration(file_id: usize, field_pair: Pair) -> FieldDeclaration { @@ -847,73 +1011,16 @@ fn build_field_declaration(file_id: usize, field_pair: Pair) -> FieldDecla } Rule::Fld => {} Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::TypeUse => { - declared_type = Some(build_type_use(file_id, inner_pair)); + declared_type = Some(Box::new(build_type_use(file_id, inner_pair))); } _ => unreachable!(), } } - FieldDeclaration { - is_mutable, - identifier: identifier.unwrap(), - declared_type: declared_type.unwrap(), - } -} - -fn build_use_statement(file_id: usize, use_statement_pair: Pair) -> UseStatement { - let as_span = use_statement_pair.as_span(); - let mut inner = use_statement_pair.into_inner(); - let inner_length = inner.len(); - - inner.next().unwrap(); // use - - let mut identifiers = vec![]; - let mut last = None; - - for (i, inner_pair) in inner.into_iter().enumerate() { - if i != inner_length - 2 { - identifiers.push(expect_and_use( - file_id, - inner_pair, - Rule::Identifier, - build_identifier, - )) - } else { - last = Some(match inner_pair.as_rule() { - Rule::Identifier => UseStatementLast::Identifier(Rc::new(RefCell::new( - build_identifier(file_id, inner_pair), - ))), - Rule::Star => UseStatementLast::Star, - Rule::UseList => UseStatementLast::Identifiers( - inner_pair - .into_inner() - .map(|identifier_pair| { - Rc::new(RefCell::new(expect_and_use( - file_id, - identifier_pair, - Rule::Identifier, - build_identifier, - ))) - }) - .collect(), - ), - _ => unreachable!(), - }) - } - } - - UseStatement::new( - identifiers, - last.unwrap(), - file_id, - Range { - start: as_span.start(), - end: as_span.end(), - }, - ) + FieldDeclaration::new(is_mutable, identifier.unwrap(), declared_type.unwrap()) } fn build_block_statement(file_id: usize, block_statement_pair: Pair) -> BlockStatement { @@ -923,39 +1030,46 @@ fn build_block_statement(file_id: usize, block_statement_pair: Pair) -> Bl for inner_pair in block_statement_pair.into_inner() { match inner_pair.as_rule() { Rule::Statement => { - statements.push(build_statement(file_id, inner_pair)); + statements.push(Box::new(build_statement(file_id, inner_pair))); } Rule::Expression => { - expression = Some(build_expression(file_id, inner_pair)); + expression = Some(Box::new(build_expression(file_id, inner_pair))); } _ => unreachable!(), } } - BlockStatement { - statements, - expression, - } + BlockStatement::new(statements, expression) } fn build_statement(file_id: usize, statement_pair: Pair) -> Statement { let first = statement_pair.into_inner().next().unwrap(); match first.as_rule() { - Rule::BlockStatement => Statement::BlockStatement(build_block_statement(file_id, first)), - Rule::VariableDeclaration => { - Statement::VariableDeclarationStatement(build_variable_declaration(file_id, first)) + Rule::BlockStatement => { + Statement::BlockStatement(Box::new(build_block_statement(file_id, first))) } + Rule::VariableDeclaration => Statement::VariableDeclarationStatement(Box::new( + build_variable_declaration(file_id, first), + )), Rule::AssignmentStatement => { - Statement::AssignStatement(build_assignment_statement(file_id, first)) + Statement::AssignStatement(Box::new(build_assignment_statement(file_id, first))) } - Rule::CallStatement => Statement::CallStatement(build_call_statement(file_id, first)), - Rule::ReturnStatement => Statement::ReturnStatement(build_return_statement(file_id, first)), - Rule::IfStatement => Statement::IfStatement(build_if_statement(file_id, first)), + Rule::CallStatement => { + Statement::CallStatement(Box::new(build_call_statement(file_id, first))) + } + Rule::ReturnStatement => { + Statement::ReturnStatement(Box::new(build_return_statement(file_id, first))) + } + Rule::IfStatement => Statement::IfStatement(Box::new(build_if_statement(file_id, first))), Rule::IfElseStatement => { - Statement::IfElseStatement(build_if_else_statement(file_id, first)) + Statement::IfElseStatement(Box::new(build_if_else_statement(file_id, first))) + } + Rule::WhileStatement => { + Statement::WhileStatement(Box::new(build_while_statement(file_id, first))) + } + Rule::ForStatement => { + Statement::ForStatement(Box::new(build_for_statement(file_id, first))) } - Rule::WhileStatement => Statement::WhileStatement(build_while_statement(file_id, first)), - Rule::ForStatement => Statement::ForStatement(build_for_statement(file_id, first)), _ => unreachable!(), } } @@ -976,36 +1090,31 @@ fn build_variable_declaration( is_mutable = true; } Rule::Identifier => { - identifier = Some(build_identifier(file_id, inner_pair)); + identifier = Some(Box::new(build_identifier(file_id, inner_pair))); } Rule::TypeUse => { - declared_type = Some(build_type_use(file_id, inner_pair)); + declared_type = Some(Box::new(build_type_use(file_id, inner_pair))); } Rule::Expression => { - initializer = Some(build_expression(file_id, inner_pair)); + initializer = Some(Box::new(build_expression(file_id, inner_pair))); } _ => unreachable!(), } } - VariableDeclarationStatement { - is_mutable, - identifier: identifier.unwrap(), - declared_type, - initializer, - } + VariableDeclarationStatement::new(is_mutable, identifier.unwrap(), declared_type, initializer) } fn build_assignment_statement(file_id: usize, assignment_pair: Pair) -> AssignStatement { let mut inner = assignment_pair.into_inner(); - let lhs = build_expression(file_id, inner.next().unwrap()); - let rhs = build_expression(file_id, inner.next().unwrap()); - AssignStatement { lhs, rhs } + let lhs = Box::new(build_expression(file_id, inner.next().unwrap())); + let rhs = Box::new(build_expression(file_id, inner.next().unwrap())); + AssignStatement::new(lhs, rhs) } fn build_call_statement(file_id: usize, call_statement_pair: Pair) -> CallStatement { let mut inner = call_statement_pair.into_inner(); - let mut result = expect_and_use( + let mut receiver = expect_and_use( file_id, inner.next().unwrap(), Rule::PrimaryExpression, @@ -1015,65 +1124,66 @@ fn build_call_statement(file_id: usize, call_statement_pair: Pair) -> Call while let Some(inner_pair) = inner.next() { match inner_pair.as_rule() { Rule::ObjectAccess => { - result = Expression::ObjectAccess(build_object_access(file_id, result, inner_pair)); + receiver = Expression::ObjectAccess(Box::new(build_object_access( + file_id, receiver, inner_pair, + ))); } Rule::ParenthesesCall => { - result = Expression::Call(build_call_expression(file_id, result, inner_pair)); + receiver = Expression::Call(Box::new(build_call_expression( + file_id, receiver, inner_pair, + ))); } Rule::PlusPlus => { - result = Expression::UnarySuffix(SuffixExpression { - expression: Box::new(result), - operator: SuffixUnaryOperator::PlusPlus, - }); + receiver = Expression::UnarySuffix(Box::new(SuffixExpression::new( + Box::new(receiver), + SuffixUnaryOperator::PlusPlus, + ))) } Rule::MinusMinus => { - result = Expression::UnarySuffix(SuffixExpression { - expression: Box::new(result), - operator: SuffixUnaryOperator::MinusMinus, - }); + receiver = Expression::UnarySuffix(Box::new(SuffixExpression::new( + Box::new(receiver), + SuffixUnaryOperator::MinusMinus, + ))); } _ => unreachable!(), } } - CallStatement(result) + CallStatement::new(Box::new(receiver)) } fn build_return_statement(file_id: usize, return_statement_pair: Pair) -> ReturnStatement { let mut inner = return_statement_pair.into_inner(); if inner.len() == 2 { inner.next().unwrap(); // return - let expression = expect_and_use( + let expression = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Expression, build_expression, - ); - ReturnStatement(Some(expression)) + )); + ReturnStatement::new(Some(expression)) } else { - ReturnStatement(None) + ReturnStatement::new(None) } } fn build_if_statement(file_id: usize, if_statement_pair: Pair) -> IfStatement { let mut inner = if_statement_pair.into_inner(); inner.next().unwrap(); // if - let condition = expect_and_use( + let condition = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Expression, build_expression, - ); - let then_block = expect_and_use( + )); + let then_block = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::BlockStatement, build_block_statement, - ); - IfStatement { - condition, - then_block, - } + )); + IfStatement::new(condition, then_block) } fn build_if_else_statement(file_id: usize, if_else_statement_pair: Pair) -> IfElseStatement { @@ -1084,85 +1194,77 @@ fn build_if_else_statement(file_id: usize, if_else_statement_pair: Pair) - for inner_pair in if_else_statement_pair.into_inner() { match inner_pair.as_rule() { Rule::IfStatement => { - if_statement = Some(build_if_statement(file_id, inner_pair)); + if_statement = Some(Box::new(build_if_statement(file_id, inner_pair))); } Rule::ElseIf => { let mut else_if_inner = inner_pair.into_inner(); else_if_inner.next().unwrap(); // else - else_ifs.0.push(expect_and_use( + else_ifs.0.push(Box::new(expect_and_use( file_id, else_if_inner.next().unwrap(), Rule::IfStatement, build_if_statement, - )); + ))); } Rule::ElseBlock => { let mut else_inner = inner_pair.into_inner(); else_inner.next().unwrap(); // else - else_block = Some(ElseBlock(expect_and_use( + else_block = Some(Box::new(ElseBlock::new(Box::new(expect_and_use( file_id, else_inner.next().unwrap(), Rule::BlockStatement, build_block_statement, - ))); + ))))); } _ => unreachable!(), } } - IfElseStatement { - if_statement: if_statement.unwrap(), - else_ifs, - else_block, - } + IfElseStatement::new(if_statement.unwrap(), Box::new(else_ifs), else_block) } fn build_while_statement(file_id: usize, while_statement_pair: Pair) -> WhileStatement { let mut inner = while_statement_pair.into_inner(); inner.next().unwrap(); // while - let condition = expect_and_use( + let condition = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Expression, build_expression, - ); + )); - let body = expect_and_use( + let body = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::BlockStatement, build_block_statement, - ); - WhileStatement { condition, body } + )); + WhileStatement::new(condition, body) } fn build_for_statement(file_id: usize, for_statement_pair: Pair) -> ForStatement { let mut inner = for_statement_pair.into_inner(); inner.next().unwrap(); // for - let variable = expect_and_use( + let variable = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Identifier, build_identifier, - ); + )); inner.next().unwrap(); // in - let iterator = expect_and_use( + let iterator = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Expression, build_expression, - ); - let body = expect_and_use( + )); + let body = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::BlockStatement, build_block_statement, - ); - ForStatement { - variable, - iterator, - body, - } + )); + ForStatement::new(variable, iterator, body) } fn build_expression(file_id: usize, expression_pair: Pair) -> Expression { @@ -1195,11 +1297,11 @@ fn build_ternary_expression(file_id: usize, ternary_pair: Pair) -> Express Rule::Expression, build_expression, ); - Expression::Ternary(TernaryExpression { - condition: Box::new(condition), - true_expression: Box::new(true_expression), - false_expression: Box::new(false_expression), - }) + Expression::Ternary(Box::new(TernaryExpression::new( + Box::new(condition), + Box::new(true_expression), + Box::new(false_expression), + ))) } else { expect_and_use( file_id, @@ -1217,14 +1319,14 @@ macro_rules! build_binary_expression { let left = expect_and_use($file_id, inner.next().unwrap(), $left_rule, $left_fn); let op = inner.next().unwrap(); // op let right = expect_and_use($file_id, inner.next().unwrap(), Rule::Expression, build_expression); - Expression::Binary(BinaryExpression { - left: Box::new(left), - operator: match op.as_rule() { + Expression::Binary(Box::new(BinaryExpression::new( + Box::new(left), + match op.as_rule() { $( $pat => $arm, )* _ => unreachable!(), }, - right: Box::new(right), - }) + Box::new(right), + ))) } else { expect_and_use($file_id, inner.next().unwrap(), $left_rule, $left_fn) } @@ -1311,40 +1413,40 @@ fn build_prefix_expression(file_id: usize, prefix_pair: Pair) -> Expressio while let Some(prefix_pair) = inner_rev.next() { match prefix_pair.as_rule() { Rule::Spread => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::Spread, - expression: Box::new(result), - }); + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::Spread, + Box::new(result), + ))); } Rule::BorrowMut => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::BorrowMut, - expression: Box::new(result), - }) + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::BorrowMut, + Box::new(result), + ))); } Rule::Borrow => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::Borrow, - expression: Box::new(result), - }) + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::Borrow, + Box::new(result), + ))) } Rule::Mut => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::Mut, - expression: Box::new(result), - }) + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::Mut, + Box::new(result), + ))) } Rule::Not => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::Not, - expression: Box::new(result), - }) + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::Not, + Box::new(result), + ))) } Rule::Negative => { - result = Expression::UnaryPrefix(PrefixExpression { - operator: PrefixUnaryOperator::Negative, - expression: Box::new(result), - }) + result = Expression::UnaryPrefix(Box::new(PrefixExpression::new( + PrefixUnaryOperator::Negative, + Box::new(result), + ))) } _ => unreachable!(), } @@ -1363,22 +1465,30 @@ fn build_suffix_expression(file_id: usize, suffix_pair: Pair) -> Expressio while let Some(suffix_pair) = inner.next() { match suffix_pair.as_rule() { Rule::ObjectAccess => { - result = Expression::ObjectAccess(build_object_access(file_id, result, suffix_pair)) + result = Expression::ObjectAccess(Box::new(build_object_access( + file_id, + result, + suffix_pair, + ))) } Rule::ParenthesesCall => { - result = Expression::Call(build_call_expression(file_id, result, suffix_pair)) + result = Expression::Call(Box::new(build_call_expression( + file_id, + result, + suffix_pair, + ))) } Rule::PlusPlus => { - result = Expression::UnarySuffix(SuffixExpression { - expression: Box::new(result), - operator: SuffixUnaryOperator::PlusPlus, - }) + result = Expression::UnarySuffix(Box::new(SuffixExpression::new( + Box::new(result), + SuffixUnaryOperator::PlusPlus, + ))); } Rule::MinusMinus => { - result = Expression::UnarySuffix(SuffixExpression { - expression: Box::new(result), - operator: SuffixUnaryOperator::MinusMinus, - }) + result = Expression::UnarySuffix(Box::new(SuffixExpression::new( + Box::new(result), + SuffixUnaryOperator::MinusMinus, + ))) } _ => unreachable!(), } @@ -1397,50 +1507,54 @@ fn build_call_expression( for inner_pair in parentheses_call_pair.into_inner() { match inner_pair.as_rule() { Rule::TurboFish => { - turbo_fish = Some(build_turbo_fish(file_id, inner_pair)); + turbo_fish = Some(Box::new(build_turbo_fish(file_id, inner_pair))); } Rule::ExpressionList => { for expression_pair in inner_pair.into_inner() { - arguments.push(expect_and_use( + arguments.push(Box::new(expect_and_use( file_id, expression_pair, Rule::Expression, build_expression, - )); + ))); } } Rule::Closure => { - arguments.push(Expression::Closure(build_closure(file_id, inner_pair))); + arguments.push(Box::new(Expression::Closure(Box::new(build_closure( + file_id, inner_pair, + ))))); } _ => unreachable!(), } } - CallExpression { - callee: Box::new(callee), + let arguments = arguments + .into_iter() + .map(|argument| Box::new(CallArgument::new(argument))) + .collect(); + + CallExpression::new( + Box::new(callee), turbo_fish, - arguments: CallArguments( - arguments - .into_iter() - .map(|argument| CallArgument(Box::new(argument))) - .collect(), - ), - } + Box::new(CallArguments::new(arguments)), + ) } fn build_turbo_fish(file_id: usize, turbo_fish_pair: Pair) -> TurboFish { - TurboFish(build_generic_arguments( + TurboFish::new(Box::new(build_generic_arguments( file_id, turbo_fish_pair.into_inner().next().unwrap(), - )) + ))) } fn build_primary_expression(file_id: usize, primary_expression_pair: Pair) -> Expression { let first_pair = primary_expression_pair.into_inner().next().unwrap(); match first_pair.as_rule() { - Rule::Literal => Expression::Literal(build_literal(file_id, first_pair)), - Rule::FullyQualifiedName => Expression::FullyQualifiedName(build_fqn(file_id, first_pair)), - Rule::Closure => Expression::Closure(build_closure(file_id, first_pair)), + Rule::Literal => Expression::Literal(Box::new(build_literal(file_id, first_pair))), + Rule::FullyQualifiedName => { + Expression::FullyQualifiedName(Box::new(build_fqn(file_id, first_pair))) + } + Rule::Closure => Expression::Closure(Box::new(build_closure(file_id, first_pair))), Rule::ParenthesizedExpression => { let inner_expression = first_pair.into_inner().next().unwrap(); expect_and_use( @@ -1459,9 +1573,9 @@ fn build_object_access( receiver: Expression, object_access_pair: Pair, ) -> ObjectAccess { - ObjectAccess { - receiver: Box::new(receiver), - navigations: ObjectNavigations( + ObjectAccess::new( + Box::new(receiver), + Box::new(ObjectNavigations::new( object_access_pair .into_inner() .map( @@ -1473,9 +1587,10 @@ fn build_object_access( _ => unreachable!(), }, ) + .map(Box::new) .collect(), - ), - } + )), + ) } fn build_object_property(file_id: usize, inner_pair: Pair) -> ObjectNavigation { @@ -1499,8 +1614,8 @@ fn build_object_index(file_id: usize, inner_pair: Pair) -> ObjectNavigatio fn build_closure(file_id: usize, closure_pair: Pair) -> Closure { let mut modifier = None; let mut is_move = false; - let mut captures = ClosureCaptures::default(); - let mut parameters = ClosureParameters::default(); + let mut captures = None; + let mut parameters = None; let mut statements = vec![]; let mut expression = None; @@ -1509,13 +1624,13 @@ fn build_closure(file_id: usize, closure_pair: Pair) -> Closure { Rule::Cons => modifier = Some(ClosureModifier::Cons), Rule::Mut => modifier = Some(ClosureModifier::Mut), Rule::ClosureCaptures => { - captures = build_closure_captures(file_id, inner_pair); + captures = Some(Box::new(build_closure_captures(file_id, inner_pair))); } Rule::ClosureParameters => { - parameters = build_closure_parameters(file_id, inner_pair); + parameters = Some(Box::new(build_closure_parameters(file_id, inner_pair))); } Rule::Statement => { - statements.push(build_statement(file_id, inner_pair)); + statements.push(Box::new(build_statement(file_id, inner_pair))); } Rule::Expression => { expression = Some(Box::new(build_expression(file_id, inner_pair))); @@ -1524,18 +1639,18 @@ fn build_closure(file_id: usize, closure_pair: Pair) -> Closure { } } - Closure { + Closure::new( modifier, is_move, - captures, - parameters, + captures.unwrap_or_else(|| Box::new(ClosureCaptures::default())), + parameters.unwrap_or_else(|| Box::new(ClosureParameters::default())), statements, expression, - } + ) } fn build_closure_captures(file_id: usize, captures_pair: Pair) -> ClosureCaptures { - ClosureCaptures( + ClosureCaptures::new( captures_pair .into_inner() .map(|capture_pair| { @@ -1546,6 +1661,7 @@ fn build_closure_captures(file_id: usize, captures_pair: Pair) -> ClosureC build_closure_capture, ) }) + .map(Box::new) .collect(), ) } @@ -1570,15 +1686,11 @@ fn build_closure_capture(file_id: usize, capture_pair: Pair) -> ClosureCap } } - ClosureCapture { - borrow_count, - is_mutable, - identifier: identifier.unwrap(), - } + ClosureCapture::new(borrow_count, is_mutable, identifier.unwrap()) } fn build_closure_parameters(file_id: usize, parameters_pair: Pair) -> ClosureParameters { - ClosureParameters( + ClosureParameters::new( parameters_pair .into_inner() .map(|parameter_pair| { @@ -1589,32 +1701,30 @@ fn build_closure_parameters(file_id: usize, parameters_pair: Pair) -> Clos build_closure_parameter, ) }) + .map(Box::new) .collect(), ) } fn build_closure_parameter(file_id: usize, parameter_pair: Pair) -> ClosureParameter { let mut inner = parameter_pair.into_inner(); - let identifier = expect_and_use( + let identifier = Box::new(expect_and_use( file_id, inner.next().unwrap(), Rule::Identifier, build_identifier, - ); + )); let type_use = if let Some(type_use_pair) = inner.next() { - Some(expect_and_use( + Some(Box::new(expect_and_use( file_id, type_use_pair, Rule::TypeUse, build_type_use, - )) + ))) } else { None }; - ClosureParameter { - identifier, - type_use, - } + ClosureParameter::new(identifier, type_use) } fn build_literal(file_id: usize, literal_pair: Pair) -> Literal { @@ -1622,7 +1732,7 @@ fn build_literal(file_id: usize, literal_pair: Pair) -> Literal { match inner_pair.as_rule() { Rule::NumberLiteral => build_number_literal(file_id, inner_pair), Rule::StringLiteral => build_string_literal(file_id, inner_pair), - Rule::BooleanLiteral => build_boolean_literal(file_id, inner_pair), + Rule::BooleanLiteral => build_boolean_literal(inner_pair), _ => unreachable!(), } } @@ -1630,38 +1740,38 @@ fn build_literal(file_id: usize, literal_pair: Pair) -> Literal { fn build_number_literal(file_id: usize, pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); match inner_pair.as_rule() { - Rule::DoubleLiteral => build_double_literal(file_id, inner_pair), - Rule::LongLiteral => build_long_literal(file_id, inner_pair), - Rule::IntLiteral => build_int_literal(file_id, inner_pair), + Rule::DoubleLiteral => build_double_literal(inner_pair), + Rule::LongLiteral => build_long_literal(inner_pair), + Rule::IntLiteral => build_int_literal(inner_pair), _ => unreachable!(), } } -fn build_double_literal(file_id: usize, inner_pair: Pair) -> Literal { +fn build_double_literal(inner_pair: Pair) -> Literal { Literal::Double(f64::from_str(&inner_pair.as_str()).unwrap()) } -fn build_long_literal(file_id: usize, inner_pair: Pair) -> Literal { +fn build_long_literal(inner_pair: Pair) -> Literal { let as_string = inner_pair.as_str(); let without_el = &as_string[0..(as_string.len() - 1)]; Literal::Long(i64::from_str(without_el).unwrap()) } -fn build_int_literal(file_id: usize, inner_pair: Pair) -> Literal { +fn build_int_literal(inner_pair: Pair) -> Literal { Literal::Integer(i32::from_str(&inner_pair.as_str()).unwrap()) } fn build_string_literal(file_id: usize, pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); match inner_pair.as_rule() { - Rule::SingleQuoteString => build_single_quote_string(file_id, inner_pair), + Rule::SingleQuoteString => build_single_quote_string(inner_pair), Rule::DoubleQuoteString => build_double_quote_string(file_id, inner_pair), Rule::BacktickString => build_backtick_string(file_id, inner_pair), _ => unreachable!(), } } -fn build_boolean_literal(file_id: usize, pair: Pair) -> Literal { +fn build_boolean_literal(pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); match inner_pair.as_rule() { Rule::True => Literal::Boolean(true), @@ -1670,28 +1780,28 @@ fn build_boolean_literal(file_id: usize, pair: Pair) -> Literal { } } -fn build_single_quote_string(file_id: usize, pair: Pair) -> Literal { +fn build_single_quote_string(pair: Pair) -> Literal { let inner_pair = pair.into_inner().next().unwrap(); Literal::String(inner_pair.as_span().as_str().to_string()) } fn build_double_quote_string(file_id: usize, pair: Pair) -> Literal { - let mut parts: Vec = vec![]; + let mut parts: Vec> = vec![]; handle_d_backtick_strings_inner(Rule::DStringInner, file_id, pair, &mut parts); if parts.len() == 1 && parts[0].is_string() { Literal::String(parts.pop().unwrap().unwrap_string()) } else { - Literal::DString(DString(parts)) + Literal::DString(Box::new(DString(parts))) } } fn build_backtick_string(file_id: usize, pair: Pair) -> Literal { - let mut parts: Vec = vec![]; + let mut parts: Vec> = vec![]; handle_d_backtick_strings_inner(Rule::BacktickInner, file_id, pair, &mut parts); if parts.len() == 1 && parts[0].is_string() { Literal::String(parts.pop().unwrap().unwrap_string()) } else { - Literal::BacktickString(DString(parts)) + Literal::BacktickString(Box::new(DString(parts))) } } @@ -1699,20 +1809,22 @@ fn handle_d_backtick_strings_inner( inner_rule: Rule, file_id: usize, pair: Pair, - parts: &mut Vec, + parts: &mut Vec>, ) { for inner_pair in pair.into_inner() { let as_rule = inner_pair.as_rule(); if as_rule == inner_rule { - parts.push(DStringPart::from_string(inner_pair.as_span().as_str())); + parts.push(Box::new(DStringPart::from_string( + inner_pair.as_span().as_str(), + ))); } else if as_rule == Rule::DStringExpression { let expression_pair = inner_pair.into_inner().next().unwrap(); - parts.push(DStringPart::from_expression(expect_and_use( + parts.push(Box::new(DStringPart::from_expression(expect_and_use( file_id, expression_pair, Rule::Expression, build_expression, - ))); + )))); } else { unreachable!() } diff --git a/src/ast/children.rs b/src/ast/children.rs new file mode 100644 index 0000000..55e3a79 --- /dev/null +++ b/src/ast/children.rs @@ -0,0 +1,736 @@ +use crate::ast::*; + +pub enum ChildRef<'a> { + Identifier(&'a Identifier), + FullyQualifiedName(&'a FullyQualifiedName), + TypeUse(&'a TypeUse), + PrimitiveTypeUse(&'a PrimitiveTypeUse), + InterfaceOrClassTypeUse(&'a InterfaceOrClassTypeUse), + TupleTypeUse(&'a TupleTypeUse), + FunctionTypeUse(&'a FunctionTypeUse), + GenericArguments(&'a GenericArguments), + GenericParameters(&'a GenericParameters), + TupleArguments(&'a TupleArguments), + ImplementsList(&'a ImplementsList), + Parameters(&'a Parameters), + Parameter(&'a Parameter), + ReturnType(&'a ReturnType), + References(&'a References), + UseStatement(&'a UseStatement), + ModuleLevelDeclaration(&'a ModuleLevelDeclaration), + InterfaceLevelDeclaration(&'a InterfaceLevelDeclaration), + ClassLevelDeclaration(&'a ClassLevelDeclaration), + FunctionBody(&'a FunctionBody), + ClassConstructor(&'a ClassConstructor), + ClassConstructorParameter(&'a ClassConstructorParameter), + BlockStatement(&'a BlockStatement), + Statement(&'a Statement), + IfStatement(&'a IfStatement), + ElseIfs(&'a ElseIfs), + ElseBlock(&'a ElseBlock), + Expression(&'a Expression), + TurboFish(&'a TurboFish), + CallArguments(&'a CallArguments), + CallArgument(&'a CallArgument), + ClosureCaptures(&'a ClosureCaptures), + ClosureCapture(&'a ClosureCapture), + ClosureParameters(&'a ClosureParameters), + ClosureParameter(&'a ClosureParameter), + ObjectNavigations(&'a ObjectNavigations), + ObjectNavigation(&'a ObjectNavigation), + DString(&'a DString), + DStringPart(&'a DStringPart), +} + +pub trait HasChildren { + fn children(&self) -> Vec; +} + +impl HasChildren for FullyQualifiedName { + fn children(&self) -> Vec { + self.identifiers() + .iter() + .map(|id| ChildRef::Identifier(*id)) + .collect() + } +} + +impl HasChildren for TypeUse { + fn children(&self) -> Vec { + match self { + TypeUse::Primitive(primitive_type_use) => primitive_type_use.children(), + TypeUse::InterfaceOrClass(interface_or_class_type_use) => { + interface_or_class_type_use.children() + } + TypeUse::Tuple(tuple_type_use) => tuple_type_use.children(), + TypeUse::Function(function_type_use) => function_type_use.children(), + } + } +} + +impl HasChildren for PrimitiveTypeUse { + fn children(&self) -> Vec { + match self { + PrimitiveTypeUse::Array(generics) => { + if let Some(generics) = generics { + vec![ChildRef::GenericArguments(&generics)] + } else { + vec![] + } + } + _ => vec![], + } + } +} + +impl HasChildren for InterfaceOrClassTypeUse { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::FullyQualifiedName(self.fqn())); + children.push(ChildRef::GenericArguments(self.generics())); + children + } +} + +impl HasChildren for TupleTypeUse { + fn children(&self) -> Vec { + vec![ChildRef::TupleArguments(self.arguments())] + } +} + +impl HasChildren for FunctionTypeUse { + fn children(&self) -> Vec { + vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ] + } +} + +impl HasChildren for GenericArguments { + fn children(&self) -> Vec { + self.arguments() + .iter() + .map(|type_use| ChildRef::TypeUse(*type_use)) + .collect() + } +} + +impl HasChildren for GenericParameters { + fn children(&self) -> Vec { + self.identifiers() + .iter() + .map(|id| ChildRef::Identifier(*id)) + .collect() + } +} + +impl HasChildren for TupleArguments { + fn children(&self) -> Vec { + self.arguments() + .iter() + .map(|type_use| ChildRef::TypeUse(*type_use)) + .collect() + } +} + +impl HasChildren for ImplementsList { + fn children(&self) -> Vec { + self.type_uses() + .iter() + .map(|type_use| ChildRef::TypeUse(*type_use)) + .collect() + } +} + +impl HasChildren for Parameters { + fn children(&self) -> Vec { + self.parameters() + .iter() + .map(|parameter| ChildRef::Parameter(*parameter)) + .collect() + } +} + +impl HasChildren for Parameter { + fn children(&self) -> Vec { + vec![ + ChildRef::Identifier(self.identifier()), + ChildRef::TypeUse(self.type_use()), + ] + } +} + +impl HasChildren for ReturnType { + fn children(&self) -> Vec { + vec![ + ChildRef::TypeUse(self.declared_type()), + ChildRef::References(self.references()), + ] + } +} + +impl HasChildren for CompilationUnit { + fn children(&self) -> Vec { + let mut children = vec![]; + if let Some(namespace) = self.namespace() { + children.push(ChildRef::FullyQualifiedName(namespace)); + } + children.extend( + self.use_statements() + .iter() + .map(|use_statement| ChildRef::UseStatement(*use_statement)), + ); + children.extend( + self.declarations() + .iter() + .map(|declaration| ChildRef::ModuleLevelDeclaration(*declaration)), + ); + children + } +} + +impl HasChildren for UseStatement { + fn children(&self) -> Vec { + let mut children = vec![]; + children.extend( + self.identifiers() + .iter() + .map(|identifier| ChildRef::Identifier(*identifier)), + ); + match self.last() { + UseStatementLast::Identifier(identifier) => { + children.push(ChildRef::Identifier(identifier)) + } + UseStatementLast::Identifiers(identifiers) => children.extend( + identifiers + .iter() + .map(|identifier| ChildRef::Identifier(identifier.clone())), + ), + UseStatementLast::Star => {} + } + children + } +} + +impl HasChildren for ModuleLevelDeclaration { + fn children(&self) -> Vec { + use ModuleLevelDeclaration::*; + match self { + Module(module_declaration) => module_declaration.children(), + Interface(interface_declaration) => interface_declaration.children(), + Class(class_declaration) => class_declaration.children(), + Function(function_definition) => function_definition.children(), + PlatformFunction(platform_function_declaration) => { + platform_function_declaration.children() + } + } + } +} + +impl HasChildren for InterfaceLevelDeclaration { + fn children(&self) -> Vec { + use InterfaceLevelDeclaration::*; + match self { + Module(module_declaration) => module_declaration.children(), + Interface(interface_declaration) => interface_declaration.children(), + Class(class_declaration) => class_declaration.children(), + Function(function_declaration) => function_declaration.children(), + OperatorFunction(operator_function_declaration) => { + operator_function_declaration.children() + } + } + } +} + +impl HasChildren for ClassLevelDeclaration { + fn children(&self) -> Vec { + use ClassLevelDeclaration::*; + match self { + Module(module_declaration) => module_declaration.children(), + Interface(interface_declaration) => interface_declaration.children(), + Class(class_declaration) => class_declaration.children(), + Function(function_definition) => function_definition.children(), + OperatorFunction(operator_function_definition) => { + operator_function_definition.children() + } + PlatformFunction(platform_function_declaration) => { + platform_function_declaration.children() + } + Property(property_declaration) => property_declaration.children(), + Field(field_declaration) => field_declaration.children(), + } + } +} + +impl HasChildren for ModuleDeclaration { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Identifier(self.identifier())); + children.extend( + self.declarations() + .iter() + .map(|declaration| ChildRef::ModuleLevelDeclaration(*declaration)), + ); + children + } +} + +impl HasChildren for InterfaceDeclaration { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Identifier(self.identifier())); + children.push(ChildRef::GenericParameters(self.generics())); + children.push(ChildRef::ImplementsList(self.implements())); + children.extend( + self.declarations() + .iter() + .map(|declaration| ChildRef::InterfaceLevelDeclaration(*declaration)), + ); + children + } +} + +impl HasChildren for ClassDeclaration { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Identifier(self.identifier())); + children.push(ChildRef::GenericParameters(self.generics())); + if let Some(class_constructor) = self.class_constructor() { + children.push(ChildRef::ClassConstructor(class_constructor)); + } + children.push(ChildRef::ImplementsList(self.implements())); + children.extend( + self.declarations() + .iter() + .map(|declaration| ChildRef::ClassLevelDeclaration(*declaration)), + ); + children + } +} + +impl HasChildren for FunctionDefinition { + fn children(&self) -> Vec { + vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Identifier(self.identifier()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ChildRef::FunctionBody(self.body()), + ] + } +} + +impl HasChildren for OperatorFunctionDefinition { + fn children(&self) -> Vec { + vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ChildRef::FunctionBody(self.body()), + ] + } +} + +impl HasChildren for PlatformFunctionDeclaration { + fn children(&self) -> Vec { + vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Identifier(self.identifier()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ] + } +} + +impl HasChildren for InterfaceFunctionDeclaration { + fn children(&self) -> Vec { + let mut children = vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Identifier(self.identifier()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ]; + if let Some(body) = self.body() { + children.push(ChildRef::FunctionBody(body)) + } + children + } +} + +impl HasChildren for InterfaceOperatorFunctionDeclaration { + fn children(&self) -> Vec { + let mut children = vec![ + ChildRef::GenericParameters(self.generics()), + ChildRef::Parameters(self.parameters()), + ChildRef::ReturnType(self.return_type()), + ]; + if let Some(body) = self.body() { + children.push(ChildRef::FunctionBody(body)) + } + children + } +} + +impl HasChildren for FunctionBody { + fn children(&self) -> Vec { + match self { + Self::Equals(expression) => expression.children(), + Self::Block(block_statement) => block_statement.children(), + Self::Alias(identifier) => vec![ChildRef::Identifier(identifier.as_ref())], + } + } +} + +impl HasChildren for ClassConstructor { + fn children(&self) -> Vec { + self.parameters() + .iter() + .map(|parameter| ChildRef::ClassConstructorParameter(*parameter)) + .collect() + } +} + +impl HasChildren for ClassConstructorParameter { + fn children(&self) -> Vec { + match self { + Self::Property(property_declaration) => property_declaration.children(), + Self::Field(field_declaration) => field_declaration.children(), + } + } +} + +impl HasChildren for PropertyDeclaration { + fn children(&self) -> Vec { + vec![ + ChildRef::Identifier(self.identifier()), + ChildRef::TypeUse(self.declared_type()), + ] + } +} + +impl HasChildren for FieldDeclaration { + fn children(&self) -> Vec { + vec![ + ChildRef::Identifier(self.identifier()), + ChildRef::TypeUse(self.declared_type()), + ] + } +} + +impl HasChildren for BlockStatement { + fn children(&self) -> Vec { + let mut children = vec![]; + children.extend( + self.statements() + .iter() + .map(|statement| ChildRef::Statement(statement)), + ); + if let Some(expression) = self.expression() { + children.push(ChildRef::Expression(expression)); + } + children + } +} + +impl HasChildren for Statement { + fn children(&self) -> Vec { + use Statement::*; + match self { + BlockStatement(block_statement) => block_statement.children(), + VariableDeclarationStatement(variable_declaration_statement) => { + variable_declaration_statement.children() + } + AssignStatement(assign_statement) => assign_statement.children(), + CallStatement(call_statement) => call_statement.children(), + ReturnStatement(return_statement) => return_statement.children(), + IfStatement(if_statement) => if_statement.children(), + IfElseStatement(if_else_statement) => if_else_statement.children(), + WhileStatement(while_statement) => while_statement.children(), + ForStatement(for_statement) => for_statement.children(), + } + } +} + +impl HasChildren for VariableDeclarationStatement { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Identifier(self.identifier())); + if let Some(declared_type) = self.declared_type() { + children.push(ChildRef::TypeUse(declared_type)); + } + if let Some(initializer) = self.initializer() { + children.push(ChildRef::Expression(initializer)); + } + children + } +} + +impl HasChildren for AssignStatement { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.lhs()), + ChildRef::Expression(self.rhs()), + ] + } +} + +impl HasChildren for CallStatement { + fn children(&self) -> Vec { + vec![ChildRef::Expression(self.expression())] + } +} + +impl HasChildren for ReturnStatement { + fn children(&self) -> Vec { + if let Some(expression) = self.expression() { + vec![ChildRef::Expression(expression)] + } else { + vec![] + } + } +} + +impl HasChildren for IfStatement { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.condition()), + ChildRef::BlockStatement(self.then_block()), + ] + } +} + +impl HasChildren for IfElseStatement { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::IfStatement(self.if_statement())); + children.push(ChildRef::ElseIfs(self.else_ifs())); + if let Some(else_block) = self.else_block() { + children.push(ChildRef::ElseBlock(else_block)); + } + children + } +} + +impl HasChildren for ElseIfs { + fn children(&self) -> Vec { + self.if_statements() + .iter() + .map(|statement| ChildRef::IfStatement(statement)) + .collect() + } +} + +impl HasChildren for ElseBlock { + fn children(&self) -> Vec { + vec![ChildRef::BlockStatement(self.block_statement())] + } +} + +impl HasChildren for WhileStatement { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.condition()), + ChildRef::BlockStatement(self.body()), + ] + } +} + +impl HasChildren for ForStatement { + fn children(&self) -> Vec { + vec![ + ChildRef::Identifier(self.variable()), + ChildRef::Expression(self.iterator()), + ChildRef::BlockStatement(self.body()), + ] + } +} + +impl HasChildren for Expression { + fn children(&self) -> Vec { + use Expression::*; + match self { + Ternary(ternary) => ternary.children(), + Binary(binary) => binary.children(), + UnaryPrefix(prefix) => prefix.children(), + UnarySuffix(suffix) => suffix.children(), + Call(call) => call.children(), + ObjectAccess(object_access) => object_access.children(), + Literal(literal) => literal.children(), + FullyQualifiedName(fully_qualified_name) => fully_qualified_name.children(), + Closure(closure) => closure.children(), + } + } +} + +impl HasChildren for TernaryExpression { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.condition()), + ChildRef::Expression(self.true_expression()), + ChildRef::Expression(self.false_expression()), + ] + } +} + +impl HasChildren for BinaryExpression { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.left()), + ChildRef::Expression(self.right()), + ] + } +} + +impl HasChildren for PrefixExpression { + fn children(&self) -> Vec { + vec![ChildRef::Expression(self.expression())] + } +} + +impl HasChildren for SuffixExpression { + fn children(&self) -> Vec { + vec![ChildRef::Expression(self.expression())] + } +} + +impl HasChildren for CallExpression { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Expression(self.callee())); + if let Some(turbo_fish) = self.turbo_fish() { + children.push(ChildRef::TurboFish(turbo_fish)); + } + children.push(ChildRef::CallArguments(self.arguments())); + children + } +} + +impl HasChildren for TurboFish { + fn children(&self) -> Vec { + vec![ChildRef::GenericArguments(self.generics())] + } +} + +impl HasChildren for CallArguments { + fn children(&self) -> Vec { + self.arguments() + .iter() + .map(|argument| ChildRef::CallArgument(*argument)) + .collect() + } +} + +impl HasChildren for CallArgument { + fn children(&self) -> Vec { + vec![ChildRef::Expression(self.expression())] + } +} + +impl HasChildren for Closure { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::ClosureCaptures(self.captures())); + children.push(ChildRef::ClosureParameters(self.parameters())); + children.extend( + self.statements() + .iter() + .map(|statement| ChildRef::Statement(statement)), + ); + if let Some(expression) = self.expression() { + children.push(ChildRef::Expression(expression)); + } + children + } +} + +impl HasChildren for ClosureCaptures { + fn children(&self) -> Vec { + self.captures() + .iter() + .map(|capture| ChildRef::ClosureCapture(*capture)) + .collect() + } +} + +impl HasChildren for ClosureCapture { + fn children(&self) -> Vec { + vec![ChildRef::Identifier(self.identifier())] + } +} + +impl HasChildren for ClosureParameters { + fn children(&self) -> Vec { + self.parameters() + .iter() + .map(|parameter| ChildRef::ClosureParameter(*parameter)) + .collect() + } +} + +impl HasChildren for ClosureParameter { + fn children(&self) -> Vec { + let mut children = vec![]; + children.push(ChildRef::Identifier(self.identifier())); + if let Some(type_use) = self.type_use() { + children.push(ChildRef::TypeUse(type_use)); + } + children + } +} + +impl HasChildren for ObjectAccess { + fn children(&self) -> Vec { + vec![ + ChildRef::Expression(self.receiver()), + ChildRef::ObjectNavigations(self.navigations()), + ] + } +} + +impl HasChildren for ObjectNavigations { + fn children(&self) -> Vec { + self.navigations() + .iter() + .map(|navigation| ChildRef::ObjectNavigation(*navigation)) + .collect() + } +} + +impl HasChildren for ObjectNavigation { + fn children(&self) -> Vec { + vec![match self { + ObjectNavigation::Identifier(identifier) => ChildRef::Identifier(identifier), + ObjectNavigation::Index(index_expression) => ChildRef::Expression(index_expression), + }] + } +} + +impl HasChildren for Literal { + fn children(&self) -> Vec { + match self { + Literal::DString(d_string) => vec![ChildRef::DString(d_string)], + Literal::BacktickString(d_string) => vec![ChildRef::DString(d_string)], + _ => vec![], + } + } +} + +impl HasChildren for DString { + fn children(&self) -> Vec { + self.parts() + .iter() + .map(|part| ChildRef::DStringPart(*part)) + .collect() + } +} + +impl HasChildren for DStringPart { + fn children(&self) -> Vec { + match self { + DStringPart::Expression(expression) => vec![ChildRef::Expression(expression)], + _ => vec![], + } + } +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 19c7044..b477d6a 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -2,11 +2,10 @@ use crate::ast::named::Named; use crate::name_analysis::symbol::Symbol; use pest::Parser; use std::borrow::Cow; -use std::cell::RefCell; use std::range::Range; -use std::rc::Rc; pub mod build; +pub mod children; pub mod named; pub mod pretty_print; pub mod unparse; @@ -44,6 +43,7 @@ pub enum PrefixUnaryOperator { Spread, BorrowMut, Borrow, + Star, Mut, Not, Negative, @@ -53,6 +53,8 @@ pub enum PrefixUnaryOperator { pub enum SuffixUnaryOperator { PlusPlus, MinusMinus, + Call, + Index, } /* Names */ @@ -68,7 +70,7 @@ pub struct Identifier { impl Identifier { pub fn new(name: &str, file_id: usize, range: Range) -> Self { - Identifier { + Self { name: name.to_string(), file_id, range, @@ -80,7 +82,7 @@ impl Identifier { #[derive(Debug)] pub struct FullyQualifiedName { - identifiers: Vec, + identifiers: Vec>, file_id: usize, range: Range, scope_id: Option, @@ -88,8 +90,8 @@ pub struct FullyQualifiedName { } impl FullyQualifiedName { - pub fn new(identifiers: Vec, file_id: usize, range: Range) -> Self { - FullyQualifiedName { + pub fn new(identifiers: Vec>, file_id: usize, range: Range) -> Self { + Self { identifiers, range, file_id, @@ -98,19 +100,31 @@ impl FullyQualifiedName { } } + pub fn identifiers(&self) -> Vec<&Identifier> { + self.identifiers.iter().map(Box::as_ref).collect() + } + + pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> { + self.identifiers.iter_mut().map(Box::as_mut).collect() + } + + #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn last(&self) -> &Identifier { &self.identifiers[self.identifiers.len() - 1] } + #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn last_mut(&mut self) -> &mut Identifier { let last_index = self.identifiers.len() - 1; &mut self.identifiers[last_index] } - + + #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn len(&self) -> usize { self.identifiers.len() } - + + #[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")] pub fn is_single_identifier(&self) -> bool { self.identifiers.len() == 1 } @@ -120,10 +134,10 @@ impl FullyQualifiedName { #[derive(Debug)] pub enum TypeUse { - Primitive(PrimitiveTypeUse), - InterfaceOrClass(InterfaceOrClassTypeUse), - Tuple(TupleTypeUse), - Function(FunctionTypeUse), + Primitive(Box), + InterfaceOrClass(Box), + Tuple(Box), + Function(Box), } #[derive(Debug)] @@ -143,37 +157,165 @@ pub enum PrimitiveTypeUse { #[derive(Debug)] pub struct InterfaceOrClassTypeUse { - pub borrow_count: usize, - pub is_mutable: bool, - pub fqn: FullyQualifiedName, - pub generics: GenericArguments, + borrow_count: usize, + is_mutable: bool, + fqn: Box, + generics: Box, +} + +impl InterfaceOrClassTypeUse { + pub fn new( + borrow_count: usize, + is_mutable: bool, + fqn: Box, + generics: Box, + ) -> Self { + Self { + borrow_count, + is_mutable, + fqn, + generics, + } + } + + pub fn borrow_count(&self) -> usize { + self.borrow_count + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn fqn(&self) -> &FullyQualifiedName { + &self.fqn + } + + pub fn fqn_mut(&mut self) -> &mut FullyQualifiedName { + &mut self.fqn + } + + pub fn generics(&self) -> &GenericArguments { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericArguments { + &mut self.generics + } } #[derive(Debug)] pub struct TupleTypeUse { - pub borrow_count: usize, - pub is_mutable: bool, - pub arguments: TupleArguments, + borrow_count: usize, + is_mutable: bool, + arguments: Box, +} + +impl TupleTypeUse { + pub fn new(borrow_count: usize, is_mutable: bool, arguments: Box) -> Self { + Self { + borrow_count, + is_mutable, + arguments, + } + } + + pub fn borrow_count(&self) -> usize { + self.borrow_count + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn arguments(&self) -> &TupleArguments { + &self.arguments + } + + pub fn arguments_mut(&mut self) -> &mut TupleArguments { + &mut self.arguments + } } #[derive(Debug)] pub struct FunctionTypeUse { - pub borrow_count: usize, - pub function_modifier: Option, - pub generics: GenericParameters, - pub parameters: Parameters, - pub return_type: ReturnType, + borrow_count: usize, + function_modifier: Option, + generics: Box, + parameters: Box, + return_type: Box, +} + +impl FunctionTypeUse { + pub fn new( + borrow_count: usize, + function_modifier: Option, + generics: Box, + parameters: Box, + return_type: Box, + ) -> Self { + Self { + borrow_count, + function_modifier, + generics, + parameters, + return_type, + } + } + + pub fn borrow_count(&self) -> usize { + self.borrow_count + } + + pub fn function_modifier(&self) -> Option<&FunctionTypeModifier> { + self.function_modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn parameters(&self) -> &Box { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Box { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } } /* Generic arguments */ #[derive(Debug)] -pub struct GenericArguments(pub Vec); +pub struct GenericArguments(Vec>); impl GenericArguments { + pub fn new(arguments: Vec>) -> Self { + Self(arguments) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn arguments(&self) -> Vec<&TypeUse> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn arguments_mut(&mut self) -> Vec<&mut TypeUse> { + self.0.iter_mut().map(Box::as_mut).collect() + } } impl Default for GenericArguments { @@ -185,12 +327,24 @@ impl Default for GenericArguments { /* Generic parameters */ #[derive(Debug)] -pub struct GenericParameters(pub Vec); +pub struct GenericParameters(Vec>); impl GenericParameters { + pub fn new(identifiers: Vec>) -> Self { + Self(identifiers) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn identifiers(&self) -> Vec<&Identifier> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> { + self.0.iter_mut().map(Box::as_mut).collect() + } } impl Default for GenericParameters { @@ -202,17 +356,47 @@ impl Default for GenericParameters { /* Tuple Arguments */ #[derive(Debug)] -pub struct TupleArguments(pub Vec); +pub struct TupleArguments(Vec>); + +impl TupleArguments { + pub fn new(arguments: Vec>) -> Self { + Self(arguments) + } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn arguments(&self) -> Vec<&TypeUse> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn arguments_mut(&mut self) -> Vec<&mut TypeUse> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} /* Implements List */ #[derive(Debug)] -pub struct ImplementsList(pub Vec); +pub struct ImplementsList(Vec>); impl ImplementsList { + pub fn new(type_uses: Vec>) -> Self { + Self(type_uses) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn type_uses(&self) -> Vec<&TypeUse> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn type_uses_mut(&mut self) -> Vec<&mut TypeUse> { + self.0.iter_mut().map(Box::as_mut).collect() + } } impl Default for ImplementsList { @@ -234,12 +418,24 @@ pub enum FunctionTypeModifier { /* Function Parameters */ #[derive(Debug)] -pub struct Parameters(pub Vec); +pub struct Parameters(Vec>); impl Parameters { + pub fn new(parameters: Vec>) -> Self { + Self(parameters) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn parameters(&self) -> Vec<&Parameter> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn parameters_mut(&mut self) -> Vec<&mut Parameter> { + self.0.iter_mut().map(Box::as_mut).collect() + } } impl Default for Parameters { @@ -250,36 +446,96 @@ impl Default for Parameters { #[derive(Debug)] pub struct Parameter { - pub identifier: Identifier, - pub type_use: TypeUse, + identifier: Box, + type_use: Box, +} + +impl Parameter { + pub fn new(identifier: Box, type_use: Box) -> Self { + Self { + identifier, + type_use, + } + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn type_use(&self) -> &TypeUse { + &self.type_use + } + + pub fn type_use_mut(&mut self) -> &mut TypeUse { + &mut self.type_use + } } /* Return Type */ #[derive(Debug)] pub struct ReturnType { - pub declared_type: Box, - pub references: References, + declared_type: Box, + references: Box, } impl ReturnType { + pub fn new(declared_type: Box, references: Box) -> Self { + Self { + declared_type, + references, + } + } + pub fn void() -> Self { ReturnType { - declared_type: Box::new(TypeUse::Primitive(PrimitiveTypeUse::Void)), - references: References::default(), + declared_type: Box::new(TypeUse::Primitive(Box::new(PrimitiveTypeUse::Void))), + references: Box::new(References::default()), } } + + pub fn declared_type(&self) -> &TypeUse { + &self.declared_type + } + + pub fn declared_type_mut(&mut self) -> &mut TypeUse { + &mut self.declared_type + } + + pub fn references(&self) -> &References { + &self.references + } + + pub fn references_mut(&mut self) -> &mut References { + &mut self.references + } } /* References */ #[derive(Debug)] -pub struct References(pub Vec); +pub struct References(Vec>); impl References { + pub fn new(identifiers: Vec>) -> Self { + Self(identifiers) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn identifiers(&self) -> Vec<&Identifier> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> { + self.0.iter_mut().map(Box::as_mut).collect() + } } impl Default for References { @@ -292,27 +548,78 @@ impl Default for References { #[derive(Debug)] pub struct CompilationUnit { - pub file_name: String, - pub file_id: usize, - pub namespace: Option, - pub use_statements: Vec, - pub declarations: Vec, + file_name: String, + file_id: usize, + namespace: Option>, + use_statements: Vec>, + declarations: Vec>, +} + +impl CompilationUnit { + pub fn new( + file_name: String, + file_id: usize, + namespace: Option>, + use_statements: Vec>, + declarations: Vec>, + ) -> Self { + Self { + file_name, + file_id, + namespace, + use_statements, + declarations, + } + } + + pub fn file_name(&self) -> &str { + &self.file_name + } + + pub fn file_id(&self) -> usize { + self.file_id + } + + pub fn namespace(&self) -> Option<&FullyQualifiedName> { + // We have to use this non-map syntax because we need a reference like `&self.namespace` + if let Some(namespace) = &self.namespace { + Some(namespace.as_ref()) + } else { + None + } + } + + pub fn use_statements(&self) -> Vec<&UseStatement> { + self.use_statements.iter().map(Box::as_ref).collect() + } + + pub fn use_statements_mut(&mut self) -> Vec<&mut UseStatement> { + self.use_statements.iter_mut().map(Box::as_mut).collect() + } + + pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> { + self.declarations.iter().map(Box::as_ref).collect() + } + + pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> { + self.declarations.iter_mut().map(Box::as_mut).collect() + } } /* Use Statement */ #[derive(Debug)] pub struct UseStatement { - pub identifiers: Vec, - pub last: UseStatementLast, - pub file_id: usize, - pub range: Range, + identifiers: Vec>, + last: Box, + file_id: usize, + range: Range, } impl UseStatement { pub fn new( - identifiers: Vec, - last: UseStatementLast, + identifiers: Vec>, + last: Box, file_id: usize, range: Range, ) -> Self { @@ -327,7 +634,7 @@ impl UseStatement { pub fn base_name(&self) -> Cow<'_, str> { use UseStatementLast::*; if self.identifiers.is_empty() { - match &self.last { + match self.last.as_ref() { Identifier(_) => Cow::from(""), Star | Identifiers(_) => panic!(), // should never get here because of grammar } @@ -346,17 +653,33 @@ impl UseStatement { } pub fn is_star(&self) -> bool { - match &self.last { + match self.last.as_ref() { UseStatementLast::Star => true, _ => false, } } + + pub fn identifiers(&self) -> Vec<&Identifier> { + self.identifiers.iter().map(Box::as_ref).collect() + } + + pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> { + self.identifiers.iter_mut().map(Box::as_mut).collect() + } + + pub fn last(&self) -> &UseStatementLast { + &self.last + } + + pub fn last_mut(&mut self) -> &mut UseStatementLast { + &mut self.last + } } #[derive(Debug)] pub enum UseStatementLast { - Identifier(Rc>), - Identifiers(Vec>>), + Identifier(Box), + Identifiers(Vec>), Star, } @@ -364,114 +687,594 @@ pub enum UseStatementLast { #[derive(Debug)] pub enum ModuleLevelDeclaration { - Module(ModuleDeclaration), - Interface(InterfaceDeclaration), - Class(ClassDeclaration), - Function(FunctionDefinition), - PlatformFunction(PlatformFunctionDeclaration), + Module(Box), + Interface(Box), + Class(Box), + Function(Box), + PlatformFunction(Box), } #[derive(Debug)] pub enum InterfaceLevelDeclaration { - Module(ModuleDeclaration), - Interface(InterfaceDeclaration), - Class(ClassDeclaration), - Function(InterfaceFunctionDeclaration), - OperatorFunction(InterfaceOperatorFunctionDeclaration), + Module(Box), + Interface(Box), + Class(Box), + Function(Box), + OperatorFunction(Box), } #[derive(Debug)] pub enum ClassLevelDeclaration { - Module(ModuleDeclaration), - Interface(InterfaceDeclaration), - Class(ClassDeclaration), - Function(FunctionDefinition), - OperatorFunction(OperatorFunctionDefinition), - PlatformFunction(PlatformFunctionDeclaration), - Property(PropertyDeclaration), - Field(FieldDeclaration), + Module(Box), + Interface(Box), + Class(Box), + Function(Box), + OperatorFunction(Box), + PlatformFunction(Box), + Property(Box), + Field(Box), } /* Main Declarations */ #[derive(Debug)] pub struct ModuleDeclaration { - pub is_public: bool, - pub identifier: Identifier, - pub declarations: Vec, + is_public: bool, + identifier: Box, + declarations: Vec>, +} + +impl ModuleDeclaration { + pub fn new( + is_public: bool, + identifier: Box, + declarations: Vec>, + ) -> Self { + Self { + is_public, + identifier, + declarations, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> { + self.declarations.iter().map(Box::as_ref).collect() + } + + pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> { + self.declarations.iter_mut().map(Box::as_mut).collect() + } } #[derive(Debug)] pub struct InterfaceDeclaration { - pub is_public: bool, - pub identifier: Identifier, - pub generics: GenericParameters, - pub implements: ImplementsList, - pub declarations: Vec, + is_public: bool, + identifier: Box, + generics: Box, + implements: Box, + declarations: Vec>, +} + +impl InterfaceDeclaration { + pub fn new( + is_public: bool, + identifier: Box, + generics: Box, + implements: Box, + declarations: Vec>, + ) -> Self { + Self { + is_public, + identifier, + generics, + implements, + declarations, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn implements(&self) -> &ImplementsList { + &self.implements + } + + pub fn implements_mut(&mut self) -> &mut ImplementsList { + &mut self.implements + } + + pub fn declarations(&self) -> Vec<&InterfaceLevelDeclaration> { + self.declarations.iter().map(Box::as_ref).collect() + } + + pub fn declarations_mut(&mut self) -> Vec<&mut InterfaceLevelDeclaration> { + self.declarations.iter_mut().map(Box::as_mut).collect() + } } #[derive(Debug)] pub struct ClassDeclaration { - pub is_public: bool, - pub identifier: Identifier, - pub generics: GenericParameters, - pub class_constructor: Option, - pub implements: ImplementsList, - pub declarations: Vec, + is_public: bool, + identifier: Box, + generics: Box, + class_constructor: Option>, + implements: Box, + declarations: Vec>, +} + +impl ClassDeclaration { + pub fn new( + is_public: bool, + identifier: Box, + generics: Box, + class_constructor: Option>, + implements: Box, + declarations: Vec>, + ) -> Self { + Self { + is_public, + identifier, + generics, + class_constructor, + implements, + declarations, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn class_constructor(&self) -> Option<&ClassConstructor> { + if let Some(class_constructor) = &self.class_constructor { + Some(class_constructor.as_ref()) + } else { + None + } + } + + pub fn class_constructor_mut(&mut self) -> Option<&mut ClassConstructor> { + if let Some(class_constructor) = &mut self.class_constructor { + Some(class_constructor.as_mut()) + } else { + None + } + } + + pub fn implements(&self) -> &ImplementsList { + &self.implements + } + + pub fn implements_mut(&mut self) -> &mut ImplementsList { + &mut self.implements + } + + pub fn declarations(&self) -> Vec<&ClassLevelDeclaration> { + self.declarations.iter().map(Box::as_ref).collect() + } + + pub fn declarations_mut(&mut self) -> Vec<&mut ClassLevelDeclaration> { + self.declarations.iter_mut().map(Box::as_mut).collect() + } } /* Function declarations and components */ #[derive(Debug)] pub struct FunctionDefinition { - pub is_public: bool, - pub modifier: Option, - pub generics: GenericParameters, - pub identifier: Identifier, - pub parameters: Parameters, - pub return_type: ReturnType, - pub body: FunctionBody, + is_public: bool, + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, + body: Box, +} + +impl FunctionDefinition { + pub fn new( + is_public: bool, + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, + body: Box, + ) -> Self { + Self { + is_public, + modifier, + generics, + identifier, + parameters, + return_type, + body, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn modifier(&self) -> Option<&FunctionModifier> { + self.modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn parameters(&self) -> &Parameters { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Parameters { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } + + pub fn body(&self) -> &FunctionBody { + &self.body + } + + pub fn body_mut(&mut self) -> &mut FunctionBody { + &mut self.body + } } #[derive(Debug)] pub struct OperatorFunctionDefinition { - pub is_public: bool, - pub modifier: Option, - pub generics: GenericParameters, - pub operator: Operator, - pub parameters: Parameters, - pub return_type: ReturnType, - pub body: FunctionBody, + is_public: bool, + modifier: Option, + generics: Box, + operator: Operator, + parameters: Box, + return_type: Box, + body: Box, +} + +impl OperatorFunctionDefinition { + pub fn new( + is_public: bool, + modifier: Option, + generics: Box, + operator: Operator, + parameters: Box, + return_type: Box, + body: Box, + ) -> Self { + Self { + is_public, + modifier, + generics, + operator, + parameters, + return_type, + body, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn modifier(&self) -> Option<&FunctionModifier> { + self.modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn operator(&self) -> &Operator { + &self.operator + } + + pub fn parameters(&self) -> &Parameters { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Parameters { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } + + pub fn body(&self) -> &FunctionBody { + &self.body + } + + pub fn body_mut(&mut self) -> &mut FunctionBody { + &mut self.body + } } #[derive(Debug)] pub struct PlatformFunctionDeclaration { - pub is_public: bool, - pub modifier: Option, - pub generics: GenericParameters, - pub identifier: Identifier, - pub parameters: Parameters, - pub return_type: ReturnType, + is_public: bool, + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, +} + +impl PlatformFunctionDeclaration { + pub fn new( + is_public: bool, + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, + ) -> Self { + Self { + is_public, + modifier, + generics, + identifier, + parameters, + return_type, + } + } + + pub fn is_public(&self) -> bool { + self.is_public + } + + pub fn modifier(&self) -> Option<&FunctionModifier> { + self.modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn parameters(&self) -> &Parameters { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Parameters { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } } #[derive(Debug)] pub struct InterfaceFunctionDeclaration { - pub modifier: Option, - pub generics: GenericParameters, - pub identifier: Identifier, - pub parameters: Parameters, - pub return_type: ReturnType, - pub body: Option, + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, + body: Option>, +} + +impl InterfaceFunctionDeclaration { + pub fn new( + modifier: Option, + generics: Box, + identifier: Box, + parameters: Box, + return_type: Box, + body: Option>, + ) -> Self { + Self { + modifier, + generics, + identifier, + parameters, + return_type, + body, + } + } + + pub fn modifier(&self) -> Option<&FunctionModifier> { + self.modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn parameters(&self) -> &Parameters { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Parameters { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } + + pub fn body(&self) -> Option<&FunctionBody> { + FunctionBody::unwrap_option(&self.body) + } + + pub fn body_mut(&mut self) -> Option<&mut FunctionBody> { + FunctionBody::unwrap_option_mut(&mut self.body) + } } #[derive(Debug)] pub struct InterfaceOperatorFunctionDeclaration { - pub modifier: Option, - pub generics: GenericParameters, - pub operator: Operator, - pub parameters: Parameters, - pub return_type: ReturnType, - pub body: Option, + modifier: Option, + generics: Box, + operator: Operator, + parameters: Box, + return_type: Box, + body: Option>, +} + +impl InterfaceOperatorFunctionDeclaration { + pub fn new( + modifier: Option, + generics: Box, + operator: Operator, + parameters: Box, + return_type: Box, + body: Option>, + ) -> Self { + Self { + modifier, + generics, + operator, + parameters, + return_type, + body, + } + } + + pub fn modifier(&self) -> Option<&FunctionModifier> { + self.modifier.as_ref() + } + + pub fn generics(&self) -> &GenericParameters { + &self.generics + } + + pub fn generics_mut(&mut self) -> &mut GenericParameters { + &mut self.generics + } + + pub fn operator(&self) -> &Operator { + &self.operator + } + + pub fn parameters(&self) -> &Box { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut Box { + &mut self.parameters + } + + pub fn return_type(&self) -> &ReturnType { + &self.return_type + } + + pub fn return_type_mut(&mut self) -> &mut ReturnType { + &mut self.return_type + } + + pub fn body(&self) -> Option<&FunctionBody> { + FunctionBody::unwrap_option(&self.body) + } + + pub fn body_mut(&mut self) -> Option<&mut FunctionBody> { + FunctionBody::unwrap_option_mut(&mut self.body) + } } #[derive(Debug)] @@ -485,174 +1288,838 @@ pub enum FunctionModifier { #[derive(Debug)] pub enum FunctionBody { - Equals(Expression), - Block(BlockStatement), - Alias(Identifier), + Equals(Box), + Block(Box), + Alias(Box), +} + +impl FunctionBody { + fn unwrap_option(opt: &Option>) -> Option<&FunctionBody> { + if let Some(body) = opt { + Some(body.as_ref()) + } else { + None + } + } + + fn unwrap_option_mut(opt: &mut Option>) -> Option<&mut FunctionBody> { + if let Some(body) = opt { + Some(body.as_mut()) + } else { + None + } + } } /* Class components */ #[derive(Debug)] -pub struct ClassConstructor(pub Vec); +pub struct ClassConstructor(Vec>); + +impl ClassConstructor { + pub fn new(parameters: Vec>) -> Self { + Self(parameters) + } + + pub fn parameters(&self) -> Vec<&ClassConstructorParameter> { + self.0.iter().map(|p| p.as_ref()).collect() + } +} #[derive(Debug)] pub enum ClassConstructorParameter { - Property(PropertyDeclaration), - Field(FieldDeclaration), + Property(Box), + Field(Box), } #[derive(Debug)] pub struct PropertyDeclaration { - pub is_mutable: bool, - pub identifier: Identifier, - pub declared_type: TypeUse, + is_mutable: bool, + identifier: Box, + declared_type: Box, +} + +impl PropertyDeclaration { + pub fn new(is_mutable: bool, identifier: Box, declared_type: Box) -> Self { + Self { + is_mutable, + identifier, + declared_type, + } + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn declared_type(&self) -> &TypeUse { + &self.declared_type + } + + pub fn declared_type_mut(&mut self) -> &mut TypeUse { + &mut self.declared_type + } } #[derive(Debug)] pub struct FieldDeclaration { - pub is_mutable: bool, - pub identifier: Identifier, - pub declared_type: TypeUse, + is_mutable: bool, + identifier: Box, + declared_type: Box, +} + +impl FieldDeclaration { + pub fn new(is_mutable: bool, identifier: Box, declared_type: Box) -> Self { + Self { + is_mutable, + identifier, + declared_type, + } + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn declared_type(&self) -> &TypeUse { + &self.declared_type + } + + pub fn declared_type_mut(&mut self) -> &mut TypeUse { + &mut self.declared_type + } } /* Statements */ #[derive(Debug)] pub struct BlockStatement { - pub statements: Vec, - pub expression: Option, + statements: Vec>, + expression: Option>, +} + +impl BlockStatement { + pub fn new(statements: Vec>, expression: Option>) -> Self { + Self { + statements, + expression, + } + } + + pub fn statements(&self) -> Vec<&Statement> { + self.statements.iter().map(AsRef::as_ref).collect() + } + + pub fn statements_mut(&mut self) -> Vec<&mut Statement> { + self.statements.iter_mut().map(AsMut::as_mut).collect() + } + + pub fn expression(&self) -> Option<&Expression> { + if let Some(ref expression) = self.expression { + Some(expression.as_ref()) + } else { + None + } + } + + pub fn expression_mut(&mut self) -> Option<&mut Expression> { + if let Some(ref mut expression) = self.expression { + Some(expression.as_mut()) + } else { + None + } + } } #[derive(Debug)] pub enum Statement { - BlockStatement(BlockStatement), - VariableDeclarationStatement(VariableDeclarationStatement), - AssignStatement(AssignStatement), - CallStatement(CallStatement), - ReturnStatement(ReturnStatement), - IfStatement(IfStatement), - IfElseStatement(IfElseStatement), - WhileStatement(WhileStatement), - ForStatement(ForStatement), + BlockStatement(Box), + VariableDeclarationStatement(Box), + AssignStatement(Box), + CallStatement(Box), + ReturnStatement(Box), + IfStatement(Box), + IfElseStatement(Box), + WhileStatement(Box), + ForStatement(Box), } #[derive(Debug)] pub struct VariableDeclarationStatement { - pub is_mutable: bool, - pub identifier: Identifier, - pub declared_type: Option, - pub initializer: Option, + is_mutable: bool, + identifier: Box, + declared_type: Option>, + initializer: Option>, +} + +impl VariableDeclarationStatement { + pub fn new( + is_mutable: bool, + identifier: Box, + declared_type: Option>, + initializer: Option>, + ) -> Self { + Self { + is_mutable, + identifier, + declared_type, + initializer, + } + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn declared_type(&self) -> Option<&TypeUse> { + if let Some(type_use) = &self.declared_type { + Some(type_use.as_ref()) + } else { + None + } + } + + pub fn declared_type_mut(&mut self) -> Option<&mut TypeUse> { + if let Some(type_use) = &mut self.declared_type { + Some(type_use.as_mut()) + } else { + None + } + } + + pub fn initializer(&self) -> Option<&Expression> { + if let Some(initializer) = &self.initializer { + Some(initializer.as_ref()) + } else { + None + } + } + + pub fn initializer_mut(&mut self) -> Option<&mut Expression> { + if let Some(initializer) = &mut self.initializer { + Some(initializer.as_mut()) + } else { + None + } + } } #[derive(Debug)] pub struct AssignStatement { - pub lhs: Expression, - pub rhs: Expression, + lhs: Box, + rhs: Box, +} + +impl AssignStatement { + pub fn new(lhs: Box, rhs: Box) -> Self { + Self { lhs, rhs } + } + + pub fn lhs(&self) -> &Expression { + &self.lhs + } + + pub fn lhs_mut(&mut self) -> &mut Expression { + &mut self.lhs + } + + pub fn rhs(&self) -> &Expression { + &self.rhs + } + + pub fn rhs_mut(&mut self) -> &mut Expression { + &mut self.rhs + } } #[derive(Debug)] -pub struct CallStatement(pub Expression); +pub struct CallStatement(Box); + +impl CallStatement { + pub fn new(call_expression: Box) -> Self { + Self(call_expression) + } + + pub fn expression(&self) -> &Expression { + &self.0 + } + + pub fn expression_mut(&mut self) -> &mut Expression { + &mut self.0 + } +} #[derive(Debug)] -pub struct ReturnStatement(pub Option); +pub struct ReturnStatement(Option>); + +impl ReturnStatement { + pub fn new(expression: Option>) -> Self { + Self(expression) + } + + pub fn expression(&self) -> Option<&Expression> { + if let Some(expression) = &self.0 { + Some(expression.as_ref()) + } else { + None + } + } + + pub fn expression_mut(&mut self) -> Option<&mut Expression> { + if let Some(expression) = &mut self.0 { + Some(expression.as_mut()) + } else { + None + } + } +} #[derive(Debug)] pub struct IfStatement { - pub condition: Expression, - pub then_block: BlockStatement, + condition: Box, + then_block: Box, +} + +impl IfStatement { + pub fn new(condition: Box, then_block: Box) -> Self { + Self { + condition, + then_block, + } + } + + pub fn condition(&self) -> &Expression { + &self.condition + } + + pub fn condition_mut(&mut self) -> &mut Expression { + &mut self.condition + } + + pub fn then_block(&self) -> &BlockStatement { + &self.then_block + } + + pub fn then_block_mut(&mut self) -> &mut BlockStatement { + &mut self.then_block + } } #[derive(Debug)] pub struct IfElseStatement { - pub if_statement: IfStatement, - pub else_ifs: ElseIfs, - pub else_block: Option, + if_statement: Box, + else_ifs: Box, + else_block: Option>, +} + +impl IfElseStatement { + pub fn new( + if_statement: Box, + else_ifs: Box, + else_block: Option>, + ) -> Self { + Self { + if_statement, + else_ifs, + else_block, + } + } + + pub fn if_statement(&self) -> &IfStatement { + &self.if_statement + } + + pub fn if_statement_mut(&mut self) -> &mut IfStatement { + &mut self.if_statement + } + + pub fn else_ifs(&self) -> &ElseIfs { + &self.else_ifs + } + + pub fn else_ifs_mut(&mut self) -> &mut ElseIfs { + &mut self.else_ifs + } + + pub fn else_block(&self) -> Option<&ElseBlock> { + if let Some(else_block) = &self.else_block { + Some(else_block.as_ref()) + } else { + None + } + } + + pub fn else_block_mut(&mut self) -> Option<&mut ElseBlock> { + if let Some(else_block) = &mut self.else_block { + Some(else_block.as_mut()) + } else { + None + } + } } #[derive(Debug, Default)] -pub struct ElseIfs(pub Vec); +pub struct ElseIfs(Vec>); + +impl ElseIfs { + pub fn new(if_statements: Vec>) -> Self { + Self(if_statements) + } + + pub fn if_statements(&self) -> Vec<&IfStatement> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn if_statements_mut(&mut self) -> Vec<&mut IfStatement> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} #[derive(Debug)] -pub struct ElseBlock(pub BlockStatement); +pub struct ElseBlock(Box); + +impl ElseBlock { + pub fn new(block: Box) -> Self { + Self(block) + } + + pub fn block_statement(&self) -> &BlockStatement { + &self.0 + } + + pub fn block_statement_mut(&mut self) -> &mut BlockStatement { + &mut self.0 + } +} #[derive(Debug)] pub struct WhileStatement { - pub condition: Expression, - pub body: BlockStatement, + condition: Box, + body: Box, +} + +impl WhileStatement { + pub fn new(condition: Box, body: Box) -> Self { + Self { condition, body } + } + + pub fn condition(&self) -> &Expression { + &self.condition + } + + pub fn condition_mut(&mut self) -> &mut Expression { + &mut self.condition + } + + pub fn body(&self) -> &BlockStatement { + &self.body + } + + pub fn body_mut(&mut self) -> &mut BlockStatement { + &mut self.body + } } #[derive(Debug)] pub struct ForStatement { - pub variable: Identifier, - pub iterator: Expression, - pub body: BlockStatement, + variable: Box, + iterator: Box, + body: Box, +} + +impl ForStatement { + pub fn new( + variable: Box, + iterator: Box, + body: Box, + ) -> Self { + Self { + variable, + iterator, + body, + } + } + + pub fn variable(&self) -> &Identifier { + &self.variable + } + + pub fn variable_mut(&mut self) -> &mut Identifier { + &mut self.variable + } + + pub fn iterator(&self) -> &Expression { + &self.iterator + } + + pub fn iterator_mut(&mut self) -> &mut Expression { + &mut self.iterator + } + + pub fn body(&self) -> &BlockStatement { + &self.body + } + + pub fn body_mut(&mut self) -> &mut BlockStatement { + &mut self.body + } } /* Expressions */ #[derive(Debug)] pub enum Expression { - Ternary(TernaryExpression), - Binary(BinaryExpression), - UnaryPrefix(PrefixExpression), - UnarySuffix(SuffixExpression), - Call(CallExpression), - ObjectAccess(ObjectAccess), - Literal(Literal), - FullyQualifiedName(FullyQualifiedName), - Closure(Closure), + Ternary(Box), + Binary(Box), + UnaryPrefix(Box), + UnarySuffix(Box), + Call(Box), + ObjectAccess(Box), + Literal(Box), + FullyQualifiedName(Box), + Closure(Box), } #[derive(Debug)] pub struct TernaryExpression { - pub condition: Box, - pub true_expression: Box, - pub false_expression: Box, + condition: Box, + true_expression: Box, + false_expression: Box, +} + +impl TernaryExpression { + pub fn new( + condition: Box, + true_expression: Box, + false_expression: Box, + ) -> Self { + Self { + condition, + true_expression, + false_expression, + } + } + + pub fn condition(&self) -> &Expression { + &self.condition + } + + pub fn condition_mut(&mut self) -> &mut Expression { + &mut self.condition + } + + pub fn true_expression(&self) -> &Expression { + &self.true_expression + } + + pub fn true_expression_mut(&mut self) -> &mut Expression { + &mut self.true_expression + } + + pub fn false_expression(&self) -> &Expression { + &self.false_expression + } + + pub fn false_expression_mut(&mut self) -> &mut Expression { + &mut self.false_expression + } } #[derive(Debug)] pub struct BinaryExpression { - pub left: Box, - pub operator: BinaryOperator, - pub right: Box, + left: Box, + operator: BinaryOperator, + right: Box, +} + +impl BinaryExpression { + pub fn new(left: Box, operator: BinaryOperator, right: Box) -> Self { + Self { + left, + operator, + right, + } + } + + pub fn left(&self) -> &Expression { + &self.left + } + + pub fn left_mut(&mut self) -> &mut Expression { + &mut self.left + } + + pub fn operator(&self) -> &BinaryOperator { + &self.operator + } + + pub fn right(&self) -> &Expression { + &self.right + } + + pub fn right_mut(&mut self) -> &mut Expression { + &mut self.right + } } #[derive(Debug)] pub struct PrefixExpression { - pub operator: PrefixUnaryOperator, - pub expression: Box, + operator: PrefixUnaryOperator, + expression: Box, +} + +impl PrefixExpression { + pub fn new(operator: PrefixUnaryOperator, expression: Box) -> Self { + Self { + operator, + expression, + } + } + + pub fn operator(&self) -> &PrefixUnaryOperator { + &self.operator + } + + pub fn expression(&self) -> &Expression { + &self.expression + } + + pub fn expression_mut(&mut self) -> &mut Expression { + &mut self.expression + } } #[derive(Debug)] pub struct SuffixExpression { - pub expression: Box, - pub operator: SuffixUnaryOperator, + expression: Box, + operator: SuffixUnaryOperator, +} + +impl SuffixExpression { + pub fn new(expression: Box, operator: SuffixUnaryOperator) -> Self { + Self { + expression, + operator, + } + } + + pub fn expression(&self) -> &Expression { + &self.expression + } + + pub fn expression_mut(&mut self) -> &mut Expression { + &mut self.expression + } + + pub fn operator(&self) -> &SuffixUnaryOperator { + &self.operator + } } #[derive(Debug)] pub struct CallExpression { - pub callee: Box, - pub turbo_fish: Option, - pub arguments: CallArguments, + callee: Box, + turbo_fish: Option>, + arguments: Box, +} + +impl CallExpression { + pub fn new( + callee: Box, + turbo_fish: Option>, + arguments: Box, + ) -> Self { + Self { + callee, + turbo_fish, + arguments, + } + } + + pub fn callee(&self) -> &Expression { + &self.callee + } + + pub fn callee_mut(&mut self) -> &mut Expression { + &mut self.callee + } + + pub fn turbo_fish(&self) -> Option<&TurboFish> { + if let Some(turbo_fish) = &self.turbo_fish { + Some(turbo_fish.as_ref()) + } else { + None + } + } + + pub fn turbo_fish_mut(&mut self) -> Option<&mut TurboFish> { + if let Some(turbo_fish) = &mut self.turbo_fish { + Some(turbo_fish.as_mut()) + } else { + None + } + } + + pub fn arguments(&self) -> &CallArguments { + &self.arguments + } + + pub fn arguments_mut(&mut self) -> &mut CallArguments { + &mut self.arguments + } } #[derive(Debug)] -pub struct TurboFish(pub GenericArguments); +pub struct TurboFish(Box); + +impl TurboFish { + pub fn new(generics: Box) -> Self { + Self(generics) + } + + pub fn generics(&self) -> &GenericArguments { + &self.0 + } + + pub fn generics_mut(&mut self) -> &mut GenericArguments { + &mut self.0 + } +} #[derive(Debug)] -pub struct CallArguments(pub Vec); +pub struct CallArguments(Vec>); + +impl CallArguments { + pub fn new(arguments: Vec>) -> Self { + Self(arguments) + } + + pub fn arguments(&self) -> Vec<&CallArgument> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn arguments_mut(&mut self) -> Vec<&mut CallArgument> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} #[derive(Debug)] -pub struct CallArgument(pub Box); +pub struct CallArgument(Box); + +impl CallArgument { + pub fn new(expression: Box) -> Self { + Self(expression) + } + + pub fn expression(&self) -> &Expression { + &self.0 + } + + pub fn expression_mut(&mut self) -> &mut Expression { + &mut self.0 + } +} #[derive(Debug)] pub struct Closure { - pub modifier: Option, - pub is_move: bool, - pub captures: ClosureCaptures, - pub parameters: ClosureParameters, - pub statements: Vec, - pub expression: Option>, + modifier: Option, + is_move: bool, + captures: Box, + parameters: Box, + statements: Vec>, + expression: Option>, +} + +impl Closure { + pub fn new( + modifier: Option, + is_move: bool, + captures: Box, + parameters: Box, + statements: Vec>, + expression: Option>, + ) -> Self { + Self { + modifier, + is_move, + captures, + parameters, + statements, + expression, + } + } + + pub fn modifier(&self) -> Option<&ClosureModifier> { + self.modifier.as_ref() + } + + pub fn is_move(&self) -> bool { + self.is_move + } + + pub fn captures(&self) -> &ClosureCaptures { + &self.captures + } + + pub fn captures_mut(&mut self) -> &mut ClosureCaptures { + &mut self.captures + } + + pub fn parameters(&self) -> &ClosureParameters { + &self.parameters + } + + pub fn parameters_mut(&mut self) -> &mut ClosureParameters { + &mut self.parameters + } + + pub fn statements(&self) -> Vec<&Statement> { + self.statements.iter().map(Box::as_ref).collect() + } + + pub fn statements_mut(&mut self) -> Vec<&mut Statement> { + self.statements.iter_mut().map(Box::as_mut).collect() + } + + pub fn expression(&self) -> Option<&Expression> { + if let Some(expression) = &self.expression { + Some(expression) + } else { + None + } + } + + pub fn expression_mut(&mut self) -> Option<&mut Expression> { + if let Some(expression) = &mut self.expression { + Some(expression) + } else { + None + } + } } #[derive(Debug)] @@ -662,7 +2129,21 @@ pub enum ClosureModifier { } #[derive(Debug, Default)] -pub struct ClosureCaptures(pub Vec); +pub struct ClosureCaptures(Vec>); + +impl ClosureCaptures { + pub fn new(captures: Vec>) -> Self { + Self(captures) + } + + pub fn captures(&self) -> Vec<&ClosureCapture> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn captures_mut(&mut self) -> Vec<&mut ClosureCapture> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} impl ClosureCaptures { pub fn is_empty(&self) -> bool { @@ -672,15 +2153,53 @@ impl ClosureCaptures { #[derive(Debug)] pub struct ClosureCapture { - pub borrow_count: usize, - pub is_mutable: bool, - pub identifier: Box, + borrow_count: usize, + is_mutable: bool, + identifier: Box, +} + +impl ClosureCapture { + pub fn new(borrow_count: usize, is_mutable: bool, identifier: Box) -> Self { + Self { + borrow_count, + is_mutable, + identifier, + } + } + + pub fn borrow_count(&self) -> usize { + self.borrow_count + } + + pub fn is_mutable(&self) -> bool { + self.is_mutable + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } } #[derive(Debug, Default)] -pub struct ClosureParameters(pub Vec); +pub struct ClosureParameters(Vec>); impl ClosureParameters { + pub fn new(parameters: Vec>) -> Self { + Self(parameters) + } + + pub fn parameters(&self) -> Vec<&ClosureParameter> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn parameters_mut(&mut self) -> Vec<&mut ClosureParameter> { + self.0.iter_mut().map(Box::as_mut).collect() + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } @@ -688,18 +2207,90 @@ impl ClosureParameters { #[derive(Debug)] pub struct ClosureParameter { - pub identifier: Identifier, - pub type_use: Option, + identifier: Box, + type_use: Option>, +} + +impl ClosureParameter { + pub fn new(identifier: Box, type_use: Option>) -> Self { + Self { + identifier, + type_use, + } + } + + pub fn identifier(&self) -> &Identifier { + &self.identifier + } + + pub fn identifier_mut(&mut self) -> &mut Identifier { + &mut self.identifier + } + + pub fn type_use(&self) -> Option<&TypeUse> { + if let Some(type_use) = &self.type_use { + Some(type_use) + } else { + None + } + } + + pub fn type_use_mut(&mut self) -> Option<&mut TypeUse> { + if let Some(type_use) = &mut self.type_use { + Some(type_use.as_mut()) + } else { + None + } + } } #[derive(Debug)] pub struct ObjectAccess { - pub receiver: Box, - pub navigations: ObjectNavigations, + receiver: Box, + navigations: Box, +} + +impl ObjectAccess { + pub fn new(receiver: Box, navigations: Box) -> Self { + Self { + receiver, + navigations, + } + } + + pub fn receiver(&self) -> &Expression { + &self.receiver + } + + pub fn receiver_mut(&mut self) -> &mut Expression { + &mut self.receiver + } + + pub fn navigations(&self) -> &ObjectNavigations { + &self.navigations + } + + pub fn navigations_mut(&mut self) -> &mut ObjectNavigations { + &mut self.navigations + } } #[derive(Debug)] -pub struct ObjectNavigations(pub Vec); +pub struct ObjectNavigations(Vec>); + +impl ObjectNavigations { + pub fn new(navigations: Vec>) -> Self { + Self(navigations) + } + + pub fn navigations(&self) -> Vec<&ObjectNavigation> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn navigations_mut(&mut self) -> Vec<&mut ObjectNavigation> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} #[derive(Debug)] pub enum ObjectNavigation { @@ -714,13 +2305,27 @@ pub enum Literal { Double(f64), USize(usize), String(String), - DString(DString), - BacktickString(DString), + DString(Box), + BacktickString(Box), Boolean(bool), } #[derive(Debug)] -pub struct DString(pub Vec); +pub struct DString(Vec>); + +impl DString { + pub fn new(parts: Vec>) -> Self { + Self(parts) + } + + pub fn parts(&self) -> Vec<&DStringPart> { + self.0.iter().map(Box::as_ref).collect() + } + + pub fn parts_mut(&mut self) -> Vec<&mut DStringPart> { + self.0.iter_mut().map(Box::as_mut).collect() + } +} #[derive(Debug)] pub enum DStringPart { diff --git a/src/ast/pretty_print.rs b/src/ast/pretty_print.rs index c33b627..d2d756f 100644 --- a/src/ast/pretty_print.rs +++ b/src/ast/pretty_print.rs @@ -1,6 +1,7 @@ use crate::ast::*; use crate::util::indent_writer::IndentWriter; use std::fmt::Debug; +use crate::ast::unparse::Unparse; pub trait PrettyPrint { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()>; @@ -20,24 +21,7 @@ impl PrettyPrint for Operator { impl PrettyPrint for BinaryOperator { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("BinaryOperator(")?; - use BinaryOperator::*; - match self { - Or => writer.write("||"), - And => writer.write("&&"), - EqualTo => writer.write("=="), - NotEqualTo => writer.write("!="), - Greater => writer.write(">"), - Less => writer.write("<"), - GreaterEqual => writer.write(">="), - LessEqual => writer.write("<="), - Add => writer.write("+"), - Subtract => writer.write("-"), - Multiply => writer.write("*"), - Divide => writer.write("/"), - Modulo => writer.write("%"), - LeftShift => writer.write("<<"), - RightShift => writer.write(">>"), - }?; + self.unparse(writer)?; writer.writeln(")")?; Ok(()) } @@ -46,15 +30,7 @@ impl PrettyPrint for BinaryOperator { impl PrettyPrint for PrefixUnaryOperator { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("PrefixUnaryOperator(")?; - use PrefixUnaryOperator::*; - match self { - Spread => writer.write("..."), - BorrowMut => writer.write("&mut"), - Borrow => writer.write("&"), - Mut => writer.write("mut"), - Not => writer.write("!"), - Negative => writer.write("-"), - }?; + self.unparse(writer)?; writer.writeln(")")?; Ok(()) } @@ -63,11 +39,7 @@ impl PrettyPrint for PrefixUnaryOperator { impl PrettyPrint for SuffixUnaryOperator { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write_indented("SuffixUnaryOperator(")?; - use SuffixUnaryOperator::*; - match self { - PlusPlus => writer.write("++"), - MinusMinus => writer.write("--"), - }?; + self.unparse(writer)?; writer.write(")")?; Ok(()) } @@ -95,20 +67,26 @@ impl PrettyPrint for TypeUse { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { use TypeUse::*; match self { - Void => { - writer.writeln_indented("TypeUse(Void)")?; + Primitive(primitive_type_use) => { + writer.writeln_indented("PrimitiveTypeUse")?; + writer.increase_indent(); + primitive_type_use.pretty_print(writer)?; + writer.decrease_indent() } InterfaceOrClass(t) => { + writer.writeln_indented("InterfaceOrClassTypeUse")?; writer.increase_indent(); t.pretty_print(writer)?; writer.decrease_indent(); } Tuple(t) => { + writer.writeln_indented("TupleTypeUse")?; writer.increase_indent(); t.pretty_print(writer)?; writer.decrease_indent(); } Function(t) => { + writer.writeln_indented("FunctionTypeUse")?; writer.increase_indent(); t.pretty_print(writer)?; writer.decrease_indent(); @@ -118,6 +96,33 @@ impl PrettyPrint for TypeUse { } } +impl PrettyPrint for PrimitiveTypeUse { + fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + use PrimitiveTypeUse::*; + match self { + Byte => writer.writeln_indented("Byte"), + Short => writer.writeln_indented("Short"), + Char => writer.writeln_indented("Char"), + Int => writer.writeln_indented("Int"), + Long => writer.writeln_indented("Long"), + Double => writer.writeln_indented("Double"), + Bool => writer.writeln_indented("Bool"), + String => writer.writeln_indented("String"), + Array(generics) => { + writer.writeln_indented("Array")?; + if let Some(generics) = generics { + writer.increase_indent(); + generics.pretty_print(writer)?; + writer.decrease_indent(); + } + Ok(()) + } + Any => writer.writeln_indented("Any"), + Void => writer.writeln_indented("Void"), + } + } +} + impl PrettyPrint for InterfaceOrClassTypeUse { fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented(&format!( @@ -606,12 +611,12 @@ impl PrettyPrint for UseStatementLast { writer.writeln_indented("UseStatementLast")?; writer.increase_indent(); match self { - UseStatementLast::Identifier(i) => i.borrow().pretty_print(writer)?, + UseStatementLast::Identifier(i) => i.pretty_print(writer)?, UseStatementLast::Identifiers(is) => { for i in is { - i.borrow().pretty_print(writer)?; + i.pretty_print(writer)?; } - }, + } UseStatementLast::Star => { writer.writeln_indented("Star")?; } @@ -785,7 +790,7 @@ impl PrettyPrint for Expression { UnarySuffix(e) => e.pretty_print(writer), Call(e) => e.pretty_print(writer), ObjectAccess(o) => o.pretty_print(writer), - Literal(literial) => literial.pretty_print(writer), + Literal(literal) => literal.pretty_print(writer), FullyQualifiedName(fqn) => fqn.pretty_print(writer), Closure(closure) => closure.pretty_print(writer), } diff --git a/src/ast/unparse.rs b/src/ast/unparse.rs index 404d837..e41738e 100644 --- a/src/ast/unparse.rs +++ b/src/ast/unparse.rs @@ -5,8 +5,8 @@ macro_rules! to_unparse_vec { ( $nodes:expr ) => { $nodes .iter() - .map(|node| node as &dyn Unparse) - .collect::>() + .map(|node| *node as &dyn Unparse) + .collect::>() }; } @@ -112,6 +112,7 @@ impl Unparse for PrefixUnaryOperator { Spread => writer.write("..."), BorrowMut => writer.write("&mut"), Borrow => writer.write("&"), + Star => writer.write("*"), Mut => writer.write("mut"), Not => writer.write("!"), Negative => writer.write("-"), @@ -125,6 +126,8 @@ impl Unparse for SuffixUnaryOperator { match self { PlusPlus => writer.write("++"), MinusMinus => writer.write("--"), + Call => writer.write("()"), + Index => writer.write("[]"), } } } @@ -143,7 +146,7 @@ impl ListUnparse for FullyQualifiedName { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.identifiers) + to_unparse_vec!(self.identifiers()) } } @@ -165,56 +168,56 @@ impl Unparse for TypeUse { impl Unparse for InterfaceOrClassTypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - for _ in 0..self.borrow_count { + for _ in 0..self.borrow_count() { writer.write("&")?; } - if self.is_mutable { + if self.is_mutable() { writer.write("mut")?; } - if self.borrow_count > 0 || self.is_mutable { + if self.borrow_count() > 0 || self.is_mutable() { writer.write(" ")?; } - self.fqn.unparse(writer)?; - self.generics.unparse(writer)?; + self.fqn().unparse(writer)?; + self.generics().unparse(writer)?; Ok(()) } } impl Unparse for TupleTypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - for _ in 0..self.borrow_count { + for _ in 0..self.borrow_count() { writer.write("&")?; } - if self.is_mutable { + if self.is_mutable() { writer.write("mut")?; } - if self.borrow_count > 0 || self.is_mutable { + if self.borrow_count() > 0 || self.is_mutable() { writer.write(" ")?; } - self.arguments.unparse(writer)?; + self.arguments().unparse(writer)?; Ok(()) } } impl Unparse for FunctionTypeUse { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - for _ in 0..self.borrow_count { + for _ in 0..self.borrow_count() { writer.write("&")?; } - if let Some(function_type_modifier) = &self.function_modifier { + if let Some(function_type_modifier) = self.function_modifier() { function_type_modifier.unparse(writer)?; } - if self.borrow_count > 0 || self.function_modifier.is_some() { + if self.borrow_count() > 0 || self.function_modifier().is_some() { writer.write(" ")?; } writer.write("fn ")?; - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - self.parameters.unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; + self.return_type().unparse(writer)?; Ok(()) } } @@ -235,7 +238,7 @@ impl ListUnparse for GenericArguments { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.arguments()) } } @@ -255,7 +258,7 @@ impl ListUnparse for GenericParameters { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.identifiers()) } } @@ -275,7 +278,7 @@ impl ListUnparse for TupleArguments { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.arguments()) } } @@ -291,7 +294,7 @@ impl ListUnparse for ImplementsList { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.type_uses()) } } @@ -325,15 +328,15 @@ impl ListUnparse for Parameters { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.parameters()) } } impl Unparse for Parameter { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - self.identifier.unparse(writer)?; + self.identifier().unparse(writer)?; writer.write(": ")?; - self.type_use.unparse(writer)?; + self.type_use().unparse(writer)?; Ok(()) } } @@ -343,10 +346,10 @@ impl Unparse for Parameter { impl Unparse for ReturnType { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.write("-> ")?; - self.declared_type.unparse(writer)?; - if !self.references.is_empty() { + self.declared_type().unparse(writer)?; + if !self.references().is_empty() { writer.write(" ")?; - self.references.unparse(writer)?; + self.references().unparse(writer)?; } Ok(()) } @@ -362,7 +365,7 @@ impl ListUnparse for References { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.identifiers()) } } @@ -370,20 +373,55 @@ impl ListUnparse for References { impl Unparse for CompilationUnit { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if let Some(namespace) = &self.namespace { + if let Some(namespace) = self.namespace() { writer.write("ns ")?; namespace.unparse(writer)?; writer.write(";\n\n")?; } - for use_statement in &self.use_statements { + for use_statement in self.use_statements() { use_statement.unparse(writer)?; writer.write(";\n")?; } - unparse_list(writer, "\n\n", &to_unparse_vec!(self.declarations))?; + unparse_list(writer, "\n\n", &to_unparse_vec!(self.declarations()))?; Ok(()) } } +impl Unparse for UseStatement { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + writer.write_indented("use ")?; + for (i, identifier) in self.identifiers().iter().enumerate() { + identifier.unparse(writer)?; + if i != self.identifiers().len() - 2 { + // 2 because of use + writer.write("::")?; + } + } + self.last().unparse(writer)?; + Ok(()) + } +} + +impl Unparse for UseStatementLast { + fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { + match self { + UseStatementLast::Star => writer.write("*"), + UseStatementLast::Identifiers(identifiers) => { + writer.write("{")?; + for (i, identifier) in identifiers.iter().enumerate() { + identifier.unparse(writer)?; + if i != identifiers.len() - 1 { + writer.write(", ")?; + } + } + writer.write("}")?; + Ok(()) + } + UseStatementLast::Identifier(i) => i.unparse(writer), + } + } +} + /* Declarations allowed in each level */ impl Unparse for ModuleLevelDeclaration { @@ -442,58 +480,58 @@ impl Unparse for ClassLevelDeclaration { impl Unparse for ModuleDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub mod ")?; } else { writer.write_indented("mod ")?; } - self.identifier.unparse(writer)?; - unparse_contained_declarations!(self.declarations, writer); + self.identifier().unparse(writer)?; + unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } impl Unparse for InterfaceDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub int ")?; } else { writer.write_indented("int ")?; } - self.identifier.unparse(writer)?; - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + self.identifier().unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - if !self.implements.is_empty() { - self.implements.unparse(writer)?; + if !self.implements().is_empty() { + self.implements().unparse(writer)?; writer.write(" ")?; } - unparse_contained_declarations!(self.declarations, writer); + unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } impl Unparse for ClassDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub class ")?; } else { writer.write_indented("class ")?; } - self.identifier.unparse(writer)?; - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + self.identifier().unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; } - if let Some(class_constructor) = &self.class_constructor { + if let Some(class_constructor) = self.class_constructor() { class_constructor.unparse(writer)?; } writer.write(" ")?; - if !self.implements.is_empty() { - self.implements.unparse(writer)?; + if !self.implements().is_empty() { + self.implements().unparse(writer)?; writer.write(" ")?; } - unparse_contained_declarations!(self.declarations, writer); + unparse_contained_declarations!(self.declarations(), writer); Ok(()) } } @@ -502,78 +540,78 @@ impl Unparse for ClassDeclaration { impl Unparse for FunctionDefinition { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub ")?; - if let Some(modifier) = &self.modifier { + if let Some(modifier) = self.modifier() { modifier.unparse(writer)?; writer.write(" fn ")?; } else { writer.write(" fn ")?; } - } else if let Some(modifier) = &self.modifier { + } else if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" fn ")?; } else { writer.write_indented("fn ")?; } - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - self.identifier.unparse(writer)?; - self.parameters.unparse(writer)?; + self.identifier().unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; + self.return_type().unparse(writer)?; writer.write(" ")?; - self.body.unparse(writer)?; + self.body().unparse(writer)?; Ok(()) } } impl Unparse for OperatorFunctionDefinition { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub ")?; - if let Some(modifier) = &self.modifier { + if let Some(modifier) = self.modifier() { modifier.unparse(writer)?; writer.write(" op ")?; } else { writer.write("op ")?; } - } else if let Some(modifier) = &self.modifier { + } else if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" op ")?; } else { writer.write_indented("op ")?; } - self.operator.unparse(writer)?; + self.operator().unparse(writer)?; writer.write(" ")?; - self.parameters.unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; + self.return_type().unparse(writer)?; writer.write(" ")?; - self.body.unparse(writer)?; + self.body().unparse(writer)?; Ok(()) } } impl Unparse for PlatformFunctionDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_public { + if self.is_public() { writer.write_indented("pub platform fn ")?; } else { writer.write_indented("platform fn ")?; } - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - self.identifier.unparse(writer)?; - self.parameters.unparse(writer)?; + self.identifier().unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; + self.return_type().unparse(writer)?; writer.write(";")?; Ok(()) } @@ -581,22 +619,22 @@ impl Unparse for PlatformFunctionDeclaration { impl Unparse for InterfaceFunctionDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if let Some(modifier) = &self.modifier { + if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" fn ")?; } else { writer.write_indented("fn ")?; } - if !self.generics.is_empty() { - self.parameters.unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - self.identifier.unparse(writer)?; - self.parameters.unparse(writer)?; + self.identifier().unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; - if let Some(body) = &self.body { + self.return_type().unparse(writer)?; + if let Some(body) = self.body() { writer.write(" ")?; body.unparse(writer)?; } @@ -606,23 +644,23 @@ impl Unparse for InterfaceFunctionDeclaration { impl Unparse for InterfaceOperatorFunctionDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if let Some(modifier) = &self.modifier { + if let Some(modifier) = self.modifier() { writer.write_indented("")?; modifier.unparse(writer)?; writer.write(" op ")?; } else { writer.write_indented("op ")?; } - if !self.generics.is_empty() { - self.generics.unparse(writer)?; + if !self.generics().is_empty() { + self.generics().unparse(writer)?; writer.write(" ")?; } - self.operator.unparse(writer)?; + self.operator().unparse(writer)?; writer.write(" ")?; - self.parameters.unparse(writer)?; + self.parameters().unparse(writer)?; writer.write(" ")?; - self.return_type.unparse(writer)?; - if let Some(body) = &self.body { + self.return_type().unparse(writer)?; + if let Some(body) = self.body() { writer.write(" ")?; body.unparse(writer)?; } @@ -686,7 +724,7 @@ impl ListUnparse for ClassConstructor { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.parameters()) } } @@ -702,66 +740,31 @@ impl Unparse for ClassConstructorParameter { impl Unparse for PropertyDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_mutable { + if self.is_mutable() { writer.write("mut ")?; } - self.identifier.unparse(writer)?; + self.identifier().unparse(writer)?; writer.write(": ")?; - self.declared_type.unparse(writer)?; + self.declared_type().unparse(writer)?; Ok(()) } } impl Unparse for FieldDeclaration { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - if self.is_mutable { + if self.is_mutable() { writer.write("mut ")?; } writer.write("fld ")?; - self.identifier.unparse(writer)?; + self.identifier().unparse(writer)?; writer.write(": ")?; - self.declared_type.unparse(writer)?; + self.declared_type().unparse(writer)?; Ok(()) } } /* Statements */ -impl Unparse for UseStatement { - fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - writer.write_indented("use ")?; - for (i, identifier) in self.identifiers.iter().enumerate() { - identifier.unparse(writer)?; - if i != self.identifiers.len() - 2 { - // 2 because of use - writer.write("::")?; - } - } - self.last.unparse(writer)?; - Ok(()) - } -} - -impl Unparse for UseStatementLast { - fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { - match self { - UseStatementLast::Star => writer.write("*"), - UseStatementLast::Identifiers(identifiers) => { - writer.write("{")?; - for (i, identifier) in identifiers.iter().enumerate() { - identifier.borrow().unparse(writer)?; - if i != identifiers.len() - 1 { - writer.write(", ")?; - } - } - writer.write("}")?; - Ok(()) - } - UseStatementLast::Identifier(i) => i.borrow().unparse(writer), - } - } -} - impl Unparse for BlockStatement { fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> { writer.writeln_indented("{")?; @@ -1024,7 +1027,7 @@ impl ListUnparse for CallArguments { } fn inner(&self) -> Vec<&dyn Unparse> { - to_unparse_vec!(self.0) + to_unparse_vec!(self.arguments()) } } diff --git a/src/lib.rs b/src/lib.rs index eb4b5ed..e34be93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,7 @@ #![feature(new_range_api)] #![allow(warnings)] +extern crate core; + pub mod ast; pub mod diagnostic; pub mod module; diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 4661e3d..5af558a 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -120,6 +120,7 @@ Star = { "*" } LeftShift = { "<<" } RightShift = { ">>" } Index = { "[]" } +BorrowMut = { Borrow ~ Mut } Operator = { Or @@ -135,16 +136,19 @@ Operator = { | Multiply | Divide | Modulo + | LeftShift + | RightShift + // unary prefix + | Spread + | BorrowMut + | Borrow + | Star | Not | Negative + // unary suffix | PlusPlus | MinusMinus | CallOp - | Spread - | Borrow - | Star - | LeftShift - | RightShift | Index } @@ -457,10 +461,10 @@ InterfaceDefaultOperatorFunction = { Def ~ FunctionModifier? ~ Op + ~ GenericParameters? ~ Operator ~ Parameters ~ ReturnType - ~ RefList? ~ FunctionBody } @@ -698,10 +702,6 @@ PrefixExpression = { ~ SuffixExpression } -BorrowMut = { - Borrow ~ Mut -} - SuffixExpression = { PrimaryExpression ~ (