Syntax tools for the Puddle coding environment
var syntax = require('puddle-syntax');
- Data Formats: Codes, Terms, and Trees
- Module
syntax.compiler
: syntactic algorithms - Module
syntax.pretty
: pretty printing - Module
syntax.tree
: tree data structures - Module
syntax.cursorTerm
: operations on terms with cursors - Module
syntax.cursor
: operations on cursor nodes of trees - Module
syntax.tokens
: tools for token classification
This module deals with four formats of data.
-
Codes - Immutable space-delimited lists of tokens.
JSON Serializable: yes
Examples:
"I" "VAR x" "APP VAR f VAR x" "DEFINE VAR two LAMBDA VAR f LAMBDA VAR x APP VAR f APP VAR f VAR x" "ASSERT EQUAL APP VAR two I I"
-
Lines - Immutable objects with a
code
field and aname
field that is eithernull
or a string. Each line is either an assertion or a definition; assertions havename = null
and definitions definename
by theircode
.JSON Serializable: yes
Examples:
// a definition { "name": "two", "code": "LAMBDA VAR f LAMBDA VAR x APP VAR f APP VAR x VAR x" } // an assertion { "name": null, "code": "EQUAL APP VAR two I I" }
-
Terms - Immutable array-representations of abstract syntax trees.
JSON Serializable: yes
Examples:
[ "DEFINE", ["VAR", "two"], [ "LAMBDA", ["VAR", "f"], [ "LAMBDA", ["VAR", "x"], [ "APP", ["VAR" "f"], [ "APP", ["VAR" "f"], ["VAR" "x"], ] ] ] ] ] [ "ASSERT", [ "EQUAL", ["APP", ["VAR", "two"], "I"], "I" ] ]
-
Trees - Mutable cross-linked abstract syntax trees for easy traversal.
JSON Serializable: no, because of cycles
Examples:
{"name": "I", "above": null, "below": []} {"name": "VAR", "varName": "x", "above": null, "below": []} var fx = { "name": "APP", "above": null, "below": [ {"name": "VAR", "varName": "f", "below": [], "above": fx}, {"name": "VAR", "varName": "x", "below": [], "above": fx} ] };
Signature:
compiler.fragments.curry : subset of compiler.symbols
compiler.fragments.church : subset of compiler.symbols
compiler.print : term -> string
compiler.parse : string -> term
compiler.load : code -> term // compatible with pomagma analyst
compiler.dump : term -> code // compatible with pomagma analyst
compiler.loadLine : line -> term
compiler.dumpLine : term -> line
compiler.enumerateFresh : int -> string (a variable name)
compiler.substitute : name * term * term -> nil
compiler.parenthesize : term -> term
compiler.fold : /\f: (string * any -> t). term -> t
Examples:
compiler.load("APP VAR f VAR x");
// = ["APP", ["VAR", "f"], ["VAR", "x"]]
compiler.dump(["APP", ["VAR", "f"], ["VAR", "x"]]);
// = "APP VAR f VAR x"
compiler.enumerateFresh(0); // = "a"
compiler.enumerateFresh(1); // = "b"
compiler.enumerateFresh(2); // = "c"
compiler.substitute(name, def, body);
Signature:
pretty : term -> string
Examples:
pretty(["LAMBDA, ["VAR", "x"], ["APP", ["VAR", "f"], ["VAR", "x"]]]);
// = "\ x f x"
Signature:
tree.load : term -> tree node
tree.dump : tree node -> term
getRoot : tree node -> tree node
getLocals : tree node -> Array of strings (variable names)
getFresh : tree node -> string (a variable name)
Examples:
tree.load(["VAR", "x"]);
// = {"name": "VAR", "varName": "x", "above": null, "below": []}
tree.dump({"name": "VAR", "varName": "x", "above": null, "below": []});
// = ["VAR", "x"]
var root = tree.getRoot(node);
var varList = tree.getBoundAbove(term); // -> ["a", "b"]
var varSet = tree.getVars(term); // -> {"a": null, "b": null}
var name = tree.getFresh(term); // -> "c"
Signature:
insertCursor : term * address -> term
removeCursor : term -> term * address
Examples:
var x = VAR("x");
var term = LAMBDA(x, APP(x, x));
insertCursor(term, []); // -> CURSOR(LAMBDA(x, APP(x, x)))
insertCursor(term, [1]); // -> LAMBDA(CURSOR(x), APP(x, x))
insertCursor(term, [2]); // -> LAMBDA(x, CURSOR(APP(x, x)))
insertCursor(term, [2, 1]); // -> LAMBDA(x, APP(CURSOR(x), x))
insertCursor(term, [2, 2]); // -> LAMBDA(x, APP(x, CURSOR(x)))
removeCursor(APP(CURSOR(x), x)) // -> {term: APP(x, x), address: [1]}
removeCursor(APP(x, x)) // -> {term: APP(x, x), address: null}
Signature:
create : nil -> cursor node
remove : cursor node -> nil
insertAbove : cursor node * tree node -> nil
replaceBelow : cursor node * tree node -> nil
tryMove : cursor node * direction -> bool (direction one of "U" "D" "L" "R")
Examples:
var direction = "U"; // or "D", "L", "R"
var success = syntax.cursor.tryMove(cursor, direction);
Signature:
tokens.isToken : string -> bool
tokens.isKeyword : string -> bool
tokens.isLocal : string -> bool
tokens.isGlobal : string -> bool
tokens.isFreeVariables : string -> object (set of free vars)
Examples:
assert(tokens.isToken("a"));
assert(tokens.isKeyword("JOIN"));
assert(tokens.isLocal("a"));
assert(tokens.isGlobal("util.pair"));
tokens.getFreeVariables("APP VAR unqualified VAR fully.qualified.name");
// -> {"fully.qualified.name": null}
Copyright 2013-2014 Fritz Obermeyer.
Puddle is licensed under the MIT license.