Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/willcrichton/rabbot
Abstract binding tree code generator
https://github.com/willcrichton/rabbot
Last synced: 2 months ago
JSON representation
Abstract binding tree code generator
- Host: GitHub
- URL: https://github.com/willcrichton/rabbot
- Owner: willcrichton
- Created: 2016-08-23T22:20:02.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2016-10-31T02:09:12.000Z (about 8 years ago)
- Last Synced: 2024-09-13T09:45:23.644Z (3 months ago)
- Language: Rust
- Homepage:
- Size: 26.4 KB
- Stars: 36
- Watchers: 4
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# rabbot
Rabbot generates interfaces to abstract binding trees (ABTs). It is a port of SML's [Abbot](https://github.com/robsimmons/abbot) to Rust.
## What is an ABT?
An abstract binding tree is a data structure similar to an abstract syntax tree, except that it lets you pleasantly and correctly handle the declaration and binding of symbols. To motivate this, let's consider a syntax tree for a simple pseudo-language. For the expression `2 + 1`, this would produce a syntax tree `Plus(Number(2), Number(1))`. For the expression `let x = 1 in x + 2`, this would produce `Let(Var("x"), Number(1), Plus(Var("x"), Number(2))`. For these examples, using a normal abstract syntax tree works fine.
However, we run into trouble if we introduce multiple bindings with the same name. For example, in the expression `let x = 1 in (let x = 2 in x) + x`, we now need some notion of scope analysis. Which `x` does each instance refer to? ABTs eliminate this problem by providing constructs to handle the binding and substitution of variables. The prior expression translates roughly to `Let(1, x . (Let(2, x . x) + x))` where the dot `.` denotes a binding site. See Bob Harper's [Practical Foundations for Programming Languages](https://www.cs.cmu.edu/~rwh/pfpl/2nded.pdf), chapter 1 for more information.
## What does Rabbot do?
The usual way to create an abstract syntax is tree is to define an enum with branches for each part of your syntax, e.g.
```rust
enum Expression {
Number(i32),
Plus(Box, Box),
...
}
```However, ABTs work differently. At its core, an ABT is a fixed tree data structure that is parameterized by a set of operators, where each operator describes functionality like `Number` or `Plus`. See `rabbot/src/abt.rs` for the definition of the data type. This lets you easily re-use the ABT structure for different kinds of programs, but it requires more boilerplate and more code in practice to use.
To alleviate the verbosity of using ABTs, Rabbot takes a description of an abstract binding tree and generates a more concise interface for the programmer to use. For example, one can implement lambda calculus with Peano numerals and its interpreter in a few lines:
```rust
#![feature(plugin, box_syntax)]
#![plugin(rabbot_plugin)]#[macro_use] extern crate rabbot;
rabbot! {
sort Term {
Z,
S(Term),
Lam(Binding . Term),
App((Term, Term))
}
}use rabbot::var::Var;
use term::*;
fn interpret(t: Term) -> Term {
match out(t) {
v @ View::Z | v @ View::Lam(_) => into(v),
View::S(t) => {
bind!(View::S{v} = out(interpret(t)));
into(View::S(v))
},
View::App((fun, arg)) => {
bind!(View::Lam{(var, body)} = out(interpret(fun)));
subst(arg, var, body)
},
View::Var(_) => unreachable!()
}
}#[test]
fn test() {
let x = Var::new("x".to_string());
let term = into(View::App((
into(View::Lam((
x.clone(), into(View::S(into(View::Var(x.clone()))))))),
into(View::Z))));println!("{:?}", interpret(term)); // prints S(Z)
}
```## Caveats
This is still in heavy development, so talk to me (email: [[email protected]](mailto:[email protected])) if you want to use it. The code generator works as a compiler plugin, so it only works on nightly, although that's not a hard requirement.