-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
141 additions
and
504 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# History | ||
|
||
## Relation to Descript | ||
|
||
This language used to be called Descript. It was renamed because TreeScript better describes what it actually does - rename trees - and it sounds similar. It's the third version / "attempt" at creating a syntax transformation language. The other 2 attempts are: | ||
|
||
1. [Descript-lang (Haskell)](https://bitbucket.org/jakobeha/descript-lang/src/master/) | ||
2. [Descript-ocaml](https://bitbucket.org/jakobeha/descript-ocaml/src/master/) | ||
|
||
### Major Changes from Descript-lang and Descript-ocaml | ||
|
||
*TreeScript code is no longer interpreted, it's now compiled into another language.* | ||
|
||
As before, there are 2 types of objects - **values** and **reducers**. A program still consists of reducers, but there's no query - all programs read source from `stdin`, transform it, and print it to `stdout`. Reducers are also organized into groups, and reducers can reference groups, which allows abstraction and sort of replaces macros. There are no macros or multiple phases, they're not needed. TreeScript no longer refactors itself directly, and if you want to write code which handles `Add`, `Subtract`, `Multiply`, and `Divide` a common way, you can do reduce these into `Arith[op: ...; left: ...; right: ...]` in the single phase. A program must also declare its records at the top of the file - builtins and source records don't need to be declared. | ||
|
||
Primitives are exactly as before. | ||
|
||
All record heads are static strings, and records must be declared, like in version #1. Record properties aren't named, and 2 records with the same name must have the same number of properties. "Injections" exist as "functions". Groups are similar to records, but they have named properties, and the names correspond to binds. | ||
|
||
"Matchers" and "paths" are renamed to "binds". Now, they both consist of a single string (desugared into an integer). Input binds can contain the empty string (or integer 0), in which case they're like "any" matchers, but not output binds. Like before, binds and functions should encapsulate all abstraction. | ||
|
||
There are no "regular" values - all values are input or output values. Thus, all values have the same specification - a value is either a primitive, record, or bind (or with sugar, a code block). | ||
|
||
--- | ||
|
||
Analyze Example | ||
|
||
```treescript | ||
js'function \name(\args...) { \body... }': Int_Code[Count[\body]] &Count[]; | ||
&Count[] | ||
=== | ||
Count[\xs] &IsList[\xs]: #Num_Add[#List_Map[Count[\1]] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Install |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Plugins | ||
|
||
## Libraries | ||
|
||
TreeScript uses **libraries** to handle “typical” programming (e.g. arithmetic, algorithms, data structures), and more complex syntax operations (e.g. function declaration lookups, extra source info). Each library is an external program. When TreeScript evaluates the function call `#<Lib>_<Fun>[<arg>, ...]`, it sends the record `<Fun>[<arg>, ...]`, encoded in **AST data**, to `stdin` of the `<Lib>` library. The library sends a value back to TreeScript through `stdout`, and that result replaces the call. | ||
|
||
Libraries are stored in `<app-data>/treescript/env/libraries`. | ||
|
||
## Language Plugins | ||
|
||
In order to support a language, TreeScript must have a corresponding **language plugin**. A language plugin consists of an specification, parser, and printer. The specification defines each node in the language's AST, the "parser" converts source code into **AST data**, and the printer converts **AST data** into source code. | ||
|
||
Language plugins are stored in `<app-data>/treescript/env/languages`. | ||
|
||
--- | ||
|
||
The following **examples** are for a minimal lambda-calculus Scheme specification: | ||
|
||
```s | ||
(((lambda (f) ((f 4) 5)) | ||
(lambda (x) (lambda (y) (lambda (z) ((+ x) ((- z) y)))))) | ||
3) | ||
``` | ||
|
||
## Language Specification | ||
|
||
The language specification defines the language's file extension, and every type of node in the AST. Each node has a name and number of children. The name must consist of only uppercase letters, lowercase letters, and numbers, and it should be CamelCase. | ||
|
||
--- | ||
|
||
(evaluates to 2). | ||
|
||
**Example:** | ||
|
||
```json | ||
{ | ||
"extension": "scm", | ||
"nodes": [ | ||
{ | ||
"name": "Var", | ||
"args": 1, //identifier | ||
}, | ||
{ | ||
"name": "Lambda", | ||
"args": 2, //bound identifier and body expression | ||
}, | ||
{ | ||
"name": "App", | ||
"args": 2, //function and body expressions | ||
}, | ||
{ | ||
"name": "Integer", | ||
"args": 1, //literal fixed-precision integer | ||
} | ||
] | ||
} | ||
``` | ||
|
||
## Language Parser | ||
|
||
A language parser is a command-line program which reads a language's source text from stdin and outputs the corresponding AST data. | ||
|
||
Each language parser must (or at least strongly should) handle indexed splices (`\#`, e.g. in `while (\0 < \1) \2++;)`), and convert `\\` occurrences to actual backslashes. When an indexed splice is encountered, in the AST data it gets converted into a `splice` node, which is followed by the splice's index. e.g. for `while (\0 < \1) \2++;)`, `\0` is encoded with `splice 0`, `1` is encoded with `splice 1`, and `2` is encoded with | ||
`splice 2` (these nodes have no children). | ||
|
||
Language parsers are specifically designed to be used by the TreeScript compiler, to desugar code blocks. As such, they have a strict specification - there are other ways to get source text into AST data, e.g. not using this specific command-line format, and you can use these other methods when getting the AST data to feed into a compiled TreeScript program. However, they're convenient when also paired with a TreeScript program - the command `cat <input> | <language-parser> | <treescript-program> --stdin --stdout | <language-printer> | <output>` will read source text from `<input>`, apply `<treescript-program>`, and print the write the transformed source text to `<output>`. | ||
|
||
## Language Printer | ||
|
||
A language printer is the opposite of a language parser - it's a command-line program which reads AST data for a language and outputs it's source code. | ||
|
||
## Templates | ||
|
||
You can create a plugin from a template using `treescript plugin new <name> -l <language-of-plugin-source>`. Library templates define datatypes for `Value`s and handle parsing and printing, so you only need to write the core function logic. Language templates also define `Value`s. TreeScript comes with built-in templates for some languages, and you can add more. (TODO) | ||
|
||
Templates are stored in `<app-data>/treescript/env/templates`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,13 @@ | |
name = "treescript-interpreter" | ||
version = "0.1.0" | ||
authors = ["jakob <[email protected]>"] | ||
license = "GPL-3.0-or-later" | ||
description = "TreeScript interpreter, with some built-in libraries and API to create more" | ||
readme = "README.md" | ||
homepage = "https://github.org/jakobeha/treescript/treescript-interpreter" | ||
repository = "https://github.org/jakobeha/treescript" | ||
keywords = ["cli", "interpreter"] | ||
categories = ["command-line-utilities"] | ||
edition = "2018" | ||
|
||
[dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# TreeScript Interpreter | ||
|
||
An interpreter for the [TreeScript](https://github.org/jakobeha/treescript#readme) language. | ||
|
||
Additionally: | ||
|
||
- Libraries shipped with TreeScript | ||
- API to create new libraries in Rust (TODO describe how to use, for now see the libraries described above for examples) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters