diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 257df08..39c6626 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1,5 +1,5 @@ -use pest::{iterators::{Pair, Pairs}, Parser}; use crate::parser::{DeimosParser, Rule}; +use pest::{iterators::Pair, Parser}; #[derive(Debug)] pub struct CompilationUnit { @@ -9,7 +9,7 @@ pub struct CompilationUnit { #[derive(Debug)] pub struct Fqn { - identifiers: Vec + identifiers: Vec, } #[derive(Debug)] @@ -25,7 +25,7 @@ pub enum Declaration { is_extern: bool, is_public: bool, type_declaration: TypeDeclaration, - impl_ctor: Option + impl_ctor: Option, }, Module { identifier: Identifier, @@ -37,92 +37,98 @@ pub enum Declaration { identifier: Identifier, is_extern: bool, is_public: bool, - statement: Statement + parameters: Vec, + declared_type: Option, + statement: Statement, }, Prop(Prop), - Field(Field) + Field(Field), } #[derive(Debug)] pub struct TypeDeclaration { generics: Vec, - extends: Vec, + extends: Vec, declarations: Vec, } impl TypeDeclaration { - pub fn new(generics: Vec, extends: Vec, declarations: Vec) -> TypeDeclaration { + pub fn new( + generics: Vec, + extends: Vec, + declarations: Vec, + ) -> TypeDeclaration { TypeDeclaration { generics, extends, - declarations + declarations, } } } #[derive(Debug)] pub struct Identifier { - name: String + name: String, } #[derive(Debug)] pub struct GenericParameter { identifier: Identifier, - bound: Option + bound: Option, } #[derive(Debug)] pub enum GenericBound { - Extends { - fqn: Fqn - }, - Super { - fqn: Fqn - } + Extends { fqn: Fqn }, + Super { fqn: Fqn }, } #[derive(Debug)] pub struct GenericArgument { - fqn: Fqn + fqn: Fqn, } #[derive(Debug)] -pub struct Type { +pub struct TypeUse { fqn: Fqn, - generics: Vec + generics: Vec, } #[derive(Debug)] pub struct ImplCtor { - args: Vec + args: Vec, } #[derive(Debug)] pub struct ImplCtorArg { is_field: bool, identifier: Identifier, - r#type: Option + r#type: Option, } #[derive(Debug)] pub struct Prop { identifier: Identifier, - r#type: Type + r#type: TypeUse, } #[derive(Debug)] pub struct Field { identifier: Identifier, - r#type: Type + r#type: TypeUse, } #[derive(Debug)] pub enum Statement { - BlockStatement { - statements: Vec - }, + BlockStatement { statements: Vec }, CallStatement, - AssignmentStatement + AssignmentStatement, +} + +#[derive(Debug)] +pub struct Parameter { + identifier: Identifier, + declared_type: Option, } fn build_field(field_pair: Pair) -> Declaration { @@ -136,27 +142,27 @@ fn build_prop(prop_pair: Pair) -> Declaration { fn build_impl_ctor_arg(impl_ctor_arg_pair: Pair) -> ImplCtorArg { let mut is_field = false; let mut identifier: Option = None; - let mut r#type: Option = None; + let mut r#type: Option = None; for pair in impl_ctor_arg_pair.into_inner() { match pair.as_rule() { Rule::fld => { is_field = true; - }, + } Rule::identifier => { identifier = Some(build_identifier(pair)); - }, - Rule::r#type => { - r#type = Some(build_type(pair)); - }, - _ => panic!("Unexpected rule: {}", pair) + } + Rule::type_use => { + r#type = Some(build_type_use(pair)); + } + _ => panic!("Unexpected rule: {}", pair), } } ImplCtorArg { is_field, identifier: identifier.unwrap(), - r#type + r#type, } } @@ -169,30 +175,30 @@ fn build_impl_ctor(impl_ctor_pair: Pair) -> ImplCtor { Rule::impl_ctor_arg => { args.push(build_impl_ctor_arg(pair)); } - _ => panic!("Unexpected rule: {}", pair) + _ => panic!("Unexpected rule: {}", pair), } } - ImplCtor { - args - } + ImplCtor { args } } fn build_generic_argument(generic_argument_pair: Pair) -> GenericArgument { let fqn_pair = generic_argument_pair.into_inner().next().unwrap(); GenericArgument { - fqn: build_fqn(fqn_pair) + fqn: build_fqn(fqn_pair), } } -fn build_generic_arguments_declaration(generic_arguments_declaration_pair: Pair) -> Vec { +fn build_generic_arguments_declaration( + generic_arguments_declaration_pair: Pair, +) -> Vec { let mut generic_arguments: Vec = vec![]; for pair in generic_arguments_declaration_pair.into_inner() { match pair.as_rule() { Rule::generic_argument => { generic_arguments.push(build_generic_argument(pair)); } - _ => panic!("Expected only generic_argument rules. Found: {}", pair) + _ => panic!("Expected only generic_argument rules. Found: {}", pair), } } generic_arguments @@ -206,7 +212,7 @@ fn build_generic_parameter(generic_parameter_pair: Pair) -> GenericParamet } } -fn build_type(type_pair: Pair) -> Type { +fn build_type_use(type_pair: Pair) -> TypeUse { let mut fqn: Option = None; let mut generic_arguments_declaration: Option> = None; @@ -218,38 +224,43 @@ fn build_type(type_pair: Pair) -> Type { Rule::generic_arguments_declaration => { generic_arguments_declaration = Some(build_generic_arguments_declaration(pair)); } - _ => panic!("Expected only fqn or generic_arguments_declaration rules. Found: {}", pair) + _ => panic!( + "Expected only fqn or generic_arguments_declaration rules. Found: {}", + pair + ), } } - Type { + TypeUse { fqn: fqn.unwrap(), - generics: generic_arguments_declaration.unwrap_or(vec![]) + generics: generic_arguments_declaration.unwrap_or(vec![]), } } -fn build_generic_parameters_declaration(generic_parameters_declaration_pair: Pair) -> Vec { +fn build_generic_parameters_declaration( + generic_parameters_declaration_pair: Pair, +) -> Vec { let mut parameters: Vec = vec![]; for pair in generic_parameters_declaration_pair.into_inner() { match pair.as_rule() { Rule::generic_parameter => { parameters.push(build_generic_parameter(pair)); } - _ => panic!("Expected only generic_parameter rule. Found: {}", pair) + _ => panic!("Expected only generic_parameter rule. Found: {}", pair), } } parameters } -fn build_extends_list(extends_list_pair: Pair) -> Vec { - let mut extensions: Vec = vec![]; +fn build_extends_list(extends_list_pair: Pair) -> Vec { + let mut extensions: Vec = vec![]; for pair in extends_list_pair.into_inner() { match pair.as_rule() { - Rule::r#type => { - extensions.push(build_type(pair)); + Rule::type_use => { + extensions.push(build_type_use(pair)); } - _ => panic!("Expected only type rule. Found: {}", pair) + _ => panic!("Expected only type rule. Found: {}", pair), } } @@ -259,7 +270,7 @@ fn build_extends_list(extends_list_pair: Pair) -> Vec { fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair) -> Declaration { let mut identifier: Option = None; let mut generic_parameters: Option> = None; - let mut extends: Option> = None; + let mut extends: Option> = None; let mut declarations: Vec = vec![]; for pair in interface_pair.into_inner() { @@ -290,36 +301,40 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair) type_declaration: TypeDeclaration::new( generic_parameters.unwrap_or(vec![]), extends.unwrap_or(vec![]), - declarations - ) + declarations, + ), } } -fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: Pair) -> Declaration { +fn build_implementation( + is_extern: bool, + is_public: bool, + implementation_pair: Pair, +) -> Declaration { let mut identifier: Option = None; let mut generic_parameters: Option> = None; let mut impl_ctor: Option = None; - let mut extends: Option> = None; + let mut extends: Option> = None; let mut declarations: Vec = vec![]; for pair in implementation_pair.into_inner() { match pair.as_rule() { Rule::identifier => { identifier = Some(build_identifier(pair)); - }, + } Rule::generic_parameters_declaration => { generic_parameters = Some(build_generic_parameters_declaration(pair)); - }, + } Rule::impl_ctor => { impl_ctor = Some(build_impl_ctor(pair)); - }, + } Rule::extends_list => { extends = Some(build_extends_list(pair)); - }, + } Rule::declaration => { declarations.push(build_declaration(pair)); } - _ => panic!("Unexpected rule: {}", pair) + _ => panic!("Unexpected rule: {}", pair), } } @@ -330,9 +345,9 @@ fn build_implementation(is_extern: bool, is_public: bool, implementation_pair: P type_declaration: TypeDeclaration::new( generic_parameters.unwrap_or(vec![]), extends.unwrap_or(vec![]), - declarations + declarations, ), - impl_ctor + impl_ctor, } } @@ -340,10 +355,88 @@ fn build_module(is_extern: bool, is_public: bool, pair: Pair) -> Declarati todo!() } -fn build_function(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { +fn build_parameter(pair: Pair) -> Parameter { + let mut identifier: Option = None; + let mut declared_type: Option = None; + for pair in pair.into_inner() { + match pair.as_rule() { + Rule::identifier => { + identifier = Some(build_identifier(pair)); + } + Rule::type_use => { + declared_type = Some(build_type_use(pair)); + } + _ => unreachable!(), + } + } + Parameter { + identifier: identifier.unwrap(), + declared_type, + } +} + +fn build_parameters_list(pair: Pair) -> Vec { + let mut parameters: Vec = vec![]; + for pair in pair.into_inner() { + match pair.as_rule() { + Rule::parameter => { + parameters.push(build_parameter(pair)); + } + _ => unreachable!(), + } + } + parameters +} + +fn build_function_body(pair: Pair) -> Statement { todo!() } +fn build_function_equals_body(pair: Pair) -> Statement { + todo!() +} + +fn build_function(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { + let mut generic_parameters: Option> = None; + let mut identifier: Option = None; + let mut parameters: Option> = None; + let mut return_type: Option = None; + let mut statement: Option = None; + + for pair in pair.into_inner() { + match pair.as_rule() { + Rule::generic_parameters_declaration => { + generic_parameters = Some(build_generic_parameters_declaration(pair)); + } + Rule::identifier => { + identifier = Some(build_identifier(pair)); + } + Rule::parameters_list => { + parameters = Some(build_parameters_list(pair)); + } + Rule::type_use => { + return_type = Some(build_type_use(pair)); + } + Rule::function_body => { + statement = Some(build_function_body(pair)); + } + Rule::function_equals_body => { + statement = Some(build_function_equals_body(pair)); + } + _ => unreachable!(), + } + } + + Declaration::Function { + is_extern, + is_public, + identifier: identifier.unwrap(), + parameters: parameters.unwrap(), + declared_type: return_type, + statement: statement.unwrap(), + } +} + fn build_declaration(declaration_pair: Pair) -> Declaration { let mut is_extern = false; let mut is_public = false; @@ -353,29 +446,32 @@ fn build_declaration(declaration_pair: Pair) -> Declaration { match pair.as_rule() { Rule::r#extern => { is_extern = true; - }, + } Rule::r#pub => { is_public = true; } Rule::interface => { declaration = Some(build_interface(is_extern, is_public, pair)); - }, + } Rule::implementation => { declaration = Some(build_implementation(is_extern, is_public, pair)); - }, + } Rule::module => { declaration = Some(build_module(is_extern, is_public, pair)); - }, + } Rule::function => { declaration = Some(build_function(is_extern, is_public, pair)); - }, + } Rule::prop => { declaration = Some(build_prop(pair)); } Rule::field => { declaration = Some(build_field(pair)); } - _ => panic!("Expected only interface, implementation, module, or function rules; found {}", pair) + _ => panic!( + "Expected only interface, implementation, module, or function rules; found {}", + pair + ), } } declaration.expect("Expected declaration.") @@ -383,12 +479,10 @@ fn build_declaration(declaration_pair: Pair) -> Declaration { fn build_identifier(pair: Pair) -> Identifier { match pair.as_rule() { - Rule::identifier => { - Identifier { - name: String::from(pair.as_str()) - } - } - _ => panic!("Expected an identifier.") + Rule::identifier => Identifier { + name: String::from(pair.as_str()), + }, + _ => panic!("Expected an identifier."), } } @@ -399,15 +493,13 @@ fn build_fqn(fqn_pair: Pair) -> Fqn { Rule::identifier => { identifiers.push(build_identifier(pair)); } - _ => panic!("Expected only identifiers.") + _ => panic!("Expected only identifiers."), } } - Fqn { - identifiers - } + Fqn { identifiers } } -fn build_compilation_unit(pair: Pair)-> CompilationUnit { +fn build_compilation_unit(pair: Pair) -> CompilationUnit { let mut namespace: Option = None; let mut declarations: Vec = vec![]; @@ -421,13 +513,16 @@ fn build_compilation_unit(pair: Pair)-> CompilationUnit { declarations.push(build_declaration(pair)); } Rule::EOI => {} // ignore - _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) + _ => panic!( + "Expected only namespace, declaration, or EOI rules, found: {}", + pair + ), } } CompilationUnit { namespace, - declarations + declarations, } } @@ -437,10 +532,7 @@ pub fn build_ast(src: &str) -> CompilationUnit { .next() .expect("Expcted compilation_unit."); match pair.as_rule() { - Rule::compilation_unit => { - build_compilation_unit(pair) - }, - _ => panic!("Expected compilation_unit rule.") + Rule::compilation_unit => build_compilation_unit(pair), + _ => panic!("Expected compilation_unit rule."), } } - diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 342a139..14c00f6 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -11,34 +11,34 @@ extern = { "extern" } pub = { "pub" } interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } -extends_list = { ":" ~ type ~ ( "+" ~ type )* } +extends_list = { ":" ~ type_use ~ ( "+" ~ type_use )* } implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } impl_ctor = { "(" ~ impl_ctor_args? ~ ")" } impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* } -impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type )? } +impl_ctor_arg = { fld? ~ identifier ~ ( ":" ~ type_use )? } fld = { "fld" } module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" } -property = { identifier ~ ( ":" ~ type )? } +property = { identifier ~ ( ":" ~ type_use )? } -function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } +function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ parameters_list? ~ ")" ~ ( ":" ~ type_use )? ~ ( function_body | function_equals_body ) } function_equals_body = { "=" ~ expression } function_body = { "{" ~ statement* ~ "}" } -type = { fqn ~ generic_arguments_declaration? } +type_use = { fqn ~ generic_arguments_declaration? } generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" } generic_parameter = { identifier } generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" } generic_argument = { fqn } -args_list = { arg ~ ( "," ~ arg )* } -arg = { identifier ~ ( ":" ~ "..."? ~ type )? } +parameters_list = { parameter ~ ( "," ~ parameter )* } +parameter = { identifier ~ ( ":" ~ "..."? ~ type_use )? } -prop = { identifier ~ ":" ~ type } -field = { fld ~ identifier ~ ":" ~ type } +prop = { identifier ~ ":" ~ type_use } +field = { fld ~ identifier ~ ":" ~ type_use } statement = { call_stmt }