preliminary bang syntax

This commit is contained in:
mehbark 2026-01-07 10:17:31 -05:00
parent 67e79b18a8
commit d19c33680c
3 changed files with 65 additions and 3 deletions

View file

@ -0,0 +1,24 @@
fn make_counter([] [inc]) (
i := 0;
fn ^inc([] [i]) (
i := i + 1;
^i := i;
);
);
a := make_counter!;
b := make_counter!;
put 65; put 10;
println {^a}.a.inc!;
println a.inc!;
println a.inc!;
put 66; put 10;
println (b.inc!).i;
println (b.inc!).i;
println (b.inc!).i;
# TODO: comments at eof don't parse
println 42;

View file

@ -15,6 +15,9 @@ use logos::Logos;
#[logos(skip r"[ \t\n\r\f]+")]
#[logos(skip r"#[^\n]*?\n")]
enum Token<'a> {
#[token("!")]
Bang,
#[token(":")]
Colon,
@ -66,6 +69,7 @@ enum Token<'a> {
impl fmt::Display for Token<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Token::Bang => write!(f, "!"),
Token::Colon => write!(f, ":"),
Token::Period => write!(f, "."),
Token::Comma => write!(f, ","),
@ -234,14 +238,20 @@ where
let e2 = access.or(e1);
let app = e2
let bang = e2.clone().foldl(just(Token::Bang).repeated(), |thunk, _| {
Ast::App(Box::new(thunk), Box::new(Ast::Block(vec![])))
});
let e3 = bang.or(e2);
let app = e3
.clone()
.foldl(e2.clone().repeated(), |f, x| {
.foldl(e3.clone().repeated(), |f, x| {
Ast::App(Box::new(f), Box::new(x))
})
.labelled("function application");
let atom = app.or(e2);
let atom = app.or(e3);
atom.pratt((
infix(none(1), just(Token::BinOp("=")), |l, _, r, _| {

View file

@ -215,3 +215,31 @@ if [wow = cool]() [
",
);
}
#[test]
fn bang() {
test(
"
a := make_counter!;
b := make_counter!;
println {^a}.a.inc!;
println a.inc!;
println a.inc!;
println b.inc!;
println b.inc!;
println b.inc!;
",
"
(set! a (make_counter ()));
(set! b (make_counter ()));
(println ({^a}.a.inc ()));
(println (a.inc ()));
(println (a.inc ()));
(println (b.inc ()));
(println (b.inc ()));
(println (b.inc ()))
",
);
}