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, While,
#[token("loop")] #[token("loop")]
Loop, Loop,
#[token("ptr")]
Ptr,
#[regex(r"[a-zA-Z_]\w*")] #[regex(r"[a-zA-Z_]\w*")]
Ident(&'a str), Ident(&'a str),
@ -131,6 +133,7 @@ impl<'a> Display for Token<'a> {
Token::Else => f.write_str("else"), Token::Else => f.write_str("else"),
Token::While => f.write_str("while"), Token::While => f.write_str("while"),
Token::Loop => f.write_str("loop"), Token::Loop => f.write_str("loop"),
Token::Ptr => f.write_str("ptr"),
Token::Ident(ident) => write!(f, "identifier `{ident}`"), Token::Ident(ident) => write!(f, "identifier `{ident}`"),
Token::String(str) => write!(f, "\"{str}\""), Token::String(str) => write!(f, "\"{str}\""),
Token::Integer(int) => write!(f, "{int}"), 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() { pub fn test() {
let src = " let src = "
fn main() { 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"); .labelled("primitive type");
let ptr = just(Token::Asterisk) let ptr = just(Token::Ptr)
.ignore_then(ty_parser.clone()) .ignore_then(ty_parser.clone())
.map_with_span(|ty: Ty, span| Ty { .map_with_span(|ty: Ty, span| Ty {
kind: TyKind::Ptr(Box::new(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"); .labelled("literal");
// A list of expressions let expr_list = expr
let items = expr
.clone() .clone()
.chain(just(Token::Comma).ignore_then(expr.clone()).repeated()) .separated_by(just(Token::Comma))
.then_ignore(just(Token::Comma).or_not()) .allow_trailing()
.or_not() .or_not()
.map(|item| item.unwrap_or_default()); .map(|item| item.unwrap_or_default())
.boxed();
let array = items let array = expr_list
.clone() .clone()
.delimited_by(just(Token::BracketO), just(Token::BracketC)) .delimited_by(just(Token::BracketO), just(Token::BracketC))
.map(Expr::Array); .map(Expr::Array);
@ -82,11 +82,13 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
.or(expr .or(expr
.clone() .clone()
.delimited_by(just(Token::ParenO), just(Token::ParenC))) .delimited_by(just(Token::ParenO), just(Token::ParenC)))
.debug("atom")
.boxed(); .boxed();
let call = atom let call = atom
.clone()
.then( .then(
items expr_list
.delimited_by(just(Token::ParenO), just(Token::ParenC)) .delimited_by(just(Token::ParenO), just(Token::ParenC))
.repeated(), .repeated(),
) )
@ -95,23 +97,36 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
callee: Box::new(callee), callee: Box::new(callee),
args, args,
}) })
}); })
.labelled("call")
.boxed();
// let _unary_op = just(Token::Minus) let unary_op = choice((
// .to(UnaryOpKind::Neg) just(Token::Minus).to(UnaryOpKind::Neg),
// .or(just(Token::Bang).to(UnaryOpKind::Not)) just(Token::Bang).to(UnaryOpKind::Not),
// .or(just(Token::Asterisk).to(UnaryOpKind::Deref)) just(Token::Ampersand).to(UnaryOpKind::AddrOf),
// .or(just(Token::Ampersand).to(UnaryOpKind::AddrOf)); just(Token::Asterisk).to(UnaryOpKind::Deref),
))
// todo: unary .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) let op = just(Token::Asterisk)
.to(BinOpKind::Mul) .to(BinOpKind::Mul)
.or(just(Token::Slash).to(BinOpKind::Div)); .or(just(Token::Slash).to(BinOpKind::Div));
let product = call let product = unary_op
.clone() .clone()
.then(op.then(call).repeated()) .then(op.then(unary_op).repeated())
.foldl(|a, (kind, b)| { .foldl(|a, (kind, b)| {
Expr::BinOp(BinOp { Expr::BinOp(BinOp {
kind, kind,
@ -135,7 +150,10 @@ fn expr_parser<'src>() -> impl Parser<Token<'src>, Expr, Error = Error<'src>> +
rhs: Box::new(b), rhs: Box::new(b),
span: 0..0, // lol todo span: 0..0, // lol todo
}) })
}); })
.labelled("product")
.debug("product")
.boxed();
// Comparison ops (equal, not-equal) have equal precedence // Comparison ops (equal, not-equal) have equal precedence
let op = just(Token::EqEq) let op = just(Token::EqEq)
@ -170,7 +188,8 @@ fn statement_parser<'src>() -> impl Parser<Token<'src>, Stmt, Error = Error<'src
rhs: Some(rhs), rhs: Some(rhs),
span: Default::default(), span: Default::default(),
}) })
}); })
.boxed();
let assignment = expr_parser() let assignment = expr_parser()
.then_ignore(just(Token::Eq)) .then_ignore(just(Token::Eq))
@ -215,7 +234,8 @@ fn statement_parser<'src>() -> impl Parser<Token<'src>, Stmt, Error = Error<'src
span, span,
}) })
}) })
.map(Stmt::IfStmt); .map(Stmt::IfStmt)
.boxed();
var_decl var_decl
.or(assignment) .or(assignment)
@ -307,7 +327,7 @@ where
I: 'src, I: 'src,
I: Iterator<Item = (Token<'src>, Span)>, 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)] #[cfg(test)]
@ -392,7 +412,7 @@ mod tests {
#[test] #[test]
fn types() { 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); insta::assert_debug_snapshot!(r);
} }
} }

View file

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