@graffiticode/basis 1.5.16 → 1.5.18

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/index.js CHANGED
@@ -3,3 +3,4 @@ export const Checker = basis.Checker;
3
3
  export const Transformer = basis.Transformer;
4
4
  export const Renderer = basis.Renderer;
5
5
  export const Compiler = basis.Compiler;
6
+ export { lexicon } from "./src/lexicon.js";
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@graffiticode/basis",
3
3
  "type": "module",
4
- "version": "1.5.16",
4
+ "version": "1.5.18",
5
5
  "description": "The basis library for creating Graffiticode languages",
6
6
  "main": "index.js",
7
7
  "scripts": {
8
- "test": "jest"
8
+ "test": "jest",
9
+ "build-spec": "npx spec-md ./spec/spec.md > ./spec/spec.html",
10
+ "watch-spec": "npx nodemon --exec 'npx spec-md > ./spec/spec.html' ./spec/spec.md"
9
11
  },
10
12
  "engines": {
11
13
  "node": "22.x"
package/spec/spec.html ADDED
@@ -0,0 +1,528 @@
1
+ <!DOCTYPE html>
2
+ <!-- Built with spec-md https://spec-md.com -->
3
+ <html>
4
+ <head><meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1"><title>Graffiticode Core Language Specification</title>
6
+ <style>@media (prefers-color-scheme: light){:root{--color-foreground: #333333;--color-background: #ffffff;--color-light-grey: #ccc;--color-grey: #666666;--color-white: #fff;--color-link: #3b5998;--color-subsection-link: var(--color-foreground);--color-toc-link: var(--color-foreground);--color-toc-id: var(--color-link);--color-toggle-border: #bbc;--color-sidebar-background: #f0f0f0;--color-sidebar-viewing-link: #8b9;--color-sidebar-toggle-button: rgba(0, 0, 0, .7);--color-sidebar-shadow-inset: rgba(0, 0, 0, .05);--color-sidebar-shadow: rgba(0, 0, 0, .04);--color-sidebar-large-shadow: rgba(0, 0, 0, .08);--color-pre-background: #fafafa;--color-pre-border: #e9e9e9;--color-code-background: rgba(0, 0, 0, .03);--color-spec-todo: var(--color-grey);--color-spec-example: #fafaff;--color-spec-example-border: #bbbbff;--color-spec-counter-example: #fffafa;--color-spec-counter-border: #ffbbbb;--color-spec-counter-example-link: #98593b;--color-spec-added-border: #396;--color-spec-removed-border: #933;--color-spec-prose: var(--color-grey);--color-spec-quantifier-list: var(--color-link);--color-spec-quantifier-optional: #83238e;--color-spec-condition: #1c7758;--color-spec-param: var(--color-grey);--color-spec-rx: var(--color-foreground);--color-spec-note-border: #f4e925;--color-spec-note-background: #fefef3;--color-spec-note-first-link: #6c6613;--color-source-link: var(--color-light-grey);--color-table-header: #f9f9f9;--color-table-header-border: #d0d0d0;--color-token-inserted: hsla(241, 71%, 34%, .69);--color-token-deleted: hsla(324, 92%, 33%, .74);--color-inserts-background: rgba(0, 200, 30, .08);--color-deletions-background: rgba(200, 0, 0, .08);--selection-background-color: #cacee0;--selection-background-color-link: #f0babe}.selection-link:hover{--selection-background-color: #3b5998}}@media (prefers-color-scheme: dark){:root{--color-foreground: #b6b6b6;--color-background: #262626;--color-light-grey: #373737;--color-grey: #828282;--color-white: rgb(29, 29, 29);--color-link: #89b7da;--color-subsection-link: var(--color-foreground);--color-toc-link: var(--color-foreground);--color-toc-id: var(--color-link);--color-toggle-border: #bbc;--color-sidebar-background: #323232;--color-sidebar-viewing-link: #8b9;--color-sidebar-toggle-button: rgba(220, 220, 220, .7);--color-sidebar-shadow-inset: rgba(0, 0, 0, .05);--color-sidebar-shadow: rgba(0, 0, 0, .04);--color-sidebar-large-shadow: rgba(0, 0, 0, .08);--color-pre-background: #2e2e2e;--color-pre-border: #3a3a3a;--color-code-background: rgba(41, 41, 41, .03);--color-spec-todo: var(--color-grey);--color-spec-example: #2b2b35;--color-spec-example-border: #4d4d6d;--color-spec-counter-example: #322828;--color-spec-counter-border: #664040;--color-spec-counter-example-link: #ff702d;--color-spec-added-border: #396;--color-spec-removed-border: #933;--color-spec-prose: var(--color-grey);--color-spec-quantifier-list: var(--color-link);--color-spec-quantifier-optional: #c689ce;--color-spec-condition: #6fa889;--color-spec-param: var(--color-grey);--color-spec-rx: var(--color-foreground);--color-spec-note-border: #605e39;--color-spec-note-background: #303028;--color-spec-note-first-link: #f0e330;--color-source-link: var(--color-grey);--color-table-header: #373737;--color-table-header-border: #525252;--color-token-inserted: hsla(241, 63%, 70%, .69);--color-token-deleted: hsla(325, 64%, 67%, .74);--color-inserts-background: rgba(0, 200, 30, .08);--color-deletions-background: rgba(200, 0, 0, .08);--selection-background-color: #656565;--selection-background-color-link: #f0babe}.selection-link:hover{--selection-background-color: #829edb}}:root{color:var(--color-foreground);background-color:var(--color-background);font-family:var(--font-family);font-size:15px;line-height:1.5;--mono-font-size: 13px;--indent: 1rem;--list-indent: 1.5rem;--dfn-indent: 0rem;--font-family: Cambria, "Palatino Linotype", Palatino, "Liberation Serif", serif;--font-family-monospace: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace}@media (min-width: 720px){:root{font-size:17px;--mono-font-size: 15px;--indent: 2rem;--list-indent: 2rem;--dfn-indent: 2rem}}body{margin:3rem 0 3rem}article{margin:0 1rem}@media (min-width: 720px){body{margin:6rem auto 3rem;max-width:800px;padding-left:75px;padding-right:clamp(0px,calc((100vw - 800px) * .25),75px)}}.source-link{display:none}@media screen and (min-width: 720px){.source-link{display:block;position:absolute;width:18px;fill:var(--color-source-link);opacity:.3}.source-link:hover{opacity:1}}.outdated-selection-link,.selection-link{position:absolute;display:block;color:var(--color-white);background:var(--selection-background-color);border-radius:4px;font-size:36px;height:23px;line-height:48px;text-align:center;text-decoration:none;width:25px;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.outdated-selection-link:hover,.selection-link:hover{text-decoration:none}.outdated-selection-link:before,.selection-link:before{border:5px solid transparent;content:"";height:0;margin-top:-5px;margin-right:-5px;position:absolute;right:1px;top:50%;width:0}@media (max-width: 719px){.outdated-selection-link:before,.selection-link:before{border-bottom-color:var(--selection-background-color);border-top:0;right:50%;top:1px}}@media (min-width: 720px){.outdated-selection-link:before,.selection-link:before{border-left-color:var(--selection-background-color);border-right:0;right:1px;top:50%}}.outdated-selection-link{background:var(--selection-background-color-link);font-size:21px;font-weight:800;line-height:27px}.outdated-selection-link:hover:after{content:"This selection content has changed since this link was created.";font:9pt/11pt var(--font-family);position:absolute;display:block;white-space:nowrap;padding:2px 5px 1px;top:-20px;background:black;color:var(--color-white)}a{color:var(--color-link);text-decoration:none}a:hover{text-decoration:underline}img{max-width:100%}dl{margin:1rem 0 1rem var(--dfn-indent)}dd{margin:.25em 0 .5em var(--indent)}dd+dd{margin-top:1rem}dfn,.spec-ref{font-style:italic}dfn>a,.spec-ref>a{color:inherit}h1,h2,h3,h4,h5,h6{font-weight:bold;margin:3em 0 1em;position:relative}@media (min-width: 720px){header>h1{margin:6em 0 3em}}h1{font-size:1.5em;margin-top:5em}h2,h3{font-size:1.25em}h4,h5,h6{font-size:1em}section{padding-top:1rem;margin-top:-1rem}section.subsec>h6{margin-top:2em}section.subsec>h6>a{color:var(--color-subsection-link)}section .spec-secid{margin-right:1ex}@media (min-width: 720px){section .spec-secid{position:absolute;right:100%;text-align:right;white-space:nowrap}}footer{font-size:75%;opacity:.5;text-align:center;margin-top:12rem}.spec-toc{margin:1rem 0 3rem}.spec-toc .title{content:"Contents";display:block;font-weight:bold;margin:5em 0 1em}.spec-toc .spec-secid{margin-right:1ex}.spec-toc ol{list-style:none;padding-left:0;margin-top:0;margin-bottom:0}.spec-toc ol ol{list-style:none;padding-left:2ex;margin-bottom:.25em}.spec-toc li{position:relative;padding:5px 0 0 30px;margin:-5px 0 0 -30px}.spec-toc a{color:var(--color-toc-link)}.spec-toc a:hover{text-decoration:none}.spec-toc a .spec-secid{color:var(--color-toc-id)}.spec-toc a:hover .spec-secid{text-decoration:underline}.spec-toc .toggle{display:none}.spec-toc .toggle+label{cursor:pointer;left:6px;opacity:1;padding:5px 6px 5px 7px;position:absolute;top:6px;transform:rotate(0deg);transition:all .18s ease-in-out}.spec-toc .toggle+label:after{border-color:transparent transparent transparent var(--color-toggle-border);border-style:solid;border-width:6px 0 6px 7px;content:" ";display:block;height:0;width:0}@media (pointer: fine){.spec-toc .toggle+label{left:10px;padding:3px 5px 3px 6px;top:8px}}.spec-toc .toggle:checked+label{transform:rotate(90deg)}@media (hover: hover){.spec-toc li:not(:hover)>.toggle:checked+label{opacity:0}}.spec-toc .toggle:not(:checked)~ol{max-height:0;overflow:hidden;margin:0}.spec-sidebar-toggle{display:none}.spec-sidebar-toggle+label>.spec-sidebar-button{position:fixed;right:0;top:0;padding:10px 15px;font-size:30px;color:var(--color-sidebar-toggle-button);z-index:2;cursor:pointer;user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.spec-sidebar-toggle:checked+label:after{content:"";position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:0}.spec-sidebar{display:none;position:fixed;right:0;top:0;width:min(320px,calc(100vw - 48px));font-size:14px;line-height:1.75;overflow-y:scroll;height:100%;padding:0 0 5rem 30px;box-sizing:border-box;background:var(--color-sidebar-background);box-shadow:inset 1px 0 var(--color-sidebar-shadow-inset),-4px 0 8px -2px var(--color-sidebar-shadow);overscroll-behavior:contain}.spec-sidebar{user-select:none;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none}.spec-sidebar-toggle:checked~.spec-sidebar{display:block}.spec-sidebar .viewing>a:after{color:var(--color-sidebar-viewing-link);content:"\2022";margin-left:1ex}@media (min-width: 1220px){.spec-sidebar-toggle+label{display:none}.spec-sidebar{display:block;box-shadow:inset 1px 0 var(--color-sidebar-shadow-inset),inset 4px 0 8px -2px var(--color-sidebar-large-shadow)!important}body{padding-right:345px}}.spec-note{background:var(--color-spec-note-background);border-left:solid 4px var(--color-spec-note-border);margin:1rem -1rem;min-width:70vw;padding:8px 1rem 12px calc(1rem - 4px);width:-moz-fit-content;width:-webkit-fit-content;width:fit-content}@media (min-width: 720px){.spec-note{min-width:416px}}.spec-note>a:first-child{color:var(--color-spec-note-first-link);display:block;font:italic 11pt/18pt var(--font-family);opacity:.6;user-select:none}.spec-todo{color:var(--color-spec-todo);margin:1em 0 1em 5em;min-height:1em}.spec-todo::before{content:"todo";display:block;float:left;margin-left:-5em;text-transform:uppercase}.spec-index ol{list-style-type:none;margin:0 0 0 var(--indent);padding:0;column-width:210px;column-gap:var(--indent)}.spec-index ol li{width:min-content;white-space:nowrap}pre,code{font-family:var(--font-family-monospace);font-size:var(--mono-font-size);font-weight:inherit}code{background:var(--color-code-background);margin:-2px -1px;padding:3px 3px;white-space:pre-wrap}pre>code{background:none;font-weight:inherit;margin:0;padding:0;white-space:pre}pre{background:var(--color-pre-background);border-left:solid 4px var(--color-pre-border);margin:1rem -1rem;min-width:70vw;padding:12px 1rem 12px calc(1rem - 4px);width:-moz-fit-content;width:-webkit-fit-content;width:fit-content;max-width:calc(100vw - 2rem);overflow-y:auto}@media (min-width: 720px){pre{min-width:40ch}}.spec-example{background:var(--color-spec-example);border-left:solid 4px var(--color-spec-example-border);padding-top:8px}.spec-counter-example{background:var(--color-spec-counter-example);border-left:solid 4px var(--color-spec-counter-border);padding-top:8px}.spec-example>a,.spec-counter-example>a{display:block;font:italic 11pt/18pt var(--font-family);opacity:.6;user-select:none}.spec-counter-example>a{color:var(--color-spec-counter-example-link)}table{border-collapse:collapse}th{background-color:var(--color-table-header)}td,th{border:1px solid var(--color-table-header-border);padding:.4em;vertical-align:baseline}ol,ul{padding-left:var(--list-indent)}li>ol,li>ul{margin-top:.25em;margin-bottom:.5em}li+li{margin-top:.25em}li.task{list-style-type:none;position:relative}li.task>input:first-child{margin-left:0;position:absolute;transform:translateX(calc(-100% - 1ch))}ins{background-color:var(--color-inserts-background);text-decoration:none}del{background-color:var(--color-deletions-background)}.spec-added,.spec-removed{border-left:4px solid;margin-left:-18px;padding-left:14px}.spec-added{border-color:var(--color-spec-added-border)}.spec-removed{border-color:var(--color-spec-removed-border);text-decoration:line-through}.spec-keyword{font-weight:bold}.spec-string{font-family:var(--font-family-monospace);font-size:85%;white-space:pre}var{font-style:italic}*[data-name]{transition:.15s background ease-out;border-radius:2px;padding:0 3px;margin:0 -3px}.spec-semantic,.spec-algo{margin:1rem 0 1rem var(--dfn-indent)}.spec-semantic>.spec-nt::after,.spec-algo>.spec-call:first-child::after{content:":";font-style:normal;font-weight:bold;margin-left:1ex}.spec-semantic ol,.spec-semantic ol ol ol ol,.spec-algo ol,.spec-algo ol ol ol ol{list-style-type:decimal}.spec-semantic ol ol,.spec-semantic ol ol ol ol ol,.spec-algo ol ol,.spec-algo ol ol ol ol ol{list-style-type:lower-alpha}.spec-semantic ol ol ol,.spec-semantic ol ol ol ol ol ol,.spec-algo ol ol ol,.spec-algo ol ol ol ol ol ol{list-style-type:lower-roman}.spec-call>a{color:inherit}.spec-production{margin:1rem 0 1rem var(--dfn-indent)}.spec-production>.spec-nt::after{content:":";font-style:normal;font-weight:bold;margin:0 1ex}.spec-semantic.d2>.spec-nt::after,.spec-production.d2>.spec-nt::after{content:"::"}.spec-semantic.d3>.spec-nt::after,.spec-production.d3>.spec-nt::after{content:":::"}.spec-production>.spec-rhs{line-height:1.1;margin:.25em 0 .5em calc(2 * var(--indent));text-indent:calc(-1 * var(--indent))}.spec-semantic>.spec-rhs{display:inline-block;text-indent:calc(-1 * var(--indent));margin-left:calc(1ex + var(--indent))}.spec-rhs>*{text-indent:0}.spec-oneof{display:inline}.spec-oneof::before{content:"one of";font-style:normal;font-weight:bold}.spec-oneof-grid{max-width:calc(100vw - 2rem);overflow:auto;margin:-1ex -1rem;padding:1ex 1rem}.spec-oneof-grid>table{margin-left:var(--indent)}.spec-oneof .spec-rhs{border:none;margin:0;padding:0 0 0 1rem;vertical-align:baseline;white-space:pre}.spec-oneof .spec-rhs:first-child{padding:0}.spec-rhs .spec-constrained:not(:first-child),.spec-rhs .spec-quantified:not(:first-child),.spec-rhs .spec-nt:not(:first-child),.spec-rhs .spec-t:not(:first-child),.spec-rhs .spec-rx:not(:first-child),.spec-rhs .spec-prose:not(:first-child),.spec-rhs .spec-empty:not(:first-child),.spec-rhs .spec-lookahead:not(:first-child){margin-left:1ex;display:inline-block}.spec-condition{font-size:85%}.spec-condition::before{content:"[if "}.spec-condition.not::before{content:"[if not "}.spec-condition::after{content:"]"}.spec-empty,.spec-prose{color:var(--color-spec-prose)}.spec-nt{font-style:italic}.spec-nt>a{color:inherit}.spec-quantifiers,.spec-params{font-size:65%;font-style:normal;vertical-align:sub}.spec-quantifier.list{color:var(--color-spec-quantifier-list)}.spec-quantifier.optional{color:var(--color-spec-quantifier-optional)}.spec-params,.spec-condition{color:var(--color-spec-condition)}.spec-params::before{content:"["}.spec-params::after{content:"]"}.spec-quantifier:not(:last-child)::after,.spec-param:not(:last-child)::after{color:var(--color-spec-param);content:", "}.spec-param.conditional::before{content:"?"}.spec-param.negated::before{content:"!"}.spec-t,.spec-rx{color:var(--color-spec-rx);font-family:var(--font-family-monospace);font-weight:bold}.spec-butnot::before{color:var(--color-grey);content:"but not";font-family:var(--font-family);font-weight:normal;margin-right:1ex}.spec-butnot>*:not(:first-child)::before{color:var(--color-grey);content:"or";font-family:var(--font-family);font-weight:normal;margin-right:1ex}.spec-rhs .spec-oneof::before,.spec-rhs .spec-butnot::before{margin-left:1ex}.spec-lookahead>*{margin:0!important}.spec-lookahead>*:not(:first-child)::before{color:var(--color-grey);content:", ";font-family:var(--font-family);font-style:normal;font-weight:normal}.spec-lookahead::before{color:var(--color-grey);content:"[lookahead = ";font-family:var(--font-family);font-style:normal;font-weight:normal}.spec-lookahead.not::before{content:"[lookahead \2260 "}.spec-lookahead.set::before{content:"[lookahead \2208 {";margin-right:0}.spec-lookahead.set.not::before{content:"[lookahead \2209 {"}.spec-lookahead.ntset::before{content:"[lookahead \2208 ";margin-right:0}.spec-lookahead.ntset.not::before{content:"[lookahead \2209 "}.spec-lookahead::after{color:var(--color-grey);content:"]"}.spec-lookahead.set::after{content:"}]"}code[class*=language-],pre[class*=language-]{color:var(--color-prism-foreground);background:none;text-shadow:0 1px var(--color-prism-text-shadow);font-family:var(--font-family-monospace);font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection{text-shadow:none;background:var(--color-prism-background)}pre[class*=language-]::selection,pre[class*=language-] ::selection,code[class*=language-]::selection,code[class*=language-] ::selection{text-shadow:none;background:var(--color-prism-background)}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:var(--color-prism-block-background)}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.atrule,.token.attr-value,.token.keyword,.token.property,.token.selector,.token.attr-name,.token.builtin,.token.entity,.token.url,.token.inserted{color:var(--color-token-inserted);background:none}.token.tag,.token.boolean,.token.number,.token.string,.token.char,.token.constant,.token.symbol,.token.regex,.token.important,.token.variable,.token.function,.token.class-name,.token.deleted{color:var(--color-token-deleted)}.token.comment,.token.prolog,.token.doctype,.token.cdata,.token.description{color:inherit;opacity:.3}.token.punctuation{color:inherit;opacity:.5}.token.operator,.token.namespace{color:inherit;opacity:.7}</style>
7
+ <script>(function(){var r,a=[];document.addEventListener("readystatechange",function(){document.readyState==="interactive"&&u()});function u(){var n=document.querySelector('label[for="spec-sidebar-toggle"]');n.addEventListener("scroll",o),n.addEventListener("touchmove",o);function o(d){d.preventDefault()}for(var t=document.getElementsByTagName("section"),e=0;e<t.length;e++)t[e].getAttribute("secid")&&a.push(t[e]);var i=window.scrollY,c=!1;window.addEventListener("scroll",function(d){i=window.scrollY,c||(c=!0,window.requestAnimationFrame(function(){s(i),c=!1}))})}function s(n){for(var o=n+document.documentElement.clientHeight/4,t,e=a.length-1;e>=0;e--)if(a[e].offsetTop<o){t=a[e];break}var i=t&&t.getAttribute("secid");i!==r&&(r&&l(r,!1),i&&l(i,!0),r=i)}function l(n,o){document.getElementById("_sidebar_"+n).className=o?"viewing":"";for(var t=n.split(".");t.length;){var e=document.getElementById("_toggle_"+t.join("."));e&&(e.checked=o),t.pop()}}s(window.scrollY);})();</script>
8
+ <script>(function(){var n=document.getElementsByTagName("style")[0].sheet,e;function u(){e&&(n.deleteRule(e),e=void 0)}function d(t){u(),e=n.insertRule('*[data-name="'+t+'"] { background: rgba(230,215,0,0.12); }',n.cssRules.length)}document.documentElement.addEventListener("mouseover",function(t){var a=t.target.attributes["data-name"];a&&d(a.value)});document.documentElement.addEventListener("mouseout",u);})();</script>
9
+ <script>(function(){var R="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",o,p,r,g;document.addEventListener("selectionchange",E);window.addEventListener("resize",C);window.addEventListener("hashchange",x);window.addEventListener("load",x);function S(n){y(new URL(n.target.href))}function x(){y(window.location)}function y(n){var e=n.hash.match(/^#sel-([A-Za-z0-9-_]+)$/);if(!!e){g=e[1],r=k(g);var t=r.getBoundingClientRect(),d=Math.max(20,Math.floor((window.innerHeight-t.height)*.4));window.scrollTo(0,window.scrollY+t.y-d);var c=document.getSelection();c.empty(),c.addRange(r),C()}}function E(n){var e=document.getSelection();if(e.isCollapsed)o&&(o.parentNode.removeChild(o),o=null);else{var t=e.getRangeAt(0);(!r||t.compareBoundaryPoints(Range.START_TO_START,r)!==0||t.compareBoundaryPoints(Range.END_TO_END,r)!==0)&&(r=t,g=B(r),C())}}function C(){if(!!r){p||(p=document.getElementsByTagName("article")[0]),o||(o=document.createElement("a"),document.body.appendChild(o)),o.href="#sel-"+g,o.onclick=S,o.className=r.isOutdated?"outdated-selection-link":"selection-link",o.innerText=r.isOutdated?"!":"\u201F";var n=window.innerWidth<720,e=r.getBoundingClientRect();if(n)o.style.left=Math.floor(e.x+e.width/2+window.scrollX-13)+"px",o.style.top=Math.floor(e.bottom+window.scrollY+10)+"px";else{var t=p.getBoundingClientRect().x;o.style.left=Math.floor(t+window.scrollX-37)+"px",o.style.top=Math.floor(e.y+window.scrollY-3)+"px"}}}function B(n){var e="",t=N(n.startContainer),d=N(n.endContainer),c=M(t,d);return l(c),l(t.slice(c.length).concat(n.startOffset)),l(d.slice(c.length).concat(n.endOffset)),i(L(n.toString())),e;function i(a){do e+=R[a&31|(a>31?32:0)],a>>=5;while(a>0)}function l(a){i(a.length);for(var h=0;h<a.length;h++)i(a[h])}}function k(n){for(var e=new Array(64),t=0;t<64;t++)e[R.charCodeAt(t)]=t;var d=0,c=m(),i=m(),l=m(),a=w(),h=i.pop(),P=O(c.concat(i)),T=l.pop(),A=O(c.concat(l)),u=document.createRange();return u.setStart(P,h),u.setEnd(A,T),u.isOutdated=a!==void 0&&a!==L(u.toString()),u;function w(){for(var s=0,v=0;d<n.length;){var f=e[n.charCodeAt(d++)];if(s|=(f&31)<<v,v+=5,f<32)return s}}function m(){var s=w();if(s!=null){for(var v=new Array(s),f=0;f<s;f++)v[f]=w();return v}}}function N(n){for(var e=[];n!=document.body;){var t=n.parentNode;e.push(Array.prototype.indexOf.call(t.childNodes,n)),n=t}return e.reverse()}function O(n){for(var e=document.body,t=0;t<n.length&&e;t++)e=e.childNodes[n[t]];return e}function M(n,e){for(var t=0;t<n.length&&t<e.length&&n[t]===e[t];)t++;return n.slice(0,t)}function L(n){for(var e=2166136261,t=0;t<n.length;++t)e^=n.charCodeAt(t),e+=(e<<1)+(e<<4)+(e<<7)+(e<<8)+(e<<24);return(e>>15^e)&32767}})();</script>
10
+ </head>
11
+ <body><article>
12
+ <header>
13
+ <h1>Graffiticode Core Language Specification</h1>
14
+ <nav class="spec-toc">
15
+ <div class="title">Contents</div>
16
+ <ol>
17
+ <li><a href="#sec-Introduction"><span class="spec-secid">1</span>Introduction</a></li>
18
+ <li><a href="#sec-Lexical-Structure"><span class="spec-secid">2</span>Lexical Structure</a><ol>
19
+ <li><a href="#sec-Tokens"><span class="spec-secid">2.1</span>Tokens</a></li>
20
+ <li><a href="#sec-Comments"><span class="spec-secid">2.2</span>Comments</a></li>
21
+ </ol>
22
+ </li>
23
+ <li><a href="#sec-Syntax"><span class="spec-secid">3</span>Syntax</a><ol>
24
+ <li><a href="#sec-Programs"><span class="spec-secid">3.1</span>Programs</a></li>
25
+ <li><a href="#sec-Expressions"><span class="spec-secid">3.2</span>Expressions</a><ol>
26
+ <li><a href="#sec-Function-Application"><span class="spec-secid">3.2.1</span>Function Application</a></li>
27
+ <li><a href="#sec-Lists"><span class="spec-secid">3.2.2</span>Lists</a></li>
28
+ <li><a href="#sec-Records"><span class="spec-secid">3.2.3</span>Records</a></li>
29
+ <li><a href="#sec-Lambdas"><span class="spec-secid">3.2.4</span>Lambdas</a></li>
30
+ <li><a href="#sec-Let-Bindings"><span class="spec-secid">3.2.5</span>Let Bindings</a></li>
31
+ </ol>
32
+ </li>
33
+ <li><a href="#sec-Pattern-Matching"><span class="spec-secid">3.3</span>Pattern Matching</a><ol>
34
+ <li><a href="#sec-Tag-Values"><span class="spec-secid">3.3.1</span>Tag Values</a></li>
35
+ </ol>
36
+ </li>
37
+ </ol>
38
+ </li>
39
+ <li><a href="#sec-Semantics"><span class="spec-secid">4</span>Semantics</a><ol>
40
+ <li><a href="#sec-Evaluation-Model"><span class="spec-secid">4.1</span>Evaluation Model</a></li>
41
+ <li><a href="#sec-Functions"><span class="spec-secid">4.2</span>Functions</a></li>
42
+ <li><a href="#sec-Scoping"><span class="spec-secid">4.3</span>Scoping</a></li>
43
+ <li><a href="#sec-Errors"><span class="spec-secid">4.4</span>Errors</a></li>
44
+ </ol>
45
+ </li>
46
+ <li><a href="#sec-Base-Library"><span class="spec-secid">5</span>Base Library</a><ol>
47
+ <li><a href="#sec-Types"><span class="spec-secid">5.1</span>Types</a></li>
48
+ <li><a href="#sec-Built-in-Functions"><span class="spec-secid">5.2</span>Built-in Functions</a><ol>
49
+ <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>
52
+ <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>
67
+ </ol>
68
+ </li>
69
+ </ol>
70
+ </li>
71
+ <li><a href="#sec-Program-Examples"><span class="spec-secid">6</span>Program Examples</a></li>
72
+ <li><a href="#index"><span class="spec-secid">§</span>Index</a></li>
73
+ </ol>
74
+ </nav>
75
+ </header>
76
+ <section id="sec-Introduction" secid="1">
77
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Introduction">1</a></span>Introduction</h1>
78
+ <p>This document defines the <strong>Graffiticode Core Language Specification</strong>, covering syntax, semantics, and the base library. It excludes dialect-specific constructs, runtime behavior, and extended libraries.</p>
79
+ </section>
80
+ <section id="sec-Lexical-Structure" secid="2">
81
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Lexical-Structure">2</a></span>Lexical Structure</h1>
82
+ <section id="sec-Tokens" secid="2.1">
83
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Tokens">2.1</a></span>Tokens</h2>
84
+ <ul>
85
+ <li><strong>Identifiers</strong>: Alphanumeric symbols beginning with a letter.</li>
86
+ <li><strong>Numbers</strong>: Integers and floats. Negative numbers start with <code>-</code>.</li>
87
+ <li><strong>Strings</strong>: Double-quoted UTF-8 strings.</li>
88
+ <li><strong>Symbols</strong>: <code>(</code>, <code>)</code>, <code>[</code>, <code>]</code>, <code>{</code>, <code>}</code>, <code>:</code>, <code>..</code>, <code>&lt;</code>, <code>&gt;</code>, <code>,</code></li>
89
+ </ul>
90
+ </section>
91
+ <section id="sec-Comments" secid="2.2">
92
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Comments">2.2</a></span>Comments</h2>
93
+ <ul>
94
+ <li><strong>Line Comments</strong>: Begin with <code>|</code> and continue to end of line.</li>
95
+ </ul>
96
+ </section>
97
+ </section>
98
+ <section id="sec-Syntax" secid="3">
99
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Syntax">3</a></span>Syntax</h1>
100
+ <section id="sec-Programs" secid="3.1">
101
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Programs">3.1</a></span>Programs</h2>
102
+ <p>A <strong>Graffiticode program</strong> is a sequence of one or more <code>let</code> declarations, followed by a single top-level expression, and terminated with <code>..</code>.</p>
103
+ <pre><code>let double = &lt;x: mul 2 x&gt;..
104
+ map (double) [1 2 3]..
105
+ </code></pre>
106
+ <p>The top-level expression must always be followed by <code>..</code>.</p>
107
+ </section>
108
+ <section id="sec-Expressions" secid="3.2">
109
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Expressions">3.2</a></span>Expressions</h2>
110
+ <section id="sec-Function-Application" secid="3.2.1">
111
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Function-Application">3.2.1</a></span>Function Application</h3>
112
+ <p>Function application is written in prefix style: <code>add 1 2</code></p>
113
+ <p>Parentheses are used to defer application: <code>map (double) [1 2 3]</code></p>
114
+ </section>
115
+ <section id="sec-Lists" secid="3.2.2">
116
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Lists">3.2.2</a></span>Lists</h3>
117
+ <pre><code>[1 2 3]
118
+ </code></pre>
119
+ </section>
120
+ <section id="sec-Records" secid="3.2.3">
121
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Records">3.2.3</a></span>Records</h3>
122
+ <pre><code>{ name: "Alice", age: 30 }
123
+ </code></pre>
124
+ </section>
125
+ <section id="sec-Lambdas" secid="3.2.4">
126
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Lambdas">3.2.4</a></span>Lambdas</h3>
127
+ <pre><code>&lt;x: add x 1&gt;
128
+ </code></pre>
129
+ <p>Multiple parameters: <code>&lt;x y: add x y&gt;</code></p>
130
+ </section>
131
+ <section id="sec-Let-Bindings" secid="3.2.5">
132
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Let-Bindings">3.2.5</a></span>Let Bindings</h3>
133
+ <pre><code>let double = &lt;x: mul 2 x&gt;..
134
+ </code></pre>
135
+ </section>
136
+ </section>
137
+ <section id="sec-Pattern-Matching" secid="3.3">
138
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Pattern-Matching">3.3</a></span>Pattern Matching</h2>
139
+ <p>Pattern matching is done using <code>case</code>: <code>case x of 0: "zero" 1: "one" _: "other" end</code></p>
140
+ <div class="spec-production" id="Supports">
141
+ <span class="spec-nt"><a href="#Supports" data-name="Supports">Supports</a></span><div class="spec-rhs"><span class="spec-nt"><span data-name="Literal">Literal</span></span><span class="spec-t">values</span></div>
142
+ <div class="spec-rhs"><span class="spec-nt"><span data-name="Tuple">Tuple</span></span><span class="spec-t">destructuring:</span><span class="spec-t">(a, b)</span></div>
143
+ <div class="spec-rhs"><span class="spec-nt"><span data-name="Record">Record</span></span><span class="spec-t">destructuring:</span><span class="spec-t">{ name, age }</span></div>
144
+ <div class="spec-rhs"><span class="spec-nt"><span data-name="Wildcard">Wildcard</span></span><span class="spec-t">_</span></div>
145
+ </div>
146
+ <p>Pattern matching on function arguments is disallowed.</p>
147
+ <section id="sec-Tag-Values" secid="3.3.1">
148
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-Tag-Values">3.3.1</a></span>Tag Values</h3>
149
+ <p>A <strong>tag value</strong> is an arity-0 symbolic value that can be used in pattern matching or to encode variant types.</p>
150
+ <pre><code>red
151
+ </code></pre>
152
+ <p>Tag values:</p>
153
+ <ul>
154
+ <li>Are unbound identifiers that appear in expression position.</li>
155
+ <li>May optionally be introduced via implicit enum definitions.</li>
156
+ <li>Match directly in <code>case</code> expressions:</li>
157
+ </ul>
158
+ <pre><code>case color of
159
+ red: "warm"
160
+ blue: "cool"
161
+ _: "other"
162
+ end
163
+ </code></pre>
164
+ <p>Tags are resolved as special constants with symbolic identity. They are case-sensitive and may be compared for equality using regular pattern match semantics.</p>
165
+ </section>
166
+ </section>
167
+ </section>
168
+ <section id="sec-Semantics" secid="4">
169
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Semantics">4</a></span>Semantics</h1>
170
+ <section id="sec-Evaluation-Model" secid="4.1">
171
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Evaluation-Model">4.1</a></span>Evaluation Model</h2>
172
+ <ul>
173
+ <li><strong>Purely functional</strong>: no side effects</li>
174
+ <li><strong>Strict evaluation</strong>: arguments evaluated before function application</li>
175
+ <li><strong>Immutable data</strong>: all values are immutable</li>
176
+ </ul>
177
+ </section>
178
+ <section id="sec-Functions" secid="4.2">
179
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Functions">4.2</a></span>Functions</h2>
180
+ <ul>
181
+ <li><strong>Fixed arity</strong>: every function has a known number of parameters</li>
182
+ <li><strong>Curried by default</strong>: partial application supported</li>
183
+ </ul>
184
+ </section>
185
+ <section id="sec-Scoping" secid="4.3">
186
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Scoping">4.3</a></span>Scoping</h2>
187
+ <ul>
188
+ <li><strong>Lexical scoping</strong></li>
189
+ <li><strong>Shadowing</strong> allowed within nested scopes</li>
190
+ </ul>
191
+ </section>
192
+ <section id="sec-Errors" secid="4.4">
193
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Errors">4.4</a></span>Errors</h2>
194
+ <ul>
195
+ <li><strong>Syntax errors</strong>: raised during parsing</li>
196
+ <li><strong>Type errors</strong>: raised during compilation</li>
197
+ <li><strong>Runtime errors</strong>: e.g., out-of-bounds access</li>
198
+ </ul>
199
+ </section>
200
+ </section>
201
+ <section id="sec-Base-Library" secid="5">
202
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Base-Library">5</a></span>Base Library</h1>
203
+ <section id="sec-Types" secid="5.1">
204
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Types">5.1</a></span>Types</h2>
205
+ <ul>
206
+ <li><code>number</code></li>
207
+ <li><code>string</code></li>
208
+ <li><code>bool</code></li>
209
+ <li><code>list</code></li>
210
+ <li><code>record</code></li>
211
+ <li><code>tuple</code></li>
212
+ <li><code>json</code></li>
213
+ </ul>
214
+ </section>
215
+ <section id="sec-Built-in-Functions" secid="5.2">
216
+ <h2><span class="spec-secid" title="link to this section"><a href="#sec-Built-in-Functions">5.2</a></span>Built-in Functions</h2>
217
+ <table>
218
+ <thead>
219
+ <tr>
220
+ <th align="left">Function</th>
221
+ <th align="left">Signature</th>
222
+ <th align="left">Description</th>
223
+ </tr>
224
+ </thead>
225
+ <tbody>
226
+ <tr>
227
+ <td align="left"><code>add</code></td>
228
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
229
+ <td align="left">Adds two numbers</td>
230
+ </tr>
231
+ <tr>
232
+ <td align="left"><code>sub</code></td>
233
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
234
+ <td align="left">Subtracts numbers</td>
235
+ </tr>
236
+ <tr>
237
+ <td align="left"><code>mul</code></td>
238
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
239
+ <td align="left">Multiplies numbers</td>
240
+ </tr>
241
+ <tr>
242
+ <td align="left"><code>div</code></td>
243
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
244
+ <td align="left">Divides numbers</td>
245
+ </tr>
246
+ <tr>
247
+ <td align="left"><code>mod</code></td>
248
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
249
+ <td align="left">Remainder of division</td>
250
+ </tr>
251
+ <tr>
252
+ <td align="left"><code>min</code></td>
253
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
254
+ <td align="left">Returns the smaller of two numbers</td>
255
+ </tr>
256
+ <tr>
257
+ <td align="left"><code>max</code></td>
258
+ <td align="left"><code>&lt;number number: number&gt;</code></td>
259
+ <td align="left">Returns the larger of two numbers</td>
260
+ </tr>
261
+ <tr>
262
+ <td align="left"><code>range</code></td>
263
+ <td align="left"><code>&lt;number number number: list&gt;</code></td>
264
+ <td align="left">Generates a range list</td>
265
+ </tr>
266
+ <tr>
267
+ <td align="left"><code>map</code></td>
268
+ <td align="left"><code>&lt;function list: list&gt;</code></td>
269
+ <td align="left">Applies function to each item</td>
270
+ </tr>
271
+ <tr>
272
+ <td align="left"><code>filter</code></td>
273
+ <td align="left"><code>&lt;function list: list&gt;</code></td>
274
+ <td align="left">Keeps items matching predicate</td>
275
+ </tr>
276
+ <tr>
277
+ <td align="left"><code>reduce</code></td>
278
+ <td align="left"><code>&lt;function list: any&gt;</code></td>
279
+ <td align="left">Combines list using a reducer</td>
280
+ </tr>
281
+ <tr>
282
+ <td align="left"><code>hd</code></td>
283
+ <td align="left"><code>&lt;list: any&gt;</code></td>
284
+ <td align="left">First item of list</td>
285
+ </tr>
286
+ <tr>
287
+ <td align="left"><code>tl</code></td>
288
+ <td align="left"><code>&lt;list: list&gt;</code></td>
289
+ <td align="left">All items except first</td>
290
+ </tr>
291
+ <tr>
292
+ <td align="left"><code>nth</code></td>
293
+ <td align="left"><code>&lt;number list: any&gt;</code></td>
294
+ <td align="left">Nth element of list</td>
295
+ </tr>
296
+ <tr>
297
+ <td align="left"><code>apply</code></td>
298
+ <td align="left"><code>&lt;function list: any&gt;</code></td>
299
+ <td align="left">Applies a function to a list of arguments</td>
300
+ </tr>
301
+ <tr>
302
+ <td align="left"><code>isEmpty</code></td>
303
+ <td align="left"><code>&lt;list: bool&gt;</code></td>
304
+ <td align="left">Returns true if the list is empty</td>
305
+ </tr>
306
+ <tr>
307
+ <td align="left"><code>get</code></td>
308
+ <td align="left"><code>&lt;record string: any&gt;</code></td>
309
+ <td align="left">Retrieves a value from a record by key</td>
310
+ </tr>
311
+ <tr>
312
+ <td align="left"><code>set</code></td>
313
+ <td align="left"><code>&lt;record string any: record&gt;</code></td>
314
+ <td align="left">Returns a new record with a key set to a value</td>
315
+ </tr>
316
+ </tbody>
317
+ </table>
318
+ <section id="sec-add" secid="5.2.1">
319
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-add">5.2.1</a></span>add</h3>
320
+ <p>Add two numbers.</p>
321
+ <pre><code>add 2 3 | returns 5
322
+ </code></pre>
323
+ </section>
324
+ <section id="sec-sub" secid="5.2.2">
325
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-sub">5.2.2</a></span>sub</h3>
326
+ <p>Subtract the second number from the first</p>
327
+ <pre><code>sub 5 2 | returns 3
328
+ </code></pre>
329
+ </section>
330
+ <section id="sec-mul" secid="5.2.3">
331
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-mul">5.2.3</a></span>mul</h3>
332
+ <p>Multiply two numbers</p>
333
+ <pre><code>mul 4 3 | returns 12
334
+ </code></pre>
335
+ </section>
336
+ <section id="sec-div" secid="5.2.4">
337
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-div">5.2.4</a></span>div</h3>
338
+ <p>Divide the first number by the second</p>
339
+ <pre><code>div 10 2 | returns 5
340
+ </code></pre>
341
+ </section>
342
+ <section id="sec-mod" secid="5.2.5">
343
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-mod">5.2.5</a></span>mod</h3>
344
+ <p>Compute the remainder</p>
345
+ <pre><code>mod 10 3 | returns 1
346
+ </code></pre>
347
+ </section>
348
+ <section id="sec-min" secid="5.2.6">
349
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-min">5.2.6</a></span>min</h3>
350
+ <p>Return the smaller of two numbers</p>
351
+ <pre><code>min 5 10 | returns 5
352
+ </code></pre>
353
+ </section>
354
+ <section id="sec-max" secid="5.2.7">
355
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-max">5.2.7</a></span>max</h3>
356
+ <p>Return the larger of two numbers</p>
357
+ <pre><code>max 5 10 | returns 10
358
+ </code></pre>
359
+ </section>
360
+ <section id="sec-range" secid="5.2.8">
361
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-range">5.2.8</a></span>range</h3>
362
+ <p>Produce a range list from start to end (exclusive) with step</p>
363
+ <pre><code>range 1 10 2 | returns [1 3 5 7 9]
364
+ </code></pre>
365
+ </section>
366
+ <section id="sec-map" secid="5.2.9">
367
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-map">5.2.9</a></span>map</h3>
368
+ <p>Apply a function to each element</p>
369
+ <pre><code>map (&lt;x: add x 1&gt;) [1 2 3] | returns [2 3 4]
370
+ </code></pre>
371
+ </section>
372
+ <section id="sec-filter" secid="5.2.10">
373
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-filter">5.2.10</a></span>filter</h3>
374
+ <p>Filter elements matching predicate</p>
375
+ <pre><code>filter (&lt;x: mod x 2&gt;) [1 2 3 4] | returns [1 3]
376
+ </code></pre>
377
+ </section>
378
+ <section id="sec-reduce" secid="5.2.11">
379
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-reduce">5.2.11</a></span>reduce</h3>
380
+ <p>Reduce a list to a single value, starting with an initial value</p>
381
+ <pre><code>reduce (&lt;a b: add a b&gt;) 0 [1 2 3 4] | returns 10
382
+ </code></pre>
383
+ </section>
384
+ <section id="sec-hd" secid="5.2.12">
385
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-hd">5.2.12</a></span>hd</h3>
386
+ <p>Return the first item</p>
387
+ <pre><code>hd [10 20 30] | returns 10
388
+ </code></pre>
389
+ </section>
390
+ <section id="sec-tl" secid="5.2.13">
391
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-tl">5.2.13</a></span>tl</h3>
392
+ <p>Return all but the first item</p>
393
+ <pre><code>tl [10 20 30] | returns [20 30]
394
+ </code></pre>
395
+ </section>
396
+ <section id="sec-nth" secid="5.2.14">
397
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-nth">5.2.14</a></span>nth</h3>
398
+ <p>Get the nth item (0-based)</p>
399
+ <pre><code>nth 1 [10 20 30] | returns 20
400
+ </code></pre>
401
+ </section>
402
+ <section id="sec-apply" secid="5.2.15">
403
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-apply">5.2.15</a></span>apply</h3>
404
+ <p>Apply a function to an argument list</p>
405
+ <pre><code>apply add [1 2] | returns 3
406
+ </code></pre>
407
+ </section>
408
+ <section id="sec-isEmpty" secid="5.2.16">
409
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-isEmpty">5.2.16</a></span>isEmpty</h3>
410
+ <p>Return true if list is empty, otherwise return false</p>
411
+ <pre><code>isEmpty [] | returns true
412
+ </code></pre>
413
+ </section>
414
+ <section id="sec-get" secid="5.2.17">
415
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-get">5.2.17</a></span>get</h3>
416
+ <p>Retrieve a record field</p>
417
+ <pre><code>get {a: 1, b: 2} "b" | returns 2
418
+ </code></pre>
419
+ </section>
420
+ <section id="sec-set" secid="5.2.18">
421
+ <h3><span class="spec-secid" title="link to this section"><a href="#sec-set">5.2.18</a></span>set</h3>
422
+ <p>Return a new record with an updated field</p>
423
+ <pre><code>set {a: 1} "a" 2 | returns {a: 2}
424
+ </code></pre>
425
+ </section>
426
+ </section>
427
+ </section>
428
+ <section id="sec-Program-Examples" secid="6">
429
+ <h1><span class="spec-secid" title="link to this section"><a href="#sec-Program-Examples">6</a></span>Program Examples</h1>
430
+ <pre><code>let double = &lt;x: mul 2 x&gt;..
431
+ map (double) [1 2 3]..
432
+ </code></pre>
433
+ <pre><code>case age of
434
+ 18: "adult"
435
+ _: "other"
436
+ end..
437
+ </code></pre>
438
+ <p>---</p>
439
+ </section>
440
+ <section id="index" secid="index" class="spec-index">
441
+ <h1>
442
+ <span class="spec-secid" title="link to the index"><a href="#index">§</a></span>Index</h1>
443
+ <ol>
444
+ <li><a href="#Supports">Supports</a></li>
445
+ </ol>
446
+ </section>
447
+ </article>
448
+ <footer>
449
+ Written in <a href="https://spec-md.com" target="_blank">Spec Markdown</a>.</footer>
450
+ <input hidden class="spec-sidebar-toggle" type="checkbox" id="spec-sidebar-toggle" aria-hidden /><label for="spec-sidebar-toggle" aria-hidden><div class="spec-sidebar-button">&#x2630;</div></label>
451
+ <div class="spec-sidebar" aria-hidden>
452
+ <div class="spec-toc">
453
+ <div class="title"><a href="#">Graffiticode Core Language Specification</a></div>
454
+ <ol><li id="_sidebar_1"><a href="#sec-Introduction"><span class="spec-secid">1</span>Introduction</a></li>
455
+ <li id="_sidebar_2"><a href="#sec-Lexical-Structure"><span class="spec-secid">2</span>Lexical Structure</a>
456
+ <input hidden class="toggle" type="checkbox" id="_toggle_2" /><label for="_toggle_2"></label>
457
+ <ol>
458
+ <li id="_sidebar_2.1"><a href="#sec-Tokens"><span class="spec-secid">2.1</span>Tokens</a></li>
459
+ <li id="_sidebar_2.2"><a href="#sec-Comments"><span class="spec-secid">2.2</span>Comments</a></li>
460
+ </ol>
461
+ </li>
462
+ <li id="_sidebar_3"><a href="#sec-Syntax"><span class="spec-secid">3</span>Syntax</a>
463
+ <input hidden class="toggle" type="checkbox" id="_toggle_3" /><label for="_toggle_3"></label>
464
+ <ol>
465
+ <li id="_sidebar_3.1"><a href="#sec-Programs"><span class="spec-secid">3.1</span>Programs</a></li>
466
+ <li id="_sidebar_3.2"><a href="#sec-Expressions"><span class="spec-secid">3.2</span>Expressions</a>
467
+ <input hidden class="toggle" type="checkbox" id="_toggle_3.2" /><label for="_toggle_3.2"></label>
468
+ <ol>
469
+ <li id="_sidebar_3.2.1"><a href="#sec-Function-Application"><span class="spec-secid">3.2.1</span>Function Application</a></li>
470
+ <li id="_sidebar_3.2.2"><a href="#sec-Lists"><span class="spec-secid">3.2.2</span>Lists</a></li>
471
+ <li id="_sidebar_3.2.3"><a href="#sec-Records"><span class="spec-secid">3.2.3</span>Records</a></li>
472
+ <li id="_sidebar_3.2.4"><a href="#sec-Lambdas"><span class="spec-secid">3.2.4</span>Lambdas</a></li>
473
+ <li id="_sidebar_3.2.5"><a href="#sec-Let-Bindings"><span class="spec-secid">3.2.5</span>Let Bindings</a></li>
474
+ </ol>
475
+ </li>
476
+ <li id="_sidebar_3.3"><a href="#sec-Pattern-Matching"><span class="spec-secid">3.3</span>Pattern Matching</a>
477
+ <input hidden class="toggle" type="checkbox" id="_toggle_3.3" /><label for="_toggle_3.3"></label>
478
+ <ol>
479
+ <li id="_sidebar_3.3.1"><a href="#sec-Tag-Values"><span class="spec-secid">3.3.1</span>Tag Values</a></li>
480
+ </ol>
481
+ </li>
482
+ </ol>
483
+ </li>
484
+ <li id="_sidebar_4"><a href="#sec-Semantics"><span class="spec-secid">4</span>Semantics</a>
485
+ <input hidden class="toggle" type="checkbox" id="_toggle_4" /><label for="_toggle_4"></label>
486
+ <ol>
487
+ <li id="_sidebar_4.1"><a href="#sec-Evaluation-Model"><span class="spec-secid">4.1</span>Evaluation Model</a></li>
488
+ <li id="_sidebar_4.2"><a href="#sec-Functions"><span class="spec-secid">4.2</span>Functions</a></li>
489
+ <li id="_sidebar_4.3"><a href="#sec-Scoping"><span class="spec-secid">4.3</span>Scoping</a></li>
490
+ <li id="_sidebar_4.4"><a href="#sec-Errors"><span class="spec-secid">4.4</span>Errors</a></li>
491
+ </ol>
492
+ </li>
493
+ <li id="_sidebar_5"><a href="#sec-Base-Library"><span class="spec-secid">5</span>Base Library</a>
494
+ <input hidden class="toggle" type="checkbox" id="_toggle_5" /><label for="_toggle_5"></label>
495
+ <ol>
496
+ <li id="_sidebar_5.1"><a href="#sec-Types"><span class="spec-secid">5.1</span>Types</a></li>
497
+ <li id="_sidebar_5.2"><a href="#sec-Built-in-Functions"><span class="spec-secid">5.2</span>Built-in Functions</a>
498
+ <input hidden class="toggle" type="checkbox" id="_toggle_5.2" /><label for="_toggle_5.2"></label>
499
+ <ol>
500
+ <li id="_sidebar_5.2.1"><a href="#sec-add"><span class="spec-secid">5.2.1</span>add</a></li>
501
+ <li id="_sidebar_5.2.2"><a href="#sec-sub"><span class="spec-secid">5.2.2</span>sub</a></li>
502
+ <li id="_sidebar_5.2.3"><a href="#sec-mul"><span class="spec-secid">5.2.3</span>mul</a></li>
503
+ <li id="_sidebar_5.2.4"><a href="#sec-div"><span class="spec-secid">5.2.4</span>div</a></li>
504
+ <li id="_sidebar_5.2.5"><a href="#sec-mod"><span class="spec-secid">5.2.5</span>mod</a></li>
505
+ <li id="_sidebar_5.2.6"><a href="#sec-min"><span class="spec-secid">5.2.6</span>min</a></li>
506
+ <li id="_sidebar_5.2.7"><a href="#sec-max"><span class="spec-secid">5.2.7</span>max</a></li>
507
+ <li id="_sidebar_5.2.8"><a href="#sec-range"><span class="spec-secid">5.2.8</span>range</a></li>
508
+ <li id="_sidebar_5.2.9"><a href="#sec-map"><span class="spec-secid">5.2.9</span>map</a></li>
509
+ <li id="_sidebar_5.2.10"><a href="#sec-filter"><span class="spec-secid">5.2.10</span>filter</a></li>
510
+ <li id="_sidebar_5.2.11"><a href="#sec-reduce"><span class="spec-secid">5.2.11</span>reduce</a></li>
511
+ <li id="_sidebar_5.2.12"><a href="#sec-hd"><span class="spec-secid">5.2.12</span>hd</a></li>
512
+ <li id="_sidebar_5.2.13"><a href="#sec-tl"><span class="spec-secid">5.2.13</span>tl</a></li>
513
+ <li id="_sidebar_5.2.14"><a href="#sec-nth"><span class="spec-secid">5.2.14</span>nth</a></li>
514
+ <li id="_sidebar_5.2.15"><a href="#sec-apply"><span class="spec-secid">5.2.15</span>apply</a></li>
515
+ <li id="_sidebar_5.2.16"><a href="#sec-isEmpty"><span class="spec-secid">5.2.16</span>isEmpty</a></li>
516
+ <li id="_sidebar_5.2.17"><a href="#sec-get"><span class="spec-secid">5.2.17</span>get</a></li>
517
+ <li id="_sidebar_5.2.18"><a href="#sec-set"><span class="spec-secid">5.2.18</span>set</a></li>
518
+ </ol>
519
+ </li>
520
+ </ol>
521
+ </li>
522
+ <li id="_sidebar_6"><a href="#sec-Program-Examples"><span class="spec-secid">6</span>Program Examples</a></li>
523
+ <li id="_sidebar_index"><a href="#index"><span class="spec-secid">§</span>Index</a></li>
524
+ </ol>
525
+ </div>
526
+ </div>
527
+ </body>
528
+ </html>
package/spec/spec.md ADDED
@@ -0,0 +1,332 @@
1
+ # Graffiticode Core Language Specification
2
+
3
+ # Introduction
4
+
5
+ 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.
6
+
7
+ # Lexical Structure
8
+
9
+ ## Tokens
10
+
11
+ - **Identifiers**: Alphanumeric symbols beginning with a letter.
12
+ - **Numbers**: Integers and floats. Negative numbers start with `-`.
13
+ - **Strings**: Double-quoted UTF-8 strings.
14
+ - **Symbols**: `(`, `)`, `[`, `]`, `{`, `}`, `:`, `..`, `<`, `>`, `,`
15
+
16
+ ## Comments
17
+
18
+ - **Line Comments**: Begin with `|` and continue to end of line.
19
+
20
+ # Syntax
21
+
22
+ ## Programs
23
+
24
+ A **Graffiticode program** is a sequence of one or more `let` declarations, followed by a single top-level expression, and terminated with `..`.
25
+
26
+ ```
27
+ let double = <x: mul 2 x>..
28
+ map (double) [1 2 3]..
29
+ ```
30
+
31
+ The top-level expression must always be followed by `..`.
32
+
33
+ ## Expressions
34
+
35
+ ### Function Application
36
+
37
+ Function application is written in prefix style:
38
+ ```
39
+ add 1 2
40
+ ```
41
+
42
+ Parentheses are used to defer application:
43
+ ```
44
+ map (double) [1 2 3]
45
+ ```
46
+
47
+ ### Lists
48
+ ```
49
+ [1 2 3]
50
+ ```
51
+
52
+ ### Records
53
+ ```
54
+ { name: "Alice", age: 30 }
55
+ ```
56
+
57
+ ### Lambdas
58
+ ```
59
+ <x: add x 1>
60
+ ```
61
+ Multiple parameters:
62
+ ```
63
+ <x y: add x y>
64
+ ```
65
+
66
+ ### Let Bindings
67
+ ```
68
+ let double = <x: mul 2 x>..
69
+ ```
70
+
71
+ ## Pattern Matching
72
+
73
+ Pattern matching is done using `case`:
74
+ ```
75
+ case x of
76
+ 0: "zero"
77
+ 1: "one"
78
+ _: "other"
79
+ end
80
+ ```
81
+
82
+ Supports:
83
+ - Literal values
84
+ - Tuple destructuring: `(a, b)`
85
+ - Record destructuring: `{ name, age }`
86
+ - Wildcard `_`
87
+
88
+ Pattern matching on function arguments is disallowed.
89
+
90
+ ### Tag Values
91
+
92
+ A **tag value** is an arity-0 symbolic value that can be used in pattern matching or to encode variant types.
93
+
94
+ ```
95
+ red
96
+ ```
97
+
98
+ Tag values:
99
+
100
+ - Are unbound identifiers that appear in expression position.
101
+ - May optionally be introduced via implicit enum definitions.
102
+ - Match directly in `case` expressions:
103
+
104
+ ```
105
+ case color of
106
+ red: "warm"
107
+ blue: "cool"
108
+ _: "other"
109
+ end
110
+ ```
111
+
112
+ Tags are resolved as special constants with symbolic identity. They are case-sensitive and may be compared for equality using regular pattern match semantics.
113
+
114
+ # Semantics
115
+
116
+ ## Evaluation Model
117
+
118
+ - **Purely functional**: no side effects
119
+ - **Strict evaluation**: arguments evaluated before function application
120
+ - **Immutable data**: all values are immutable
121
+
122
+ ## Functions
123
+
124
+ - **Fixed arity**: every function has a known number of parameters
125
+ - **Curried by default**: partial application supported
126
+
127
+ ## Scoping
128
+
129
+ - **Lexical scoping**
130
+ - **Shadowing** allowed within nested scopes
131
+
132
+ ## Errors
133
+
134
+ - **Syntax errors**: raised during parsing
135
+ - **Type errors**: raised during compilation
136
+ - **Runtime errors**: e.g., out-of-bounds access
137
+
138
+ # Base Library
139
+
140
+ ## Types
141
+
142
+ - `number`
143
+ - `string`
144
+ - `bool`
145
+ - `list`
146
+ - `record`
147
+ - `tuple`
148
+ - `json`
149
+
150
+ ## Built-in Functions
151
+
152
+ | Function | Signature | Description |
153
+ | :------- | :-------- | :---------- |
154
+ | `add` | `<number number: number>` | Adds two numbers |
155
+ | `sub` | `<number number: number>` | Subtracts numbers |
156
+ | `mul` | `<number number: number>` | Multiplies numbers |
157
+ | `div` | `<number number: number>` | Divides numbers |
158
+ | `mod` | `<number number: number>` | Remainder of division |
159
+ | `min` | `<number number: number>` | Returns the smaller of two numbers |
160
+ | `max` | `<number number: number>` | Returns the larger of two numbers |
161
+ | `range` | `<number number number: list>` | Generates a range list |
162
+ | `map` | `<function list: list>` | Applies function to each item |
163
+ | `filter` | `<function list: list>` | Keeps items matching predicate |
164
+ | `reduce` | `<function list: any>` | Combines list using a reducer |
165
+ | `hd` | `<list: any>` | First item of list |
166
+ | `tl` | `<list: list>` | All items except first |
167
+ | `nth` | `<number list: any>` | Nth element of list |
168
+ | `apply` | `<function list: any>` | Applies a function to a list of arguments |
169
+ | `isEmpty` | `<list: bool>` | Returns true if the list is empty |
170
+ | `get` | `<record string: any>` | Retrieves a value from a record by key |
171
+ | `set` | `<record string any: record>` | Returns a new record with a key set to a value |
172
+
173
+ ### add
174
+
175
+ Add two numbers.
176
+
177
+ ```
178
+ add 2 3 | returns 5
179
+ ```
180
+
181
+ ### sub
182
+
183
+ Subtract the second number from the first
184
+
185
+ ```
186
+ sub 5 2 | returns 3
187
+ ```
188
+
189
+ ### mul
190
+
191
+ Multiply two numbers
192
+
193
+ ```
194
+ mul 4 3 | returns 12
195
+ ```
196
+
197
+ ### div
198
+
199
+ Divide the first number by the second
200
+
201
+ ```
202
+ div 10 2 | returns 5
203
+ ```
204
+
205
+ ### mod
206
+
207
+ Compute the remainder
208
+
209
+ ```
210
+ mod 10 3 | returns 1
211
+ ```
212
+
213
+ ### min
214
+
215
+ Return the smaller of two numbers
216
+
217
+ ```
218
+ min 5 10 | returns 5
219
+ ```
220
+
221
+ ### max
222
+
223
+ Return the larger of two numbers
224
+
225
+ ```
226
+ max 5 10 | returns 10
227
+ ```
228
+
229
+ ### range
230
+
231
+ Produce a range list from start to end (exclusive) with step
232
+
233
+ ```
234
+ range 1 10 2 | returns [1 3 5 7 9]
235
+ ```
236
+
237
+ ### map
238
+
239
+ Apply a function to each element
240
+
241
+ ```
242
+ map (<x: add x 1>) [1 2 3] | returns [2 3 4]
243
+ ```
244
+
245
+ ### filter
246
+
247
+ Filter elements matching predicate
248
+
249
+ ```
250
+ filter (<x: mod x 2>) [1 2 3 4] | returns [1 3]
251
+ ```
252
+
253
+ ### reduce
254
+
255
+ Reduce a list to a single value, starting with an initial value
256
+
257
+ ```
258
+ reduce (<a b: add a b>) 0 [1 2 3 4] | returns 10
259
+ ```
260
+
261
+ ### hd
262
+
263
+ Return the first item
264
+
265
+ ```
266
+ hd [10 20 30] | returns 10
267
+ ```
268
+
269
+ ### tl
270
+
271
+ Return all but the first item
272
+
273
+ ```
274
+ tl [10 20 30] | returns [20 30]
275
+ ```
276
+
277
+ ### nth
278
+
279
+ Get the nth item (0-based)
280
+
281
+ ```
282
+ nth 1 [10 20 30] | returns 20
283
+ ```
284
+
285
+ ### apply
286
+
287
+ Apply a function to an argument list
288
+
289
+ ```
290
+ apply add [1 2] | returns 3
291
+ ```
292
+
293
+ ### isEmpty
294
+
295
+ Return true if list is empty, otherwise return false
296
+
297
+ ```
298
+ isEmpty [] | returns true
299
+ ```
300
+
301
+ ### get
302
+
303
+ Retrieve a record field
304
+
305
+ ```
306
+ get {a: 1, b: 2} "b" | returns 2
307
+ ```
308
+
309
+ ### set
310
+
311
+ Return a new record with an updated field
312
+
313
+ ```
314
+ set {a: 1} "a" 2 | returns {a: 2}
315
+ ```
316
+
317
+ # Program Examples
318
+
319
+ ```
320
+ let double = <x: mul 2 x>..
321
+ map (double) [1 2 3]..
322
+ ```
323
+
324
+ ```
325
+ case age of
326
+ 18: "adult"
327
+ _: "other"
328
+ end..
329
+ ```
330
+
331
+ ---
332
+
package/src/compiler.js CHANGED
@@ -407,6 +407,24 @@ export class Checker extends Visitor {
407
407
  });
408
408
  });
409
409
  }
410
+ MIN(node, options, resume) {
411
+ this.visit(node.elts[0], options, (err1, val1) => {
412
+ this.visit(node.elts[1], options, (err2, val2) => {
413
+ const err = [].concat(err1).concat(err2);
414
+ const val = node;
415
+ resume(err, val);
416
+ });
417
+ });
418
+ }
419
+ MAX(node, options, resume) {
420
+ this.visit(node.elts[0], options, (err1, val1) => {
421
+ this.visit(node.elts[1], options, (err2, val2) => {
422
+ const err = [].concat(err1).concat(err2);
423
+ const val = node;
424
+ resume(err, val);
425
+ });
426
+ });
427
+ }
410
428
  }
411
429
 
412
430
  function enterEnv(ctx, name, paramc) {
@@ -503,7 +521,7 @@ export class Transformer extends Visitor {
503
521
  }
504
522
  const patternNid = this.internPattern(pattern);
505
523
  if (patternNid === this.internPattern(node) ||
506
- patternNid === this.internPattern(newNode('IDENT', ['_']))) {
524
+ patternNid === this.internPattern(newNode('_', []))) {
507
525
  return true;
508
526
  }
509
527
  if (pattern.tag === node.tag) {
@@ -1097,6 +1115,32 @@ export class Transformer extends Visitor {
1097
1115
  });
1098
1116
  });
1099
1117
  }
