add access syntax
This commit is contained in:
parent
79c3113689
commit
b06f2f052f
3 changed files with 90 additions and 6 deletions
|
|
@ -72,6 +72,8 @@ pub enum Ast {
|
|||
Num(f64),
|
||||
/// `(println bla; 3) #=> 3`
|
||||
Block(Vec<Ast>),
|
||||
/// `std.println`
|
||||
Access(Box<Ast>, Symbol),
|
||||
}
|
||||
|
||||
impl fmt::Display for Ast {
|
||||
|
|
@ -108,6 +110,9 @@ impl fmt::Display for Ast {
|
|||
let body: Vec<_> = body.iter().map(|stmt| format!("{stmt}")).collect();
|
||||
write!(f, "({})", body.join(" "))
|
||||
}
|
||||
Ast::Access(val, sym) => {
|
||||
write!(f, "{val}.{sym}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ enum Token<'a> {
|
|||
#[token(":")]
|
||||
Colon,
|
||||
|
||||
#[token(".")]
|
||||
Period,
|
||||
|
||||
#[token(",")]
|
||||
Comma,
|
||||
|
||||
|
|
@ -64,6 +67,7 @@ impl fmt::Display for Token<'_> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Token::Colon => write!(f, ":"),
|
||||
Token::Period => write!(f, "."),
|
||||
Token::Comma => write!(f, ","),
|
||||
Token::Semicolon => write!(f, ";"),
|
||||
Token::Set => write!(f, ":="),
|
||||
|
|
@ -99,6 +103,8 @@ where
|
|||
recursive(|expr| {
|
||||
let expr = expr.labelled("expression");
|
||||
|
||||
let symbol = select! { Token::Var(s) => s.to_owned() };
|
||||
|
||||
let ident = choice((
|
||||
just(Token::Return)
|
||||
.ignore_then(select! {
|
||||
|
|
@ -194,7 +200,7 @@ where
|
|||
})
|
||||
.labelled("standalone function");
|
||||
|
||||
let non_app = choice((
|
||||
let e1 = choice((
|
||||
set,
|
||||
num,
|
||||
standalone_func,
|
||||
|
|
@ -202,18 +208,28 @@ where
|
|||
ident.map(Ast::Var).labelled("variable"),
|
||||
map,
|
||||
block.map(Ast::Block),
|
||||
));
|
||||
))
|
||||
.boxed();
|
||||
|
||||
let app = non_app
|
||||
let access = e1
|
||||
.clone()
|
||||
.foldl(non_app.clone().repeated(), |f, x| {
|
||||
.then_ignore(just(Token::Period))
|
||||
.foldl(symbol.separated_by(just(Token::Period)), |a, b| {
|
||||
Ast::Access(Box::new(a), b)
|
||||
})
|
||||
.labelled("access");
|
||||
|
||||
let e2 = access.or(e1);
|
||||
|
||||
let app = e2
|
||||
.clone()
|
||||
.foldl(e2.clone().repeated(), |f, x| {
|
||||
Ast::App(Box::new(f), Box::new(x))
|
||||
})
|
||||
.labelled("function application");
|
||||
|
||||
let atom = app.or(non_app);
|
||||
let atom = app.or(e2);
|
||||
|
||||
// %
|
||||
atom.pratt((
|
||||
infix(none(1), just(Token::BinOp("=")), |l, _, r, _| {
|
||||
Ast::BinOp(Box::new(l), BinOp::Eq, Box::new(r))
|
||||
|
|
|
|||
|
|
@ -134,3 +134,66 @@ foo := 3;
|
|||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oop() {
|
||||
test(
|
||||
"
|
||||
fn make_counter([] [obj]) (
|
||||
i := 0;
|
||||
{
|
||||
fn ^inc() (
|
||||
i := i + 1;
|
||||
);
|
||||
|
||||
fn ^dec() (
|
||||
i := i - 1;
|
||||
);
|
||||
|
||||
fn ^get([] [i]) ();
|
||||
}
|
||||
);
|
||||
|
||||
counter_a := make_counter {};
|
||||
counter_b := make_counter {};
|
||||
|
||||
counter_a.inc {};
|
||||
std.println(counter_a.get {});
|
||||
counter_a.inc {};
|
||||
std.println(counter_a.get {});
|
||||
counter_a.inc {};
|
||||
std.println(counter_a.get {});
|
||||
counter_a.dec {};
|
||||
std.println(counter_a.get {});
|
||||
|
||||
counter_b.inc {};
|
||||
std.println(counter_b.get {});
|
||||
counter_b.dec {};
|
||||
",
|
||||
"
|
||||
(set! make_counter \
|
||||
(fn ([] [obj]) \
|
||||
(set! i 0) \
|
||||
{\
|
||||
(set! ^inc (fn ([] []) (set! i (i + 1)))) \
|
||||
(set! ^dec (fn ([] []) (set! i (i - 1)))) \
|
||||
(set! ^get (fn ([] [i])))\
|
||||
}\
|
||||
)\
|
||||
);
|
||||
(set! counter_a (make_counter {}));
|
||||
(set! counter_b (make_counter {}));
|
||||
(counter_a.inc {});
|
||||
(std.println ((counter_a.get {})));
|
||||
(counter_a.inc {});
|
||||
(std.println ((counter_a.get {})));
|
||||
(counter_a.inc {});
|
||||
(std.println ((counter_a.get {})));
|
||||
(counter_a.dec {});
|
||||
(std.println ((counter_a.get {})));
|
||||
(counter_b.inc {});
|
||||
(std.println ((counter_b.get {})));
|
||||
(counter_b.dec {})
|
||||
",
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue