diff --git a/dm_std_lib/std/core/string.dm b/dm_std_lib/std/core/string.dm index c00552d..9aa2a4f 100644 --- a/dm_std_lib/std/core/string.dm +++ b/dm_std_lib/std/core/string.dm @@ -4,5 +4,4 @@ pub int String { bytes: Array } -#[internal] impl StringImpl(bytes) : String diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 47d810d..257df08 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -24,7 +24,8 @@ pub enum Declaration { identifier: Identifier, is_extern: bool, is_public: bool, - type_declaration: TypeDeclaration + type_declaration: TypeDeclaration, + impl_ctor: Option }, Module { identifier: Identifier, @@ -36,8 +37,10 @@ pub enum Declaration { identifier: Identifier, is_extern: bool, is_public: bool, - statement: Statement - } + statement: Statement + }, + Prop(Prop), + Field(Field) } #[derive(Debug)] @@ -89,6 +92,30 @@ pub struct Type { generics: Vec } +#[derive(Debug)] +pub struct ImplCtor { + args: Vec +} + +#[derive(Debug)] +pub struct ImplCtorArg { + is_field: bool, + identifier: Identifier, + r#type: Option +} + +#[derive(Debug)] +pub struct Prop { + identifier: Identifier, + r#type: Type +} + +#[derive(Debug)] +pub struct Field { + identifier: Identifier, + r#type: Type +} + #[derive(Debug)] pub enum Statement { BlockStatement { @@ -98,6 +125,59 @@ pub enum Statement { AssignmentStatement } +fn build_field(field_pair: Pair) -> Declaration { + todo!() +} + +fn build_prop(prop_pair: Pair) -> Declaration { + todo!() +} + +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; + + 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) + } + } + + ImplCtorArg { + is_field, + identifier: identifier.unwrap(), + r#type + } +} + +fn build_impl_ctor(impl_ctor_pair: Pair) -> ImplCtor { + let impl_ctor_args_pair = impl_ctor_pair.into_inner().next().unwrap(); + let mut args: Vec = vec![]; + + for pair in impl_ctor_args_pair.into_inner() { + match pair.as_rule() { + Rule::impl_ctor_arg => { + args.push(build_impl_ctor_arg(pair)); + } + _ => panic!("Unexpected rule: {}", pair) + } + } + + ImplCtor { + args + } +} + fn build_generic_argument(generic_argument_pair: Pair) -> GenericArgument { let fqn_pair = generic_argument_pair.into_inner().next().unwrap(); GenericArgument { @@ -163,14 +243,14 @@ fn build_generic_parameters_declaration(generic_parameters_declaration_pair: Pai 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)); + extensions.push(build_type(pair)); } _ => panic!("Expected only type rule. Found: {}", pair) - } + } } extensions @@ -181,7 +261,7 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair) let mut generic_parameters: Option> = None; let mut extends: Option> = None; let mut declarations: Vec = vec![]; - + for pair in interface_pair.into_inner() { match pair.as_rule() { Rule::identifier => { @@ -191,7 +271,7 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair) generic_parameters = Some(build_generic_parameters_declaration(pair)); } Rule::extends_list => { - extends = Some(build_extends_list(pair)); + extends = Some(build_extends_list(pair)); } Rule::declaration => { declarations.push(build_declaration(pair)); @@ -203,20 +283,57 @@ fn build_interface(is_extern: bool, is_public: bool, interface_pair: Pair) } } - Declaration::Interface { - identifier: identifier.unwrap(), - is_extern, - is_public, + Declaration::Interface { + identifier: identifier.unwrap(), + is_extern, + is_public, type_declaration: TypeDeclaration::new( generic_parameters.unwrap_or(vec![]), - extends.unwrap_or(vec![]), + extends.unwrap_or(vec![]), declarations ) } } -fn build_implementation(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { - todo!() +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 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) + } + } + + Declaration::Implementation { + identifier: identifier.unwrap(), + is_extern, + is_public, + type_declaration: TypeDeclaration::new( + generic_parameters.unwrap_or(vec![]), + extends.unwrap_or(vec![]), + declarations + ), + impl_ctor + } } fn build_module(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { @@ -240,7 +357,7 @@ fn build_declaration(declaration_pair: Pair) -> Declaration { Rule::r#pub => { is_public = true; } - Rule::interface => { + Rule::interface => { declaration = Some(build_interface(is_extern, is_public, pair)); }, Rule::implementation => { @@ -252,6 +369,12 @@ fn build_declaration(declaration_pair: Pair) -> Declaration { 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) } } @@ -265,8 +388,8 @@ fn build_identifier(pair: Pair) -> Identifier { name: String::from(pair.as_str()) } } - _ => panic!("Expected an identifier.") - } + _ => panic!("Expected an identifier.") + } } fn build_fqn(fqn_pair: Pair) -> Fqn { @@ -291,7 +414,7 @@ fn build_compilation_unit(pair: Pair)-> CompilationUnit { for pair in pair.into_inner() { match pair.as_rule() { Rule::namespace => { - let fqn_pair = pair.into_inner().next().unwrap(); + let fqn_pair = pair.into_inner().next().unwrap(); namespace = Some(build_fqn(fqn_pair)); } Rule::declaration => { @@ -299,7 +422,7 @@ fn build_compilation_unit(pair: Pair)-> CompilationUnit { } Rule::EOI => {} // ignore _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) - } + } } CompilationUnit { diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index f2061ac..342a139 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -6,22 +6,22 @@ identifier = @{ identifier_start_char ~ identifier_char* } identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" } identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } -declaration = { extern? ~ pub? ~ ( interface | implementation | module | function ) } +declaration = { extern? ~ pub? ~ ( interface | implementation | module | function | prop | field ) } extern = { "extern" } pub = { "pub" } interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } extends_list = { ":" ~ type ~ ( "+" ~ type )* } -implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? } +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 )? } fld = { "fld" } module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" } -property = { identifier ~ ":" ~ type } +property = { identifier ~ ( ":" ~ type )? } function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } function_equals_body = { "=" ~ expression } @@ -37,6 +37,9 @@ generic_argument = { fqn } args_list = { arg ~ ( "," ~ arg )* } arg = { identifier ~ ( ":" ~ "..."? ~ type )? } +prop = { identifier ~ ":" ~ type } +field = { fld ~ identifier ~ ":" ~ type } + statement = { call_stmt } call_stmt = { call_expr }