preliminary bang syntax
This commit is contained in:
parent
67e79b18a8
commit
d19c33680c
3 changed files with 65 additions and 3 deletions
24
examples/make_counter.puyo
Normal file
24
examples/make_counter.puyo
Normal 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;
|
||||
|
|
@ -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, _| {
|
||||
|
|
|
|||
|
|
@ -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 ()))
|
||||
",
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue