From 816aebda014fecaf68a99d52ed93c409de703429 Mon Sep 17 00:00:00 2001 From: janis Date: Tue, 30 Sep 2025 17:29:38 +0200 Subject: [PATCH] try out pomelo parser --- crates/parser/Cargo.toml | 5 +- crates/parser/src/lib.rs | 104 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/crates/parser/Cargo.toml b/crates/parser/Cargo.toml index 4db7793..c93d5c5 100644 --- a/crates/parser/Cargo.toml +++ b/crates/parser/Cargo.toml @@ -11,4 +11,7 @@ thiserror = { workspace = true } itertools = { workspace = true } internment = "0.8.6" -lexer = { path = "../lexer", version = "0.1.0" } \ No newline at end of file +lexer = { path = "../lexer", version = "0.1.0" } + +logos = "0.15" +pomelo = "0.2" \ No newline at end of file diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index e6ef52b..885462d 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -3,6 +3,8 @@ use lexer::{ Consuming, ReborrowingConsumingIterator, ReborrowingIterator, ReborrowingPeekingIterator, Token, TokenConsumer, TokenItem, TokenItemIterator, }; +use logos::Logos; +use pomelo::pomelo; use thiserror::Error; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -87,10 +89,7 @@ pub enum AstNode { name: String, param_type: Type, }, - FunctionDecl { - proto: Index, - body: Index, - }, + FunctionDecl(FunctionDecl), Block { statements: Vec, expr: Option, @@ -274,6 +273,103 @@ impl Ast { pub fn new() -> Self { Self::default() } + pub fn push(&mut self, node: AstNode) -> Index { + let index = self.nodes.len() as u32; + self.nodes.push(node); + Index(index) + } +} + +#[derive(Debug)] +struct FunctionDecl { + name: String, + return_type: Type, + parameter_list: Option, + body: Index, +} + +#[derive(Debug)] +struct Parameter { + name: String, + param_type: Type, +} + +#[derive(Debug)] +struct ParameterList { + parameters: Vec, +} + +#[derive(Debug)] +struct ExtraToken<'a> { + lexeme: &'a str, + offset: u32, +} + +pomelo! { + %include { + use super::AstNode; + use super::{ + Parameter, Ast, ParameterList, FunctionDecl, Type, InnerType, + FloatType, ExtraToken, Index, + }; + }; + %extra_argument Ast; + %parser pub struct Parser<'a>{}; + %extra_token (&'a str, u32); + %type fn_decl FunctionDecl; + %type parameter Parameter; + %type parameter_list ParameterList; + %type typ Type; + %type return_type Type; + %type block Index; + + file ::= decl_list?; + decl_list ::= decl; + decl_list ::= decl_list decl; + + typ ::= Bool { internment::Intern::new(InnerType::Bool) }; + typ ::= I8 { internment::Intern::new(InnerType::Int { signed: true, bits: 8 }) }; + typ ::= I16 { internment::Intern::new(InnerType::Int { signed: true, bits: 16 }) }; + typ ::= I32 { internment::Intern::new(InnerType::Int { signed: true, bits: 32 }) }; + typ ::= I64 { internment::Intern::new(InnerType::Int { signed: true, bits: 64 }) }; + typ ::= U8 { internment::Intern::new(InnerType::Int { signed: false, bits: 8 }) }; + typ ::= U16 { internment::Intern::new(InnerType::Int { signed: false, bits: 16 }) }; + typ ::= U32 { internment::Intern::new(InnerType::Int { signed: false, bits: 32 }) }; + typ ::= U64 { internment::Intern::new(InnerType::Int { signed: false, bits: 64 }) }; + typ ::= F32 { internment::Intern::new(InnerType::Float { float_type: FloatType::F32 }) }; + typ ::= F64 { internment::Intern::new(InnerType::Float { float_type: FloatType::F64 }) }; + typ ::= Bang { internment::Intern::new(InnerType::Bottom) }; + typ ::= LParen RParen { internment::Intern::new(InnerType::Unit) }; + + return_type ::= Arrow typ(return_type) { return_type }; + block ::= LBrace RBrace { extra.push(AstNode::Block { statements: vec![], expr: None }) }; + parameter ::= Ident(name) Colon typ(param_type) { + Parameter { name: name.0.to_string(), param_type } + }; + parameter_list ::= parameter(p) { + let idx = extra.push(AstNode::Parameter { name: p.name, param_type: p.param_type }); + ParameterList { parameters: vec![idx] } + }; + parameter_list ::= parameter_list(pl) Comma parameter(p) { + let idx = extra.push(AstNode::Parameter { name: p.name, param_type: p.param_type }); + let mut parameters = pl.parameters; + parameters.push(idx); + ParameterList { parameters } + }; + parameter_list ::= parameter_list(pl) Comma { + pl + }; + + decl ::= fn_decl(f) { extra.nodes.push(AstNode::FunctionDecl(f)); }; + fn_decl ::= Fn Ident(name) LParen parameter_list?(parameters) RParen return_type(rtype) block(body) { + let name = name.0.to_string(); + FunctionDecl { + name, + return_type: rtype, + parameter_list: parameters, + body, + } + }; } #[cfg(test)]