Skip to content

Commit

Permalink
updating for distribution
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakobeha committed Mar 31, 2019
1 parent 06bfcce commit de0388a
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 504 deletions.
515 changes: 13 additions & 502 deletions README.md

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions doc/History.md
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]]
```
1 change: 1 addition & 0 deletions doc/Install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Install
76 changes: 76 additions & 0 deletions doc/Plugins.md
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`.
2 changes: 1 addition & 1 deletion doc/Semantics.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ c’println(\str)’: js’console.log(\str)’;
A **group** organizes other statements.

```treescript
&Print[](
&Print[];
&Print[].
——-
Expand Down
Empty file added install.sh
Empty file.
7 changes: 7 additions & 0 deletions treescript-interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 8 additions & 0 deletions treescript-interpreter/README.md
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)
2 changes: 1 addition & 1 deletion treescript-interpreter/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl<'a, R: Read> Parser<'a, R> {
match iter.next() {
Some('"') => break,
Some(' ') | Some('\n') => (),
next => panic!("expected Some('\"') for string start, got {}", next),
next => panic!("expected Some('\"') for string start, got {:?}", next),
};
}
let mut is_escaping = false;
Expand Down

0 comments on commit de0388a

Please sign in to comment.