@graffiticode/basis 1.5.20 → 1.6.0

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graffiticode/basis",
3
3
  "type": "module",
4
- "version": "1.5.20",
4
+ "version": "1.6.0",
5
5
  "description": "The basis library for creating Graffiticode languages",
6
6
  "main": "index.js",
7
7
  "scripts": {
package/spec/spec.html CHANGED
@@ -11,6 +11,11 @@
11
11
  <body><article>
12
12
  <header>
13
13
  <h1>Graffiticode Core Language Specification</h1>
14
+ <section id="intro">
15
+ <pre><code>Version: 0.1.0
16
+ Date: 2025-04-30
17
+ </code></pre>
18
+ </section>
14
19
  <nav class="spec-toc">
15
20
  <div class="title">Contents</div>
16
21
  <ol>
@@ -47,23 +52,27 @@
47
52
  <li><a href="#sec-Types"><span class="spec-secid">5.1</span>Types</a></li>
48
53
  <li><a href="#sec-Built-in-Functions"><span class="spec-secid">5.2</span>Built-in Functions</a><ol>
49
54
  <li><a href="#sec-add"><span class="spec-secid">5.2.1</span>add</a></li>
50
- <li><a href="#sec-sub"><span class="spec-secid">5.2.2</span>sub</a></li>
51
- <li><a href="#sec-mul"><span class="spec-secid">5.2.3</span>mul</a></li>
55
+ <li><a href="#sec-and"><span class="spec-secid">5.2.2</span>and</a></li>
56
+ <li><a href="#sec-apply"><span class="spec-secid">5.2.3</span>apply</a></li>
52
57
  <li><a href="#sec-div"><span class="spec-secid">5.2.4</span>div</a></li>
53
- <li><a href="#sec-mod"><span class="spec-secid">5.2.5</span>mod</a></li>
54
- <li><a href="#sec-min"><span class="spec-secid">5.2.6</span>min</a></li>
55
- <li><a href="#sec-max"><span class="spec-secid">5.2.7</span>max</a></li>
56
- <li><a href="#sec-range"><span class="spec-secid">5.2.8</span>range</a></li>
57
- <li><a href="#sec-map"><span class="spec-secid">5.2.9</span>map</a></li>
58
- <li><a href="#sec-filter"><span class="spec-secid">5.2.10</span>filter</a></li>
59
- <li><a href="#sec-reduce"><span class="spec-secid">5.2.11</span>reduce</a></li>
60
- <li><a href="#sec-hd"><span class="spec-secid">5.2.12</span>hd</a></li>
61
- <li><a href="#sec-tl"><span class="spec-secid">5.2.13</span>tl</a></li>
62
- <li><a href="#sec-nth"><span class="spec-secid">5.2.14</span>nth</a></li>
63
- <li><a href="#sec-apply"><span class="spec-secid">5.2.15</span>apply</a></li>
64
- <li><a href="#sec-isEmpty"><span class="spec-secid">5.2.16</span>isEmpty</a></li>
65
- <li><a href="#sec-get"><span class="spec-secid">5.2.17</span>get</a></li>
66
- <li><a href="#sec-set"><span class="spec-secid">5.2.18</span>set</a></li>
58
+ <li><a href="#sec-equiv"><span class="spec-secid">5.2.5</span>equiv</a></li>
59
+ <li><a href="#sec-filter"><span class="spec-secid">5.2.6</span>filter</a></li>
60
+ <li><a href="#sec-get"><span class="spec-secid">5.2.7</span>get</a></li>
61
+ <li><a href="#sec-hd"><span class="spec-secid">5.2.8</span>hd</a></li>
62
+ <li><a href="#sec-isEmpty"><span class="spec-secid">5.2.9</span>isEmpty</a></li>
63
+ <li><a href="#sec-map"><span class="spec-secid">5.2.10</span>map</a></li>
64
+ <li><a href="#sec-max"><span class="spec-secid">5.2.11</span>max</a></li>
65
+ <li><a href="#sec-min"><span class="spec-secid">5.2.12</span>min</a></li>
66
+ <li><a href="#sec-mod"><span class="spec-secid">5.2.13</span>mod</a></li>
67
+ <li><a href="#sec-mul"><span class="spec-secid">5.2.14</span>mul</a></li>
68
+ <li><a href="#sec-not"><span class="spec-secid">5.2.15</span>not</a></li>
69
+ <li><a href="#sec-nth"><span class="spec-secid">5.2.16</span>nth</a></li>
70
+ <li><a href="#sec-or"><span class="spec-secid">5.2.17</span>or</a></li>
71
+ <li><a href="#sec-range"><span class="spec-secid">5.2.18</span>range</a></li>
72
+ <li><a href="#sec-reduce"><span class="spec-secid">5.2.19</span>reduce</a></li>
73
+ <li><a href="#sec-set"><span class="spec-secid">5.2.20</span>set</a></li>
74
+ <li><a href="#sec-sub"><span class="spec-secid">5.2.21</span>sub</a></li>
75
+ <li><a href="#sec-tl"><span class="spec-secid">5.2.22</span>tl</a></li>
67
76
  </ol>
68
77
  </li>
69
78
  </ol>
@@ -232,14 +241,14 @@ end
232
241
  <td align="left">Adds two numbers</td>
233
242
  </tr>
234
243
  <tr>
235
- <td align="left"><code>sub</code></td>
236
- <td align="left"><code>&lt;number number: number&gt;</code></td>
237
- <td align="left">Subtracts numbers</td>
244
+ <td align="left"><code>and</code></td>
245
+ <td align="left"><code>&lt;bool bool: bool&gt;</code></td>
246
+ <td align="left">Logical AND operation</td>
238
247
  </tr>
239
248
  <tr>
240
- <td align="left"><code>mul</code></td>
241
- <td align="left"><code>&lt;number number: number&gt;</code></td>
242
- <td align="left">Multiplies numbers</td>
249
+ <td align="left"><code>apply</code></td>
250
+ <td align="left"><code>&lt;function list: any&gt;</code></td>
251
+ <td align="left">Applies a function to a list of arguments</td>
243
252
  </tr>
244
253
  <tr>
245
254
  <td align="left"><code>div</code></td>
@@ -247,24 +256,29 @@ end
247
256
  <td align="left">Divides numbers</td>
248
257
  </tr>
249
258
  <tr>
250
- <td align="left"><code>mod</code></td>
251
- <td align="left"><code>&lt;number number: number&gt;</code></td>
252
- <td align="left">Remainder of division</td>
259
+ <td align="left"><code>equiv</code></td>
260
+ <td align="left"><code>&lt;any any: bool&gt;</code></td>
261
+ <td align="left">Tests if two values are strictly equivalent</td>
253
262
  </tr>
254
263
  <tr>
255
- <td align="left"><code>min</code></td>
256
- <td align="left"><code>&lt;number number: number&gt;</code></td>
257
- <td align="left">Returns the smaller of two numbers</td>
264
+ <td align="left"><code>filter</code></td>
265
+ <td align="left"><code>&lt;function list: list&gt;</code></td>
266
+ <td align="left">Keeps items matching predicate</td>
258
267
  </tr>
259
268
  <tr>
260
- <td align="left"><code>max</code></td>
261
- <td align="left"><code>&lt;number number: number&gt;</code></td>
262
- <td align="left">Returns the larger of two numbers</td>
269
+ <td align="left"><code>get</code></td>
270
+ <td align="left"><code>&lt;string record: any&gt;</code></td>
271
+ <td align="left">Retrieves a value from a record by key</td>
263
272
  </tr>
264
273
  <tr>
265
- <td align="left"><code>range</code></td>
266
- <td align="left"><code>&lt;number number number: list&gt;</code></td>
267
- <td align="left">Generates a range list</td>
274
+ <td align="left"><code>hd</code></td>
275
+ <td align="left"><code>&lt;list: any&gt;</code></td>
276
+ <td align="left">First item of list</td>
277
+ </tr>
278
+ <tr>
279
+ <td align="left"><code>isEmpty</code></td>
280
+ <td align="left"><code>&lt;list: bool&gt;</code></td>
281
+ <td align="left">Returns true if the list is empty</td>
268
282
  </tr>
269
283
  <tr>
270
284
  <td align="left"><code>map</code></td>
@@ -272,24 +286,29 @@ end
272
286
  <td align="left">Applies function to each item</td>
273
287
  </tr>
274
288
  <tr>
275
- <td align="left"><code>filter</code></td>
276
- <td align="left"><code>&lt;function list: list&gt;</code></td>
277
- <td align="left">Keeps items matching predicate</td>
289
+ <td align="left"><code>max</code></td>
290
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
291
+ <td align="left">Returns the larger of two numbers</td>
278
292
  </tr>
279
293
  <tr>
280
- <td align="left"><code>reduce</code></td>
281
- <td align="left"><code>&lt;function list: any&gt;</code></td>
282
- <td align="left">Combines list using a reducer</td>
294
+ <td align="left"><code>min</code></td>
295
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
296
+ <td align="left">Returns the smaller of two numbers</td>
283
297
  </tr>
284
298
  <tr>
285
- <td align="left"><code>hd</code></td>
286
- <td align="left"><code>&lt;list: any&gt;</code></td>
287
- <td align="left">First item of list</td>
299
+ <td align="left"><code>mod</code></td>
300
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
301
+ <td align="left">Remainder of division</td>
288
302
  </tr>
289
303
  <tr>
290
- <td align="left"><code>tl</code></td>
291
- <td align="left"><code>&lt;list: list&gt;</code></td>
292
- <td align="left">All items except first</td>
304
+ <td align="left"><code>mul</code></td>
305
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
306
+ <td align="left">Multiplies numbers</td>
307
+ </tr>
308
+ <tr>
309
+ <td align="left"><code>not</code></td>
310
+ <td align="left"><code>&lt;bool: bool&gt;</code></td>
311
+ <td align="left">Logical NOT operation, inverts a boolean value</td>
293
312
  </tr>
294
313
  <tr>
295
314
  <td align="left"><code>nth</code></td>
@@ -297,25 +316,35 @@ end
297
316
  <td align="left">Nth element of list</td>
298
317
  </tr>
299
318
  <tr>
300
- <td align="left"><code>apply</code></td>
301
- <td align="left"><code>&lt;function list: any&gt;</code></td>
302
- <td align="left">Applies a function to a list of arguments</td>
319
+ <td align="left"><code>or</code></td>
320
+ <td align="left"><code>&lt;bool bool: bool&gt;</code></td>
321
+ <td align="left">Logical OR operation</td>
303
322
  </tr>
304
323
  <tr>
305
- <td align="left"><code>isEmpty</code></td>
306
- <td align="left"><code>&lt;list: bool&gt;</code></td>
307
- <td align="left">Returns true if the list is empty</td>
324
+ <td align="left"><code>range</code></td>
325
+ <td align="left"><code>&lt;number number number: list&gt;</code></td>
326
+ <td align="left">Generates a range list</td>
308
327
  </tr>
309
328
  <tr>
310
- <td align="left"><code>get</code></td>
311
- <td align="left"><code>&lt;string record: any&gt;</code></td>
312
- <td align="left">Retrieves a value from a record by key</td>
329
+ <td align="left"><code>reduce</code></td>
330
+ <td align="left"><code>&lt;function any list: any&gt;</code></td>
331
+ <td align="left">Combines list using a reducer with initial value</td>
313
332
  </tr>
314
333
  <tr>
315
334
  <td align="left"><code>set</code></td>
316
335
  <td align="left"><code>&lt;string any record: record&gt;</code></td>
317
336
  <td align="left">Returns a new record with a key set to a value</td>
318
337
  </tr>
338
+ <tr>
339
+ <td align="left"><code>sub</code></td>
340
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
341
+ <td align="left">Subtracts numbers</td>
342
+ </tr>
343
+ <tr>
344
+ <td align="left"><code>tl</code></td>
345
+ <td align="left"><code>&lt;list: list&gt;</code></td>
346
+ <td align="left">All items except first</td>
347
+ </tr>
319
348
  </tbody>
320
349
  </table>
321
350
  <section id="sec-add" secid="5.2.1">
@@ -324,16 +353,19 @@ end
324
353
  <pre><code>add 2 3 | returns 5
325
354
  </code></pre>
326
355
  </section>
327
- <section id="sec-sub" secid="5.2.2">
328
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-sub">5.2.2</a></span>sub</h3>
329
- <p>Subtract the second number from the first</p>
330
- <pre><code>sub 5 2 | returns 3
356
+ <section id="sec-and" secid="5.2.2">
357
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-and">5.2.2</a></span>and</h3>
358
+ <p>Logical AND operation</p>
359
+ <pre><code>and false false | returns false
360
+ and false true | returns false
361
+ and true false | returns false
362
+ and true true | returns true
331
363
  </code></pre>
332
364
  </section>
333
- <section id="sec-mul" secid="5.2.3">
334
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-mul">5.2.3</a></span>mul</h3>
335
- <p>Multiply two numbers</p>
336
- <pre><code>mul 4 3 | returns 12
365
+ <section id="sec-apply" secid="5.2.3">
366
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-apply">5.2.3</a></span>apply</h3>
367
+ <p>Apply a function to an argument list</p>
368
+ <pre><code>apply add [1 2] | returns 3
337
369
  </code></pre>
338
370
  </section>
339
371
  <section id="sec-div" secid="5.2.4">
@@ -342,90 +374,122 @@ end
342
374
  <pre><code>div 10 2 | returns 5
343
375
  </code></pre>
344
376
  </section>
345
- <section id="sec-mod" secid="5.2.5">
346
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-mod">5.2.5</a></span>mod</h3>
347
- <p>Compute the remainder</p>
348
- <pre><code>mod 10 3 | returns 1
377
+ <section id="sec-equiv" secid="5.2.5">
378
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-equiv">5.2.5</a></span>equiv</h3>
379
+ <p>Tests if two values are strictly equivalent</p>
380
+ <pre><code>equiv 1 1 | returns true
381
+ equiv "a" "a" | returns true
382
+ equiv true true | returns true
383
+ equiv 1 2 | returns false
384
+ equiv "a" "b" | returns false
349
385
  </code></pre>
350
386
  </section>
351
- <section id="sec-min" secid="5.2.6">
352
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-min">5.2.6</a></span>min</h3>
353
- <p>Return the smaller of two numbers</p>
354
- <pre><code>min 5 10 | returns 5
387
+ <section id="sec-filter" secid="5.2.6">
388
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-filter">5.2.6</a></span>filter</h3>
389
+ <p>Filter elements matching predicate</p>
390
+ <pre><code>filter (&lt;x: mod x 2&gt;) [1 2 3 4] | returns [1 3]
355
391
  </code></pre>
356
392
  </section>
357
- <section id="sec-max" secid="5.2.7">
358
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-max">5.2.7</a></span>max</h3>
359
- <p>Return the larger of two numbers</p>
360
- <pre><code>max 5 10 | returns 10
393
+ <section id="sec-get" secid="5.2.7">
394
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-get">5.2.7</a></span>get</h3>
395
+ <p>Retrieve a record field</p>
396
+ <pre><code>get "b" {a: 1, b: 2} | returns 2
361
397
  </code></pre>
362
398
  </section>
363
- <section id="sec-range" secid="5.2.8">
364
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-range">5.2.8</a></span>range</h3>
365
- <p>Produce a range list from start to end (exclusive) with step</p>
366
- <pre><code>range 1 10 2 | returns [1 3 5 7 9]
399
+ <section id="sec-hd" secid="5.2.8">
400
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-hd">5.2.8</a></span>hd</h3>
401
+ <p>Return the first item</p>
402
+ <pre><code>hd [10 20 30] | returns 10
403
+ </code></pre>
404
+ </section>
405
+ <section id="sec-isEmpty" secid="5.2.9">
406
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-isEmpty">5.2.9</a></span>isEmpty</h3>
407
+ <p>Return true if list is empty, otherwise return false</p>
408
+ <pre><code>isEmpty [] | returns true
367
409
  </code></pre>
368
410
  </section>
369
- <section id="sec-map" secid="5.2.9">
370
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-map">5.2.9</a></span>map</h3>
411
+ <section id="sec-map" secid="5.2.10">
412
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-map">5.2.10</a></span>map</h3>
371
413
  <p>Apply a function to each element</p>
372
414
  <pre><code>map (&lt;x: add x 1&gt;) [1 2 3] | returns [2 3 4]
373
415
  </code></pre>
374
416
  </section>
375
- <section id="sec-filter" secid="5.2.10">
376
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-filter">5.2.10</a></span>filter</h3>
377
- <p>Filter elements matching predicate</p>
378
- <pre><code>filter (&lt;x: mod x 2&gt;) [1 2 3 4] | returns [1 3]
417
+ <section id="sec-max" secid="5.2.11">
418
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-max">5.2.11</a></span>max</h3>
419
+ <p>Return the larger of two numbers</p>
420
+ <pre><code>max 5 10 | returns 10
379
421
  </code></pre>
380
422
  </section>
381
- <section id="sec-reduce" secid="5.2.11">
382
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-reduce">5.2.11</a></span>reduce</h3>
383
- <p>Reduce a list to a single value, starting with an initial value</p>
384
- <pre><code>reduce (&lt;a b: add a b&gt;) 0 [1 2 3 4] | returns 10
423
+ <section id="sec-min" secid="5.2.12">
424
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-min">5.2.12</a></span>min</h3>
425
+ <p>Return the smaller of two numbers</p>
426
+ <pre><code>min 5 10 | returns 5
385
427
  </code></pre>
386
428
  </section>
387
- <section id="sec-hd" secid="5.2.12">
388
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-hd">5.2.12</a></span>hd</h3>
389
- <p>Return the first item</p>
390
- <pre><code>hd [10 20 30] | returns 10
429
+ <section id="sec-mod" secid="5.2.13">
430
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-mod">5.2.13</a></span>mod</h3>
431
+ <p>Compute the remainder</p>
432
+ <pre><code>mod 10 3 | returns 1
391
433
  </code></pre>
392
434
  </section>
393
- <section id="sec-tl" secid="5.2.13">
394
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-tl">5.2.13</a></span>tl</h3>
395
- <p>Return all but the first item</p>
396
- <pre><code>tl [10 20 30] | returns [20 30]
435
+ <section id="sec-mul" secid="5.2.14">
436
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-mul">5.2.14</a></span>mul</h3>
437
+ <p>Multiply two numbers</p>
438
+ <pre><code>mul 4 3 | returns 12
439
+ </code></pre>
440
+ </section>
441
+ <section id="sec-not" secid="5.2.15">
442
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-not">5.2.15</a></span>not</h3>
443
+ <p>Logical NOT that inverts a boolean value</p>
444
+ <pre><code>not true | returns false
445
+ not false | returns true
397
446
  </code></pre>
398
447
  </section>
399
- <section id="sec-nth" secid="5.2.14">
400
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-nth">5.2.14</a></span>nth</h3>
448
+ <section id="sec-nth" secid="5.2.16">
449
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-nth">5.2.16</a></span>nth</h3>
401
450
  <p>Get the nth item (0-based)</p>
402
451
  <pre><code>nth 1 [10 20 30] | returns 20
403
452
  </code></pre>
404
453
  </section>
405
- <section id="sec-apply" secid="5.2.15">
406
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-apply">5.2.15</a></span>apply</h3>
407
- <p>Apply a function to an argument list</p>
408
- <pre><code>apply add [1 2] | returns 3
454
+ <section id="sec-or" secid="5.2.17">
455
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-or">5.2.17</a></span>or</h3>
456
+ <p>Logical OR operation</p>
457
+ <pre><code>or false false | returns false
458
+ or false true | returns true
459
+ or true false | returns true
460
+ or true true | returns true
409
461
  </code></pre>
410
462
  </section>
411
- <section id="sec-isEmpty" secid="5.2.16">
412
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-isEmpty">5.2.16</a></span>isEmpty</h3>
413
- <p>Return true if list is empty, otherwise return false</p>
414
- <pre><code>isEmpty [] | returns true
463
+ <section id="sec-range" secid="5.2.18">
464
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-range">5.2.18</a></span>range</h3>
465
+ <p>Produce a range list from start to end (exclusive) with step</p>
466
+ <pre><code>range 1 10 2 | returns [1 3 5 7 9]
415
467
  </code></pre>
416
468
  </section>
417
- <section id="sec-get" secid="5.2.17">
418
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-get">5.2.17</a></span>get</h3>
419
- <p>Retrieve a record field</p>
420
- <pre><code>get "b" {a: 1, b: 2} | returns 2
469
+ <section id="sec-reduce" secid="5.2.19">
470
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-reduce">5.2.19</a></span>reduce</h3>
471
+ <p>Reduce a list to a single value, starting with an initial value</p>
472
+ <pre><code>reduce (&lt;a b: add a b&gt;) 0 [1 2 3 4] | returns 10
421
473
  </code></pre>
422
474
  </section>
423
- <section id="sec-set" secid="5.2.18">
424
- <h3><span class="spec-secid" title="link to this section"><a href="#sec-set">5.2.18</a></span>set</h3>
475
+ <section id="sec-set" secid="5.2.20">
476
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-set">5.2.20</a></span>set</h3>
425
477
  <p>Return a new record with an updated field</p>
426
478
  <pre><code>set "a" 2 {a: 1} | returns {a: 2}
427
479
  </code></pre>
428
480
  </section>
481
+ <section id="sec-sub" secid="5.2.21">
482
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-sub">5.2.21</a></span>sub</h3>
483
+ <p>Subtract the second number from the first</p>
484
+ <pre><code>sub 5 2 | returns 3
485
+ </code></pre>
486
+ </section>
487
+ <section id="sec-tl" secid="5.2.22">
488
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-tl">5.2.22</a></span>tl</h3>
489
+ <p>Return all but the first item</p>
490
+ <pre><code>tl [10 20 30] | returns [20 30]
491
+ </code></pre>
492
+ </section>
429
493
  </section>
430
494
  </section>
431
495
  <section id="sec-Program-Examples" secid="6">
@@ -501,23 +565,27 @@ Written in <a href="https://spec-md.com" target="_blank">Spec Markdown</a>.</foo
501
565
  <input hidden class="toggle" type="checkbox" id="_toggle_5.2" /><label for="_toggle_5.2"></label>
502
566
  <ol>
503
567
  <li id="_sidebar_5.2.1"><a href="#sec-add"><span class="spec-secid">5.2.1</span>add</a></li>
504
- <li id="_sidebar_5.2.2"><a href="#sec-sub"><span class="spec-secid">5.2.2</span>sub</a></li>
505
- <li id="_sidebar_5.2.3"><a href="#sec-mul"><span class="spec-secid">5.2.3</span>mul</a></li>
568
+ <li id="_sidebar_5.2.2"><a href="#sec-and"><span class="spec-secid">5.2.2</span>and</a></li>
569
+ <li id="_sidebar_5.2.3"><a href="#sec-apply"><span class="spec-secid">5.2.3</span>apply</a></li>
506
570
  <li id="_sidebar_5.2.4"><a href="#sec-div"><span class="spec-secid">5.2.4</span>div</a></li>
507
- <li id="_sidebar_5.2.5"><a href="#sec-mod"><span class="spec-secid">5.2.5</span>mod</a></li>
508
- <li id="_sidebar_5.2.6"><a href="#sec-min"><span class="spec-secid">5.2.6</span>min</a></li>
509
- <li id="_sidebar_5.2.7"><a href="#sec-max"><span class="spec-secid">5.2.7</span>max</a></li>
510
- <li id="_sidebar_5.2.8"><a href="#sec-range"><span class="spec-secid">5.2.8</span>range</a></li>
511
- <li id="_sidebar_5.2.9"><a href="#sec-map"><span class="spec-secid">5.2.9</span>map</a></li>
512
- <li id="_sidebar_5.2.10"><a href="#sec-filter"><span class="spec-secid">5.2.10</span>filter</a></li>
513
- <li id="_sidebar_5.2.11"><a href="#sec-reduce"><span class="spec-secid">5.2.11</span>reduce</a></li>
514
- <li id="_sidebar_5.2.12"><a href="#sec-hd"><span class="spec-secid">5.2.12</span>hd</a></li>
515
- <li id="_sidebar_5.2.13"><a href="#sec-tl"><span class="spec-secid">5.2.13</span>tl</a></li>
516
- <li id="_sidebar_5.2.14"><a href="#sec-nth"><span class="spec-secid">5.2.14</span>nth</a></li>
517
- <li id="_sidebar_5.2.15"><a href="#sec-apply"><span class="spec-secid">5.2.15</span>apply</a></li>
518
- <li id="_sidebar_5.2.16"><a href="#sec-isEmpty"><span class="spec-secid">5.2.16</span>isEmpty</a></li>
519
- <li id="_sidebar_5.2.17"><a href="#sec-get"><span class="spec-secid">5.2.17</span>get</a></li>
520
- <li id="_sidebar_5.2.18"><a href="#sec-set"><span class="spec-secid">5.2.18</span>set</a></li>
571
+ <li id="_sidebar_5.2.5"><a href="#sec-equiv"><span class="spec-secid">5.2.5</span>equiv</a></li>
572
+ <li id="_sidebar_5.2.6"><a href="#sec-filter"><span class="spec-secid">5.2.6</span>filter</a></li>
573
+ <li id="_sidebar_5.2.7"><a href="#sec-get"><span class="spec-secid">5.2.7</span>get</a></li>
574
+ <li id="_sidebar_5.2.8"><a href="#sec-hd"><span class="spec-secid">5.2.8</span>hd</a></li>
575
+ <li id="_sidebar_5.2.9"><a href="#sec-isEmpty"><span class="spec-secid">5.2.9</span>isEmpty</a></li>
576
+ <li id="_sidebar_5.2.10"><a href="#sec-map"><span class="spec-secid">5.2.10</span>map</a></li>
577
+ <li id="_sidebar_5.2.11"><a href="#sec-max"><span class="spec-secid">5.2.11</span>max</a></li>
578
+ <li id="_sidebar_5.2.12"><a href="#sec-min"><span class="spec-secid">5.2.12</span>min</a></li>
579
+ <li id="_sidebar_5.2.13"><a href="#sec-mod"><span class="spec-secid">5.2.13</span>mod</a></li>
580
+ <li id="_sidebar_5.2.14"><a href="#sec-mul"><span class="spec-secid">5.2.14</span>mul</a></li>
581
+ <li id="_sidebar_5.2.15"><a href="#sec-not"><span class="spec-secid">5.2.15</span>not</a></li>
582
+ <li id="_sidebar_5.2.16"><a href="#sec-nth"><span class="spec-secid">5.2.16</span>nth</a></li>
583
+ <li id="_sidebar_5.2.17"><a href="#sec-or"><span class="spec-secid">5.2.17</span>or</a></li>
584
+ <li id="_sidebar_5.2.18"><a href="#sec-range"><span class="spec-secid">5.2.18</span>range</a></li>
585
+ <li id="_sidebar_5.2.19"><a href="#sec-reduce"><span class="spec-secid">5.2.19</span>reduce</a></li>
586
+ <li id="_sidebar_5.2.20"><a href="#sec-set"><span class="spec-secid">5.2.20</span>set</a></li>
587
+ <li id="_sidebar_5.2.21"><a href="#sec-sub"><span class="spec-secid">5.2.21</span>sub</a></li>
588
+ <li id="_sidebar_5.2.22"><a href="#sec-tl"><span class="spec-secid">5.2.22</span>tl</a></li>
521
589
  </ol>
522
590
  </li>
523
591
  </ol>
package/spec/spec.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Graffiticode Core Language Specification
2
2
 
3
+ ```
4
+ Version: 0.1.0
5
+ Date: 2025-04-30
6
+ ```
7
+
3
8
  # Introduction
4
9
 
5
10
  This document defines the **Graffiticode Core Language Specification**, covering syntax, semantics, and the base library. It excludes dialect-specific constructs, runtime behavior, and extended libraries.
@@ -160,23 +165,27 @@ This approach draws inspiration from **Model-View-Update** (MVU) architectures,
160
165
  | Function | Signature | Description |
161
166
  | :------- | :-------- | :---------- |
162
167
  | `add` | `<number number: number>` | Adds two numbers |
163
- | `sub` | `<number number: number>` | Subtracts numbers |
164
- | `mul` | `<number number: number>` | Multiplies numbers |
168
+ | `and` | `<bool bool: bool>` | Logical AND operation |
169
+ | `apply` | `<function list: any>` | Applies a function to a list of arguments |
165
170
  | `div` | `<number number: number>` | Divides numbers |
166
- | `mod` | `<number number: number>` | Remainder of division |
167
- | `min` | `<number number: number>` | Returns the smaller of two numbers |
168
- | `max` | `<number number: number>` | Returns the larger of two numbers |
169
- | `range` | `<number number number: list>` | Generates a range list |
170
- | `map` | `<function list: list>` | Applies function to each item |
171
+ | `equiv` | `<any any: bool>` | Tests if two values are strictly equivalent |
171
172
  | `filter` | `<function list: list>` | Keeps items matching predicate |
172
- | `reduce` | `<function list: any>` | Combines list using a reducer |
173
+ | `get` | `<string record: any>` | Retrieves a value from a record by key |
173
174
  | `hd` | `<list: any>` | First item of list |
174
- | `tl` | `<list: list>` | All items except first |
175
- | `nth` | `<number list: any>` | Nth element of list |
176
- | `apply` | `<function list: any>` | Applies a function to a list of arguments |
177
175
  | `isEmpty` | `<list: bool>` | Returns true if the list is empty |
178
- | `get` | `<string record: any>` | Retrieves a value from a record by key |
176
+ | `map` | `<function list: list>` | Applies function to each item |
177
+ | `max` | `<number number: number>` | Returns the larger of two numbers |
178
+ | `min` | `<number number: number>` | Returns the smaller of two numbers |
179
+ | `mod` | `<number number: number>` | Remainder of division |
180
+ | `mul` | `<number number: number>` | Multiplies numbers |
181
+ | `not` | `<bool: bool>` | Logical NOT operation, inverts a boolean value |
182
+ | `nth` | `<number list: any>` | Nth element of list |
183
+ | `or` | `<bool bool: bool>` | Logical OR operation |
184
+ | `range` | `<number number number: list>` | Generates a range list |
185
+ | `reduce` | `<function any list: any>` | Combines list using a reducer with initial value |
179
186
  | `set` | `<string any record: record>` | Returns a new record with a key set to a value |
187
+ | `sub` | `<number number: number>` | Subtracts numbers |
188
+ | `tl` | `<list: list>` | All items except first |
180
189
 
181
190
  ### add
182
191
 
@@ -186,20 +195,23 @@ Add two numbers.
186
195
  add 2 3 | returns 5
187
196
  ```
188
197
 
189
- ### sub
198
+ ### and
190
199
 
191
- Subtract the second number from the first
200
+ Logical AND operation
192
201
 
193
202
  ```
194
- sub 5 2 | returns 3
203
+ and false false | returns false
204
+ and false true | returns false
205
+ and true false | returns false
206
+ and true true | returns true
195
207
  ```
196
208
 
197
- ### mul
209
+ ### apply
198
210
 
199
- Multiply two numbers
211
+ Apply a function to an argument list
200
212
 
201
213
  ```
202
- mul 4 3 | returns 12
214
+ apply add [1 2] | returns 3
203
215
  ```
204
216
 
205
217
  ### div
@@ -210,36 +222,48 @@ Divide the first number by the second
210
222
  div 10 2 | returns 5
211
223
  ```
212
224
 
213
- ### mod
225
+ ### equiv
214
226
 
215
- Compute the remainder
227
+ Tests if two values are strictly equivalent
216
228
 
217
229
  ```
218
- mod 10 3 | returns 1
230
+ equiv 1 1 | returns true
231
+ equiv "a" "a" | returns true
232
+ equiv true true | returns true
233
+ equiv 1 2 | returns false
234
+ equiv "a" "b" | returns false
219
235
  ```
220
236
 
221
- ### min
237
+ ### filter
222
238
 
223
- Return the smaller of two numbers
239
+ Filter elements matching predicate
224
240
 
225
241
  ```
226
- min 5 10 | returns 5
242
+ filter (<x: mod x 2>) [1 2 3 4] | returns [1 3]
227
243
  ```
228
244
 
229
- ### max
245
+ ### get
230
246
 
231
- Return the larger of two numbers
247
+ Retrieve a record field
232
248
 
233
249
  ```
234
- max 5 10 | returns 10
250
+ get "b" {a: 1, b: 2} | returns 2
235
251
  ```
236
252
 
237
- ### range
253
+ ### hd
238
254
 
239
- Produce a range list from start to end (exclusive) with step
255
+ Return the first item
240
256
 
241
257
  ```
242
- range 1 10 2 | returns [1 3 5 7 9]
258
+ hd [10 20 30] | returns 10
259
+ ```
260
+
261
+ ### isEmpty
262
+
263
+ Return true if list is empty, otherwise return false
264
+
265
+ ```
266
+ isEmpty [] | returns true
243
267
  ```
244
268
 
245
269
  ### map
@@ -250,36 +274,45 @@ Apply a function to each element
250
274
  map (<x: add x 1>) [1 2 3] | returns [2 3 4]
251
275
  ```
252
276
 
253
- ### filter
277
+ ### max
254
278
 
255
- Filter elements matching predicate
279
+ Return the larger of two numbers
256
280
 
257
281
  ```
258
- filter (<x: mod x 2>) [1 2 3 4] | returns [1 3]
282
+ max 5 10 | returns 10
259
283
  ```
260
284
 
261
- ### reduce
285
+ ### min
262
286
 
263
- Reduce a list to a single value, starting with an initial value
287
+ Return the smaller of two numbers
264
288
 
265
289
  ```
266
- reduce (<a b: add a b>) 0 [1 2 3 4] | returns 10
290
+ min 5 10 | returns 5
267
291
  ```
268
292
 
269
- ### hd
293
+ ### mod
270
294
 
271
- Return the first item
295
+ Compute the remainder
272
296
 
273
297
  ```
274
- hd [10 20 30] | returns 10
298
+ mod 10 3 | returns 1
275
299
  ```
276
300
 
277
- ### tl
301
+ ### mul
278
302
 
279
- Return all but the first item
303
+ Multiply two numbers
280
304
 
281
305
  ```
282
- tl [10 20 30] | returns [20 30]
306
+ mul 4 3 | returns 12
307
+ ```
308
+
309
+ ### not
310
+
311
+ Logical NOT that inverts a boolean value
312
+
313
+ ```
314
+ not true | returns false
315
+ not false | returns true
283
316
  ```
284
317
 
285
318
  ### nth
@@ -290,28 +323,31 @@ Get the nth item (0-based)
290
323
  nth 1 [10 20 30] | returns 20
291
324
  ```
292
325
 
293
- ### apply
326
+ ### or
294
327
 
295
- Apply a function to an argument list
328
+ Logical OR operation
296
329
 
297
330
  ```
298
- apply add [1 2] | returns 3
331
+ or false false | returns false
332
+ or false true | returns true
333
+ or true false | returns true
334
+ or true true | returns true
299
335
  ```
300
336
 
301
- ### isEmpty
337
+ ### range
302
338
 
303
- Return true if list is empty, otherwise return false
339
+ Produce a range list from start to end (exclusive) with step
304
340
 
305
341
  ```
306
- isEmpty [] | returns true
342
+ range 1 10 2 | returns [1 3 5 7 9]
307
343
  ```
308
344
 
309
- ### get
345
+ ### reduce
310
346
 
311
- Retrieve a record field
347
+ Reduce a list to a single value, starting with an initial value
312
348
 
313
349
  ```
314
- get "b" {a: 1, b: 2} | returns 2
350
+ reduce (<a b: add a b>) 0 [1 2 3 4] | returns 10
315
351
  ```
316
352
 
317
353
  ### set
@@ -322,6 +358,22 @@ Return a new record with an updated field
322
358
  set "a" 2 {a: 1} | returns {a: 2}
323
359
  ```
324
360
 
361
+ ### sub
362
+
363
+ Subtract the second number from the first
364
+
365
+ ```
366
+ sub 5 2 | returns 3
367
+ ```
368
+
369
+ ### tl
370
+
371
+ Return all but the first item
372
+
373
+ ```
374
+ tl [10 20 30] | returns [20 30]
375
+ ```
376
+
325
377
  # Program Examples
326
378
 
327
379
  ```
package/src/compiler.js CHANGED
@@ -38,6 +38,7 @@ class Visitor {
38
38
  // "Visitor/visit()",
39
39
  // "nodePool=" + JSON.stringify(this.nodePool, null, 2),
40
40
  // "node.tag=" + node.tag,
41
+ // "options=" + JSON.stringify(options, null, 2),
41
42
  // );
42
43
  const fn = (this[node.tag] || this["CATCH_ALL"])?.bind(this);
43
44
  assert(node && node.tag && node.elts, "2000: Visitor.visit() tag=" + node.tag + " elts= " + JSON.stringify(node.elts));
@@ -481,6 +482,30 @@ export class Checker extends Visitor {
481
482
  });
482
483
  });
