Parse field access suffix
This commit is contained in:
parent
23a126cbfd
commit
63a33b47a1
2 changed files with 130 additions and 3 deletions
|
|
@ -402,7 +402,7 @@ impl HasSpan for Expr {
|
||||||
Expr::Paren { span, .. } => *span,
|
Expr::Paren { span, .. } => *span,
|
||||||
Expr::TableConstr(tcr) => tcr.span(),
|
Expr::TableConstr(tcr) => tcr.span(),
|
||||||
Expr::Var { span, .. } => *span,
|
Expr::Var { span, .. } => *span,
|
||||||
Expr::VarIdent(_) => todo!(),
|
Expr::VarIdent(name) => name.span(),
|
||||||
Expr::VarAssign { span, .. } => *span,
|
Expr::VarAssign { span, .. } => *span,
|
||||||
Expr::VarIdentAssign { name, value, .. } => name.span().join(value.span()),
|
Expr::VarIdentAssign { name, value, .. } => name.span().join(value.span()),
|
||||||
Expr::Neg { minus, expr, .. } => minus.join(expr.span()),
|
Expr::Neg { minus, expr, .. } => minus.join(expr.span()),
|
||||||
|
|
|
||||||
131
src/parser.rs
131
src/parser.rs
|
|
@ -5,7 +5,7 @@ use crate::ast::{
|
||||||
Expr, Ident, Lit, NumLit, NumLitStr, Space, StringLit, TableConstr, TableConstrElem, TableLit,
|
Expr, Ident, Lit, NumLit, NumLitStr, Space, StringLit, TableConstr, TableConstrElem, TableLit,
|
||||||
TableLitElem,
|
TableLitElem,
|
||||||
};
|
};
|
||||||
use crate::span::Span;
|
use crate::span::{HasSpan, Span};
|
||||||
|
|
||||||
type Error = Simple<char, Span>;
|
type Error = Simple<char, Span>;
|
||||||
|
|
||||||
|
|
@ -286,10 +286,137 @@ fn atom(
|
||||||
.or(var_ident)
|
.or(var_ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Suffix {
|
||||||
|
/// See [`Expr::Field`].
|
||||||
|
Field {
|
||||||
|
s0: Space,
|
||||||
|
s1: Space,
|
||||||
|
index: Box<Expr>,
|
||||||
|
s2: Space,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// See [`Expr::FieldIdent`].
|
||||||
|
FieldIdent { s0: Space, s1: Space, ident: Ident },
|
||||||
|
|
||||||
|
/// See [`Expr::FieldAssign`].
|
||||||
|
FieldAssign {
|
||||||
|
s0: Space,
|
||||||
|
s1: Space,
|
||||||
|
index: Box<Expr>,
|
||||||
|
s2: Space,
|
||||||
|
s3: Space,
|
||||||
|
s4: Space,
|
||||||
|
value: Box<Expr>,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// See [`Expr::FieldIdentAssign`].
|
||||||
|
FieldIdentAssign {
|
||||||
|
s0: Space,
|
||||||
|
s1: Space,
|
||||||
|
ident: Ident,
|
||||||
|
s2: Space,
|
||||||
|
s3: Space,
|
||||||
|
value: Box<Expr>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Suffix {
|
||||||
|
fn into_expr(self, expr: Expr) -> Expr {
|
||||||
|
let expr = Box::new(expr);
|
||||||
|
match self {
|
||||||
|
Suffix::Field {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index,
|
||||||
|
s2,
|
||||||
|
span,
|
||||||
|
} => Expr::Field {
|
||||||
|
span: expr.span().join(span),
|
||||||
|
expr,
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index,
|
||||||
|
s2,
|
||||||
|
},
|
||||||
|
Suffix::FieldIdent { s0, s1, ident } => Expr::FieldIdent {
|
||||||
|
expr,
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
ident,
|
||||||
|
},
|
||||||
|
Suffix::FieldAssign {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index,
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
s4,
|
||||||
|
value,
|
||||||
|
} => Expr::FieldAssign {
|
||||||
|
expr,
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index,
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
s4,
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
Suffix::FieldIdentAssign {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
ident,
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
value,
|
||||||
|
} => Expr::FieldIdentAssign {
|
||||||
|
expr,
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
ident,
|
||||||
|
s2,
|
||||||
|
s3,
|
||||||
|
value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffix_field(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
|
) -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
space()
|
||||||
|
.then_ignore(just("["))
|
||||||
|
.then(space())
|
||||||
|
.then(expr)
|
||||||
|
.then(space())
|
||||||
|
.then_ignore(just("]"))
|
||||||
|
.map_with_span(|(((s0, s1), index), s2), span| Suffix::Field {
|
||||||
|
s0,
|
||||||
|
s1,
|
||||||
|
index: Box::new(index),
|
||||||
|
s2,
|
||||||
|
span,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn suffixed(
|
||||||
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
|
) -> impl Parser<char, Expr, Error = Error> {
|
||||||
|
let suffix_field = suffix_field(expr.clone());
|
||||||
|
|
||||||
|
let suffix = suffix_field;
|
||||||
|
|
||||||
|
atom(expr)
|
||||||
|
.then(suffix.repeated())
|
||||||
|
.foldl(|expr, suffix| suffix.into_expr(expr))
|
||||||
|
}
|
||||||
|
|
||||||
fn expr(
|
fn expr(
|
||||||
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> {
|
||||||
atom(expr)
|
suffixed(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parser() -> impl Parser<char, Expr, Error = Error> {
|
pub fn parser() -> impl Parser<char, Expr, Error = Error> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue