implement comments
This commit is contained in:
parent
7febf91d3c
commit
d3095d5980
2 changed files with 50 additions and 23 deletions
|
@ -1,7 +1,9 @@
|
||||||
|
|
||||||
|
// recursion
|
||||||
fn fibo(n) {
|
fn fibo(n) {
|
||||||
if (n < 1) return n;
|
if (n <= 0) return 0;
|
||||||
|
if (n <= 1) return 1;
|
||||||
return fibo(n - 1) + fibo(n - 2);
|
return fibo(n - 1) + fibo(n - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
fibo(3)
|
fibo(10)
|
||||||
|
|
67
src/ast.rs
67
src/ast.rs
|
@ -6,8 +6,8 @@ use libm::floor;
|
||||||
use crate::{util::Boxable, Context, EvalError, FunImpl, Function, Value};
|
use crate::{util::Boxable, Context, EvalError, FunImpl, Function, Value};
|
||||||
use chumsky::{
|
use chumsky::{
|
||||||
error::Simple,
|
error::Simple,
|
||||||
prelude::{end, just, none_of, one_of, recursive, Recursive},
|
prelude::{end, filter, just, none_of, one_of, recursive, Recursive},
|
||||||
text::TextParser,
|
text::whitespace,
|
||||||
Parser,
|
Parser,
|
||||||
};
|
};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
@ -17,8 +17,23 @@ extern crate alloc;
|
||||||
pub trait Parse<O>: Parser<char, O, Error = Simple<char>> + Clone + 'static {}
|
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 {}
|
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> {
|
fn lx(word: &'static str) -> impl Parse<&'static str> {
|
||||||
just(word).padded().labelled("token")
|
pad(just(word)).labelled("token")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id() -> impl Parse<String> {
|
fn id() -> impl Parse<String> {
|
||||||
|
@ -82,8 +97,8 @@ pub struct FunDef {
|
||||||
|
|
||||||
impl FunDef {
|
impl FunDef {
|
||||||
pub fn parser_def(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<(String, Self)> {
|
pub fn parser_def(instr: impl Parse<Instr>, expr: impl Parse<Expr>) -> impl Parse<(String, Self)> {
|
||||||
let arguments = id().padded().separated_by(lx(","));
|
let arguments = pad(id()).separated_by(lx(","));
|
||||||
(lx("fn").ignore_then(id().padded()))
|
(lx("fn").ignore_then(pad(id())))
|
||||||
.then(lx("(").ignore_then(arguments).then_ignore(lx(")")))
|
.then(lx("(").ignore_then(arguments).then_ignore(lx(")")))
|
||||||
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
|
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
|
||||||
.map(|((id, args), body)| (id, Self { args, body }))
|
.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> {
|
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(")")))
|
(lx("(").ignore_then(arguments).then_ignore(lx(")")))
|
||||||
.then_ignore(lx("=>"))
|
.then_ignore(lx("=>"))
|
||||||
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
|
.then(lx("{").ignore_then(Block::parser(instr, expr)).then_ignore(lx("}")))
|
||||||
|
@ -248,31 +263,41 @@ pub enum Expr {
|
||||||
impl Expr {
|
impl Expr {
|
||||||
pub fn parser(instr: impl Parse<Instr>) -> impl Parse<Self> {
|
pub fn parser(instr: impl Parse<Instr>) -> impl Parse<Self> {
|
||||||
recursive(|expr: Recursive<'_, _, 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((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((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()
|
.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_ignore(lx("("))
|
||||||
.then(expr.clone().separated_by(lx(",")))
|
.then(expr.clone().separated_by(lx(",")))
|
||||||
.then_ignore(lx(")"))
|
.then_ignore(lx(")"))
|
||||||
.map(|(e, a)| Self::Call(e.to_box(), a)))
|
.map(|(e, a)| Self::Call(e.to_box(), a))
|
||||||
.or((left.clone())
|
.or(atom);
|
||||||
|
|
||||||
|
let index = call
|
||||||
|
.clone()
|
||||||
.then_ignore(lx("["))
|
.then_ignore(lx("["))
|
||||||
.then(expr.clone())
|
.then(expr.clone())
|
||||||
.then_ignore(lx("]"))
|
.then_ignore(lx("]"))
|
||||||
.map(|(e, i)| Self::Index(e.to_box(), i.to_box())))
|
.map(|(e, i)| Self::Index(e.to_box(), i.to_box()))
|
||||||
.or(left)
|
.or(call);
|
||||||
.labelled("expression")
|
|
||||||
|
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")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue