From 040961ed675121eac7395bd3e2c9af2f19794bba Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Thu, 30 Jan 2025 18:36:35 -0600 Subject: [PATCH] Finally building an AST with Pest. --- .gitignore | 3 +- src/ast/mod.rs | 134 +++++++++++++++++++++++++++++++++++++++++ src/bin/dvm/main.rs | 4 ++ src/lib.rs | 2 + src/parser/deimos.pest | 2 +- 5 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 src/ast/mod.rs diff --git a/.gitignore b/.gitignore index 2a0038a..3d358ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target -.idea \ No newline at end of file +.idea +*.swp diff --git a/src/ast/mod.rs b/src/ast/mod.rs new file mode 100644 index 0000000..4112e12 --- /dev/null +++ b/src/ast/mod.rs @@ -0,0 +1,134 @@ +use pest::{iterators::{Pair, Pairs}, Parser}; +use crate::parser::{DeimosParser, Rule}; + +#[derive(Debug)] +pub struct CompilationUnit { + namespace: Option, + declarations: Vec, +} + +#[derive(Debug)] +pub struct Fqn { + identifiers: Vec +} + +#[derive(Debug)] +pub enum Declaration { + Interface { + identifier: Identifier, + type_declaration: TypeDeclaration, + }, + Implementation { + identifier: Identifier, + type_declaration: TypeDeclaration + }, + Module { + identifier: Identifier, + declarations: Vec, + }, + Function { + identifier: Identifier, + statement: Statement + } +} + +#[derive(Debug)] +pub struct TypeDeclaration { + generics: Vec, + extends: Vec, + declarations: Vec, +} + +#[derive(Debug)] +pub struct Identifier { + name: String +} + +#[derive(Debug)] +pub struct GenericParameter { + identifier: Identifier, + bound: Option +} + +#[derive(Debug)] +pub enum GenericBound { + Extends { + identifier: Identifier + }, + Super { + identifier: Identifier + } +} + +#[derive(Debug)] +pub enum Statement { + BlockStatement { + statements: Vec + }, + CallStatement, + AssignmentStatement +} + +fn build_identifier(pair: Pair) -> Identifier { + match pair.as_rule() { + Rule::identifier => { + Identifier { + name: String::from(pair.as_str()) + } + } + _ => panic!("Expected an identifier.") + } +} + +fn build_fqn(fqn_pair: Pair) -> Fqn { + let mut identifiers: Vec = vec![]; + for pair in fqn_pair.into_inner() { + match pair.as_rule() { + Rule::identifier => { + identifiers.push(build_identifier(pair)); + } + _ => panic!("Expected only identifiers.") + } + } + Fqn { + identifiers + } +} + +fn build_compilation_unit(pair: Pair)-> CompilationUnit { + let mut namespace: Option = None; + let mut declarations: Vec = vec![]; + + for pair in pair.into_inner() { + match pair.as_rule() { + Rule::namespace => { + let fqn_pair = pair.into_inner().next().unwrap(); + namespace = Some(build_fqn(fqn_pair)); + } + Rule::declaration => { + todo!(); + } + Rule::EOI => {} // ignore + _ => panic!("Expected only namespace, declaration, or EOI rules, found: {}", pair) + } + } + + CompilationUnit { + namespace, + declarations + } +} + +pub fn build_ast(src: &str) -> CompilationUnit { + let pair = DeimosParser::parse(Rule::compilation_unit, src) + .expect("Unsuccessful parse.") + .next() + .expect("Expcted compilation_unit."); + match pair.as_rule() { + Rule::compilation_unit => { + build_compilation_unit(pair) + }, + _ => panic!("Expected compilation_unit rule.") + } +} + diff --git a/src/bin/dvm/main.rs b/src/bin/dvm/main.rs index 3563426..ddd37e3 100644 --- a/src/bin/dvm/main.rs +++ b/src/bin/dvm/main.rs @@ -1,3 +1,4 @@ +use deimos::ast::build_ast; use deimos::vm::dm_type::DmType; use deimos::vm::lib::{DmConstant, DmLib}; use deimos::vm::object_type::{DmField, DmFn, DmImplementation, DmInterface, DmMethod}; @@ -13,6 +14,9 @@ fn main() { // - write a single lib with a main() // - call the main fn // fn main() { println "Hello, World!" } + + let compilation_unit = build_ast("ns hello::test::bye"); + println!("{:?}", compilation_unit); // std/core/array lib let mut array_lib = DmLib::new("std/core/array"); diff --git a/src/lib.rs b/src/lib.rs index 6661955..b77c95b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ +#![allow(warnings)] mod compiler; pub mod parser; mod util; pub mod vm; +pub mod ast; diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index a7de239..84f81df 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -58,4 +58,4 @@ string_char = { | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } -WHITESPACE = _{ " " | "\t" | "\n" | "\r" } \ No newline at end of file +WHITESPACE = _{ " " | "\t" | "\n" | "\r" }