Parse suffixes
This commit is contained in:
parent
3e2f118e2e
commit
94198d126f
2 changed files with 117 additions and 16 deletions
|
|
@ -6,7 +6,7 @@ use super::{Expr, Space, TableConstr};
|
||||||
pub enum Call {
|
pub enum Call {
|
||||||
/// `a(b)`
|
/// `a(b)`
|
||||||
///
|
///
|
||||||
/// Structure: `expr s0 ( s1 arg s2)
|
/// Structure: `expr s0 ( s1 arg s2 )`
|
||||||
Arg {
|
Arg {
|
||||||
expr: Box<Expr>,
|
expr: Box<Expr>,
|
||||||
s0: Space,
|
s0: Space,
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,11 @@ use chumsky::prelude::*;
|
||||||
use crate::ast::{Call, Expr, Field, Ident, Space, TableConstr};
|
use crate::ast::{Call, Expr, Field, Ident, Space, TableConstr};
|
||||||
use crate::span::{HasSpan, Span};
|
use crate::span::{HasSpan, Span};
|
||||||
|
|
||||||
use super::basic::{space, Error};
|
use super::basic::{ident, space, Error};
|
||||||
|
use super::table_constr::table_constr;
|
||||||
|
|
||||||
enum Suffix {
|
enum Suffix {
|
||||||
|
/// See [`Call::Arg`].
|
||||||
CallArg {
|
CallArg {
|
||||||
s0: Space,
|
s0: Space,
|
||||||
s1: Space,
|
s1: Space,
|
||||||
|
|
@ -15,16 +17,13 @@ enum Suffix {
|
||||||
s2: Space,
|
s2: Space,
|
||||||
},
|
},
|
||||||
|
|
||||||
CallNoArg {
|
/// See [`Call::NoArg`].
|
||||||
s0: Space,
|
CallNoArg { s0: Space, s1: Space },
|
||||||
s1: Space,
|
|
||||||
},
|
|
||||||
|
|
||||||
CallConstr {
|
/// See [`Call::Constr`].
|
||||||
s0: Space,
|
CallConstr { s0: Space, constr: TableConstr },
|
||||||
constr: TableConstr,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
/// See [`Field::Access`].
|
||||||
FieldAccess {
|
FieldAccess {
|
||||||
s0: Space,
|
s0: Space,
|
||||||
s1: Space,
|
s1: Space,
|
||||||
|
|
@ -32,6 +31,7 @@ enum Suffix {
|
||||||
s2: Space,
|
s2: Space,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// See [`Field::Assign`].
|
||||||
FieldAssign {
|
FieldAssign {
|
||||||
s0: Space,
|
s0: Space,
|
||||||
s1: Space,
|
s1: Space,
|
||||||
|
|
@ -42,12 +42,10 @@ enum Suffix {
|
||||||
value: Box<Expr>,
|
value: Box<Expr>,
|
||||||
},
|
},
|
||||||
|
|
||||||
FieldAccessIdent {
|
/// See [`Field::AccessIdent`].
|
||||||
s0: Space,
|
FieldAccessIdent { s0: Space, s1: Space, ident: Ident },
|
||||||
s1: Space,
|
|
||||||
ident: Ident,
|
|
||||||
},
|
|
||||||
|
|
||||||
|
/// See [`Field::AssignIdent`].
|
||||||
FieldAssignIdent {
|
FieldAssignIdent {
|
||||||
s0: Space,
|
s0: Space,
|
||||||
s1: Space,
|
s1: Space,
|
||||||
|
|
@ -132,6 +130,39 @@ impl Suffix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suffix_call_arg(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error>,
|
||||||
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just('('))
|
||||||
|
.then(space())
|
||||||
|
.then(expr)
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just(')'))
|
||||||
|
.map(|(((s0, s1), arg), s2)| Suffix::CallArg {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
arg: Box::new(arg),
|
||||||
|
s2,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix_call_no_arg() -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just('('))
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just(')'))
|
||||||
|
.map(|(s0, s1)| Suffix::CallNoArg { s0, s1 })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix_call_constr(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then(table_constr(expr))
|
||||||
|
.map(|(s0, constr)| Suffix::CallConstr { s0, constr })
|
||||||
|
}
|
||||||
|
|
||||||
fn suffix_field_access(
|
fn suffix_field_access(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Suffix, Error = Error> {
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
|
@ -149,13 +180,83 @@ fn suffix_field_access(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suffix_field_assign(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just('['))
|
||||||
|
.then(space())
|
||||||
|
.then(expr.clone())
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just(']'))
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just('='))
|
||||||
|
.then(space())
|
||||||
|
.then(expr)
|
||||||
|
.map(
|
||||||
|
|((((((s0, s1), index), s2), s3), s4), value)| Suffix::FieldAssign {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index: Box::new(index),
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
s4,
|
||||||
|
value: Box::new(value),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix_field_access_ident() -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just('.'))
|
||||||
|
.then(space())
|
||||||
|
.then(ident())
|
||||||
|
.map(|((s0, s1), ident)| Suffix::FieldAccessIdent { s0, s1, ident })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix_field_assign_ident(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error>,
|
||||||
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just('.'))
|
||||||
|
.then(space())
|
||||||
|
.then(ident())
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just('='))
|
||||||
|
.then(space())
|
||||||
|
.then(expr)
|
||||||
|
.map(
|
||||||
|
|(((((s0, s1), ident), s2), s3), value)| Suffix::FieldAssignIdent {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
ident,
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
value: Box::new(value),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn suffixed(
|
pub fn suffixed(
|
||||||
atom: impl Parser<char, Expr, Error = Error>,
|
atom: impl Parser<char, Expr, Error = Error>,
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Error> {
|
) -> impl Parser<char, Expr, Error = Error> {
|
||||||
|
let call_arg = suffix_call_arg(expr.clone());
|
||||||
|
let call_no_arg = suffix_call_no_arg();
|
||||||
|
let call_constr = suffix_call_constr(expr.clone());
|
||||||
let field_access = suffix_field_access(expr.clone());
|
let field_access = suffix_field_access(expr.clone());
|
||||||
|
let field_assign = suffix_field_assign(expr.clone());
|
||||||
|
let field_access_ident = suffix_field_access_ident();
|
||||||
|
let field_assign_ident = suffix_field_assign_ident(expr);
|
||||||
|
|
||||||
let suffix = field_access.map_with_span(|suffix, span| (suffix, span));
|
let suffix = call_arg
|
||||||
|
.or(call_no_arg)
|
||||||
|
.or(call_constr)
|
||||||
|
.or(field_assign)
|
||||||
|
.or(field_access)
|
||||||
|
.or(field_assign_ident)
|
||||||
|
.or(field_access_ident)
|
||||||
|
.map_with_span(|suffix, span| (suffix, span));
|
||||||
|
|
||||||
atom.then(suffix.repeated())
|
atom.then(suffix.repeated())
|
||||||
.foldl(|expr, (suffix, span)| suffix.into_expr(expr.span().join(span), expr))
|
.foldl(|expr, (suffix, span)| suffix.into_expr(expr.span().join(span), expr))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue