Parse table destructuring

This commit is contained in:
Joscha 2022-11-18 21:40:27 +01:00
parent a82b625631
commit 73e32252c4
3 changed files with 73 additions and 3 deletions

View file

@ -8,6 +8,7 @@ use super::basic::{space, Error};
use super::lit::lit;
use super::suffix::suffixed;
use super::table_constr::table_constr;
use super::table_destr::table_destr;
use super::var::var;
fn atom_paren(
@ -30,11 +31,12 @@ fn atom(
expr: impl Parser<char, Expr, Error = Error> + Clone,
) -> impl Parser<char, Expr, Error = Error> {
let lit = lit(expr.clone()).map(Expr::Lit);
let paren = atom_paren(expr.clone());
let var = var(expr.clone()).map(Expr::Var);
let table_constr = table_constr(expr.clone()).map(Expr::TableConstr);
let var = var(expr).map(Expr::Var);
let table_destr = table_destr(expr.clone()).map(Expr::TableDestr);
let paren = atom_paren(expr);
lit.or(paren).or(table_constr).or(var)
lit.or(paren).or(table_destr).or(table_constr).or(var)
}
pub fn expr(

67
src/parser/table_destr.rs Normal file
View file

@ -0,0 +1,67 @@
//! Corresponds to `ast::table_constr`.
use chumsky::prelude::*;
use crate::ast::{Expr, TableDestr, TablePattern, TablePatternElem};
use super::basic::{ident, space, Error};
pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error> {
let positional = ident().map(TablePatternElem::Positional);
let named = ident()
.then(space())
.then_ignore(just(':'))
.then(space())
.then(ident())
.map_with_span(|(((name, s0), s1), ident), span| TablePatternElem::Named {
name,
s0,
s1,
ident,
span,
});
named.or(positional)
}
pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> {
let elem = space()
.then(table_pattern_elem())
.then(space())
.map(|((s0, elem), s1)| (s0, elem, s1));
let trailing_comma = just(",").ignore_then(space()).or_not();
let elems = elem.separated_by(just(",")).then(trailing_comma);
just("{")
.ignore_then(elems)
.then_ignore(just("}"))
.map_with_span(|(elems, trailing_comma), span| TablePattern {
elems,
trailing_comma,
span,
})
}
pub fn table_destr(
expr: impl Parser<char, Expr, Error = Error>,
) -> impl Parser<char, TableDestr, Error = Error> {
let local = text::keyword("local").ignore_then(space()).or_not();
local
.then(table_pattern())
.then(space())
.then_ignore(just('='))
.then(space())
.then(expr)
.map_with_span(|((((local, pattern), s0), s1), value), span| TableDestr {
local,
pattern,
s0,
s1,
value: Box::new(value),
span,
})
}