More work upon AST building.

This commit is contained in:
Jesse Brault 2025-01-31 14:40:46 -06:00
parent 173ec3ab38
commit 18551af61a
3 changed files with 205 additions and 12 deletions

View File

@ -16,18 +16,26 @@ pub struct Fqn {
pub enum Declaration { pub enum Declaration {
Interface { Interface {
identifier: Identifier, identifier: Identifier,
is_extern: bool,
is_public: bool,
type_declaration: TypeDeclaration, type_declaration: TypeDeclaration,
}, },
Implementation { Implementation {
identifier: Identifier, identifier: Identifier,
is_extern: bool,
is_public: bool,
type_declaration: TypeDeclaration type_declaration: TypeDeclaration
}, },
Module { Module {
identifier: Identifier, identifier: Identifier,
is_extern: bool,
is_public: bool,
declarations: Vec<Declaration>, declarations: Vec<Declaration>,
}, },
Function { Function {
identifier: Identifier, identifier: Identifier,
is_extern: bool,
is_public: bool,
statement: Statement statement: Statement
} }
} }
@ -35,10 +43,20 @@ pub enum Declaration {
#[derive(Debug)] #[derive(Debug)]
pub struct TypeDeclaration { pub struct TypeDeclaration {
generics: Vec<GenericParameter>, generics: Vec<GenericParameter>,
extends: Vec<Identifier>, extends: Vec<Type>,
declarations: Vec<Declaration>, declarations: Vec<Declaration>,
} }
impl TypeDeclaration {
pub fn new(generics: Vec<GenericParameter>, extends: Vec<Type>, declarations: Vec<Declaration>) -> TypeDeclaration {
TypeDeclaration {
generics,
extends,
declarations
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Identifier { pub struct Identifier {
name: String name: String
@ -53,13 +71,24 @@ pub struct GenericParameter {
#[derive(Debug)] #[derive(Debug)]
pub enum GenericBound { pub enum GenericBound {
Extends { Extends {
identifier: Identifier fqn: Fqn
}, },
Super { Super {
identifier: Identifier fqn: Fqn
} }
} }
#[derive(Debug)]
pub struct GenericArgument {
fqn: Fqn
}
#[derive(Debug)]
pub struct Type {
fqn: Fqn,
generics: Vec<GenericArgument>
}
#[derive(Debug)] #[derive(Debug)]
pub enum Statement { pub enum Statement {
BlockStatement { BlockStatement {
@ -69,6 +98,166 @@ pub enum Statement {
AssignmentStatement AssignmentStatement
} }
fn build_generic_argument(generic_argument_pair: Pair<Rule>) -> 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<Rule>) -> Vec<GenericArgument> {
let mut generic_arguments: Vec<GenericArgument> = 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<Rule>) -> 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<Rule>) -> Type {
let mut fqn: Option<Fqn> = None;
let mut generic_arguments_declaration: Option<Vec<GenericArgument>> = 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<Rule>) -> Vec<GenericParameter> {
let mut parameters: Vec<GenericParameter> = 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<Rule>) -> Vec<Type> {
let mut extensions: Vec<Type> = 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<Rule>) -> Declaration {
let mut identifier: Option<Identifier> = None;
let mut generic_parameters: Option<Vec<GenericParameter>> = None;
let mut extends: Option<Vec<Type>> = None;
let mut declarations: Vec<Declaration> = 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<Rule>) -> Declaration {
todo!()
}
fn build_module(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
todo!()
}
fn build_function(is_extern: bool, is_public: bool, pair: Pair<Rule>) -> Declaration {
todo!()
}
fn build_declaration(declaration_pair: Pair<Rule>) -> Declaration {
let mut is_extern = false;
let mut is_public = false;
let mut declaration: Option<Declaration> = 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<Rule>) -> Identifier { fn build_identifier(pair: Pair<Rule>) -> Identifier {
match pair.as_rule() { match pair.as_rule() {
Rule::identifier => { Rule::identifier => {
@ -106,7 +295,7 @@ fn build_compilation_unit(pair: Pair<Rule>)-> CompilationUnit {
namespace = Some(build_fqn(fqn_pair)); namespace = Some(build_fqn(fqn_pair));
} }
Rule::declaration => { Rule::declaration => {
todo!(); declarations.push(build_declaration(pair));
} }
Rule::EOI => {} // ignore Rule::EOI => {} // ignore
_ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair)

View File

@ -15,7 +15,7 @@ fn main() {
// - call the main fn // - call the main fn
// fn main() { println "Hello, World!" } // 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<T> : Testing<T> {}");
println!("{:?}", compilation_unit); println!("{:?}", compilation_unit);
// std/core/array lib // std/core/array lib

View File

@ -6,14 +6,14 @@ identifier = @{ identifier_start_char ~ identifier_char* }
identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" } identifier_start_char = { 'a'..'z' | 'A'..'Z' | "_" }
identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } identifier_char = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" }
declaration = { decl? ~ pub? ~ ( interface | implementation | module | function ) } declaration = { extern? ~ pub? ~ ( interface | implementation | module | function ) }
decl = { "decl" } extern = { "extern" }
pub = { "pub" } pub = { "pub" }
interface = { "int" ~ identifier ~ generics_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? } interface = { "int" ~ identifier ~ generic_parameters_declaration? ~ extends_list? ~ ( "{" ~ declaration* ~ "}" )? }
extends_list = { ":" ~ type ~ ( "+" ~ type )* } 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 = { "(" ~ impl_ctor_args? ~ ")" }
impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* } impl_ctor_args = { impl_ctor_arg ~ ( "," ~ impl_ctor_arg )* }
impl_ctor_arg = { fld? ~ identifier ~ ":" ~ type } impl_ctor_arg = { fld? ~ identifier ~ ":" ~ type }
@ -23,12 +23,16 @@ module = { "mod" ~ identifier ~ "{" ~ declaration* ~ "}" }
property = { identifier ~ ":" ~ type } 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_equals_body = { "=" ~ expression }
function_body = { "{" ~ statement* ~ "}" } function_body = { "{" ~ statement* ~ "}" }
type = { identifier ~ generics_declaration? } type = { fqn ~ generic_arguments_declaration? }
generics_declaration = { "<" ~ identifier ~ ( "," ~ identifier )* ~ ">"} generic_parameters_declaration = { "<" ~ generic_parameter ~ ( "," ~ generic_parameter )* ~ ">" }
generic_parameter = { identifier }
generic_arguments_declaration = { "<" ~ generic_argument ~ ( "," ~ generic_argument )* ~ ">" }
generic_argument = { fqn }
args_list = { arg ~ ( "," ~ arg )* } args_list = { arg ~ ( "," ~ arg )* }
arg = { identifier ~ ( ":" ~ "..."? ~ type )? } arg = { identifier ~ ( ":" ~ "..."? ~ type )? }