483
484
  }
485
+ HD(node, options, resume) {
486
+ this.visit(node.elts[0], options, (err1, val1) => {
487
+ let err = [].concat(err1);
488
+ // if (!Array.isArray(val1)) {
489
+ // err.push(`HD operation requires a list argument, got ${typeof val1}`);
490
+ // } else if (val1.length === 0) {
491
+ // err.push(`HD operation called on an empty list`);
492
+ // }
493
+ const val = node;
494
+ resume(err, val);
495
+ });
496
+ }
497
+ TL(node, options, resume) {
498
+ this.visit(node.elts[0], options, (err1, val1) => {
499
+ let err = [].concat(err1);
500
+ // if (!Array.isArray(val1)) {
501
+ // err.push(`TL operation requires a list argument, got ${typeof val1}`);
502
+ // } else if (val1.length === 0) {
503
+ // err.push(`TL operation called on an empty list`);
504
+ // }
505
+ const val = node;
506
+ resume(err, val);
507
+ });
508
+ }
484
509
  }
485
510
 
486
511
  function enterEnv(ctx, name, paramc) {
@@ -1299,6 +1324,46 @@ export class Transformer extends Visitor {
1299
1324
  });
1300
1325
  });
1301
1326
  }
1327
+ HD(node, options, resume) {
1328
+ this.visit(node.elts[0], options, (e0, v0) => {
1329
+ const err = [].concat(e0);
1330
+ try {
1331
+ if (!Array.isArray(v0)) {
1332
+ resume([...err, `Error in HD operation: expected an array, got ${typeof v0}`], null);
1333
+ return;
1334
+ }
1335
+ if (v0.length === 0) {
1336
+ resume([...err, `Error in HD operation: empty array has no head`], null);
1337
+ return;
1338
+ }
1339
+ // Return the first element of the array
1340
+ const val = v0[0];
1341
+ resume(err, val);
1342
+ } catch (e) {
1343
+ resume([...err, `Error in HD operation: ${e.message}`], null);
1344
+ }
1345
+ });
1346
+ }
1347
+ TL(node, options, resume) {
1348
+ this.visit(node.elts[0], options, (e0, v0) => {
1349
+ const err = [].concat(e0);
1350
+ try {
1351
+ if (!Array.isArray(v0)) {
1352
+ resume([...err, `Error in TL operation: expected an array, got ${typeof v0}`], []);
1353
+ return;
1354
+ }
1355
+ if (v0.length === 0) {
1356
+ resume([...err, `Error in TL operation: empty array has no tail`], []);
1357
+ return;
1358
+ }
1359
+ // Return all elements except the first
1360
+ const val = v0.slice(1);
1361
+ resume(err, val);
1362
+ } catch (e) {
1363
+ resume([...err, `Error in TL operation: ${e.message}`], []);
1364
+ }
1365
+ });
1366
+ }
1302
1367
  }
