try out pomelo parser
This commit is contained in:
parent
357590ec07
commit
816aebda01
|
@ -11,4 +11,7 @@ thiserror = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
internment = "0.8.6"
|
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,
|
Consuming, ReborrowingConsumingIterator, ReborrowingIterator, ReborrowingPeekingIterator,
|
||||||
Token, TokenConsumer, TokenItem, TokenItemIterator,
|
Token, TokenConsumer, TokenItem, TokenItemIterator,
|
||||||
};
|
};
|
||||||
|
use logos::Logos;
|
||||||
|
use pomelo::pomelo;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
@ -87,10 +89,7 @@ pub enum AstNode {
|
||||||
name: String,
|
name: String,
|
||||||
param_type: Type,
|
param_type: Type,
|
||||||
},
|
},
|
||||||
FunctionDecl {
|
FunctionDecl(FunctionDecl),
|
||||||
proto: Index,
|
|
||||||
body: Index,
|
|
||||||
},
|
|
||||||
Block {
|
Block {
|
||||||
statements: Vec<Index>,
|
statements: Vec<Index>,
|
||||||
expr: Option<Index>,
|
expr: Option<Index>,
|
||||||
|
@ -274,6 +273,103 @@ impl Ast {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
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)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue