@graffiticode/basis 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +55 -0
- package/package.json +1 -1
- package/spec/package.json +6 -0
- package/spec/spec.html +291 -155
- package/spec/spec.md +164 -11
- package/src/compiler.js +40 -3
- package/src/lexicon.js +44 -35
package/spec/spec.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Graffiticode Core Language Specification
|
|
2
2
|
|
|
3
3
|
```
|
|
4
|
-
Version: 0.1.
|
|
5
|
-
Date:
|
|
4
|
+
Version: 0.1.2
|
|
5
|
+
Date: 2026-01-26
|
|
6
6
|
```
|
|
7
7
|
|
|
8
8
|
# Introduction
|
|
@@ -44,6 +44,8 @@ Function application is written in prefix style:
|
|
|
44
44
|
add 1 2
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
Functions have fixed arity, so applications can be parsed unambiguously without grouping syntax. For example, `add 1 mul 2 3` parses as `add(1, mul(2, 3))` because the parser knows `add` takes 2 arguments and `mul` takes 2 arguments.
|
|
48
|
+
|
|
47
49
|
Parentheses are used to defer application:
|
|
48
50
|
```
|
|
49
51
|
map (double) [1 2 3]
|
|
@@ -55,10 +57,53 @@ map (double) [1 2 3]
|
|
|
55
57
|
```
|
|
56
58
|
|
|
57
59
|
### Records
|
|
60
|
+
|
|
61
|
+
Records may use **shorthand syntax** for fields where the value is a reference to a variable of the same name.
|
|
62
|
+
|
|
63
|
+
```gc
|
|
64
|
+
let foo = 10..
|
|
65
|
+
{foo} | equivalent to {foo: 10}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This provides a concise way to construct records using in-scope variable names as field keys and values.
|
|
69
|
+
|
|
70
|
+
You can also mix shorthand and explicit fields:
|
|
71
|
+
|
|
72
|
+
```gc
|
|
73
|
+
let x = 1..
|
|
74
|
+
let y = 2..
|
|
75
|
+
{x y z: 3} | equivalent to {x: 1, y: 2, z: 3}
|
|
58
76
|
```
|
|
77
|
+
|
|
78
|
+
```gc
|
|
59
79
|
{ name: "Alice", age: 30 }
|
|
60
80
|
```
|
|
61
81
|
|
|
82
|
+
### Tags
|
|
83
|
+
|
|
84
|
+
A **tag value** is an arity-0 symbolic value used to represent symbolic variants in pattern matching or other symbolic forms.
|
|
85
|
+
|
|
86
|
+
Tag values are **only defined** by using record shorthand syntax. For example:
|
|
87
|
+
|
|
88
|
+
```gc
|
|
89
|
+
{red blue green} | defines the tag values red, blue, and green
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Tag values:
|
|
93
|
+
|
|
94
|
+
- Must be introduced via record shorthand notation
|
|
95
|
+
- Are resolved as symbolic constants with identity semantics
|
|
96
|
+
- Match directly in `case` expressions:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
let color = get "red" {red blue green}
|
|
100
|
+
case color of
|
|
101
|
+
red: "warm"
|
|
102
|
+
blue: "cool"
|
|
103
|
+
_: "other"
|
|
104
|
+
end
|
|
105
|
+
```
|
|
106
|
+
|
|
62
107
|
### Lambdas
|
|
63
108
|
```
|
|
64
109
|
<x: add x 1>
|
|
@@ -76,6 +121,7 @@ let double = <x: mul 2 x>..
|
|
|
76
121
|
## Pattern Matching
|
|
77
122
|
|
|
78
123
|
Pattern matching is done using `case`:
|
|
124
|
+
|
|
79
125
|
```
|
|
80
126
|
case x of
|
|
81
127
|
0: "zero"
|
|
@@ -92,29 +138,126 @@ Supports:
|
|
|
92
138
|
|
|
93
139
|
Pattern matching on function arguments is disallowed.
|
|
94
140
|
|
|
95
|
-
|
|
141
|
+
# Type System
|
|
142
|
+
|
|
143
|
+
Graffiticode includes a implicit structural type system. Every expression has
|
|
144
|
+
a statically inferred type, and type errors are detected at compile time.
|
|
145
|
+
Explicit type annotations are not included in the grammar.
|
|
146
|
+
|
|
147
|
+
## Primitive Types
|
|
96
148
|
|
|
97
|
-
|
|
149
|
+
- `number` – Represents integers or floating-point numbers.
|
|
150
|
+
- `string` – Represents UTF-8 strings.
|
|
151
|
+
- `bool` – Represents Boolean values: `true` and `false`.
|
|
152
|
+
- `json` – Represents any JSON-compatible value (opaque, untyped).
|
|
153
|
+
- `any` – Used internally to denote an unconstrained type (e.g., during inference).
|
|
98
154
|
|
|
155
|
+
## Composite Types
|
|
156
|
+
|
|
157
|
+
- **Lists** – Written as `[T]` where `T` is any type.
|
|
158
|
+
```
|
|
159
|
+
[string] | list of strings
|
|
160
|
+
[number] | list of numbers
|
|
161
|
+
[[bool]] | list of lists of booleans
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- **Records** – Key-value maps with known keys and types.
|
|
165
|
+
```
|
|
166
|
+
{ name: string, age: number }
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
- **Tuples** – Ordered, fixed-length collections with heterogeneous types.
|
|
170
|
+
```
|
|
171
|
+
(number, string, bool)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Function Types
|
|
175
|
+
|
|
176
|
+
Functions are written using Graffiticode lambda signature syntax:
|
|
99
177
|
```
|
|
100
|
-
|
|
178
|
+
<number number: number> | function taking two numbers and returning a number
|
|
179
|
+
<string: [string]> | function taking a string and returning a list of strings
|
|
180
|
+
<list record: record> | common signature for structural transformation
|
|
101
181
|
```
|
|
102
182
|
|
|
103
|
-
|
|
183
|
+
Function types are curried by default. That means:
|
|
184
|
+
```
|
|
185
|
+
<number number: number>
|
|
186
|
+
```
|
|
187
|
+
is equivalent to a function that returns another function:
|
|
188
|
+
```
|
|
189
|
+
<number: <number: number>>
|
|
190
|
+
```
|
|
104
191
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
192
|
+
## Tag Sets and Tag Value Type
|
|
193
|
+
|
|
194
|
+
Tag values are symbolic constants introduced using record shorthand syntax. They have a default type of `tag`, and their identity is preserved across bindings.
|
|
195
|
+
|
|
196
|
+
### Tag Identity and Type
|
|
197
|
+
|
|
198
|
+
Tag values are symbolic constants identified **solely by their name**. The same tag name (e.g., `A`) refers to the same symbolic value, regardless of where it is defined.
|
|
199
|
+
|
|
200
|
+
Tag values compare equal by name. For example, `A` in `{A B}` and `A` in `{A C}` are equal.
|
|
201
|
+
|
|
202
|
+
### Tag Sets as Structural Types
|
|
203
|
+
|
|
204
|
+
Although tag values are globally identified by name, the **type system tracks which tags are expected to co-occur**.
|
|
205
|
+
|
|
206
|
+
For example, `{A B}` and `{A C}` are different types:
|
|
108
207
|
|
|
109
208
|
```
|
|
110
|
-
|
|
209
|
+
{A B} | type: { A: tag, B: tag }
|
|
210
|
+
{A C} | type: { A: tag, C: tag }
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
This allows the type system to constrain the expected context for pattern matching, record shapes, or enum-style uses of tags.
|
|
214
|
+
|
|
215
|
+
Using tags not part of the expected set results in a type error.
|
|
216
|
+
|
|
217
|
+
### Default Type: `tag`
|
|
218
|
+
|
|
219
|
+
By default, a tag value has the type:
|
|
220
|
+
|
|
221
|
+
```gc
|
|
222
|
+
tag
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
When tags are introduced with:
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
{A B C}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
the resulting type is:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
{ A: tag, B: tag, C: tag }
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This allows for composition and safe comparison.
|
|
238
|
+
|
|
239
|
+
### Example
|
|
240
|
+
|
|
241
|
+
```gc
|
|
242
|
+
let colors = {red blue green}..
|
|
243
|
+
case red of
|
|
111
244
|
red: "warm"
|
|
112
245
|
blue: "cool"
|
|
113
246
|
_: "other"
|
|
114
247
|
end
|
|
115
248
|
```
|
|
116
249
|
|
|
117
|
-
|
|
250
|
+
In this case, `red`, `blue`, and `green` are all of type `tag`, and `case` matches by identity.
|
|
251
|
+
|
|
252
|
+
## Example: Annotated Definitions
|
|
253
|
+
|
|
254
|
+
```gc
|
|
255
|
+
let inc = <x: add x 1> | type: <number: number>
|
|
256
|
+
let greet = <name: concat ["Hello, " name]> | type: <string: string>
|
|
257
|
+
let zip = <xs ys: zipLists xs ys> | type: <[T] [U]: [(T, U)]>
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
(Note: actual Graffiticode does not use type annotations in `let` bindings; types are inferred.)
|
|
118
261
|
|
|
119
262
|
# Semantics
|
|
120
263
|
|
|
@@ -173,6 +316,7 @@ This approach draws inspiration from **Model-View-Update** (MVU) architectures,
|
|
|
173
316
|
| `get` | `<string record: any>` | Retrieves a value from a record by key |
|
|
174
317
|
| `hd` | `<list: any>` | First item of list |
|
|
175
318
|
| `isEmpty` | `<list: bool>` | Returns true if the list is empty |
|
|
319
|
+
| `log` | `<any: any>` | Logs the value to console and returns it (identity function) |
|
|
176
320
|
| `map` | `<function list: list>` | Applies function to each item |
|
|
177
321
|
| `max` | `<number number: number>` | Returns the larger of two numbers |
|
|
178
322
|
| `min` | `<number number: number>` | Returns the smaller of two numbers |
|
|
@@ -266,6 +410,15 @@ Return true if list is empty, otherwise return false
|
|
|
266
410
|
isEmpty [] | returns true
|
|
267
411
|
```
|
|
268
412
|
|
|
413
|
+
### log
|
|
414
|
+
|
|
415
|
+
Log a value to the console and return the value unchanged
|
|
416
|
+
|
|
417
|
+
```
|
|
418
|
+
log "Hello" | prints "Hello" to console and returns "Hello"
|
|
419
|
+
log (add 1 2) | prints 3 to console and returns 3
|
|
420
|
+
```
|
|
421
|
+
|
|
269
422
|
### map
|
|
270
423
|
|
|
271
424
|
Apply a function to each element
|
package/src/compiler.js
CHANGED
|
@@ -73,6 +73,7 @@ class Visitor {
|
|
|
73
73
|
case "STR":
|
|
74
74
|
case "IDENT":
|
|
75
75
|
case "BOOL":
|
|
76
|
+
case "TAG":
|
|
76
77
|
elts[0] = n.elts[0];
|
|
77
78
|
break;
|
|
78
79
|
default:
|
|
@@ -173,6 +174,11 @@ export class Checker extends Visitor {
|
|
|
173
174
|
const val = node;
|
|
174
175
|
resume(err, val);
|
|
175
176
|
}
|
|
177
|
+
TAG(node, options, resume) {
|
|
178
|
+
const err = [];
|
|
179
|
+
const val = node;
|
|
180
|
+
resume(err, val);
|
|
181
|
+
}
|
|
176
182
|
STR(node, options, resume) {
|
|
177
183
|
const err = [];
|
|
178
184
|
const val = node.elts[0];
|
|
@@ -506,6 +512,13 @@ export class Checker extends Visitor {
|
|
|
506
512
|
resume(err, val);
|
|
507
513
|
});
|
|
508
514
|
}
|
|
515
|
+
LOG(node, options, resume) {
|
|
516
|
+
this.visit(node.elts[0], options, (err1, val1) => {
|
|
517
|
+
const err = [].concat(err1);
|
|
518
|
+
const val = node;
|
|
519
|
+
resume(err, val);
|
|
520
|
+
});
|
|
521
|
+
}
|
|
509
522
|
}
|
|
510
523
|
|
|
511
524
|
function enterEnv(ctx, name, paramc) {
|
|
@@ -602,7 +615,7 @@ export class Transformer extends Visitor {
|
|
|
602
615
|
}
|
|
603
616
|
const patternNid = this.internPattern(pattern);
|
|
604
617
|
if (patternNid === this.internPattern(node) ||
|
|
605
|
-
patternNid === this.internPattern(newNode('
|
|
618
|
+
patternNid === this.internPattern(newNode('TAG', ['_']))) {
|
|
606
619
|
return true;
|
|
607
620
|
}
|
|
608
621
|
if (pattern.tag === node.tag) {
|
|
@@ -641,8 +654,9 @@ export class Transformer extends Visitor {
|
|
|
641
654
|
return matches;
|
|
642
655
|
}
|
|
643
656
|
CATCH_ALL(node, options, resume) {
|
|
657
|
+
// Fallback for unknown node types.
|
|
644
658
|
const err = [];
|
|
645
|
-
const val = node;
|
|
659
|
+
const val = node;
|
|
646
660
|
resume(err, val);
|
|
647
661
|
}
|
|
648
662
|
PROG(node, options, resume) {
|
|
@@ -735,6 +749,11 @@ export class Transformer extends Visitor {
|
|
|
735
749
|
const val = word?.val !== undefined ? word.val : node.elts[0];
|
|
736
750
|
resume(err, val);
|
|
737
751
|
}
|
|
752
|
+
TAG(node, options, resume) {
|
|
753
|
+
const err = [];
|
|
754
|
+
const val = { tag: node.elts[0] };
|
|
755
|
+
resume(err, val);
|
|
756
|
+
}
|
|
738
757
|
STR(node, options, resume) {
|
|
739
758
|
const err = [];
|
|
740
759
|
const val = node.elts[0];
|
|
@@ -820,6 +839,10 @@ export class Transformer extends Visitor {
|
|
|
820
839
|
const ndx = [];
|
|
821
840
|
for (let elt of node.elts) {
|
|
822
841
|
this.visit(elt, options, (e0, v0) => {
|
|
842
|
+
console.log(
|
|
843
|
+
"RECORD()",
|
|
844
|
+
"v0=" + JSON.stringify(v0, null, 2),
|
|
845
|
+
);
|
|
823
846
|
err = err.concat(e0);
|
|
824
847
|
ndx[elt] = v0;
|
|
825
848
|
if (++len === node.elts.length) {
|
|
@@ -1028,7 +1051,8 @@ export class Transformer extends Visitor {
|
|
|
1028
1051
|
const val = `${v0}`;
|
|
1029
1052
|
const expr = (
|
|
1030
1053
|
v0 === null && {tag: "NUL", elts: []} ||
|
|
1031
|
-
v0
|
|
1054
|
+
v0?.tag !== undefined && !v0.elts && {tag: "TAG", elts: [v0.tag]} ||
|
|
1055
|
+
v0?.tag !== undefined && v0 || // Already an AST node.
|
|
1032
1056
|
type === "boolean" && {tag: "BOOL", elts: [val]} ||
|
|
1033
1057
|
type === "number" && {tag: "NUM", elts: [val]} ||
|
|
1034
1058
|
{tag: "STR", elts: [val]}
|
|
@@ -1364,6 +1388,19 @@ export class Transformer extends Visitor {
|
|
|
1364
1388
|
}
|
|
1365
1389
|
});
|
|
1366
1390
|
}
|
|
1391
|
+
LOG(node, options, resume) {
|
|
1392
|
+
this.visit(node.elts[0], options, (e0, v0) => {
|
|
1393
|
+
const err = [].concat(e0);
|
|
1394
|
+
try {
|
|
1395
|
+
// Log the value to the console
|
|
1396
|
+
console.log(`LOG: ${v0}`);
|
|
1397
|
+
// Return the value unchanged (identity function)
|
|
1398
|
+
resume(err, v0);
|
|
1399
|
+
} catch (e) {
|
|
1400
|
+
resume([...err, `Error in LOG operation: ${e.message}`], null);
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1367
1404
|
}
|
|
1368
1405
|
|
|
1369
1406
|
export class Renderer {
|
package/src/lexicon.js
CHANGED
|
@@ -3,256 +3,256 @@ export const lexicon = {
|
|
|
3
3
|
"tk": 1,
|
|
4
4
|
"name": "PRINT",
|
|
5
5
|
"cls": "function",
|
|
6
|
-
"length": 1,
|
|
7
6
|
"arity": 1,
|
|
7
|
+
"type": "<any: record>",
|
|
8
8
|
"description": "Outputs a value to the form."
|
|
9
9
|
},
|
|
10
10
|
"get": {
|
|
11
11
|
"tk": 1,
|
|
12
12
|
"name": "GET",
|
|
13
13
|
"cls": "function",
|
|
14
|
-
"length": 2,
|
|
15
14
|
"arity": 2,
|
|
15
|
+
"type": "<integer record|list: any>",
|
|
16
16
|
"description": "Retrieves a value from a record or list by key or index."
|
|
17
17
|
},
|
|
18
18
|
"set": {
|
|
19
19
|
"tk": 1,
|
|
20
20
|
"name": "SET",
|
|
21
21
|
"cls": "function",
|
|
22
|
-
"length": 3,
|
|
23
22
|
"arity": 3,
|
|
23
|
+
"type": "<integer any record|list: record|list>",
|
|
24
24
|
"description": "Returns a new record or list with the specified key or index updated."
|
|
25
25
|
},
|
|
26
26
|
"nth": {
|
|
27
27
|
"tk": 1,
|
|
28
28
|
"name": "NTH",
|
|
29
29
|
"cls": "function",
|
|
30
|
-
"length": 2,
|
|
31
30
|
"arity": 2,
|
|
31
|
+
"type": "<integer list: any>",
|
|
32
32
|
"description": "Returns the nth element of a list by index."
|
|
33
33
|
},
|
|
34
34
|
"sub": {
|
|
35
35
|
"tk": 1,
|
|
36
36
|
"name": "SUB",
|
|
37
37
|
"cls": "function",
|
|
38
|
-
"length": 2,
|
|
39
38
|
"arity": 2,
|
|
39
|
+
"type": "<number number: number>",
|
|
40
40
|
"description": "Subtracts the second number from the first."
|
|
41
41
|
},
|
|
42
42
|
"filter": {
|
|
43
43
|
"tk": 1,
|
|
44
44
|
"name": "FILTER",
|
|
45
45
|
"cls": "function",
|
|
46
|
-
"length": 2,
|
|
47
46
|
"arity": 2,
|
|
47
|
+
"type": "<lambda list: list>",
|
|
48
48
|
"description": "Returns a list of elements that match a predicate."
|
|
49
49
|
},
|
|
50
50
|
"reduce": {
|
|
51
51
|
"tk": 1,
|
|
52
52
|
"name": "REDUCE",
|
|
53
53
|
"cls": "function",
|
|
54
|
-
"length": 3,
|
|
55
54
|
"arity": 3,
|
|
55
|
+
"type": "<lambda any list: any>",
|
|
56
56
|
"description": "Reduces a list to a single value using a binary function and initial value."
|
|
57
57
|
},
|
|
58
58
|
"map": {
|
|
59
59
|
"tk": 1,
|
|
60
60
|
"name": "MAP",
|
|
61
61
|
"cls": "function",
|
|
62
|
-
"length": 2,
|
|
63
62
|
"arity": 2,
|
|
63
|
+
"type": "<lambda list: list>",
|
|
64
64
|
"description": "Applies a function to each element in a list and returns a new list."
|
|
65
65
|
},
|
|
66
66
|
"lt": {
|
|
67
67
|
"tk": 1,
|
|
68
68
|
"name": "LT",
|
|
69
69
|
"cls": "function",
|
|
70
|
-
"length": 2,
|
|
71
70
|
"arity": 2,
|
|
71
|
+
"type": "<number number: boolean>",
|
|
72
72
|
"description": "Returns true if the first value is less than the second."
|
|
73
73
|
},
|
|
74
74
|
"le": {
|
|
75
75
|
"tk": 1,
|
|
76
76
|
"name": "LE",
|
|
77
77
|
"cls": "function",
|
|
78
|
-
"length": 2,
|
|
79
78
|
"arity": 2,
|
|
79
|
+
"type": "<number number: boolean>",
|
|
80
80
|
"description": "Returns true if the first value is less than or equal to the second."
|
|
81
81
|
},
|
|
82
82
|
"gt": {
|
|
83
83
|
"tk": 1,
|
|
84
84
|
"name": "GT",
|
|
85
85
|
"cls": "function",
|
|
86
|
-
"length": 2,
|
|
87
86
|
"arity": 2,
|
|
87
|
+
"type": "<number number: boolean>",
|
|
88
88
|
"description": "Returns true if the first value is greater than the second."
|
|
89
89
|
},
|
|
90
90
|
"ge": {
|
|
91
91
|
"tk": 1,
|
|
92
92
|
"name": "GE",
|
|
93
93
|
"cls": "function",
|
|
94
|
-
"length": 2,
|
|
95
94
|
"arity": 2,
|
|
95
|
+
"type": "<number number: boolean>",
|
|
96
96
|
"description": "Returns true if the first value is greater than or equal to the second."
|
|
97
97
|
},
|
|
98
98
|
"ne": {
|
|
99
99
|
"tk": 1,
|
|
100
100
|
"name": "NE",
|
|
101
101
|
"cls": "function",
|
|
102
|
-
"length": 2,
|
|
103
102
|
"arity": 2,
|
|
103
|
+
"type": "<number number: boolean>",
|
|
104
104
|
"description": "Returns true if the two values are not equal."
|
|
105
105
|
},
|
|
106
106
|
"len": {
|
|
107
107
|
"tk": 1,
|
|
108
108
|
"name": "LEN",
|
|
109
109
|
"cls": "function",
|
|
110
|
-
"length": 1,
|
|
111
110
|
"arity": 1,
|
|
111
|
+
"type": "<list|string: integer>",
|
|
112
112
|
"description": "Returns the length of a list or string."
|
|
113
113
|
},
|
|
114
114
|
"concat": {
|
|
115
115
|
"tk": 1,
|
|
116
116
|
"name": "CONCAT",
|
|
117
117
|
"cls": "function",
|
|
118
|
-
"length": 1,
|
|
119
118
|
"arity": 1,
|
|
119
|
+
"type": "<list: list|string>",
|
|
120
120
|
"description": "Concatenates a list of strings or nested lists."
|
|
121
121
|
},
|
|
122
122
|
"add": {
|
|
123
123
|
"tk": 1,
|
|
124
124
|
"name": "ADD",
|
|
125
125
|
"cls": "function",
|
|
126
|
-
"length": 2,
|
|
127
126
|
"arity": 2,
|
|
127
|
+
"type": "<number number: number>",
|
|
128
128
|
"description": "Adds two numbers."
|
|
129
129
|
},
|
|
130
130
|
"mul": {
|
|
131
131
|
"tk": 1,
|
|
132
132
|
"name": "MUL",
|
|
133
133
|
"cls": "function",
|
|
134
|
-
"length": 2,
|
|
135
134
|
"arity": 2,
|
|
135
|
+
"type": "<number number: number>",
|
|
136
136
|
"description": "Multiplies two numbers."
|
|
137
137
|
},
|
|
138
138
|
"pow": {
|
|
139
139
|
"tk": 1,
|
|
140
140
|
"name": "POW",
|
|
141
141
|
"cls": "function",
|
|
142
|
-
"length": 2,
|
|
143
142
|
"arity": 2,
|
|
143
|
+
"type": "<number number: number>",
|
|
144
144
|
"description": "Raises the first number to the power of the second."
|
|
145
145
|
},
|
|
146
146
|
"apply": {
|
|
147
147
|
"tk": 1,
|
|
148
148
|
"name": "APPLY",
|
|
149
149
|
"cls": "function",
|
|
150
|
-
"length": 2,
|
|
151
150
|
"arity": 2,
|
|
151
|
+
"type": "<number number: number>",
|
|
152
152
|
"description": "Applies a function to a list of arguments."
|
|
153
153
|
},
|
|
154
154
|
"data": {
|
|
155
155
|
"tk": 1,
|
|
156
156
|
"name": "DATA",
|
|
157
157
|
"cls": "function",
|
|
158
|
-
"length": 1,
|
|
159
158
|
"arity": 1,
|
|
160
|
-
"
|
|
159
|
+
"type": "<record: record>",
|
|
160
|
+
"description": "Returns the data from the upstream task, or the argument value if no input exists."
|
|
161
161
|
},
|
|
162
162
|
"json": {
|
|
163
163
|
"tk": 1,
|
|
164
164
|
"name": "JSON",
|
|
165
165
|
"cls": "function",
|
|
166
|
-
"length": 1,
|
|
167
166
|
"arity": 1,
|
|
168
|
-
"
|
|
167
|
+
"type": "<string: any>",
|
|
168
|
+
"description": "Parses a string as JSON."
|
|
169
169
|
},
|
|
170
170
|
"eq": {
|
|
171
171
|
"tk": 1,
|
|
172
172
|
"name": "EQ",
|
|
173
173
|
"cls": "function",
|
|
174
|
-
"length": 2,
|
|
175
174
|
"arity": 2,
|
|
175
|
+
"type": "<number number: boolean>",
|
|
176
176
|
"description": "Returns true if the two values are equal."
|
|
177
177
|
},
|
|
178
178
|
"mod": {
|
|
179
179
|
"tk": 1,
|
|
180
180
|
"name": "MOD",
|
|
181
181
|
"cls": "function",
|
|
182
|
-
"length": 2,
|
|
183
182
|
"arity": 2,
|
|
183
|
+
"type": "<number number: integer>",
|
|
184
184
|
"description": "Returns the remainder of dividing the first number by the second."
|
|
185
185
|
},
|
|
186
186
|
"min": {
|
|
187
187
|
"tk": 1,
|
|
188
188
|
"name": "MIN",
|
|
189
189
|
"cls": "function",
|
|
190
|
-
"length": 2,
|
|
191
190
|
"arity": 2,
|
|
191
|
+
"type": "<number number: number>",
|
|
192
192
|
"description": "Returns the smaller of two values."
|
|
193
193
|
},
|
|
194
194
|
"max": {
|
|
195
195
|
"tk": 1,
|
|
196
196
|
"name": "MAX",
|
|
197
197
|
"cls": "function",
|
|
198
|
-
"length": 2,
|
|
199
198
|
"arity": 2,
|
|
199
|
+
"type": "<number number: number>",
|
|
200
200
|
"description": "Returns the larger of two values."
|
|
201
201
|
},
|
|
202
202
|
"range": {
|
|
203
203
|
"tk": 1,
|
|
204
204
|
"name": "RANGE",
|
|
205
205
|
"cls": "function",
|
|
206
|
-
"length": 3,
|
|
207
206
|
"arity": 3,
|
|
207
|
+
"type": "<number number number: list>",
|
|
208
208
|
"description": "Generates a list of numbers from start to end using a step."
|
|
209
209
|
},
|
|
210
210
|
"not": {
|
|
211
211
|
"tk": 1,
|
|
212
212
|
"name": "NOT",
|
|
213
213
|
"cls": "function",
|
|
214
|
-
"length": 1,
|
|
215
214
|
"arity": 1,
|
|
215
|
+
"type": "<boolean: boolean>",
|
|
216
216
|
"description": "Returns the logical negation of a boolean value."
|
|
217
217
|
},
|
|
218
218
|
"equiv": {
|
|
219
219
|
"tk": 1,
|
|
220
220
|
"name": "EQUIV",
|
|
221
221
|
"cls": "function",
|
|
222
|
-
"length": 2,
|
|
223
222
|
"arity": 2,
|
|
223
|
+
"type": "<any any: boolean>",
|
|
224
224
|
"description": "Returns true if the two values are semantically equivalent."
|
|
225
225
|
},
|
|
226
226
|
"or": {
|
|
227
227
|
"tk": 1,
|
|
228
228
|
"name": "OR",
|
|
229
229
|
"cls": "function",
|
|
230
|
-
"length": 2,
|
|
231
230
|
"arity": 2,
|
|
231
|
+
"type": "<boolean boolean: boolean>",
|
|
232
232
|
"description": "Returns true if at least one of the two values is true."
|
|
233
233
|
},
|
|
234
234
|
"and": {
|
|
235
235
|
"tk": 1,
|
|
236
236
|
"name": "AND",
|
|
237
237
|
"cls": "function",
|
|
238
|
-
"length": 2,
|
|
239
238
|
"arity": 2,
|
|
239
|
+
"type": "<boolean boolean: boolean>",
|
|
240
240
|
"description": "Returns true if both values are true."
|
|
241
241
|
},
|
|
242
242
|
"hd": {
|
|
243
243
|
"tk": 1,
|
|
244
244
|
"name": "HD",
|
|
245
245
|
"cls": "function",
|
|
246
|
-
"length": 1,
|
|
247
246
|
"arity": 1,
|
|
247
|
+
"type": "<list: any>",
|
|
248
248
|
"description": "Returns the first element of a list."
|
|
249
249
|
},
|
|
250
250
|
"tl": {
|
|
251
251
|
"tk": 1,
|
|
252
252
|
"name": "TL",
|
|
253
253
|
"cls": "function",
|
|
254
|
-
"length": 1,
|
|
255
254
|
"arity": 1,
|
|
255
|
+
"type": "<list: list>",
|
|
256
256
|
"description": "Returns the list without its first element."
|
|
257
257
|
},
|
|
258
258
|
"cons": {
|
|
@@ -261,14 +261,23 @@ export const lexicon = {
|
|
|
261
261
|
"cls": "function",
|
|
262
262
|
"length": 2,
|
|
263
263
|
"arity": 2,
|
|
264
|
+
"type": "<any list: list>",
|
|
264
265
|
"description": "Prepends an element to the front of a list."
|
|
265
266
|
},
|
|
266
267
|
"append": {
|
|
267
268
|
"tk": 1,
|
|
268
269
|
"name": "APPEND",
|
|
269
270
|
"cls": "function",
|
|
270
|
-
"length": 2,
|
|
271
271
|
"arity": 2,
|
|
272
|
+
"type": "<any list: list>",
|
|
272
273
|
"description": "Appends an element to the end of a list."
|
|
274
|
+
},
|
|
275
|
+
"log": {
|
|
276
|
+
"tk": 1,
|
|
277
|
+
"name": "LOG",
|
|
278
|
+
"cls": "function",
|
|
279
|
+
"arity": 1,
|
|
280
|
+
"type": "<any: any>",
|
|
281
|
+
"description": "Logs the value to the console and returns the value (identity function)."
|
|
273
282
|
}
|
|
274
283
|
};
|