1303
1368
 
1304
1369
  export class Renderer {
package/src/lexicon.js CHANGED
@@ -1,221 +1,274 @@
1
- export const lexicon = {
2
- "print" : {
1
+ export default {
2
+ "print": {
3
3
  "tk": 1,
4
4
  "name": "PRINT",
5
5
  "cls": "function",
6
6
  "length": 1,
7
- "arity": 1
7
+ "arity": 1,
8
+ "description": "Outputs a value to the form."
8
9
  },
9
- "get" : {
10
+ "get": {
10
11
  "tk": 1,
11
12
  "name": "GET",
12
13
  "cls": "function",
13
14
  "length": 2,
14
15
  "arity": 2,
15
- "args": ["key", "record"]
16
+ "description": "Retrieves a value from a record or list by key or index."
16
17
  },
17
- "set" : {
18
+ "set": {
18
19
  "tk": 1,
19
20
  "name": "SET",
20
21
  "cls": "function",
21
22
  "length": 3,
22
23
  "arity": 3,
23
- "args": ["key", "value", "record"]
24
+ "description": "Returns a new record or list with the specified key or index updated."
24
25
  },
25
- "nth" : {
26
+ "nth": {
26
27
  "tk": 1,
27
28
  "name": "NTH",
28
29
  "cls": "function",
29
30
  "length": 2,
30
- "arity": 2
31
+ "arity": 2,
32
+ "description": "Returns the nth element of a list by index."
31
33
  },
32
- "sub" : {
34
+ "sub": {
33
35
  "tk": 1,
34
36
  "name": "SUB",
35
37
  "cls": "function",
36
38
  "length": 2,
37
- "arity": 2
39
+ "arity": 2,
40
+ "description": "Subtracts the second number from the first."
38
41
  },
39
- "filter" : {
42
+ "filter": {
40
43
  "tk": 1,
41
44
  "name": "FILTER",
42
45
  "cls": "function",
43
46
  "length": 2,
44
- "arity": 2
47
+ "arity": 2,
48
+ "description": "Returns a list of elements that match a predicate."
45
49
  },
46
- "reduce" : {
50
+ "reduce": {
47
51
  "tk": 1,
48
52
  "name": "REDUCE",
49
53
  "cls": "function",
50
54
  "length": 3,
51
- "arity": 3
55
+ "arity": 3,
56
+ "description": "Reduces a list to a single value using a binary function and initial value."
52
57
  },
53
- "map" : {
58
+ "map": {
54
59
  "tk": 1,
55
60
  "name": "MAP",
56
61
  "cls": "function",
57
62
  "length": 2,
58
- "arity": 2
63
+ "arity": 2,
64
+ "description": "Applies a function to each element in a list and returns a new list."
59
65
  },
60
- "lt" : {
66
+ "lt": {
61
67
  "tk": 1,
62
68
  "name": "LT",
63
69
  "cls": "function",
64
70
  "length": 2,
65
- "arity": 2
71
+ "arity": 2,
72
+ "description": "Returns true if the first value is less than the second."
66
73
  },
67
- "le" : {
74
+ "le": {
68
75
  "tk": 1,
69
76
  "name": "LE",
70
77
  "cls": "function",
71
78
  "length": 2,
72
- "arity": 2
79
+ "arity": 2,
80
+ "description": "Returns true if the first value is less than or equal to the second."
73
81
  },
74
- "gt" : {
82
+ "gt": {
75
83
  "tk": 1,
76
84
  "name": "GT",
77
85
  "cls": "function",
78
86
  "length": 2,
79
- "arity": 2
87
+ "arity": 2,
88
+ "description": "Returns true if the first value is greater than the second."
80
89
  },
81
- "ge" : {
90
+ "ge": {
82
91
  "tk": 1,
83
92
  "name": "GE",
84
93
  "cls": "function",
85
94
  "length": 2,
86
- "arity": 2
95
+ "arity": 2,
96
+ "description": "Returns true if the first value is greater than or equal to the second."
87
97
  },
88
- "ne" : {
98
+ "ne": {
89
99
  "tk": 1,
90
100
  "name": "NE",
91
101
  "cls": "function",
92
102
  "length": 2,
93
- "arity": 2
103
+ "arity": 2,
104
+ "description": "Returns true if the two values are not equal."
94
105
  },
95
- "len" : {
106
+ "len": {
96
107
  "tk": 1,
97
108
  "name": "LEN",
98
109
  "cls": "function",
99
110
  "length": 1,
100
- "arity": 1
111
+ "arity": 1,
112
+ "description": "Returns the length of a list or string."
101
113
  },
102
- "concat" : {
114
+ "concat": {
103
115
  "tk": 1,
104
116
  "name": "CONCAT",
105
117
  "cls": "function",
106
118
  "length": 1,
107
- "arity": 1
119
+ "arity": 1,
120
+ "description": "Concatenates a list of strings or nested lists."
108
121
  },
109
- "add" : {
122
+ "add": {
110
123
  "tk": 1,
111
124
  "name": "ADD",
112
125
  "cls": "function",
113
126
  "length": 2,
114
- "arity": 2
127
+ "arity": 2,
128
+ "description": "Adds two numbers."
115
129
  },
116
- "mul" : {
130
+ "mul": {
117
131
  "tk": 1,
118
132
  "name": "MUL",
119
133
  "cls": "function",
120
134
  "length": 2,
121
- "arity": 2
135
+ "arity": 2,
136
+ "description": "Multiplies two numbers."
122
137
  },
123
- "pow" : {
138
+ "pow": {
124
139
  "tk": 1,
125
140
  "name": "POW",
126
141
  "cls": "function",
127
142
  "length": 2,
128
- "arity": 2
129
- },
130
- "map" : {
131
- "tk": 1,
132
- "name": "MAP",
133
- "cls": "function",
134
- "length": 2,
135
- "arity": 2
143
+ "arity": 2,
144
+ "description": "Raises the first number to the power of the second."
136
145
  },
137
- "apply" : {
146
+ "apply": {
138
147
  "tk": 1,
139
148
  "name": "APPLY",
140
149
  "cls": "function",
141
150
  "length": 2,
142
- "arity": 2
151
+ "arity": 2,
152
+ "description": "Applies a function to a list of arguments."
143
153
  },
144
- "data" : {
154
+ "data": {
145
155
  "tk": 1,
146
156
  "name": "DATA",
147
157
  "cls": "function",
148
158
  "length": 1,
149
- "arity": 1
159
+ "arity": 1,
160
+ "description": "Returns the raw data payload from a structured input."
150
161
  },
151
- "json" : {
162
+ "json": {
152
163
  "tk": 1,
153
164
  "name": "JSON",
154
165
  "cls": "function",
155
166
  "length": 1,
156
- "arity": 1
167
+ "arity": 1,
168
+ "description": "Parses a string as JSON or serializes a value to JSON."
157
169
  },
158
- "eq" : {
170
+ "eq": {
159
171
  "tk": 1,
160
172
  "name": "EQ",
161
173
  "cls": "function",
162
174
  "length": 2,
163
- "arity": 2
175
+ "arity": 2,
176
+ "description": "Returns true if the two values are equal."
164
177
  },
165
- "mod" : {
178
+ "mod": {
166
179
  "tk": 1,
167
180
  "name": "MOD",
168
181
  "cls": "function",
169
182
  "length": 2,
170
- "arity": 2
183
+ "arity": 2,
184
+ "description": "Returns the remainder of dividing the first number by the second."
171
185
  },
172
- "min" : {
186
+ "min": {
173
187
  "tk": 1,
174
188
  "name": "MIN",
175
189
  "cls": "function",
176
190
  "length": 2,
177
- "arity": 2
191
+ "arity": 2,
192
+ "description": "Returns the smaller of two values."
178
193
  },
179
- "max" : {
194
+ "max": {
180
195
  "tk": 1,
181
196
  "name": "MAX",
182
197
  "cls": "function",
183
198
  "length": 2,
184
- "arity": 2
199
+ "arity": 2,
200
+ "description": "Returns the larger of two values."
185
201
  },
186
- "range" : {
202
+ "range": {
187
203
  "tk": 1,
188
204
  "name": "RANGE",
189
205
  "cls": "function",
190
206
  "length": 3,
191
- "arity": 3
207
+ "arity": 3,
208
+ "description": "Generates a list of numbers from start to end using a step."
192
209
  },
193
- "not" : {
210
+ "not": {
194
211
  "tk": 1,
195
212
  "name": "NOT",
196
213
  "cls": "function",
197
214
  "length": 1,
198
- "arity": 1
215
+ "arity": 1,
216
+ "description": "Returns the logical negation of a boolean value."
199
217
  },
200
- "equiv" : {
218
+ "equiv": {
201
219
  "tk": 1,
202
220
  "name": "EQUIV",
203
221
  "cls": "function",
204
222
  "length": 2,
205
- "arity": 2
223
+ "arity": 2,
224
+ "description": "Returns true if the two values are semantically equivalent."
206
225
  },
207
- "or" : {
226
+ "or": {
208
227
  "tk": 1,
209
228
  "name": "OR",
210
229
  "cls": "function",
211
230
  "length": 2,
212
- "arity": 2
231
+ "arity": 2,
232
+ "description": "Returns true if at least one of the two values is true."
213
233
  },
214
- "and" : {
234
+ "and": {
215
235
  "tk": 1,
216
236
  "name": "AND",
217
237
  "cls": "function",
218
238
  "length": 2,
219
- "arity": 2
239
+ "arity": 2,
240
+ "description": "Returns true if both values are true."
241
+ },
242
+ "hd": {
243
+ "tk": 1,
244
+ "name": "HD",
245
+ "cls": "function",
246
+ "length": 1,
247
+ "arity": 1,
248
+ "description": "Returns the first element of a list."
249
+ },
250
+ "tl": {
251
+ "tk": 1,
252
+ "name": "TL",
253
+ "cls": "function",
254
+ "length": 1,
255
+ "arity": 1,
256
+ "description": "Returns the list without its first element."
257
+ },
258
+ "cons": {
259
+ "tk": 1,
260
+ "name": "CONS",
261
+ "cls": "function",
262
+ "length": 2,
263
+ "arity": 2,
264
+ "description": "Prepends an element to the front of a list."
265
+ },
266
+ "append": {
267
+ "tk": 1,
268
+ "name": "APPEND",
269
+ "cls": "function",
270
+ "length": 2,
271
+ "arity": 2,
272
+ "description": "Appends an element to the end of a list."
220
273
  }
221
- }
274
+ };