Split up parser

The structure mostly follows the ast structure, with some slight
changes. Each parser submodule documents which ast submodule it
corresponds to.

This parser is not yet complete, and I have yet to go through its
modules one-by-one to fix and complete them.
This commit is contained in:
Joscha 2022-11-18 20:20:37 +01:00
parent 037a0f69a3
commit a559966c1d
7 changed files with 511 additions and 419 deletions

86
src/parser/var.rs Normal file
View file

@ -0,0 +1,86 @@
//! Corresponds to `ast::var`.
use chumsky::prelude::*;
use crate::ast::{Expr, Var};
use super::basic::{ident, space, Error};
fn var_access(
expr: impl Parser<char, Expr, Error = Error> + Clone,
) -> impl Parser<char, Var, Error = Error> {
just("[")
.ignore_then(space())
.then(expr)
.then(space())
.then_ignore(just("]"))
.map_with_span(|((s0, index), s1), span| Var::Access {
s0,
index: Box::new(index),
s1,
span,
})
}
fn var_assign(
expr: impl Parser<char, Expr, Error = Error> + Clone,
) -> impl Parser<char, Var, Error = Error> {
let local = text::keyword("local").ignore_then(space()).or_not();
local
.then_ignore(just("["))
.then(space())
.then(expr.clone())
.then(space())
.then_ignore(just("]"))
.then(space())
.then_ignore(just("="))
.then(space())
.then(expr)
.map_with_span(
|((((((local, s0), index), s1), s2), s3), value), span| Var::Assign {
local,
s0,
index: Box::new(index),
s1,
s2,
s3,
value: Box::new(value),
span,
},
)
}
fn var_assign_ident(
expr: impl Parser<char, Expr, Error = Error> + Clone,
) -> impl Parser<char, Var, Error = Error> {
let local = text::keyword("local").ignore_then(space()).or_not();
local
.then(ident())
.then(space())
.then_ignore(just("="))
.then(space())
.then(expr)
.map_with_span(
|((((local, name), s0), s1), value), span| Var::AssignIdent {
local,
name,
s0,
s1,
value: Box::new(value),
span,
},
)
}
pub fn var(
expr: impl Parser<char, Expr, Error = Error> + Clone,
) -> impl Parser<char, Var, Error = 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);
assign.or(access).or(assign_ident).or(access_ident)
}