A language to transform source code from/between different languages.
objc'for (\i = 0; \i < \n; \i++) \expr' &Env[]: swift'for \i in 0..<\n \expr';
&Env[].
---
TypeOf[\i]: "Int";
TypeOf[\n]: "Int";
Modifies[\expr; \i]: False[];
Modifies[\expr; \n]: False[];
Currently TreeScript requires:
Stack
Cargo
- For syntax highlighting,
Visual Studio Code
- For scheme and R language support
R
- For JavaScript language support,
Node.js
- Additionally, make sure that
~/.local/bin
and~/.cargo/bin
are on yourPATH
environment
Install with the following command:
tstmp=$(mktemp -d)
curl -Ls https://github.com/Jakobeha/treescript/releases/download/v0.1.0.0/treescript-0.1.0.0.tar.gz | tar xvz -C $tstmp
$tstmp/treescript-0.1.0.0/install.sh
This script:
- Creates a temporary directory
- Downloads and extracts the tarball into the directory
- Runs
install.sh
, which:- Runs
cargo install
to install the interpreter and libraries - Runs
stack install
to install the compiler - If VS Code is installed, runs
code --load-extension
to install syntax highlighting
- Runs
TreeScript is a DSL for writing code to analyze and transform syntax trees.
TreeScript is especially designed to:
- Refactor: Trivial (e.g. rename a variable) and non-trivial (convert all symbols from camel case to snake case)
- Transpile: Convert one language into another (e.g. CoffeeScript to JavaScript, C to Java)
- Analyze: - e.g. find the # of occurrences of a certain symbol.
- Allow small groups to slightly customize existing languages, creating their own "mini DSLs".
TreeScript could also:
- Compile: - Apply one or more passes, convert a syntax tree into a very basic syntax tree
- Optimize: Transform expressions into equivalent ones which run faster
- Interpret: "Reduce" a syntax tree as much as possible
- Print: Convert a syntax tree into text
- Parse: Convert text into a syntax tree
TreeScript is very minimal, but it can easily be extended. It relies on "libraries" to handle logic and operations like function lookup. You can download libraries, or easily create them yourself in any language.
Eventually TreeScript could even transform its own syntax trees (with a TreeScript language plugin).
Often, if you want to transform a language's syntax, you must learn and use a language-specific API (e.g. SourceKit for Swift, HaRe for Haskell, Scalameta for Scala). Or if the language doesn't have an API, you must create one yourself. Furthermore, these APIs are often implemented in languages which aren't designed for syntax transformation.
TreeScript is one API, explicitly designed to transform syntax, which works for many languages. To support a language, TreeScript only needs a specification, parser, and printer. You can transform the syntax of one language using a library created in a completely different language, or transform the syntax of your own language using a library created by someone else.
Basically, a TreeScript program consists of reducers (syntax - <input>: <output>;
). A reducer takes a specific block of code and replaces it with another block of code.
r'print(\msg)': r'cat(\msg)';
The above program transforms:
print("Hello") print("Hola") print("Bonjour")into
cat("Hello") cat("Hola") cat("Bonjour")
See doc/Semantics.md for informal semantics, and doc/examples for examples.
Run treescript run <EXEC>.tscr <INPUT> -o <OUTPUT>
to take the source code from <INPUT>
, transform it using <EXEC>.tscr
, and write the result to <OUTPUT>
.
TreeScript programs can also be compiled into executables.
Run treescript compile <SRC>.tscr
to compile <SRC>.tscr
into <SRC>.tprg
. Then run ./<SRC>.tprg <INPUT> -o <OUTPUT>
.
TreeScript relies a lot on plugins. TreeScript comes with built-in plugins, and you can download or create more.
You can add/modify plugins using treescript plugin update <plugin-path> --type <lib/lang/template-lib/template-lang>
(TODO). Plugins are stored in <app-data>/treescript/env
(<app-data>
is ~/Library/Application Support
on OSX and ~/%APPDATA%/
on Windows).
See Plugins.md for how to create plugins.
See Internals.md for how the TreeScript compiler / interpreter works.
This is based on an earlier project, Descript.