try out pomelo parser

This commit is contained in:
janis 2025-09-30 17:29:38 +02:00
parent 357590ec07
commit 816aebda01
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
2 changed files with 104 additions and 5 deletions

View file

@ -12,3 +12,6 @@ itertools = { workspace = true }
internment = "0.8.6"
lexer = { path = "../lexer", version = "0.1.0" }
logos = "0.15"
pomelo = "0.2"

View file

@ -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<Index>,
expr: Option<Index>,
@ -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<ParameterList>,
body: Index,
}
#[derive(Debug)]
struct Parameter {
name: String,
param_type: Type,
}
#[derive(Debug)]
struct ParameterList {
parameters: Vec<Index>,
}
#[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)]