Parse table constructors
This commit is contained in:
parent
e7e4ca76fc
commit
0cb667f2cd
1 changed files with 50 additions and 8 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
use chumsky::text::Character;
|
use chumsky::text::Character;
|
||||||
|
|
||||||
use crate::ast::{Expr, Ident, Lit, NumLit, TableLit, TableLitElem};
|
use crate::ast::{Expr, Ident, Lit, NumLit, TableConstr, TableConstrElem, TableLit, TableLitElem};
|
||||||
|
|
||||||
fn ident() -> impl Parser<char, Ident, Error = Simple<char>> {
|
fn ident() -> impl Parser<char, Ident, Error = Simple<char>> {
|
||||||
text::ident().padded().map(Ident)
|
text::ident().padded().map(Ident)
|
||||||
|
|
@ -59,19 +59,24 @@ fn num_lit() -> impl Parser<char, NumLit, Error = Simple<char>> + Clone {
|
||||||
.padded()
|
.padded()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_lit_elems(
|
fn table_lit_elem(
|
||||||
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
) -> impl Parser<char, (Vec<TableLitElem>, bool), Error = Simple<char>> {
|
) -> impl Parser<char, TableLitElem, Error = Simple<char>> {
|
||||||
let positional = expr.clone().map(|e| TableLitElem::Positional(Box::new(e)));
|
let positional = expr.clone().map(|e| TableLitElem::Positional(Box::new(e)));
|
||||||
let named = ident()
|
let named = ident()
|
||||||
.then_ignore(just(":"))
|
.then_ignore(just(":"))
|
||||||
.then(expr)
|
.then(expr)
|
||||||
.map(|(n, e)| TableLitElem::Named(n, Box::new(e)));
|
.map(|(n, e)| TableLitElem::Named(n, Box::new(e)));
|
||||||
|
|
||||||
|
positional.or(named)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_lit_elems(
|
||||||
|
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
|
) -> impl Parser<char, (Vec<TableLitElem>, bool), Error = Simple<char>> {
|
||||||
let trailing_comma = just(',').or_not().map(|o| o.is_some());
|
let trailing_comma = just(',').or_not().map(|o| o.is_some());
|
||||||
|
|
||||||
positional
|
table_lit_elem(expr)
|
||||||
.or(named)
|
|
||||||
.separated_by(just(','))
|
.separated_by(just(','))
|
||||||
.then(trailing_comma)
|
.then(trailing_comma)
|
||||||
.padded()
|
.padded()
|
||||||
|
|
@ -112,7 +117,44 @@ fn lit(
|
||||||
.padded()
|
.padded()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parser() -> impl Parser<char, Lit, Error = Simple<char>> {
|
fn table_constr_elem(
|
||||||
let expr = num_lit().map(|num| Expr::Lit(Lit::Num(num)));
|
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
lit(expr).then_ignore(end())
|
) -> impl Parser<char, TableConstrElem, Error = Simple<char>> {
|
||||||
|
let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit);
|
||||||
|
let indexed = (just('[').ignore_then(expr.clone()).then_ignore(just(']')))
|
||||||
|
.padded()
|
||||||
|
.then_ignore(just(':'))
|
||||||
|
.then(expr)
|
||||||
|
.map(|(i, v)| TableConstrElem::Indexed(Box::new(i), Box::new(v)));
|
||||||
|
|
||||||
|
lit.or(indexed)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_constr_elems(
|
||||||
|
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
|
) -> impl Parser<char, (Vec<TableConstrElem>, bool), Error = Simple<char>> {
|
||||||
|
let trailing_comma = just(',').or_not().map(|o| o.is_some());
|
||||||
|
|
||||||
|
table_constr_elem(expr)
|
||||||
|
.separated_by(just(','))
|
||||||
|
.then(trailing_comma)
|
||||||
|
.padded()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn table_constr(
|
||||||
|
expr: impl Parser<char, Expr, Error = Simple<char>> + Clone,
|
||||||
|
) -> impl Parser<char, TableConstr, Error = Simple<char>> {
|
||||||
|
just("{")
|
||||||
|
.ignore_then(table_constr_elems(expr))
|
||||||
|
.then_ignore(just("}"))
|
||||||
|
.padded()
|
||||||
|
.map(|(elems, trailing_comma)| TableConstr {
|
||||||
|
elems,
|
||||||
|
trailing_comma,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parser() -> impl Parser<char, TableConstr, Error = Simple<char>> {
|
||||||
|
let expr = num_lit().map(|num| Expr::Lit(Lit::Num(num)));
|
||||||
|
table_constr(expr).then_ignore(end())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue