Parse binary operators
For now, they're all left associative.
This commit is contained in:
parent
63f8026007
commit
408219073a
10 changed files with 99 additions and 39 deletions
|
|
@ -20,6 +20,14 @@ pub enum BinOp {
|
||||||
Eq,
|
Eq,
|
||||||
/// `!=`
|
/// `!=`
|
||||||
Neq,
|
Neq,
|
||||||
|
/// `>`
|
||||||
|
Gt,
|
||||||
|
/// `>=`
|
||||||
|
Ge,
|
||||||
|
/// `<`
|
||||||
|
Lt,
|
||||||
|
/// `<=`
|
||||||
|
Le,
|
||||||
/// `and`
|
/// `and`
|
||||||
And,
|
And,
|
||||||
/// `or`
|
/// `or`
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// TODO Turn multiple calls to subparsers into clone-s
|
||||||
|
|
||||||
mod basic;
|
mod basic;
|
||||||
mod expr;
|
mod expr;
|
||||||
mod lit;
|
mod lit;
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,17 @@ pub type Error = Simple<char, Span>;
|
||||||
|
|
||||||
// TODO https://github.com/rust-lang/rust/issues/63063
|
// TODO https://github.com/rust-lang/rust/issues/63063
|
||||||
|
|
||||||
pub fn inline() -> impl Parser<char, (), Error = Error> {
|
pub fn inline() -> impl Parser<char, (), Error = Error> + Clone {
|
||||||
filter(|c: &char| c.is_whitespace() && *c != '\n')
|
filter(|c: &char| c.is_whitespace() && *c != '\n')
|
||||||
.repeated()
|
.repeated()
|
||||||
.to(())
|
.to(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn newline() -> impl Parser<char, (), Error = Error> {
|
pub fn newline() -> impl Parser<char, (), Error = Error> + Clone {
|
||||||
just('\n').to(())
|
just('\n').to(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn line() -> impl Parser<char, Line, Error = Error> {
|
pub fn line() -> impl Parser<char, Line, Error = Error> + Clone {
|
||||||
let empty = newline().to(Line::Empty);
|
let empty = newline().to(Line::Empty);
|
||||||
|
|
||||||
let comment = just('#')
|
let comment = just('#')
|
||||||
|
|
@ -32,7 +32,7 @@ pub fn line() -> impl Parser<char, Line, Error = Error> {
|
||||||
empty.or(comment)
|
empty.or(comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn space() -> impl Parser<char, Space, Error = Error> {
|
pub fn space() -> impl Parser<char, Space, Error = Error> + Clone {
|
||||||
inline()
|
inline()
|
||||||
.ignore_then(line())
|
.ignore_then(line())
|
||||||
.repeated()
|
.repeated()
|
||||||
|
|
@ -40,7 +40,7 @@ pub fn space() -> impl Parser<char, Space, Error = Error> {
|
||||||
.map_with_span(|lines, span| Space { lines, span })
|
.map_with_span(|lines, span| Space { lines, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ident() -> impl Parser<char, Ident, Error = Error> {
|
pub fn ident() -> impl Parser<char, Ident, Error = Error> + Clone {
|
||||||
text::ident().try_map(|name, span| {
|
text::ident().try_map(|name, span| {
|
||||||
if matches!(
|
if matches!(
|
||||||
&name as &str,
|
&name as &str,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::ast::Expr;
|
use crate::ast::{BinOp, Expr};
|
||||||
|
use crate::span::HasSpan;
|
||||||
|
|
||||||
use super::basic::{space, Error};
|
use super::basic::{space, Error};
|
||||||
use super::lit::lit;
|
use super::lit::lit;
|
||||||
|
|
@ -14,7 +15,7 @@ use super::var::var;
|
||||||
|
|
||||||
fn atom_paren(
|
fn atom_paren(
|
||||||
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> + Clone {
|
||||||
just('(')
|
just('(')
|
||||||
.ignore_then(space())
|
.ignore_then(space())
|
||||||
.then(expr)
|
.then(expr)
|
||||||
|
|
@ -30,7 +31,7 @@ fn atom_paren(
|
||||||
|
|
||||||
fn atom(
|
fn atom(
|
||||||
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> + Clone {
|
||||||
let lit = lit(expr.clone()).map(Expr::Lit);
|
let lit = lit(expr.clone()).map(Expr::Lit);
|
||||||
let var = var(expr.clone()).map(Expr::Var);
|
let var = var(expr.clone()).map(Expr::Var);
|
||||||
let table_constr = table_constr(expr.clone()).map(Expr::TableConstr);
|
let table_constr = table_constr(expr.clone()).map(Expr::TableConstr);
|
||||||
|
|
@ -41,8 +42,57 @@ fn atom(
|
||||||
prefixed(suffixed(base, expr))
|
prefixed(suffixed(base, expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn left_assoc(
|
||||||
|
op: impl Parser<char, BinOp, Error = Error> + Clone,
|
||||||
|
over: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
|
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
||||||
|
let op_over = space()
|
||||||
|
.then(op)
|
||||||
|
.then(space())
|
||||||
|
.then(over.clone())
|
||||||
|
.map(|(((s0, op), s1), right)| (s0, op, s1, right));
|
||||||
|
|
||||||
|
over.then(op_over.repeated())
|
||||||
|
.foldl(|left, (s0, op, s1, right)| Expr::BinOp {
|
||||||
|
span: left.span().join(right.span()),
|
||||||
|
left: Box::new(left),
|
||||||
|
s0,
|
||||||
|
op,
|
||||||
|
s1,
|
||||||
|
right: Box::new(right),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expr(
|
pub 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)
|
// * / %
|
||||||
|
let prec0 = (just('*').to(BinOp::Mul))
|
||||||
|
.or(just('/').to(BinOp::Div))
|
||||||
|
.or(just('%').to(BinOp::Mod));
|
||||||
|
|
||||||
|
// + -
|
||||||
|
let prec1 = (just('+').to(BinOp::Add)).or(just('-').to(BinOp::Sub));
|
||||||
|
|
||||||
|
// == != > >= < <=
|
||||||
|
let prec2 = (just("==").to(BinOp::Eq))
|
||||||
|
.or(just("!=").to(BinOp::Neq))
|
||||||
|
.or(just('>').to(BinOp::Gt))
|
||||||
|
.or(just(">=").to(BinOp::Ge))
|
||||||
|
.or(just('<').to(BinOp::Lt))
|
||||||
|
.or(just("<=").to(BinOp::Le));
|
||||||
|
|
||||||
|
// and
|
||||||
|
let prec3 = text::keyword("and").to(BinOp::And);
|
||||||
|
|
||||||
|
// or
|
||||||
|
let prec4 = text::keyword("or").to(BinOp::Or);
|
||||||
|
|
||||||
|
left_assoc(
|
||||||
|
prec4,
|
||||||
|
left_assoc(
|
||||||
|
prec3,
|
||||||
|
left_assoc(prec2, left_assoc(prec1, left_assoc(prec0, atom(expr)))),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use crate::builtin::Builtin;
|
||||||
|
|
||||||
use super::basic::{ident, space, Error};
|
use super::basic::{ident, space, Error};
|
||||||
|
|
||||||
fn builtin_lit() -> impl Parser<char, Builtin, Error = Error> {
|
fn builtin_lit() -> impl Parser<char, Builtin, Error = Error> + Clone {
|
||||||
just('\'').ignore_then(choice((
|
just('\'').ignore_then(choice((
|
||||||
text::keyword("get").to(Builtin::Get),
|
text::keyword("get").to(Builtin::Get),
|
||||||
text::keyword("set").to(Builtin::Set),
|
text::keyword("set").to(Builtin::Set),
|
||||||
|
|
@ -78,14 +78,14 @@ pub fn num_lit() -> impl Parser<char, NumLit, Error = Error> + Clone {
|
||||||
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn string_lit() -> impl Parser<char, StringLit, Error = Error> {
|
pub fn string_lit() -> impl Parser<char, StringLit, Error = Error> + Clone {
|
||||||
// TODO Parse string literals
|
// TODO Parse string literals
|
||||||
filter(|_| false).map(|_| unreachable!())
|
filter(|_| false).map(|_| unreachable!())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_lit_elem(
|
pub fn table_lit_elem(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, TableLitElem, Error = Error> {
|
) -> impl Parser<char, TableLitElem, Error = Error> + Clone {
|
||||||
let positional = expr
|
let positional = expr
|
||||||
.clone()
|
.clone()
|
||||||
.map(|value| TableLitElem::Positional(Box::new(value)));
|
.map(|value| TableLitElem::Positional(Box::new(value)));
|
||||||
|
|
@ -108,7 +108,7 @@ pub fn table_lit_elem(
|
||||||
|
|
||||||
pub fn table_lit(
|
pub fn table_lit(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, TableLit, Error = Error> {
|
) -> impl Parser<char, TableLit, Error = Error> + Clone {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_lit_elem(expr))
|
.then(table_lit_elem(expr))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -130,7 +130,7 @@ pub fn table_lit(
|
||||||
|
|
||||||
pub fn lit(
|
pub fn lit(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Lit, Error = Error> {
|
) -> impl Parser<char, Lit, Error = Error> + Clone {
|
||||||
let nil = text::keyword("nil").map_with_span(|_, span| Lit::Nil(span));
|
let nil = text::keyword("nil").map_with_span(|_, span| Lit::Nil(span));
|
||||||
let r#true = text::keyword("true").map_with_span(|_, span| Lit::Bool(true, span));
|
let r#true = text::keyword("true").map_with_span(|_, span| Lit::Bool(true, span));
|
||||||
let r#false = text::keyword("false").map_with_span(|_, span| Lit::Bool(false, span));
|
let r#false = text::keyword("false").map_with_span(|_, span| Lit::Bool(false, span));
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,14 @@ impl Prefix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_neg() -> impl Parser<char, Prefix, Error = Error> {
|
fn prefix_neg() -> impl Parser<char, Prefix, Error = Error> + Clone {
|
||||||
just('-')
|
just('-')
|
||||||
.map_with_span(|_, span| span)
|
.map_with_span(|_, span| span)
|
||||||
.then(space())
|
.then(space())
|
||||||
.map(|(minus, s0)| Prefix::Neg { minus, s0 })
|
.map(|(minus, s0)| Prefix::Neg { minus, s0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prefix_not() -> impl Parser<char, Prefix, Error = Error> {
|
fn prefix_not() -> impl Parser<char, Prefix, Error = Error> + Clone {
|
||||||
text::keyword("not")
|
text::keyword("not")
|
||||||
.map_with_span(|_, span| span)
|
.map_with_span(|_, span| span)
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -50,8 +50,8 @@ fn prefix_not() -> impl Parser<char, Prefix, Error = Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prefixed(
|
pub fn prefixed(
|
||||||
suffixed: impl Parser<char, Expr, Error = Error>,
|
suffixed: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Expr, Error = Error> {
|
) -> impl Parser<char, Expr, Error = Error> + Clone {
|
||||||
let prefix = prefix_neg()
|
let prefix = prefix_neg()
|
||||||
.or(prefix_not())
|
.or(prefix_not())
|
||||||
.map_with_span(|prefix, span| (prefix, span));
|
.map_with_span(|prefix, span| (prefix, span));
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,8 @@ impl Suffix {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suffix_call_arg(
|
fn suffix_call_arg(
|
||||||
expr: impl Parser<char, Expr, Error = Error>,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Suffix, Error = Error> {
|
) -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('('))
|
.then_ignore(just('('))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -147,7 +147,7 @@ fn suffix_call_arg(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suffix_call_no_arg() -> impl Parser<char, Suffix, Error = Error> {
|
fn suffix_call_no_arg() -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('('))
|
.then_ignore(just('('))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -157,7 +157,7 @@ fn suffix_call_no_arg() -> impl Parser<char, Suffix, Error = Error> {
|
||||||
|
|
||||||
fn suffix_call_constr(
|
fn suffix_call_constr(
|
||||||
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> + Clone {
|
||||||
space()
|
space()
|
||||||
.then(table_constr(expr))
|
.then(table_constr(expr))
|
||||||
.map(|(s0, constr)| Suffix::CallConstr { s0, constr })
|
.map(|(s0, constr)| Suffix::CallConstr { s0, constr })
|
||||||
|
|
@ -165,7 +165,7 @@ fn suffix_call_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> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('['))
|
.then_ignore(just('['))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -182,7 +182,7 @@ fn suffix_field_access(
|
||||||
|
|
||||||
fn suffix_field_assign(
|
fn suffix_field_assign(
|
||||||
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> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('['))
|
.then_ignore(just('['))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -206,7 +206,7 @@ fn suffix_field_assign(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suffix_field_access_ident() -> impl Parser<char, Suffix, Error = Error> {
|
fn suffix_field_access_ident() -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('.'))
|
.then_ignore(just('.'))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -215,8 +215,8 @@ fn suffix_field_access_ident() -> impl Parser<char, Suffix, Error = Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suffix_field_assign_ident(
|
fn suffix_field_assign_ident(
|
||||||
expr: impl Parser<char, Expr, Error = Error>,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Suffix, Error = Error> {
|
) -> impl Parser<char, Suffix, Error = Error> + Clone {
|
||||||
space()
|
space()
|
||||||
.then_ignore(just('.'))
|
.then_ignore(just('.'))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -238,9 +238,9 @@ fn suffix_field_assign_ident(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn suffixed(
|
pub fn suffixed(
|
||||||
atom: impl Parser<char, Expr, Error = Error>,
|
atom: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
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> + Clone {
|
||||||
let call_arg = suffix_call_arg(expr.clone());
|
let call_arg = suffix_call_arg(expr.clone());
|
||||||
let call_no_arg = suffix_call_no_arg();
|
let call_no_arg = suffix_call_no_arg();
|
||||||
let call_constr = suffix_call_constr(expr.clone());
|
let call_constr = suffix_call_constr(expr.clone());
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use super::lit::table_lit_elem;
|
||||||
|
|
||||||
pub fn table_constr_elem(
|
pub fn table_constr_elem(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, TableConstrElem, Error = Error> {
|
) -> impl Parser<char, TableConstrElem, Error = Error> + Clone {
|
||||||
let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit);
|
let lit = table_lit_elem(expr.clone()).map(TableConstrElem::Lit);
|
||||||
|
|
||||||
let indexed = just('[')
|
let indexed = just('[')
|
||||||
|
|
@ -38,7 +38,7 @@ pub fn table_constr_elem(
|
||||||
|
|
||||||
pub fn table_constr(
|
pub fn table_constr(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, TableConstr, Error = Error> {
|
) -> impl Parser<char, TableConstr, Error = Error> + Clone {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_constr_elem(expr))
|
.then(table_constr_elem(expr))
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::ast::{Expr, TableDestr, TablePattern, TablePatternElem};
|
||||||
|
|
||||||
use super::basic::{ident, space, Error};
|
use super::basic::{ident, space, Error};
|
||||||
|
|
||||||
pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error> {
|
pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error> + Clone {
|
||||||
let positional = ident().map(TablePatternElem::Positional);
|
let positional = ident().map(TablePatternElem::Positional);
|
||||||
|
|
||||||
let named = ident()
|
let named = ident()
|
||||||
|
|
@ -25,7 +25,7 @@ pub fn table_pattern_elem() -> impl Parser<char, TablePatternElem, Error = Error
|
||||||
named.or(positional)
|
named.or(positional)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> {
|
pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> + Clone {
|
||||||
let elem = space()
|
let elem = space()
|
||||||
.then(table_pattern_elem())
|
.then(table_pattern_elem())
|
||||||
.then(space())
|
.then(space())
|
||||||
|
|
@ -46,8 +46,8 @@ pub fn table_pattern() -> impl Parser<char, TablePattern, Error = Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_destr(
|
pub fn table_destr(
|
||||||
expr: impl Parser<char, Expr, Error = Error>,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, TableDestr, Error = Error> {
|
) -> impl Parser<char, TableDestr, Error = Error> + Clone {
|
||||||
let local = text::keyword("local").ignore_then(space()).or_not();
|
let local = text::keyword("local").ignore_then(space()).or_not();
|
||||||
|
|
||||||
local
|
local
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use super::basic::{ident, space, Error};
|
||||||
|
|
||||||
fn var_access(
|
fn var_access(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Var, Error = Error> {
|
) -> impl Parser<char, Var, Error = Error> + Clone {
|
||||||
just('[')
|
just('[')
|
||||||
.ignore_then(space())
|
.ignore_then(space())
|
||||||
.then(expr)
|
.then(expr)
|
||||||
|
|
@ -24,7 +24,7 @@ fn var_access(
|
||||||
|
|
||||||
fn var_assign(
|
fn var_assign(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Var, Error = Error> {
|
) -> impl Parser<char, Var, Error = Error> + Clone {
|
||||||
let local = text::keyword("local").ignore_then(space()).or_not();
|
let local = text::keyword("local").ignore_then(space()).or_not();
|
||||||
|
|
||||||
local
|
local
|
||||||
|
|
@ -53,7 +53,7 @@ fn var_assign(
|
||||||
|
|
||||||
fn var_assign_ident(
|
fn var_assign_ident(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Var, Error = Error> {
|
) -> impl Parser<char, Var, Error = Error> + Clone {
|
||||||
let local = text::keyword("local").ignore_then(space()).or_not();
|
let local = text::keyword("local").ignore_then(space()).or_not();
|
||||||
|
|
||||||
local
|
local
|
||||||
|
|
@ -76,7 +76,7 @@ fn var_assign_ident(
|
||||||
|
|
||||||
pub fn var(
|
pub fn var(
|
||||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||||
) -> impl Parser<char, Var, Error = Error> {
|
) -> impl Parser<char, Var, Error = Error> + Clone {
|
||||||
let access = var_access(expr.clone());
|
let access = var_access(expr.clone());
|
||||||
let assign = var_assign(expr.clone());
|
let assign = var_assign(expr.clone());
|
||||||
let access_ident = ident().map(Var::AccessIdent);
|
let access_ident = ident().map(Var::AccessIdent);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue