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