Create each main parser only once
This commit is contained in:
parent
b291619d10
commit
ea7518b183
10 changed files with 346 additions and 222 deletions
|
|
@ -2,17 +2,15 @@
|
|||
|
||||
use chumsky::prelude::*;
|
||||
|
||||
use crate::ast::{Expr, Var};
|
||||
use crate::ast::{Expr, Ident, Space, Var};
|
||||
|
||||
use super::basic::{ident, local, space, Error};
|
||||
use super::basic::{EParser, Error};
|
||||
|
||||
fn var_access(
|
||||
expr: impl Parser<char, Expr, Error = Error>,
|
||||
) -> impl Parser<char, Var, Error = Error> {
|
||||
fn var_access(space: EParser<Space>, expr: EParser<Expr>) -> impl Parser<char, Var, Error = Error> {
|
||||
just('[')
|
||||
.ignore_then(space())
|
||||
.ignore_then(space.clone())
|
||||
.then(expr)
|
||||
.then(space())
|
||||
.then(space)
|
||||
.then_ignore(just(']'))
|
||||
.map_with_span(|((s0, index), s1), span| Var::Access {
|
||||
s0,
|
||||
|
|
@ -23,17 +21,19 @@ fn var_access(
|
|||
}
|
||||
|
||||
fn var_assign(
|
||||
expr: impl Parser<char, Expr, Error = Error> + Clone,
|
||||
space: EParser<Space>,
|
||||
local: EParser<Option<Space>>,
|
||||
expr: EParser<Expr>,
|
||||
) -> impl Parser<char, Var, Error = Error> {
|
||||
local()
|
||||
local
|
||||
.then_ignore(just('['))
|
||||
.then(space())
|
||||
.then(space.clone())
|
||||
.then(expr.clone())
|
||||
.then(space())
|
||||
.then(space.clone())
|
||||
.then_ignore(just(']'))
|
||||
.then(space())
|
||||
.then(space.clone())
|
||||
.then_ignore(just('='))
|
||||
.then(space())
|
||||
.then(space)
|
||||
.then(expr)
|
||||
.map_with_span(
|
||||
|((((((local, s0), index), s1), s2), s3), value), span| Var::Assign {
|
||||
|
|
@ -50,13 +50,16 @@ fn var_assign(
|
|||
}
|
||||
|
||||
fn var_assign_ident(
|
||||
expr: impl Parser<char, Expr, Error = Error>,
|
||||
space: EParser<Space>,
|
||||
ident: EParser<Ident>,
|
||||
local: EParser<Option<Space>>,
|
||||
expr: EParser<Expr>,
|
||||
) -> impl Parser<char, Var, Error = Error> {
|
||||
local()
|
||||
.then(ident())
|
||||
.then(space())
|
||||
local
|
||||
.then(ident)
|
||||
.then(space.clone())
|
||||
.then_ignore(just('='))
|
||||
.then(space())
|
||||
.then(space)
|
||||
.then(expr)
|
||||
.map_with_span(
|
||||
|((((local, name), s0), s1), value), span| Var::AssignIdent {
|
||||
|
|
@ -71,12 +74,15 @@ fn var_assign_ident(
|
|||
}
|
||||
|
||||
pub fn var(
|
||||
expr: impl Parser<char, Expr, Error = Error> + Clone + 'static,
|
||||
) -> BoxedParser<'static, char, Var, Error> {
|
||||
let access = var_access(expr.clone());
|
||||
let assign = var_assign(expr.clone());
|
||||
let access_ident = ident().map(Var::AccessIdent);
|
||||
let assign_ident = var_assign_ident(expr);
|
||||
space: EParser<Space>,
|
||||
ident: EParser<Ident>,
|
||||
local: EParser<Option<Space>>,
|
||||
expr: EParser<Expr>,
|
||||
) -> EParser<Var> {
|
||||
let access = var_access(space.clone(), expr.clone());
|
||||
let assign = var_assign(space.clone(), local.clone(), expr.clone());
|
||||
let access_ident = ident.clone().map(Var::AccessIdent);
|
||||
let assign_ident = var_assign_ident(space, ident, local, expr);
|
||||
|
||||
assign.or(access).or(assign_ident).or(access_ident).boxed()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue