~remexre/stahl

a3465faae7c2fda2797cf888dc874b159ddf582b — Nathan Ringo 6 days ago 1d7f2a0
Adds $ form to explicitly specify application.
2 files changed, 22 insertions(+), 10 deletions(-)

M lang/prelude.stahl
M langbs/driver/src/compiler/expr_form.rs
M lang/prelude.stahl => lang/prelude.stahl +1 -1
@@ 18,6 18,6 @@
(def the (pi ((a type) (x a)) a)
     (fn (a x) x))

(check (the unit <>))
(check ($ the unit <>))

; vi: set ft=lisp :

M langbs/driver/src/compiler/expr_form.rs => langbs/driver/src/compiler/expr_form.rs +21 -9
@@ 54,6 54,7 @@ pub enum ExprForm<'a> {
impl<'a> ExprForm<'a> {
    pub fn parse<'b>(arena: &'a Bump, sexpr: Sexpr<'b>) -> Result<ExprForm<'a>> {
        let head_syms = [
            *SYM_APP,
            *SYM_CAR,
            *SYM_CDR,
            *SYM_CONS,


@@ 67,20 68,31 @@ impl<'a> ExprForm<'a> {
        ];
        match sexpr.ensure_shl_oneof(&head_syms) {
            Ok((0, tail)) => match *tail {
                [func, ref args @ ..] => {
                    let mut out = ExprForm::parse(arena, func)?;
                    for arg in args.iter().copied() {
                        let arg = ExprForm::parse(arena, arg)?;
                        out = ExprForm::App(arena.alloc(out), arena.alloc(arg), sexpr.span());
                    }
                    Ok(out)
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "($ EXPRS+)").into()),
            },
            Ok((1, tail)) => match *tail {
                [expr] => {
                    let expr = ExprForm::parse(arena, expr)?;
                    Ok(ExprForm::Car(arena.alloc(expr), sexpr.span()))
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(car EXPR)").into()),
            },
            Ok((1, tail)) => match *tail {
            Ok((2, tail)) => match *tail {
                [expr] => {
                    let expr = ExprForm::parse(arena, expr)?;
                    Ok(ExprForm::Cdr(arena.alloc(expr), sexpr.span()))
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(cdr EXPR)").into()),
            },
            Ok((2, tail)) => match *tail {
            Ok((3, tail)) => match *tail {
                [a, d] => {
                    let a = ExprForm::parse(arena, a)?;
                    let d = ExprForm::parse(arena, d)?;


@@ 88,7 100,7 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(cons A D)").into()),
            },
            Ok((3, tail)) => match *tail {
            Ok((4, tail)) => match *tail {
                [args, body] => {
                    let (implicits, explicits) = split_arg_list(args.ensure_list()?)?;
                    let mut out = ExprForm::parse(arena, body)?;


@@ 112,7 124,7 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(fn ARGS BODY)").into()),
            },
            Ok((4, tail)) => match *tail {
            Ok((5, tail)) => match *tail {
                [args, body] => {
                    let (implicit_forms, explicit_forms) = split_arg_list(args.ensure_list()?)?;
                    let mut implicits = parse_arg_type_pairs(arena, implicit_forms)?;


@@ 140,7 152,7 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(pi ARGS BODY)").into()),
            },
            Ok((5, tail)) => match *tail {
            Ok((6, tail)) => match *tail {
                [args, body] => {
                    let mut args = parse_arg_type_pairs(arena, args.ensure_list()?)?;
                    let mut out = ExprForm::parse(arena, body)?;


@@ 151,7 163,7 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(sigma ARGS BODY)").into()),
            },
            Ok((6, tail)) => match *tail {
            Ok((7, tail)) => match *tail {
                [ref init @ .., fini] => {
                    let mut out = ExprForm::parse(arena, fini)?;
                    for arg in init.iter().rev().copied() {


@@ 162,7 174,7 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(tuple EXPRS+)").into()),
            },
            Ok((7, tail)) => match *tail {
            Ok((8, tail)) => match *tail {
                [Sexpr::Int(n, span)] => match n.try_into() {
                    Ok(n) => Ok(ExprForm::Uni(Level::Fin(n, span), sexpr.span())),
                    Err(err) => Err(ErrorKind::InvalidUniverseLevel(sexpr.leak(), err).into()),


@@ 172,11 184,11 @@ impl<'a> ExprForm<'a> {
                }
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(type LEVEL)").into()),
            },
            Ok((8, tail)) => match *tail {
            Ok((9, tail)) => match *tail {
                [] => Ok(ExprForm::UnitCtor(sexpr.span())),
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(%<>)").into()),
            },
            Ok((9, tail)) => match *tail {
            Ok((10, tail)) => match *tail {
                [] => Ok(ExprForm::UnitType(sexpr.span())),
                _ => Err(ErrorKind::InvalidForm(sexpr.leak(), "(%unit)").into()),
            },