try out pomelo parser
This commit is contained in:
parent
357590ec07
commit
816aebda01
|
@ -11,4 +11,7 @@ thiserror = { workspace = true }
|
|||
itertools = { workspace = true }
|
||||
internment = "0.8.6"
|
||||
|
||||
lexer = { path = "../lexer", version = "0.1.0" }
|
||||
lexer = { path = "../lexer", version = "0.1.0" }
|
||||
|
||||
logos = "0.15"
|
||||
pomelo = "0.2"
|
|
@ -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)]
|
||||
|
|
Loading…
Reference in a new issue