1118
+ MIN(node, options, resume) {
1119
+ this.visit(node.elts[0], options, (e0, v0) => {
1120
+ this.visit(node.elts[1], options, (e1, v1) => {
1121
+ const err = [].concat(e0).concat(e1);
1122
+ try {
1123
+ const val = Decimal.min(new Decimal(v0), new Decimal(v1)).toNumber();
1124
+ resume(err, val);
1125
+ } catch (e) {
1126
+ resume([...err, `Error in MIN operation: ${e.message}`], NaN);
1127
+ }
1128
+ });
1129
+ });
1130
+ }
1131
+ MAX(node, options, resume) {
1132
+ this.visit(node.elts[0], options, (e0, v0) => {
1133
+ this.visit(node.elts[1], options, (e1, v1) => {
1134
+ const err = [].concat(e0).concat(e1);
1135
+ try {
1136
+ const val = Decimal.max(new Decimal(v0), new Decimal(v1)).toNumber();
1137
+ resume(err, val);
1138
+ } catch (e) {
1139
+ resume([...err, `Error in MAX operation: ${e.message}`], NaN);
1140
+ }
1141
+ });
1142
+ });
1143
+ }
1100
1144
  RANGE(node, options, resume) {
1101
1145
  this.visit(node.elts[0], options, (e0, v0) => {
1102
1146
  this.visit(node.elts[1], options, (e1, v1) => {
package/src/lexicon.js ADDED
@@ -0,0 +1,191 @@
1
+ export const lexicon = {
2
+ "print" : {
3
+ "tk": 1,
4
+ "name": "PRINT",
5
+ "cls": "function",
6
+ "length": 1,
7
+ "arity": 1
8
+ },
9
+ "get" : {
10
+ "tk": 1,
11
+ "name": "GET",
12
+ "cls": "function",
13
+ "length": 2,
14
+ "arity": 2
15
+ },
16
+ "set" : {
17
+ "tk": 1,
18
+ "name": "SET",
19
+ "cls": "function",
20
+ "length": 3,
21
+ "arity": 3
22
+ },
23
+ "nth" : {
24
+ "tk": 1,
25
+ "name": "NTH",
26
+ "cls": "function",
27
+ "length": 2,
28
+ "arity": 2
29
+ },
30
+ "sub" : {
31
+ "tk": 1,
32
+ "name": "SUB",
33
+ "cls": "function",
34
+ "length": 2,
35
+ "arity": 2
36
+ },
37
+ "filter" : {
38
+ "tk": 1,
39
+ "name": "FILTER",
40
+ "cls": "function",
41
+ "length": 2,
42
+ "arity": 2
43
+ },
44
+ "reduce" : {
45
+ "tk": 1,
46
+ "name": "REDUCE",
47
+ "cls": "function",
48
+ "length": 3,
49
+ "arity": 3
50
+ },
51
+ "map" : {
52
+ "tk": 1,
53
+ "name": "MAP",
54
+ "cls": "function",
55
+ "length": 2,
56
+ "arity": 2
57
+ },
58
+ "lt" : {
59
+ "tk": 1,
60
+ "name": "LT",
61
+ "cls": "function",
62
+ "length": 2,
63
+ "arity": 2
64
+ },
65
+ "le" : {
66
+ "tk": 1,
67
+ "name": "LE",
68
+ "cls": "function",
69
+ "length": 2,
70
+ "arity": 2
71
+ },
72
+ "gt" : {
73
+ "tk": 1,
74
+ "name": "GT",
75
+ "cls": "function",
76
+ "length": 2,
77
+ "arity": 2
78
+ },
79
+ "ge" : {
80
+ "tk": 1,
81
+ "name": "GE",
82
+ "cls": "function",
83
+ "length": 2,
84
+ "arity": 2
85
+ },
86
+ "ne" : {
87
+ "tk": 1,
88
+ "name": "NE",
89
+ "cls": "function",
90
+ "length": 2,
91
+ "arity": 2
92
+ },
93
+ "len" : {
94
+ "tk": 1,
95
+ "name": "LEN",
96
+ "cls": "function",
97
+ "length": 1,
98
+ "arity": 1
99
+ },
100
+ "concat" : {
101
+ "tk": 1,
102
+ "name": "CONCAT",
103
+ "cls": "function",
104
+ "length": 1,
105
+ "arity": 1
106
+ },
107
+ "add" : {
108
+ "tk": 1,
109
+ "name": "ADD",
110
+ "cls": "function",
111
+ "length": 2,
112
+ "arity": 2
113
+ },
114
+ "mul" : {
115
+ "tk": 1,
116
+ "name": "MUL",
117
+ "cls": "function",
118
+ "length": 2,
119
+ "arity": 2
120
+ },
121
+ "pow" : {
122
+ "tk": 1,
123
+ "name": "POW",
124
+ "cls": "function",
125
+ "length": 2,
126
+ "arity": 2
127
+ },
128
+ "map" : {
129
+ "tk": 1,
130
+ "name": "MAP",
131
+ "cls": "function",
132
+ "length": 2,
133
+ "arity": 2
134
+ },
135
+ "apply" : {
136
+ "tk": 1,
137
+ "name": "APPLY",
138
+ "cls": "function",
139
+ "length": 2,
140
+ "arity": 2
141
+ },
142
+ "data" : {
143
+ "tk": 1,
144
+ "name": "DATA",
145
+ "cls": "function",
146
+ "length": 1,
147
+ "arity": 1
148
+ },
149
+ "json" : {
150
+ "tk": 1,
151
+ "name": "JSON",
152
+ "cls": "function",
153
+ "length": 1,
154
+ "arity": 1
155
+ },
156
+ "eq" : {
157
+ "tk": 1,
158
+ "name": "EQ",
159
+ "cls": "function",
160
+ "length": 2,
161
+ "arity": 2
162
+ },
163
+ "mod" : {
164
+ "tk": 1,
165
+ "name": "MOD",
166
+ "cls": "function",
167
+ "length": 2,
168
+ "arity": 2
169
+ },
170
+ "min" : {
171
+ "tk": 1,
172
+ "name": "MIN",
173
+ "cls": "function",
174
+ "length": 2,
175
+ "arity": 2
176
+ },
177
+ "max" : {
178
+ "tk": 1,
179
+ "name": "MAX",
180
+ "cls": "function",
181
+ "length": 2,
182
+ "arity": 2
183
+ },
184
+ "range" : {
185
+ "tk": 1,
186
+ "name": "RANGE",
187
+ "cls": "function",
188
+ "length": 3,
189
+ "arity": 3
190
+ }
191
+ }