implement comments

This commit is contained in:
Matthieu Jolimaitre 2024-10-25 14:33:55 +02:00
parent 7febf91d3c
commit d3095d5980
2 changed files with 50 additions and 23 deletions

View file

@ -6,8 +6,8 @@ use libm::floor;
use crate::{util::Boxable, Context, EvalError, FunImpl, Function, Value};
use chumsky::{
error::Simple,
prelude::{end, just, none_of, one_of, recursive, Recursive},
text::TextParser,
prelude::{end, filter, just, none_of, one_of, recursive, Recursive},
text::whitespace,
Parser,
};
use hashbrown::HashMap;
@ -17,8 +17,23 @@ extern crate alloc;
pub trait Parse<O>: Parser<char, O, Error = Simple<char>> + Clone + 'static {}
impl<T: Parser<char, O, Error = Simple<char>> + Clone + 'static, O> Parse<O> for T {}
fn pad<O: 'static>(parser: impl Parse<O>) -> impl Parse<O> {
let comment = just("//")
.ignore_then(none_of("\n").repeated())
.ignore_then(just("\n"))
.ignored();
let padding = filter(|c| char::is_whitespace(*c))
.ignored()
.or(comment)
.repeated()
.ignored()
.or(whitespace().ignored());
padding.clone().ignore_then(parser).then_ignore(padding)
}
fn lx(word: &'static str) -> impl Parse<&'static str> {
just(word).padded().labelled("token")
pad(just(word)).labelled("token")
}
fn id() -> impl Parse<String> {
@ -82,8 +97,8 @@ pub struct FunDef {
impl FunDef {
pub fn parser_def(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<(String, Self)> {
let arguments = id().padded().separated_by(lx(","));
(lx("fn").ignore_then(id().padded()))
let arguments = pad(id()).separated_by(lx(","));
(lx("fn").ignore_then(pad(id())))
.then(lx("(").ignore_then(arguments).then_ignore(lx(")")))
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
.map(|((id, args), body)| (id, Self { args, body }))
@ -91,7 +106,7 @@ impl FunDef {
}
pub fn parser_lamb(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<Self> {
let arguments = id().padded().separated_by(lx(","));
let arguments = pad(id()).separated_by(lx(","));
(lx("(").ignore_then(arguments).then_ignore(lx(")")))
.then_ignore(lx("=>"))
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
@ -248,31 +263,41 @@ pub enum Expr {
impl Expr {
pub fn parser(instr: impl Parse<Instr>) -> impl Parse<Self> {
recursive(|expr: Recursive<'_, _, Self, _>| {
let left = (Litteral::parser(instr, expr.clone()).map(Self::Litteral))
let atom = (Litteral::parser(instr, expr.clone()).map(Self::Litteral))
.or((lx("(").ignore_then(expr.clone()).then_ignore(lx(")"))).map(|e| Self::Parens(e.to_box())))
.or((UniOp::parser().then(expr.clone())).map(|(o, e)| Self::UniOp(o, e.to_box())))
.or(id().map(Self::Var).padded());
.or(pad(id()).map(Self::Var));
(left
let call = atom
.clone()
.then(Op::parser().then(expr.clone()).repeated().at_least(1)))
.map(|(f, o)| Self::BinOps(f.to_box(), o))
.or((left.clone())
.then_ignore(lx("."))
.then(id().padded())
.map(|(e, a)| Self::Access(e.to_box(), a)))
.or((left.clone())
.then_ignore(lx("("))
.then(expr.clone().separated_by(lx(",")))
.then_ignore(lx(")"))
.map(|(e, a)| Self::Call(e.to_box(), a)))
.or((left.clone())
.map(|(e, a)| Self::Call(e.to_box(), a))
.or(atom);
let index = call
.clone()
.then_ignore(lx("["))
.then(expr.clone())
.then_ignore(lx("]"))
.map(|(e, i)| Self::Index(e.to_box(), i.to_box())))
.or(left)
.labelled("expression")
.map(|(e, i)| Self::Index(e.to_box(), i.to_box()))
.or(call);
let access = index
.clone()
.then_ignore(lx("."))
.then(pad(id()))
.map(|(e, a)| Self::Access(e.to_box(), a))
.or(index);
let ops = access
.clone()
.then(Op::parser().then(expr.clone()).repeated().at_least(1))
.map(|(f, o)| Self::BinOps(f.to_box(), o))
.or(access);
ops.labelled("expression")
})
}