From 18551af61a6a55338816217d22681028bcbf1dc9 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 31 Jan 2025 14:40:46 -0600 Subject: [PATCH] More work upon AST building. --- src/ast/mod.rs | 197 ++++++++++++++++++++++++++++++++++++++++- src/bin/dvm/main.rs | 2 +- src/parser/deimos.pest | 18 ++-- 3 files changed, 205 insertions(+), 12 deletions(-) diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 4112e12..f573a5c 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -16,18 +16,26 @@ pub struct Fqn { pub enum Declaration { Interface { identifier: Identifier, + is_extern: bool, + is_public: bool, type_declaration: TypeDeclaration, }, Implementation { identifier: Identifier, + is_extern: bool, + is_public: bool, type_declaration: TypeDeclaration }, Module { identifier: Identifier, + is_extern: bool, + is_public: bool, declarations: Vec, }, Function { identifier: Identifier, + is_extern: bool, + is_public: bool, statement: Statement } } @@ -35,10 +43,20 @@ pub enum Declaration { #[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 { + TypeDeclaration { + generics, + extends, + declarations + } + } +} + #[derive(Debug)] pub struct Identifier { name: String @@ -53,13 +71,24 @@ pub struct GenericParameter { #[derive(Debug)] pub enum GenericBound { Extends { - identifier: Identifier + fqn: Fqn }, Super { - identifier: Identifier + fqn: Fqn } } +#[derive(Debug)] +pub struct GenericArgument { + fqn: Fqn +} + +#[derive(Debug)] +pub struct Type { + fqn: Fqn, + generics: Vec +} + #[derive(Debug)] pub enum Statement { BlockStatement { @@ -69,6 +98,166 @@ pub enum Statement { AssignmentStatement } +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) + } +} + +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) + } + } + generic_arguments +} + +fn build_generic_parameter(generic_parameter_pair: Pair) -> GenericParameter { + let identifier_pair = generic_parameter_pair.into_inner().next().unwrap(); + GenericParameter { + identifier: build_identifier(identifier_pair), + bound: None, + } +} + +fn build_type(type_pair: Pair) -> Type { + let mut fqn: Option = None; + let mut generic_arguments_declaration: Option> = None; + + for pair in type_pair.into_inner() { + match pair.as_rule() { + Rule::fqn => { + fqn = Some(build_fqn(pair)); + } + Rule::generic_arguments_declaration => { + generic_arguments_declaration = Some(build_generic_arguments_declaration(pair)); + } + _ => panic!("Expected only fqn or generic_arguments_declaration rules. Found: {}", pair) + } + } + + Type { + fqn: fqn.unwrap(), + generics: generic_arguments_declaration.unwrap_or(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) + } + } + parameters +} + +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)); + } + _ => panic!("Expected only type rule. Found: {}", pair) + } + } + + extensions +} + +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 declarations: Vec = vec![]; + + for pair in interface_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::extends_list => { + extends = Some(build_extends_list(pair)); + } + Rule::declaration => { + declarations.push(build_declaration(pair)); + }, + _ => panic!( + "Expected only identifier, generics_declaration, extends_list, or declaration rules. Found: {}", + pair + ) + } + } + + Declaration::Interface { + identifier: identifier.unwrap(), + is_extern, + is_public, + type_declaration: TypeDeclaration::new( + generic_parameters.unwrap_or(vec![]), + extends.unwrap_or(vec![]), + declarations + ) + } +} + +fn build_implementation(is_extern: bool,is_public: bool, pair: Pair) -> Declaration { + todo!() +} + +fn build_module(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { + todo!() +} + +fn build_function(is_extern: bool, is_public: bool, pair: Pair) -> Declaration { + todo!() +} + +fn build_declaration(declaration_pair: Pair) -> Declaration { + let mut is_extern = false; + let mut is_public = false; + let mut declaration: Option = None; + + for pair in declaration_pair.into_inner() { + 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)); + }, + _ => panic!("Expected only interface, implementation, module, or function rules; found {}", pair) + } + } + declaration.expect("Expected declaration.") +} + fn build_identifier(pair: Pair) -> Identifier { match pair.as_rule() { Rule::identifier => { @@ -106,7 +295,7 @@ fn build_compilation_unit(pair: Pair)-> CompilationUnit { namespace = Some(build_fqn(fqn_pair)); } Rule::declaration => { - todo!(); + declarations.push(build_declaration(pair)); } Rule::EOI => {} // ignore _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) diff --git a/src/bin/dvm/main.rs b/src/bin/dvm/main.rs index ddd37e3..93ba7f7 100644 --- a/src/bin/dvm/main.rs +++ b/src/bin/dvm/main.rs @@ -15,7 +15,7 @@ fn main() { // - call the main fn // fn main() { println "Hello, World!" } - let compilation_unit = build_ast("ns hello::test::bye"); + let compilation_unit = build_ast("ns hello::test::bye\npub int Test : Testing {}"); println!("{:?}", compilation_unit); // std/core/array lib diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 84f81df..f2061ac 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -6,14 +6,14 @@ identifier = @{ identifier_start_char ~ identifier_char* } identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" } identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } -declaration = { decl? ~ pub? ~ ( interface | implementation | module | function ) } -decl = { "decl" } +declaration = { extern? ~ pub? ~ ( interface | implementation | module | function ) } +extern = { "extern" } pub = { "pub" } -interface = { "int" ~ identifier ~ generics_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } +interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } extends_list = { ":" ~ type ~ ( "+" ~ type )* } -implementation = { "impl" ~ identifier ~ generics_declaration? ~ impl_ctor? ~ extends_list? } +implementation = { "impl" ~ identifier ~ generic_parameters_declaration? ~ impl_ctor? ~ extends_list? } impl_ctor = { "(" ~ impl_ctor_args? ~ ")" } impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* } impl_ctor_arg = { fld? ~ identifier ~ ":" ~ type } @@ -23,12 +23,16 @@ module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" } property = { identifier ~ ":" ~ type } -function = { "fn" ~ generics_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } +function = { "fn" ~ generic_parameters_declaration? ~ identifier ~ "(" ~ args_list? ~ ")" ~ ( ":" ~ type )? ~ ( function_body | function_equals_body ) } function_equals_body = { "=" ~ expression } function_body = { "{" ~ statement* ~ "}" } -type = { identifier ~ generics_declaration? } -generics_declaration = { "<" ~ identifier ~ ( "," ~ identifier )* ~ ">"} +type = { 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 )? }