From ff3edf17e52ba2d487ade7617969843f43100d10 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 19 Nov 2022 19:13:30 +0100 Subject: [PATCH] Parse anonymous function definitions --- src/ast/table_destr.rs | 2 ++ src/parser.rs | 1 + src/parser/func_defs.rs | 71 +++++++++++++++++++++++++++++++++++++-- src/parser/table_destr.rs | 3 +- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/ast/table_destr.rs b/src/ast/table_destr.rs index 2886985..56c8d36 100644 --- a/src/ast/table_destr.rs +++ b/src/ast/table_destr.rs @@ -2,6 +2,8 @@ use crate::span::{HasSpan, Span}; use super::{Expr, Ident, Space}; +// TODO Make table patterns recursive + #[derive(Debug, Clone)] pub enum TablePatternElem { /// `foo` diff --git a/src/parser.rs b/src/parser.rs index 7f4a722..6688a5b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -6,6 +6,7 @@ //! made public later. // TODO Turn multiple calls to subparsers into clone-s +// TODO Remove unnecessary +Clone-s and 'static-s mod basic; mod expr; diff --git a/src/parser/func_defs.rs b/src/parser/func_defs.rs index af6b0f7..0d7b51a 100644 --- a/src/parser/func_defs.rs +++ b/src/parser/func_defs.rs @@ -2,10 +2,75 @@ use chumsky::prelude::*; use crate::ast::{Expr, FuncDef}; -use super::basic::Error; +use super::basic::{ident, space, Error}; +use super::table_destr::table_pattern; + +fn func_def_anon_no_arg( + expr: impl Parser, +) -> impl Parser { + text::keyword("function") + .ignore_then(space()) + .then_ignore(just('(')) + .then(space()) + .then_ignore(just(')')) + .then(space()) + .then(expr) + .map_with_span(|(((s0, s1), s2), body), span| FuncDef::AnonNoArg { + s0, + s1, + s2, + body: Box::new(body), + span, + }) +} + +fn func_def_anon_arg( + expr: impl Parser, +) -> impl Parser { + text::keyword("function") + .ignore_then(space()) + .then_ignore(just('(')) + .then(space()) + .then(ident()) + .then(space()) + .then_ignore(just(')')) + .then(space()) + .then(expr) + .map_with_span( + |(((((s0, s1), arg), s2), s3), body), span| FuncDef::AnonArg { + s0, + s1, + arg, + s2, + s3, + body: Box::new(body), + span, + }, + ) +} + +fn func_def_anon_destr( + expr: impl Parser, +) -> impl Parser { + text::keyword("function") + .ignore_then(space()) + .then(table_pattern()) + .then(space()) + .then(expr) + .map_with_span(|(((s0, pattern), s1), body), span| FuncDef::AnonDestr { + s0, + pattern, + s1, + body: Box::new(body), + span, + }) +} pub fn func_def( - expr: impl Parser, + expr: impl Parser + Clone + 'static, ) -> BoxedParser<'static, char, FuncDef, Error> { - todo().boxed() + func_def_anon_no_arg(expr.clone()) + .or(func_def_anon_arg(expr.clone())) + .or(func_def_anon_destr(expr)) + .boxed() } diff --git a/src/parser/table_destr.rs b/src/parser/table_destr.rs index 8490962..538a6a9 100644 --- a/src/parser/table_destr.rs +++ b/src/parser/table_destr.rs @@ -25,7 +25,7 @@ fn table_pattern_elem() -> impl Parser + named.or(positional) } -fn table_pattern() -> impl Parser + Clone { +pub fn table_pattern() -> BoxedParser<'static, char, TablePattern, Error> { let elem = space() .then(table_pattern_elem()) .then(space()) @@ -43,6 +43,7 @@ fn table_pattern() -> impl Parser + Clone { trailing_comma, span, }) + .boxed() } pub fn table_destr(