From 009927764438ea87a97b3cfd05216e5fd1d0220d Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 19 Nov 2022 19:24:23 +0100 Subject: [PATCH] Parse named function definitions --- src/parser/basic.rs | 4 ++ src/parser/func_defs.rs | 90 ++++++++++++++++++++++++++++++++++++++++- src/parser/var.rs | 10 ++--- 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/parser/basic.rs b/src/parser/basic.rs index f5e732b..cc0b41a 100644 --- a/src/parser/basic.rs +++ b/src/parser/basic.rs @@ -55,3 +55,7 @@ pub fn ident() -> BoxedParser<'static, char, Ident, Error> { }) .boxed() } + +pub fn local() -> BoxedParser<'static, char, Option, Error> { + text::keyword("local").ignore_then(space()).or_not().boxed() +} diff --git a/src/parser/func_defs.rs b/src/parser/func_defs.rs index 0d7b51a..0662aed 100644 --- a/src/parser/func_defs.rs +++ b/src/parser/func_defs.rs @@ -2,7 +2,7 @@ use chumsky::prelude::*; use crate::ast::{Expr, FuncDef}; -use super::basic::{ident, space, Error}; +use super::basic::{ident, local, space, Error}; use super::table_destr::table_pattern; fn func_def_anon_no_arg( @@ -66,11 +66,97 @@ fn func_def_anon_destr( }) } +fn func_def_named_no_arg( + expr: impl Parser, +) -> impl Parser { + local() + .then_ignore(text::keyword("function")) + .then(space()) + .then(ident()) + .then(space()) + .then_ignore(just('(')) + .then(space()) + .then_ignore(just(')')) + .then(space()) + .then(expr) + .map_with_span( + |((((((local, s0), name), s1), s2), s3), body), span| FuncDef::NamedNoArg { + local, + s0, + name, + s1, + s2, + s3, + body: Box::new(body), + span, + }, + ) +} + +fn func_def_named_arg( + expr: impl Parser, +) -> impl Parser { + local() + .then_ignore(text::keyword("function")) + .then(space()) + .then(ident()) + .then(space()) + .then_ignore(just('(')) + .then(space()) + .then(ident()) + .then(space()) + .then_ignore(just(')')) + .then(space()) + .then(expr) + .map_with_span( + |((((((((local, s0), name), s1), s2), arg), s3), s4), body), span| FuncDef::NamedArg { + local, + s0, + name, + s1, + s2, + arg, + s3, + s4, + body: Box::new(body), + span, + }, + ) +} + +fn func_def_named_destr( + expr: impl Parser, +) -> impl Parser { + local() + .then_ignore(text::keyword("function")) + .then(space()) + .then(ident()) + .then(space()) + .then(table_pattern()) + .then(space()) + .then(expr) + .map_with_span(|((((((local, s0), name), s1), pattern), s2), body), span| { + FuncDef::NamedDestr { + local, + s0, + name, + s1, + pattern, + s2, + body: Box::new(body), + span, + } + }) +} + pub fn func_def( expr: impl Parser + Clone + 'static, ) -> BoxedParser<'static, char, FuncDef, Error> { func_def_anon_no_arg(expr.clone()) .or(func_def_anon_arg(expr.clone())) - .or(func_def_anon_destr(expr)) + .or(func_def_anon_destr(expr.clone())) + .or(func_def_named_no_arg(expr.clone())) + .or(func_def_named_arg(expr.clone())) + .or(func_def_named_destr(expr)) .boxed() } diff --git a/src/parser/var.rs b/src/parser/var.rs index 6f4fc62..1d1610f 100644 --- a/src/parser/var.rs +++ b/src/parser/var.rs @@ -4,7 +4,7 @@ use chumsky::prelude::*; use crate::ast::{Expr, Var}; -use super::basic::{ident, space, Error}; +use super::basic::{ident, local, space, Error}; fn var_access( expr: impl Parser + Clone, @@ -25,9 +25,7 @@ fn var_access( fn var_assign( expr: impl Parser + Clone, ) -> impl Parser + Clone { - let local = text::keyword("local").ignore_then(space()).or_not(); - - local + local() .then_ignore(just('[')) .then(space()) .then(expr.clone()) @@ -54,9 +52,7 @@ fn var_assign( fn var_assign_ident( expr: impl Parser + Clone, ) -> impl Parser + Clone { - let local = text::keyword("local").ignore_then(space()).or_not(); - - local + local() .then(ident()) .then(space()) .then_ignore(just('='))