diff --git a/parser/src/ast.rs b/parser/src/ast.rs index b02bff7..15a6681 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -17,7 +17,7 @@ pub struct Ty { #[derive(Debug, Clone, PartialEq)] pub enum TyKind { U64, - Ptr(Box), + Ptr(Box), Name(String), } diff --git a/parser/src/parser.rs b/parser/src/parser.rs index e033feb..8a7c651 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -17,19 +17,37 @@ fn ident_parser<'src>() -> impl Parser, String, Error = Error<'src>> let ident = select! { Token::Ident(ident) => ident.to_owned(), }; - ident.labelled("identifier") + ident.labelled("identifier").boxed() } fn ty_parser<'src>() -> impl Parser, Ty, Error = Error<'src>> + Clone { - filter_map(|span, token| { - let kind = match token { - Token::Ident("u64") => TyKind::U64, - _ => return Err(Simple::expected_input_found(span, Vec::new(), Some(token))), - }; + recursive(|ty_parser| { + let primitive = filter_map(|span, token| { + let kind = match token { + Token::Ident("u64") => TyKind::U64, + _ => return Err(Simple::expected_input_found(span, Vec::new(), Some(token))), + }; + Ok(Ty { span, kind }) + }) + .labelled("primitive type"); - Ok(Ty { span, kind }) + let ptr = just(Token::Asterisk) + .ignore_then(ty_parser.clone()) + .map_with_span(|ty: Ty, span| Ty { + kind: TyKind::Ptr(Box::new(ty)), + span, + }) + .labelled("pointer type"); + + let name = ident_parser() + .map_with_span(|name: String, span| Ty { + kind: TyKind::Name(name), + span, + }) + .labelled("name type"); + + primitive.or(ptr).or(name).labelled("type").boxed() }) - .labelled("type") } fn expr_parser<'src>() -> impl Parser, Expr, Error = Error<'src>> + Clone { @@ -51,7 +69,7 @@ fn expr_parser<'src>() -> impl Parser, Expr, Error = Error<'src>> + .chain(just(Token::Comma).ignore_then(expr.clone()).repeated()) .then_ignore(just(Token::Comma).or_not()) .or_not() - .map(|item| item.unwrap_or_else(Vec::new)); + .map(|item| item.unwrap_or_default()); let array = items .clone() @@ -72,7 +90,7 @@ fn expr_parser<'src>() -> impl Parser, Expr, Error = Error<'src>> + .delimited_by(just(Token::ParenO), just(Token::ParenC)) .repeated(), ) - .foldl(|callee, args| { + .foldl(|callee: Expr, args: Vec| { Expr::Call(Call { callee: Box::new(callee), args, @@ -126,7 +144,7 @@ fn expr_parser<'src>() -> impl Parser, Expr, Error = Error<'src>> + span: 0..0, // lol todo }) }); - compare.labelled("comparison") + compare.labelled("comparison").boxed() }) } @@ -244,8 +262,7 @@ fn item_parser<'src>() -> impl Parser, Item, Error = Error<'src>> + let ret_ty = just(Token::Arrow).ignore_then(ty_parser()).or_not(); let function = just(Token::Fn) - .map_with_span(|_, span| span) - .then(name) + .ignore_then(name) .then(params) .then(ret_ty) .then( @@ -253,11 +270,11 @@ fn item_parser<'src>() -> impl Parser, Item, Error = Error<'src>> + .repeated() .delimited_by(just(Token::BraceO), just(Token::BraceC)), ) - .map(|((((fn_span, name), params), ret_ty), body)| FnDecl { + .map_with_span(|(((name, params), ret_ty), body), span| FnDecl { name, params, ret_ty, - span: fn_span, + span, body, }) .labelled("function"); @@ -274,10 +291,10 @@ fn file_parser<'src>( file_name: PathBuf, ) -> impl Parser, File, Error = Error<'src>> + Clone { item_parser() - // .repeated() + .repeated() .map(move |items| File { name: file_name.clone(), - items: vec![items], + items, }) .labelled("file") } @@ -356,4 +373,10 @@ mod tests { let r = parse("struct X { y: u64, x: u64 }"); insta::assert_debug_snapshot!(r); } + + #[test] + fn types() { + let r = parse("fn types() -> *u64 { Test test = 2; *Hello = true; }"); + insta::assert_debug_snapshot!(r); + } } diff --git a/parser/src/snapshots/parser__parser__tests__addition.snap b/parser/src/snapshots/parser__parser__tests__addition.snap index fe5cc4a..1da1d84 100644 --- a/parser/src/snapshots/parser__parser__tests__addition.snap +++ b/parser/src/snapshots/parser__parser__tests__addition.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 272 +assertion_line: 332 expression: r --- ( @@ -13,7 +13,7 @@ expression: r name: "main", params: [], ret_ty: None, - span: 0..2, + span: 0..20, body: [ Expr( BinOp( diff --git a/parser/src/snapshots/parser__parser__tests__expression.snap b/parser/src/snapshots/parser__parser__tests__expression.snap index 1aae64f..bb296e6 100644 --- a/parser/src/snapshots/parser__parser__tests__expression.snap +++ b/parser/src/snapshots/parser__parser__tests__expression.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 278 +assertion_line: 338 expression: r --- ( @@ -13,7 +13,7 @@ expression: r name: "main", params: [], ret_ty: None, - span: 0..2, + span: 0..32, body: [ Expr( BinOp( diff --git a/parser/src/snapshots/parser__parser__tests__function.snap b/parser/src/snapshots/parser__parser__tests__function.snap index a7101f9..707c4ee 100644 --- a/parser/src/snapshots/parser__parser__tests__function.snap +++ b/parser/src/snapshots/parser__parser__tests__function.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 284 +assertion_line: 344 expression: r --- ( @@ -18,7 +18,7 @@ expression: r kind: U64, }, ), - span: 0..2, + span: 0..26, body: [ Expr( BinOp( diff --git a/parser/src/snapshots/parser__parser__tests__if_else.snap b/parser/src/snapshots/parser__parser__tests__if_else.snap index 590101a..0788927 100644 --- a/parser/src/snapshots/parser__parser__tests__if_else.snap +++ b/parser/src/snapshots/parser__parser__tests__if_else.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 330 +assertion_line: 356 expression: r --- ( @@ -18,7 +18,7 @@ expression: r kind: U64, }, ), - span: 0..2, + span: 0..39, body: [ IfStmt( IfStmt { diff --git a/parser/src/snapshots/parser__parser__tests__if_no_else.snap b/parser/src/snapshots/parser__parser__tests__if_no_else.snap index ed7192d..dfd96ff 100644 --- a/parser/src/snapshots/parser__parser__tests__if_no_else.snap +++ b/parser/src/snapshots/parser__parser__tests__if_no_else.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 333 +assertion_line: 350 expression: r --- ( @@ -18,7 +18,7 @@ expression: r kind: U64, }, ), - span: 0..2, + span: 0..31, body: [ IfStmt( IfStmt { diff --git a/parser/src/snapshots/parser__parser__tests__var_decl.snap b/parser/src/snapshots/parser__parser__tests__var_decl.snap index 44dafde..3242ff7 100644 --- a/parser/src/snapshots/parser__parser__tests__var_decl.snap +++ b/parser/src/snapshots/parser__parser__tests__var_decl.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 319 +assertion_line: 368 expression: r --- ( @@ -18,7 +18,7 @@ expression: r kind: U64, }, ), - span: 0..2, + span: 0..34, body: [ VarDecl( VarDecl { diff --git a/parser/src/snapshots/parser__parser__tests__while_loop.snap b/parser/src/snapshots/parser__parser__tests__while_loop.snap index 4744129..59261cb 100644 --- a/parser/src/snapshots/parser__parser__tests__while_loop.snap +++ b/parser/src/snapshots/parser__parser__tests__while_loop.snap @@ -1,6 +1,6 @@ --- source: parser/src/parser.rs -assertion_line: 336 +assertion_line: 362 expression: r --- ( @@ -18,7 +18,7 @@ expression: r kind: U64, }, ), - span: 0..2, + span: 0..34, body: [ WhileStmt( WhileStmt {