├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── coil-lang-vs-code ├── .vscodeignore ├── README.md ├── language-configuration.json ├── package.json └── syntaxes │ └── coil.tmLanguage.json └── compiler ├── LICENSE ├── dist ├── cli.mjs ├── compiler.mjs ├── emit.mjs ├── parse_error.mjs ├── parser.mjs ├── shared.mjs └── tokenizer.mjs ├── eval ├── example.coil ├── package-lock.json ├── package.json ├── rebuild_compiler ├── run_tests ├── src ├── cli.coil ├── compiler.coil ├── emit.coil ├── parser.coil ├── shared.coil ├── std │ ├── algebra.mjs │ ├── bool.mjs │ ├── collection.mjs │ ├── globals.mjs │ ├── iter.mjs │ ├── meta.mjs │ ├── ordered_collection.mjs │ ├── range.mjs │ ├── record.mjs │ └── underscore.mjs └── tokenizer.coil └── test ├── algebra.coil └── collection.coil /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.js 3 | **/**/dist/test -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Working on the Compiler 2 | 3 | [Contributing doc](./compiler/CONTRIBUTING.md) 4 | 5 | # Vs Code extension 6 | 7 | Copy the extension into vscode extensions folder to get syntax highlighting 8 | 9 | ``` 10 | $> cp -r coil-lang-vs-code ~/.vscode/extensions 11 | ``` 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Marcel-Alin Rusu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coil-Lang 2 | 3 | Coil is a web language that is made with love 4 | 5 | Coil values expressiveness & code-reuse with minimal hassle 6 | -------------------------------------------------------------------------------- /coil-lang-vs-code/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .gitignore 4 | vsc-extension-quickstart.md 5 | -------------------------------------------------------------------------------- /coil-lang-vs-code/README.md: -------------------------------------------------------------------------------- 1 | # Coil Syntax Highlighter for VSCode 2 | 3 | # Installation 4 | 5 | ``` 6 | cp -r coil-lang-vs-code ~/.vscode/extensions/ 7 | ``` 8 | -------------------------------------------------------------------------------- /coil-lang-vs-code/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | // symbol used for single line comment. Remove this entry if your language does not support line comments 4 | "lineComment": "--", 5 | // symbols used for start and end a block comment. Remove this entry if your language does not support block comments 6 | "blockComment": ["/*", "*/"] 7 | }, 8 | // symbols used as brackets 9 | "brackets": [ 10 | ["{", "}"], 11 | ["[", "]"], 12 | ["(", ")"] 13 | ], 14 | // symbols that are auto closed when typing 15 | "autoClosingPairs": [ 16 | ["{", "}"], 17 | ["[", "]"], 18 | ["(", ")"], 19 | ["\"", "\""], 20 | ["'", "'"] 21 | ], 22 | // symbols that can be used to surround a selection 23 | "surroundingPairs": [ 24 | ["{", "}"], 25 | ["[", "]"], 26 | ["(", ")"], 27 | ["\"", "\""], 28 | ["'", "'"] 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /coil-lang-vs-code/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coil-lang", 3 | "displayName": "coil-lang", 4 | "description": "coil language support", 5 | "version": "0.0.1", 6 | "engines": { 7 | "vscode": "^1.75.0" 8 | }, 9 | "categories": [ 10 | "Programming Languages" 11 | ], 12 | "contributes": { 13 | "languages": [ 14 | { 15 | "id": "coil", 16 | "aliases": [ 17 | "coil", 18 | "coil" 19 | ], 20 | "extensions": [ 21 | ".coil" 22 | ], 23 | "configuration": "./language-configuration.json" 24 | } 25 | ], 26 | "grammars": [ 27 | { 28 | "language": "coil", 29 | "scopeName": "source.coil", 30 | "path": "./syntaxes/coil.tmLanguage.json" 31 | } 32 | ] 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /coil-lang-vs-code/syntaxes/coil.tmLanguage.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", 3 | "name": "coil", 4 | "patterns": [ 5 | { 6 | "include": "#comments" 7 | }, 8 | { 9 | "include": "#lang_constants" 10 | }, 11 | { 12 | "include": "#strings" 13 | }, 14 | { 15 | "include": "#regex" 16 | }, 17 | { 18 | "include": "#functions" 19 | }, 20 | { 21 | "include": "#record_constructor" 22 | }, 23 | { 24 | "include": "#keywords" 25 | }, 26 | { 27 | "include": "#variables" 28 | }, 29 | { 30 | "include": "#numbers" 31 | } 32 | ], 33 | "repository": { 34 | "comments": { 35 | "patterns": [ 36 | { 37 | "name": "comment.line.coil", 38 | "begin": "(--).*", 39 | "end": "\n" 40 | } 41 | ] 42 | }, 43 | "keywords": { 44 | "patterns": [ 45 | { 46 | "name": "keyword.control.coil", 47 | "match": "(await|async|or|and|keyof|of|impl|define|let|protocol|do|end|if|def|fn|while|loop|try|catch|finally|else|yield|return|continue|break|export|default|import|from|for)\\b" 48 | } 49 | ] 50 | }, 51 | "variables": { 52 | "patterns": [ 53 | { 54 | "match": "\\b([A-Z][a-zA-Z0-9_\\-\\!\\?]*)\\b", 55 | "name": "entity.name.type" 56 | }, 57 | { 58 | "match": "\\b([a-z][a-zA-Z0-9_\\-\\!\\?]*)\\b", 59 | "name": "variable.name" 60 | } 61 | ] 62 | }, 63 | "lang_constants": { 64 | "patterns": [ 65 | { 66 | "match": "\\b(instanceof|true|false|nil|this)\\b", 67 | "name": "constant.language" 68 | }, 69 | { 70 | "match": "(:[a-zA-Z_?!$0-9/]+)", 71 | "name": "constant.language" 72 | } 73 | ] 74 | }, 75 | "functions": { 76 | "patterns": [ 77 | { 78 | "match": "\\.([a-zA-Z][a-zA-Z0-9_\\!\\?]+)\\(", 79 | "name": "entity.name.function" 80 | }, 81 | { 82 | "match": "([a-zA-Z][a-zA-Z0-9_\\!\\?]+)\\(", 83 | "name": "entity.name.function" 84 | } 85 | ] 86 | }, 87 | "regex": { 88 | "name": "constant.regexp", 89 | "match": "(\\/.*\\/)", 90 | "patterns": [ 91 | { 92 | "name": "constant.character.escape.coil", 93 | "match": "\\\\." 94 | } 95 | ] 96 | }, 97 | "strings": { 98 | "name": "string.quoted.double.coil", 99 | "begin": "\"", 100 | "end": "\"", 101 | "patterns": [ 102 | { 103 | "name": "constant.character.escape.coil", 104 | "match": "\\\\." 105 | } 106 | ] 107 | }, 108 | "numbers": { 109 | "patterns": [ 110 | { 111 | "match": "[\\-\\+]?(\\d+)(n)", 112 | "captures": { 113 | "1": { 114 | "name": "constant.numeric" 115 | }, 116 | "2": { 117 | "name": "emphasis" 118 | } 119 | } 120 | }, 121 | { 122 | "name": "constant.numeric", 123 | "match": "[\\-\\+]?(\\d*\\.)?\\d+" 124 | } 125 | ] 126 | } 127 | }, 128 | "scopeName": "source.coil" 129 | } 130 | -------------------------------------------------------------------------------- /compiler/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2024 Marcel-Alin Rusu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /compiler/dist/cli.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | import compile from "./compiler.mjs"; 14 | let [src_file_name, out_name, ...args] = dot(Deno, 'args'); 15 | src_file_name ??= nil; 16 | out_name ??= nil; 17 | args ??= nil;; 18 | let src = dot(Deno, 'readTextFileSync')[invoke](src_file_name); 19 | src ??= nil;; 20 | let std_prefix = "."; 21 | std_prefix ??= nil;; 22 | var __coil_if_let_temp = dot(args, find)[invoke](dot(_, has__q)[invoke]("--std-prefix")) ?? nil; 23 | if (__coil_if_let_temp[Meta.as_bool]()) { 24 | let arg = __coil_if_let_temp; 25 | arg ??= nil;; 26 | let __coil_temp; 27 | std_prefix = dot(dot(arg, 'split')[invoke]("--std-prefix="), at)[invoke]((-1)); 28 | }; 29 | dot(Deno, 'writeTextFile')[invoke](out_name, compile[invoke](src, std_prefix)[Algebra["+"]]("\n")); 30 | -------------------------------------------------------------------------------- /compiler/dist/compiler.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | import {ParseError} from "./parse_error.mjs"; 14 | import tokenize from "./tokenizer.mjs"; 15 | import parse from "./parser.mjs"; 16 | import emit from "./emit.mjs"; 17 | import {CollectionView} from "./shared.mjs"; 18 | let compile = function (string, std_prefix) { 19 | string ??= nil; 20 | std_prefix ??= nil;let __coil_temp; 21 | let tokens = dot(string, pipe)[invoke](tokenize); 22 | tokens ??= nil;; 23 | let collection_view = CollectionView[Meta.create]([tokens, (0)]); 24 | collection_view ??= nil;; 25 | let ast = parse[invoke](collection_view); 26 | ast ??= nil;; 27 | let js = emit[invoke](ast); 28 | js ??= nil;; 29 | let imports = str[invoke](`\"use strict\"; 30 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '`, std_prefix, `/src/std/globals.mjs' 31 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '`, std_prefix, `/src/std/meta.mjs'; 32 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '`, std_prefix, `/src/std/iter.mjs'; 33 | import Algebra from '`, std_prefix, `/src/std/algebra.mjs'; 34 | import Bool, {negate} from '`, std_prefix, `/src/std/bool.mjs'; 35 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '`, std_prefix, `/src/std/collection.mjs'; 36 | import OrderedCollection, {first} from '`, std_prefix, `/src/std/ordered_collection.mjs'; 37 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '`, std_prefix, `/src/std/range.mjs'; 38 | import Record, {keys, values, set, set__b} from '`, std_prefix, `/src/std/record.mjs'; 39 | import Underscore, {_} from '`, std_prefix, `/src/std/underscore.mjs'; 40 | `); 41 | imports ??= nil;; 42 | return imports[Algebra["+"]](js);}; 43 | export default compile; 44 | -------------------------------------------------------------------------------- /compiler/dist/emit.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | let resolve_name = function (name) { 14 | name ??= nil;let __coil_temp; 15 | if ((name[Meta["=="]]("new"))[Meta.as_bool]()) { 16 | let __coil_temp; 17 | return "__new__"; 18 | } else if ((name[Meta["=="]]("delete"))[Meta.as_bool]()) { 19 | let __coil_temp; 20 | return "__delete__"; 21 | } else if ((name)[Meta.as_bool]()) { 22 | let __coil_temp; 23 | return dot(dot(dot(name, Keyword.for("replaceAll"))[invoke]("?", "__q"), Keyword.for("replaceAll"))[invoke]("!", "__b"), Keyword.for("replaceAll"))[invoke](">", "_lt_"); 24 | } else { 25 | let __coil_temp; 26 | return name; 27 | };}; 28 | let eval_if_branch = function (branch) { 29 | branch ??= nil;let __coil_temp; 30 | if ((dot(branch, nil__q)[invoke]())[Meta.as_bool]()) { 31 | let __coil_temp; 32 | return ""; 33 | } else if ((dot(branch, Keyword.for("type"))[Meta["=="]](Keyword.for("else")))[Meta.as_bool]()) { 34 | let __coil_temp; 35 | return str[invoke](" else {\n", eval_ast[invoke]((__coil_temp = {left: dot(branch, Keyword.for("body"))}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : [])), "\n}"); 36 | } else if ((dot(branch, Keyword.for("type"))[Meta["=="]](Keyword.for("else_if_let")))[Meta.as_bool]()) { 37 | let __coil_temp; 38 | return str[invoke](" else {\n", eval_if_let[invoke](branch), "\n}"); 39 | } else if ((dot(branch, Keyword.for("type"))[Meta["=="]](Keyword.for("else_if")))[Meta.as_bool]()) { 40 | let __coil_temp; 41 | return str[invoke](" else if ((", eval_expr[invoke](dot(branch, at)[invoke](Keyword.for("expr"))), ")[Meta.as_bool]()) {\n", eval_ast[invoke]((__coil_temp = {left: dot(branch, at)[invoke](Keyword.for("pass"))}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : [])), "\n}", eval_if_branch[invoke](dot(branch, at)[invoke](Keyword.for("fail")))); 42 | } else { 43 | let __coil_temp; 44 | panic__b[invoke]("Expected else if"); 45 | };}; 46 | let eval_if = function ({'expr': expr, 'pass': pass, 'fail': fail}) { 47 | expr ??= nil; 48 | pass ??= nil; 49 | fail ??= nil;let __coil_temp; 50 | return str[invoke]("if ((", eval_expr[invoke](expr), ")[Meta.as_bool]()) {\n", eval_ast[invoke](pass), "\n", "}", eval_if_branch[invoke](fail));}; 51 | let eval_str = function ({'value': value}) { 52 | value ??= nil;let __coil_temp; 53 | value = dot(value, Keyword.for("slice"))[invoke]((1), (-1)); 54 | if ((dot(value, Keyword.for("includes"))[invoke]("\n"))[Meta.as_bool]()) { 55 | let __coil_temp; 56 | return str[invoke]("`", dot(value, 'replaceAll')[invoke]("`", "\\`"), "`"); 57 | } else { 58 | let __coil_temp; 59 | return str[invoke]("\"", value, "\""); 60 | };}; 61 | let eval_fn_call = function ({'lhs': lhs, 'args': args}) { 62 | lhs ??= nil; 63 | args ??= nil;let __coil_temp; 64 | return str[invoke](eval_expr[invoke](lhs), "[invoke](", dot(dot(args, map)[invoke](eval_expr), join)[invoke](", "), ")");}; 65 | let eval_id_assign_name = function ({'name': name}) { 66 | name ??= nil;let __coil_temp; 67 | if ((name[Meta["=="]]("_"))[Meta.as_bool]()) { 68 | let __coil_temp; 69 | return "_ignore_me_"; 70 | } else { 71 | let __coil_temp; 72 | return resolve_name[invoke](name); 73 | };}; 74 | let eval_spread_assign = function ({'name': name}) { 75 | name ??= nil;let __coil_temp; 76 | return str[invoke]("...", resolve_name[invoke](name));}; 77 | let eval_array_deconstruction_entry = function (node) { 78 | node ??= nil;let __coil_temp; 79 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("id_assign"), eval_id_assign_name], [Keyword.for("spread_assign"), eval_spread_assign], [Keyword.for("array_deconstruction"), eval_array_deconstruction_names], [Keyword.for("object_deconstruction"), eval_object_deconstruction_names]]))[invoke](node);}; 80 | let eval_array_deconstruction_names = function ({'entries': entries}) { 81 | entries ??= nil;let __coil_temp; 82 | return str[invoke]("[", dot(dot(entries, map)[invoke](eval_array_deconstruction_entry), join)[invoke](", "), "]");}; 83 | let eval_obj_reg_entry = function ({'name': name}) { 84 | name ??= nil;let __coil_temp; 85 | return str[invoke]("'", name, "': ", resolve_name[invoke](name));}; 86 | let eval_obj_entry_rename = function ({'old_name': old_name, 'new_name': new_name}) { 87 | old_name ??= nil; 88 | new_name ??= nil;let __coil_temp; 89 | return str[invoke]("'", old_name, "': ", resolve_name[invoke](new_name));}; 90 | let eval_obj_assign_expr = function ({'property': property, 'assign_expr': assign_expr}) { 91 | property ??= nil; 92 | assign_expr ??= nil;let __coil_temp; 93 | return str[invoke]("'", property, "': ", eval_assign_expr[invoke](assign_expr));}; 94 | let eval_obj_deconstruction_entry = function (node) { 95 | node ??= nil;let __coil_temp; 96 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("obj_reg_entry"), eval_obj_reg_entry], [Keyword.for("obj_assign_expr"), eval_obj_assign_expr], [Keyword.for("obj_entry_rename"), eval_obj_entry_rename], [Keyword.for("spread_assign"), eval_spread_assign], [Keyword.for("object_deconstruction"), eval_object_deconstruction_names]]))[invoke](node);}; 97 | let eval_object_deconstruction_names = function ({'entries': entries}) { 98 | entries ??= nil;let __coil_temp; 99 | return str[invoke]("{", dot(dot(entries, map)[invoke](eval_obj_deconstruction_entry), join)[invoke](", "), "}");}; 100 | let eval_this_assign = function ({'name': name}) { 101 | name ??= nil;let __coil_temp; 102 | return resolve_name[invoke](name);}; 103 | let eval_this_spread_assign = function ({'name': name}) { 104 | name ??= nil;let __coil_temp; 105 | return str[invoke]("...", resolve_name[invoke](name));}; 106 | let eval_assign_all_as = function ({'name': name}) { 107 | name ??= nil;let __coil_temp; 108 | return str[invoke]("* as ", name);}; 109 | let eval_assign_expr = function (node) { 110 | node ??= nil;let __coil_temp; 111 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("id_assign"), eval_id_assign_name], [Keyword.for("spread_assign"), eval_spread_assign], [Keyword.for("array_deconstruction"), eval_array_deconstruction_names], [Keyword.for("object_deconstruction"), eval_object_deconstruction_names], [Keyword.for("this_assign"), eval_this_assign], [Keyword.for("this_spread_assign"), eval_spread_assign]]))[invoke](node);}; 112 | let eval_while_let_loop = function ({'test_expr': test_expr, 'assign_expr': assign_expr, 'body': body}) { 113 | test_expr ??= nil; 114 | assign_expr ??= nil; 115 | body ??= nil;let __coil_temp; 116 | return str[invoke]("var __coil_while_let_temp = ", eval_expr[invoke](test_expr), " ?? nil;\n", "while (__coil_while_let_temp[Meta.as_bool]()) {\n", "let ", eval_assign_expr[invoke](assign_expr), " = __coil_while_let_temp;\n", eval_nil_destructure_args[invoke]([assign_expr]), ";\n", eval_ast[invoke](body), "\n", "__coil_while_let_temp = ", eval_expr[invoke](test_expr), " ?? nil;\n", "}");}; 117 | let eval_if_let = function ({'expr': expr, 'assign_expr': assign_expr, 'pass': pass, 'fail': fail}) { 118 | expr ??= nil; 119 | assign_expr ??= nil; 120 | pass ??= nil; 121 | fail ??= nil;let __coil_temp; 122 | return str[invoke]("var __coil_if_let_temp = ", eval_expr[invoke](expr), " ?? nil;\n", "if (__coil_if_let_temp[Meta.as_bool]()) {\n", "let ", eval_assign_expr[invoke](assign_expr), " = __coil_if_let_temp;\n", eval_nil_destructure_args[invoke]([assign_expr]), ";\n", eval_ast[invoke](pass), "\n", "}", eval_if_branch[invoke](fail));}; 123 | let eval_spread = function ({'expr': expr}) { 124 | expr ??= nil;let __coil_temp; 125 | return str[invoke]("...", eval_expr[invoke](expr));}; 126 | let eval_let = function ({'assign_expr': assign_expr, 'rhs': rhs}) { 127 | assign_expr ??= nil; 128 | rhs ??= nil;let __coil_temp; 129 | return str[invoke]("let ", eval_assign_expr[invoke](assign_expr), " = ", eval_expr[invoke](rhs), ";\n", eval_nil_destructure_args[invoke]([assign_expr]));}; 130 | let eval_array = function ({'elements': elements}) { 131 | elements ??= nil;let __coil_temp; 132 | return str[invoke]("[", dot(dot(elements, map)[invoke](eval_expr), join)[invoke](", "), "]");}; 133 | let eval_this_assignments = function (args) { 134 | args ??= nil;let __coil_temp; 135 | return dot(dot(dot(args, filter)[invoke](Keyword.for("type"), Set[Meta.create]([Keyword.for("this_assign"), Keyword.for("this_spread_assign")])), map)[invoke](({'name': name}) => { 136 | name ??= nil;; 137 | return str[invoke]("this['", name, "'] = ", resolve_name[invoke](name), ";\n");}), into)[invoke]("");}; 138 | let eval_name_expr = function (node) { 139 | node ??= nil;let __coil_temp; 140 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("dot"), function ({'lhs': lhs, 'rhs': rhs}) { 141 | lhs ??= nil; 142 | rhs ??= nil;let __coil_temp; 143 | return str[invoke](eval_name_expr[invoke](lhs), "[", eval_name_expr[invoke](rhs), "]");}], [Keyword.for("keyword_lookup"), function ({'lhs': lhs, 'property': property}) { 144 | lhs ??= nil; 145 | property ??= nil;let __coil_temp; 146 | return str[invoke](eval_name_expr[invoke](lhs), "['", property, "']");}]]), (eval_fn) => { 147 | eval_fn ??= nil;; 148 | return (__coil_temp = {left: eval_fn}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : eval_expr);})[invoke](node);}; 149 | let entries_arg_names = function ({'entries': entries}) { 150 | entries ??= nil;let __coil_temp; 151 | return dot(entries, 'flatMap')[invoke](arg_names);}; 152 | let arg_names = function (node) { 153 | node ??= nil;let __coil_temp; 154 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("array_deconstruction"), entries_arg_names], [Keyword.for("object_deconstruction"), entries_arg_names], [Keyword.for("obj_assign_expr"), function ({'property': property, 'assign_expr': assign_expr}) { 155 | property ??= nil; 156 | assign_expr ??= nil;let __coil_temp; 157 | return arg_names[invoke](assign_expr);}], [Keyword.for("id_assign"), function ({'name': name}) { 158 | name ??= nil;let __coil_temp; 159 | return [name];}], [Keyword.for("obj_reg_entry"), function ({'name': name}) { 160 | name ??= nil;let __coil_temp; 161 | return [name];}], [Keyword.for("obj_entry_rename"), function ({'new_name': new_name}) { 162 | new_name ??= nil;let __coil_temp; 163 | return [new_name];}], [Keyword.for("spread_assign"), function ({'name': name}) { 164 | name ??= nil;let __coil_temp; 165 | return [name];}], [Keyword.for("obj_str_rename_entry"), function ({'new_name': new_name}) { 166 | new_name ??= nil;let __coil_temp; 167 | return [new_name];}], [Keyword.for("this_assign"), function ({'name': name}) { 168 | name ??= nil;let __coil_temp; 169 | return [name];}], [Keyword.for("this_spread_assign"), function ({'name': name}) { 170 | name ??= nil;let __coil_temp; 171 | return [name];}]]))[invoke](node);}; 172 | let eval_nil_destructure_args = function (args) { 173 | args ??= nil;let __coil_temp; 174 | if ((args)[Meta.as_bool]()) { 175 | let __coil_temp; 176 | return dot(dot(dot(args, 'flatMap')[invoke](arg_names), map)[invoke]((name) => { 177 | name ??= nil;; 178 | return str[invoke](resolve_name[invoke](name), " ??= nil;");}), join)[invoke]("\n"); 179 | } else { 180 | let __coil_temp; 181 | return ""; 182 | };}; 183 | let eval_fn_expr = function ({'is_async?': is_async__q, 'generator?': generator__q, 'args': args, 'body': body}) { 184 | is_async__q ??= nil; 185 | generator__q ??= nil; 186 | args ??= nil; 187 | body ??= nil;let __coil_temp; 188 | return str[invoke](((__coil_temp = {left: is_async__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "async ", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), "function ", ((__coil_temp = {left: generator__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "*", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), "(", dot(dot(args, map)[invoke](eval_assign_expr), join)[invoke](", "), ") {\n", eval_this_assignments[invoke](args), eval_nil_destructure_args[invoke](args), eval_ast[invoke](body), "}");}; 189 | let eval_fn = function (node) { 190 | node ??= nil;let __coil_temp; 191 | return str[invoke]((__coil_temp = {left: ((__coil_temp = {left: dot(dot(node, 'name_expr'), 'type')[Meta["=="]](Keyword.for("id_lookup"))}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "let ", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right))}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : ""), eval_name_expr[invoke](dot(node, 'name_expr')), " = ", eval_fn_expr[invoke](node));}; 192 | let eval_obj_fn = function ({'name': name, 'generator?': generator__q, 'is_async?': is_async__q, 'args': args, 'body': body}) { 193 | name ??= nil; 194 | generator__q ??= nil; 195 | is_async__q ??= nil; 196 | args ??= nil; 197 | body ??= nil;let __coil_temp; 198 | return str[invoke](((__coil_temp = {left: is_async__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "async ", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), ((__coil_temp = {left: generator__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "*", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), "['", name, "'](", dot(dot(args, map)[invoke](eval_assign_expr), join)[invoke](", "), ") {\n", eval_nil_destructure_args[invoke](args), ";\n", eval_ast[invoke](body), "\n}");}; 199 | let eval_id_lookup = function ({'name': name}) { 200 | name ??= nil;let __coil_temp; 201 | return resolve_name[invoke](name);}; 202 | let eval_num = function ({'value': value}) { 203 | value ??= nil;let __coil_temp; 204 | return str[invoke]("(", value, ")");}; 205 | let eval_double_equals = function ({'lhs': lhs, 'rhs': rhs}) { 206 | lhs ??= nil; 207 | rhs ??= nil;let __coil_temp; 208 | return str[invoke](eval_expr[invoke](lhs), "[Equal['==']](", eval_expr[invoke](rhs), ")");}; 209 | let eval_not_equals = function ({'lhs': lhs, 'rhs': rhs}) { 210 | lhs ??= nil; 211 | rhs ??= nil;let __coil_temp; 212 | return str[invoke](eval_expr[invoke](lhs), "[Equal['!=']](", eval_expr[invoke](rhs), ")");}; 213 | let eval_not = function ({'expr': expr}) { 214 | expr ??= nil;let __coil_temp; 215 | return str[invoke](eval_expr[invoke](expr), "[Bool.negate]()");}; 216 | let eval_meta_from_entries = function ({'lhs': lhs, 'entries': entries}) { 217 | lhs ??= nil; 218 | entries ??= nil;let __coil_temp; 219 | return str[invoke](eval_expr[invoke](lhs), "[Meta.from_entries]([", dot(dot(entries, map)[invoke](eval_record_entry), join)[invoke](", "), "])");}; 220 | let eval_meta_create = function ({'lhs': lhs, 'entries': entries}) { 221 | lhs ??= nil; 222 | entries ??= nil;let __coil_temp; 223 | return str[invoke](eval_expr[invoke](lhs), "[Meta.create]([", dot(dot(entries, map)[invoke](eval_expr), join)[invoke](", "), "])");}; 224 | let eval_await = function ({'expr': expr}) { 225 | expr ??= nil;let __coil_temp; 226 | return str[invoke]("await ", eval_expr[invoke](expr));}; 227 | let eval_yield = function ({'star?': star__q, 'expr': expr}) { 228 | star__q ??= nil; 229 | expr ??= nil;let __coil_temp; 230 | return str[invoke]("(yield", ((__coil_temp = {left: star__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "*", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), " ", eval_expr[invoke](expr), ")");}; 231 | let eval_dot_yield = function ({'lhs': lhs}) { 232 | lhs ??= nil;let __coil_temp; 233 | return str[invoke]("(yield ", eval_expr[invoke](lhs), ")");}; 234 | let eval_paren_expr = function ({'expr': expr}) { 235 | expr ??= nil;let __coil_temp; 236 | return str[invoke]("(", eval_expr[invoke](expr), ")");}; 237 | let eval_keyword = function ({'value': value}) { 238 | value ??= nil;let __coil_temp; 239 | return str[invoke]("Keyword.for(\"", value, "\")");}; 240 | let eval_regular_record_entry = function ({'key_expr': key_expr, 'value_expr': value_expr}) { 241 | key_expr ??= nil; 242 | value_expr ??= nil;let __coil_temp; 243 | return str[invoke]("[", eval_expr[invoke](key_expr), ", ", eval_expr[invoke](value_expr), "]");}; 244 | let eval_keyword_record_entry = function ({'name': name, 'expr': expr}) { 245 | name ??= nil; 246 | expr ??= nil;let __coil_temp; 247 | return str[invoke]("[", eval_keyword[invoke](ObjectLiteral[Meta.from_entries]([[Keyword.for("value"), name]])), ", ", eval_expr[invoke](expr), "]");}; 248 | let eval_fn_record_entry = function (fn_node) { 249 | fn_node ??= nil;let __coil_temp; 250 | return str[invoke]("[", eval_expr[invoke](dot(fn_node, 'name_expr')), ", ", eval_fn_expr[invoke](fn_node), "]");}; 251 | let eval_id_shorthand_record_entry = function ({'name': name}) { 252 | name ??= nil;let __coil_temp; 253 | return str[invoke]("[", eval_keyword[invoke](ObjectLiteral[Meta.from_entries]([[Keyword.for("value"), name]])), ", ", resolve_name[invoke](name), "]");}; 254 | let eval_record_entry = function (node) { 255 | node ??= nil;let __coil_temp; 256 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("regular_record_entry"), eval_regular_record_entry], [Keyword.for("keyword_record_entry"), eval_keyword_record_entry], [Keyword.for("id_shorthand_record_entry"), eval_id_shorthand_record_entry], [Keyword.for("spread"), eval_spread], [Keyword.for("fn"), eval_fn_record_entry]]))[invoke](node);}; 257 | let eval_inclusive_range = function ({'lhs': lhs, 'rhs': rhs}) { 258 | lhs ??= nil; 259 | rhs ??= nil;let __coil_temp; 260 | if ((rhs)[Meta.as_bool]()) { 261 | let __coil_temp; 262 | return str[invoke]("new InclusiveRange(", eval_expr[invoke](lhs), ", ", eval_expr[invoke](rhs), ")"); 263 | } else { 264 | let __coil_temp; 265 | return str[invoke]("new InclusiveRangeNoMaximum(", eval_expr[invoke](lhs), ")"); 266 | };}; 267 | let eval_exclusive_range = function ({'lhs': lhs, 'rhs': rhs}) { 268 | lhs ??= nil; 269 | rhs ??= nil;let __coil_temp; 270 | if ((rhs)[Meta.as_bool]()) { 271 | let __coil_temp; 272 | return str[invoke]("new ExclusiveRange(", eval_expr[invoke](lhs), ", ", eval_expr[invoke](rhs), ")"); 273 | } else { 274 | let __coil_temp; 275 | return str[invoke]("new ExclusiveRangeNoMaximum(", eval_expr[invoke](lhs), ")"); 276 | };}; 277 | let eval_regex_lit = function ({'value': value}) { 278 | value ??= nil;let __coil_temp; 279 | return value;}; 280 | let eval_prefix_exclusive_range = function ({'expr': expr}) { 281 | expr ??= nil;let __coil_temp; 282 | return str[invoke]("new ExclusiveRangeNoMinimum(", eval_expr[invoke](expr), ")");}; 283 | let eval_prefix_inclusive_range = function ({'expr': expr}) { 284 | expr ??= nil;let __coil_temp; 285 | return str[invoke]("new InclusiveRangeNoMinimum(", eval_expr[invoke](expr), ")");}; 286 | let eval_dot = function ({'lhs': lhs, 'rhs': rhs}) { 287 | lhs ??= nil; 288 | rhs ??= nil;let __coil_temp; 289 | return str[invoke]("dot(", eval_expr[invoke](lhs), ", ", eval_expr[invoke](rhs), ")");}; 290 | let eval_keyword_lookup = function ({'lhs': lhs, 'property': property}) { 291 | lhs ??= nil; 292 | property ??= nil;let __coil_temp; 293 | return str[invoke]("dot(", eval_expr[invoke](lhs), ", '", property, "')");}; 294 | let eval_object_literal = function ({'entries': entries}) { 295 | entries ??= nil;let __coil_temp; 296 | return str[invoke]("ObjectLiteral[Meta.from_entries]([", dot(dot(entries, map)[invoke](eval_record_entry), join)[invoke](", "), "])");}; 297 | let eval_anon_fn_body = function (node) { 298 | node ??= nil;let __coil_temp; 299 | if ((dot(node, 'type')[Meta["=="]](Keyword.for("brace_body")))[Meta.as_bool]()) { 300 | let __coil_temp; 301 | return eval_ast[invoke](dot(node, 'body')); 302 | } else { 303 | let __coil_temp; 304 | return str[invoke]("return ", eval_expr[invoke](node), ";"); 305 | };}; 306 | let eval_anon_fn = function ({'args': args, 'return_node': return_node}) { 307 | args ??= nil; 308 | return_node ??= nil;let __coil_temp; 309 | return str[invoke]("(", dot(dot(args, map)[invoke](eval_assign_expr), join)[invoke](", "), ") => {\n", eval_nil_destructure_args[invoke](args), ";\n", eval_anon_fn_body[invoke](return_node), "}");}; 310 | let eval_anon_gen_fn = function ({'args': args, 'return_node': return_node}) { 311 | args ??= nil; 312 | return_node ??= nil;let __coil_temp; 313 | return str[invoke]("function *(", dot(dot(args, map)[invoke](eval_assign_expr), join)[invoke](", "), ") {\n", eval_nil_destructure_args[invoke](args), ";\n", eval_anon_fn_body[invoke](return_node), "}.bind(this)");}; 314 | let eval_anon_body_fn = function ({'args': args, 'body': body}) { 315 | args ??= nil; 316 | body ??= nil;let __coil_temp; 317 | return str[invoke]("(", dot(dot(args, map)[invoke](eval_assign_expr), join)[invoke](", "), ") => {\n", eval_nil_destructure_args[invoke](args), "\n", eval_ast[invoke](body), "}");}; 318 | let eval_algebra_op = function ({'lhs': lhs, 'op': op, 'rhs': rhs}) { 319 | lhs ??= nil; 320 | op ??= nil; 321 | rhs ??= nil;let __coil_temp; 322 | return str[invoke](eval_expr[invoke](lhs), "[Algebra[\"", op, "\"]](", eval_expr[invoke](rhs), ")");}; 323 | let eval_equality_op = function ({'lhs': lhs, 'op': op, 'rhs': rhs}) { 324 | lhs ??= nil; 325 | op ??= nil; 326 | rhs ??= nil;let __coil_temp; 327 | return str[invoke](eval_expr[invoke](lhs), "[Meta[\"", op, "\"]](", eval_expr[invoke](rhs), ")");}; 328 | let eval_instanceof = function ({'lhs': lhs, 'rhs': rhs}) { 329 | lhs ??= nil; 330 | rhs ??= nil;let __coil_temp; 331 | return str[invoke]("(", eval_expr[invoke](lhs), " instanceof ", eval_expr[invoke](rhs), ")");}; 332 | let eval_and = function ({'lhs': lhs, 'rhs': rhs}) { 333 | lhs ??= nil; 334 | rhs ??= nil;let __coil_temp; 335 | return str[invoke]("(__coil_temp = {left: ", eval_expr[invoke](lhs), "}", ", __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left", " : (__coil_temp.right = ", eval_expr[invoke](rhs), ", __coil_temp.right[Meta.as_bool]() === true) ", " ? __coil_temp.right : __coil_temp.right)");}; 336 | let eval_or = function ({'lhs': lhs, 'rhs': rhs}) { 337 | lhs ??= nil; 338 | rhs ??= nil;let __coil_temp; 339 | return str[invoke]("(__coil_temp = {left: ", eval_expr[invoke](lhs), "}", ", __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : ", eval_expr[invoke](rhs), ")");}; 340 | let eval_unapplied_algebra_op = function ({'op': op}) { 341 | op ??= nil;let __coil_temp; 342 | return str[invoke]("Algebra['", op, "']");}; 343 | let eval_unapplied_equality_op = function ({'op': op}) { 344 | op ??= nil;let __coil_temp; 345 | return str[invoke]("Meta['", op, "']");}; 346 | let eval_snd_assign = function ({'lhs': lhs, 'rhs': rhs}) { 347 | lhs ??= nil; 348 | rhs ??= nil;let __coil_temp; 349 | return str[invoke](eval_name_expr[invoke](lhs), " = ", eval_expr[invoke](rhs));}; 350 | let eval_expr = function (node) { 351 | node ??= nil;let __coil_temp; 352 | return dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("algebra_op"), eval_algebra_op], [Keyword.for("unapplied_algebra_op"), eval_unapplied_algebra_op], [Keyword.for("unapplied_equality_op"), eval_unapplied_equality_op], [Keyword.for("equality_op"), eval_equality_op], [Keyword.for("and"), eval_and], [Keyword.for("or"), eval_or], [Keyword.for("instanceof"), eval_instanceof], [Keyword.for("str"), eval_str], [Keyword.for("dot"), eval_dot], [Keyword.for("snd_assign"), eval_snd_assign], [Keyword.for("keyword_lookup"), eval_keyword_lookup], [Keyword.for("object_literal"), eval_object_literal], [Keyword.for("regex_lit"), eval_regex_lit], [Keyword.for("keyword"), eval_keyword], [Keyword.for("prefix_exclusive_range"), eval_prefix_exclusive_range], [Keyword.for("prefix_inclusive_range"), eval_prefix_inclusive_range], [Keyword.for("id_lookup"), eval_id_lookup], [Keyword.for("fn_call"), eval_fn_call], [Keyword.for("num"), eval_num], [Keyword.for("array"), eval_array], [Keyword.for("double_equals"), eval_double_equals], [Keyword.for("not_equals"), eval_not_equals], [Keyword.for("not"), eval_not], [Keyword.for("fn"), eval_fn], [Keyword.for("meta_from_entries"), eval_meta_from_entries], [Keyword.for("meta_create"), eval_meta_create], [Keyword.for("spread"), eval_spread], [Keyword.for("await"), eval_await], [Keyword.for("yield"), eval_yield], [Keyword.for("dot_yield"), eval_dot_yield], [Keyword.for("paren_expr"), eval_paren_expr], [Keyword.for("inclusive_range"), eval_inclusive_range], [Keyword.for("exclusive_range"), eval_exclusive_range], [Keyword.for("anon_fn"), eval_anon_fn], [Keyword.for("anon_gen_fn"), eval_anon_gen_fn], [Keyword.for("anon_body_fn"), eval_anon_body_fn]]))[invoke](node);}; 353 | let eval_return = function ({'expr': expr}) { 354 | expr ??= nil;let __coil_temp; 355 | if ((expr)[Meta.as_bool]()) { 356 | let __coil_temp; 357 | return str[invoke]("return ", eval_expr[invoke](expr)); 358 | } else { 359 | let __coil_temp; 360 | return "return"; 361 | };}; 362 | let eval_protocol = function ({'name': name, 'methods': methods}) { 363 | name ??= nil; 364 | methods ??= nil;let __coil_temp; 365 | if ((methods)[Meta.as_bool]()) { 366 | let __coil_temp; 367 | return str[invoke]("const ", name, " = Object.freeze({", dot(dot(dot(methods, 'names'), map)[invoke]((method) => { 368 | method ??= nil;; 369 | return str[invoke]("\"", dot(method, 'name'), "\": Symbol(\"", name, ":", dot(method, 'name'), "\")");}), join)[invoke](",\n"), "})"); 370 | } else { 371 | let __coil_temp; 372 | return str[invoke]("const ", resolve_name[invoke](name), " = Symbol(\"", name, "\")"); 373 | };}; 374 | let eval_for_loop = function ({'is_await?': is_await__q, 'assign_expr': assign_expr, 'iterable_expr': iterable_expr, 'body': body}) { 375 | is_await__q ??= nil; 376 | assign_expr ??= nil; 377 | iterable_expr ??= nil; 378 | body ??= nil;let __coil_temp; 379 | return str[invoke]("for ", ((__coil_temp = {left: is_await__q}, __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left : (__coil_temp.right = "await ", __coil_temp.right[Meta.as_bool]() === true) ? __coil_temp.right : __coil_temp.right)), " (let ", eval_assign_expr[invoke](assign_expr), " of ", eval_expr[invoke](iterable_expr), ") {\n", eval_nil_destructure_args[invoke]([assign_expr]), ";\n", eval_ast[invoke](body), "\n", "}");}; 380 | let eval_id_assign = function ({'name': name, 'expr': expr}) { 381 | name ??= nil; 382 | expr ??= nil;let __coil_temp; 383 | return str[invoke](resolve_name[invoke](name), " = ", eval_expr[invoke](expr));}; 384 | let eval_while_loop = function ({'test_expr': test_expr, 'body': body}) { 385 | test_expr ??= nil; 386 | body ??= nil;let __coil_temp; 387 | return str[invoke]("while ((", eval_expr[invoke](test_expr), ")[Meta.as_bool]()) {\n", eval_ast[invoke](body), "\n}");}; 388 | let eval_loop = function ({'body': body}) { 389 | body ??= nil;let __coil_temp; 390 | return str[invoke]("while (true) {\n", eval_ast[invoke](body), "\n}");}; 391 | let eval_continue = function () { 392 | let __coil_temp; 393 | return "continue";}; 394 | let eval_break = function () { 395 | let __coil_temp; 396 | return "break";}; 397 | let get_deconstructed_obj_entry_name = function (node) { 398 | node ??= nil;let __coil_temp; 399 | return dot(dot(Map[Meta.from_entries]([[Keyword.for("obj_reg_entry"), Keyword.for("name")], [Keyword.for("obj_entry_rename"), Keyword.for("old_name")]]), at)[invoke](dot(node, at)[invoke](Keyword.for("type"))), pipe)[invoke](node);}; 400 | let get_deconstructed_array_entry_name = function (node) { 401 | node ??= nil;let __coil_temp; 402 | return dot(dot(Map[Meta.from_entries]([[Keyword.for("id_assign"), Keyword.for("name")]]), at)[invoke](dot(node, at)[invoke](Keyword.for("type"))), pipe)[invoke](node);}; 403 | let eval_import_deconstruction_entry = function (node) { 404 | node ??= nil;let __coil_temp; 405 | return dot(node, pipe)[invoke](Keyword.for("type"), Map[Meta.from_entries]([[Keyword.for("obj_reg_entry"), function ({'name': name}) { 406 | name ??= nil;let __coil_temp; 407 | return resolve_name[invoke](name);}], [Keyword.for("obj_entry_rename"), function ({'old_name': old_name, 'new_name': new_name}) { 408 | old_name ??= nil; 409 | new_name ??= nil;let __coil_temp; 410 | return str[invoke](resolve_name[invoke](old_name), " as ", resolve_name[invoke](new_name));}]]))[invoke](node);}; 411 | let eval_import_deconstruction_expr = function ({'entries': entries}) { 412 | entries ??= nil;let __coil_temp; 413 | return str[invoke]("{", dot(dot(entries, map)[invoke](eval_import_deconstruction_entry), join)[invoke](", "), "}");}; 414 | let eval_import_assign_exprs = function (node) { 415 | node ??= nil;let __coil_temp; 416 | return dot(node, pipe)[invoke](Keyword.for("type"), Map[Meta.from_entries]([[Keyword.for("id_assign"), eval_id_assign_name], [Keyword.for("object_deconstruction"), eval_import_deconstruction_expr], [Keyword.for("assign_all_as"), eval_assign_all_as]]))[invoke](node);}; 417 | let eval_import = function ({'assign_expr': assign_expr, 'path': path}) { 418 | assign_expr ??= nil; 419 | path ??= nil;let __coil_temp; 420 | return str[invoke]("import ", eval_import_assign_exprs[invoke](assign_expr), " from \"", dot(dot(path, 'value'), 'slice')[invoke]((1), (-1)), "\"");}; 421 | let eval_export = function ({'statement': statement}) { 422 | statement ??= nil;let __coil_temp; 423 | return str[invoke]("export ", eval_statement[invoke](statement));}; 424 | let eval_export_default = function ({'expr': expr}) { 425 | expr ??= nil;let __coil_temp; 426 | return str[invoke]("export default ", eval_expr[invoke](expr));}; 427 | let eval_direct_import = function ({'path': path}) { 428 | path ??= nil;let __coil_temp; 429 | return str[invoke]("import ", path);}; 430 | let eval_statement = function (node) { 431 | node ??= nil;let __coil_temp; 432 | let eval_fn = dot(dot(node, at)[invoke](Keyword.for("type")), pipe)[invoke](Map[Meta.from_entries]([[Keyword.for("if"), eval_if], [Keyword.for("direct_import"), eval_direct_import], [Keyword.for("import"), eval_import], [Keyword.for("export"), eval_export], [Keyword.for("export_default"), eval_export_default], [Keyword.for("let"), eval_let], [Keyword.for("if_let"), eval_if_let], [Keyword.for("return"), eval_return], [Keyword.for("protocol_def"), eval_protocol], [Keyword.for("for_loop"), eval_for_loop], [Keyword.for("id_assign"), eval_id_assign], [Keyword.for("while_loop"), eval_while_loop], [Keyword.for("loop"), eval_loop], [Keyword.for("while_let_loop"), eval_while_let_loop], [Keyword.for("continue"), eval_continue], [Keyword.for("break"), eval_break]])); 433 | eval_fn ??= nil;; 434 | return ((__coil_temp = {left: eval_fn}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : eval_expr))[invoke](node)[Algebra["+"]](";");}; 435 | let eval_ast = function (ast) { 436 | ast ??= nil;let __coil_temp; 437 | return str[invoke]("let __coil_temp;\n", dot(dot(ast, map)[invoke](eval_statement), join)[invoke]("\n"));}; 438 | export default eval_ast; 439 | -------------------------------------------------------------------------------- /compiler/dist/parse_error.mjs: -------------------------------------------------------------------------------- 1 | export class ParseError extends Error { 2 | constructor(expected_token_type, { type, line, col }) { 3 | super(`Expected: ${expected_token_type} got ${type} @ ${line}:${col}`); 4 | this.stack = new Error().stack; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /compiler/dist/parser.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | import {ParseError} from "./parse_error.mjs"; 14 | let expect_token__b = function (tokens, kw) { 15 | tokens ??= nil; 16 | kw ??= nil;let __coil_temp; 17 | if ((dot(dot(tokens, first)[invoke](), at)[invoke](Keyword.for("type"))[Meta["!="]](kw))[Meta.as_bool]()) { 18 | let __coil_temp; 19 | raise__b[invoke](ParseError[Meta.create]([kw, dot(tokens, first)[invoke]()])); 20 | } else { 21 | let __coil_temp; 22 | return tokens; 23 | };}; 24 | let verify_exists__b = function (expr, parser) { 25 | expr ??= nil; 26 | parser ??= nil;let __coil_temp; 27 | if ((dot(expr, nil__q)[invoke]())[Meta.as_bool]()) { 28 | let __coil_temp; 29 | dot(parser, log)[invoke](); 30 | panic__b[invoke]("Parser Failed"); 31 | } else { 32 | let __coil_temp; 33 | return expr; 34 | };}; 35 | const parse = Symbol("parse"); 36 | let line_and_col = function ({'line': line, 'col': col}) { 37 | line ??= nil; 38 | col ??= nil;let __coil_temp; 39 | return ObjectLiteral[Meta.from_entries]([[Keyword.for("line"), line], [Keyword.for("col"), col]]);}; 40 | let Init = function (expr) { 41 | this['expr'] = expr; 42 | expr ??= nil;let __coil_temp; 43 | }; 44 | Init['prototype'][parse] = function ([_expr, tokens]) { 45 | _expr ??= nil; 46 | tokens ??= nil;let __coil_temp; 47 | return [ObjectLiteral[Meta.from_entries]([...dot(this, 'expr'), [Keyword.for("pos"), line_and_col[invoke](dot(tokens, first)[invoke]())]]), tokens];}; 48 | let One = function (kw, as) { 49 | this['kw'] = kw; 50 | this['as'] = as; 51 | kw ??= nil; 52 | as ??= nil;let __coil_temp; 53 | }; 54 | One['prototype'][parse] = function ([expr, tokens]) { 55 | expr ??= nil; 56 | tokens ??= nil;let __coil_temp; 57 | let {'value': value, 'type': type} = dot(expect_token__b[invoke](tokens, dot(this, 'kw')), first)[invoke](); 58 | value ??= nil; 59 | type ??= nil;; 60 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'as'), value]]), dot(tokens, 'slice')[invoke]((1))];}; 61 | const can_parse__q = Symbol("can_parse?"); 62 | Keyword['prototype'][can_parse__q] = function ([{'type': type}]) { 63 | type ??= nil;let __coil_temp; 64 | return this[Meta["=="]](type);}; 65 | Set['prototype'][can_parse__q] = function (tokens) { 66 | tokens ??= nil;let __coil_temp; 67 | return dot(this, any__q)[invoke]((cond) => { 68 | cond ??= nil;; 69 | return dot(cond, can_parse__q)[invoke](tokens);});}; 70 | _[can_parse__q] = function ([]) { 71 | let __coil_temp; 72 | return true;}; 73 | Array['prototype'][can_parse__q] = function (tokens) { 74 | tokens ??= nil;let __coil_temp; 75 | if ((dot(this, len)[invoke]()[Algebra[">"]](dot(tokens, len)[invoke]()))[Meta.as_bool]()) { 76 | let __coil_temp; 77 | return false; 78 | } else { 79 | let __coil_temp; 80 | return dot(dot(this, zip)[invoke](tokens), all__q)[invoke](([pattern, token]) => { 81 | pattern ??= nil; 82 | token ??= nil;; 83 | return dot(pattern, can_parse__q)[invoke]([token]);}); 84 | };}; 85 | let Optional = function (parse_cond, parse_fn, as) { 86 | this['parse_cond'] = parse_cond; 87 | this['parse_fn'] = parse_fn; 88 | this['as'] = as; 89 | parse_cond ??= nil; 90 | parse_fn ??= nil; 91 | as ??= nil;let __coil_temp; 92 | }; 93 | Optional['prototype'][parse] = function ([expr, tokens]) { 94 | expr ??= nil; 95 | tokens ??= nil;let __coil_temp; 96 | if ((dot(tokens, empty__q)[invoke]())[Meta.as_bool]()) { 97 | let __coil_temp; 98 | return [expr, tokens]; 99 | } else if ((dot(dot(this, 'parse_cond'), can_parse__q)[invoke](tokens))[Meta.as_bool]()) { 100 | let __coil_temp; 101 | return dot(Then[Meta.create]([dot(this, 'parse_fn'), dot(this, 'as')]), parse)[invoke]([expr, tokens]); 102 | } else { 103 | let __coil_temp; 104 | return [expr, tokens]; 105 | };}; 106 | Function['prototype'][parse] = function ([_expr, tokens]) { 107 | _expr ??= nil; 108 | tokens ??= nil;let __coil_temp; 109 | return this[invoke](tokens);}; 110 | let Chomp = function (...kws) { 111 | this['kws'] = kws; 112 | kws ??= nil;let __coil_temp; 113 | }; 114 | Chomp['prototype'][parse] = function ([expr, tokens]) { 115 | expr ??= nil; 116 | tokens ??= nil;let __coil_temp; 117 | let i = (0); 118 | i ??= nil;; 119 | for (let kw of dot(this, 'kws')) { 120 | kw ??= nil;; 121 | let __coil_temp; 122 | expect_token__b[invoke](dot(tokens, 'slice')[invoke](i), kw); 123 | i = i[Algebra["+"]]((1)); 124 | }; 125 | return [expr, dot(tokens, 'slice')[invoke](i)];}; 126 | let Then = function (parser, kw) { 127 | this['parser'] = parser; 128 | this['kw'] = kw; 129 | parser ??= nil; 130 | kw ??= nil;let __coil_temp; 131 | }; 132 | Then['prototype'][parse] = function ([expr, tokens]) { 133 | expr ??= nil; 134 | tokens ??= nil;let __coil_temp; 135 | var __coil_if_let_temp = dot(this, 'parser')[invoke](tokens) ?? nil; 136 | if (__coil_if_let_temp[Meta.as_bool]()) { 137 | let [new_expr, new_tokens] = __coil_if_let_temp; 138 | new_expr ??= nil; 139 | new_tokens ??= nil;; 140 | let __coil_temp; 141 | if ((dot(this, 'kw'))[Meta.as_bool]()) { 142 | let __coil_temp; 143 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'kw'), new_expr]]), new_tokens]; 144 | } else { 145 | let __coil_temp; 146 | return [new_expr, new_tokens]; 147 | }; 148 | } else { 149 | let __coil_temp; 150 | return [expr, tokens]; 151 | };}; 152 | let FMap = function (f) { 153 | this['f'] = f; 154 | f ??= nil;let __coil_temp; 155 | }; 156 | FMap['prototype'][parse] = function ([expr, tokens]) { 157 | expr ??= nil; 158 | tokens ??= nil;let __coil_temp; 159 | return [dot(this, 'f')[invoke](expr), tokens];}; 160 | let Until = function (end_kw, parser, kw) { 161 | this['end_kw'] = end_kw; 162 | this['parser'] = parser; 163 | this['kw'] = kw; 164 | end_kw ??= nil; 165 | parser ??= nil; 166 | kw ??= nil;let __coil_temp; 167 | }; 168 | Until['prototype'][parse] = function ([expr, tokens]) { 169 | expr ??= nil; 170 | tokens ??= nil;let __coil_temp; 171 | let exprs = []; 172 | exprs ??= nil;; 173 | while ((dot(dot(tokens, first)[invoke](), at)[invoke](Keyword.for("type"))[Meta["!="]](dot(this, 'end_kw')))[Meta.as_bool]()) { 174 | let __coil_temp; 175 | let [expr, new_tokens] = verify_exists__b[invoke](dot(this, 'parser')[invoke](tokens), this); 176 | expr ??= nil; 177 | new_tokens ??= nil;; 178 | dot(exprs, 'push')[invoke](expr); 179 | tokens = new_tokens; 180 | }; 181 | if ((dot(this, 'kw'))[Meta.as_bool]()) { 182 | let __coil_temp; 183 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'kw'), exprs]]), tokens]; 184 | } else { 185 | let __coil_temp; 186 | return [exprs, tokens]; 187 | };}; 188 | let UntilEither = function (set, parser, kw) { 189 | this['set'] = set; 190 | this['parser'] = parser; 191 | this['kw'] = kw; 192 | set ??= nil; 193 | parser ??= nil; 194 | kw ??= nil;let __coil_temp; 195 | }; 196 | UntilEither['prototype'][parse] = function ([expr, tokens]) { 197 | expr ??= nil; 198 | tokens ??= nil;let __coil_temp; 199 | let exprs = []; 200 | exprs ??= nil;; 201 | while ((dot(dot(dot(tokens, first)[invoke](), at)[invoke](Keyword.for("type")), pipe)[invoke](dot(this, 'set'))[Bool.negate]())[Meta.as_bool]()) { 202 | let __coil_temp; 203 | let [expr, new_tokens] = verify_exists__b[invoke](dot(this, 'parser')[invoke](tokens), this); 204 | expr ??= nil; 205 | new_tokens ??= nil;; 206 | dot(exprs, 'push')[invoke](expr); 207 | tokens = new_tokens; 208 | }; 209 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'kw'), exprs]]), tokens];}; 210 | let Case = function (parse_map, kw) { 211 | this['parse_map'] = parse_map; 212 | this['kw'] = kw; 213 | parse_map ??= nil; 214 | kw ??= nil;let __coil_temp; 215 | }; 216 | Case['prototype'][parse] = function ([expr, tokens]) { 217 | expr ??= nil; 218 | tokens ??= nil;let __coil_temp; 219 | var __coil_if_let_temp = dot(this, 'parse_map')[invoke](tokens) ?? nil; 220 | if (__coil_if_let_temp[Meta.as_bool]()) { 221 | let [new_expr, new_tokens] = __coil_if_let_temp; 222 | new_expr ??= nil; 223 | new_tokens ??= nil;; 224 | let __coil_temp; 225 | if ((dot(this, 'kw'))[Meta.as_bool]()) { 226 | let __coil_temp; 227 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'kw'), new_expr]]), new_tokens]; 228 | } else { 229 | let __coil_temp; 230 | return [new_expr, new_tokens]; 231 | }; 232 | } else { 233 | let __coil_temp; 234 | dot(console, log)[invoke](dot(dot(this, 'tokens'), first)[invoke](), dot(this, 'parse_map')); 235 | panic__b[invoke]("Case Parse Failed"); 236 | };}; 237 | let Either = function (set, kw) { 238 | this['set'] = set; 239 | this['kw'] = kw; 240 | set ??= nil; 241 | kw ??= nil;let __coil_temp; 242 | }; 243 | Either['prototype'][parse] = function ([expr, tokens]) { 244 | expr ??= nil; 245 | tokens ??= nil;let __coil_temp; 246 | let op = verify_exists__b[invoke](dot(this, 'set')[invoke](dot(dot(tokens, first)[invoke](), at)[invoke](Keyword.for("type"))), dot(this, 'set')); 247 | op ??= nil;; 248 | let [new_expr, rest] = [dot(tokens, first)[invoke](), dot(tokens, 'slice')[invoke]((1))]; 249 | new_expr ??= nil; 250 | rest ??= nil;; 251 | return [ObjectLiteral[Meta.from_entries]([...expr, [dot(this, 'kw'), dot(new_expr, at)[invoke](Keyword.for("value"))]]), rest];}; 252 | let Parser = function (...instructions) { 253 | this['instructions'] = instructions; 254 | instructions ??= nil;let __coil_temp; 255 | }; 256 | Parser['prototype'][invoke] = function (tokens) { 257 | tokens ??= nil;let __coil_temp; 258 | return dot(this, parse)[invoke]([nil, tokens]);}; 259 | let AbortIf = function (cond_fn) { 260 | this['cond_fn'] = cond_fn; 261 | cond_fn ??= nil;let __coil_temp; 262 | }; 263 | Parser['prototype'][parse] = function (result) { 264 | result ??= nil;let __coil_temp; 265 | for (let instruction of dot(this, 'instructions')) { 266 | instruction ??= nil;; 267 | let __coil_temp; 268 | if (((instruction instanceof AbortIf))[Meta.as_bool]()) { 269 | let __coil_temp; 270 | if ((dot(instruction, 'cond_fn')[invoke](result))[Meta.as_bool]()) { 271 | let __coil_temp; 272 | return; 273 | } else { 274 | let __coil_temp; 275 | continue; 276 | }; 277 | }; 278 | result = dot(instruction, parse)[invoke](result); 279 | }; 280 | return result;}; 281 | let ParseMap = function (entries) { 282 | this['entries'] = entries; 283 | entries ??= nil;let __coil_temp; 284 | }; 285 | ParseMap['prototype'][(dot(Record, 'keys'))] = function () { 286 | let __coil_temp; 287 | return dot(dot(dot(this, 'entries'), map)[invoke](([pattern, _ignore_me_]) => { 288 | pattern ??= nil; 289 | _ ??= nil;; 290 | return pattern;}), into)[invoke](Set[Meta.create]([]));}; 291 | ParseMap['prototype'][invoke] = function (tokens, ...args) { 292 | tokens ??= nil; 293 | args ??= nil;let __coil_temp; 294 | if ((dot(tokens, empty__q)[invoke]())[Meta.as_bool]()) { 295 | let __coil_temp; 296 | return; 297 | } else { 298 | let __coil_temp; 299 | for (let [pattern, parser] of dot(this, 'entries')) { 300 | pattern ??= nil; 301 | parser ??= nil;; 302 | let __coil_temp; 303 | if ((dot(pattern, can_parse__q)[invoke](tokens))[Meta.as_bool]()) { 304 | let __coil_temp; 305 | return parser[invoke](tokens, ...args); 306 | }; 307 | }; 308 | };}; 309 | let algebra_ops = Set[Meta.create]([Keyword.for("mod"), Keyword.for("plus"), Keyword.for("minus"), Keyword.for("times"), Keyword.for("pow"), Keyword.for("div"), Keyword.for("lt"), Keyword.for("gt"), Keyword.for("lt_eq"), Keyword.for("gt_eq")]); 310 | algebra_ops ??= nil;; 311 | let parse_dot = function (tokens, lhs) { 312 | tokens ??= nil; 313 | lhs ??= nil;let __coil_temp; 314 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("dot")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("dot")]), Then[Meta.create]([parse_single_expr, Keyword.for("rhs")])])[invoke](tokens);}; 315 | let parse_keyword_lookup = function (tokens, lhs) { 316 | tokens ??= nil; 317 | lhs ??= nil;let __coil_temp; 318 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("keyword_lookup")], [Keyword.for("lhs"), lhs]])]), One[Meta.create]([Keyword.for("keyword"), Keyword.for("property")]), FMap[Meta.create]([({'lhs': lhs, 'type': type, 'property': property, 'pos': pos}) => { 319 | lhs ??= nil; 320 | type ??= nil; 321 | property ??= nil; 322 | pos ??= nil;; 323 | return (ObjectLiteral[Meta.from_entries]([[Keyword.for("lhs"), lhs], [Keyword.for("type"), type], [Keyword.for("property"), dot(property, 'slice')[invoke]((1))], [Keyword.for("pos"), pos]]));}])])[invoke](tokens);}; 324 | let not_adjacent__q = function ([_expr, tokens]) { 325 | _expr ??= nil; 326 | tokens ??= nil;let __coil_temp; 327 | let current = dot(tokens, first)[invoke](); 328 | current ??= nil;; 329 | let previous = dot(tokens, at)[invoke]((-1)); 330 | previous ??= nil;; 331 | if ((dot(current, 'line')[Meta["!="]](dot(previous, 'line')))[Meta.as_bool]()) { 332 | let __coil_temp; 333 | return true; 334 | } else { 335 | let __coil_temp; 336 | let end_of_prev_token = dot(previous, 'col')[Algebra["+"]](dot(dot(previous, 'value'), 'length')); 337 | end_of_prev_token ??= nil;; 338 | return (dot(current, 'col')[Algebra["-"]](end_of_prev_token))[Algebra[">="]]((1)); 339 | };}; 340 | let parse_adjacent_expr = function (tokens) { 341 | tokens ??= nil;let __coil_temp; 342 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Then[Meta.create]([parse_expr])])[invoke](tokens);}; 343 | let parse_inclusive_range = function (tokens, lhs) { 344 | tokens ??= nil; 345 | lhs ??= nil;let __coil_temp; 346 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("inclusive_range")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("dot_dot"), Keyword.for("eq")]), Optional[Meta.create]([dot(SINGLE_EXPR_PARSE_MAP, keys)[invoke](), parse_adjacent_expr, Keyword.for("rhs")])])[invoke](tokens);}; 347 | let parse_exclusive_range = function (tokens, lhs) { 348 | tokens ??= nil; 349 | lhs ??= nil;let __coil_temp; 350 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("exclusive_range")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("dot_dot")]), Optional[Meta.create]([dot(SINGLE_EXPR_PARSE_MAP, keys)[invoke](), parse_adjacent_expr, Keyword.for("rhs")])])[invoke](tokens);}; 351 | let parse_fn_call = function (tokens, lhs) { 352 | tokens ??= nil; 353 | lhs ??= nil;let __coil_temp; 354 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("fn_call")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("open_p")]), Until[Meta.create]([Keyword.for("close_p"), parse_expr, Keyword.for("args")]), Chomp[Meta.create]([Keyword.for("close_p")])])[invoke](tokens);}; 355 | let parse_meta_from_entries = function (tokens, lhs) { 356 | tokens ??= nil; 357 | lhs ??= nil;let __coil_temp; 358 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("meta_from_entries")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("open_b")]), Until[Meta.create]([Keyword.for("close_b"), parse_record_entry, Keyword.for("entries")]), Chomp[Meta.create]([Keyword.for("close_b")])])[invoke](tokens, lhs);}; 359 | let parse_meta_create = function (tokens, lhs) { 360 | tokens ??= nil; 361 | lhs ??= nil;let __coil_temp; 362 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("meta_create")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("open_sq")]), Until[Meta.create]([Keyword.for("close_sq"), parse_expr, Keyword.for("entries")]), Chomp[Meta.create]([Keyword.for("close_sq")])])[invoke](tokens, lhs);}; 363 | let parse_snd_assign = function (tokens, lhs) { 364 | tokens ??= nil; 365 | lhs ??= nil;let __coil_temp; 366 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("snd_assign")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("rhs")])])[invoke](tokens);}; 367 | let parse_dot_yield = function (tokens, lhs) { 368 | tokens ??= nil; 369 | lhs ??= nil;let __coil_temp; 370 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("dot_yield")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("dot"), Keyword.for("yield")])])[invoke](tokens);}; 371 | let PARSE_SND_EXPR_STEP_MAP = ParseMap[Meta.from_entries]([[Keyword.for("open_p"), parse_fn_call], [Keyword.for("open_b"), parse_meta_from_entries], [Keyword.for("open_sq"), parse_meta_create], [Keyword.for("keyword"), parse_keyword_lookup], [[Keyword.for("dot"), Keyword.for("yield")], parse_dot_yield], [Keyword.for("dot"), parse_dot], [[Keyword.for("dot_dot"), Keyword.for("eq")], parse_inclusive_range], [Keyword.for("dot_dot"), parse_exclusive_range]]); 372 | PARSE_SND_EXPR_STEP_MAP ??= nil;; 373 | let parse_snd_expr_step = function (tokens, lhs) { 374 | tokens ??= nil; 375 | lhs ??= nil;let __coil_temp; 376 | return PARSE_SND_EXPR_STEP_MAP[invoke](tokens, lhs);}; 377 | let parse_snd_expr = function ([lhs, tokens]) { 378 | lhs ??= nil; 379 | tokens ??= nil;let __coil_temp; 380 | var __coil_while_let_temp = parse_snd_expr_step[invoke](tokens, lhs) ?? nil; 381 | while (__coil_while_let_temp[Meta.as_bool]()) { 382 | let [new_lhs, rest] = __coil_while_let_temp; 383 | new_lhs ??= nil; 384 | rest ??= nil;; 385 | let __coil_temp; 386 | lhs = new_lhs; 387 | tokens = rest; 388 | __coil_while_let_temp = parse_snd_expr_step[invoke](tokens, lhs) ?? nil; 389 | }; 390 | return [lhs, tokens];}; 391 | let parse_algebra_op = function (tokens, lhs) { 392 | tokens ??= nil; 393 | lhs ??= nil;let __coil_temp; 394 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("algebra_op")], [Keyword.for("lhs"), lhs]])]), Either[Meta.create]([algebra_ops, Keyword.for("op")]), Then[Meta.create]([parse_1_2_expr, Keyword.for("rhs")])])[invoke](tokens);}; 395 | let parse_instanceof = function (tokens, lhs) { 396 | tokens ??= nil; 397 | lhs ??= nil;let __coil_temp; 398 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("instanceof")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("instanceof")]), Then[Meta.create]([parse_1_2_expr, Keyword.for("rhs")])])[invoke](tokens);}; 399 | let parse_third_expr_step = function (tokens, lhs) { 400 | tokens ??= nil; 401 | lhs ??= nil;let __coil_temp; 402 | return ParseMap[Meta.from_entries]([[Keyword.for("eq"), parse_snd_assign], [Keyword.for("instanceof"), parse_instanceof], [algebra_ops, parse_algebra_op]])[invoke](tokens, lhs);}; 403 | let parse_third_expr = function ([lhs, tokens]) { 404 | lhs ??= nil; 405 | tokens ??= nil;let __coil_temp; 406 | var __coil_while_let_temp = parse_third_expr_step[invoke](tokens, lhs) ?? nil; 407 | while (__coil_while_let_temp[Meta.as_bool]()) { 408 | let [new_lhs, rest] = __coil_while_let_temp; 409 | new_lhs ??= nil; 410 | rest ??= nil;; 411 | let __coil_temp; 412 | lhs = new_lhs; 413 | tokens = rest; 414 | __coil_while_let_temp = parse_third_expr_step[invoke](tokens, lhs) ?? nil; 415 | }; 416 | return [lhs, tokens];}; 417 | let equality_ops = Set[Meta.create]([Keyword.for("double_eq"), Keyword.for("not_eq")]); 418 | equality_ops ??= nil;; 419 | let parse_eq_op = function (tokens, lhs) { 420 | tokens ??= nil; 421 | lhs ??= nil;let __coil_temp; 422 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("equality_op")], [Keyword.for("lhs"), lhs]])]), Either[Meta.create]([equality_ops, Keyword.for("op")]), Then[Meta.create]([parse_1_2_3_expr, Keyword.for("rhs")])])[invoke](tokens);}; 423 | let parse_fourth_expr_step = function (tokens, lhs) { 424 | tokens ??= nil; 425 | lhs ??= nil;let __coil_temp; 426 | return ParseMap[Meta.from_entries]([[equality_ops, parse_eq_op]])[invoke](tokens, lhs);}; 427 | let parse_fourth_expr = function ([lhs, tokens]) { 428 | lhs ??= nil; 429 | tokens ??= nil;let __coil_temp; 430 | var __coil_while_let_temp = parse_fourth_expr_step[invoke](tokens, lhs) ?? nil; 431 | while (__coil_while_let_temp[Meta.as_bool]()) { 432 | let [new_lhs, rest] = __coil_while_let_temp; 433 | new_lhs ??= nil; 434 | rest ??= nil;; 435 | let __coil_temp; 436 | lhs = new_lhs; 437 | tokens = rest; 438 | __coil_while_let_temp = parse_fourth_expr_step[invoke](tokens, lhs) ?? nil; 439 | }; 440 | return [lhs, tokens];}; 441 | let parse_and = function (tokens, lhs) { 442 | tokens ??= nil; 443 | lhs ??= nil;let __coil_temp; 444 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("and")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("and")]), Then[Meta.create]([parse_1_2_3_4_expr, Keyword.for("rhs")])])[invoke](tokens);}; 445 | let parse_or = function (tokens, lhs) { 446 | tokens ??= nil; 447 | lhs ??= nil;let __coil_temp; 448 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("or")], [Keyword.for("lhs"), lhs]])]), Chomp[Meta.create]([Keyword.for("or")]), Then[Meta.create]([parse_1_2_3_4_expr, Keyword.for("rhs")])])[invoke](tokens);}; 449 | let parse_fifth_expr_step = function (tokens, lhs) { 450 | tokens ??= nil; 451 | lhs ??= nil;let __coil_temp; 452 | return ParseMap[Meta.from_entries]([[Keyword.for("and"), parse_and], [Keyword.for("or"), parse_or]])[invoke](tokens, lhs);}; 453 | let parse_fifth_expr = function ([lhs, tokens]) { 454 | lhs ??= nil; 455 | tokens ??= nil;let __coil_temp; 456 | var __coil_while_let_temp = parse_fifth_expr_step[invoke](tokens, lhs) ?? nil; 457 | while (__coil_while_let_temp[Meta.as_bool]()) { 458 | let [new_lhs, rest] = __coil_while_let_temp; 459 | new_lhs ??= nil; 460 | rest ??= nil;; 461 | let __coil_temp; 462 | lhs = new_lhs; 463 | tokens = rest; 464 | __coil_while_let_temp = parse_fifth_expr_step[invoke](tokens, lhs) ?? nil; 465 | }; 466 | return [lhs, tokens];}; 467 | let parse_regex = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("regex_lit")]])]), One[Meta.create]([Keyword.for("regex_lit"), Keyword.for("value")])]); 468 | parse_regex ??= nil;; 469 | let parse_str = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("str")]])]), One[Meta.create]([Keyword.for("string_lit"), Keyword.for("value")])]); 470 | parse_str ??= nil;; 471 | let valid_ids_in_all_contexts = Set[Meta.create]([Keyword.for("id"), Keyword.for("from")]); 472 | valid_ids_in_all_contexts ??= nil;; 473 | let parse_id = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("id_lookup")]])]), Either[Meta.create]([Set[Meta.create]([...valid_ids_in_all_contexts, Keyword.for("import")]), Keyword.for("name")])]); 474 | parse_id ??= nil;; 475 | let parse_obj = function (tokens) { 476 | tokens ??= nil;let __coil_temp; 477 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("object_literal")]])]), Chomp[Meta.create]([Keyword.for("open_b")]), Until[Meta.create]([Keyword.for("close_b"), parse_record_entry, Keyword.for("entries")]), Chomp[Meta.create]([Keyword.for("close_b")])])[invoke](tokens);}; 478 | let parse_spread_assign = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("spread_assign")]])]), Chomp[Meta.create]([Keyword.for("dot_dot_dot")]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("name")])]); 479 | parse_spread_assign ??= nil;; 480 | let parse_assign_id = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("id_assign")]])]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("name")])]); 481 | parse_assign_id ??= nil;; 482 | let parse_assign_array = function (tokens) { 483 | tokens ??= nil;let __coil_temp; 484 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("array_deconstruction")]])]), Chomp[Meta.create]([Keyword.for("open_sq")]), Until[Meta.create]([Keyword.for("close_sq"), parse_assign_expr, Keyword.for("entries")]), Chomp[Meta.create]([Keyword.for("close_sq")])])[invoke](tokens);}; 485 | let parse_obj_entry_rename = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("obj_entry_rename")]])]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("old_name")]), Chomp[Meta.create]([Keyword.for("colon")]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("new_name")])]); 486 | parse_obj_entry_rename ??= nil;; 487 | let parse_regular_obj_assign_entry = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("obj_reg_entry")]])]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("name")])]); 488 | parse_regular_obj_assign_entry ??= nil;; 489 | let parse_obj_entry_destructure = function (tokens) { 490 | tokens ??= nil;let __coil_temp; 491 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("obj_assign_expr")]])]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("property")]), Chomp[Meta.create]([Keyword.for("colon")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")])])[invoke](tokens);}; 492 | let parse_obj_assign_entry = ParseMap[Meta.from_entries]([[[Keyword.for("id"), Keyword.for("colon"), Keyword.for("id")], parse_obj_entry_rename], [[Keyword.for("id"), Keyword.for("colon")], parse_obj_entry_destructure], [Keyword.for("id"), parse_regular_obj_assign_entry], [Keyword.for("dot_dot_dot"), parse_spread_assign]]); 493 | parse_obj_assign_entry ??= nil;; 494 | let parse_assign_obj = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("object_deconstruction")]])]), Chomp[Meta.create]([Keyword.for("open_b")]), Until[Meta.create]([Keyword.for("close_b"), parse_obj_assign_entry, Keyword.for("entries")]), Chomp[Meta.create]([Keyword.for("close_b")])]); 495 | parse_assign_obj ??= nil;; 496 | let parse_this_assign = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("this_assign")]])]), Chomp[Meta.create]([Keyword.for("at")]), Either[Meta.create]([valid_ids_in_all_contexts, Keyword.for("name")])]); 497 | parse_this_assign ??= nil;; 498 | let parse_this_spread_assign = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("this_spread_assign")]])]), Chomp[Meta.create]([Keyword.for("dot_dot_dot"), Keyword.for("at")]), One[Meta.create]([Keyword.for("id"), Keyword.for("name")])]); 499 | parse_this_spread_assign ??= nil;; 500 | let parse_assign_expr = ParseMap[Meta.from_entries]([[Keyword.for("id"), parse_assign_id], [Keyword.for("open_sq"), parse_assign_array], [Keyword.for("open_b"), parse_assign_obj], [Keyword.for("at"), parse_this_assign], [[Keyword.for("dot_dot_dot"), Keyword.for("at")], parse_this_spread_assign], [Keyword.for("dot_dot_dot"), parse_spread_assign]]); 501 | parse_assign_expr ??= nil;; 502 | let parse_paren_expr = function (tokens) { 503 | tokens ??= nil;let __coil_temp; 504 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("paren_expr")]])]), Chomp[Meta.create]([Keyword.for("open_p")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), Chomp[Meta.create]([Keyword.for("close_p")])])[invoke](tokens);}; 505 | let parse_yield = function (tokens) { 506 | tokens ??= nil;let __coil_temp; 507 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("yield")]])]), Chomp[Meta.create]([Keyword.for("yield")]), Optional[Meta.create]([Keyword.for("times"), (tokens) => { 508 | tokens ??= nil;; 509 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([])]), Chomp[Meta.create]([Keyword.for("times")])])[invoke](tokens);}, Keyword.for("star?")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 510 | let parse_await = function (tokens) { 511 | tokens ??= nil;let __coil_temp; 512 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("await")]])]), Chomp[Meta.create]([Keyword.for("await")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 513 | let parse_num = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("num")]])]), One[Meta.create]([Keyword.for("num"), Keyword.for("value")])]); 514 | parse_num ??= nil;; 515 | let parse_array = function (tokens) { 516 | tokens ??= nil;let __coil_temp; 517 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("array")]])]), Chomp[Meta.create]([Keyword.for("open_sq")]), Until[Meta.create]([Keyword.for("close_sq"), parse_expr, Keyword.for("elements")]), Chomp[Meta.create]([Keyword.for("close_sq")])])[invoke](tokens);}; 518 | let parse_spread = function (tokens) { 519 | tokens ??= nil;let __coil_temp; 520 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("spread")]])]), Chomp[Meta.create]([Keyword.for("dot_dot_dot")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 521 | let parse_not = function (tokens) { 522 | tokens ??= nil;let __coil_temp; 523 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("not")]])]), Chomp[Meta.create]([Keyword.for("bang")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 524 | let parse_async_modifier = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([])]), Chomp[Meta.create]([Keyword.for("async")])]); 525 | parse_async_modifier ??= nil;; 526 | let parse_gen_modifier = Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Init[Meta.create]([ObjectLiteral[Meta.from_entries]([])]), Chomp[Meta.create]([Keyword.for("times")])]); 527 | parse_gen_modifier ??= nil;; 528 | let parse_fn_expr_body = function (tokens) { 529 | tokens ??= nil;let __coil_temp; 530 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("return")]])]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), FMap[Meta.create]([(node) => { 531 | node ??= nil;; 532 | return [node];}])])[invoke](tokens);}; 533 | let parse_args_def = function (tokens) { 534 | tokens ??= nil;let __coil_temp; 535 | return Parser[Meta.create]([AbortIf[Meta.create]([not_adjacent__q]), Chomp[Meta.create]([Keyword.for("open_p")]), Until[Meta.create]([Keyword.for("close_p"), parse_assign_expr]), Chomp[Meta.create]([Keyword.for("close_p")])])[invoke](tokens);}; 536 | let parse_name_expr = function (tokens) { 537 | tokens ??= nil;let __coil_temp; 538 | var __coil_if_let_temp = parse_single_expr[invoke](tokens) ?? nil; 539 | if (__coil_if_let_temp[Meta.as_bool]()) { 540 | let [expr, tokens] = __coil_if_let_temp; 541 | expr ??= nil; 542 | tokens ??= nil;; 543 | let __coil_temp; 544 | let parse_map = ParseMap[Meta.from_entries]([[Keyword.for("dot"), parse_dot], [Keyword.for("keyword"), parse_keyword_lookup]]); 545 | parse_map ??= nil;; 546 | var __coil_while_let_temp = parse_map[invoke](tokens, expr) ?? nil; 547 | while (__coil_while_let_temp[Meta.as_bool]()) { 548 | let [new_expr, new_tokens] = __coil_while_let_temp; 549 | new_expr ??= nil; 550 | new_tokens ??= nil;; 551 | let __coil_temp; 552 | expr = new_expr; 553 | tokens = new_tokens; 554 | __coil_while_let_temp = parse_map[invoke](tokens, expr) ?? nil; 555 | }; 556 | return [expr, tokens]; 557 | };}; 558 | let parse_def = function (tokens) { 559 | tokens ??= nil;let __coil_temp; 560 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("fn")]])]), Optional[Meta.create]([Keyword.for("async"), parse_async_modifier, Keyword.for("is_async?")]), Chomp[Meta.create]([Keyword.for("def")]), Optional[Meta.create]([Keyword.for("times"), parse_gen_modifier, Keyword.for("generator?")]), Then[Meta.create]([parse_name_expr, Keyword.for("name_expr")]), Optional[Meta.create]([Keyword.for("open_p"), parse_args_def, Keyword.for("args")]), Case[Meta.create]([ParseMap[Meta.from_entries]([[Keyword.for("eq"), parse_fn_expr_body], [_, block[invoke]()]]), Keyword.for("body")])])[invoke](tokens);}; 561 | let parse_id_shorthand_record_entry = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("id_shorthand_record_entry")]])]), One[Meta.create]([Keyword.for("id"), Keyword.for("name")])]); 562 | parse_id_shorthand_record_entry ??= nil;; 563 | let parse_keyword_record_entry = function (tokens) { 564 | tokens ??= nil;let __coil_temp; 565 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("keyword_record_entry")]])]), One[Meta.create]([Keyword.for("id"), Keyword.for("name")]), Chomp[Meta.create]([Keyword.for("colon")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 566 | let parse_regular_record_entry = function (tokens) { 567 | tokens ??= nil;let __coil_temp; 568 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("regular_record_entry")]])]), Then[Meta.create]([parse_expr, Keyword.for("key_expr")]), Chomp[Meta.create]([Keyword.for("arrow")]), Then[Meta.create]([parse_expr, Keyword.for("value_expr")])])[invoke](tokens);}; 569 | let parse_record_entry = ParseMap[Meta.from_entries]([[Keyword.for("dot_dot_dot"), parse_spread], [[Keyword.for("id"), Keyword.for("colon")], parse_keyword_record_entry], [[Keyword.for("id"), Keyword.for("arrow")], parse_regular_record_entry], [Keyword.for("def"), parse_def], [[Keyword.for("async"), Keyword.for("def")], parse_def], [[Keyword.for("id"), dot(PARSE_SND_EXPR_STEP_MAP, keys)[invoke]()], parse_regular_record_entry], [Keyword.for("id"), parse_id_shorthand_record_entry], [_, parse_regular_record_entry]]); 570 | parse_record_entry ??= nil;; 571 | let parse_prefix_inclusive_range = function (tokens) { 572 | tokens ??= nil;let __coil_temp; 573 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("prefix_inclusive_range")]])]), Chomp[Meta.create]([Keyword.for("dot_dot"), Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 574 | let parse_prefix_exclusive_range = function (tokens) { 575 | tokens ??= nil;let __coil_temp; 576 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("prefix_exclusive_range")]])]), Chomp[Meta.create]([Keyword.for("dot_dot")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 577 | let parse_keyword = function (tokens) { 578 | tokens ??= nil;let __coil_temp; 579 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("keyword")]])]), One[Meta.create]([Keyword.for("keyword"), Keyword.for("value")]), FMap[Meta.create]([({'type': type, 'value': value, 'pos': pos}) => { 580 | type ??= nil; 581 | value ??= nil; 582 | pos ??= nil;; 583 | return (ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), type], [Keyword.for("value"), dot(value, 'slice')[invoke]((1))], [Keyword.for("pos"), pos]]));}])])[invoke](tokens);}; 584 | let parse_anon_fn_body = function (tokens) { 585 | tokens ??= nil;let __coil_temp; 586 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("brace_body")]])]), Chomp[Meta.create]([Keyword.for("open_b")]), Until[Meta.create]([Keyword.for("close_b"), parse_statement, Keyword.for("body")]), Chomp[Meta.create]([Keyword.for("close_b")])])[invoke](tokens);}; 587 | let parse_anon_fn = function (tokens) { 588 | tokens ??= nil;let __coil_temp; 589 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("anon_fn")]])]), Chomp[Meta.create]([Keyword.for("pipe_bar")]), Until[Meta.create]([Keyword.for("pipe_bar"), parse_assign_expr, Keyword.for("args")]), Chomp[Meta.create]([Keyword.for("pipe_bar")]), Then[Meta.create]([ParseMap[Meta.from_entries]([[Keyword.for("open_b"), parse_anon_fn_body], [_, parse_expr]]), Keyword.for("return_node")])])[invoke](tokens);}; 590 | let parse_anon_gen_fn = function (tokens) { 591 | tokens ??= nil;let __coil_temp; 592 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("anon_gen_fn")]])]), Chomp[Meta.create]([Keyword.for("times")]), Chomp[Meta.create]([Keyword.for("pipe_bar")]), Until[Meta.create]([Keyword.for("pipe_bar"), parse_assign_expr, Keyword.for("args")]), Chomp[Meta.create]([Keyword.for("pipe_bar")]), Then[Meta.create]([ParseMap[Meta.from_entries]([[Keyword.for("open_b"), parse_anon_fn_body], [_, parse_expr]]), Keyword.for("return_node")])])[invoke](tokens);}; 593 | let parse_unapplied_algebra_op = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("unapplied_algebra_op")]])]), Either[Meta.create]([algebra_ops, Keyword.for("op")])]); 594 | parse_unapplied_algebra_op ??= nil;; 595 | let parse_unapplied_equality_op = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("unapplied_equality_op")]])]), Either[Meta.create]([equality_ops, Keyword.for("op")])]); 596 | parse_unapplied_equality_op ??= nil;; 597 | let SINGLE_EXPR_PARSE_MAP = ParseMap[Meta.from_entries]([[Keyword.for("string_lit"), parse_str], [Keyword.for("regex_lit"), parse_regex], [Keyword.for("keyword"), parse_keyword], [Keyword.for("open_p"), parse_paren_expr], [Keyword.for("await"), parse_await], [Keyword.for("num"), parse_num], [Keyword.for("open_sq"), parse_array], [Keyword.for("dot_dot_dot"), parse_spread], [Keyword.for("bang"), parse_not], [Keyword.for("open_b"), parse_obj], [Keyword.for("pipe_bar"), parse_anon_fn], [Keyword.for("def"), parse_def], [Keyword.for("yield"), parse_yield], [[Keyword.for("times"), Keyword.for("pipe_bar")], parse_anon_gen_fn], [[Keyword.for("dot_dot"), Keyword.for("eq")], parse_prefix_inclusive_range], [Keyword.for("dot_dot"), parse_prefix_exclusive_range], [Set[Meta.create]([...valid_ids_in_all_contexts, Keyword.for("import")]), parse_id], [[Keyword.for("async"), Keyword.for("def")], parse_def], [equality_ops, parse_unapplied_equality_op], [algebra_ops, parse_unapplied_algebra_op]]); 598 | SINGLE_EXPR_PARSE_MAP ??= nil;; 599 | let parse_single_expr = function (tokens) { 600 | tokens ??= nil;let __coil_temp; 601 | return SINGLE_EXPR_PARSE_MAP[invoke](tokens);}; 602 | let parse_expr = function (tokens) { 603 | tokens ??= nil;let __coil_temp; 604 | return parse_fifth_expr[invoke](parse_fourth_expr[invoke](parse_third_expr[invoke](parse_snd_expr[invoke](parse_single_expr[invoke](tokens)))));}; 605 | let parse_1_2_expr = function (tokens) { 606 | tokens ??= nil;let __coil_temp; 607 | return parse_snd_expr[invoke](parse_single_expr[invoke](tokens));}; 608 | let parse_1_2_3_expr = function (tokens) { 609 | tokens ??= nil;let __coil_temp; 610 | return parse_third_expr[invoke](parse_snd_expr[invoke](parse_single_expr[invoke](tokens)));}; 611 | let parse_1_2_3_4_expr = function (tokens) { 612 | tokens ??= nil;let __coil_temp; 613 | return parse_fourth_expr[invoke](parse_third_expr[invoke](parse_snd_expr[invoke](parse_single_expr[invoke](tokens))));}; 614 | let parse_else_branch = function (tokens) { 615 | tokens ??= nil;let __coil_temp; 616 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("else")]])]), Chomp[Meta.create]([Keyword.for("else")]), UntilEither[Meta.create]([Set[Meta.create]([Keyword.for("else"), Keyword.for("end")]), parse_statement, Keyword.for("body")])])[invoke](tokens);}; 617 | let parse_else_if_branch = function (tokens) { 618 | tokens ??= nil;let __coil_temp; 619 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("else_if")]])]), Chomp[Meta.create]([Keyword.for("else"), Keyword.for("if")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), UntilEither[Meta.create]([Set[Meta.create]([Keyword.for("else"), Keyword.for("end")]), parse_statement, Keyword.for("pass")]), Optional[Meta.create]([Keyword.for("else"), parse_if_branch, Keyword.for("fail")])])[invoke](tokens);}; 620 | let parse_else_if_let_branch = function (tokens) { 621 | tokens ??= nil;let __coil_temp; 622 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("else_if_let")]])]), Chomp[Meta.create]([Keyword.for("else"), Keyword.for("if"), Keyword.for("let")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), UntilEither[Meta.create]([Set[Meta.create]([Keyword.for("else"), Keyword.for("end")]), parse_statement, Keyword.for("pass")]), Optional[Meta.create]([Keyword.for("else"), parse_if_branch, Keyword.for("fail")])])[invoke](tokens);}; 623 | let parse_if_branch = ParseMap[Meta.from_entries]([[[Keyword.for("else"), Keyword.for("if"), Keyword.for("let")], parse_else_if_let_branch], [[Keyword.for("else"), Keyword.for("if")], parse_else_if_branch], [Keyword.for("else"), parse_else_branch]]); 624 | parse_if_branch ??= nil;; 625 | let parse_if = function (tokens) { 626 | tokens ??= nil;let __coil_temp; 627 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("if")]])]), Chomp[Meta.create]([Keyword.for("if")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), UntilEither[Meta.create]([Set[Meta.create]([Keyword.for("else"), Keyword.for("end")]), parse_statement, Keyword.for("pass")]), Optional[Meta.create]([Keyword.for("else"), parse_if_branch, Keyword.for("fail")]), Chomp[Meta.create]([Keyword.for("end")])])[invoke](tokens);}; 628 | let parse_let = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("let")]])]), Chomp[Meta.create]([Keyword.for("let")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("rhs")])]); 629 | parse_let ??= nil;; 630 | let parse_if_let = function (tokens) { 631 | tokens ??= nil;let __coil_temp; 632 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("if_let")]])]), Chomp[Meta.create]([Keyword.for("if"), Keyword.for("let")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("expr")]), UntilEither[Meta.create]([Set[Meta.create]([Keyword.for("else"), Keyword.for("end")]), parse_statement, Keyword.for("pass")]), Optional[Meta.create]([Keyword.for("else"), parse_if_branch, Keyword.for("fail")]), Chomp[Meta.create]([Keyword.for("end")])])[invoke](tokens);}; 633 | let parse_protocol_methods = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("protocol_method")]])]), Chomp[Meta.create]([Keyword.for("open_b")]), Until[Meta.create]([Keyword.for("close_b"), parse_id, Keyword.for("names")]), Chomp[Meta.create]([Keyword.for("close_b")])]); 634 | parse_protocol_methods ??= nil;; 635 | let parse_protocol = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("protocol_def")]])]), Chomp[Meta.create]([Keyword.for("protocol")]), One[Meta.create]([Keyword.for("id"), Keyword.for("name")]), Optional[Meta.create]([Keyword.for("open_b"), parse_protocol_methods, Keyword.for("methods")])]); 636 | parse_protocol ??= nil;; 637 | let parse_return = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("return")]])]), Chomp[Meta.create]([Keyword.for("return")]), Optional[Meta.create]([dot(SINGLE_EXPR_PARSE_MAP, keys)[invoke](), parse_expr, Keyword.for("expr")])]); 638 | parse_return ??= nil;; 639 | let parse_await_modifier = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([])]), Chomp[Meta.create]([Keyword.for("await")])]); 640 | parse_await_modifier ??= nil;; 641 | let parse_for_loop = function (tokens) { 642 | tokens ??= nil;let __coil_temp; 643 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("for_loop")]])]), Chomp[Meta.create]([Keyword.for("for")]), Optional[Meta.create]([Keyword.for("await"), parse_await_modifier, Keyword.for("is_await?")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("of")]), Then[Meta.create]([parse_expr, Keyword.for("iterable_expr")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 644 | let parse_loop = function (tokens) { 645 | tokens ??= nil;let __coil_temp; 646 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("loop")]])]), Chomp[Meta.create]([Keyword.for("loop")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 647 | let parse_while_loop = function (tokens) { 648 | tokens ??= nil;let __coil_temp; 649 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("while_loop")]])]), Chomp[Meta.create]([Keyword.for("while")]), Then[Meta.create]([parse_expr, Keyword.for("test_expr")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 650 | let parse_while_let_loop = function (tokens) { 651 | tokens ??= nil;let __coil_temp; 652 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("while_let_loop")]])]), Chomp[Meta.create]([Keyword.for("while"), Keyword.for("let")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("eq")]), Then[Meta.create]([parse_expr, Keyword.for("test_expr")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 653 | let parse_continue = function (tokens) { 654 | tokens ??= nil;let __coil_temp; 655 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("continue")]])]), Chomp[Meta.create]([Keyword.for("continue")])])[invoke](tokens);}; 656 | let parse_break = function (tokens) { 657 | tokens ??= nil;let __coil_temp; 658 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("break")]])]), Chomp[Meta.create]([Keyword.for("break")])])[invoke](tokens);}; 659 | let parse_catch = function (tokens) { 660 | tokens ??= nil;let __coil_temp; 661 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("catch")]])]), Chomp[Meta.create]([Keyword.for("catch")]), One[Meta.create]([Keyword.for("id"), Keyword.for("name")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 662 | let parse_finally = function (tokens) { 663 | tokens ??= nil;let __coil_temp; 664 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("finally")]])]), Chomp[Meta.create]([Keyword.for("finally")]), block[invoke](Keyword.for("body"))])[invoke](tokens);}; 665 | let parse_import = function (tokens) { 666 | tokens ??= nil;let __coil_temp; 667 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("import")]])]), Chomp[Meta.create]([Keyword.for("import")]), Then[Meta.create]([parse_assign_expr, Keyword.for("assign_expr")]), Chomp[Meta.create]([Keyword.for("from")]), Then[Meta.create]([parse_str, Keyword.for("path")])])[invoke](tokens);}; 668 | let parse_export = function (tokens) { 669 | tokens ??= nil;let __coil_temp; 670 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("export")]])]), Chomp[Meta.create]([Keyword.for("export")]), Then[Meta.create]([parse_statement, Keyword.for("statement")])])[invoke](tokens);}; 671 | let parse_export_default = function (tokens) { 672 | tokens ??= nil;let __coil_temp; 673 | return Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("export_default")]])]), Chomp[Meta.create]([Keyword.for("export"), Keyword.for("default")]), Then[Meta.create]([parse_expr, Keyword.for("expr")])])[invoke](tokens);}; 674 | let parse_direct_import = Parser[Meta.create]([Init[Meta.create]([ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), Keyword.for("direct_import")]])]), Chomp[Meta.create]([Keyword.for("import")]), One[Meta.create]([Keyword.for("string_lit"), Keyword.for("path")])]); 675 | parse_direct_import ??= nil;; 676 | let parse_statement = function (tokens) { 677 | tokens ??= nil;let __coil_temp; 678 | return ParseMap[Meta.from_entries]([[Keyword.for("let"), parse_let], [Keyword.for("for"), parse_for_loop], [Keyword.for("protocol"), parse_protocol], [Keyword.for("return"), parse_return], [Keyword.for("continue"), parse_continue], [Keyword.for("break"), parse_break], [Keyword.for("loop"), parse_loop], [[Keyword.for("import"), Keyword.for("string_lit")], parse_direct_import], [Keyword.for("import"), parse_import], [[Keyword.for("export"), Keyword.for("default")], parse_export_default], [Keyword.for("export"), parse_export], [[Keyword.for("while"), Keyword.for("let")], parse_while_let_loop], [Keyword.for("while"), parse_while_loop], [[Keyword.for("if"), Keyword.for("let")], parse_if_let], [Keyword.for("if"), parse_if], [_, parse_expr]])[invoke](tokens);}; 679 | let block = function (name) { 680 | name ??= nil;let __coil_temp; 681 | return Parser[Meta.create]([Until[Meta.create]([Keyword.for("end"), parse_statement, name]), Chomp[Meta.create]([Keyword.for("end")])]);}; 682 | let parse_tokens = function (tokens) { 683 | tokens ??= nil;let __coil_temp; 684 | let ast = []; 685 | ast ??= nil;; 686 | var __coil_while_let_temp = parse_statement[invoke](tokens) ?? nil; 687 | while (__coil_while_let_temp[Meta.as_bool]()) { 688 | let [statement_or_expr, rest] = __coil_while_let_temp; 689 | statement_or_expr ??= nil; 690 | rest ??= nil;; 691 | let __coil_temp; 692 | dot(ast, 'push')[invoke](statement_or_expr); 693 | tokens = rest; 694 | __coil_while_let_temp = parse_statement[invoke](tokens) ?? nil; 695 | }; 696 | return ast;}; 697 | export default parse_tokens; 698 | -------------------------------------------------------------------------------- /compiler/dist/shared.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | export let CollectionView = function (collection, idx) { 14 | this['collection'] = collection; 15 | this['idx'] = idx; 16 | collection ??= nil; 17 | idx ??= nil;let __coil_temp; 18 | };; 19 | CollectionView['prototype'][(dot(Collection, 'len'))] = function () { 20 | let __coil_temp; 21 | return dot(dot(this, 'collection'), len)[invoke]()[Algebra["-"]](dot(this, 'idx'));}; 22 | CollectionView['prototype'][(dot(Collection, 'empty?'))] = function () { 23 | let __coil_temp; 24 | return dot(this, len)[invoke]()[Meta["=="]]((0));}; 25 | CollectionView['prototype'][(dot(Collection, 'at'))] = function (idx) { 26 | idx ??= nil;let __coil_temp; 27 | return dot(dot(this, 'collection'), at)[invoke](dot(this, 'idx')[Algebra["+"]](idx));}; 28 | CollectionView['prototype'][first] = function () { 29 | let __coil_temp; 30 | return dot(dot(this, 'collection'), at)[invoke](dot(this, 'idx'));}; 31 | CollectionView['prototype']['slice'] = function (n) { 32 | n ??= nil;let __coil_temp; 33 | return CollectionView[Meta.create]([dot(this, 'collection'), dot(this, 'idx')[Algebra["+"]](n)]);}; 34 | CollectionView['prototype'][(dot(Symbol, 'iterator'))] = function *() { 35 | let __coil_temp; 36 | for (let i of new ExclusiveRange(dot(this, 'idx'), dot(dot(this, 'collection'), len)[invoke]())) { 37 | i ??= nil;; 38 | let __coil_temp; 39 | (yield dot(dot(this, 'collection'), i)); 40 | };}; 41 | -------------------------------------------------------------------------------- /compiler/dist/tokenizer.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | import {ObjectLiteral, Nil, nil, Keyword, dot, raise__b, panic__b, type_of, str, from_js} from '../src/std/globals.mjs' 3 | import Meta, {nil__q, create, from_entries, as_num, exists__q, as_bool, log, invoke, pipe, as_kw, assert__b, freeze__b, assert_eq__b} from '../src/std/meta.mjs'; 4 | import Iter, {take, until, skip, find, find_map, zip, reduce, map, flat_map, each, count, filter, filter_map, reject, all__q, any__q, split, compact, join, into, compose} from '../src/std/iter.mjs'; 5 | import Algebra from '../src/std/algebra.mjs'; 6 | import Bool, {negate} from '../src/std/bool.mjs'; 7 | import Collection, {at, len, empty__q, has__q, delete__b, __delete__} from '../src/std/collection.mjs'; 8 | import OrderedCollection, {first} from '../src/std/ordered_collection.mjs'; 9 | import {inc, InclusiveRange, ExclusiveRange, InclusiveRangeNoMaximum, InclusiveRangeNoMinimum, ExclusiveRangeNoMaximum, ExclusiveRangeNoMinimum} from '../src/std/range.mjs'; 10 | import Record, {keys, values, set, set__b} from '../src/std/record.mjs'; 11 | import Underscore, {_} from '../src/std/underscore.mjs'; 12 | let __coil_temp; 13 | let Tokenizer = function (entries) { 14 | this['entries'] = entries; 15 | entries ??= nil;let __coil_temp; 16 | }; 17 | let pass = function () { 18 | let __coil_temp; 19 | }; 20 | let newline = function () { 21 | let __coil_temp; 22 | }; 23 | Tokenizer['prototype'][invoke] = function (str) { 24 | str ??= nil;let __coil_temp; 25 | let tokens = []; 26 | tokens ??= nil;; 27 | let index = (0); 28 | index ??= nil;; 29 | let rest_of_string = function () { 30 | let __coil_temp; 31 | return dot(str, 'slice')[invoke](index);}; 32 | let scan = function (pattern) { 33 | pattern ??= nil;let __coil_temp; 34 | let result = dot(rest_of_string[invoke](), Keyword.for("match"))[invoke](pattern); 35 | result ??= nil;; 36 | if (((__coil_temp = {left: dot(result, nil__q)[invoke]()}, __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : dot(result, 'index')[Meta["!="]]((0))))[Meta.as_bool]()) { 37 | let __coil_temp; 38 | return false; 39 | } else { 40 | let __coil_temp; 41 | index = index[Algebra["+"]](dot(dot(result, (0)), Keyword.for("length"))); 42 | return dot(result, (0)); 43 | };}; 44 | let line = (1); 45 | line ??= nil;; 46 | let col = (1); 47 | col ??= nil;; 48 | while ((rest_of_string[invoke]()[Meta["!="]](""))[Meta.as_bool]()) { 49 | let __coil_temp; 50 | let found = false; 51 | found ??= nil;; 52 | for (let [pattern, type] of dot(this, 'entries')) { 53 | pattern ??= nil; 54 | type ??= nil;; 55 | let __coil_temp; 56 | var __coil_if_let_temp = scan[invoke](pattern) ?? nil; 57 | if (__coil_if_let_temp[Meta.as_bool]()) { 58 | let value = __coil_if_let_temp; 59 | value ??= nil;; 60 | let __coil_temp; 61 | if ((type[Meta["=="]](newline))[Meta.as_bool]()) { 62 | let __coil_temp; 63 | line = line[Algebra["+"]]((1)); 64 | col = (1); 65 | } else if ((type[Meta["!="]](pass))[Meta.as_bool]()) { 66 | let __coil_temp; 67 | dot(tokens, 'push')[invoke](ObjectLiteral[Meta.from_entries]([[Keyword.for("type"), type], [Keyword.for("value"), value], [Keyword.for("line"), line], [Keyword.for("col"), col]])); 68 | col = col[Algebra["+"]](dot(value, len)[invoke]()); 69 | } else { 70 | let __coil_temp; 71 | col = col[Algebra["+"]](dot(value, len)[invoke]()); 72 | }; 73 | found = true; 74 | break; 75 | }; 76 | }; 77 | if ((found[Bool.negate]())[Meta.as_bool]()) { 78 | let __coil_temp; 79 | panic__b[invoke]("No token matched."); 80 | }; 81 | }; 82 | return tokens;}; 83 | let tokenize = Tokenizer[Meta.from_entries]([[/^\n/, newline], [/^\s+/, pass], [/^\#.*/, pass], [/^\-\-.*/, pass], [/^\,/, pass], [/^\;/, pass], [/^if\s/, Keyword.for("if")], [/^else\s/, Keyword.for("else")], [/^return\s/, Keyword.for("return")], [/^import\s/, Keyword.for("import")], [/^export\s/, Keyword.for("export")], [/^default\s/, Keyword.for("default")], [/^from\s/, Keyword.for("from")], [/^let\s/, Keyword.for("let")], [/^protocol\s/, Keyword.for("protocol")], [/^for\s/, Keyword.for("for")], [/^catch\s/, Keyword.for("catch")], [/^finally\s/, Keyword.for("finally")], [/^instanceof\s/, Keyword.for("instanceof")], [/^end\b/, Keyword.for("end")], [/^while\s/, Keyword.for("while")], [/^loop\s/, Keyword.for("loop")], [/^and\s/, Keyword.for("and")], [/^or\s/, Keyword.for("or")], [/^continue\s/, Keyword.for("continue")], [/^break\s/, Keyword.for("break")], [/^of\s/, Keyword.for("of")], [/^yield\b/, Keyword.for("yield")], [/^async\s/, Keyword.for("async")], [/^await\s/, Keyword.for("await")], [/^\=\>/, Keyword.for("arrow")], [/^\@/, Keyword.for("at")], [/^\=\=/, Keyword.for("double_eq")], [/^\!\=/, Keyword.for("not_eq")], [/^\!/, Keyword.for("bang")], [/^\=/, Keyword.for("eq")], [/^def\b/, Keyword.for("def")], [/^\{/, Keyword.for("open_b")], [/^\}/, Keyword.for("close_b")], [/^\(/, Keyword.for("open_p")], [/^\)/, Keyword.for("close_p")], [/^\|/, Keyword.for("pipe_bar")], [/^[\-\+]?(\d+\.)?\d+n/, Keyword.for("bigint")], [/^[\-\+]?(\d+\.)?\d+/, Keyword.for("num")], [/^\.\.\./, Keyword.for("dot_dot_dot")], [/^\.\./, Keyword.for("dot_dot")], [/^\./, Keyword.for("dot")], [/^\/.*\/[a-z]?/, Keyword.for("regex_lit")], [/^\>\=/, Keyword.for("gt_eq")], [/^\<\=/, Keyword.for("lt_eq")], [/^\>/, Keyword.for("gt")], [/^\", "_lt_") 11 | else 12 | return name 13 | end 14 | end 15 | 16 | def eval_if_branch(branch) 17 | if branch.nil?() 18 | return "" 19 | else if branch.:type == :else 20 | return str(" else {\n" eval_ast(branch.:body or []) "\n}") 21 | else if branch.:type == :else_if_let 22 | return str(" else {\n" eval_if_let(branch) "\n}") 23 | else if branch.:type == :else_if 24 | return str( 25 | " else if ((" eval_expr(branch.at(:expr)) ")[Meta.as_bool]()) {\n" 26 | eval_ast(branch.at(:pass) or []) 27 | "\n}" eval_if_branch(branch.at(:fail)) 28 | ) 29 | else 30 | panic!("Expected else if") 31 | end 32 | end 33 | 34 | def eval_if({expr, pass, fail}) = str( 35 | "if ((" eval_expr(expr) ")[Meta.as_bool]()) {\n" 36 | eval_ast(pass) "\n" 37 | "}" eval_if_branch(fail) 38 | ) 39 | 40 | def eval_str({value}) 41 | value = value.:slice(1, -1) 42 | if value.:includes("\n") 43 | return str("`" value:replaceAll("`", "\\`") "`") 44 | else 45 | return str("\"" value "\"") 46 | end 47 | end 48 | 49 | def eval_fn_call({lhs args}) = 50 | str(eval_expr(lhs) "[invoke](" args.map(eval_expr).join(", ") ")") 51 | 52 | def eval_id_assign_name({name}) 53 | if name == "_" 54 | return "_ignore_me_" 55 | else 56 | return resolve_name(name) 57 | end 58 | end 59 | 60 | def eval_spread_assign({name}) = str("..." resolve_name(name)) 61 | 62 | def eval_array_deconstruction_entry(node) = node.at(:type).pipe(Map{ 63 | :id_assign => eval_id_assign_name 64 | :spread_assign => eval_spread_assign 65 | :array_deconstruction => eval_array_deconstruction_names 66 | :object_deconstruction => eval_object_deconstruction_names 67 | })(node) 68 | 69 | def eval_array_deconstruction_names({entries}) = 70 | str("[" entries.map(eval_array_deconstruction_entry).join(", ") "]") 71 | 72 | def eval_obj_reg_entry({name}) = str("'" name "': " resolve_name(name)) 73 | 74 | def eval_obj_entry_rename({old_name, new_name}) = 75 | str("'" old_name "': " resolve_name(new_name)) 76 | 77 | def eval_obj_assign_expr({property, assign_expr}) = 78 | str("'" property "': " eval_assign_expr(assign_expr)) 79 | 80 | def eval_obj_deconstruction_entry(node) = node.at(:type).pipe(Map{ 81 | :obj_reg_entry => eval_obj_reg_entry 82 | :obj_assign_expr => eval_obj_assign_expr 83 | :obj_entry_rename => eval_obj_entry_rename 84 | :spread_assign => eval_spread_assign 85 | :object_deconstruction => eval_object_deconstruction_names 86 | })(node) 87 | 88 | def eval_object_deconstruction_names({entries}) = 89 | str("{" entries.map(eval_obj_deconstruction_entry).join(", ") "}") 90 | 91 | def eval_this_assign({name}) = resolve_name(name) 92 | 93 | def eval_this_spread_assign({name}) = str("..." resolve_name(name)) 94 | 95 | def eval_assign_all_as({name}) = str("* as " name) 96 | 97 | def eval_assign_expr(node) = node.at(:type).pipe(Map{ 98 | :id_assign => eval_id_assign_name 99 | :spread_assign => eval_spread_assign 100 | :array_deconstruction => eval_array_deconstruction_names 101 | :object_deconstruction => eval_object_deconstruction_names 102 | :this_assign => eval_this_assign 103 | :this_spread_assign => eval_spread_assign 104 | })(node) 105 | 106 | def eval_while_let_loop({test_expr, assign_expr, body}) = str( 107 | "var __coil_while_let_temp = " eval_expr(test_expr) " ?? nil;\n" 108 | "while (__coil_while_let_temp[Meta.as_bool]()) {\n" 109 | "let " eval_assign_expr(assign_expr) " = __coil_while_let_temp;\n" 110 | eval_nil_destructure_args([assign_expr]) ";\n" 111 | eval_ast(body) "\n" 112 | "__coil_while_let_temp = " eval_expr(test_expr) " ?? nil;\n" 113 | "}") 114 | 115 | def eval_if_let({expr, assign_expr, pass, fail}) = str( 116 | "var __coil_if_let_temp = " eval_expr(expr) " ?? nil;\n" 117 | "if (__coil_if_let_temp[Meta.as_bool]()) {\n" 118 | "let " eval_assign_expr(assign_expr) " = __coil_if_let_temp;\n" 119 | eval_nil_destructure_args([assign_expr]) ";\n" 120 | eval_ast(pass) "\n" 121 | "}" eval_if_branch(fail) 122 | ) 123 | 124 | def eval_spread({expr}) = str("..." eval_expr(expr)) 125 | 126 | def eval_let({assign_expr, rhs}) = 127 | str( 128 | "let " eval_assign_expr(assign_expr) " = " eval_expr(rhs) ";\n" 129 | eval_nil_destructure_args([assign_expr]) 130 | ) 131 | 132 | def eval_array({elements}) = str("[" elements.map(eval_expr).join(", ") "]") 133 | 134 | def eval_this_assignments(args) = args 135 | .filter(:type Set[:this_assign :this_spread_assign]) 136 | .map(|{name}| str("this['" name "'] = " resolve_name(name) ";\n")) 137 | .into("") 138 | 139 | def eval_name_expr(node) = node.at(:type).pipe(Map{ 140 | def :dot({lhs rhs}) = str(eval_name_expr(lhs) "[" eval_name_expr(rhs) "]") 141 | def :keyword_lookup({lhs, property}) = str(eval_name_expr(lhs) "['" property "']") 142 | } |eval_fn| eval_fn or eval_expr)(node) 143 | 144 | def entries_arg_names({entries}) = 145 | entries:flatMap(arg_names) 146 | 147 | def arg_names(node) = node.at(:type).pipe(Map{ 148 | :array_deconstruction => entries_arg_names 149 | :object_deconstruction => entries_arg_names 150 | def :obj_assign_expr({property, assign_expr}) = arg_names(assign_expr) 151 | def :id_assign({name}) = [name] 152 | def :obj_reg_entry({name}) = [name] 153 | def :obj_entry_rename({new_name}) = [new_name] 154 | def :spread_assign({name}) = [name] 155 | def :obj_str_rename_entry({new_name}) = [new_name] 156 | def :this_assign({name}) = [name] 157 | def :this_spread_assign({name}) = [name] 158 | })(node) 159 | 160 | def eval_nil_destructure_args(args) 161 | if args 162 | return args:flatMap(arg_names) 163 | .map(|name| str(resolve_name(name) " ??= nil;")) 164 | .join("\n") 165 | else 166 | return "" 167 | end 168 | end 169 | 170 | def eval_fn_expr({is_async? generator? args body}) = str( 171 | (is_async? and "async ") 172 | "function " 173 | (generator? and "*") 174 | "(" args.map(eval_assign_expr).join(", ") ") {\n" 175 | eval_this_assignments(args) 176 | eval_nil_destructure_args(args) 177 | eval_ast(body) 178 | "}") 179 | 180 | def eval_fn(node) = str( 181 | (node:name_expr:type == :id_lookup and "let ") or "" 182 | eval_name_expr(node:name_expr) " = " 183 | eval_fn_expr(node) 184 | ) 185 | 186 | def eval_obj_fn({name generator? is_async? args body}) = 187 | str((is_async? and "async ") 188 | (generator? and "*") 189 | "['" name "'](" args.map(eval_assign_expr).join(", ") ") {\n" 190 | eval_nil_destructure_args(args) ";\n" 191 | eval_ast(body) "\n}") 192 | 193 | def eval_id_lookup({name}) = resolve_name(name) 194 | 195 | def eval_num({value}) = str("(" value ")") 196 | 197 | def eval_double_equals({lhs, rhs}) = 198 | str(eval_expr(lhs) "[Equal['==']](" eval_expr(rhs) ")") 199 | 200 | def eval_not_equals({lhs, rhs}) = str(eval_expr(lhs) "[Equal['!=']](" eval_expr(rhs) ")") 201 | 202 | def eval_not({expr}) = str(eval_expr(expr) "[Bool.negate]()") 203 | 204 | def eval_meta_from_entries({lhs entries}) = 205 | str(eval_expr(lhs) "[Meta.from_entries]([" 206 | entries.map(eval_record_entry).join(", ") "])") 207 | 208 | def eval_meta_create({lhs, entries}) = 209 | str(eval_expr(lhs) "[Meta.create]([" entries.map(eval_expr).join(", ") "])") 210 | 211 | def eval_await({expr}) = str("await " eval_expr(expr)) 212 | 213 | def eval_yield({star? expr}) = str("(yield" (star? and "*") " " eval_expr(expr) ")") 214 | 215 | def eval_dot_yield({lhs}) = str("(yield " eval_expr(lhs) ")") 216 | 217 | def eval_paren_expr({expr}) = str("(" eval_expr(expr) ")") 218 | 219 | def eval_keyword({value}) = str("Keyword.for(\"" value "\")") 220 | 221 | def eval_regular_record_entry({key_expr value_expr}) = 222 | str("[" eval_expr(key_expr) ", " eval_expr(value_expr) "]") 223 | 224 | def eval_keyword_record_entry({name expr}) = 225 | str("[" eval_keyword({value: name}) ", " eval_expr(expr) "]") 226 | 227 | def eval_fn_record_entry(fn_node) = 228 | str("[" eval_expr(fn_node:name_expr) ", " eval_fn_expr(fn_node) "]") 229 | 230 | def eval_id_shorthand_record_entry({name}) = str("[" eval_keyword({value: name}) ", " resolve_name(name) "]") 231 | 232 | def eval_record_entry(node) = node.at(:type).pipe(Map{ 233 | :regular_record_entry => eval_regular_record_entry 234 | :keyword_record_entry => eval_keyword_record_entry 235 | :id_shorthand_record_entry => eval_id_shorthand_record_entry 236 | :spread => eval_spread 237 | :fn => eval_fn_record_entry 238 | })(node) 239 | 240 | def eval_inclusive_range({lhs, rhs}) 241 | if rhs 242 | return str("new InclusiveRange(" eval_expr(lhs) ", " eval_expr(rhs) ")") 243 | else 244 | return str("new InclusiveRangeNoMaximum(" eval_expr(lhs) ")") 245 | end 246 | end 247 | 248 | def eval_exclusive_range({lhs, rhs}) 249 | if rhs 250 | return str("new ExclusiveRange(" eval_expr(lhs) ", " eval_expr(rhs) ")") 251 | else 252 | return str("new ExclusiveRangeNoMaximum(" eval_expr(lhs) ")") 253 | end 254 | end 255 | 256 | def eval_regex_lit({value}) = value 257 | 258 | def eval_prefix_exclusive_range({expr}) = str("new ExclusiveRangeNoMinimum(" eval_expr(expr) ")") 259 | 260 | def eval_prefix_inclusive_range({expr}) = str("new InclusiveRangeNoMinimum(" eval_expr(expr) ")") 261 | 262 | def eval_dot({lhs, rhs}) = str("dot(" eval_expr(lhs) ", " eval_expr(rhs) ")") 263 | 264 | def eval_keyword_lookup({lhs property}) = 265 | str("dot(" eval_expr(lhs) ", '" property "')") 266 | 267 | def eval_object_literal({entries}) = str( 268 | "ObjectLiteral[Meta.from_entries]([" 269 | entries.map(eval_record_entry).join(", ") 270 | "])" 271 | ) 272 | 273 | def eval_anon_fn_body(node) 274 | if node:type == :brace_body 275 | return eval_ast(node:body) 276 | else 277 | return str("return " eval_expr(node) ";") 278 | end 279 | end 280 | 281 | def eval_anon_fn({args, return_node}) = str( 282 | "(" args.map(eval_assign_expr).join(", ") ") => {\n" 283 | eval_nil_destructure_args(args) ";\n" 284 | eval_anon_fn_body(return_node) 285 | "}" 286 | ) 287 | 288 | def eval_anon_gen_fn({args, return_node}) = str( 289 | "function *(" args.map(eval_assign_expr).join(", ") ") {\n" 290 | eval_nil_destructure_args(args) ";\n" 291 | eval_anon_fn_body(return_node) 292 | -- match arrow function behavior 293 | "}.bind(this)" 294 | ) 295 | 296 | def eval_anon_body_fn({args body}) = str( 297 | "(" args.map(eval_assign_expr).join(", ") ") => {\n" 298 | eval_nil_destructure_args(args) "\n" 299 | eval_ast(body) 300 | "}" 301 | ) 302 | 303 | def eval_algebra_op({lhs, op, rhs}) = str( 304 | eval_expr(lhs) "[Algebra[\"" op "\"]](" eval_expr(rhs) ")" 305 | ) 306 | 307 | def eval_equality_op({lhs, op, rhs}) = str( 308 | eval_expr(lhs) "[Meta[\"" op "\"]](" eval_expr(rhs)")" 309 | ) 310 | 311 | def eval_instanceof({lhs, rhs}) = str("(" eval_expr(lhs) " instanceof " eval_expr(rhs) ")") 312 | 313 | def eval_and({lhs, rhs}) = str( 314 | "(__coil_temp = {left: " eval_expr(lhs) "}" 315 | ", __coil_temp.left[Meta.as_bool]() === false ? __coil_temp.left" 316 | " : (__coil_temp.right = " eval_expr(rhs) ", __coil_temp.right[Meta.as_bool]() === true) " 317 | " ? __coil_temp.right : __coil_temp.right)" 318 | ) 319 | 320 | def eval_or({lhs, rhs}) = str( 321 | "(__coil_temp = {left: " eval_expr(lhs) "}" 322 | ", __coil_temp.left[Meta.as_bool]() ? __coil_temp.left : " eval_expr(rhs) ")" 323 | ) 324 | 325 | def eval_unapplied_algebra_op({op}) = str("Algebra['" op "']") 326 | 327 | def eval_unapplied_equality_op({op}) = str("Meta['" op "']") 328 | 329 | def eval_snd_assign({lhs, rhs}) = str(eval_name_expr(lhs) " = " eval_expr(rhs)) 330 | 331 | def eval_expr(node) = node.at(:type).pipe(Map{ 332 | :algebra_op => eval_algebra_op 333 | :unapplied_algebra_op => eval_unapplied_algebra_op 334 | :unapplied_equality_op => eval_unapplied_equality_op 335 | :equality_op => eval_equality_op 336 | :and => eval_and 337 | :or => eval_or 338 | :instanceof => eval_instanceof 339 | :str => eval_str 340 | :dot => eval_dot 341 | :snd_assign => eval_snd_assign 342 | :keyword_lookup => eval_keyword_lookup 343 | :object_literal => eval_object_literal 344 | :regex_lit => eval_regex_lit 345 | :keyword => eval_keyword 346 | :prefix_exclusive_range => eval_prefix_exclusive_range 347 | :prefix_inclusive_range => eval_prefix_inclusive_range 348 | :id_lookup => eval_id_lookup 349 | :fn_call => eval_fn_call 350 | :num => eval_num 351 | :array => eval_array 352 | :double_equals => eval_double_equals 353 | :not_equals => eval_not_equals 354 | :not => eval_not 355 | :fn => eval_fn 356 | :meta_from_entries => eval_meta_from_entries 357 | :meta_create => eval_meta_create 358 | :spread => eval_spread 359 | :await => eval_await 360 | :yield => eval_yield 361 | :dot_yield => eval_dot_yield 362 | :paren_expr => eval_paren_expr 363 | :inclusive_range => eval_inclusive_range 364 | :exclusive_range => eval_exclusive_range 365 | :anon_fn => eval_anon_fn 366 | :anon_gen_fn => eval_anon_gen_fn 367 | :anon_body_fn => eval_anon_body_fn 368 | })(node) 369 | 370 | def eval_return({expr}) 371 | if expr 372 | return str("return " eval_expr(expr)) 373 | else 374 | return "return" 375 | end 376 | end 377 | 378 | def eval_protocol({name, methods}) 379 | if methods 380 | return str( 381 | "const " name " = Object.freeze({" 382 | methods:names 383 | .map(|method| str("\"" method:name "\": Symbol(\"" name ":" method:name "\")")) 384 | .join(",\n") 385 | "})" 386 | ) 387 | else 388 | return str("const " resolve_name(name) " = Symbol(\"" name "\")") 389 | end 390 | end 391 | 392 | def eval_for_loop({is_await? assign_expr iterable_expr body}) = 393 | str("for " 394 | (is_await? and "await ") 395 | " (let " eval_assign_expr(assign_expr) " of " eval_expr(iterable_expr) ") {\n" 396 | eval_nil_destructure_args([assign_expr]) ";\n" 397 | eval_ast(body) "\n" 398 | "}") 399 | 400 | def eval_id_assign({name, expr}) = str(resolve_name(name) " = " eval_expr(expr)) 401 | 402 | def eval_while_loop({test_expr, body}) = 403 | str("while ((" eval_expr(test_expr) ")[Meta.as_bool]()) {\n" eval_ast(body) "\n}") 404 | 405 | def eval_loop({body}) = str("while (true) {\n" eval_ast(body) "\n}") 406 | 407 | def eval_continue() = "continue" 408 | 409 | def eval_break() = "break" 410 | 411 | def get_deconstructed_obj_entry_name(node) = 412 | Map{:obj_reg_entry => :name 413 | :obj_entry_rename => :old_name} 414 | .at(node.at(:type)) 415 | .pipe(node) 416 | 417 | def get_deconstructed_array_entry_name(node) = 418 | Map{:id_assign => :name}.at(node.at(:type)).pipe(node) 419 | 420 | def eval_import_deconstruction_entry(node) = node.pipe(:type Map{ 421 | def :obj_reg_entry({name}) = resolve_name(name) 422 | def :obj_entry_rename({old_name, new_name}) = 423 | str(resolve_name(old_name) " as " resolve_name(new_name)) 424 | })(node) 425 | 426 | def eval_import_deconstruction_expr({entries}) = 427 | str("{" entries.map(eval_import_deconstruction_entry).join(", ") "}") 428 | 429 | def eval_import_assign_exprs(node) = node.pipe(:type Map{ 430 | :id_assign => eval_id_assign_name 431 | :object_deconstruction => eval_import_deconstruction_expr 432 | :assign_all_as => eval_assign_all_as 433 | })(node) 434 | 435 | def eval_import({assign_expr, path}) = 436 | str("import " eval_import_assign_exprs(assign_expr) " from \"" path:value:slice(1, -1) "\"") 437 | 438 | def eval_export({statement}) = str("export " eval_statement(statement)) 439 | 440 | def eval_export_default({expr}) = str("export default " eval_expr(expr)) 441 | 442 | def eval_direct_import({path}) = str("import " path) 443 | 444 | def eval_statement(node) 445 | let eval_fn = node.at(:type).pipe(Map{ 446 | :if => eval_if 447 | :direct_import => eval_direct_import 448 | :import => eval_import 449 | :export => eval_export 450 | :export_default => eval_export_default 451 | :let => eval_let 452 | :if_let => eval_if_let 453 | :return => eval_return 454 | :protocol_def => eval_protocol 455 | :for_loop => eval_for_loop 456 | :id_assign => eval_id_assign 457 | :while_loop => eval_while_loop 458 | :loop => eval_loop 459 | :while_let_loop => eval_while_let_loop 460 | :continue => eval_continue 461 | :break => eval_break 462 | }) 463 | 464 | return (eval_fn or eval_expr)(node) + ";" 465 | end 466 | 467 | def eval_ast(ast) = 468 | str("let __coil_temp;\n" ast.map(eval_statement).join("\n")) 469 | 470 | export default eval_ast 471 | -------------------------------------------------------------------------------- /compiler/src/parser.coil: -------------------------------------------------------------------------------- 1 | import {ParseError} from "./parse_error.mjs" 2 | 3 | def expect_token!(tokens, kw) 4 | if tokens.first().at(:type) != kw 5 | raise!(ParseError[kw, tokens.first()]) 6 | else 7 | return tokens 8 | end 9 | end 10 | 11 | def verify_exists!(expr, parser) 12 | if expr.nil?() 13 | parser.log() 14 | panic!("Parser Failed") 15 | else 16 | return expr 17 | end 18 | end 19 | 20 | -- PARSER MACHINE IMPL 21 | 22 | protocol parse 23 | 24 | def line_and_col({line, col}) = {line, col} 25 | 26 | def Init(@expr) end 27 | def Init:prototype.parse([_expr tokens]) = 28 | [{...this:expr, pos: line_and_col(tokens.first())} tokens] 29 | 30 | def One(@kw, @as) end 31 | def One:prototype.parse([expr tokens]) 32 | let {value, type} = expect_token!(tokens this:kw).first() 33 | return [{...expr, this:as => value} tokens:slice(1)] 34 | end 35 | 36 | protocol can_parse? 37 | 38 | def Keyword:prototype.can_parse?([{type}]) = this == type 39 | 40 | def Set:prototype.can_parse?(tokens) = 41 | this.any?(|cond| cond.can_parse?(tokens)) 42 | 43 | def _.can_parse?([]) = true 44 | 45 | def Array:prototype.can_parse?(tokens) 46 | if this.len() > tokens.len() 47 | return false 48 | else 49 | return this.zip(tokens).all?(|[pattern token]| pattern.can_parse?([token])) 50 | end 51 | end 52 | 53 | def Optional(@parse_cond, @parse_fn, @as) end 54 | def Optional:prototype.parse([expr tokens]) 55 | if tokens.empty?() 56 | return [expr tokens] 57 | else if this:parse_cond.can_parse?(tokens) 58 | return Then[this:parse_fn, this:as].parse([expr tokens]) 59 | else 60 | return [expr tokens] 61 | end 62 | end 63 | 64 | def Function:prototype.parse([_expr tokens]) = this(tokens) 65 | 66 | def Chomp(...@kws) end 67 | def Chomp:prototype.parse([expr tokens]) 68 | let i = 0 69 | for kw of this:kws 70 | expect_token!(tokens:slice(i), kw) 71 | i = i + 1 72 | end 73 | return [expr, tokens:slice(i)] 74 | end 75 | 76 | def Then(@parser, @kw) end 77 | def Then:prototype.parse([expr tokens]) 78 | if let [new_expr new_tokens] = this:parser(tokens) 79 | if this:kw 80 | return [{...expr, this:kw => new_expr} new_tokens] 81 | else 82 | return [new_expr new_tokens] 83 | end 84 | else 85 | return [expr tokens] 86 | end 87 | end 88 | 89 | def FMap(@f) end 90 | def FMap:prototype.parse([expr tokens]) = [this:f(expr) tokens] 91 | 92 | def Until(@end_kw, @parser, @kw) end 93 | def Until:prototype.parse([expr tokens]) 94 | let exprs = [] 95 | while tokens.first().at(:type) != this:end_kw 96 | let [expr new_tokens] = verify_exists!(this:parser(tokens) this) 97 | exprs:push(expr) 98 | tokens = new_tokens 99 | end 100 | if this:kw 101 | return [{...expr this:kw => exprs} tokens] 102 | else 103 | return [exprs, tokens] 104 | end 105 | end 106 | 107 | def UntilEither(@set, @parser, @kw) end 108 | def UntilEither:prototype.parse([expr tokens]) 109 | let exprs = [] 110 | while !tokens.first().at(:type).pipe(this:set) 111 | let [expr new_tokens] = verify_exists!(this:parser(tokens) this) 112 | exprs:push(expr) 113 | tokens = new_tokens 114 | end 115 | return [{...expr, this:kw => exprs} tokens] 116 | end 117 | 118 | def Case(@parse_map, @kw) end 119 | def Case:prototype.parse([expr tokens]) 120 | if let [new_expr, new_tokens] = this:parse_map(tokens) 121 | if this:kw 122 | return [{...expr, this:kw => new_expr}, new_tokens] 123 | else 124 | return [new_expr new_tokens] 125 | end 126 | else 127 | console.log(this:tokens.first(), this:parse_map) 128 | panic!("Case Parse Failed") 129 | end 130 | end 131 | 132 | def Either(@set, @kw) end 133 | def Either:prototype.parse([expr tokens]) 134 | let op = verify_exists!(this:set(tokens.first().at(:type)), this:set) 135 | let [new_expr, rest] = [tokens.first(), tokens:slice(1)] 136 | return [{...expr this:kw => new_expr.at(:value)}, rest] 137 | end 138 | 139 | def Parser(...@instructions) end 140 | def Parser:prototype.invoke(tokens) = this.parse([nil tokens]) 141 | 142 | def AbortIf(@cond_fn) end 143 | 144 | def Parser:prototype.parse(result) 145 | for instruction of this:instructions 146 | if instruction instanceof AbortIf 147 | if instruction:cond_fn(result) 148 | return 149 | else 150 | continue 151 | end 152 | end 153 | result = instruction.parse(result) 154 | end 155 | return result 156 | end 157 | 158 | def ParseMap(@entries) end 159 | 160 | def ParseMap:prototype.(Record:keys) = 161 | this:entries.map(|[pattern _]| pattern).into(Set[]) 162 | 163 | def ParseMap:prototype.invoke(tokens, ...args) 164 | if tokens.empty?() 165 | return 166 | else 167 | for [pattern parser] of this:entries 168 | if pattern.can_parse?(tokens) 169 | return parser(tokens, ...args) 170 | end 171 | end 172 | end 173 | end 174 | 175 | let algebra_ops = Set[:mod :plus :minus :times :pow :div :lt :gt :lt_eq :gt_eq] 176 | 177 | def parse_dot(tokens, lhs) = Parser[ 178 | Init[{type: :dot, lhs}] 179 | Chomp[:dot] 180 | Then[parse_single_expr :rhs] 181 | ](tokens) 182 | 183 | def parse_keyword_lookup(tokens, lhs) = Parser[ 184 | AbortIf[not_adjacent?] 185 | Init[{type: :keyword_lookup, lhs}] 186 | One[:keyword :property] 187 | FMap[|{lhs, type, property, pos}| ({lhs, type, property: property:slice(1), pos})] 188 | ](tokens) 189 | 190 | def not_adjacent?([_expr tokens]) 191 | let current = tokens.first() 192 | let previous = tokens.at(-1) 193 | if current:line != previous:line 194 | return true 195 | else 196 | let end_of_prev_token = previous:col + previous:value:length 197 | return (current:col - end_of_prev_token) >= 1 198 | end 199 | end 200 | 201 | def parse_adjacent_expr(tokens) = Parser[ 202 | AbortIf[not_adjacent?] 203 | Then[parse_expr] 204 | ](tokens) 205 | 206 | def parse_inclusive_range(tokens lhs) = Parser[ 207 | AbortIf[not_adjacent?] 208 | Init[{type: :inclusive_range, lhs}] 209 | Chomp[:dot_dot :eq] 210 | Optional[SINGLE_EXPR_PARSE_MAP.keys() parse_adjacent_expr :rhs] 211 | ](tokens) 212 | 213 | def parse_exclusive_range(tokens lhs) = Parser[ 214 | AbortIf[not_adjacent?] 215 | Init[{type: :exclusive_range, lhs}] 216 | Chomp[:dot_dot] 217 | Optional[SINGLE_EXPR_PARSE_MAP.keys() parse_adjacent_expr :rhs] 218 | ](tokens) 219 | 220 | def parse_fn_call(tokens lhs) = Parser[ 221 | AbortIf[not_adjacent?] 222 | Init[{type: :fn_call, lhs}] 223 | Chomp[:open_p] 224 | Until[:close_p parse_expr :args] 225 | Chomp[:close_p] 226 | ](tokens) 227 | 228 | def parse_meta_from_entries(tokens lhs) = Parser[ 229 | AbortIf[not_adjacent?] 230 | Init[{type: :meta_from_entries, lhs}] 231 | Chomp[:open_b] 232 | Until[:close_b parse_record_entry :entries] 233 | Chomp[:close_b] 234 | ](tokens lhs) 235 | 236 | def parse_meta_create(tokens lhs) = Parser[ 237 | AbortIf[not_adjacent?] 238 | Init[{type: :meta_create, lhs}] 239 | Chomp[:open_sq] 240 | Until[:close_sq parse_expr :entries] 241 | Chomp[:close_sq] 242 | ](tokens lhs) 243 | 244 | def parse_snd_assign(tokens lhs) = Parser[ 245 | Init[{type: :snd_assign, lhs}] 246 | Chomp[:eq] 247 | Then[parse_expr :rhs] 248 | ](tokens) 249 | 250 | def parse_dot_yield(tokens lhs) = Parser[ 251 | Init[{type: :dot_yield, lhs}] 252 | Chomp[:dot :yield] 253 | ](tokens) 254 | 255 | let PARSE_SND_EXPR_STEP_MAP = ParseMap{ 256 | :open_p => parse_fn_call 257 | :open_b => parse_meta_from_entries 258 | :open_sq => parse_meta_create 259 | :keyword => parse_keyword_lookup 260 | [:dot :yield] => parse_dot_yield 261 | :dot => parse_dot 262 | [:dot_dot :eq] => parse_inclusive_range 263 | :dot_dot => parse_exclusive_range 264 | } 265 | 266 | def parse_snd_expr_step(tokens, lhs) = PARSE_SND_EXPR_STEP_MAP(tokens, lhs) 267 | 268 | def parse_snd_expr([lhs tokens]) 269 | while let [new_lhs rest] = parse_snd_expr_step(tokens, lhs) 270 | lhs = new_lhs 271 | tokens = rest 272 | end 273 | return [lhs tokens] 274 | end 275 | 276 | def parse_algebra_op(tokens lhs) = Parser[ 277 | Init[{type: :algebra_op, lhs}] 278 | Either[algebra_ops :op] 279 | Then[parse_1_2_expr :rhs] 280 | ](tokens) 281 | 282 | def parse_instanceof(tokens lhs) = Parser[ 283 | Init[{type: :instanceof, lhs}] 284 | Chomp[:instanceof] 285 | Then[parse_1_2_expr :rhs] 286 | ](tokens) 287 | 288 | def parse_third_expr_step(tokens, lhs) = ParseMap{ 289 | :eq => parse_snd_assign 290 | :instanceof => parse_instanceof 291 | algebra_ops => parse_algebra_op 292 | }(tokens, lhs) 293 | 294 | def parse_third_expr([lhs tokens]) 295 | while let [new_lhs rest] = parse_third_expr_step(tokens, lhs) 296 | lhs = new_lhs 297 | tokens = rest 298 | end 299 | return [lhs tokens] 300 | end 301 | 302 | let equality_ops = Set[:double_eq :not_eq] 303 | 304 | def parse_eq_op(tokens, lhs) = Parser[ 305 | Init[{type: :equality_op, lhs}] 306 | Either[equality_ops :op] 307 | Then[parse_1_2_3_expr :rhs] 308 | ](tokens) 309 | 310 | def parse_fourth_expr_step(tokens, lhs) = 311 | ParseMap{equality_ops => parse_eq_op}(tokens, lhs) 312 | 313 | def parse_fourth_expr([lhs tokens]) 314 | while let [new_lhs rest] = parse_fourth_expr_step(tokens, lhs) 315 | lhs = new_lhs 316 | tokens = rest 317 | end 318 | return [lhs tokens] 319 | end 320 | 321 | def parse_and(tokens lhs) = Parser[ 322 | Init[{type: :and, lhs}] 323 | Chomp[:and] 324 | Then[parse_1_2_3_4_expr :rhs] 325 | ](tokens) 326 | 327 | def parse_or(tokens lhs) = Parser[ 328 | Init[{type: :or, lhs}] 329 | Chomp[:or] 330 | Then[parse_1_2_3_4_expr :rhs] 331 | ](tokens) 332 | 333 | def parse_fifth_expr_step(tokens, lhs) = ParseMap{ 334 | :and => parse_and 335 | :or => parse_or 336 | }(tokens, lhs) 337 | 338 | def parse_fifth_expr([lhs tokens]) 339 | while let [new_lhs rest] = parse_fifth_expr_step(tokens, lhs) 340 | lhs = new_lhs 341 | tokens = rest 342 | end 343 | return [lhs tokens] 344 | end 345 | 346 | let parse_regex = Parser[ 347 | Init[{type: :regex_lit}] 348 | One[:regex_lit :value] 349 | ] 350 | 351 | let parse_str = Parser[ 352 | Init[{type: :str}] 353 | One[:string_lit :value] 354 | ] 355 | 356 | let valid_ids_in_all_contexts = Set[:id :from] 357 | 358 | let parse_id = Parser[ 359 | Init[{type: :id_lookup}] 360 | Either[Set[...valid_ids_in_all_contexts :import] :name] 361 | ] 362 | 363 | def parse_obj(tokens) = Parser[ 364 | Init[{type: :object_literal}] 365 | Chomp[:open_b] 366 | Until[:close_b parse_record_entry :entries] 367 | Chomp[:close_b] 368 | ](tokens) 369 | 370 | let parse_spread_assign = Parser[ 371 | Init[{type: :spread_assign}] 372 | Chomp[:dot_dot_dot] 373 | Either[valid_ids_in_all_contexts :name] 374 | ] 375 | 376 | let parse_assign_id = Parser[ 377 | Init[{type: :id_assign}] 378 | Either[valid_ids_in_all_contexts :name] 379 | ] 380 | 381 | def parse_assign_array(tokens) = Parser[ 382 | Init[{type: :array_deconstruction}] 383 | Chomp[:open_sq] 384 | Until[:close_sq parse_assign_expr :entries] 385 | Chomp[:close_sq] 386 | ](tokens) 387 | 388 | let parse_obj_entry_rename = Parser[ 389 | Init[{type: :obj_entry_rename}] 390 | Either[valid_ids_in_all_contexts :old_name] 391 | Chomp[:colon] 392 | Either[valid_ids_in_all_contexts :new_name] 393 | ] 394 | 395 | let parse_regular_obj_assign_entry = Parser[ 396 | Init[{type: :obj_reg_entry}] 397 | Either[valid_ids_in_all_contexts :name] 398 | ] 399 | 400 | def parse_obj_entry_destructure(tokens) = Parser[ 401 | Init[{type: :obj_assign_expr}] 402 | Either[valid_ids_in_all_contexts :property] 403 | Chomp[:colon] 404 | Then[parse_assign_expr :assign_expr] 405 | ](tokens) 406 | 407 | let parse_obj_assign_entry = ParseMap{ 408 | [:id :colon :id] => parse_obj_entry_rename 409 | [:id :colon] => parse_obj_entry_destructure 410 | :id => parse_regular_obj_assign_entry 411 | :dot_dot_dot => parse_spread_assign 412 | } 413 | 414 | let parse_assign_obj = Parser[ 415 | Init[{type: :object_deconstruction}] 416 | Chomp[:open_b] 417 | Until[:close_b parse_obj_assign_entry :entries] 418 | Chomp[:close_b] 419 | ] 420 | 421 | let parse_this_assign = Parser[ 422 | Init[{type: :this_assign}] 423 | Chomp[:at] 424 | Either[valid_ids_in_all_contexts :name] 425 | ] 426 | 427 | let parse_this_spread_assign = Parser[ 428 | Init[{type: :this_spread_assign}] 429 | Chomp[:dot_dot_dot :at] 430 | One[:id :name] 431 | ] 432 | 433 | let parse_assign_expr = ParseMap{ 434 | :id => parse_assign_id 435 | :open_sq => parse_assign_array 436 | :open_b => parse_assign_obj 437 | :at => parse_this_assign 438 | [:dot_dot_dot :at] => parse_this_spread_assign 439 | :dot_dot_dot => parse_spread_assign 440 | } 441 | 442 | def parse_paren_expr(tokens) = Parser[ 443 | Init[{type: :paren_expr}] 444 | Chomp[:open_p] 445 | Then[parse_expr :expr] 446 | Chomp[:close_p] 447 | ](tokens) 448 | 449 | def parse_yield(tokens) = Parser[ 450 | Init[{type: :yield}] 451 | Chomp[:yield] 452 | Optional[ 453 | :times 454 | |tokens| Parser[Init[{}] Chomp[:times]](tokens) 455 | :star?] 456 | Then[parse_expr :expr] 457 | ](tokens) 458 | 459 | def parse_await(tokens) = Parser[ 460 | Init[{type: :await}] 461 | Chomp[:await] 462 | Then[parse_expr :expr] 463 | ](tokens) 464 | 465 | let parse_num = Parser[Init[{type: :num}] One[:num :value]] 466 | 467 | def parse_array(tokens) = Parser[ 468 | Init[{type: :array}] 469 | Chomp[:open_sq] 470 | Until[:close_sq parse_expr :elements] 471 | Chomp[:close_sq] 472 | ](tokens) 473 | 474 | def parse_spread(tokens) = Parser[ 475 | Init[{type: :spread}] 476 | Chomp[:dot_dot_dot] 477 | Then[parse_expr :expr] 478 | ](tokens) 479 | 480 | def parse_not(tokens) = Parser[ 481 | Init[{type: :not}] 482 | Chomp[:bang] 483 | Then[parse_expr :expr] 484 | ](tokens) 485 | 486 | let parse_async_modifier = Parser[ 487 | Init[{}] 488 | Chomp[:async] 489 | ] 490 | 491 | let parse_gen_modifier = Parser[ 492 | AbortIf[not_adjacent?] 493 | Init[{}] 494 | Chomp[:times] 495 | ] 496 | 497 | def parse_fn_expr_body(tokens) = Parser[ 498 | Init[{type: :return}] 499 | Chomp[:eq] 500 | Then[parse_expr :expr] 501 | FMap[|node| [node]] 502 | ](tokens) 503 | 504 | def parse_args_def(tokens) = Parser[ 505 | AbortIf[not_adjacent?] 506 | Chomp[:open_p] 507 | Until[:close_p parse_assign_expr] 508 | Chomp[:close_p] 509 | ](tokens) 510 | 511 | def parse_name_expr(tokens) 512 | if let [expr tokens] = parse_single_expr(tokens) 513 | let parse_map = ParseMap{ 514 | :dot => parse_dot 515 | :keyword => parse_keyword_lookup 516 | } 517 | while let [new_expr new_tokens] = parse_map(tokens expr) 518 | expr = new_expr 519 | tokens = new_tokens 520 | end 521 | return [expr tokens] 522 | end 523 | end 524 | 525 | def parse_def(tokens) = Parser[ 526 | Init[{type: :fn}] 527 | Optional[:async parse_async_modifier :is_async?] 528 | Chomp[:def] 529 | Optional[:times parse_gen_modifier :generator?] 530 | Then[parse_name_expr :name_expr] 531 | Optional[:open_p parse_args_def :args] 532 | Case[ParseMap{ 533 | :eq => parse_fn_expr_body, 534 | _ => block() 535 | } :body] 536 | ](tokens) 537 | 538 | let parse_id_shorthand_record_entry = Parser[ 539 | Init[{type: :id_shorthand_record_entry}] 540 | One[:id :name] 541 | ] 542 | 543 | def parse_keyword_record_entry(tokens) = Parser[ 544 | Init[{type: :keyword_record_entry}] 545 | One[:id :name] 546 | Chomp[:colon] 547 | Then[parse_expr :expr] 548 | ](tokens) 549 | 550 | def parse_regular_record_entry(tokens) = Parser[ 551 | Init[{type: :regular_record_entry}] 552 | Then[parse_expr :key_expr] 553 | Chomp[:arrow] 554 | Then[parse_expr :value_expr] 555 | ](tokens) 556 | 557 | let parse_record_entry = ParseMap{ 558 | :dot_dot_dot => parse_spread 559 | [:id :colon] => parse_keyword_record_entry 560 | [:id :arrow] => parse_regular_record_entry 561 | :def => parse_def 562 | [:async :def] => parse_def 563 | [:id PARSE_SND_EXPR_STEP_MAP.keys()] => parse_regular_record_entry 564 | :id => parse_id_shorthand_record_entry 565 | _ => parse_regular_record_entry 566 | } 567 | 568 | def parse_prefix_inclusive_range(tokens) = Parser[ 569 | Init[{type: :prefix_inclusive_range}] 570 | Chomp[:dot_dot :eq] 571 | Then[parse_expr :expr] 572 | ](tokens) 573 | 574 | def parse_prefix_exclusive_range(tokens) = Parser[ 575 | Init[{type: :prefix_exclusive_range}] 576 | Chomp[:dot_dot] 577 | Then[parse_expr :expr] 578 | ](tokens) 579 | 580 | def parse_keyword(tokens) = Parser[ 581 | Init[{type: :keyword}] 582 | One[:keyword :value] 583 | FMap[|{type, value, pos}| ({type: type, value: value:slice(1), pos: pos})] 584 | ](tokens) 585 | 586 | def parse_anon_fn_body(tokens) = Parser[ 587 | Init[{type: :brace_body}] 588 | Chomp[:open_b] 589 | Until[:close_b parse_statement :body] 590 | Chomp[:close_b] 591 | ](tokens) 592 | 593 | def parse_anon_fn(tokens) = Parser[ 594 | Init[{type: :anon_fn}] 595 | Chomp[:pipe_bar] 596 | Until[:pipe_bar parse_assign_expr :args] 597 | Chomp[:pipe_bar] 598 | Then[ParseMap{:open_b => parse_anon_fn_body, _ => parse_expr} :return_node] 599 | ](tokens) 600 | 601 | def parse_anon_gen_fn(tokens) = Parser[ 602 | Init[{type: :anon_gen_fn}] 603 | Chomp[:times] 604 | Chomp[:pipe_bar] 605 | Until[:pipe_bar parse_assign_expr :args] 606 | Chomp[:pipe_bar] 607 | Then[ParseMap{:open_b => parse_anon_fn_body, _ => parse_expr} :return_node] 608 | ](tokens) 609 | 610 | let parse_unapplied_algebra_op = Parser[ 611 | Init[{type: :unapplied_algebra_op}] 612 | Either[algebra_ops :op] 613 | ] 614 | 615 | let parse_unapplied_equality_op = Parser[ 616 | Init[{type: :unapplied_equality_op}] 617 | Either[equality_ops :op] 618 | ] 619 | 620 | let SINGLE_EXPR_PARSE_MAP = ParseMap{ 621 | :string_lit => parse_str 622 | :regex_lit => parse_regex 623 | :keyword => parse_keyword 624 | :open_p => parse_paren_expr 625 | :await => parse_await 626 | :num => parse_num 627 | :open_sq => parse_array 628 | :dot_dot_dot => parse_spread 629 | :bang => parse_not 630 | :open_b => parse_obj 631 | :pipe_bar => parse_anon_fn 632 | :def => parse_def 633 | :yield => parse_yield 634 | [:times :pipe_bar] => parse_anon_gen_fn 635 | [:dot_dot :eq] => parse_prefix_inclusive_range 636 | :dot_dot => parse_prefix_exclusive_range 637 | Set[...valid_ids_in_all_contexts :import] => parse_id 638 | [:async :def] => parse_def 639 | equality_ops => parse_unapplied_equality_op 640 | algebra_ops => parse_unapplied_algebra_op 641 | } 642 | 643 | def parse_single_expr(tokens) = SINGLE_EXPR_PARSE_MAP(tokens) 644 | 645 | def parse_expr(tokens) = parse_fifth_expr(parse_fourth_expr(parse_third_expr(parse_snd_expr(parse_single_expr(tokens))))) 646 | 647 | def parse_1_2_expr(tokens) = parse_snd_expr(parse_single_expr(tokens)) 648 | 649 | def parse_1_2_3_expr(tokens) = parse_third_expr(parse_snd_expr(parse_single_expr(tokens))) 650 | 651 | def parse_1_2_3_4_expr(tokens) = parse_fourth_expr(parse_third_expr(parse_snd_expr(parse_single_expr(tokens)))) 652 | 653 | def parse_else_branch(tokens) = Parser[ 654 | Init[{type: :else}] 655 | Chomp[:else] 656 | UntilEither[Set[:else :end] parse_statement :body] 657 | ](tokens) 658 | 659 | def parse_else_if_branch(tokens) = Parser[ 660 | Init[{type: :else_if}] 661 | Chomp[:else :if] 662 | Then[parse_expr :expr] 663 | UntilEither[Set[:else :end] parse_statement :pass] 664 | Optional[:else parse_if_branch :fail] 665 | ](tokens) 666 | 667 | def parse_else_if_let_branch(tokens) = Parser[ 668 | Init[{type: :else_if_let}] 669 | Chomp[:else :if :let] 670 | Then[parse_assign_expr :assign_expr] 671 | Chomp[:eq] 672 | Then[parse_expr :expr] 673 | UntilEither[Set[:else :end] parse_statement :pass] 674 | Optional[:else parse_if_branch :fail] 675 | ](tokens) 676 | 677 | let parse_if_branch = ParseMap{ 678 | [:else :if :let] => parse_else_if_let_branch 679 | [:else :if] => parse_else_if_branch 680 | :else => parse_else_branch 681 | } 682 | 683 | def parse_if(tokens) = Parser[ 684 | Init[{type: :if}] 685 | Chomp[:if] 686 | Then[parse_expr :expr] 687 | UntilEither[Set[:else :end] parse_statement :pass] 688 | Optional[:else parse_if_branch :fail] 689 | Chomp[:end] 690 | ](tokens) 691 | 692 | let parse_let = Parser[ 693 | Init[{type: :let}] 694 | Chomp[:let] 695 | Then[parse_assign_expr :assign_expr] 696 | Chomp[:eq] 697 | Then[parse_expr :rhs] 698 | ] 699 | 700 | def parse_if_let(tokens) = Parser[ 701 | Init[{type: :if_let}] 702 | Chomp[:if :let] 703 | Then[parse_assign_expr :assign_expr] 704 | Chomp[:eq] 705 | Then[parse_expr :expr] 706 | UntilEither[Set[:else :end] parse_statement :pass] 707 | Optional[:else parse_if_branch :fail] 708 | Chomp[:end] 709 | ](tokens) 710 | 711 | let parse_protocol_methods = Parser[ 712 | Init[{type: :protocol_method}] 713 | Chomp[:open_b] 714 | Until[:close_b parse_id :names] 715 | Chomp[:close_b] 716 | ] 717 | 718 | let parse_protocol = Parser[ 719 | Init[{type: :protocol_def}] 720 | Chomp[:protocol] 721 | One[:id :name] 722 | Optional[:open_b parse_protocol_methods :methods] 723 | ] 724 | 725 | let parse_return = Parser[ 726 | Init[{type: :return}] 727 | Chomp[:return] 728 | Optional[SINGLE_EXPR_PARSE_MAP.keys() parse_expr :expr] 729 | ] 730 | 731 | let parse_await_modifier = Parser[ 732 | Init[{}] 733 | Chomp[:await] 734 | ] 735 | 736 | def parse_for_loop(tokens) = Parser[ 737 | Init[{type: :for_loop}] 738 | Chomp[:for] 739 | Optional[:await parse_await_modifier :is_await?] 740 | Then[parse_assign_expr :assign_expr] 741 | Chomp[:of] 742 | Then[parse_expr :iterable_expr] 743 | block(:body) 744 | ](tokens) 745 | 746 | def parse_loop(tokens) = Parser[ 747 | Init[{type: :loop}] 748 | Chomp[:loop] 749 | block(:body) 750 | ](tokens) 751 | 752 | def parse_while_loop(tokens) = Parser[ 753 | Init[{type: :while_loop}] 754 | Chomp[:while] 755 | Then[parse_expr :test_expr] 756 | block(:body) 757 | ](tokens) 758 | 759 | def parse_while_let_loop(tokens) = Parser[ 760 | Init[{type: :while_let_loop}] 761 | Chomp[:while :let] 762 | Then[parse_assign_expr :assign_expr] 763 | Chomp[:eq] 764 | Then[parse_expr :test_expr] 765 | block(:body) 766 | ](tokens) 767 | 768 | def parse_continue(tokens) = Parser[ 769 | Init[{type: :continue}] 770 | Chomp[:continue] 771 | ](tokens) 772 | 773 | def parse_break(tokens) = Parser[ 774 | Init[{type: :break}] 775 | Chomp[:break] 776 | ](tokens) 777 | 778 | def parse_catch(tokens) = Parser[ 779 | Init[{type: :catch}] 780 | Chomp[:catch] 781 | One[:id :name] 782 | block(:body) 783 | ](tokens) 784 | 785 | def parse_finally(tokens) = Parser[ 786 | Init[{type: :finally}] 787 | Chomp[:finally] 788 | block(:body) 789 | ](tokens) 790 | 791 | def parse_import(tokens) = Parser[ 792 | Init[{type: :import}] 793 | Chomp[:import] 794 | Then[parse_assign_expr :assign_expr] 795 | Chomp[:from] 796 | Then[parse_str :path] 797 | ](tokens) 798 | 799 | def parse_export(tokens) = Parser[ 800 | Init[{type: :export}] 801 | Chomp[:export] 802 | Then[parse_statement :statement] 803 | ](tokens) 804 | 805 | def parse_export_default(tokens) = Parser[ 806 | Init[{type: :export_default}] 807 | Chomp[:export :default] 808 | Then[parse_expr :expr] 809 | ](tokens) 810 | 811 | let parse_direct_import = Parser[ 812 | Init[{type: :direct_import}] 813 | Chomp[:import] 814 | One[:string_lit :path] 815 | ] 816 | 817 | def parse_statement(tokens) = ParseMap{ 818 | :let => parse_let 819 | :for => parse_for_loop 820 | :protocol => parse_protocol 821 | :return => parse_return 822 | :continue => parse_continue 823 | :break => parse_break 824 | :loop => parse_loop 825 | [:import :string_lit] => parse_direct_import 826 | :import => parse_import 827 | [:export :default] => parse_export_default 828 | :export => parse_export 829 | [:while :let] => parse_while_let_loop 830 | :while => parse_while_loop 831 | [:if :let] => parse_if_let 832 | :if => parse_if 833 | _ => parse_expr 834 | }(tokens) 835 | 836 | def block(name) = Parser[ 837 | Until[:end parse_statement name] 838 | Chomp[:end] 839 | ] 840 | 841 | def parse_tokens(tokens) 842 | let ast = [] 843 | while let [statement_or_expr, rest] = parse_statement(tokens) 844 | ast:push(statement_or_expr) 845 | tokens = rest 846 | end 847 | return ast 848 | end 849 | 850 | export default parse_tokens 851 | -------------------------------------------------------------------------------- /compiler/src/shared.coil: -------------------------------------------------------------------------------- 1 | export def CollectionView(@collection, @idx) end 2 | 3 | def CollectionView:prototype.(Collection:len) = 4 | this:collection.len() - this:idx 5 | 6 | def CollectionView:prototype.(Collection:empty?) = 7 | this.len() == 0 8 | 9 | def CollectionView:prototype.(Collection:at)(idx) = 10 | this:collection.at(this:idx + idx) 11 | 12 | def CollectionView:prototype.first = 13 | this:collection.at(this:idx) 14 | 15 | def CollectionView:prototype:slice(n) = 16 | CollectionView[this:collection, this:idx + n] 17 | 18 | def* CollectionView:prototype.(Symbol:iterator) 19 | for i of this:idx..this:collection.len() 20 | yield this:collection.i 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /compiler/src/std/algebra.mjs: -------------------------------------------------------------------------------- 1 | const Algebra = Object.freeze({ 2 | "+": Symbol("std/algebra/Algebra:+"), 3 | "-": Symbol("std/algebra/Algebra:-"), 4 | "/": Symbol("std/algebra/Algebra:/"), 5 | "*": Symbol("std/algebra/Algebra:*"), 6 | "**": Symbol("std/algebra/Algebra:**"), 7 | "%": Symbol("std/algebra/Algebra:%"), 8 | ">": Symbol("std/algebra/Algebra:>"), 9 | ">=": Symbol("std/algebra/Algebra:>="), 10 | "<": Symbol("std/algebra/Algebra:<"), 11 | "<=": Symbol("std/algebra/Algebra:<="), 12 | }); 13 | 14 | Number.prototype[Algebra["+"]] = function (other) { 15 | if (typeof other !== "number") throw new TypeError("Expected number"); 16 | return this + other; 17 | }; 18 | 19 | Number.prototype[Algebra["-"]] = function (other) { 20 | if (typeof other !== "number") throw new TypeError("Expected number"); 21 | return this - other; 22 | }; 23 | 24 | Number.prototype[Algebra["/"]] = function (other) { 25 | if (typeof other !== "number") throw new TypeError("Expected number"); 26 | return this / other; 27 | }; 28 | 29 | Number.prototype[Algebra["*"]] = function (other) { 30 | if (typeof other !== "number") throw new TypeError("Expected number"); 31 | return this * other; 32 | }; 33 | 34 | Number.prototype[Algebra["**"]] = function (other) { 35 | if (typeof other !== "number") throw new TypeError("Expected number"); 36 | return this ** other; 37 | }; 38 | 39 | Number.prototype[Algebra[">"]] = function (other) { 40 | if (typeof other !== "number") throw new TypeError("Expected number"); 41 | return this > other; 42 | }; 43 | 44 | Number.prototype[Algebra["<"]] = function (other) { 45 | if (typeof other !== "number") throw new TypeError("Expected number"); 46 | return this < other; 47 | }; 48 | 49 | Number.prototype[Algebra[">="]] = function (other) { 50 | if (typeof other !== "number") throw new TypeError("Expected number"); 51 | return this >= other; 52 | }; 53 | 54 | Number.prototype[Algebra["<="]] = function (other) { 55 | if (typeof other !== "number") throw new TypeError("Expected number"); 56 | return this <= other; 57 | }; 58 | 59 | Number.prototype[Algebra["%"]] = function (other) { 60 | if (typeof other !== "number") throw new TypeError("Expected number"); 61 | return this % other; 62 | }; 63 | 64 | BigInt.prototype[Algebra["+"]] = function (other) { 65 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 66 | return this + other; 67 | }; 68 | 69 | BigInt.prototype[Algebra["-"]] = function (other) { 70 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 71 | return this - other; 72 | }; 73 | 74 | BigInt.prototype[Algebra["/"]] = function (other) { 75 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 76 | return this / other; 77 | }; 78 | 79 | BigInt.prototype[Algebra["*"]] = function (other) { 80 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 81 | return this * other; 82 | }; 83 | 84 | BigInt.prototype[Algebra["**"]] = function (other) { 85 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 86 | return this ** other; 87 | }; 88 | 89 | BigInt.prototype[Algebra[">"]] = function (other) { 90 | if (typeof other !== "bigint") throw new TypeError("Expected bigint"); 91 | return this > other; 92 | }; 93 | 94 | BigInt.prototype[Algebra["<"]] = function (other) { 95 | if (typeof other !== "number") throw new TypeError("Expected number"); 96 | return this < other; 97 | }; 98 | 99 | BigInt.prototype[Algebra[">="]] = function (other) { 100 | if (typeof other !== "number") throw new TypeError("Expected number"); 101 | return this >= other; 102 | }; 103 | 104 | BigInt.prototype[Algebra["<="]] = function (other) { 105 | if (typeof other !== "number") throw new TypeError("Expected number"); 106 | return this <= other; 107 | }; 108 | 109 | BigInt.prototype[Algebra["%"]] = function (other) { 110 | if (typeof other !== "number") throw new TypeError("Expected number"); 111 | return this % other; 112 | }; 113 | 114 | Set.prototype[Algebra["+"]] = function (other) { 115 | return new Set(...this, ...other); 116 | }; 117 | 118 | Array.prototype[Algebra["+"]] = function (other) { 119 | return [...this, ...other]; 120 | }; 121 | 122 | String.prototype[Algebra["+"]] = function (other) { 123 | if (typeof other !== "string") throw new TypeError("Expected string!"); 124 | return this + other; 125 | }; 126 | 127 | String.prototype[Algebra["*"]] = function (other) { 128 | if (typeof other !== "number") throw new TypeError("Expected number!"); 129 | return this.repeat(other); 130 | }; 131 | 132 | String.prototype[Algebra["<"]] = function (str) { 133 | if (typeof str !== "string") throw new TypeError("Expected string!"); 134 | return this < str; 135 | }; 136 | 137 | String.prototype[Algebra["<="]] = function (str) { 138 | if (typeof str !== "string") throw new TypeError("Expected string!"); 139 | return this <= str; 140 | }; 141 | 142 | String.prototype[Algebra[">"]] = function (str) { 143 | if (typeof str !== "string") throw new TypeError("Expected string!"); 144 | return this > str; 145 | }; 146 | 147 | String.prototype[Algebra[">="]] = function (str) { 148 | if (typeof str !== "string") throw new TypeError("Expected string!"); 149 | return this >= str; 150 | }; 151 | 152 | export default Algebra; 153 | -------------------------------------------------------------------------------- /compiler/src/std/bool.mjs: -------------------------------------------------------------------------------- 1 | import { Nil } from "./globals.mjs"; 2 | 3 | const Bool = Object.freeze({ 4 | negate: Symbol("std/bool/Bool:negate"), 5 | }); 6 | 7 | Nil.prototype[Bool.negate] = function () { 8 | return true; 9 | }; 10 | 11 | Object.prototype[Bool.negate] = function () { 12 | return false; 13 | }; 14 | 15 | Boolean.prototype[Bool.negate] = function () { 16 | return !this; 17 | }; 18 | 19 | export default Bool; 20 | 21 | export const { negate } = Bool; 22 | -------------------------------------------------------------------------------- /compiler/src/std/collection.mjs: -------------------------------------------------------------------------------- 1 | import Meta from "./meta.mjs"; 2 | import { ObjectLiteral } from "./globals.mjs"; 3 | 4 | const Collection = Object.freeze({ 5 | at: Symbol("std/collection/Collection:at"), 6 | len: Symbol("std/collection/Collection:len"), 7 | "empty?": Symbol("std/collection/Collection:empty?"), 8 | "has?": Symbol("std/collection/Collection:has?"), 9 | "delete!": Symbol("std/collection/Collection:delete!"), 10 | delete: Symbol("std/collection/Collection:delete"), 11 | }); 12 | 13 | ObjectLiteral.prototype[Collection.delete] = function (...keys) { 14 | let out = new ObjectLiteral(this); 15 | for (let key of keys) delete out[key]; 16 | return out; 17 | }; 18 | 19 | ObjectLiteral.prototype[Collection["delete!"]] = function (...keys) { 20 | for (let key of keys) delete this[key]; 21 | return this; 22 | }; 23 | 24 | ObjectLiteral.prototype[Collection.at] = function (key) { 25 | return this[key]; 26 | }; 27 | 28 | ObjectLiteral.prototype[Collection.len] = function () { 29 | return Object.keys(this).length; 30 | }; 31 | 32 | ObjectLiteral.prototype[Collection["empty?"]] = function () { 33 | return this[Collection.len]() === 0; 34 | }; 35 | 36 | ObjectLiteral.prototype[Collection["has?"]] = function (key) { 37 | return key in this; 38 | }; 39 | 40 | Array.prototype[Collection.at] = function (idx) { 41 | if (typeof idx !== "number") throw new TypeError("Expected number"); 42 | return this.at(idx); 43 | }; 44 | 45 | Array.prototype[Collection.len] = function () { 46 | return this.length; 47 | }; 48 | 49 | Array.prototype[Collection["empty?"]] = function () { 50 | return this.length === 0; 51 | }; 52 | 53 | Array.prototype[Collection["has?"]] = function (value) { 54 | return this.some((elem) => elem[Meta["=="]](value)); 55 | }; 56 | 57 | Array.prototype[Collection["delete!"]] = function (...values) { 58 | for (let i = 0; i < this.length; i++) { 59 | if (values.some((val) => this[i][Meta["=="]](val))) { 60 | this.splice(i, 1); 61 | } 62 | } 63 | return this; 64 | }; 65 | 66 | Array.prototype[Collection.delete] = function (...values) { 67 | return this.filter((value) => !values.some((val) => val[Meta["=="]](value))); 68 | }; 69 | 70 | String.prototype[Collection.at] = function (idx) { 71 | return this.at(idx); 72 | }; 73 | 74 | String.prototype[Collection.len] = function () { 75 | return this.length; 76 | }; 77 | 78 | String.prototype[Collection["empty?"]] = function () { 79 | return this.length === 0; 80 | }; 81 | 82 | String.prototype[Collection["has?"]] = function (substring) { 83 | return this.includes(substring); 84 | }; 85 | 86 | Map.prototype[Collection.at] = function (key) { 87 | return this.get(key); 88 | }; 89 | 90 | Map.prototype[Collection.len] = function () { 91 | return this.size; 92 | }; 93 | 94 | Map.prototype[Collection["empty?"]] = function () { 95 | return this.size === 0; 96 | }; 97 | 98 | Map.prototype[Collection["has?"]] = function (key) { 99 | return this.has(key); 100 | }; 101 | 102 | Map.prototype[Collection["delete!"]] = function (...keys) { 103 | for (let key of keys) this.delete(key); 104 | return this; 105 | }; 106 | 107 | Map.prototype[Collection.delete] = function (...keys) { 108 | let out = new Map(this); 109 | for (let key of keys) out.delete(key); 110 | return out; 111 | }; 112 | 113 | Set.prototype[Collection.at] = function (value) { 114 | if (this.has(value)) { 115 | return value; 116 | } 117 | }; 118 | 119 | Set.prototype[Collection.len] = function () { 120 | return this.size; 121 | }; 122 | 123 | Set.prototype[Collection["empty?"]] = function () { 124 | return this.size === 0; 125 | }; 126 | 127 | Set.prototype[Collection["has?"]] = function (value) { 128 | return this.has(value); 129 | }; 130 | 131 | Set.prototype[Collection["delete!"]] = function (...values) { 132 | for (let value of values) this.delete(value); 133 | return this; 134 | }; 135 | 136 | Set.prototype[Collection.delete] = function (...values) { 137 | let out = new Set(this); 138 | for (let value of values) out.delete(value); 139 | return out; 140 | }; 141 | 142 | export default Collection; 143 | 144 | export const { 145 | at, 146 | len, 147 | "empty?": empty__q, 148 | "has?": has__q, 149 | "delete!": delete__b, 150 | delete: __delete__, 151 | } = Collection; 152 | -------------------------------------------------------------------------------- /compiler/src/std/globals.mjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | export class ObjectLiteral { 4 | constructor(entries) { 5 | Object.assign(this, Object.fromEntries(entries)); 6 | } 7 | *[Symbol.iterator]() { 8 | for (let key in this) { 9 | yield [key, this[key]]; 10 | } 11 | } 12 | } 13 | 14 | export class Nil { 15 | toString() { 16 | return ""; 17 | } 18 | *[Symbol.iterator]() {} 19 | } 20 | 21 | export let nil = new Nil(); 22 | 23 | export class Keyword { 24 | static cache = new Map(); 25 | static for(name) { 26 | if (this.cache.get(name)) { 27 | return Keyword.cache.get(name); 28 | } else { 29 | let kw = new Keyword(name); 30 | Keyword.cache.set(name, kw); 31 | return kw; 32 | } 33 | } 34 | constructor(value) { 35 | this.value = value; 36 | } 37 | [Symbol.toPrimitive]() { 38 | return this.value; 39 | } 40 | toString() { 41 | return this.value; 42 | } 43 | } 44 | 45 | export function dot(lhs, rhs) { 46 | let result = lhs[rhs]; 47 | if (typeof result === "function") { 48 | let fn = result.bind(lhs); 49 | for (let key in result) { 50 | fn[key] = result[key]?.bind(lhs); 51 | } 52 | return fn; 53 | } else { 54 | return result ?? nil; 55 | } 56 | } 57 | 58 | export function from_js(js_object) { 59 | if (js_object == null) { 60 | return nil; 61 | } else if (Object.getPrototypeOf(js_object) === Object.prototype) { 62 | let out = new ObjectLiteral([]); 63 | for (let key in js_object) { 64 | out[key] = from_js(js_object[key]); 65 | } 66 | return out; 67 | } else { 68 | return js_object; 69 | } 70 | } 71 | 72 | export function raise__b(error) { 73 | console.error(error.stack); 74 | throw error; 75 | } 76 | 77 | export function panic__b(...args) { 78 | throw new Error(str(...args)); 79 | } 80 | 81 | export function type_of(object) { 82 | return typeof object; 83 | } 84 | 85 | export function str(...strs) { 86 | return strs.join(""); 87 | } 88 | -------------------------------------------------------------------------------- /compiler/src/std/iter.mjs: -------------------------------------------------------------------------------- 1 | import Algebra from "./algebra.mjs"; 2 | import { ObjectLiteral } from "./globals.mjs"; 3 | import Meta from "./meta.mjs"; 4 | 5 | export function compose(...fns) { 6 | return (arg) => { 7 | let out = arg; 8 | for (let f of fns) { 9 | out = f[Meta.invoke](out); 10 | } 11 | return out ?? nil; 12 | }; 13 | } 14 | 15 | const Iter = Object.freeze({ 16 | take: Symbol("std/iter/Iter:take"), 17 | until: Symbol("std/iter/Iter:until"), 18 | skip: Symbol("std/iter/Iter:skip"), 19 | find: Symbol("std/iter/Iter:find"), 20 | find_map: Symbol("std/iter/Iter:find_map"), 21 | zip: Symbol("std/iter/Iter:zip"), 22 | reduce: Symbol("std/iter/Iter:reduce"), 23 | map: Symbol("std/iter/Iter:map"), 24 | flat_map: Symbol("std/iter/Iter:flat_map"), 25 | each: Symbol("std/iter/Iter:each"), 26 | filter: Symbol("std/iter/Iter:filter"), 27 | filter_map: Symbol("std/iter/Iter:filter_map"), 28 | reject: Symbol("std/iter/Iter:reject"), 29 | "all?": Symbol("std/iter/Iter:all?"), 30 | "any?": Symbol("std/iter/Iter:any?"), 31 | split: Symbol("std/iter/Iter:split"), 32 | compact: Symbol("std/iter/Iter:compact"), 33 | join: Symbol("std/iter/Iter:join"), 34 | into: Symbol("std/iter/into"), 35 | collect: Symbol("std/iter/collect"), 36 | count: Symbol("std/iter/count"), 37 | }); 38 | 39 | Object.prototype[Iter.take] = function* take(n) { 40 | let i = 0; 41 | for (let elem of this) { 42 | if (i++ == n) { 43 | break; 44 | } else { 45 | yield elem; 46 | } 47 | } 48 | }; 49 | 50 | Object.prototype[Iter.until] = function* (...fns) { 51 | let f = compose(...fns); 52 | for (let elem of this) { 53 | if (f(elem)[Meta.as_bool]()) { 54 | break; 55 | } else { 56 | yield elem; 57 | } 58 | } 59 | }; 60 | 61 | Object.prototype[Iter.skip] = function* (n) { 62 | let i = 0; 63 | for (let elem of this) { 64 | if (i++ < n) { 65 | continue; 66 | } else { 67 | yield elem; 68 | } 69 | } 70 | }; 71 | 72 | Object.prototype[Iter.find] = function (...fns) { 73 | let f = compose(...fns); 74 | for (let elem of this) { 75 | if (f(elem)[Meta.as_bool]()) { 76 | return elem; 77 | } 78 | } 79 | }; 80 | 81 | Object.prototype[Iter.find_map] = function (...fns) { 82 | let f = compose(...fns); 83 | for (let elem of this) { 84 | let val = f(elem); 85 | if (val[Meta.as_bool]()) { 86 | return val; 87 | } 88 | } 89 | }; 90 | 91 | Object.prototype[Iter.zip] = function* (...collections) { 92 | let generators = [this, ...collections].map((item) => 93 | item[Symbol.iterator]() 94 | ); 95 | while (true) { 96 | let gen_states = generators.map((state) => state.next()); 97 | if (gen_states.some((x) => x.done)) { 98 | break; 99 | } else { 100 | yield gen_states.map((x) => x.value); 101 | } 102 | } 103 | }; 104 | 105 | Object.prototype[Iter.reduce] = function (f, start) { 106 | let accumulator = start; 107 | for (let elem of this) { 108 | accumulator = f[Meta.invoke](accumulator, elem); 109 | } 110 | return accumulator; 111 | }; 112 | 113 | Object.prototype[Iter.map] = function* (...fns) { 114 | let f = compose(...fns); 115 | for (let elem of this) { 116 | yield f(elem); 117 | } 118 | }; 119 | 120 | Object.prototype[Iter.flat_map] = function* (...fns) { 121 | let f = compose(...fns); 122 | for (let elem of this) { 123 | yield* f(elem); 124 | } 125 | }; 126 | 127 | Object.prototype[Iter.each] = function (...fns) { 128 | let f = compose(...fns); 129 | for (let elem of this) { 130 | f(elem); 131 | } 132 | }; 133 | 134 | Object.prototype[Iter.filter] = function* (...fns) { 135 | let f = compose(...fns); 136 | for (let elem of this) { 137 | if (f(elem)[Meta.as_bool]()) { 138 | yield elem; 139 | } 140 | } 141 | }; 142 | 143 | Object.prototype[Iter.filter_map] = function* (...fns) { 144 | let f = compose(...fns); 145 | for (let elem of this) { 146 | let result = f(elem); 147 | if (result[Meta.as_bool]()) { 148 | yield result; 149 | } 150 | } 151 | }; 152 | 153 | Object.prototype[Iter.reject] = function* (...fns) { 154 | let f = compose(...fns); 155 | for (let elem of this) { 156 | if (!f(elem)[Meta.as_bool]()) { 157 | yield elem; 158 | } 159 | } 160 | }; 161 | 162 | Object.prototype[Iter["all?"]] = function (...fns) { 163 | let f = compose(...fns); 164 | for (let elem of this) { 165 | if (!f(elem)) { 166 | return false; 167 | } 168 | } 169 | return true; 170 | }; 171 | 172 | Object.prototype[Iter["any?"]] = function (...fns) { 173 | let f = compose(...fns); 174 | for (let elem of this) { 175 | if (f(elem)) { 176 | return true; 177 | } 178 | } 179 | return false; 180 | }; 181 | 182 | Object.prototype[Iter.split] = function* (...fns) { 183 | let f = compose(...fns); 184 | let chunk = []; 185 | for (let elem of this) { 186 | if (f(elem)) { 187 | yield chunk; 188 | chunk = []; 189 | } else { 190 | chunk.push(elem); 191 | } 192 | } 193 | yield chunk; 194 | }; 195 | 196 | Object.prototype[Iter.compact] = function* () { 197 | for (let elem of this) { 198 | if (elem[Meta["nil?"]]()) { 199 | continue; 200 | } else { 201 | yield elem; 202 | } 203 | } 204 | }; 205 | 206 | Object.prototype[Iter.join] = function (separator) { 207 | let iter = this[Symbol.iterator](); 208 | let out = iter.next().value; 209 | for (let elem of iter) { 210 | out = out[Algebra["+"]](separator)[Algebra["+"]](elem); 211 | } 212 | return out; 213 | }; 214 | 215 | Object.prototype[Iter.count] = function () { 216 | let count = 0; 217 | for (let _ of this) { 218 | count++; 219 | } 220 | return count; 221 | }; 222 | 223 | Object.prototype[Iter.into] = function (collector) { 224 | return collector[Iter.collect](this); 225 | }; 226 | 227 | Array.prototype[Iter.collect] = function (iterable) { 228 | return [...this, ...iterable]; 229 | }; 230 | 231 | Map.prototype[Iter.collect] = function (iterable) { 232 | return new Map([...this, ...iterable]); 233 | }; 234 | 235 | Set.prototype[Iter.collect] = function (iterable) { 236 | return new Set([...this, ...iterable]); 237 | }; 238 | 239 | String.prototype[Iter.collect] = function (iterable) { 240 | return this[Algebra["+"]]( 241 | iterable[reduce]((acc, cur) => acc[Algebra["+"]](cur), "") 242 | ); 243 | }; 244 | 245 | ObjectLiteral.prototype[Iter.collect] = function (entries) { 246 | return new ObjectLiteral([...this[Symbol.iterator](), ...entries]); 247 | }; 248 | 249 | export default Iter; 250 | 251 | export const { 252 | take, 253 | until, 254 | skip, 255 | find, 256 | find_map, 257 | zip, 258 | reduce, 259 | map, 260 | flat_map, 261 | each, 262 | filter, 263 | filter_map, 264 | reject, 265 | "all?": all__q, 266 | "any?": any__q, 267 | split, 268 | compact, 269 | join, 270 | into, 271 | consume, 272 | count, 273 | } = Iter; 274 | -------------------------------------------------------------------------------- /compiler/src/std/meta.mjs: -------------------------------------------------------------------------------- 1 | import { ObjectLiteral, Keyword, Nil, nil, str } from "./globals.mjs"; 2 | import { at } from "./collection.mjs"; 3 | 4 | const Meta = Object.freeze({ 5 | "nil?": Symbol("std/meta/Meta:nil?"), 6 | create: Symbol("std/meta/Meta:create"), 7 | from_entries: Symbol("std/meta/Meta:from_entries"), 8 | "==": Symbol("std/meta/Meta:=="), 9 | "!=": Symbol("std/meta/Meta:!="), 10 | "exists?": Symbol("std/meta/Meta:exists?"), 11 | log: Symbol("std/meta/Meta:log"), 12 | invoke: Symbol("std/meta/Meta:invoke"), 13 | pipe: Symbol("std/meta/Meta:pipe"), 14 | as_bool: Symbol("std/meta/Meta:as_bool"), 15 | as_num: Symbol("std/meta/Meta:as_num"), 16 | as_kw: Symbol("std/meta/Meta:as_kw"), 17 | "assert!": Symbol("std/meta/Meta:assert!"), 18 | "assert_eq!": Symbol("std/meta/Meta:assert_eq!"), 19 | "freeze!": Symbol("std/metaMeta:freeze"), 20 | }); 21 | 22 | Object.prototype[Meta["freeze!"]] = function () { 23 | return Object.freeze(this); 24 | }; 25 | 26 | Nil[Meta.create] = function () { 27 | throw new TypeError("Cannot create instance of Nil"); 28 | }; 29 | 30 | str.fmt = function (...args) { 31 | return (object) => { 32 | let out = ""; 33 | for (let arg of args) { 34 | if (typeof arg === "string") { 35 | out += arg; 36 | } else { 37 | out += arg[Meta.invoke](object); 38 | } 39 | } 40 | return out; 41 | }; 42 | }; 43 | 44 | String.prototype[Meta.as_kw] = function () { 45 | return Keyword.for(this); 46 | }; 47 | 48 | Object.prototype[Meta.log] = function (...args) { 49 | console.log(...args, this); 50 | return this; 51 | }; 52 | 53 | String.prototype[Meta.as_num] = function () { 54 | let result = Number(this); 55 | if (Number.isNaN(result)) throw new TypeError("Not a number"); 56 | return result; 57 | }; 58 | 59 | Number.prototype[Meta.as_num] = function () { 60 | return this; 61 | }; 62 | 63 | Nil.prototype[Meta.as_bool] = function () { 64 | return false; 65 | }; 66 | 67 | Boolean.prototype[Meta.as_bool] = function () { 68 | return this; 69 | }; 70 | 71 | Object.prototype[Meta.as_bool] = function () { 72 | return true; 73 | }; 74 | 75 | ObjectLiteral[Meta.from_entries] = function (entries) { 76 | return new ObjectLiteral(entries); 77 | }; 78 | 79 | Array[Meta.from_entries] = (entries) => entries; 80 | 81 | Nil.prototype[Meta["nil?"]] = function () { 82 | return true; 83 | }; 84 | 85 | Object.prototype[Meta["nil?"]] = function () { 86 | return false; 87 | }; 88 | 89 | Object.prototype[Meta["!="]] = function (other) { 90 | return !this[Meta["=="]](other); 91 | }; 92 | 93 | Boolean.prototype[Meta["=="]] = function (other) { 94 | return this.valueOf() === other.valueOf(); 95 | }; 96 | 97 | Nil.prototype[Meta["=="]] = function (other) { 98 | return this === other; 99 | }; 100 | 101 | Function.prototype[Meta["=="]] = function (other) { 102 | return this === other; 103 | }; 104 | 105 | Number.prototype[Meta["=="]] = function (other) { 106 | return this === other; 107 | }; 108 | 109 | String.prototype[Meta["=="]] = function (other) { 110 | return this === other; 111 | }; 112 | 113 | BigInt.prototype[Meta["=="]] = function (other) { 114 | return this === other; 115 | }; 116 | 117 | Keyword.prototype[Meta["=="]] = function (other) { 118 | return this === other; 119 | }; 120 | 121 | Set.prototype[Meta["=="]] = function (other) { 122 | if (!(other instanceof Set)) { 123 | return false; 124 | } else if (other.size !== this.size) { 125 | return false; 126 | } else { 127 | for (let value of this) { 128 | if (!other.has(value)) { 129 | return false; 130 | } 131 | } 132 | return true; 133 | } 134 | }; 135 | 136 | Array.prototype[Meta["=="]] = function (other) { 137 | if (!(other instanceof Array)) { 138 | return false; 139 | } else if (this.length !== other.length) { 140 | return false; 141 | } else { 142 | for (let i = 0; i < this.length; i++) { 143 | if (this[i][Meta["!="]](other[i])) { 144 | return false; 145 | } 146 | } 147 | return true; 148 | } 149 | }; 150 | 151 | Map.prototype[Meta["=="]] = function (other) { 152 | if (!(other instanceof Map)) { 153 | return false; 154 | } else if (other.size !== this.size) { 155 | return false; 156 | } else { 157 | for (let [key, value] of this) { 158 | if (other.get(key)[Meta["!="]](value)) { 159 | return false; 160 | } 161 | } 162 | return true; 163 | } 164 | }; 165 | 166 | ObjectLiteral.prototype[Meta["=="]] = function (other) { 167 | if (!(other instanceof ObjectLiteral)) { 168 | return false; 169 | } 170 | let my_keys = Object.keys(this); 171 | let your_keys = Object.keys(other); 172 | if (my_keys.length !== your_keys.length) { 173 | return false; 174 | } else { 175 | for (let key of my_keys) { 176 | if (this[key][Meta["!="]](other[key])) { 177 | return false; 178 | } 179 | } 180 | return true; 181 | } 182 | }; 183 | 184 | Object.prototype[Meta["exists?"]] = function () { 185 | return true; 186 | }; 187 | 188 | Nil.prototype[Meta["exists?"]] = function () { 189 | return false; 190 | }; 191 | 192 | Function.prototype[Meta.create] = function (args) { 193 | return Reflect.construct(this, args); 194 | }; 195 | 196 | Set[Meta.create] = function (elements) { 197 | return new Set(elements); 198 | }; 199 | 200 | Function.prototype[Meta.from_entries] = function (entries) { 201 | return Reflect.construct(this, [entries]); 202 | }; 203 | 204 | Object.prototype[Meta.pipe] = function pipe(...fns) { 205 | let result = this; 206 | for (let fn of fns) { 207 | result = fn[Meta.invoke](result); 208 | } 209 | return result; 210 | }; 211 | 212 | Function.prototype[Meta.invoke] = function (...args) { 213 | return this(...args) ?? nil; 214 | }; 215 | 216 | Set.prototype[Meta.invoke] = function (item) { 217 | return this.has(item) ?? nil; 218 | }; 219 | 220 | Map.prototype[Meta.invoke] = function (key) { 221 | return this.get(key) ?? nil; 222 | }; 223 | 224 | ObjectLiteral.prototype[Meta.invoke] = function (key) { 225 | return this[key] ?? nil; 226 | }; 227 | 228 | Array.prototype[Meta.invoke] = function (index) { 229 | return this.at(index) ?? nil; 230 | }; 231 | 232 | String.prototype[Meta.invoke] = function (collection) { 233 | return collection[at](this) ?? nil; 234 | }; 235 | 236 | Number.prototype[Meta.invoke] = function (collection) { 237 | return collection[at](this) ?? nil; 238 | }; 239 | 240 | Keyword.prototype[Meta.invoke] = function (collection) { 241 | if (collection[at]) return collection[at](this) ?? nil; 242 | // hmm.. not sure if we wanna allow this, really have to think about the purpose of Keywords in coil 243 | else return collection[this] ?? nil; 244 | }; 245 | 246 | class AssertionError extends Error {} 247 | 248 | Object.prototype[Meta["assert!"]] = function (msg, ...args) { 249 | if (!this[Meta.as_bool]()) { 250 | if (args.length > 0) console.log(...args); 251 | throw new AssertionError(msg); 252 | } 253 | return this; 254 | }; 255 | 256 | Object.prototype[Meta["assert_eq!"]] = function (other, msg, ...args) { 257 | if (!this[Meta["=="]](other)) { 258 | console.log(this, "not equal to", other, ...args); 259 | throw new AssertionError(msg); 260 | } 261 | return this; 262 | }; 263 | 264 | export default Meta; 265 | 266 | export const { 267 | "nil?": nil__q, 268 | create, 269 | from_entries, 270 | "exists?": exists__q, 271 | as_bool, 272 | log, 273 | invoke, 274 | pipe, 275 | as_num, 276 | as_kw, 277 | "assert!": assert__b, 278 | "assert_eq!": assert_eq__b, 279 | "freeze!": freeze__b, 280 | } = Meta; 281 | -------------------------------------------------------------------------------- /compiler/src/std/ordered_collection.mjs: -------------------------------------------------------------------------------- 1 | const OrderedCollection = Object.freeze({ 2 | first: Symbol("std/ordered_collection/OrderedCollection:first"), 3 | }); 4 | 5 | Array.prototype[OrderedCollection.first] = function () { 6 | return this.at(0); 7 | }; 8 | 9 | String.prototype[OrderedCollection.first] = function () { 10 | return this.at(0); 11 | }; 12 | 13 | Map.prototype[OrderedCollection.first] = function () { 14 | return this.entries().next().value; 15 | }; 16 | 17 | export default OrderedCollection; 18 | 19 | export const { first } = OrderedCollection; 20 | -------------------------------------------------------------------------------- /compiler/src/std/range.mjs: -------------------------------------------------------------------------------- 1 | import Meta from "./meta.mjs"; 2 | import Algebra from "./algebra.mjs"; 3 | 4 | export const inc = Symbol("std/range/inc"); 5 | 6 | Number.prototype[inc] = function () { 7 | return this + 1; 8 | }; 9 | 10 | BigInt.prototype[inc] = function () { 11 | return this + 1n; 12 | }; 13 | 14 | String.prototype[inc] = function () { 15 | if (this.length !== 1) 16 | throw new TypeError("Can't increment a string of more than 1 character"); 17 | return String.fromCharCode(this.charCodeAt(0) + 1); 18 | }; 19 | 20 | export class InclusiveRange { 21 | constructor(start, end) { 22 | this.start = start; 23 | this.end = end; 24 | } 25 | [Meta.invoke](value) { 26 | return value[Algebra[">="]](this.start) && value[Algebra["<="]](this.end); 27 | } 28 | *[Symbol.iterator]() { 29 | let i = this.start; 30 | while (i[Algebra["<="]](this.end)) { 31 | yield i; 32 | i = i[inc](); 33 | } 34 | } 35 | } 36 | 37 | export class ExclusiveRange { 38 | constructor(start, end) { 39 | this.start = start; 40 | this.end = end; 41 | } 42 | [Meta.invoke](value) { 43 | return value[Algebra[">="]](this.start) && value[Algebra["<"]](this.end); 44 | } 45 | *[Symbol.iterator]() { 46 | let i = this.start; 47 | while (i[Algebra["<"]](this.end)) { 48 | yield i; 49 | i = i[inc](); 50 | } 51 | } 52 | } 53 | 54 | export class InclusiveRangeNoMaximum { 55 | constructor(start) { 56 | this.start = start; 57 | } 58 | [Meta.invoke](value) { 59 | return value[Algebra[">="]](this.start); 60 | } 61 | } 62 | 63 | export class InclusiveRangeNoMinimum { 64 | constructor(end) { 65 | this.end = end; 66 | } 67 | [Meta.invoke](value) { 68 | return value[Algebra["<="]](this.end); 69 | } 70 | } 71 | 72 | export class ExclusiveRangeNoMaximum { 73 | constructor(start) { 74 | this.start = start; 75 | } 76 | [Meta.invoke](value) { 77 | return value[Algebra[">="]](this.start); 78 | } 79 | *[Symbol.iterator]() { 80 | let i = this.start; 81 | while (true) { 82 | yield i; 83 | i = i[inc](); 84 | } 85 | } 86 | } 87 | 88 | export class ExclusiveRangeNoMinimum { 89 | constructor(end) { 90 | this.end = end; 91 | } 92 | [Meta.invoke](value) { 93 | return value[Algebra["<"]](this.end); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /compiler/src/std/record.mjs: -------------------------------------------------------------------------------- 1 | import { ObjectLiteral } from "./globals.mjs"; 2 | 3 | const Record = Object.freeze({ 4 | keys: Symbol("std/record/Record:keys"), 5 | values: Symbol("std/record/Record:values"), 6 | set: Symbol("std/record/Record:set"), 7 | "set!": Symbol("std/record/Record:set!"), 8 | }); 9 | 10 | ObjectLiteral.prototype[Record.keys] = function () { 11 | return Object.keys(this); 12 | }; 13 | 14 | ObjectLiteral.prototype[Record.values] = function () { 15 | return Object.values(this); 16 | }; 17 | 18 | ObjectLiteral.prototype[Record.set] = function (key, value) { 19 | return new ObjectLiteral([...this, [key, value]]); 20 | }; 21 | 22 | ObjectLiteral.prototype[Record["set!"]] = function (key, value) { 23 | this[key] = value; 24 | return this; 25 | }; 26 | 27 | Map.prototype[Record.keys] = function () { 28 | return this.keys(); 29 | }; 30 | 31 | Map.prototype[Record.values] = function () { 32 | return this.values(); 33 | }; 34 | 35 | Map.prototype[Record.set] = function (key, value) { 36 | return new Map([...this, [key, value]]); 37 | }; 38 | 39 | Map.prototype[Record["set!"]] = function (key, value) { 40 | this.set(key, value); 41 | return this; 42 | }; 43 | 44 | export default Record; 45 | export const { keys, values, set, "set!": set__b } = Record; 46 | -------------------------------------------------------------------------------- /compiler/src/std/underscore.mjs: -------------------------------------------------------------------------------- 1 | import Meta from "./meta.mjs"; 2 | import Iter from "./iter.mjs"; 3 | import Collection from "./collection.mjs"; 4 | import OrderedSequence from "./ordered_collection.mjs"; 5 | import Algebra from "./algebra.mjs"; 6 | import Record from "./record.mjs"; 7 | import Bool from "./bool.mjs"; 8 | import { inc } from "./range.mjs"; 9 | import { dot } from "./globals.mjs"; 10 | 11 | export default class Underscore { 12 | constructor(transforms) { 13 | this.transforms = transforms; 14 | } 15 | 16 | insert(symbol, ...args) { 17 | return new Underscore([...this.transforms, { symbol, args }]); 18 | } 19 | 20 | [Meta.invoke](data) { 21 | let result = data; 22 | for (let { symbol, args } of this.transforms) { 23 | result = dot(result, symbol)[Meta.invoke](...args); 24 | } 25 | return result; 26 | } 27 | } 28 | 29 | for (let sym of [Meta, Iter, Collection, OrderedSequence, Algebra, Record, Bool] 30 | .flatMap(Object.values) 31 | .concat([inc])) { 32 | if (sym === Meta.invoke) { 33 | continue; 34 | } else { 35 | Underscore.prototype[sym] = function (...args) { 36 | return this.insert(sym, ...args); 37 | }; 38 | } 39 | } 40 | 41 | export let _ = new Underscore([]); 42 | -------------------------------------------------------------------------------- /compiler/src/tokenizer.coil: -------------------------------------------------------------------------------- 1 | def Tokenizer(@entries) end 2 | 3 | def pass() end 4 | def newline() end 5 | 6 | def Tokenizer:prototype.invoke(str) 7 | let tokens = [] 8 | let index = 0 9 | def rest_of_string() = str:slice(index) 10 | 11 | def scan(pattern) 12 | let result = rest_of_string().:match(pattern) 13 | if result.nil?() or result:index != 0 14 | return false 15 | else 16 | index = index + result.0.:length 17 | return result.0 18 | end 19 | end 20 | 21 | let line = 1 22 | let col = 1 23 | while rest_of_string() != "" 24 | let found = false 25 | for [pattern type] of this:entries 26 | if let value = scan(pattern) 27 | if type == newline 28 | line = line + 1 29 | col = 1 30 | else if type != pass 31 | tokens:push({ 32 | type: type, 33 | value: value, 34 | line: line, 35 | col: col 36 | }) 37 | col = col + value.len() 38 | else 39 | col = col + value.len() 40 | end 41 | found = true 42 | break 43 | end 44 | end 45 | if !found 46 | panic!("No token matched.") 47 | end 48 | end 49 | 50 | return tokens 51 | end 52 | 53 | let tokenize = Tokenizer{ 54 | /^\n/ => newline 55 | /^\s+/ => pass 56 | /^\#.*/ => pass 57 | /^\-\-.*/ => pass 58 | /^\,/ => pass 59 | /^\;/ => pass 60 | /^if\s/ => :if 61 | /^else\s/ => :else 62 | /^return\s/ => :return 63 | /^import\s/ => :import 64 | /^export\s/ => :export 65 | /^default\s/ => :default 66 | /^from\s/ => :from 67 | /^let\s/ => :let 68 | /^protocol\s/ => :protocol 69 | /^for\s/ => :for 70 | /^catch\s/ => :catch 71 | /^finally\s/ => :finally 72 | /^instanceof\s/ => :instanceof 73 | /^end\b/ => :end 74 | /^while\s/ => :while 75 | /^loop\s/ => :loop 76 | /^and\s/ => :and 77 | /^or\s/ => :or 78 | /^continue\s/ => :continue 79 | /^break\s/ => :break 80 | /^of\s/ => :of 81 | /^yield\b/ => :yield 82 | /^async\s/ => :async 83 | /^await\s/ => :await 84 | /^\=\>/ => :arrow 85 | /^\@/ => :at 86 | /^\=\=/ => :double_eq 87 | /^\!\=/ => :not_eq 88 | /^\!/ => :bang 89 | /^\=/ => :eq 90 | /^def\b/ => :def 91 | /^\{/ => :open_b 92 | /^\}/ => :close_b 93 | /^\(/ => :open_p 94 | /^\)/ => :close_p 95 | /^\|/ => :pipe_bar 96 | /^[\-\+]?(\d+\.)?\d+n/ => :bigint 97 | /^[\-\+]?(\d+\.)?\d+/ => :num 98 | /^\.\.\./ => :dot_dot_dot 99 | /^\.\./ => :dot_dot 100 | /^\./ => :dot 101 | /^\/.*\/[a-z]?/ => :regex_lit 102 | /^\>\=/ => :gt_eq 103 | /^\<\=/ => :lt_eq 104 | /^\>/ => :gt 105 | /^\ :lt 106 | /^\+/ => :plus 107 | /^\%/ => :mod 108 | /^\-/ => :minus 109 | /^\*\*/ => :pow 110 | /^\*/ => :times 111 | /^\// => :div 112 | /^\[/ => :open_sq 113 | /^\]/ => :close_sq 114 | /^\"([^\\\"]|\\.)*\"/s => :string_lit 115 | /^[a-zA-Z_\?\!\$0-9]+/ => :id 116 | /^\:[a-zA-Z_\?\!\$0-9]+/ => :keyword 117 | /^\:/ => :colon 118 | } 119 | 120 | export default tokenize 121 | -------------------------------------------------------------------------------- /compiler/test/algebra.coil: -------------------------------------------------------------------------------- 1 | import { assertEquals: assert_equals, assertThrows: assert_throws } from "https://deno.land/std@0.220.0/assert/mod.ts" 2 | 3 | let {test} = Deno 4 | 5 | test("1 + 1 == 2" || assert_equals(1 + 1, 2)) 6 | test("1 - 1 == 0" || assert_equals(1 - 1, 0)) 7 | test("10 / 2 == 5" || assert_equals(10 / 2, 5)) 8 | test("2 * 2 == 4" || assert_equals(2 * 2, 4)) 9 | test("4 ** 2 == 16" || assert_equals(4 ** 2, 16)) 10 | test("10 % 2 == 0" || assert_equals(10 % 2, 0)) 11 | test("5 > 3 == true" || assert_equals(5 > 3, true)) 12 | test("3 < 3 == false" || assert_equals(3 < 3, false)) 13 | test("3 <= 3 == true" || assert_equals(3 <= 3, true)) 14 | test("3 >= 3 == true" || assert_equals(3 >= 3, true)) 15 | -- type safety tests 16 | test("1 + \"2\" throws" || assert_throws(|| 1 + "2")) 17 | test("1 - \"2\" throws" || assert_throws(|| 1 - "2")) 18 | test("1 / \"2\" throws" || assert_throws(|| 1 / "2")) 19 | test("1 * \"2\" throws" || assert_throws(|| 1 * "2")) 20 | test("1 ** \"2\" throws" || assert_throws(|| 1 ** "2")) 21 | test("1 % \"2\" throws" || assert_throws(|| 1 % "2")) 22 | test("1 > \"2\" throws" || assert_throws(|| 1 > "2")) 23 | test("1 < \"2\" throws" || assert_throws(|| 1 < "2")) 24 | test("1 >= \"2\" throws" || assert_throws(|| 1 >= "2")) 25 | test("1 <= \"2\" throws" || assert_throws(|| 1 <= "2")) 26 | -------------------------------------------------------------------------------- /compiler/test/collection.coil: -------------------------------------------------------------------------------- 1 | import { assertEquals: assert_equals, assertThrows: assert_throws } from "https://deno.land/std@0.220.0/assert/mod.ts" 2 | 3 | let {test} = Deno 4 | 5 | test("{}.empty?() == true" || assert_equals({}.empty?() true)) 6 | test("[].empty?() == true" || assert_equals([].empty?() true)) 7 | test("Set[].empty?() == true" || assert_equals(Set[].empty?() true)) 8 | test("Map{}.empty?() == true" || assert_equals(Map{}.empty?() true)) 9 | test("{key: :value}.empty?() == false" || assert_equals({key: :value}.empty?() false)) 10 | test("[1].empty?() == false" || assert_equals([1].empty?() false)) 11 | test("Set[1].empty?() == false" || assert_equals(Set[1].empty?() false)) 12 | test("Map{key: :value}.empty?() == false" || assert_equals(Map{key: :value}.empty?() false)) 13 | test("[1].at(0) == 1" || assert_equals([1].at(0), 1)) 14 | test("Set[1].at(1) == 1" || assert_equals(Set[1].at(1), 1)) 15 | test("{key: :value}.at(:key) == :value" || assert_equals({key: :value}.at(:key), :value)) 16 | test("Map{key: :value}.at(:key) == :value" || assert_equals(Map{key: :value}.at(:key), :value)) 17 | test("[1 2 3].len() == 3" || assert_equals([1 2 3].len(), 3)) 18 | test("Set[1 2 3].len() == 3" || assert_equals(Set[1 2 3].len(), 3)) 19 | test("{key: :value}.len() == 1" || assert_equals({key: :value}.len(), 1)) 20 | test("Map{key: :value}.len() == 1" || assert_equals(Map{key: :value}.len(), 1)) 21 | test("[1].has?(1) == true" || assert_equals([1].has?(1), true)) 22 | test("Set[1].has?(1) == true" || assert_equals(Set[1].has?(1), true)) 23 | test("{key: :value}.has?(:key) == true" || assert_equals({key: :value}.has?(:key), true)) 24 | test("Map{key: :value}.has?(:key) == true" || assert_equals(Map{key: :value}.has?(:key), true)) 25 | test("[1 2].delete(1)" || { 26 | let original = [1 2] 27 | let deleted = original.delete(1) 28 | assert_equals(original, [1 2]) 29 | assert_equals(deleted, [2]) 30 | }) 31 | test("Set[1 2].delete(1)" || { 32 | let original = Set[1 2] 33 | let deleted = original.delete(1) 34 | assert_equals(original, Set[1 2]) 35 | assert_equals(deleted, Set[2]) 36 | }) 37 | test("{key: :value}.delete(:key)" || { 38 | let original = {key: :value} 39 | let deleted = original.delete(:key) 40 | assert_equals(original, {key: :value}) 41 | assert_equals(deleted, {}) 42 | }) 43 | test("Map{key: :value}.delete(:key)" || { 44 | let original = Map{key: :value} 45 | let deleted = original.delete(:key) 46 | assert_equals(original, Map{key: :value}) 47 | assert_equals(deleted, Map{}) 48 | }) 49 | --------------------------------------------------------------------------------