fix parser kind of i guess

This commit is contained in:
nora 2022-06-12 21:01:34 +02:00
parent 84c99c5c20
commit 31938274a7
5 changed files with 174 additions and 33 deletions

View file

@ -78,6 +78,8 @@ pub enum Token<'a> {
While,
#[token("loop")]
Loop,
#[token("ptr")]
Ptr,
#[regex(r"[a-zA-Z_]\w*")]
Ident(&'a str),
@ -131,6 +133,7 @@ impl<'a> Display for Token<'a> {
Token::Else => f.write_str("else"),
Token::While => f.write_str("while"),
Token::Loop => f.write_str("loop"),
Token::Ptr => f.write_str("ptr"),
Token::Ident(ident) => write!(f, "identifier `{ident}`"),
Token::String(str) => write!(f, "\"{str}\""),
Token::Integer(int) => write!(f, "{int}"),

View file

@ -19,7 +19,10 @@ pub fn parse(_str: &str, _file_name: PathBuf) -> Result<ast::File, ()> {
pub fn test() {
let src = "
fn main() {
u64 hello = 4
//-(*5);
//&5;
//2 + &8;
*6 * *8; // :)
}
";

View file

@ -31,7 +31,7 @@ fn ty_parser<'src>() -> impl Parser<Token<'src>, Ty, Error = Error<'src>> + Clon
})
.labelled("primitive type");
let ptr = just(Token::Asterisk)
let ptr = just(Token::Ptr)
.ignore_then(ty_parser.clone())
.map_with_span(|ty: Ty, span| Ty {
kind: TyKind::Ptr(Box::new(ty)),
@ -63,15 +63,15 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
})
.labelled("literal");
// A list of expressions
let items = expr
let expr_list = expr
.clone()
.chain(just(Token::Comma).ignore_then(expr.clone()).repeated())
.then_ignore(just(Token::Comma).or_not())
.separated_by(just(Token::Comma))
.allow_trailing()
.or_not()
.map(|item| item.unwrap_or_default());
.map(|item| item.unwrap_or_default())
.boxed();
let array = items
let array = expr_list
.clone()
.delimited_by(just(Token::BracketO), just(Token::BracketC))
.map(Expr::Array);
@ -82,11 +82,13 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
.or(expr
.clone()
.delimited_by(just(Token::ParenO), just(Token::ParenC)))
.debug("atom")
.boxed();
let call = atom
.clone()
.then(
items
expr_list
.delimited_by(just(Token::ParenO), just(Token::ParenC))
.repeated(),
)
@ -95,23 +97,36 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
callee: Box::new(callee),
args,
})
});
})
.labelled("call")
.boxed();
// let _unary_op = just(Token::Minus)
// .to(UnaryOpKind::Neg)
// .or(just(Token::Bang).to(UnaryOpKind::Not))
// .or(just(Token::Asterisk).to(UnaryOpKind::Deref))
// .or(just(Token::Ampersand).to(UnaryOpKind::AddrOf));
// todo: unary
let unary_op = choice((
just(Token::Minus).to(UnaryOpKind::Neg),
just(Token::Bang).to(UnaryOpKind::Not),
just(Token::Ampersand).to(UnaryOpKind::AddrOf),
just(Token::Asterisk).to(UnaryOpKind::Deref),
))
.repeated()
.then(call)
.foldr(|kind, rhs| {
Expr::UnaryOp(UnaryOp {
expr: Box::new(rhs),
kind,
span: 0..0, // lol todo
})
})
.labelled("unary")
.debug("unary")
.boxed();
let op = just(Token::Asterisk)
.to(BinOpKind::Mul)
.or(just(Token::Slash).to(BinOpKind::Div));
let product = call
let product = unary_op
.clone()
.then(op.then(call).repeated())
.then(op.then(unary_op).repeated())
.foldl(|a, (kind, b)| {
Expr::BinOp(BinOp {
kind,
@ -135,7 +150,10 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
rhs: Box::new(b),
span: 0..0, // lol todo
})
});
})
.labelled("product")
.debug("product")
.boxed();
// Comparison ops (equal, not-equal) have equal precedence
let op = just(Token::EqEq)
@ -170,7 +188,8 @@ fn statement_parser<'src>() -> impl Parser<Token<'src>, Stmt, Error = Error<'src
rhs: Some(rhs),
span: Default::default(),
})
});
})
.boxed();
let assignment = expr_parser()
.then_ignore(just(Token::Eq))
@ -215,7 +234,8 @@ fn statement_parser<'src>() -> impl Parser<Token<'src>, Stmt, Error = Error<'src
span,
})
})
.map(Stmt::IfStmt);
.map(Stmt::IfStmt)
.boxed();
var_decl
.or(assignment)
@ -307,7 +327,7 @@ where
I: 'src,
I: Iterator<Item = (Token<'src>, Span)>,
{
file_parser(file_name).parse_recovery(Stream::from_iter(len..len + 1, lexer))
file_parser(file_name).parse_recovery_verbose(Stream::from_iter(len..len + 1, lexer))
}
#[cfg(test)]
@ -392,7 +412,7 @@ mod tests {
#[test]
fn types() {
let r = parse("fn types() -> *u64 { Test test = 2; *u64 int = 25; }");
let r = parse("fn types() -> ptr u64 { Test test = 2; ptr u64 int = 25; }");
insta::assert_debug_snapshot!(r);
}
}

View file

@ -1,6 +1,5 @@
---
source: parser/src/parser.rs
assertion_line: 382
expression: r
---
(
@ -14,22 +13,22 @@ expression: r
params: [],
ret_ty: Some(
Ty {
span: 14..18,
span: 14..21,
kind: Ptr(
Ty {
span: 15..18,
span: 18..21,
kind: U64,
},
),
},
),
span: 0..52,
span: 0..58,
body: [
VarDecl(
VarDecl {
name: "test",
ty: Ty {
span: 21..25,
span: 24..28,
kind: Name(
"Test",
),
@ -38,7 +37,7 @@ expression: r
Literal(
Integer(
2,
33..34,
36..37,
),
),
),
@ -49,10 +48,10 @@ expression: r
VarDecl {
name: "int",
ty: Ty {
span: 36..40,
span: 39..46,
kind: Ptr(
Ty {
span: 37..40,
span: 43..46,
kind: U64,
},
),
@ -61,7 +60,7 @@ expression: r
Literal(
Integer(
25,
47..49,
53..55,
),
),
),

View file

@ -0,0 +1,116 @@
---
source: parser/src/parser.rs
expression: r
---
(
Some(
File {
name: "parser__parser__tests",
items: [
FnDecl(
FnDecl {
name: "main",
params: [],
ret_ty: None,
span: 0..63,
body: [
Expr(
UnaryOp(
UnaryOp {
expr: UnaryOp(
UnaryOp {
expr: Literal(
Integer(
5,
19..20,
),
),
kind: Deref,
span: 0..0,
},
),
kind: Neg,
span: 0..0,
},
),
),
Expr(
UnaryOp(
UnaryOp {
expr: Literal(
Integer(
5,
28..29,
),
),
kind: AddrOf,
span: 0..0,
},
),
),
Expr(
BinOp(
BinOp {
kind: Add,
lhs: Literal(
Integer(
2,
35..36,
),
),
rhs: UnaryOp(
UnaryOp {
expr: Literal(
Integer(
8,
40..41,
),
),
kind: AddrOf,
span: 0..0,
},
),
span: 0..0,
},
),
),
Expr(
BinOp(
BinOp {
kind: Mul,
lhs: UnaryOp(
UnaryOp {
expr: Literal(
Integer(
6,
48..49,
),
),
kind: Deref,
span: 0..0,
},
),
rhs: UnaryOp(
UnaryOp {
expr: Literal(
Integer(
8,
53..54,
),
),
kind: Deref,
span: 0..0,
},
),
span: 0..0,
},
),
),
],
},
),
],
},
),
[],
)