rip-lang 3.16.2 → 3.17.0-wip.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/dist/rip.js CHANGED
@@ -1925,6 +1925,16 @@ function __schemaFkName(m) { return ''; } // ditto
1925
1925
  `;
1926
1926
 
1927
1927
  // src/parser.js
1928
+ var __subLocsOn = false;
1929
+ var setSubLocs = (on) => {
1930
+ __subLocsOn = on;
1931
+ };
1932
+ var __sub = (node, subLocs) => {
1933
+ if (subLocs && Array.isArray(node))
1934
+ Object.defineProperty(node, "subLocs", { value: subLocs, enumerable: false, configurable: true, writable: true });
1935
+ return node;
1936
+ };
1937
+ var __spl = (child) => child && child.subLocs ? child.subLocs : Array.isArray(child) ? child.map(() => null) : [];
1928
1938
  var parserInstance = {
1929
1939
  symbolIds: { $accept: 0, $end: 1, error: 2, Root: 3, Body: 4, Line: 5, TERMINATOR: 6, Expression: 7, ExpressionLine: 8, Statement: 9, Return: 10, STATEMENT: 11, Import: 12, Export: 13, Value: 14, Code: 15, Operation: 16, Assign: 17, ReactiveAssign: 18, ComputedAssign: 19, ReadonlyAssign: 20, Effect: 21, Gate: 22, If: 23, Try: 24, While: 25, For: 26, Switch: 27, Class: 28, Component: 29, Render: 30, Throw: 31, Yield: 32, Def: 33, Enum: 34, Schema: 35, CodeLine: 36, OperationLine: 37, Assignable: 38, Literal: 39, Parenthetical: 40, Range: 41, Invocation: 42, DoIife: 43, This: 44, Super: 45, MetaProperty: 46, MapLiteral: 47, Atom: 48, JS: 49, Regex: 50, UNDEFINED: 51, NULL: 52, BOOL: 53, INFINITY: 54, NAN: 55, SYMBOL: 56, NUMBER: 57, String: 58, Identifier: 59, IDENTIFIER: 60, Property: 61, PROPERTY: 62, STRING: 63, STRING_START: 64, Interpolations: 65, STRING_END: 66, InterpolationChunk: 67, INTERPOLATION_START: 68, INTERPOLATION_END: 69, INDENT: 70, OUTDENT: 71, REGEX: 72, REGEX_START: 73, REGEX_END: 74, RegexWithIndex: 75, ",": 76, "=": 77, REACTIVE_ASSIGN: 78, COMPUTED_ASSIGN: 79, Block: 80, READONLY_ASSIGN: 81, GATE: 82, EFFECT: 83, SimpleAssignable: 84, Array: 85, Object: 86, Subjectable: 87, ThisProperty: 88, ".": 89, "?.": 90, INDEX_START: 91, INDEX_END: 92, Slice: 93, PICK_START: 94, PickList: 95, OptComma: 96, PICK_END: 97, OPTPICK_START: 98, ES6_OPTIONAL_INDEX: 99, "{": 100, ObjAssignable: 101, ":": 102, FOR: 103, ForVariables: 104, FOROF: 105, "}": 106, WHEN: 107, OWN: 108, AssignList: 109, AssignObj: 110, ObjRestValue: 111, SimpleObjAssignable: 112, "[": 113, "]": 114, "@": 115, "...": 116, ObjSpreadExpr: 117, SUPER: 118, Arguments: 119, DYNAMIC_IMPORT: 120, MAP_START: 121, MapAssignList: 122, MAP_END: 123, MapAssignObj: 124, MapAssignable: 125, PickItem: 126, PickKey: 127, Elisions: 128, ArgElisionList: 129, OptElisions: 130, ArgElision: 131, Arg: 132, Elision: 133, RangeDots: 134, "..": 135, DEF: 136, CALL_START: 137, ParamList: 138, CALL_END: 139, PARAM_START: 140, PARAM_END: 141, ArrowKind: 142, "->": 143, "=>": 144, Param: 145, ParamVar: 146, Splat: 147, ES6_OPTIONAL_CALL: 148, ArgList: 149, SimpleArgs: 150, THIS: 151, NEW_TARGET: 152, IMPORT_META: 153, "(": 154, ")": 155, RETURN: 156, THROW: 157, YIELD: 158, FROM: 159, IfBlock: 160, IF: 161, IfElseTail: 162, ELSE: 163, UnlessBlock: 164, UNLESS: 165, POST_IF: 166, POST_UNLESS: 167, TRY: 168, Catch: 169, FINALLY: 170, CATCH: 171, SWITCH: 172, Cases: 173, When: 174, LEADING_WHEN: 175, WhileSource: 176, WHILE: 177, UNTIL: 178, Loop: 179, LOOP: 180, FORIN: 181, BY: 182, FORAS: 183, AWAIT: 184, FORASAWAIT: 185, ForValue: 186, ClassName: 187, CLASS: 188, EXTENDS: 189, ENUM: 190, SCHEMA: 191, SCHEMA_BODY: 192, COMPONENT: 193, ComponentBody: 194, ComponentLine: 195, OFFER: 196, ACCEPT: 197, RENDER: 198, IMPORT: 199, ImportDefaultSpecifier: 200, ImportNamespaceSpecifier: 201, ImportSpecifierList: 202, ImportSpecifier: 203, AS: 204, DEFAULT: 205, IMPORT_ALL: 206, EXPORT: 207, ExportSpecifierList: 208, EXPORT_ALL: 209, ExportSpecifier: 210, UNARY: 211, DO: 212, DO_IIFE: 213, UNARY_MATH: 214, "-": 215, "+": 216, "?": 217, PRESENCE: 218, "--": 219, "++": 220, MATH: 221, "**": 222, SHIFT: 223, COMPARE: 224, "&": 225, "^": 226, "|": 227, "||": 228, "??": 229, "&&": 230, RELATION: 231, TERNARY: 232, COMPOUND_ASSIGN: 233 },
1930
1940
  tokenNames: { 2: "error", 6: "TERMINATOR", 11: "STATEMENT", 49: "JS", 51: "UNDEFINED", 52: "NULL", 53: "BOOL", 54: "INFINITY", 55: "NAN", 56: "SYMBOL", 57: "NUMBER", 60: "IDENTIFIER", 62: "PROPERTY", 63: "STRING", 64: "STRING_START", 66: "STRING_END", 68: "INTERPOLATION_START", 69: "INTERPOLATION_END", 70: "INDENT", 71: "OUTDENT", 72: "REGEX", 73: "REGEX_START", 74: "REGEX_END", 76: ",", 77: "=", 78: "REACTIVE_ASSIGN", 79: "COMPUTED_ASSIGN", 81: "READONLY_ASSIGN", 82: "GATE", 83: "EFFECT", 89: ".", 90: "?.", 91: "INDEX_START", 92: "INDEX_END", 94: "PICK_START", 97: "PICK_END", 98: "OPTPICK_START", 99: "ES6_OPTIONAL_INDEX", 100: "{", 102: ":", 103: "FOR", 105: "FOROF", 106: "}", 107: "WHEN", 108: "OWN", 113: "[", 114: "]", 115: "@", 116: "...", 118: "SUPER", 120: "DYNAMIC_IMPORT", 121: "MAP_START", 123: "MAP_END", 135: "..", 136: "DEF", 137: "CALL_START", 139: "CALL_END", 140: "PARAM_START", 141: "PARAM_END", 143: "->", 144: "=>", 148: "ES6_OPTIONAL_CALL", 151: "THIS", 152: "NEW_TARGET", 153: "IMPORT_META", 154: "(", 155: ")", 156: "RETURN", 157: "THROW", 158: "YIELD", 159: "FROM", 161: "IF", 163: "ELSE", 165: "UNLESS", 166: "POST_IF", 167: "POST_UNLESS", 168: "TRY", 170: "FINALLY", 171: "CATCH", 172: "SWITCH", 175: "LEADING_WHEN", 177: "WHILE", 178: "UNTIL", 180: "LOOP", 181: "FORIN", 182: "BY", 183: "FORAS", 184: "AWAIT", 185: "FORASAWAIT", 188: "CLASS", 189: "EXTENDS", 190: "ENUM", 191: "SCHEMA", 192: "SCHEMA_BODY", 193: "COMPONENT", 196: "OFFER", 197: "ACCEPT", 198: "RENDER", 199: "IMPORT", 204: "AS", 205: "DEFAULT", 206: "IMPORT_ALL", 207: "EXPORT", 209: "EXPORT_ALL", 211: "UNARY", 212: "DO", 213: "DO_IIFE", 214: "UNARY_MATH", 215: "-", 216: "+", 217: "?", 218: "PRESENCE", 219: "--", 220: "++", 221: "MATH", 222: "**", 223: "SHIFT", 224: "COMPARE", 225: "&", 226: "^", 227: "|", 228: "||", 229: "??", 230: "&&", 231: "RELATION", 232: "TERNARY", 233: "COMPOUND_ASSIGN" },
@@ -1946,12 +1956,13 @@ function __schemaFkName(m) { return ''; } // ditto
1946
1956
  ruleTable: [0, 0, 3, 0, 3, 1, 4, 1, 4, 3, 4, 2, 5, 1, 5, 1, 5, 1, 9, 1, 9, 1, 9, 1, 9, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 48, 1, 48, 1, 59, 1, 61, 1, 58, 1, 58, 3, 65, 1, 65, 2, 67, 3, 67, 5, 67, 2, 67, 1, 50, 1, 50, 3, 75, 3, 75, 1, 17, 3, 17, 4, 17, 5, 18, 3, 18, 4, 18, 5, 19, 3, 19, 4, 19, 3, 20, 3, 20, 4, 20, 5, 22, 3, 21, 3, 21, 4, 21, 3, 21, 2, 21, 3, 21, 2, 38, 1, 38, 1, 38, 1, 87, 1, 87, 1, 84, 1, 84, 1, 84, 3, 84, 3, 84, 4, 84, 6, 84, 4, 84, 6, 84, 5, 84, 5, 84, 7, 84, 7, 84, 4, 84, 5, 84, 7, 86, 10, 86, 12, 86, 11, 86, 13, 86, 4, 109, 0, 109, 1, 109, 3, 109, 4, 109, 6, 110, 1, 110, 1, 110, 3, 110, 5, 110, 3, 110, 5, 112, 1, 112, 1, 112, 1, 101, 1, 101, 3, 101, 4, 101, 1, 111, 2, 111, 2, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 2, 117, 2, 117, 2, 117, 2, 117, 3, 117, 3, 117, 4, 117, 6, 117, 5, 117, 5, 117, 7, 117, 7, 47, 4, 122, 0, 122, 1, 122, 3, 122, 4, 122, 6, 124, 3, 124, 5, 124, 2, 95, 1, 95, 3, 95, 4, 95, 6, 126, 1, 126, 3, 126, 3, 126, 5, 127, 1, 127, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 85, 2, 85, 3, 85, 4, 129, 1, 129, 3, 129, 4, 129, 4, 129, 6, 131, 1, 131, 2, 130, 1, 130, 2, 128, 1, 128, 2, 133, 1, 133, 2, 134, 1, 134, 1, 41, 5, 93, 3, 93, 2, 93, 2, 93, 1, 33, 6, 33, 3, 15, 5, 15, 2, 36, 5, 36, 2, 142, 1, 142, 1, 138, 0, 138, 1, 138, 3, 138, 4, 138, 6, 145, 1, 145, 3, 145, 2, 145, 1, 146, 1, 146, 1, 146, 1, 146, 1, 147, 2, 42, 2, 42, 2, 42, 3, 42, 2, 42, 2, 119, 2, 119, 4, 149, 1, 149, 3, 149, 4, 149, 4, 149, 6, 132, 1, 132, 1, 132, 1, 132, 1, 150, 1, 150, 3, 44, 1, 44, 1, 88, 2, 45, 3, 45, 4, 45, 6, 46, 3, 46, 3, 80, 2, 80, 3, 40, 3, 40, 5, 96, 0, 96, 1, 10, 2, 10, 4, 10, 1, 31, 2, 31, 4, 32, 1, 32, 2, 32, 4, 32, 3, 160, 3, 160, 4, 162, 4, 162, 5, 162, 2, 164, 3, 164, 5, 23, 1, 23, 1, 23, 3, 23, 3, 23, 7, 23, 5, 23, 3, 23, 3, 24, 2, 24, 3, 24, 4, 24, 5, 169, 3, 169, 3, 169, 3, 169, 2, 27, 5, 27, 7, 27, 4, 27, 6, 173, 1, 173, 2, 174, 3, 174, 4, 176, 2, 176, 4, 176, 2, 176, 4, 25, 2, 25, 2, 25, 2, 25, 1, 179, 2, 179, 2, 179, 3, 26, 5, 26, 7, 26, 7, 26, 9, 26, 9, 26, 5, 26, 7, 26, 6, 26, 8, 26, 5, 26, 7, 26, 6, 26, 8, 26, 5, 26, 7, 26, 3, 26, 5, 26, 5, 26, 7, 26, 7, 26, 9, 26, 9, 26, 5, 26, 7, 26, 6, 26, 8, 26, 5, 26, 7, 26, 6, 26, 8, 26, 5, 26, 7, 26, 3, 26, 5, 186, 1, 186, 3, 104, 1, 104, 3, 187, 1, 187, 1, 28, 1, 28, 2, 28, 3, 28, 4, 28, 2, 28, 3, 28, 4, 28, 5, 34, 3, 35, 2, 29, 4, 29, 6, 194, 1, 194, 3, 194, 2, 195, 1, 195, 1, 195, 1, 195, 2, 195, 2, 30, 2, 30, 2, 12, 2, 12, 4, 12, 4, 12, 5, 12, 7, 12, 6, 12, 9, 202, 1, 202, 3, 202, 4, 202, 4, 202, 6, 203, 1, 203, 3, 203, 1, 203, 3, 200, 1, 201, 3, 13, 3, 13, 5, 13, 2, 13, 2, 13, 2, 13, 2, 13, 4, 13, 5, 13, 6, 13, 2, 13, 2, 13, 2, 13, 2, 13, 3, 13, 5, 13, 4, 13, 5, 13, 7, 208, 1, 208, 3, 208, 4, 208, 4, 208, 6, 210, 1, 210, 3, 210, 3, 210, 1, 210, 3, 37, 2, 37, 2, 37, 2, 16, 2, 16, 2, 16, 2, 16, 2, 16, 2, 16, 2, 16, 2, 16, 2, 16, 4, 16, 2, 16, 2, 16, 2, 16, 2, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 3, 16, 5, 16, 4, 43, 2],
1947
1957
  ruleActions: (rule, vals, locs, shared) => {
1948
1958
  const $ = vals;
1959
+ const $L = locs;
1949
1960
  const $0 = vals.length - 1;
1950
1961
  switch (rule) {
1951
1962
  case 1:
1952
- return ["program"];
1963
+ return __sub(["program"], __subLocsOn ? [null] : null);
1953
1964
  case 2:
1954
- return ["program", ...$[$0]];
1965
+ return __sub(["program", ...$[$0]], __subLocsOn ? [null, ...__spl($[$0])] : null);
1955
1966
  case 3:
1956
1967
  case 62:
1957
1968
  case 117:
@@ -1961,24 +1972,22 @@ function __schemaFkName(m) { return ''; } // ditto
1961
1972
  case 198:
1962
1973
  case 218:
1963
1974
  case 238:
1964
- case 247:
1965
1975
  case 299:
1966
1976
  case 350:
1967
1977
  case 366:
1968
1978
  case 383:
1969
1979
  case 412:
1970
- return [$[$0]];
1980
+ return __sub([$[$0]], __subLocsOn ? [$L[$0]] : null);
1971
1981
  case 4:
1972
1982
  case 118:
1973
1983
  case 156:
1974
1984
  case 163:
1975
1985
  case 219:
1976
1986
  case 239:
1977
- case 248:
1978
1987
  case 367:
1979
1988
  case 384:
1980
1989
  case 413:
1981
- return [...$[$0 - 2], $[$0]];
1990
+ return __sub([...$[$0 - 2], $[$0]], __subLocsOn ? [...__spl($[$0 - 2]), $L[$0]] : null);
1982
1991
  case 5:
1983
1992
  case 64:
1984
1993
  case 201:
@@ -2106,14 +2115,14 @@ function __schemaFkName(m) { return ''; } // ditto
2106
2115
  return "null";
2107
2116
  case 55:
2108
2117
  case 185:
2109
- return ["symbol", $[$0]];
2118
+ return __sub(["symbol", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2110
2119
  case 61:
2111
- return ["str", ...$[$0 - 1]];
2120
+ return __sub(["str", ...$[$0 - 1]], __subLocsOn ? [null, ...__spl($[$0 - 1])] : null);
2112
2121
  case 63:
2113
2122
  case 195:
2114
2123
  case 199:
2115
2124
  case 300:
2116
- return [...$[$0 - 1], $[$0]];
2125
+ return __sub([...$[$0 - 1], $[$0]], __subLocsOn ? [...__spl($[$0 - 1]), $L[$0]] : null);
2117
2126
  case 65:
2118
2127
  case 237:
2119
2128
  case 241:
@@ -2123,53 +2132,53 @@ function __schemaFkName(m) { return ''; } // ditto
2123
2132
  case 66:
2124
2133
  return "";
2125
2134
  case 69:
2126
- return ["regex", $[$0 - 1]];
2135
+ return __sub(["regex", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2127
2136
  case 70:
2128
- return ["regex-index", $[$0 - 2], $[$0]];
2137
+ return __sub(["regex-index", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2129
2138
  case 71:
2130
- return ["regex-index", $[$0], null];
2139
+ return __sub(["regex-index", $[$0], null], __subLocsOn ? [null, $L[$0], null] : null);
2131
2140
  case 72:
2132
2141
  case 125:
2133
- return ["=", $[$0 - 2], $[$0]];
2142
+ return __sub(["=", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2134
2143
  case 73:
2135
- return ["=", $[$0 - 3], $[$0]];
2144
+ return __sub(["=", $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0]] : null);
2136
2145
  case 74:
2137
2146
  case 126:
2138
- return ["=", $[$0 - 4], $[$0 - 1]];
2147
+ return __sub(["=", $[$0 - 4], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 1]] : null);
2139
2148
  case 75:
2140
- return ["state", $[$0 - 2], $[$0]];
2149
+ return __sub(["state", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2141
2150
  case 76:
2142
- return ["state", $[$0 - 3], $[$0]];
2151
+ return __sub(["state", $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0]] : null);
2143
2152
  case 77:
2144
- return ["state", $[$0 - 4], $[$0 - 1]];
2153
+ return __sub(["state", $[$0 - 4], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 1]] : null);
2145
2154
  case 78:
2146
2155
  case 80:
2147
- return ["computed", $[$0 - 2], $[$0]];
2156
+ return __sub(["computed", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2148
2157
  case 79:
2149
- return ["computed", $[$0 - 3], $[$0]];
2158
+ return __sub(["computed", $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0]] : null);
2150
2159
  case 81:
2151
- return ["readonly", $[$0 - 2], $[$0]];
2160
+ return __sub(["readonly", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2152
2161
  case 82:
2153
- return ["readonly", $[$0 - 3], $[$0]];
2162
+ return __sub(["readonly", $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0]] : null);
2154
2163
  case 83:
2155
- return ["readonly", $[$0 - 4], $[$0 - 1]];
2164
+ return __sub(["readonly", $[$0 - 4], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 1]] : null);
2156
2165
  case 84:
2157
- return ["gate", $[$0 - 2], $[$0]];
2166
+ return __sub(["gate", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2158
2167
  case 85:
2159
2168
  case 87:
2160
- return ["effect", $[$0 - 2], $[$0]];
2169
+ return __sub(["effect", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2161
2170
  case 86:
2162
- return ["effect", $[$0 - 3], $[$0]];
2171
+ return __sub(["effect", $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0]] : null);
2163
2172
  case 88:
2164
2173
  case 89:
2165
2174
  case 90:
2166
- return ["effect", null, $[$0]];
2175
+ return __sub(["effect", null, $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2167
2176
  case 98:
2168
2177
  case 145:
2169
- return [".", $[$0 - 2], $[$0]];
2178
+ return __sub([".", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2170
2179
  case 99:
2171
2180
  case 146:
2172
- return ["?.", $[$0 - 2], $[$0]];
2181
+ return __sub(["?.", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2173
2182
  case 100:
2174
2183
  case 102:
2175
2184
  case 147:
@@ -2180,22 +2189,22 @@ function __schemaFkName(m) { return ''; } // ditto
2180
2189
  return ["[]", $[$0 - 5], $[$0 - 2]];
2181
2190
  case 104:
2182
2191
  case 149:
2183
- return [".{}", $[$0 - 4], ...$[$0 - 2]];
2192
+ return __sub([".{}", $[$0 - 4], ...$[$0 - 2]], __subLocsOn ? [null, $L[$0 - 4], ...__spl($[$0 - 2])] : null);
2184
2193
  case 105:
2185
2194
  case 150:
2186
- return ["?.{}", $[$0 - 4], ...$[$0 - 2]];
2195
+ return __sub(["?.{}", $[$0 - 4], ...$[$0 - 2]], __subLocsOn ? [null, $L[$0 - 4], ...__spl($[$0 - 2])] : null);
2187
2196
  case 106:
2188
2197
  case 151:
2189
- return [".{}", $[$0 - 6], ...$[$0 - 3]];
2198
+ return __sub([".{}", $[$0 - 6], ...$[$0 - 3]], __subLocsOn ? [null, $L[$0 - 6], ...__spl($[$0 - 3])] : null);
2190
2199
  case 107:
2191
2200
  case 152:
2192
- return ["?.{}", $[$0 - 6], ...$[$0 - 3]];
2201
+ return __sub(["?.{}", $[$0 - 6], ...$[$0 - 3]], __subLocsOn ? [null, $L[$0 - 6], ...__spl($[$0 - 3])] : null);
2193
2202
  case 108:
2194
2203
  return [$[$0 - 1][0], $[$0 - 3], ...$[$0 - 1].slice(1)];
2195
2204
  case 109:
2196
- return ["optindex", $[$0 - 4], $[$0 - 1]];
2205
+ return __sub(["optindex", $[$0 - 4], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 1]] : null);
2197
2206
  case 110:
2198
- return ["optindex", $[$0 - 6], $[$0 - 2]];
2207
+ return __sub(["optindex", $[$0 - 6], $[$0 - 2]], __subLocsOn ? [null, $L[$0 - 6], $L[$0 - 2]] : null);
2199
2208
  case 111:
2200
2209
  return ["object-comprehension", $[$0 - 8], $[$0 - 6], [["for-of", $[$0 - 4], $[$0 - 2], false]], []];
2201
2210
  case 112:
@@ -2205,7 +2214,7 @@ function __schemaFkName(m) { return ''; } // ditto
2205
2214
  case 114:
2206
2215
  return ["object-comprehension", $[$0 - 11], $[$0 - 9], [["for-of", $[$0 - 6], $[$0 - 4], true]], [$[$0 - 2]]];
2207
2216
  case 115:
2208
- return ["object", ...$[$0 - 2]];
2217
+ return __sub(["object", ...$[$0 - 2]], __subLocsOn ? [null, ...__spl($[$0 - 2])] : null);
2209
2218
  case 116:
2210
2219
  case 154:
2211
2220
  case 196:
@@ -2219,7 +2228,7 @@ function __schemaFkName(m) { return ''; } // ditto
2219
2228
  case 240:
2220
2229
  case 385:
2221
2230
  case 414:
2222
- return [...$[$0 - 3], $[$0]];
2231
+ return __sub([...$[$0 - 3], $[$0]], __subLocsOn ? [...__spl($[$0 - 3]), $L[$0]] : null);
2223
2232
  case 120:
2224
2233
  case 158:
2225
2234
  case 165:
@@ -2227,59 +2236,59 @@ function __schemaFkName(m) { return ''; } // ditto
2227
2236
  case 242:
2228
2237
  case 387:
2229
2238
  case 416:
2230
- return [...$[$0 - 5], ...$[$0 - 2]];
2239
+ return __sub([...$[$0 - 5], ...$[$0 - 2]], __subLocsOn ? [...__spl($[$0 - 5]), ...__spl($[$0 - 2])] : null);
2231
2240
  case 121:
2232
- return [null, $[$0], $[$0]];
2241
+ return __sub([null, $[$0], $[$0]], __subLocsOn ? [null, $L[$0], $L[$0]] : null);
2233
2242
  case 123:
2234
2243
  case 159:
2235
- return [":", $[$0 - 2], $[$0]];
2244
+ return __sub([":", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2236
2245
  case 124:
2237
2246
  case 160:
2238
- return [":", $[$0 - 4], $[$0 - 1]];
2247
+ return __sub([":", $[$0 - 4], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 1]] : null);
2239
2248
  case 131:
2240
- return ["dynamicKey", $[$0 - 1]];
2249
+ return __sub(["dynamicKey", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2241
2250
  case 132:
2242
2251
  return ["[]", "this", $[$0 - 1]];
2243
2252
  case 134:
2244
2253
  case 135:
2245
2254
  case 161:
2246
2255
  case 230:
2247
- return ["...", $[$0]];
2256
+ return __sub(["...", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2248
2257
  case 141:
2249
2258
  case 234:
2250
- return ["super", ...$[$0]];
2259
+ return __sub(["super", ...$[$0]], __subLocsOn ? [null, ...__spl($[$0])] : null);
2251
2260
  case 142:
2252
2261
  case 143:
2253
2262
  case 144:
2254
2263
  case 232:
2255
2264
  case 235:
2256
- return [$[$0 - 1], ...$[$0]];
2265
+ return __sub([$[$0 - 1], ...$[$0]], __subLocsOn ? [$L[$0 - 1], ...__spl($[$0])] : null);
2257
2266
  case 153:
2258
- return ["map-literal", ...$[$0 - 2]];
2267
+ return __sub(["map-literal", ...$[$0 - 2]], __subLocsOn ? [null, ...__spl($[$0 - 2])] : null);
2259
2268
  case 166:
2260
- return [$[$0], $[$0], null];
2269
+ return __sub([$[$0], $[$0], null], __subLocsOn ? [$L[$0], $L[$0], null] : null);
2261
2270
  case 167:
2262
- return [$[$0 - 2], $[$0], null];
2271
+ return __sub([$[$0 - 2], $[$0], null], __subLocsOn ? [$L[$0 - 2], $L[$0], null] : null);
2263
2272
  case 168:
2264
- return [$[$0 - 2], $[$0 - 2], $[$0]];
2273
+ return __sub([$[$0 - 2], $[$0 - 2], $[$0]], __subLocsOn ? [$L[$0 - 2], $L[$0 - 2], $L[$0]] : null);
2265
2274
  case 169:
2266
- return [$[$0 - 4], $[$0 - 2], $[$0]];
2275
+ return __sub([$[$0 - 4], $[$0 - 2], $[$0]], __subLocsOn ? [$L[$0 - 4], $L[$0 - 2], $L[$0]] : null);
2267
2276
  case 186:
2268
- return ["array"];
2277
+ return __sub(["array"], __subLocsOn ? [null] : null);
2269
2278
  case 187:
2270
- return ["array", ...$[$0 - 1]];
2279
+ return __sub(["array", ...$[$0 - 1]], __subLocsOn ? [null, ...__spl($[$0 - 1])] : null);
2271
2280
  case 188:
2272
- return ["array", ...$[$0 - 2], ...$[$0 - 1]];
2281
+ return __sub(["array", ...$[$0 - 2], ...$[$0 - 1]], __subLocsOn ? [null, ...__spl($[$0 - 2]), ...__spl($[$0 - 1])] : null);
2273
2282
  case 190:
2274
- return [...$[$0 - 2], ...$[$0]];
2283
+ return __sub([...$[$0 - 2], ...$[$0]], __subLocsOn ? [...__spl($[$0 - 2]), ...__spl($[$0])] : null);
2275
2284
  case 191:
2276
- return [...$[$0 - 3], ...$[$0]];
2285
+ return __sub([...$[$0 - 3], ...$[$0]], __subLocsOn ? [...__spl($[$0 - 3]), ...__spl($[$0])] : null);
2277
2286
  case 192:
2278
- return [...$[$0 - 2], ...$[$0 - 1]];
2287
+ return __sub([...$[$0 - 2], ...$[$0 - 1]], __subLocsOn ? [...__spl($[$0 - 2]), ...__spl($[$0 - 1])] : null);
2279
2288
  case 193:
2280
- return [...$[$0 - 5], ...$[$0 - 4], ...$[$0 - 2], ...$[$0 - 1]];
2289
+ return __sub([...$[$0 - 5], ...$[$0 - 4], ...$[$0 - 2], ...$[$0 - 1]], __subLocsOn ? [...__spl($[$0 - 5]), ...__spl($[$0 - 4]), ...__spl($[$0 - 2]), ...__spl($[$0 - 1])] : null);
2281
2290
  case 197:
2282
- return [...$[$0]];
2291
+ return __sub([...$[$0]], __subLocsOn ? [...__spl($[$0])] : null);
2283
2292
  case 200:
2284
2293
  return null;
2285
2294
  case 202:
@@ -2288,88 +2297,92 @@ function __schemaFkName(m) { return ''; } // ditto
2288
2297
  case 246:
2289
2298
  return "...";
2290
2299
  case 204:
2291
- return [$[$0 - 2], $[$0 - 3], $[$0 - 1]];
2300
+ return __sub([$[$0 - 2], $[$0 - 3], $[$0 - 1]], __subLocsOn ? [$L[$0 - 2], $L[$0 - 3], $L[$0 - 1]] : null);
2292
2301
  case 205:
2293
2302
  case 440:
2294
2303
  case 442:
2295
2304
  case 443:
2296
2305
  case 456:
2297
2306
  case 458:
2298
- return [$[$0 - 1], $[$0 - 2], $[$0]];
2307
+ return __sub([$[$0 - 1], $[$0 - 2], $[$0]], __subLocsOn ? [$L[$0 - 1], $L[$0 - 2], $L[$0]] : null);
2299
2308
  case 206:
2300
- return [$[$0], $[$0 - 1], null];
2309
+ return __sub([$[$0], $[$0 - 1], null], __subLocsOn ? [$L[$0], $L[$0 - 1], null] : null);
2301
2310
  case 207:
2302
- return [$[$0 - 1], null, $[$0]];
2311
+ return __sub([$[$0 - 1], null, $[$0]], __subLocsOn ? [$L[$0 - 1], null, $L[$0]] : null);
2303
2312
  case 208:
2304
- return [$[$0], null, null];
2313
+ return __sub([$[$0], null, null], __subLocsOn ? [$L[$0], null, null] : null);
2305
2314
  case 209:
2306
- return ["def", $[$0 - 4], $[$0 - 2], $[$0]];
2315
+ return __sub(["def", $[$0 - 4], $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 2], $L[$0]] : null);
2307
2316
  case 210:
2308
2317
  return ["def", $[$0 - 1], [], $[$0]];
2309
2318
  case 211:
2310
2319
  case 213:
2311
- return [$[$0 - 1], $[$0 - 3], $[$0]];
2320
+ return __sub([$[$0 - 1], $[$0 - 3], $[$0]], __subLocsOn ? [$L[$0 - 1], $L[$0 - 3], $L[$0]] : null);
2312
2321
  case 212:
2313
2322
  case 214:
2314
2323
  return [$[$0 - 1], [], $[$0]];
2315
2324
  case 223:
2316
2325
  case 349:
2317
- return ["default", $[$0 - 2], $[$0]];
2326
+ return __sub(["default", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2318
2327
  case 224:
2319
- return ["rest", $[$0]];
2328
+ return __sub(["rest", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2320
2329
  case 225:
2321
- return ["expansion"];
2330
+ return __sub(["expansion"], __subLocsOn ? [null] : null);
2322
2331
  case 231:
2323
- return ["tagged-template", $[$0 - 1], $[$0]];
2332
+ return __sub(["tagged-template", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2324
2333
  case 233:
2325
- return ["optcall", $[$0 - 2], ...$[$0]];
2334
+ return __sub(["optcall", $[$0 - 2], ...$[$0]], __subLocsOn ? [null, $L[$0 - 2], ...__spl($[$0])] : null);
2335
+ case 247:
2336
+ return [$[$0]];
2337
+ case 248:
2338
+ return [...$[$0 - 2], $[$0]];
2326
2339
  case 249:
2327
2340
  case 250:
2328
2341
  return "this";
2329
2342
  case 251:
2330
- return [".", "this", $[$0]];
2343
+ return __sub([".", "this", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2331
2344
  case 252:
2332
- return [".", "super", $[$0]];
2345
+ return __sub([".", "super", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2333
2346
  case 253:
2334
2347
  return ["[]", "super", $[$0 - 1]];
2335
2348
  case 254:
2336
2349
  return ["[]", "super", $[$0 - 2]];
2337
2350
  case 255:
2338
- return [".", "new", $[$0]];
2351
+ return __sub([".", "new", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2339
2352
  case 256:
2340
- return [".", "import", $[$0]];
2353
+ return __sub([".", "import", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2341
2354
  case 257:
2342
- return ["block"];
2355
+ return __sub(["block"], __subLocsOn ? [null] : null);
2343
2356
  case 258:
2344
- return ["block", ...$[$0 - 1]];
2357
+ return __sub(["block", ...$[$0 - 1]], __subLocsOn ? [null, ...__spl($[$0 - 1])] : null);
2345
2358
  case 259:
2346
2359
  return $[$0 - 1].length === 1 ? (Array.isArray($[$0 - 1][0]) && ($[$0 - 1][0].parenthesized = true), $[$0 - 1][0]) : ["block", ...$[$0 - 1]];
2347
2360
  case 260:
2348
2361
  return $[$0 - 2].length === 1 ? (Array.isArray($[$0 - 2][0]) && ($[$0 - 2][0].parenthesized = true), $[$0 - 2][0]) : ["block", ...$[$0 - 2]];
2349
2362
  case 263:
2350
- return ["return", $[$0]];
2363
+ return __sub(["return", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2351
2364
  case 264:
2352
- return ["return", $[$0 - 1]];
2365
+ return __sub(["return", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2353
2366
  case 265:
2354
- return ["return"];
2367
+ return __sub(["return"], __subLocsOn ? [null] : null);
2355
2368
  case 266:
2356
- return ["throw", $[$0]];
2369
+ return __sub(["throw", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2357
2370
  case 267:
2358
- return ["throw", $[$0 - 1]];
2371
+ return __sub(["throw", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2359
2372
  case 268:
2360
- return ["yield"];
2373
+ return __sub(["yield"], __subLocsOn ? [null] : null);
2361
2374
  case 269:
2362
- return ["yield", $[$0]];
2375
+ return __sub(["yield", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2363
2376
  case 270:
2364
- return ["yield", $[$0 - 1]];
2377
+ return __sub(["yield", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2365
2378
  case 271:
2366
- return ["yield-from", $[$0]];
2379
+ return __sub(["yield-from", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2367
2380
  case 272:
2368
2381
  case 274:
2369
- return ["if", $[$0 - 1], $[$0]];
2382
+ return __sub(["if", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2370
2383
  case 273:
2371
2384
  case 275:
2372
- return ["if", $[$0 - 2], $[$0 - 1], $[$0]];
2385
+ return __sub(["if", $[$0 - 2], $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0 - 1], $L[$0]] : null);
2373
2386
  case 277:
2374
2387
  return ["if", ["!", $[$0 - 1]], $[$0]];
2375
2388
  case 278:
@@ -2378,45 +2391,45 @@ function __schemaFkName(m) { return ''; } // ditto
2378
2391
  case 282:
2379
2392
  return ["if", $[$0], [$[$0 - 2]]];
2380
2393
  case 283:
2381
- return ["?:", $[$0 - 4], $[$0 - 6], $[$0 - 1]];
2394
+ return __sub(["?:", $[$0 - 4], $[$0 - 6], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 6], $L[$0 - 1]] : null);
2382
2395
  case 284:
2383
- return ["?:", $[$0 - 2], $[$0 - 4], $[$0]];
2396
+ return __sub(["?:", $[$0 - 2], $[$0 - 4], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0 - 4], $L[$0]] : null);
2384
2397
  case 285:
2385
2398
  case 286:
2386
2399
  return ["if", ["!", $[$0]], [$[$0 - 2]]];
2387
2400
  case 287:
2388
- return ["try", $[$0]];
2401
+ return __sub(["try", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2389
2402
  case 288:
2390
- return ["try", $[$0 - 1], $[$0]];
2403
+ return __sub(["try", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2391
2404
  case 289:
2392
- return ["try", $[$0 - 2], $[$0]];
2405
+ return __sub(["try", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2393
2406
  case 290:
2394
- return ["try", $[$0 - 3], $[$0 - 2], $[$0]];
2407
+ return __sub(["try", $[$0 - 3], $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 2], $L[$0]] : null);
2395
2408
  case 291:
2396
2409
  case 292:
2397
2410
  case 293:
2398
2411
  case 422:
2399
2412
  case 425:
2400
2413
  case 427:
2401
- return [$[$0 - 1], $[$0]];
2414
+ return __sub([$[$0 - 1], $[$0]], __subLocsOn ? [$L[$0 - 1], $L[$0]] : null);
2402
2415
  case 294:
2403
- return [null, $[$0]];
2416
+ return __sub([null, $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2404
2417
  case 295:
2405
- return ["switch", $[$0 - 3], $[$0 - 1], null];
2418
+ return __sub(["switch", $[$0 - 3], $[$0 - 1], null], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null] : null);
2406
2419
  case 296:
2407
- return ["switch", $[$0 - 5], $[$0 - 3], $[$0 - 1]];
2420
+ return __sub(["switch", $[$0 - 5], $[$0 - 3], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], $L[$0 - 1]] : null);
2408
2421
  case 297:
2409
- return ["switch", null, $[$0 - 1], null];
2422
+ return __sub(["switch", null, $[$0 - 1], null], __subLocsOn ? [null, null, $L[$0 - 1], null] : null);
2410
2423
  case 298:
2411
- return ["switch", null, $[$0 - 3], $[$0 - 1]];
2424
+ return __sub(["switch", null, $[$0 - 3], $[$0 - 1]], __subLocsOn ? [null, null, $L[$0 - 3], $L[$0 - 1]] : null);
2412
2425
  case 301:
2413
- return ["when", $[$0 - 1], $[$0]];
2426
+ return __sub(["when", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2414
2427
  case 302:
2415
- return ["when", $[$0 - 2], $[$0 - 1]];
2428
+ return __sub(["when", $[$0 - 2], $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 2], $L[$0 - 1]] : null);
2416
2429
  case 303:
2417
- return ["while", $[$0]];
2430
+ return __sub(["while", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2418
2431
  case 304:
2419
- return ["while", $[$0 - 2], $[$0]];
2432
+ return __sub(["while", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2420
2433
  case 305:
2421
2434
  return ["while", ["!", $[$0]]];
2422
2435
  case 306:
@@ -2427,39 +2440,39 @@ function __schemaFkName(m) { return ''; } // ditto
2427
2440
  case 309:
2428
2441
  return $[$0].length === 2 ? [$[$0][0], $[$0][1], [$[$0 - 1]]] : [$[$0][0], $[$0][1], $[$0][2], [$[$0 - 1]]];
2429
2442
  case 311:
2430
- return ["loop", $[$0]];
2443
+ return __sub(["loop", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2431
2444
  case 312:
2432
2445
  return ["loop", [$[$0]]];
2433
2446
  case 313:
2434
- return ["loop-n", $[$0 - 1], $[$0]];
2447
+ return __sub(["loop-n", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2435
2448
  case 314:
2436
- return ["for-in", $[$0 - 3], $[$0 - 1], null, null, $[$0]];
2449
+ return __sub(["for-in", $[$0 - 3], $[$0 - 1], null, null, $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null, null, $L[$0]] : null);
2437
2450
  case 315:
2438
- return ["for-in", $[$0 - 5], $[$0 - 3], null, $[$0 - 1], $[$0]];
2451
+ return __sub(["for-in", $[$0 - 5], $[$0 - 3], null, $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], null, $L[$0 - 1], $L[$0]] : null);
2439
2452
  case 316:
2440
- return ["for-in", $[$0 - 5], $[$0 - 3], $[$0 - 1], null, $[$0]];
2453
+ return __sub(["for-in", $[$0 - 5], $[$0 - 3], $[$0 - 1], null, $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], $L[$0 - 1], null, $L[$0]] : null);
2441
2454
  case 317:
2442
- return ["for-in", $[$0 - 7], $[$0 - 5], $[$0 - 1], $[$0 - 3], $[$0]];
2455
+ return __sub(["for-in", $[$0 - 7], $[$0 - 5], $[$0 - 1], $[$0 - 3], $[$0]], __subLocsOn ? [null, $L[$0 - 7], $L[$0 - 5], $L[$0 - 1], $L[$0 - 3], $L[$0]] : null);
2443
2456
  case 318:
2444
- return ["for-in", $[$0 - 7], $[$0 - 5], $[$0 - 3], $[$0 - 1], $[$0]];
2457
+ return __sub(["for-in", $[$0 - 7], $[$0 - 5], $[$0 - 3], $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 7], $L[$0 - 5], $L[$0 - 3], $L[$0 - 1], $L[$0]] : null);
2445
2458
  case 319:
2446
- return ["for-of", $[$0 - 3], $[$0 - 1], false, null, $[$0]];
2459
+ return __sub(["for-of", $[$0 - 3], $[$0 - 1], false, null, $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null, null, $L[$0]] : null);
2447
2460
  case 320:
2448
- return ["for-of", $[$0 - 5], $[$0 - 3], false, $[$0 - 1], $[$0]];
2461
+ return __sub(["for-of", $[$0 - 5], $[$0 - 3], false, $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], null, $L[$0 - 1], $L[$0]] : null);
2449
2462
  case 321:
2450
- return ["for-of", $[$0 - 3], $[$0 - 1], true, null, $[$0]];
2463
+ return __sub(["for-of", $[$0 - 3], $[$0 - 1], true, null, $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null, null, $L[$0]] : null);
2451
2464
  case 322:
2452
- return ["for-of", $[$0 - 5], $[$0 - 3], true, $[$0 - 1], $[$0]];
2465
+ return __sub(["for-of", $[$0 - 5], $[$0 - 3], true, $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], null, $L[$0 - 1], $L[$0]] : null);
2453
2466
  case 323:
2454
- return ["for-as", $[$0 - 3], $[$0 - 1], false, null, $[$0]];
2467
+ return __sub(["for-as", $[$0 - 3], $[$0 - 1], false, null, $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null, null, $L[$0]] : null);
2455
2468
  case 324:
2456
- return ["for-as", $[$0 - 5], $[$0 - 3], false, $[$0 - 1], $[$0]];
2469
+ return __sub(["for-as", $[$0 - 5], $[$0 - 3], false, $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], null, $L[$0 - 1], $L[$0]] : null);
2457
2470
  case 325:
2458
2471
  case 327:
2459
- return ["for-as", $[$0 - 3], $[$0 - 1], true, null, $[$0]];
2472
+ return __sub(["for-as", $[$0 - 3], $[$0 - 1], true, null, $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], null, null, $L[$0]] : null);
2460
2473
  case 326:
2461
2474
  case 328:
2462
- return ["for-as", $[$0 - 5], $[$0 - 3], true, $[$0 - 1], $[$0]];
2475
+ return __sub(["for-as", $[$0 - 5], $[$0 - 3], true, $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 5], $L[$0 - 3], null, $L[$0 - 1], $L[$0]] : null);
2463
2476
  case 329:
2464
2477
  return ["for-in", [], $[$0 - 1], null, null, $[$0]];
2465
2478
  case 330:
@@ -2504,56 +2517,56 @@ function __schemaFkName(m) { return ''; } // ditto
2504
2517
  case 418:
2505
2518
  case 419:
2506
2519
  case 421:
2507
- return [$[$0 - 2], $[$0]];
2520
+ return __sub([$[$0 - 2], $[$0]], __subLocsOn ? [$L[$0 - 2], $L[$0]] : null);
2508
2521
  case 354:
2509
- return ["class", null, null];
2522
+ return __sub(["class", null, null], __subLocsOn ? [null, null, null] : null);
2510
2523
  case 355:
2511
- return ["class", null, null, $[$0]];
2524
+ return __sub(["class", null, null, $[$0]], __subLocsOn ? [null, null, null, $L[$0]] : null);
2512
2525
  case 356:
2513
- return ["class", null, $[$0]];
2526
+ return __sub(["class", null, $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2514
2527
  case 357:
2515
- return ["class", null, $[$0 - 1], $[$0]];
2528
+ return __sub(["class", null, $[$0 - 1], $[$0]], __subLocsOn ? [null, null, $L[$0 - 1], $L[$0]] : null);
2516
2529
  case 358:
2517
- return ["class", $[$0], null];
2530
+ return __sub(["class", $[$0], null], __subLocsOn ? [null, $L[$0], null] : null);
2518
2531
  case 359:
2519
- return ["class", $[$0 - 1], null, $[$0]];
2532
+ return __sub(["class", $[$0 - 1], null, $[$0]], __subLocsOn ? [null, $L[$0 - 1], null, $L[$0]] : null);
2520
2533
  case 360:
2521
- return ["class", $[$0 - 2], $[$0]];
2534
+ return __sub(["class", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2522
2535
  case 361:
2523
- return ["class", $[$0 - 3], $[$0 - 1], $[$0]];
2536
+ return __sub(["class", $[$0 - 3], $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 3], $L[$0 - 1], $L[$0]] : null);
2524
2537
  case 362:
2525
- return ["enum", $[$0 - 1], $[$0]];
2538
+ return __sub(["enum", $[$0 - 1], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0]] : null);
2526
2539
  case 363:
2527
- return ["schema", $[$0]];
2540
+ return __sub(["schema", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2528
2541
  case 364:
2529
2542
  return ["component", null, ["block", ...$[$0 - 1]]];
2530
2543
  case 365:
2531
2544
  return ["component", $[$0 - 3], ["block", ...$[$0 - 1]]];
2532
2545
  case 372:
2533
- return ["offer", $[$0]];
2546
+ return __sub(["offer", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2534
2547
  case 373:
2535
- return ["accept", $[$0]];
2548
+ return __sub(["accept", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2536
2549
  case 374:
2537
2550
  case 375:
2538
- return ["render", $[$0]];
2551
+ return __sub(["render", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2539
2552
  case 376:
2540
2553
  case 379:
2541
- return ["import", "{}", $[$0]];
2554
+ return __sub(["import", "{}", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2542
2555
  case 377:
2543
2556
  case 378:
2544
- return ["import", $[$0 - 2], $[$0]];
2557
+ return __sub(["import", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2545
2558
  case 380:
2546
- return ["import", $[$0 - 4], $[$0]];
2559
+ return __sub(["import", $[$0 - 4], $[$0]], __subLocsOn ? [null, $L[$0 - 4], $L[$0]] : null);
2547
2560
  case 381:
2548
- return ["import", $[$0 - 4], $[$0 - 2], $[$0]];
2561
+ return __sub(["import", $[$0 - 4], $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 2], $L[$0]] : null);
2549
2562
  case 382:
2550
- return ["import", $[$0 - 7], $[$0 - 4], $[$0]];
2563
+ return __sub(["import", $[$0 - 7], $[$0 - 4], $[$0]], __subLocsOn ? [null, $L[$0 - 7], $L[$0 - 4], $L[$0]] : null);
2551
2564
  case 393:
2552
- return ["*", $[$0]];
2565
+ return __sub(["*", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2553
2566
  case 394:
2554
- return ["export", "{}"];
2567
+ return __sub(["export", "{}"], __subLocsOn ? [null, null] : null);
2555
2568
  case 395:
2556
- return ["export", $[$0 - 2]];
2569
+ return __sub(["export", $[$0 - 2]], __subLocsOn ? [null, $L[$0 - 2]] : null);
2557
2570
  case 396:
2558
2571
  case 397:
2559
2572
  case 398:
@@ -2562,7 +2575,7 @@ function __schemaFkName(m) { return ''; } // ditto
2562
2575
  case 404:
2563
2576
  case 405:
2564
2577
  case 406:
2565
- return ["export", $[$0]];
2578
+ return __sub(["export", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2566
2579
  case 400:
2567
2580
  return ["export", ["=", $[$0 - 2], $[$0]]];
2568
2581
  case 401:
@@ -2570,71 +2583,71 @@ function __schemaFkName(m) { return ''; } // ditto
2570
2583
  case 402:
2571
2584
  return ["export", ["=", $[$0 - 4], $[$0 - 1]]];
2572
2585
  case 407:
2573
- return ["export-default", $[$0]];
2586
+ return __sub(["export-default", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2574
2587
  case 408:
2575
- return ["export-default", $[$0 - 1]];
2588
+ return __sub(["export-default", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2576
2589
  case 409:
2577
- return ["export-all", $[$0]];
2590
+ return __sub(["export-all", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2578
2591
  case 410:
2579
- return ["export-from", "{}", $[$0]];
2592
+ return __sub(["export-from", "{}", $[$0]], __subLocsOn ? [null, null, $L[$0]] : null);
2580
2593
  case 411:
2581
- return ["export-from", $[$0 - 4], $[$0]];
2594
+ return __sub(["export-from", $[$0 - 4], $[$0]], __subLocsOn ? [null, $L[$0 - 4], $L[$0]] : null);
2582
2595
  case 423:
2583
2596
  case 424:
2584
2597
  case 426:
2585
2598
  case 461:
2586
- return ["do-iife", $[$0]];
2599
+ return __sub(["do-iife", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2587
2600
  case 428:
2588
- return ["-", $[$0]];
2601
+ return __sub(["-", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2589
2602
  case 429:
2590
- return ["+", $[$0]];
2603
+ return __sub(["+", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2591
2604
  case 430:
2592
- return ["?", $[$0 - 1]];
2605
+ return __sub(["?", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2593
2606
  case 431:
2594
- return ["presence", $[$0 - 1]];
2607
+ return __sub(["presence", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2595
2608
  case 432:
2596
- return ["await", $[$0]];
2609
+ return __sub(["await", $[$0]], __subLocsOn ? [null, $L[$0]] : null);
2597
2610
  case 433:
2598
- return ["await", $[$0 - 1]];
2611
+ return __sub(["await", $[$0 - 1]], __subLocsOn ? [null, $L[$0 - 1]] : null);
2599
2612
  case 434:
2600
- return ["--", $[$0], false];
2613
+ return __sub(["--", $[$0], false], __subLocsOn ? [null, $L[$0], null] : null);
2601
2614
  case 435:
2602
- return ["++", $[$0], false];
2615
+ return __sub(["++", $[$0], false], __subLocsOn ? [null, $L[$0], null] : null);
2603
2616
  case 436:
2604
- return ["--", $[$0 - 1], true];
2617
+ return __sub(["--", $[$0 - 1], true], __subLocsOn ? [null, $L[$0 - 1], null] : null);
2605
2618
  case 437:
2606
- return ["++", $[$0 - 1], true];
2619
+ return __sub(["++", $[$0 - 1], true], __subLocsOn ? [null, $L[$0 - 1], null] : null);
2607
2620
  case 438:
2608
- return ["+", $[$0 - 2], $[$0]];
2621
+ return __sub(["+", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2609
2622
  case 439:
2610
- return ["-", $[$0 - 2], $[$0]];
2623
+ return __sub(["-", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2611
2624
  case 441:
2612
- return ["**", $[$0 - 2], $[$0]];
2625
+ return __sub(["**", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2613
2626
  case 444:
2614
- return ["&", $[$0 - 2], $[$0]];
2627
+ return __sub(["&", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2615
2628
  case 445:
2616
- return ["^", $[$0 - 2], $[$0]];
2629
+ return __sub(["^", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2617
2630
  case 446:
2618
- return ["|", $[$0 - 2], $[$0]];
2631
+ return __sub(["|", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2619
2632
  case 447:
2620
2633
  case 448:
2621
2634
  case 449:
2622
2635
  case 450:
2623
2636
  case 451:
2624
2637
  case 452:
2625
- return ["control", $[$0 - 1], $[$0 - 2], $[$0]];
2638
+ return __sub(["control", $[$0 - 1], $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 1], $L[$0 - 2], $L[$0]] : null);
2626
2639
  case 453:
2627
- return ["&&", $[$0 - 2], $[$0]];
2640
+ return __sub(["&&", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2628
2641
  case 454:
2629
- return ["||", $[$0 - 2], $[$0]];
2642
+ return __sub(["||", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2630
2643
  case 455:
2631
- return ["??", $[$0 - 2], $[$0]];
2644
+ return __sub(["??", $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 2], $L[$0]] : null);
2632
2645
  case 457:
2633
- return ["?:", $[$0 - 4], $[$0 - 2], $[$0]];
2646
+ return __sub(["?:", $[$0 - 4], $[$0 - 2], $[$0]], __subLocsOn ? [null, $L[$0 - 4], $L[$0 - 2], $L[$0]] : null);
2634
2647
  case 459:
2635
- return [$[$0 - 3], $[$0 - 4], $[$0 - 1]];
2648
+ return __sub([$[$0 - 3], $[$0 - 4], $[$0 - 1]], __subLocsOn ? [$L[$0 - 3], $L[$0 - 4], $L[$0 - 1]] : null);
2636
2649
  case 460:
2637
- return [$[$0 - 2], $[$0 - 3], $[$0]];
2650
+ return __sub([$[$0 - 2], $[$0 - 3], $[$0]], __subLocsOn ? [$L[$0 - 2], $L[$0 - 3], $L[$0]] : null);
2638
2651
  }
2639
2652
  },
2640
2653
  parseError(str, hash) {
@@ -2654,7 +2667,7 @@ function __schemaFkName(m) { return ''; } // ditto
2654
2667
  }
2655
2668
  },
2656
2669
  parse(input) {
2657
- let EOF, TERROR, action, errStr, expected, len, lex, lexer, loc, locs, newState, p, parseTable, preErrorSymbol, r, recovering, rv, sharedState, state, stk, symbol, tokenLen, tokenLine, tokenLoc, tokenText, vals;
2670
+ let EOF, TERROR, action, errStr, expected, last, len, lex, lexer, loc, locs, n, newState, p, parseTable, preErrorSymbol, r, recovering, rv, sharedState, state, stk, symbol, tokenLen, tokenLine, tokenLoc, tokenText, vals;
2658
2671
  [stk, vals, locs] = [[0], [null], []];
2659
2672
  [parseTable, tokenText, tokenLine, tokenLen, recovering] = [this.parseTable, "", 0, 0, 0];
2660
2673
  [TERROR, EOF] = [2, 1];
@@ -2727,7 +2740,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
2727
2740
  len = this.ruleTable[-action * 2 + 1];
2728
2741
  rv.$ = vals[vals.length - len];
2729
2742
  loc = locs[locs.length - (len || 1)];
2730
- rv._$ = { r: loc.r, c: loc.c };
2743
+ last = len ? locs[locs.length - 1] : loc;
2744
+ n = last != null && last.r === loc.r && loc.c != null && last.c != null ? last.c + (last.n || 0) - loc.c : loc.n || 0;
2745
+ rv._$ = { r: loc.r, c: loc.c, n };
2731
2746
  r = this.ruleActions.call(rv, -action, vals, locs, sharedState.ctx);
2732
2747
  if (r != null)
2733
2748
  rv.$ = r;
@@ -2776,10 +2791,10 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
2776
2791
  int: "integer",
2777
2792
  whole: "integer",
2778
2793
  float: "number",
2779
- money: "number",
2780
- money_even: "number",
2794
+ money: "integer",
2795
+ money_even: "integer",
2781
2796
  cents: "integer",
2782
- cents_even: "integer",
2797
+ decimal: "string",
2783
2798
  bool: "boolean",
2784
2799
  truthy: "boolean",
2785
2800
  falsy: "boolean",
@@ -4829,12 +4844,236 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4829
4844
  } catch {}
4830
4845
  }
4831
4846
 
4847
+ // src/error.js
4848
+ class RipError extends Error {
4849
+ constructor(message, {
4850
+ code = null,
4851
+ file = null,
4852
+ line = null,
4853
+ column = null,
4854
+ length = 1,
4855
+ source = null,
4856
+ suggestion = null,
4857
+ phase = null
4858
+ } = {}) {
4859
+ super(message);
4860
+ this.name = "RipError";
4861
+ this.code = code;
4862
+ this.file = file;
4863
+ this.line = line;
4864
+ this.column = column;
4865
+ this.length = length;
4866
+ this.source = source;
4867
+ this.suggestion = suggestion;
4868
+ this.phase = phase;
4869
+ }
4870
+ static fromLexer(err, source, file) {
4871
+ let loc = err.location || {};
4872
+ return new RipError(err.message, {
4873
+ code: "E_SYNTAX",
4874
+ file,
4875
+ line: loc.first_line ?? null,
4876
+ column: loc.first_column ?? null,
4877
+ length: loc.last_column != null && loc.first_column != null ? loc.last_column - loc.first_column + 1 : 1,
4878
+ source,
4879
+ phase: "lexer"
4880
+ });
4881
+ }
4882
+ static fromParser(err, source, file) {
4883
+ let h = err.hash || {};
4884
+ let loc = h.loc || {};
4885
+ let line = h.line ?? loc.r ?? null;
4886
+ let column = loc.first_column ?? loc.c ?? null;
4887
+ let suggestion = null;
4888
+ if (h.expected?.length) {
4889
+ let first5 = h.expected.slice(0, 5).map((e) => e.replace(/'/g, ""));
4890
+ suggestion = `Expected ${first5.join(", ")}`;
4891
+ if (h.expected.length > 5)
4892
+ suggestion += `, ... (${h.expected.length} total)`;
4893
+ }
4894
+ let token = h.token || "token";
4895
+ let expectedSet = new Set((h.expected || []).map((e) => e.replace(/'/g, "")));
4896
+ let TERNARY_ENDERS = new Set([
4897
+ "TERMINATOR",
4898
+ ",",
4899
+ ")",
4900
+ "]",
4901
+ "OUTDENT",
4902
+ "CALL_END",
4903
+ "INDEX_END",
4904
+ "PARAM_END",
4905
+ "EOF"
4906
+ ]);
4907
+ if (expectedSet.has(":") && (expectedSet.has("POST_IF") || expectedSet.has("POST_UNLESS") || expectedSet.has("FOR") || expectedSet.has("WHILE")) && TERNARY_ENDERS.has(token)) {
4908
+ suggestion = "Binary `x ? y` was removed — use `x ?? y` for nullish coalescing, or a full ternary `x ? y : z`";
4909
+ }
4910
+ let near = h.text ? ` near '${h.text}'` : "";
4911
+ let message = `Unexpected ${token}${near}`;
4912
+ return new RipError(message, {
4913
+ code: "E_PARSE",
4914
+ file,
4915
+ line,
4916
+ column,
4917
+ length: h.text?.length || 1,
4918
+ source,
4919
+ suggestion,
4920
+ phase: "parser"
4921
+ });
4922
+ }
4923
+ static fromSExpr(message, sexpr, source, file, suggestion) {
4924
+ let loc = sexpr?.loc || {};
4925
+ return new RipError(message, {
4926
+ code: "E_CODEGEN",
4927
+ file,
4928
+ line: loc.r ?? null,
4929
+ column: loc.c ?? null,
4930
+ length: loc.n ?? 1,
4931
+ source,
4932
+ suggestion,
4933
+ phase: "codegen"
4934
+ });
4935
+ }
4936
+ get locationString() {
4937
+ let parts = [];
4938
+ if (this.file)
4939
+ parts.push(this.file);
4940
+ if (this.line != null) {
4941
+ parts.push(`${this.line + 1}:${(this.column ?? 0) + 1}`);
4942
+ }
4943
+ return parts.join(":");
4944
+ }
4945
+ format({ color = true } = {}) {
4946
+ let c = color ? {
4947
+ red: "\x1B[31m",
4948
+ yellow: "\x1B[33m",
4949
+ cyan: "\x1B[36m",
4950
+ dim: "\x1B[2m",
4951
+ bold: "\x1B[1m",
4952
+ reset: "\x1B[0m"
4953
+ } : { red: "", yellow: "", cyan: "", dim: "", bold: "", reset: "" };
4954
+ let lines = [];
4955
+ let loc = this.locationString;
4956
+ let header = loc ? `${c.cyan}${loc}${c.reset} ` : "";
4957
+ lines.push(`${header}${c.red}${c.bold}error${c.reset}${c.bold}: ${this.message}${c.reset}`);
4958
+ let snippet = this._snippet();
4959
+ if (snippet) {
4960
+ lines.push("");
4961
+ for (let s of snippet) {
4962
+ if (s.type === "source") {
4963
+ lines.push(`${c.dim}${s.gutter}${c.reset}${s.text}`);
4964
+ } else if (s.type === "caret") {
4965
+ lines.push(`${c.dim}${s.gutter}${c.reset}${c.red}${c.bold}${s.text}${c.reset}`);
4966
+ }
4967
+ }
4968
+ }
4969
+ if (this.suggestion) {
4970
+ lines.push("");
4971
+ lines.push(`${c.yellow}hint${c.reset}: ${this.suggestion}`);
4972
+ }
4973
+ return lines.join(`
4974
+ `);
4975
+ }
4976
+ formatHTML() {
4977
+ let lines = [];
4978
+ lines.push('<div class="rip-error">');
4979
+ lines.push("<style>");
4980
+ lines.push(`.rip-error { font-family: ui-monospace, "SF Mono", Menlo, Monaco, monospace; font-size: 13px; line-height: 1.5; padding: 16px 20px; background: #1e1e2e; color: #cdd6f4; border-radius: 8px; overflow-x: auto; }`);
4981
+ lines.push(`.rip-error .re-header { color: #f38ba8; font-weight: 600; }`);
4982
+ lines.push(`.rip-error .re-loc { color: #89b4fa; }`);
4983
+ lines.push(`.rip-error .re-gutter { color: #585b70; user-select: none; }`);
4984
+ lines.push(`.rip-error .re-caret { color: #f38ba8; font-weight: 700; }`);
4985
+ lines.push(`.rip-error .re-hint { color: #f9e2af; }`);
4986
+ lines.push(`.rip-error .re-snippet { margin: 8px 0; }`);
4987
+ lines.push("</style>");
4988
+ let loc = this.locationString;
4989
+ let locSpan = loc ? `<span class="re-loc">${esc(loc)}</span> ` : "";
4990
+ lines.push(`<div class="re-header">${locSpan}error: ${esc(this.message)}</div>`);
4991
+ let snippet = this._snippet();
4992
+ if (snippet) {
4993
+ lines.push('<pre class="re-snippet">');
4994
+ for (let s of snippet) {
4995
+ if (s.type === "source") {
4996
+ lines.push(`<span class="re-gutter">${esc(s.gutter)}</span>${esc(s.text)}`);
4997
+ } else if (s.type === "caret") {
4998
+ lines.push(`<span class="re-gutter">${esc(s.gutter)}</span><span class="re-caret">${esc(s.text)}</span>`);
4999
+ }
5000
+ }
5001
+ lines.push("</pre>");
5002
+ }
5003
+ if (this.suggestion) {
5004
+ lines.push(`<div class="re-hint">hint: ${esc(this.suggestion)}</div>`);
5005
+ }
5006
+ lines.push("</div>");
5007
+ return lines.join(`
5008
+ `);
5009
+ }
5010
+ _snippet() {
5011
+ if (this.source == null || this.line == null)
5012
+ return null;
5013
+ let sourceLines = this.source.split(`
5014
+ `);
5015
+ let errLine = this.line;
5016
+ if (errLine < 0 || errLine >= sourceLines.length)
5017
+ return null;
5018
+ let contextRadius = 2;
5019
+ let start = Math.max(0, errLine - contextRadius);
5020
+ let end = Math.min(sourceLines.length - 1, errLine + contextRadius);
5021
+ let gutterWidth = String(end + 1).length;
5022
+ let result = [];
5023
+ for (let i = start;i <= end; i++) {
5024
+ let lineNum = String(i + 1).padStart(gutterWidth);
5025
+ let gutter = ` ${lineNum} │ `;
5026
+ result.push({ type: "source", gutter, text: sourceLines[i] });
5027
+ if (i === errLine && this.column != null) {
5028
+ let pad = " ".repeat(this.column);
5029
+ let caretLen = Math.max(1, Math.min(this.length || 1, sourceLines[i].length - this.column));
5030
+ let carets = "^".repeat(caretLen);
5031
+ let emptyGutter = " ".repeat(gutterWidth + 2) + "│ ";
5032
+ result.push({ type: "caret", gutter: emptyGutter, text: `${pad}${carets}` });
5033
+ }
5034
+ }
5035
+ return result;
5036
+ }
5037
+ }
5038
+ function isLexerError(err) {
5039
+ return err instanceof SyntaxError && err.location != null;
5040
+ }
5041
+ function isParserError(err) {
5042
+ return !(err instanceof SyntaxError) && err.hash != null;
5043
+ }
5044
+ function toRipError(err, source, file) {
5045
+ if (err instanceof RipError) {
5046
+ if (file && !err.file)
5047
+ err.file = file;
5048
+ if (source && !err.source)
5049
+ err.source = source;
5050
+ return err;
5051
+ }
5052
+ if (isLexerError(err))
5053
+ return RipError.fromLexer(err, source, file);
5054
+ if (isParserError(err))
5055
+ return RipError.fromParser(err, source, file);
5056
+ return new RipError(err.message, { file, source, phase: "unknown" });
5057
+ }
5058
+ function formatError(err, { source, file, color = true } = {}) {
5059
+ let re = err instanceof RipError ? err : toRipError(err, source, file);
5060
+ return re.format({ color });
5061
+ }
5062
+ function formatErrorHTML(err, { source, file } = {}) {
5063
+ let re = err instanceof RipError ? err : toRipError(err, source, file);
5064
+ return re.formatHTML();
5065
+ }
5066
+ function esc(s) {
5067
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
5068
+ }
5069
+
4832
5070
  // src/types.js
4833
5071
  function installTypeSupport(Lexer) {
4834
5072
  let proto = Lexer.prototype;
4835
5073
  proto.rewriteTypes = function() {
4836
5074
  let tokens = this.tokens;
4837
5075
  let typeRefNames = this.typeRefNames = new Set;
5076
+ reclassifyColonTypes(tokens);
4838
5077
  let gen = (tag, val, origin) => {
4839
5078
  let t = [tag, val];
4840
5079
  t.pre = 0;
@@ -4883,7 +5122,19 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
4883
5122
  let prevToken = tokens2[i - 1];
4884
5123
  if (!prevToken)
4885
5124
  return 1;
4886
- let typeTokens = collectTypeExpression(tokens2, i + 1);
5125
+ let isArrowReturn = prevToken[0] === "PARAM_END";
5126
+ let typeTokens = collectTypeExpression(tokens2, i + 1, { stopAtFatArrow: isArrowReturn });
5127
+ if (isArrowReturn && looksLikeBareFunctionType(typeTokens)) {
5128
+ let loc = tokens2[i + 1]?.loc;
5129
+ throw new RipError("A function-type return on an arrow must be parenthesized", {
5130
+ code: "E_SYNTAX",
5131
+ phase: "lexer",
5132
+ line: loc?.r ?? null,
5133
+ column: loc?.c ?? null,
5134
+ length: loc?.n ?? 1,
5135
+ suggestion: "wrap the whole function type in parens — " + "`(x):: ((a: T) => R) => body`, not `(x):: (a: T) => R => body`"
5136
+ });
5137
+ }
4887
5138
  let typeStr = buildTypeString(typeTokens);
4888
5139
  let target = prevToken;
4889
5140
  let propName = "type";
@@ -5068,45 +5319,465 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
5068
5319
  }
5069
5320
  };
5070
5321
  }
5071
- function collectTypeExpression(tokens, j) {
5072
- let typeTokens = [];
5322
+ function looksLikeBareFunctionType(typeTokens) {
5323
+ const isOpen = (t) => t === "(" || t === "PARAM_START" || t === "CALL_START";
5324
+ const isClose = (t) => t === ")" || t === "PARAM_END" || t === "CALL_END";
5325
+ if (typeTokens.length < 2 || !isOpen(typeTokens[0][0]))
5326
+ return false;
5073
5327
  let depth = 0;
5074
- let bracketStack = [];
5075
- let startJ = j;
5076
- while (j < tokens.length) {
5077
- let t = tokens[j];
5078
- let tTag = t[0];
5079
- let isOpen = tTag === "(" || tTag === "[" || tTag === "{" || tTag === "CALL_START" || tTag === "PARAM_START" || tTag === "INDEX_START" || tTag === "COMPARE" && t[1] === "<";
5080
- let isClose = tTag === ")" || tTag === "]" || tTag === "}" || tTag === "CALL_END" || tTag === "PARAM_END" || tTag === "INDEX_END" || tTag === "COMPARE" && t[1] === ">";
5081
- if (tTag === "SHIFT" && t[1] === ">>" && depth >= 2) {
5082
- depth -= 2;
5083
- if (bracketStack[bracketStack.length - 1] === "<")
5084
- bracketStack.pop();
5085
- if (bracketStack[bracketStack.length - 1] === "<")
5086
- bracketStack.pop();
5087
- typeTokens.push(t);
5088
- j++;
5089
- continue;
5090
- }
5091
- if (isOpen) {
5328
+ for (let k = 0;k < typeTokens.length; k++) {
5329
+ const tag = typeTokens[k][0];
5330
+ if (isOpen(tag))
5092
5331
  depth++;
5093
- let kind = tTag === "{" ? "{" : tTag === "[" || tTag === "INDEX_START" ? "[" : tTag === "COMPARE" && t[1] === "<" ? "<" : "(";
5094
- bracketStack.push(kind);
5095
- typeTokens.push(t);
5096
- j++;
5097
- continue;
5332
+ else if (isClose(tag)) {
5333
+ if (--depth === 0 && k !== typeTokens.length - 1)
5334
+ return false;
5098
5335
  }
5099
- if (isClose) {
5100
- if (depth > 0) {
5101
- depth--;
5102
- bracketStack.pop();
5103
- typeTokens.push(t);
5104
- j++;
5105
- continue;
5106
- }
5107
- break;
5336
+ }
5337
+ if (depth !== 0)
5338
+ return false;
5339
+ if (typeTokens.length === 2)
5340
+ return true;
5341
+ let d = 0, pendingTernary = false;
5342
+ for (const t of typeTokens) {
5343
+ const tag = t[0];
5344
+ if (isOpen(tag) || tag === "[" || tag === "{" || tag === "INDEX_START")
5345
+ d++;
5346
+ else if (isClose(tag) || tag === "]" || tag === "}" || tag === "INDEX_END")
5347
+ d--;
5348
+ else if (d === 1 && tag === "TERNARY")
5349
+ pendingTernary = true;
5350
+ else if (d === 1 && tag === ":") {
5351
+ if (pendingTernary)
5352
+ pendingTernary = false;
5353
+ else
5354
+ return true;
5355
+ }
5356
+ }
5357
+ return false;
5358
+ }
5359
+ function isCompleteTypeExpr(tokens, a, b) {
5360
+ if (b <= a)
5361
+ return false;
5362
+ const SEP = new Set(["|", "&", ",", ":", "?", ".", "...", "=>"]);
5363
+ let par = 0, brk = 0, brc = 0, gen = 0, atomEnd = false;
5364
+ for (let j = a;j < b; j++) {
5365
+ const t = tokens[j][0], v = tokens[j][1];
5366
+ if (t === "(" || t === "PARAM_START") {
5367
+ par++;
5368
+ atomEnd = false;
5369
+ continue;
5370
+ }
5371
+ if (t === ")" || t === "PARAM_END") {
5372
+ if (--par < 0)
5373
+ return false;
5374
+ atomEnd = true;
5375
+ continue;
5376
+ }
5377
+ if (t === "[" || t === "INDEX_START") {
5378
+ brk++;
5379
+ atomEnd = false;
5380
+ continue;
5381
+ }
5382
+ if (t === "]" || t === "INDEX_END") {
5383
+ if (--brk < 0)
5384
+ return false;
5385
+ atomEnd = true;
5386
+ continue;
5387
+ }
5388
+ if (t === "{") {
5389
+ brc++;
5390
+ atomEnd = false;
5391
+ continue;
5392
+ }
5393
+ if (t === "}") {
5394
+ if (--brc < 0)
5395
+ return false;
5396
+ atomEnd = true;
5397
+ continue;
5398
+ }
5399
+ if (t === "COMPARE") {
5400
+ if (v === "<") {
5401
+ gen++;
5402
+ atomEnd = false;
5403
+ continue;
5404
+ }
5405
+ if (v === ">") {
5406
+ if (gen <= 0)
5407
+ return false;
5408
+ gen--;
5409
+ atomEnd = true;
5410
+ continue;
5411
+ }
5412
+ return false;
5413
+ }
5414
+ if (t === "SHIFT") {
5415
+ if (v === ">>") {
5416
+ if (gen < 2)
5417
+ return false;
5418
+ gen -= 2;
5419
+ atomEnd = true;
5420
+ continue;
5421
+ }
5422
+ return false;
5423
+ }
5424
+ if (t === "=") {
5425
+ if (gen > 0) {
5426
+ atomEnd = false;
5427
+ continue;
5428
+ }
5429
+ return false;
5430
+ }
5431
+ if (SEP.has(t)) {
5432
+ atomEnd = false;
5433
+ continue;
5434
+ }
5435
+ if (t === "IDENTIFIER" || t === "PROPERTY" || t === "NUMBER" || t === "STRING" || t === "NULL" || t === "UNDEFINED" || t === "BOOL") {
5436
+ if (atomEnd)
5437
+ return false;
5438
+ atomEnd = true;
5439
+ continue;
5440
+ }
5441
+ return false;
5442
+ }
5443
+ return par === 0 && brk === 0 && brc === 0 && gen === 0 && atomEnd;
5444
+ }
5445
+ function assignedLaterInBlock(tokens, start, name) {
5446
+ const ASSIGN = new Set(["=", "REACTIVE_ASSIGN", "COMPUTED_ASSIGN", "READONLY_ASSIGN"]);
5447
+ let indent = 0, bracket = 0, closureDepth = 0;
5448
+ const closureAt = [];
5449
+ for (let j = start;j < tokens.length; j++) {
5450
+ const g = tokens[j][0];
5451
+ if (g === "INDENT") {
5452
+ indent++;
5453
+ const p = tokens[j - 1]?.[0];
5454
+ if (p === "->" || p === "=>") {
5455
+ closureAt.push(indent);
5456
+ closureDepth++;
5457
+ }
5458
+ continue;
5459
+ }
5460
+ if (g === "OUTDENT") {
5461
+ if (indent === 0)
5462
+ return false;
5463
+ if (closureAt[closureAt.length - 1] === indent) {
5464
+ closureAt.pop();
5465
+ closureDepth--;
5466
+ }
5467
+ indent--;
5468
+ continue;
5469
+ }
5470
+ if (g === "(" || g === "CALL_START" || g === "PARAM_START" || g === "[" || g === "INDEX_START" || g === "{") {
5471
+ bracket++;
5472
+ continue;
5473
+ }
5474
+ if (g === ")" || g === "CALL_END" || g === "PARAM_END" || g === "]" || g === "INDEX_END" || g === "}") {
5475
+ bracket--;
5476
+ continue;
5477
+ }
5478
+ if (closureDepth === 0 && bracket === 0 && (g === "IDENTIFIER" || g === "PROPERTY") && tokens[j][1] === name && ASSIGN.has(tokens[j + 1]?.[0]))
5479
+ return true;
5480
+ }
5481
+ return false;
5482
+ }
5483
+ function reclassifyColonTypes(tokens) {
5484
+ const isOpen = (t) => t === "(" || t === "CALL_START" || t === "PARAM_START" || t === "{" || t === "[" || t === "INDEX_START";
5485
+ const isClose = (t) => t === ")" || t === "CALL_END" || t === "PARAM_END" || t === "}" || t === "]" || t === "INDEX_END";
5486
+ const isDefParamStart = (i) => {
5487
+ let j = i - 1;
5488
+ const g0 = tokens[j]?.[0], v0 = tokens[j]?.[1];
5489
+ if (g0 === "COMPARE" && v0 === ">" || g0 === "SHIFT" && v0 === ">>") {
5490
+ let depth = g0 === "SHIFT" ? 2 : 1;
5491
+ j--;
5492
+ while (j >= 0 && depth > 0) {
5493
+ const g = tokens[j][0], v = tokens[j][1];
5494
+ if (g === "COMPARE" && v === ">")
5495
+ depth++;
5496
+ else if (g === "SHIFT" && v === ">>")
5497
+ depth += 2;
5498
+ else if (g === "COMPARE" && v === "<")
5499
+ depth--;
5500
+ else if (g === "SHIFT" && v === "<<")
5501
+ depth -= 2;
5502
+ j--;
5503
+ }
5504
+ }
5505
+ if (tokens[j]?.[0] !== "IDENTIFIER" && tokens[j]?.[0] !== "PROPERTY")
5506
+ return false;
5507
+ return tokens[j - 1]?.[0] === "DEF";
5508
+ };
5509
+ const STMT_START = new Set(["TERMINATOR", "INDENT", "OUTDENT", "EXPORT"]);
5510
+ const BINDING_OPS = new Set(["=", "REACTIVE_ASSIGN", "COMPUTED_ASSIGN", "READONLY_ASSIGN"]);
5511
+ const atStatementStart = (t) => !t || STMT_START.has(t[0]);
5512
+ const declBindsBeforeArrow = (start) => {
5513
+ let depth = 0;
5514
+ for (let j = start;j < tokens.length; j++) {
5515
+ const g = tokens[j][0];
5516
+ if (isOpen(g))
5517
+ depth++;
5518
+ else if (isClose(g))
5519
+ depth--;
5520
+ else if (depth === 0) {
5521
+ if (g === "->" || g === "=>")
5522
+ return false;
5523
+ if (BINDING_OPS.has(g))
5524
+ return true;
5525
+ if ((g === "EFFECT" || g === "GATE") && j > start)
5526
+ return true;
5527
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5528
+ return false;
5529
+ }
5530
+ }
5531
+ return false;
5532
+ };
5533
+ const valueIsMethod = (start) => {
5534
+ let depth = 0;
5535
+ for (let j = start;j < tokens.length; j++) {
5536
+ const g = tokens[j][0];
5537
+ if (isOpen(g))
5538
+ depth++;
5539
+ else if (isClose(g))
5540
+ depth--;
5541
+ else if (depth === 0) {
5542
+ if (g === "->" || g === "=>")
5543
+ return true;
5544
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5545
+ return false;
5546
+ }
5547
+ }
5548
+ return false;
5549
+ };
5550
+ let pendingBody = false;
5551
+ const indentStack = [];
5552
+ const inTypedBody = () => indentStack.length > 0 && indentStack[indentStack.length - 1];
5553
+ const nameAtStatementStart = (i) => {
5554
+ const p = tokens[i - 1]?.[0];
5555
+ if (p !== "PROPERTY" && p !== "IDENTIFIER")
5556
+ return false;
5557
+ if (tokens[i - 2]?.[0] === "@")
5558
+ return atStatementStart(tokens[i - 3]);
5559
+ return atStatementStart(tokens[i - 2]);
5560
+ };
5561
+ let inType = false, typeStartDepth = 0;
5562
+ const enterType = () => {
5563
+ inType = true;
5564
+ typeStartDepth = stack.length;
5565
+ };
5566
+ let prevSiblingKV = false, curLineKV = false;
5567
+ const stack = [];
5568
+ for (let i = 0;i < tokens.length; i++) {
5569
+ const tag = tokens[i][0];
5570
+ if (tag === "CLASS" || tag === "COMPONENT") {
5571
+ pendingBody = true;
5572
+ continue;
5573
+ }
5574
+ if (tag === "INDENT") {
5575
+ indentStack.push(pendingBody);
5576
+ pendingBody = false;
5577
+ prevSiblingKV = curLineKV = false;
5578
+ if (inType && stack.length <= typeStartDepth)
5579
+ inType = false;
5580
+ continue;
5581
+ }
5582
+ if (tag === "OUTDENT") {
5583
+ indentStack.pop();
5584
+ prevSiblingKV = curLineKV = false;
5585
+ if (inType && stack.length <= typeStartDepth)
5586
+ inType = false;
5587
+ continue;
5588
+ }
5589
+ if (isOpen(tag)) {
5590
+ let kind = "other";
5591
+ if (!inType) {
5592
+ if (tag === "PARAM_START")
5593
+ kind = "param";
5594
+ else if ((tag === "CALL_START" || tag === "(") && isDefParamStart(i))
5595
+ kind = "defparam";
5596
+ }
5597
+ stack.push({ kind, sawEq: false, sawType: false });
5598
+ continue;
5599
+ }
5600
+ if (isClose(tag)) {
5601
+ const f2 = stack.pop();
5602
+ if (f2?.kind === "defparam") {
5603
+ (tokens[i].data ??= {}).isDefParamEnd = true;
5604
+ }
5605
+ if (inType && stack.length < typeStartDepth)
5606
+ inType = false;
5607
+ continue;
5608
+ }
5609
+ if (tag === "TYPE_ANNOTATION") {
5610
+ if (!inType)
5611
+ enterType();
5612
+ continue;
5613
+ }
5614
+ if (inType) {
5615
+ if (stack.length <= typeStartDepth && (tag === "=" || tag === "," || tag === "TERMINATOR" || tag === "->" || BINDING_OPS.has(tag))) {
5616
+ inType = false;
5617
+ } else {
5618
+ continue;
5619
+ }
5620
+ }
5621
+ if (tag === "TERMINATOR" && stack.length === 0) {
5622
+ prevSiblingKV = curLineKV;
5623
+ curLineKV = false;
5624
+ }
5625
+ if (tag === ":") {
5626
+ const prev = tokens[i - 1];
5627
+ const prevTag = prev?.[0];
5628
+ if (stack.length === 0 && (prevTag === "IDENTIFIER" || prevTag === "PROPERTY") && atStatementStart(tokens[i - 2]))
5629
+ curLineKV = true;
5630
+ if (prevTag === "PARAM_END" || (prevTag === ")" || prevTag === "CALL_END") && prev.data?.isDefParamEnd) {
5631
+ tokens[i][0] = "TYPE_ANNOTATION";
5632
+ enterType();
5633
+ continue;
5634
+ }
5635
+ if ((prevTag === "IDENTIFIER" || prevTag === "PROPERTY") && tokens[i - 2]?.[0] === "DEF") {
5636
+ if (prevTag === "PROPERTY")
5637
+ prev[0] = "IDENTIFIER";
5638
+ tokens[i][0] = "TYPE_ANNOTATION";
5639
+ enterType();
5640
+ continue;
5641
+ }
5642
+ if (stack.length === 0 && nameAtStatementStart(i) && declBindsBeforeArrow(i + 1)) {
5643
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5644
+ prev[0] = "IDENTIFIER";
5645
+ tokens[i][0] = "TYPE_ANNOTATION";
5646
+ enterType();
5647
+ continue;
5648
+ }
5649
+ if (stack.length === 0 && nameAtStatementStart(i)) {
5650
+ let depth = 0;
5651
+ for (let j = i + 1;j < tokens.length; j++) {
5652
+ const g = tokens[j][0];
5653
+ if (isOpen(g))
5654
+ depth++;
5655
+ else if (isClose(g)) {
5656
+ if (depth === 0)
5657
+ break;
5658
+ depth--;
5659
+ } else if (depth === 0) {
5660
+ if (g === "TERMINATOR" || g === "INDENT" || g === "OUTDENT")
5661
+ break;
5662
+ if (g === "=" && isCompleteTypeExpr(tokens, i + 1, j)) {
5663
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5664
+ prev[0] = "IDENTIFIER";
5665
+ tokens[i][0] = "TYPE_ANNOTATION";
5666
+ enterType();
5667
+ break;
5668
+ }
5669
+ }
5670
+ }
5671
+ if (tokens[i][0] === "TYPE_ANNOTATION")
5672
+ continue;
5673
+ }
5674
+ if (inTypedBody() && stack.length === 0 && nameAtStatementStart(i) && !valueIsMethod(i + 1)) {
5675
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5676
+ prev[0] = "IDENTIFIER";
5677
+ tokens[i][0] = "TYPE_ANNOTATION";
5678
+ enterType();
5679
+ continue;
5680
+ }
5681
+ if (stack.length === 0 && nameAtStatementStart(i) && tokens[i - 2]?.[0] !== "@") {
5682
+ let depth = 0, end = -1;
5683
+ for (let j = i + 1;j < tokens.length; j++) {
5684
+ const g = tokens[j][0];
5685
+ if (isOpen(g))
5686
+ depth++;
5687
+ else if (isClose(g)) {
5688
+ if (depth === 0)
5689
+ break;
5690
+ depth--;
5691
+ } else if (depth === 0) {
5692
+ if (g === "TERMINATOR") {
5693
+ end = j;
5694
+ break;
5695
+ }
5696
+ if (g === "INDENT" || g === "OUTDENT" || g === "=" || BINDING_OPS.has(g))
5697
+ break;
5698
+ }
5699
+ }
5700
+ const nk = tokens[end + 1];
5701
+ const nextKV = nk && (nk[0] === "IDENTIFIER" || nk[0] === "PROPERTY") && tokens[end + 2]?.[0] === ":";
5702
+ if (end > i + 1 && nk && nk[0] !== "OUTDENT" && !prevSiblingKV && !nextKV && isCompleteTypeExpr(tokens, i + 1, end) && assignedLaterInBlock(tokens, end + 1, prev[1])) {
5703
+ if (prevTag === "PROPERTY")
5704
+ prev[0] = "IDENTIFIER";
5705
+ tokens[i][0] = "TYPE_ANNOTATION";
5706
+ enterType();
5707
+ continue;
5708
+ }
5709
+ }
5710
+ }
5711
+ const f = stack[stack.length - 1];
5712
+ if (f && (f.kind === "param" || f.kind === "defparam")) {
5713
+ if (tag === ",") {
5714
+ f.sawEq = false;
5715
+ f.sawType = false;
5716
+ continue;
5717
+ }
5718
+ if (tag === "=") {
5719
+ f.sawEq = true;
5720
+ continue;
5721
+ }
5722
+ if (tag === ":" && !f.sawEq && !f.sawType) {
5723
+ const prev = tokens[i - 1];
5724
+ const prevTag = prev?.[0];
5725
+ if (prevTag === "PROPERTY" || prevTag === "IDENTIFIER") {
5726
+ if (prevTag === "PROPERTY" && tokens[i - 2]?.[0] !== "@")
5727
+ prev[0] = "IDENTIFIER";
5728
+ tokens[i][0] = "TYPE_ANNOTATION";
5729
+ f.sawType = true;
5730
+ enterType();
5731
+ } else if (prevTag === "}" || prevTag === "]" || prevTag === "INDEX_END") {
5732
+ tokens[i][0] = "TYPE_ANNOTATION";
5733
+ f.sawType = true;
5734
+ enterType();
5735
+ }
5736
+ }
5737
+ }
5738
+ }
5739
+ }
5740
+ function collectTypeExpression(tokens, j, opts = {}) {
5741
+ let typeTokens = [];
5742
+ let depth = 0;
5743
+ let bracketStack = [];
5744
+ let startJ = j;
5745
+ while (j < tokens.length) {
5746
+ let t = tokens[j];
5747
+ let tTag = t[0];
5748
+ let isOpen = tTag === "(" || tTag === "[" || tTag === "{" || tTag === "CALL_START" || tTag === "PARAM_START" || tTag === "INDEX_START" || tTag === "COMPARE" && t[1] === "<";
5749
+ let isClose = tTag === ")" || tTag === "]" || tTag === "}" || tTag === "CALL_END" || tTag === "PARAM_END" || tTag === "INDEX_END" || tTag === "COMPARE" && t[1] === ">";
5750
+ if (tTag === "SHIFT" && t[1] === ">>" && depth >= 2) {
5751
+ depth -= 2;
5752
+ if (bracketStack[bracketStack.length - 1] === "<")
5753
+ bracketStack.pop();
5754
+ if (bracketStack[bracketStack.length - 1] === "<")
5755
+ bracketStack.pop();
5756
+ typeTokens.push(t);
5757
+ j++;
5758
+ continue;
5759
+ }
5760
+ if (isOpen) {
5761
+ depth++;
5762
+ let kind = tTag === "{" ? "{" : tTag === "[" || tTag === "INDEX_START" ? "[" : tTag === "COMPARE" && t[1] === "<" ? "<" : "(";
5763
+ bracketStack.push(kind);
5764
+ typeTokens.push(t);
5765
+ j++;
5766
+ continue;
5767
+ }
5768
+ if (isClose) {
5769
+ if (depth > 0) {
5770
+ depth--;
5771
+ bracketStack.pop();
5772
+ typeTokens.push(t);
5773
+ j++;
5774
+ continue;
5775
+ }
5776
+ break;
5108
5777
  }
5109
5778
  if (depth === 0) {
5779
+ if (opts.stopAtFatArrow && tTag === "=>")
5780
+ break;
5110
5781
  if (tTag === "INDENT" && typeTokens.length > 0 && typeTokens[typeTokens.length - 1][0] === "=>") {
5111
5782
  j++;
5112
5783
  let nest = 1;
@@ -5575,7 +6246,8 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
5575
6246
  "LOOP",
5576
6247
  "TERMINATOR",
5577
6248
  "||",
5578
- "&&"
6249
+ "&&",
6250
+ "??"
5579
6251
  ]);
5580
6252
  var IMPLICIT_COMMA_BEFORE_ARROW = new Set([
5581
6253
  "STRING",
@@ -6208,6 +6880,11 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6208
6880
  depth--;
6209
6881
  if (depth === 0 && tk[0] === "TYPE_ANNOTATION")
6210
6882
  return false;
6883
+ if (depth === 0 && tk[0] === ":") {
6884
+ let pv = this.tokens[k - 1];
6885
+ if (pv && (pv[0] === ")" || pv[0] === "PARAM_END" || pv[0] === "CALL_END"))
6886
+ return false;
6887
+ }
6211
6888
  if (depth === 0 && tk[0] === "IDENTIFIER" && tk[1] === "type")
6212
6889
  return false;
6213
6890
  if (tk[0] === "INTERFACE")
@@ -6737,7 +7414,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6737
7414
  } else if (tg === "(" || tg === "[" || tg === "{" || tg === "CALL_START" || tg === "PARAM_START" || tg === "INDEX_START" || tg === "COMPARE" && tk[1] === "<") {
6738
7415
  depth--;
6739
7416
  } else if (depth === 0) {
6740
- if (tg === "TYPE_ANNOTATION") {
7417
+ if (tg === "TYPE_ANNOTATION" || tg === ":") {
6741
7418
  if (j > 0 && this.tokens[j - 1][0] === ")")
6742
7419
  found = j - 1;
6743
7420
  break;
@@ -6750,6 +7427,22 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6750
7427
  if (found < 0)
6751
7428
  return this.tagDoIife();
6752
7429
  closeIdx = found;
7430
+ } else {
7431
+ let d = 0, op = -1;
7432
+ for (let k = closeIdx;k >= 0; k--) {
7433
+ let tg = this.tokens[k][0];
7434
+ if (tg === ")" || tg === "CALL_END" || tg === "PARAM_END")
7435
+ d++;
7436
+ else if (tg === "(" || tg === "CALL_START" || tg === "PARAM_START") {
7437
+ if (--d === 0) {
7438
+ op = k;
7439
+ break;
7440
+ }
7441
+ }
7442
+ }
7443
+ if (op > 1 && this.tokens[op - 1][0] === "TYPE_ANNOTATION" && this.tokens[op - 2]?.[0] === ")") {
7444
+ closeIdx = op - 2;
7445
+ }
6753
7446
  }
6754
7447
  let i = closeIdx;
6755
7448
  let stack = [];
@@ -6889,7 +7582,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
6889
7582
  let indent = null;
6890
7583
  let outdent = null;
6891
7584
  let condition = (token, i) => {
6892
- return token[1] !== ";" && SINGLE_CLOSERS.has(token[0]) && !(token[0] === "TERMINATOR" && EXPRESSION_CLOSE.has(this.tokens[i + 1]?.[0])) && !(token[0] === "ELSE" && starter !== "THEN") || token[0] === "INDENT" && !token.generated && (starter === "->" || starter === "=>") || token[0] === "," && (starter === "->" || starter === "=>") && !this.commaInImplicitCall(i) && !this.commaInImplicitObject(i) || CALL_CLOSERS.has(token[0]) && (this.tokens[i - 1]?.newLine || this.tokens[i - 1]?.[0] === "OUTDENT");
7585
+ return token[1] !== ";" && SINGLE_CLOSERS.has(token[0]) && !(token[0] === "TERMINATOR" && EXPRESSION_CLOSE.has(this.tokens[i + 1]?.[0])) && !(token[0] === "ELSE" && starter !== "THEN") || token[0] === "INDENT" && !token.generated && (starter === "->" || starter === "=>") || token[0] === "," && (starter === "->" || starter === "=>" || starter === "THEN" || starter === "ELSE") && !this.commaInImplicitCall(i) && !this.commaInImplicitObject(i) || CALL_CLOSERS.has(token[0]) && (this.tokens[i - 1]?.newLine || this.tokens[i - 1]?.[0] === "OUTDENT");
6893
7586
  };
6894
7587
  let action = (token, i) => {
6895
7588
  let idx = this.tokens[i - 1]?.[0] === "," ? i - 1 : i;
@@ -7153,7 +7846,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
7153
7846
  }
7154
7847
  }
7155
7848
  let newLine = prevTag === "OUTDENT" || prevToken.newLine;
7156
- let isLogicalOp = tag === "||" || tag === "&&";
7849
+ let isLogicalOp = tag === "||" || tag === "&&" || tag === "??";
7157
7850
  let logicalKeep = false;
7158
7851
  if (isLogicalOp) {
7159
7852
  let j = i + 1, t = tokens[j]?.[0];
@@ -7857,12 +8550,19 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
7857
8550
  };
7858
8551
  let startsWithTag = (tokens, i) => {
7859
8552
  let j = i;
8553
+ while (j > 0 && tokens[j][0] === "OUTDENT") {
8554
+ j = skipBalancedPair(tokens, j - 1, "OUTDENT", "INDENT");
8555
+ }
7860
8556
  while (j > 0) {
7861
8557
  let pt = tokens[j - 1][0];
7862
8558
  if (pt === "TERMINATOR" || pt === "RENDER") {
7863
8559
  break;
7864
8560
  }
7865
- if (pt === "INDENT" || pt === "OUTDENT") {
8561
+ if (pt === "OUTDENT") {
8562
+ j = skipBalancedPair(tokens, j - 2, "OUTDENT", "INDENT");
8563
+ continue;
8564
+ }
8565
+ if (pt === "INDENT") {
7866
8566
  let jt = tokens[j][0];
7867
8567
  if (jt === "CALL_END" || jt === ")") {
7868
8568
  j = skipBalancedPair(tokens, j - 1, jt, jt === "CALL_END" ? "CALL_START" : "(");
@@ -8078,7 +8778,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8078
8778
  isTemplateElement = true;
8079
8779
  } else if (tag === "IDENTIFIER" && !isAfterControlFlow) {
8080
8780
  isTemplateElement = atLineStart || startsWithTag(tokens, i);
8081
- } else if (tag === "PROPERTY" || tag === "STRING" || tag === "STRING_END" || tag === "NUMBER" || tag === "BOOL" || tag === "CALL_END" || tag === ")" || tag === "PRESENCE") {
8781
+ } else if (tag === "PROPERTY" || tag === "STRING" || tag === "STRING_END" || tag === "NUMBER" || tag === "BOOL" || tag === "CALL_END" || tag === ")" || tag === "]" || tag === "INDEX_END" || tag === "}" || tag === "MAP_END" || tag === "PRESENCE") {
8082
8782
  isTemplateElement = startsWithTag(tokens, i);
8083
8783
  }
8084
8784
  if (isTemplateElement) {
@@ -8448,25 +9148,32 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8448
9148
  if (hookDecls.length)
8449
9149
  sl.push(" " + hookDecls.join(" "));
8450
9150
  sl.push(" emit(_name: string, _detail?: any): void {}");
8451
- const propEntries = [];
9151
+ const baseEntries = [];
9152
+ const requiredBindUnions = [];
8452
9153
  for (const { name, type, isPublic, required, optional } of stateVars) {
8453
9154
  if (!isPublic)
8454
9155
  continue;
8455
- const ts = expandType(type);
8456
- const opt = optional ?? !required ? "?" : "";
8457
- propEntries.push(`${name}${opt}: ${ts || "any"}`);
8458
- propEntries.push(`__bind_${name}__?: Signal<${ts || "any"}>`);
9156
+ const ts = expandType(type) || "any";
9157
+ if (optional ?? !required) {
9158
+ baseEntries.push(`${name}?: ${ts}`);
9159
+ baseEntries.push(`__bind_${name}__?: Signal<${ts}>`);
9160
+ } else {
9161
+ requiredBindUnions.push(`({ ${name}: ${ts}; __bind_${name}__?: Signal<${ts}> } | { ${name}?: ${ts}; __bind_${name}__: Signal<${ts}> })`);
9162
+ }
8459
9163
  }
8460
9164
  for (const { name, type, isPublic } of readonlyVars) {
8461
9165
  if (!isPublic)
8462
9166
  continue;
8463
- const ts = expandType(type);
8464
- propEntries.push(`${name}?: ${ts || "any"}`);
9167
+ const ts = expandType(type) || "any";
9168
+ baseEntries.push(`${name}?: ${ts}`);
8465
9169
  }
8466
9170
  {
8467
- const hasRequired = propEntries.length > 0 && stateVars.some((v) => v.isPublic && v.required && !v.optional);
8468
- const propsOpt = hasRequired ? "" : "?";
8469
- let propsType = propEntries.length > 0 ? `{${propEntries.join("; ")}}` : "{}";
9171
+ const propsOpt = requiredBindUnions.length > 0 ? "" : "?";
9172
+ const parts = [];
9173
+ if (baseEntries.length)
9174
+ parts.push(`{${baseEntries.join("; ")}}`);
9175
+ parts.push(...requiredBindUnions);
9176
+ let propsType = parts.length ? parts.join(" & ") : "{}";
8470
9177
  if (inheritsTag)
8471
9178
  propsType += ` & __RipProps<'${inheritsTag}'>`;
8472
9179
  sl.push(` constructor(_props${propsOpt}: ${propsType}) {}`);
@@ -8620,12 +9327,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8620
9327
  let [, params, methodBody] = func;
8621
9328
  if ((!params || Array.isArray(params) && params.length === 0) && this.containsIt(methodBody))
8622
9329
  params = ["it"];
8623
- let paramStr = Array.isArray(params) ? params.map((p) => {
8624
- let base = this.formatParam(p);
8625
- if (p?.type)
8626
- base += `: ${p.type}`;
8627
- return base;
8628
- }).join(", ") : "";
9330
+ let paramStr = Array.isArray(params) ? params.map((p) => this.formatParam(p)).join(", ") : "";
8629
9331
  const boundEvent = eventMethodTypes.get(name);
8630
9332
  if (boundEvent && Array.isArray(params) && params.length > 0) {
8631
9333
  const firstParam = params[0];
@@ -8665,7 +9367,25 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8665
9367
  const sourceLines = this.options.source?.split(`
8666
9368
  `);
8667
9369
  const wrapCompHref = (val) => typeof val === "string" && /^["'`]\//.test(val) ? `__ripRoute(${val})` : val;
8668
- const extractProps = (args) => {
9370
+ const FLAG_RE = /^[a-zA-Z_$][\w$]*$/;
9371
+ const isFlagArg = (a) => typeof a === "string" && FLAG_RE.test(a) && !/^(?:true|false|null|undefined)$/.test(a) && !CodeEmitter.GENERATORS[a] && !this._isInScopeValue(a);
9372
+ const findFlagLine = (name, fromLine) => {
9373
+ if (fromLine == null || !sourceLines)
9374
+ return fromLine;
9375
+ const re = new RegExp(`(?<![\\w$.#@])${name}(?![\\w$])`);
9376
+ for (let ln = fromLine;ln < sourceLines.length; ln++) {
9377
+ if (sourceLines[ln] && re.test(sourceLines[ln]))
9378
+ return ln;
9379
+ }
9380
+ return fromLine;
9381
+ };
9382
+ const emitFlag = (name, fromLine, headLine) => {
9383
+ const srcLine = findFlagLine(name, fromLine);
9384
+ if (srcLine != null && srcLine === headLine)
9385
+ return;
9386
+ constructions.push(` ({ ${name}: true });` + (srcLine != null ? ` // @rip-src:${srcLine}` : ""));
9387
+ };
9388
+ const extractProps = (args, nodeLine) => {
8669
9389
  const props = [];
8670
9390
  const sideExprs = [];
8671
9391
  for (const arg of args) {
@@ -8673,12 +9393,18 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8673
9393
  if (this.is(arg, "object")) {
8674
9394
  obj = arg;
8675
9395
  } else if (Array.isArray(arg) && (arg[0] === "->" || arg[0] === "=>") && this.is(arg[2], "block")) {
9396
+ const blockLine = arg[2].loc?.r ?? nodeLine;
8676
9397
  for (let k = 1;k < arg[2].length; k++) {
8677
- if (this.is(arg[2][k], "object")) {
8678
- obj = arg[2][k];
8679
- break;
8680
- }
9398
+ const bc = arg[2][k];
9399
+ if (this.is(bc, "object")) {
9400
+ if (!obj)
9401
+ obj = bc;
9402
+ } else if (isFlagArg(bc))
9403
+ emitFlag(bc, blockLine, nodeLine);
8681
9404
  }
9405
+ } else if (isFlagArg(arg)) {
9406
+ emitFlag(arg, nodeLine, nodeLine);
9407
+ continue;
8682
9408
  }
8683
9409
  if (obj) {
8684
9410
  for (let j = 1;j < obj.length; j++) {
@@ -8715,7 +9441,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8715
9441
  props.sideExprs = sideExprs;
8716
9442
  return props;
8717
9443
  };
8718
- const extractIntrinsicProps = (args, tagName) => {
9444
+ const extractIntrinsicProps = (args, tagName, nodeLine) => {
8719
9445
  const props = [];
8720
9446
  const wrapHrefVal = (val) => {
8721
9447
  if (tagName !== "a")
@@ -8735,12 +9461,18 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8735
9461
  if (this.is(arg, "object")) {
8736
9462
  obj = arg;
8737
9463
  } else if (Array.isArray(arg) && (arg[0] === "->" || arg[0] === "=>") && this.is(arg[2], "block")) {
9464
+ const blockLine = arg[2].loc?.r ?? nodeLine;
8738
9465
  for (let k = 1;k < arg[2].length; k++) {
8739
- if (this.is(arg[2][k], "object")) {
8740
- obj = arg[2][k];
8741
- break;
8742
- }
9466
+ const bc = arg[2][k];
9467
+ if (this.is(bc, "object")) {
9468
+ if (!obj)
9469
+ obj = bc;
9470
+ } else if (isFlagArg(bc))
9471
+ emitFlag(bc, blockLine, nodeLine);
8743
9472
  }
9473
+ } else if (isFlagArg(arg)) {
9474
+ emitFlag(arg, nodeLine, nodeLine);
9475
+ continue;
8744
9476
  }
8745
9477
  if (obj) {
8746
9478
  for (let j = 1;j < obj.length; j++) {
@@ -8887,10 +9619,14 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8887
9619
  } else {
8888
9620
  constructions.push(` for (const ${varPattern} of ${iterCode}) {${srcMarker}`);
8889
9621
  }
9622
+ const asName = (v) => typeof v === "string" || v instanceof String ? String(v) : null;
9623
+ const loopFrame = Array.isArray(vars) ? { itemVar: asName(vars[0]), indexVar: asName(vars[1]) } : { itemVar: asName(vars), indexVar: null };
9624
+ (this._loopVarStack || (this._loopVarStack = [])).push(loopFrame);
8890
9625
  for (let bi = 3;bi < node.length; bi++) {
8891
9626
  if (node[bi] != null)
8892
9627
  walkRender(node[bi]);
8893
9628
  }
9629
+ this._loopVarStack.pop();
8894
9630
  constructions.push(` }`);
8895
9631
  return;
8896
9632
  }
@@ -8968,9 +9704,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8968
9704
  }
8969
9705
  if (this.componentMembers && this.componentMembers.has(child)) {
8970
9706
  constructions.push(` this.${child};${srcMarker}`);
8971
- } else if (isTextChild) {
9707
+ } else if (this._isInScopeValue(child)) {
8972
9708
  constructions.push(` ${child};${srcMarker}`);
8973
- } else {
9709
+ } else if (!isTextChild && this.isHtmlTag(child)) {
8974
9710
  constructions.push(` __ripEl('${child}');${srcMarker}`);
8975
9711
  }
8976
9712
  };
@@ -8978,6 +9714,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
8978
9714
  if (head2 === "block") {
8979
9715
  for (let i = 1;i < node.length; i++)
8980
9716
  emitBareIdent(node[i], node, false);
9717
+ } else if (typeof head2 === "string" && /^[A-Z]/.test(head2)) {
9718
+ for (let i = 1;i < node.length; i++)
9719
+ emitBareIdent(node[i], node, true);
8981
9720
  } else if (isTagHead) {
8982
9721
  for (let i = 1;i < node.length; i++)
8983
9722
  emitBareIdent(node[i], node, true);
@@ -9009,7 +9748,7 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
9009
9748
  for (let i = 1;i < node.length; i++)
9010
9749
  walkRender(node[i]);
9011
9750
  if (typeof head2 === "string" && /^[A-Z]/.test(head2)) {
9012
- const props = extractProps(node.slice(1));
9751
+ const props = extractProps(node.slice(1), node.loc?.r);
9013
9752
  const varName = `_${constructionIdx++}`;
9014
9753
  const propsType = `ConstructorParameters<typeof ${head2}>[0] & {}`;
9015
9754
  if (props.length === 0) {
@@ -9039,23 +9778,24 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
9039
9778
  }
9040
9779
  } else if (typeof head2 === "string" && !CodeEmitter.GENERATORS[head2] && (TEMPLATE_TAGS.has(head2.split(/[.#]/)[0]) || /^[a-z][\w-]*$/.test(head2) && node.length > 1)) {
9041
9780
  const tagName = head2.split(/[.#]/)[0];
9042
- const iProps = extractIntrinsicProps(node.slice(1), tagName);
9781
+ const elFn = SVG_TAGS.has(tagName) ? "__ripSvgEl" : "__ripEl";
9782
+ const iProps = extractIntrinsicProps(node.slice(1), tagName, node.loc?.r);
9043
9783
  const tagLine = node.loc?.r;
9044
9784
  const srcMarker = tagLine != null ? ` // @rip-src:${tagLine}` : "";
9045
9785
  if (iProps.length === 0) {
9046
- constructions.push(` __ripEl('${tagName}');${srcMarker}`);
9786
+ constructions.push(` ${elFn}('${tagName}');${srcMarker}`);
9047
9787
  } else if (iProps.length === 1) {
9048
9788
  const srcLine = iProps[0].srcLine ?? tagLine;
9049
9789
  const marker = srcLine != null ? ` // @rip-src:${srcLine}` : "";
9050
- constructions.push(` __ripEl('${tagName}', {${iProps[0].code}});${marker}`);
9790
+ constructions.push(` ${elFn}('${tagName}', {${iProps[0].code}});${marker}`);
9051
9791
  } else {
9052
9792
  const distinctLines = new Set(iProps.map((p) => p.srcLine).filter((l) => l != null));
9053
9793
  if (distinctLines.size <= 1) {
9054
9794
  const srcLine = iProps[0].srcLine ?? tagLine;
9055
9795
  const marker = srcLine != null ? ` // @rip-src:${srcLine}` : "";
9056
- constructions.push(` __ripEl('${tagName}', {${iProps.map((p) => p.code).join(", ")}});${marker}`);
9796
+ constructions.push(` ${elFn}('${tagName}', {${iProps.map((p) => p.code).join(", ")}});${marker}`);
9057
9797
  } else {
9058
- constructions.push(` __ripEl('${tagName}', {${srcMarker}`);
9798
+ constructions.push(` ${elFn}('${tagName}', {${srcMarker}`);
9059
9799
  for (const p of iProps) {
9060
9800
  constructions.push(` ${p.code},` + (p.srcLine != null ? ` // @rip-src:${p.srcLine}` : ""));
9061
9801
  }
@@ -9243,6 +9983,9 @@ Expecting ${expected.join(", ")}, got '${this.tokenNames[symbol] || symbol}'`;
9243
9983
  for (const line of result.createLines) {
9244
9984
  lines.push(` ${line}`);
9245
9985
  }
9986
+ if (this._fragChildren.has(result.rootVar)) {
9987
+ lines.push(` this._nodes = [...${result.rootVar}.childNodes];`);
9988
+ }
9246
9989
  lines.push(` return ${result.rootVar};`);
9247
9990
  lines.push(" }");
9248
9991
  if (result.setupLines.length > 0) {
@@ -9411,6 +10154,19 @@ ${blockFactoriesCode}return ${lines.join(`
9411
10154
  }
9412
10155
  return false;
9413
10156
  };
10157
+ proto._isInScopeValue = function(name) {
10158
+ if (!name || typeof name !== "string")
10159
+ return false;
10160
+ if (this.reactiveMembers && this.reactiveMembers.has(name))
10161
+ return true;
10162
+ if (this.componentMembers && this.componentMembers.has(name))
10163
+ return true;
10164
+ if (this._isRenderLocal(name))
10165
+ return true;
10166
+ if (this.moduleBindings && this.moduleBindings.has(name))
10167
+ return true;
10168
+ return false;
10169
+ };
9414
10170
  proto.emitNode = function(sexpr) {
9415
10171
  if (this._isRenderBinding(sexpr)) {
9416
10172
  const [op, name, expr] = sexpr;
@@ -9610,6 +10366,8 @@ ${blockFactoriesCode}return ${lines.join(`
9610
10366
  if (!this._isRenderLocal(baseName) && (this.isHtmlTag(baseName || "div") || this.isComponent(baseName))) {
9611
10367
  const childVar = this.emitNode(arg);
9612
10368
  this._createLines.push(`${elVar}.appendChild(${childVar});`);
10369
+ } else if (/^[A-Za-z_$][\w$]*$/.test(val) && !this._isInScopeValue(val)) {
10370
+ this.emitAttributes(elVar, ["object", [":", val, "true"]]);
9613
10371
  } else {
9614
10372
  const textVar = this.newTextVar();
9615
10373
  if (val.startsWith('"') || val.startsWith("'") || val.startsWith("`")) {
@@ -9775,10 +10533,11 @@ ${blockFactoriesCode}return ${lines.join(`
9775
10533
  this._pushEffect(`${elVar}.className = __clsx(${valueCode2});`);
9776
10534
  }
9777
10535
  } else {
10536
+ const out = Array.isArray(value) ? `__clsx(${valueCode2})` : valueCode2;
9778
10537
  if (this._svgDepth > 0) {
9779
- this._createLines.push(`${elVar}.setAttribute('class', ${valueCode2});`);
10538
+ this._createLines.push(`${elVar}.setAttribute('class', ${out});`);
9780
10539
  } else {
9781
- this._createLines.push(`${elVar}.className = ${valueCode2};`);
10540
+ this._createLines.push(`${elVar}.className = ${out};`);
9782
10541
  }
9783
10542
  }
9784
10543
  continue;
@@ -10019,17 +10778,17 @@ ${blockFactoriesCode}return ${lines.join(`
10019
10778
  }
10020
10779
  factoryLines.push(` },`);
10021
10780
  factoryLines.push(` d(detaching) {`);
10022
- factoryLines.push(` for (const __c of _factoryChildren) { try { __c.unmount?.({removeDOM: false}); } catch (__e) { console.error('[Rip] factory child unmount error:', __e); } }`);
10781
+ factoryLines.push(` for (const __c of _factoryChildren) { try { __c.unmount?.({removeDOM: detaching}); } catch (__e) { console.error('[Rip] factory child unmount error:', __e); } }`);
10023
10782
  factoryLines.push(` _factoryChildren = [];`);
10024
10783
  if (hasEffects) {
10025
10784
  factoryLines.push(` disposers.forEach(d => d());`);
10026
10785
  }
10027
10786
  if (fragChildren) {
10028
10787
  for (const child of fragChildren) {
10029
- factoryLines.push(` if (detaching && ${child}) ${child}.remove();`);
10788
+ factoryLines.push(` if (detaching) __detach(${child});`);
10030
10789
  }
10031
10790
  } else {
10032
- factoryLines.push(` if (detaching && ${rootVar}) ${rootVar}.remove();`);
10791
+ factoryLines.push(` if (detaching) __detach(${rootVar});`);
10033
10792
  }
10034
10793
  factoryLines.push(` }`);
10035
10794
  factoryLines.push(` };`);
@@ -10200,7 +10959,7 @@ ${blockFactoriesCode}return ${lines.join(`
10200
10959
  for (const arg of args) {
10201
10960
  if (this.is(arg, "object")) {
10202
10961
  addObjectProps(arg);
10203
- } else if (isBareIdent(arg)) {
10962
+ } else if (isBareIdent(arg) && !this._isInScopeValue(arg)) {
10204
10963
  addProp(arg, "true");
10205
10964
  } else if (Array.isArray(arg) && (arg[0] === "->" || arg[0] === "=>")) {
10206
10965
  let block = arg[2];
@@ -10210,6 +10969,8 @@ ${blockFactoriesCode}return ${lines.join(`
10210
10969
  for (const child of block.slice(1)) {
10211
10970
  if (this.is(child, "object")) {
10212
10971
  addObjectProps(child);
10972
+ } else if (isBareIdent(child) && !this._isInScopeValue(child)) {
10973
+ addProp(child, "true");
10213
10974
  } else {
10214
10975
  domChildren.push(child);
10215
10976
  }
@@ -10350,6 +11111,17 @@ ${blockFactoriesCode}return ${lines.join(`
10350
11111
 
10351
11112
  let __currentComponent = null;
10352
11113
 
11114
+ // Remove a node from the DOM, tolerant of what it actually is. A
11115
+ // DocumentFragment (a multi-root component's _root) is skipped: it is emptied
11116
+ // the moment it is inserted, so it owns nothing to remove — its real top-level
11117
+ // nodes are tracked on the component instance (_nodes) and removed there. A
11118
+ // detached node (parentNode null) is a harmless no-op.
11119
+ function __detach(node) {
11120
+ if (!node || node.nodeType === 11) return;
11121
+ if (typeof node.remove === 'function') node.remove();
11122
+ else if (node.parentNode) node.parentNode.removeChild(node);
11123
+ }
11124
+
10353
11125
  function __pushComponent(component) {
10354
11126
  // The component stack tracks the currently-active scope (so __effect
10355
11127
  // and friends can find it). Parent assignment happens ONCE — on the
@@ -10646,6 +11418,7 @@ class __Component {
10646
11418
  constructor(props = {}) {
10647
11419
  Object.assign(this, props);
10648
11420
  if (!this.app && globalThis.__ripApp) this.app = globalThis.__ripApp;
11421
+ if (!this.router && globalThis.__ripRouter) this.router = globalThis.__ripRouter;
10649
11422
  // A component with render gates (<~) is honored only via route
10650
11423
  // matching — the renderer sets __ripGateMount around each route/layout
10651
11424
  // construction. Constructed as an embedded child (a parent scope is
@@ -10740,9 +11513,16 @@ class __Component {
10740
11513
  try {
10741
11514
  if (this.unmounted) this.unmounted();
10742
11515
  } catch (e) { console.error('[Rip] unmounted error:', e); }
10743
- if (removeDOM && this._root && this._root.parentNode) {
10744
- this._root.parentNode.removeChild(this._root);
11516
+ if (removeDOM) {
11517
+ if (this._nodes) {
11518
+ // Multi-root: detach each captured top-level node (the _root fragment
11519
+ // is empty and owns nothing).
11520
+ for (const n of this._nodes) __detach(n);
11521
+ } else if (this._root && this._root.parentNode) {
11522
+ this._root.parentNode.removeChild(this._root);
11523
+ }
10745
11524
  }
11525
+ this._nodes = null;
10746
11526
  }
10747
11527
  emit(name, detail) {
10748
11528
  if (this._root) {
@@ -10756,7 +11536,7 @@ class __Component {
10756
11536
 
10757
11537
  // Register on globalThis for runtime deduplication
10758
11538
  if (typeof globalThis !== 'undefined') {
10759
- globalThis.__ripComponent = { __pushComponent, __popComponent, __getCurrentComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __Component };
11539
+ globalThis.__ripComponent = { __pushComponent, __popComponent, __getCurrentComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __detach, __Component };
10760
11540
  }
10761
11541
 
10762
11542
  `;
@@ -11018,312 +11798,198 @@ if (typeof globalThis !== 'undefined') {
11018
11798
  for (let li = 0;li < info.perLineSegs.length; li++) {
11019
11799
  const target = info.lineOffset + li;
11020
11800
  if (target >= mergedPerLineSegs.length) {
11021
- while (mergedPerLineSegs.length <= target)
11022
- mergedPerLineSegs.push([]);
11023
- }
11024
- for (const seg of info.perLineSegs[li]) {
11025
- if (seg.src == null) {
11026
- mergedPerLineSegs[target].push({ genCol: seg.genCol });
11027
- } else {
11028
- const remapped = {
11029
- genCol: seg.genCol,
11030
- src: info.srcRemap[seg.src],
11031
- origLine: seg.origLine,
11032
- origCol: seg.origCol
11033
- };
11034
- if (seg.name != null)
11035
- remapped.name = info.nameRemap[seg.name];
11036
- mergedPerLineSegs[target].push(remapped);
11037
- }
11038
- }
11039
- }
11040
- }
11041
- const mergedMappings = encodeMappings(mergedPerLineSegs);
11042
- const mergedMap = {
11043
- version: 3,
11044
- sources: mergedSources,
11045
- sourcesContent: mergedSourcesContent,
11046
- names: mergedNames,
11047
- mappings: mergedMappings
11048
- };
11049
- return { js: mergedJS, mapJSON: JSON.stringify(mergedMap) };
11050
- }
11051
- function utf8ToBase64(str) {
11052
- if (typeof Buffer !== "undefined") {
11053
- return Buffer.from(str, "utf8").toString("base64");
11054
- }
11055
- const bytes = new TextEncoder().encode(str);
11056
- let bin = "";
11057
- for (let i = 0;i < bytes.length; i++)
11058
- bin += String.fromCharCode(bytes[i]);
11059
- return btoa(bin);
11060
- }
11061
- function mergeChunksWithInlineMap(chunks) {
11062
- const { js, mapJSON } = mergeChunks(chunks);
11063
- if (!mapJSON)
11064
- return js;
11065
- const b64 = utf8ToBase64(mapJSON);
11066
- return js + `
11067
- //# sourceMappingURL=data:application/json;base64,` + b64 + `
11068
- `;
11069
- }
11070
-
11071
- // src/stdlib.js
11072
- function getStdlibCode() {
11073
- return `// rip:stdlib:begin
11074
- globalThis.abort ??= (msg) => { if (msg) console.error(msg); process.exit(1); };
11075
- globalThis.assert ??= (v, msg) => { if (!v) throw new Error(msg || "Assertion failed"); };
11076
- globalThis.exit ??= (code) => process.exit(code || 0);
11077
- globalThis.kind ??= (v) => v != null ? (v.constructor?.name || Object.prototype.toString.call(v).slice(8, -1)).toLowerCase() : String(v);
11078
- globalThis.noop ??= () => {};
11079
- globalThis.p ??= console.log;
11080
- globalThis.pp ??= (v) => { console.dir(v, { depth: null, colors: true }); return v; };
11081
- globalThis.pj ??= (v) => { console.log(JSON.stringify(v, null, 2)); return v; };
11082
- globalThis.pr ??= (() => {
11083
- const BARE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
11084
- const esc = (s, q) => s.replace(/\\\\/g, "\\\\\\\\").replace(/\\n/g, "\\\\n").replace(/\\r/g, "\\\\r").replace(/\\t/g, "\\\\t").replace(new RegExp(q, 'g'), "\\\\" + q);
11085
- const qs = (s) => !s.includes("'") ? "'" + esc(s, "'") + "'" : !s.includes('"') ? '"' + esc(s, '"').split("#{").join("\\\\#{") + '"' : "'" + esc(s, "'") + "'";
11086
- const ks = (k) => { if (typeof k === 'symbol') { const n = Symbol.keyFor(k); return n && BARE.test(n) ? ':' + n : qs(String(k)); } return BARE.test(k) ? k : qs(k); };
11087
- const fmt = (v, d) => {
11088
- if (v === null) return 'null';
11089
- if (v === undefined) return 'undefined';
11090
- const t = typeof v;
11091
- if (t === 'number' || t === 'boolean') return String(v);
11092
- if (t === 'string') return qs(v);
11093
- if (t === 'symbol') { const n = Symbol.keyFor(v); return n && BARE.test(n) ? ':' + n : null; }
11094
- if (Array.isArray(v)) {
11095
- if (v.length === 0) return '[]';
11096
- const pad = ' '.repeat(d + 1), end = ' '.repeat(d);
11097
- return '[\\n' + pad + v.map(x => fmt(x, d + 1) ?? 'null').join('\\n' + pad) + '\\n' + end + ']';
11098
- }
11099
- if (t === 'object') {
11100
- const proto = Object.getPrototypeOf(v);
11101
- if (proto !== Object.prototype && proto !== null) return null;
11102
- const keys = Object.keys(v);
11103
- if (keys.length === 0) return '{}';
11104
- const pad = ' '.repeat(d + 1), end = ' '.repeat(d);
11105
- return '{\\n' + pad + keys.map(k => ks(k) + ': ' + (fmt(v[k], d + 1) ?? 'null')).join('\\n' + pad) + '\\n' + end + '}';
11106
- }
11107
- return null;
11108
- };
11109
- return (v) => { const s = fmt(v, 0); s !== null ? console.log(s) : console.dir(v, { depth: null, colors: true }); return v; };
11110
- })();
11111
- globalThis.raise ??= (a, b) => { throw (b !== undefined ? new a(b) : new Error(a)); };
11112
- globalThis.rand ??= (a, b) => b !== undefined ? (a > b && ([a, b] = [b, a]), Math.floor(Math.random() * (b - a + 1) + a)) : a ? Math.floor(Math.random() * a) : Math.random();
11113
- globalThis.sleep ??= (ms) => new Promise(r => setTimeout(r, ms));
11114
- globalThis.todo ??= (msg) => { throw new Error(msg || "Not implemented"); };
11115
- globalThis.warn ??= console.warn;
11116
- globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11117
- // rip:stdlib:end
11118
- `;
11119
- }
11120
-
11121
- // src/error.js
11122
- class RipError extends Error {
11123
- constructor(message, {
11124
- code = null,
11125
- file = null,
11126
- line = null,
11127
- column = null,
11128
- length = 1,
11129
- source = null,
11130
- suggestion = null,
11131
- phase = null
11132
- } = {}) {
11133
- super(message);
11134
- this.name = "RipError";
11135
- this.code = code;
11136
- this.file = file;
11137
- this.line = line;
11138
- this.column = column;
11139
- this.length = length;
11140
- this.source = source;
11141
- this.suggestion = suggestion;
11142
- this.phase = phase;
11143
- }
11144
- static fromLexer(err, source, file) {
11145
- let loc = err.location || {};
11146
- return new RipError(err.message, {
11147
- code: "E_SYNTAX",
11148
- file,
11149
- line: loc.first_line ?? null,
11150
- column: loc.first_column ?? null,
11151
- length: loc.last_column != null && loc.first_column != null ? loc.last_column - loc.first_column + 1 : 1,
11152
- source,
11153
- phase: "lexer"
11154
- });
11155
- }
11156
- static fromParser(err, source, file) {
11157
- let h = err.hash || {};
11158
- let loc = h.loc || {};
11159
- let line = h.line ?? loc.r ?? null;
11160
- let column = loc.first_column ?? loc.c ?? null;
11161
- let suggestion = null;
11162
- if (h.expected?.length) {
11163
- let first5 = h.expected.slice(0, 5).map((e) => e.replace(/'/g, ""));
11164
- suggestion = `Expected ${first5.join(", ")}`;
11165
- if (h.expected.length > 5)
11166
- suggestion += `, ... (${h.expected.length} total)`;
11167
- }
11168
- let token = h.token || "token";
11169
- let near = h.text ? ` near '${h.text}'` : "";
11170
- let message = `Unexpected ${token}${near}`;
11171
- return new RipError(message, {
11172
- code: "E_PARSE",
11173
- file,
11174
- line,
11175
- column,
11176
- length: h.text?.length || 1,
11177
- source,
11178
- suggestion,
11179
- phase: "parser"
11180
- });
11181
- }
11182
- static fromSExpr(message, sexpr, source, file, suggestion) {
11183
- let loc = sexpr?.loc || {};
11184
- return new RipError(message, {
11185
- code: "E_CODEGEN",
11186
- file,
11187
- line: loc.r ?? null,
11188
- column: loc.c ?? null,
11189
- length: loc.n ?? 1,
11190
- source,
11191
- suggestion,
11192
- phase: "codegen"
11193
- });
11194
- }
11195
- get locationString() {
11196
- let parts = [];
11197
- if (this.file)
11198
- parts.push(this.file);
11199
- if (this.line != null) {
11200
- parts.push(`${this.line + 1}:${(this.column ?? 0) + 1}`);
11201
- }
11202
- return parts.join(":");
11203
- }
11204
- format({ color = true } = {}) {
11205
- let c = color ? {
11206
- red: "\x1B[31m",
11207
- yellow: "\x1B[33m",
11208
- cyan: "\x1B[36m",
11209
- dim: "\x1B[2m",
11210
- bold: "\x1B[1m",
11211
- reset: "\x1B[0m"
11212
- } : { red: "", yellow: "", cyan: "", dim: "", bold: "", reset: "" };
11213
- let lines = [];
11214
- let loc = this.locationString;
11215
- let header = loc ? `${c.cyan}${loc}${c.reset} ` : "";
11216
- lines.push(`${header}${c.red}${c.bold}error${c.reset}${c.bold}: ${this.message}${c.reset}`);
11217
- let snippet = this._snippet();
11218
- if (snippet) {
11219
- lines.push("");
11220
- for (let s of snippet) {
11221
- if (s.type === "source") {
11222
- lines.push(`${c.dim}${s.gutter}${c.reset}${s.text}`);
11223
- } else if (s.type === "caret") {
11224
- lines.push(`${c.dim}${s.gutter}${c.reset}${c.red}${c.bold}${s.text}${c.reset}`);
11225
- }
11226
- }
11227
- }
11228
- if (this.suggestion) {
11229
- lines.push("");
11230
- lines.push(`${c.yellow}hint${c.reset}: ${this.suggestion}`);
11231
- }
11232
- return lines.join(`
11233
- `);
11234
- }
11235
- formatHTML() {
11236
- let lines = [];
11237
- lines.push('<div class="rip-error">');
11238
- lines.push("<style>");
11239
- lines.push(`.rip-error { font-family: ui-monospace, "SF Mono", Menlo, Monaco, monospace; font-size: 13px; line-height: 1.5; padding: 16px 20px; background: #1e1e2e; color: #cdd6f4; border-radius: 8px; overflow-x: auto; }`);
11240
- lines.push(`.rip-error .re-header { color: #f38ba8; font-weight: 600; }`);
11241
- lines.push(`.rip-error .re-loc { color: #89b4fa; }`);
11242
- lines.push(`.rip-error .re-gutter { color: #585b70; user-select: none; }`);
11243
- lines.push(`.rip-error .re-caret { color: #f38ba8; font-weight: 700; }`);
11244
- lines.push(`.rip-error .re-hint { color: #f9e2af; }`);
11245
- lines.push(`.rip-error .re-snippet { margin: 8px 0; }`);
11246
- lines.push("</style>");
11247
- let loc = this.locationString;
11248
- let locSpan = loc ? `<span class="re-loc">${esc(loc)}</span> ` : "";
11249
- lines.push(`<div class="re-header">${locSpan}error: ${esc(this.message)}</div>`);
11250
- let snippet = this._snippet();
11251
- if (snippet) {
11252
- lines.push('<pre class="re-snippet">');
11253
- for (let s of snippet) {
11254
- if (s.type === "source") {
11255
- lines.push(`<span class="re-gutter">${esc(s.gutter)}</span>${esc(s.text)}`);
11256
- } else if (s.type === "caret") {
11257
- lines.push(`<span class="re-gutter">${esc(s.gutter)}</span><span class="re-caret">${esc(s.text)}</span>`);
11258
- }
11259
- }
11260
- lines.push("</pre>");
11261
- }
11262
- if (this.suggestion) {
11263
- lines.push(`<div class="re-hint">hint: ${esc(this.suggestion)}</div>`);
11264
- }
11265
- lines.push("</div>");
11266
- return lines.join(`
11267
- `);
11268
- }
11269
- _snippet() {
11270
- if (this.source == null || this.line == null)
11271
- return null;
11272
- let sourceLines = this.source.split(`
11273
- `);
11274
- let errLine = this.line;
11275
- if (errLine < 0 || errLine >= sourceLines.length)
11276
- return null;
11277
- let contextRadius = 2;
11278
- let start = Math.max(0, errLine - contextRadius);
11279
- let end = Math.min(sourceLines.length - 1, errLine + contextRadius);
11280
- let gutterWidth = String(end + 1).length;
11281
- let result = [];
11282
- for (let i = start;i <= end; i++) {
11283
- let lineNum = String(i + 1).padStart(gutterWidth);
11284
- let gutter = ` ${lineNum} │ `;
11285
- result.push({ type: "source", gutter, text: sourceLines[i] });
11286
- if (i === errLine && this.column != null) {
11287
- let pad = " ".repeat(this.column);
11288
- let caretLen = Math.max(1, Math.min(this.length || 1, sourceLines[i].length - this.column));
11289
- let carets = "^".repeat(caretLen);
11290
- let emptyGutter = " ".repeat(gutterWidth + 2) + "│ ";
11291
- result.push({ type: "caret", gutter: emptyGutter, text: `${pad}${carets}` });
11801
+ while (mergedPerLineSegs.length <= target)
11802
+ mergedPerLineSegs.push([]);
11803
+ }
11804
+ for (const seg of info.perLineSegs[li]) {
11805
+ if (seg.src == null) {
11806
+ mergedPerLineSegs[target].push({ genCol: seg.genCol });
11807
+ } else {
11808
+ const remapped = {
11809
+ genCol: seg.genCol,
11810
+ src: info.srcRemap[seg.src],
11811
+ origLine: seg.origLine,
11812
+ origCol: seg.origCol
11813
+ };
11814
+ if (seg.name != null)
11815
+ remapped.name = info.nameRemap[seg.name];
11816
+ mergedPerLineSegs[target].push(remapped);
11817
+ }
11292
11818
  }
11293
11819
  }
11294
- return result;
11295
11820
  }
11821
+ const mergedMappings = encodeMappings(mergedPerLineSegs);
11822
+ const mergedMap = {
11823
+ version: 3,
11824
+ sources: mergedSources,
11825
+ sourcesContent: mergedSourcesContent,
11826
+ names: mergedNames,
11827
+ mappings: mergedMappings
11828
+ };
11829
+ return { js: mergedJS, mapJSON: JSON.stringify(mergedMap) };
11296
11830
  }
11297
- function isLexerError(err) {
11298
- return err instanceof SyntaxError && err.location != null;
11831
+ function utf8ToBase64(str) {
11832
+ if (typeof Buffer !== "undefined") {
11833
+ return Buffer.from(str, "utf8").toString("base64");
11834
+ }
11835
+ const bytes = new TextEncoder().encode(str);
11836
+ let bin = "";
11837
+ for (let i = 0;i < bytes.length; i++)
11838
+ bin += String.fromCharCode(bytes[i]);
11839
+ return btoa(bin);
11299
11840
  }
11300
- function isParserError(err) {
11301
- return !(err instanceof SyntaxError) && err.hash != null;
11841
+ function mergeChunksWithInlineMap(chunks) {
11842
+ const { js, mapJSON } = mergeChunks(chunks);
11843
+ if (!mapJSON)
11844
+ return js;
11845
+ const b64 = utf8ToBase64(mapJSON);
11846
+ return js + `
11847
+ //# sourceMappingURL=data:application/json;base64,` + b64 + `
11848
+ `;
11302
11849
  }
11303
- function toRipError(err, source, file) {
11304
- if (err instanceof RipError) {
11305
- if (file && !err.file)
11306
- err.file = file;
11307
- if (source && !err.source)
11308
- err.source = source;
11309
- return err;
11850
+ var MARK_OPEN = "";
11851
+ var MARK_SHUT = "";
11852
+ var MARK_SEP = "";
11853
+
11854
+ class MarkerRecorder {
11855
+ constructor() {
11856
+ this.nextId = 1;
11857
+ this.meta = new Map;
11858
+ }
11859
+ wrap(kind, loc, text, data = null) {
11860
+ if (loc == null || text == null || text === "")
11861
+ return text;
11862
+ const id = this.nextId++;
11863
+ this.meta.set(id, { kind, loc, data });
11864
+ return `${MARK_OPEN}${id}${MARK_SEP}${text}${MARK_SHUT}${id}${MARK_SEP}`;
11865
+ }
11866
+ get active() {
11867
+ return this.nextId > 1;
11310
11868
  }
11311
- if (isLexerError(err))
11312
- return RipError.fromLexer(err, source, file);
11313
- if (isParserError(err))
11314
- return RipError.fromParser(err, source, file);
11315
- return new RipError(err.message, { file, source, phase: "unknown" });
11316
11869
  }
11317
- function formatError(err, { source, file, color = true } = {}) {
11318
- let re = err instanceof RipError ? err : toRipError(err, source, file);
11319
- return re.format({ color });
11870
+ function stripMarkers(markedCode, recorder) {
11871
+ let out = "";
11872
+ let offset = 0, line = 0, column = 0;
11873
+ const marks = [];
11874
+ const stack = [];
11875
+ const readTag = (i) => {
11876
+ let j = i + 1;
11877
+ const sepAt = markedCode.indexOf(MARK_SEP, j);
11878
+ if (sepAt < 0)
11879
+ throw new Error("markers: unterminated tag");
11880
+ const id = Number(markedCode.slice(j, sepAt));
11881
+ if (!Number.isInteger(id))
11882
+ throw new Error("markers: malformed marker id");
11883
+ return { id, next: sepAt + 1 };
11884
+ };
11885
+ for (let i = 0;i < markedCode.length; ) {
11886
+ const ch = markedCode[i];
11887
+ if (ch === MARK_OPEN) {
11888
+ const { id, next } = readTag(i);
11889
+ const meta = recorder.meta.get(id);
11890
+ if (!meta)
11891
+ throw new Error(`markers: unknown open id ${id}`);
11892
+ stack.push({ id, meta, genStart: offset, genLine: line, genCol: column });
11893
+ i = next;
11894
+ continue;
11895
+ }
11896
+ if (ch === MARK_SHUT) {
11897
+ const { id, next } = readTag(i);
11898
+ const open = stack.pop();
11899
+ if (!open || open.id !== id)
11900
+ throw new Error(`markers: unbalanced close id ${id}`);
11901
+ marks.push({
11902
+ kind: open.meta.kind,
11903
+ loc: open.meta.loc,
11904
+ data: open.meta.data,
11905
+ genStart: open.genStart,
11906
+ genEnd: offset,
11907
+ genLine: open.genLine,
11908
+ genCol: open.genCol
11909
+ });
11910
+ i = next;
11911
+ continue;
11912
+ }
11913
+ out += ch;
11914
+ if (ch === `
11915
+ `) {
11916
+ line++;
11917
+ column = 0;
11918
+ } else {
11919
+ column++;
11920
+ }
11921
+ offset++;
11922
+ i++;
11923
+ }
11924
+ if (stack.length)
11925
+ throw new Error("markers: unclosed marker(s)");
11926
+ return { code: out, marks };
11320
11927
  }
11321
- function formatErrorHTML(err, { source, file } = {}) {
11322
- let re = err instanceof RipError ? err : toRipError(err, source, file);
11323
- return re.formatHTML();
11928
+
11929
+ // src/stdlib.js
11930
+ function getStdlibCode() {
11931
+ return `// rip:stdlib:begin
11932
+ globalThis.abort ??= (msg) => { if (msg) console.error(msg); process.exit(1); };
11933
+ globalThis.assert ??= (v, msg) => { if (!v) throw new Error(msg || "Assertion failed"); };
11934
+ globalThis.exit ??= (code) => process.exit(code || 0);
11935
+ globalThis.kind ??= (v) => v != null ? (v.constructor?.name || Object.prototype.toString.call(v).slice(8, -1)).toLowerCase() : String(v);
11936
+ globalThis.noop ??= () => {};
11937
+ globalThis.p ??= console.log;
11938
+ globalThis.pp ??= (v) => { console.dir(v, { depth: null, colors: true }); return v; };
11939
+ globalThis.pj ??= (v) => { console.log(JSON.stringify(v, null, 2)); return v; };
11940
+ globalThis.pr ??= (() => {
11941
+ const BARE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
11942
+ const esc = (s, q) => s.replace(/\\\\/g, "\\\\\\\\").replace(/\\n/g, "\\\\n").replace(/\\r/g, "\\\\r").replace(/\\t/g, "\\\\t").replace(new RegExp(q, 'g'), "\\\\" + q);
11943
+ const qs = (s) => !s.includes("'") ? "'" + esc(s, "'") + "'" : !s.includes('"') ? '"' + esc(s, '"').split("#{").join("\\\\#{") + '"' : "'" + esc(s, "'") + "'";
11944
+ const ks = (k) => { if (typeof k === 'symbol') { const n = Symbol.keyFor(k); return n && BARE.test(n) ? ':' + n : qs(String(k)); } return BARE.test(k) ? k : qs(k); };
11945
+ const fmt = (v, d) => {
11946
+ if (v === null) return 'null';
11947
+ if (v === undefined) return 'undefined';
11948
+ const t = typeof v;
11949
+ if (t === 'number' || t === 'boolean') return String(v);
11950
+ if (t === 'string') return qs(v);
11951
+ if (t === 'symbol') { const n = Symbol.keyFor(v); return n && BARE.test(n) ? ':' + n : null; }
11952
+ if (Array.isArray(v)) {
11953
+ if (v.length === 0) return '[]';
11954
+ const pad = ' '.repeat(d + 1), end = ' '.repeat(d);
11955
+ return '[\\n' + pad + v.map(x => fmt(x, d + 1) ?? 'null').join('\\n' + pad) + '\\n' + end + ']';
11956
+ }
11957
+ if (t === 'object') {
11958
+ const proto = Object.getPrototypeOf(v);
11959
+ if (proto !== Object.prototype && proto !== null) return null;
11960
+ const keys = Object.keys(v);
11961
+ if (keys.length === 0) return '{}';
11962
+ const pad = ' '.repeat(d + 1), end = ' '.repeat(d);
11963
+ return '{\\n' + pad + keys.map(k => ks(k) + ': ' + (fmt(v[k], d + 1) ?? 'null')).join('\\n' + pad) + '\\n' + end + '}';
11964
+ }
11965
+ return null;
11966
+ };
11967
+ return (v) => { const s = fmt(v, 0); s !== null ? console.log(s) : console.dir(v, { depth: null, colors: true }); return v; };
11968
+ })();
11969
+ globalThis.raise ??= (a, b) => { throw (b !== undefined ? new a(b) : new Error(a)); };
11970
+ globalThis.rand ??= (a, b) => b !== undefined ? (a > b && ([a, b] = [b, a]), Math.floor(Math.random() * (b - a + 1) + a)) : a ? Math.floor(Math.random() * a) : Math.random();
11971
+ globalThis.sleep ??= (ms) => new Promise(r => setTimeout(r, ms));
11972
+ globalThis.todo ??= (msg) => { throw new Error(msg || "Not implemented"); };
11973
+ globalThis.warn ??= console.warn;
11974
+ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11975
+ // rip:stdlib:end
11976
+ `;
11324
11977
  }
11325
- function esc(s) {
11326
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
11978
+
11979
+ // src/params.js
11980
+ function ripToTs(typeStr) {
11981
+ if (!typeStr)
11982
+ return typeStr;
11983
+ return typeStr.replace(/::/g, ":");
11984
+ }
11985
+ function emitTsParam({ name, ripType, optional, hasDefault }, mode) {
11986
+ let isOptional = optional || mode === "declaration" && hasDefault;
11987
+ let type = ripToTs(ripType);
11988
+ if (type)
11989
+ return `${name}${isOptional ? "?" : ""}: ${type}`;
11990
+ if (isOptional)
11991
+ return `${name}?: any`;
11992
+ return name;
11327
11993
  }
11328
11994
 
11329
11995
  // src/compiler.js
@@ -11647,12 +12313,44 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11647
12313
  if (this.options.foldProjections)
11648
12314
  foldDerivedSchemas(sexpr);
11649
12315
  this.collectProgramVariables(sexpr);
11650
- let code = this.emit(sexpr);
12316
+ this.moduleBindings = new Set;
12317
+ this.collectModuleBindings(sexpr);
12318
+ this.validateComprehensionFilters(sexpr);
12319
+ let code;
12320
+ if (this.options.exactMarks) {
12321
+ this.markRecorder = new MarkerRecorder;
12322
+ const marked = this.emit(sexpr);
12323
+ const stripped = stripMarkers(marked, this.markRecorder);
12324
+ this.markRecorder = null;
12325
+ code = stripped.code;
12326
+ this.exactMarks = stripped.marks;
12327
+ } else {
12328
+ code = this.emit(sexpr);
12329
+ }
11651
12330
  if (this.sourceMap)
11652
12331
  this.buildMappings();
11653
12332
  return code;
11654
12333
  }
12334
+ markIdent(code, node, loc) {
12335
+ if (!this.markRecorder || !loc)
12336
+ return code;
12337
+ if (typeof node === "string" || node instanceof String) {
12338
+ const name = str(node);
12339
+ if (/^[A-Za-z_$][\w$]*$/.test(name))
12340
+ return this.markRecorder.wrap("ident", loc, code);
12341
+ }
12342
+ return code;
12343
+ }
11655
12344
  buildMappings() {
12345
+ this._exactSrc = new Set;
12346
+ if (this.exactMarks) {
12347
+ for (const m of this.exactMarks) {
12348
+ if (!m.loc)
12349
+ continue;
12350
+ this.sourceMap.addMapping(m.genLine, m.genCol, m.loc.r, m.loc.c);
12351
+ this._exactSrc.add(m.loc.r + ":" + m.loc.c);
12352
+ }
12353
+ }
11656
12354
  if (this._importEntries) {
11657
12355
  let importLineOffset = 0;
11658
12356
  for (let entry of this._importEntries) {
@@ -11791,6 +12489,8 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11791
12489
  return ranges;
11792
12490
  };
11793
12491
  for (let { name, origLine, origCol } of subs) {
12492
+ if (this._exactSrc?.has(origLine + ":" + origCol))
12493
+ continue;
11794
12494
  let escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11795
12495
  let re = new RegExp("\\b" + escaped + "\\b", "g");
11796
12496
  let m;
@@ -11910,6 +12610,70 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
11910
12610
  }
11911
12611
  return null;
11912
12612
  }
12613
+ collectModuleBindings(program) {
12614
+ if (!Array.isArray(program))
12615
+ return;
12616
+ let statements;
12617
+ if (str(program[0]) === "program")
12618
+ statements = program.slice(1);
12619
+ else if (Array.isArray(program[0]))
12620
+ statements = program;
12621
+ else
12622
+ statements = [program];
12623
+ for (const stmt of statements)
12624
+ this._collectTopLevelBinding(stmt);
12625
+ }
12626
+ _addModuleBinding(name) {
12627
+ const s = name && name.valueOf ? name.valueOf() : name;
12628
+ if (typeof s === "string" && /^[A-Za-z_$][\w$]*$/.test(s))
12629
+ this.moduleBindings.add(s);
12630
+ }
12631
+ _collectTopLevelBinding(stmt) {
12632
+ if (!Array.isArray(stmt))
12633
+ return;
12634
+ const head = str(stmt[0]) ?? stmt[0];
12635
+ if (head === "export" || head === "export-default")
12636
+ return this._collectTopLevelBinding(stmt[1]);
12637
+ if (CodeEmitter.ASSIGNMENT_OPS.has(head)) {
12638
+ const target = stmt[1];
12639
+ if (typeof target === "string" || target instanceof String)
12640
+ this._addModuleBinding(target);
12641
+ else if (this.is(target, "array"))
12642
+ this.collectVarsFromArray(target, this.moduleBindings);
12643
+ else if (this.is(target, "object"))
12644
+ this.collectVarsFromObject(target, this.moduleBindings);
12645
+ return;
12646
+ }
12647
+ if (head === "def")
12648
+ return this._addModuleBinding(stmt[1]);
12649
+ if (head === "import")
12650
+ return this._collectImportNames(stmt.slice(1));
12651
+ }
12652
+ _collectImportNames(rest) {
12653
+ const addSpec = (spec) => {
12654
+ if (typeof spec === "string" || spec instanceof String)
12655
+ this._addModuleBinding(spec);
12656
+ else if (Array.isArray(spec)) {
12657
+ if (spec[0] === "*" && spec.length === 2)
12658
+ this._addModuleBinding(spec[1]);
12659
+ else
12660
+ for (const i of spec) {
12661
+ if (Array.isArray(i) && i.length === 2)
12662
+ this._addModuleBinding(i[1]);
12663
+ else
12664
+ this._addModuleBinding(i);
12665
+ }
12666
+ }
12667
+ };
12668
+ if (rest.length === 1)
12669
+ return;
12670
+ if (rest.length === 3) {
12671
+ this._addModuleBinding(rest[0]);
12672
+ addSpec(rest[1]);
12673
+ return;
12674
+ }
12675
+ addSpec(rest[0]);
12676
+ }
11913
12677
  collectProgramVariables(sexpr) {
11914
12678
  if (!Array.isArray(sexpr))
11915
12679
  return;
@@ -12327,10 +13091,10 @@ globalThis.zip ??= (...a) => a[0].map((_, i) => a.map(b => b[i]));
12327
13091
  }
12328
13092
  if (this.usesTemplates && !skip) {
12329
13093
  if (skipRT) {
12330
- code += `var { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __Component } = globalThis.__ripComponent;
13094
+ code += `var { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __detach, __Component } = globalThis.__ripComponent;
12331
13095
  `;
12332
13096
  } else if (typeof globalThis !== "undefined" && globalThis.__ripComponent) {
12333
- code += `const { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __Component } = globalThis.__ripComponent;
13097
+ code += `const { __pushComponent, __popComponent, setContext, getContext, hasContext, __clsx, __lis, __reconcile, __transition, __handleComponentError, __gateBind, __detach, __Component } = globalThis.__ripComponent;
12334
13098
  `;
12335
13099
  } else {
12336
13100
  code += this.getComponentRuntime();
@@ -12621,7 +13385,7 @@ function _setDataSection() {
12621
13385
  let v = this.emit(value, "value"), r = this.emit(regex, "value");
12622
13386
  let idx = captureIndex !== null ? this.emit(captureIndex, "value") : "0";
12623
13387
  let allowNL = r.includes("/m") ? ", true" : "";
12624
- return `(_ = toMatchable(${v}${allowNL}).match(${r})) && _[${idx}]`;
13388
+ return `((_ = toMatchable(${v}${allowNL}).match(${r})) && _[${idx}])`;
12625
13389
  }
12626
13390
  emitIndexAccess(head, rest) {
12627
13391
  let [arr, index] = rest;
@@ -12698,7 +13462,14 @@ function _setDataSection() {
12698
13462
  let bodyCode = this.emitFunctionBody(body, params, sideEffectOnly);
12699
13463
  let isAsync = this.containsAwait(body);
12700
13464
  let isGen = this.containsYield(body);
12701
- return `${isAsync ? "async " : ""}function${isGen ? "*" : ""} ${cleanName}(${paramList}) ${bodyCode}`;
13465
+ let ret = this.inlineReturnType(name);
13466
+ return `${isAsync ? "async " : ""}function${isGen ? "*" : ""} ${cleanName}(${paramList})${ret} ${bodyCode}`;
13467
+ }
13468
+ inlineReturnType(node) {
13469
+ if (!this.options.inlineTypes)
13470
+ return "";
13471
+ let rt = meta(node, "returnType");
13472
+ return rt ? `: ${ripToTs(rt)}` : "";
12702
13473
  }
12703
13474
  emitThinArrow(head, rest, context, sexpr) {
12704
13475
  let [params, body] = rest;
@@ -12709,7 +13480,8 @@ function _setDataSection() {
12709
13480
  let bodyCode = this.emitFunctionBody(body, params, sideEffectOnly);
12710
13481
  let isAsync = this.containsAwait(body);
12711
13482
  let isGen = this.containsYield(body);
12712
- let fn = `${isAsync ? "async " : ""}function${isGen ? "*" : ""}(${paramList}) ${bodyCode}`;
13483
+ let ret = this.inlineReturnType(sexpr?.[0]);
13484
+ let fn = `${isAsync ? "async " : ""}function${isGen ? "*" : ""}(${paramList})${ret} ${bodyCode}`;
12713
13485
  return context === "value" ? `(${fn})` : fn;
12714
13486
  }
12715
13487
  emitFatArrow(head, rest, context, sexpr) {
@@ -12718,7 +13490,8 @@ function _setDataSection() {
12718
13490
  params = ["it"];
12719
13491
  let sideEffectOnly = sexpr.isVoid || false;
12720
13492
  let paramList = this.emitParamList(params);
12721
- let isSingle = params.length === 1 && typeof params[0] === "string" && !paramList.includes("=") && !paramList.includes("...") && !paramList.includes("[") && !paramList.includes("{");
13493
+ let ret = this.inlineReturnType(sexpr?.[0]);
13494
+ let isSingle = !ret && params.length === 1 && typeof params[0] === "string" && !paramList.includes("=") && !paramList.includes("...") && !paramList.includes("[") && !paramList.includes("{");
12722
13495
  let paramSyntax = isSingle ? paramList : `(${paramList})`;
12723
13496
  let isAsync = this.containsAwait(body);
12724
13497
  let prefix = isAsync ? "async " : "";
@@ -12730,18 +13503,18 @@ function _setDataSection() {
12730
13503
  let code = this.emit(expr, "value");
12731
13504
  if (code[0] === "{")
12732
13505
  code = `(${code})`;
12733
- return `${prefix}${paramSyntax} => ${code}`;
13506
+ return `${prefix}${paramSyntax}${ret} => ${code}`;
12734
13507
  }
12735
13508
  }
12736
13509
  if (!Array.isArray(body) || body[0] !== "block") {
12737
13510
  let code = this.emit(body, "value");
12738
13511
  if (code[0] === "{")
12739
13512
  code = `(${code})`;
12740
- return `${prefix}${paramSyntax} => ${code}`;
13513
+ return `${prefix}${paramSyntax}${ret} => ${code}`;
12741
13514
  }
12742
13515
  }
12743
13516
  let bodyCode = this.emitFunctionBody(body, params, sideEffectOnly);
12744
- return `${prefix}${paramSyntax} => ${bodyCode}`;
13517
+ return `${prefix}${paramSyntax}${ret} => ${bodyCode}`;
12745
13518
  }
12746
13519
  emitReturn(head, rest, context, sexpr) {
12747
13520
  if (rest.length === 0)
@@ -12914,6 +13687,127 @@ function _setDataSection() {
12914
13687
  let [condition, thenBranch, ...elseBranches] = rest;
12915
13688
  return context === "value" ? this.emitIfAsExpression(condition, thenBranch, elseBranches) : this.emitIfAsStatement(condition, thenBranch, elseBranches);
12916
13689
  }
13690
+ validateComprehensionFilters(node) {
13691
+ if (!Array.isArray(node))
13692
+ return;
13693
+ if (str(node[0]) === "if") {
13694
+ let [, condition, thenBranch, ...elseBranches] = node;
13695
+ this._checkComprehensionFilterTrap(condition, thenBranch, elseBranches, node);
13696
+ }
13697
+ for (let i = 0;i < node.length; i++)
13698
+ this.validateComprehensionFilters(node[i]);
13699
+ }
13700
+ _checkComprehensionFilterTrap(condition, thenBranch, elseBranches, sexpr) {
13701
+ if (elseBranches.length)
13702
+ return;
13703
+ let thenVars = this._collectLeakVars(thenBranch);
13704
+ if (thenVars.size && this._referencesAnyName(condition, thenVars)) {
13705
+ this._throwComprehensionFilterTrap(sexpr);
13706
+ }
13707
+ let condVars = this._collectLeakVars(condition);
13708
+ if (condVars.size && this._referencesAnyName(thenBranch, condVars)) {
13709
+ this._throwComprehensionFilterTrap(sexpr);
13710
+ }
13711
+ }
13712
+ _collectLeakVars(node) {
13713
+ let names = new Set;
13714
+ let walk = (n) => {
13715
+ if (!Array.isArray(n))
13716
+ return;
13717
+ let h = str(n[0]);
13718
+ if (h === "comprehension" || h === "object-comprehension") {
13719
+ for (let v of this._collectComprehensionVars(n))
13720
+ names.add(v);
13721
+ }
13722
+ for (let i = 0;i < n.length; i++)
13723
+ walk(n[i]);
13724
+ };
13725
+ walk(node);
13726
+ return names;
13727
+ }
13728
+ _throwComprehensionFilterTrap(sexpr) {
13729
+ this.error("Comprehensions filter with `when`, not `if` — the trailing `if` wraps the whole comprehension and its loop variable is out of scope here", sexpr, { suggestion: "Use `(expr for x in xs when cond)` instead of `(expr for x in xs if cond)`" });
13730
+ }
13731
+ _collectComprehensionVars(comp) {
13732
+ let names = new Set;
13733
+ let addLeaves = (v) => {
13734
+ if (typeof v === "string") {
13735
+ names.add(v);
13736
+ return;
13737
+ }
13738
+ if (v instanceof String) {
13739
+ names.add(v.valueOf());
13740
+ return;
13741
+ }
13742
+ if (!Array.isArray(v))
13743
+ return;
13744
+ let head = str(v[0]);
13745
+ if (head === "default") {
13746
+ addLeaves(v[1]);
13747
+ return;
13748
+ }
13749
+ if (head === "..." || head === "rest") {
13750
+ addLeaves(v[1]);
13751
+ return;
13752
+ }
13753
+ if (head === "array") {
13754
+ for (let i = 1;i < v.length; i++)
13755
+ if (v[i] !== "," && v[i] != null)
13756
+ addLeaves(v[i]);
13757
+ return;
13758
+ }
13759
+ if (head === "object") {
13760
+ for (let i = 1;i < v.length; i++) {
13761
+ let entry = v[i];
13762
+ if (!Array.isArray(entry))
13763
+ continue;
13764
+ let h = str(entry[0]);
13765
+ if (h === null || h === ":")
13766
+ addLeaves(entry[2]);
13767
+ else if (h === "=" || h === "...")
13768
+ addLeaves(entry[1]);
13769
+ }
13770
+ return;
13771
+ }
13772
+ };
13773
+ let iterators = (str(comp[0]) === "object-comprehension" ? comp[3] : comp[2]) || [];
13774
+ for (let iter of iterators) {
13775
+ let vars = iter[1];
13776
+ if (Array.isArray(vars))
13777
+ for (let v of vars)
13778
+ addLeaves(v);
13779
+ else
13780
+ addLeaves(vars);
13781
+ }
13782
+ return names;
13783
+ }
13784
+ _referencesAnyName(node, names) {
13785
+ if (typeof node === "string")
13786
+ return names.has(node);
13787
+ if (node instanceof String)
13788
+ return names.has(node.valueOf());
13789
+ if (!Array.isArray(node))
13790
+ return false;
13791
+ let head = str(node[0]);
13792
+ if ((head === "." || head === "?.") && node.length === 3) {
13793
+ return this._referencesAnyName(node[1], names);
13794
+ }
13795
+ if (head === "comprehension" || head === "object-comprehension") {
13796
+ let inner = this._collectComprehensionVars(node);
13797
+ if ([...inner].some((n) => names.has(n))) {
13798
+ names = new Set([...names].filter((n) => !inner.has(n)));
13799
+ if (names.size === 0)
13800
+ return false;
13801
+ }
13802
+ }
13803
+ if (names.has(head))
13804
+ return true;
13805
+ for (let i = 1;i < node.length; i++) {
13806
+ if (this._referencesAnyName(node[i], names))
13807
+ return true;
13808
+ }
13809
+ return false;
13810
+ }
12917
13811
  emitForIn(head, rest, context, sexpr) {
12918
13812
  let [vars, iterable, step, guard, body] = rest;
12919
13813
  if (context === "value" && this.comprehensionDepth === 0) {
@@ -13198,8 +14092,11 @@ ${this.indent()}}`;
13198
14092
  let result = `(${v} in ${c})`;
13199
14093
  return isNeg ? `(!${result})` : result;
13200
14094
  }
13201
- emitRegexMatch(head, rest) {
14095
+ emitRegexMatch(head, rest, context, sexpr) {
13202
14096
  let [left, right] = rest;
14097
+ if (this.is(left, "=~") && !left.parenthesized) {
14098
+ this.error("`=~` does not chain — `a =~ b =~ c` would match the first match result against the second pattern", sexpr, { suggestion: "Parenthesize the intended match, e.g. `(a =~ b) =~ c`, or split into separate expressions" });
14099
+ }
13203
14100
  this.helpers.add("toMatchable");
13204
14101
  this.programVars.add("_");
13205
14102
  let r = this.emit(right, "value");
@@ -14065,18 +14962,21 @@ export default ${expr[1]}`;
14065
14962
  return `${tagCode}\`${content.slice(1, -1)}\``;
14066
14963
  return `${tagCode}\`${content}\``;
14067
14964
  }
14965
+ escapeTemplateText(s) {
14966
+ return s.replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
14967
+ }
14068
14968
  emitString(head, rest) {
14069
14969
  let result = "`";
14070
14970
  for (let part of rest) {
14071
14971
  if (part instanceof String) {
14072
- result += this.extractStringContent(part);
14972
+ result += this.escapeTemplateText(this.extractStringContent(part));
14073
14973
  } else if (typeof part === "string") {
14074
14974
  if (part.startsWith('"') || part.startsWith("'")) {
14075
14975
  if (this.options.debug)
14076
14976
  console.warn("[Rip] Unexpected quoted primitive in str:", part);
14077
- result += part.slice(1, -1);
14977
+ result += this.escapeTemplateText(part.slice(1, -1));
14078
14978
  } else {
14079
- result += part;
14979
+ result += this.escapeTemplateText(part);
14080
14980
  }
14081
14981
  } else if (Array.isArray(part)) {
14082
14982
  if (part.length === 1 && typeof part[0] === "string" && !Array.isArray(part[0])) {
@@ -14152,12 +15052,67 @@ export default ${expr[1]}`;
14152
15052
  this.restMiddleParam = null;
14153
15053
  return params.map((p) => this.formatParam(p)).join(", ");
14154
15054
  }
15055
+ destructuredType(node) {
15056
+ if (this.is(node, "object")) {
15057
+ let parts = [], hasType = false;
15058
+ for (let pair of node.slice(1)) {
15059
+ if (this.is(pair, "...")) {
15060
+ parts.push("[key: string]: unknown");
15061
+ continue;
15062
+ }
15063
+ let [op, key, value] = pair;
15064
+ let propName = str(key);
15065
+ if (op === "=") {
15066
+ let t2 = key instanceof String ? key.type : null;
15067
+ if (t2)
15068
+ hasType = true;
15069
+ parts.push(`${propName}?: ${t2 ? ripToTs(t2) : "any"}`);
15070
+ continue;
15071
+ }
15072
+ if (this.is(value, "object") || this.is(value, "array")) {
15073
+ let inner = this.destructuredType(value);
15074
+ if (inner.hasType)
15075
+ hasType = true;
15076
+ parts.push(`${propName}: ${inner.type}`);
15077
+ continue;
15078
+ }
15079
+ let t = value instanceof String && value.type || key instanceof String && key.type || null;
15080
+ if (t)
15081
+ hasType = true;
15082
+ parts.push(`${propName}: ${t ? ripToTs(t) : "any"}`);
15083
+ }
15084
+ return { type: `{${parts.join(", ")}}`, hasType };
15085
+ }
15086
+ if (this.is(node, "array")) {
15087
+ let parts = [], hasType = false;
15088
+ for (let el of node.slice(1)) {
15089
+ if (el === "," || el === "...")
15090
+ continue;
15091
+ if (this.is(el, "...")) {
15092
+ parts.push("...any[]");
15093
+ continue;
15094
+ }
15095
+ let typedEl = this.is(el, "=") ? el[1] : el;
15096
+ let t = typedEl instanceof String ? typedEl.type : null;
15097
+ if (t)
15098
+ hasType = true;
15099
+ parts.push(t ? ripToTs(t) : "any");
15100
+ }
15101
+ return { type: `[${parts.join(", ")}]`, hasType };
15102
+ }
15103
+ return { type: "any", hasType: false };
15104
+ }
14155
15105
  formatParam(param) {
14156
15106
  if (typeof param === "string")
14157
15107
  return param;
14158
15108
  if (param instanceof String) {
14159
- if (this.options.inlineTypes && param.type) {
14160
- return `${param.valueOf()}: ${param.type.replace(/::/g, ":")}`;
15109
+ if (this.options.inlineTypes) {
15110
+ return emitTsParam({
15111
+ name: param.valueOf(),
15112
+ ripType: param.type,
15113
+ optional: !!meta(param, "optional"),
15114
+ hasDefault: false
15115
+ }, "implementation");
14161
15116
  }
14162
15117
  return param.valueOf();
14163
15118
  }
@@ -14173,6 +15128,18 @@ export default ${expr[1]}`;
14173
15128
  }
14174
15129
  if (this.is(param, ".") && param[1] === "this")
14175
15130
  return param[2];
15131
+ if ((this.is(param, "object") || this.is(param, "array")) && this.options.inlineTypes) {
15132
+ let { type, hasType } = this.destructuredType(param);
15133
+ let saved = this.options.inlineTypes;
15134
+ this.options.inlineTypes = false;
15135
+ let pattern;
15136
+ try {
15137
+ pattern = this.formatParam(param);
15138
+ } finally {
15139
+ this.options.inlineTypes = saved;
15140
+ }
15141
+ return hasType ? `${pattern}: ${type}` : pattern;
15142
+ }
14176
15143
  if (this.is(param, "array")) {
14177
15144
  let els = param.slice(1).map((el) => {
14178
15145
  if (el === ",")
@@ -14268,10 +15235,11 @@ export default ${expr[1]}`;
14268
15235
  `;
14269
15236
  }
14270
15237
  let firstIsSuper = autoAssignments.length > 0 && statements.length > 0 && Array.isArray(statements[0]) && statements[0][0] === "super";
14271
- let genStatements = (stmts) => {
15238
+ let genStatements = (stmts, locBase = null) => {
14272
15239
  stmts.forEach((stmt, index) => {
14273
15240
  let isLast = index === stmts.length - 1;
14274
15241
  let h = Array.isArray(stmt) ? stmt[0] : null;
15242
+ let stmtLoc = locBase != null && body.subLocs ? body.subLocs[locBase + index] : null;
14275
15243
  if (!isLast && h === "comprehension") {
14276
15244
  let [, expr, iters, guards] = stmt;
14277
15245
  code += this.indent() + this.emitComprehensionAsLoop(expr, iters, guards) + `
@@ -14330,7 +15298,7 @@ export default ${expr[1]}`;
14330
15298
  let ctx = needsReturn ? "value" : "statement";
14331
15299
  let sc = this.emit(stmt, ctx);
14332
15300
  if (needsReturn)
14333
- code += this.indent() + "return " + sc + `;
15301
+ code += this.indent() + "return " + this.markIdent(sc, stmt, stmtLoc) + `;
14334
15302
  `;
14335
15303
  else
14336
15304
  code += this.indent() + this.addSemicolon(stmt, sc) + `
@@ -14353,7 +15321,8 @@ export default ${expr[1]}`;
14353
15321
  for (let a of autoAssignments)
14354
15322
  code += this.indent() + a + `;
14355
15323
  `;
14356
- genStatements(statements);
15324
+ let locBase = this.is(body, "block") && body.subLocs && statements.length === body.length - 1 ? 1 : null;
15325
+ genStatements(statements, locBase);
14357
15326
  }
14358
15327
  if (sideEffectOnly && statements.length > 0) {
14359
15328
  let lastH = Array.isArray(statements[statements.length - 1]) ? statements[statements.length - 1][0] : null;
@@ -15836,6 +16805,7 @@ if (typeof globalThis !== 'undefined') {
15836
16805
  return token[0];
15837
16806
  }
15838
16807
  };
16808
+ setSubLocs(!!this.options.exactMarks);
15839
16809
  let sexpr;
15840
16810
  try {
15841
16811
  sexpr = parser.parse(source);
@@ -15881,6 +16851,7 @@ if (typeof globalThis !== 'undefined') {
15881
16851
  inlineTypes: this.options.inlineTypes,
15882
16852
  schemaMode: this.options.schemaMode,
15883
16853
  foldProjections: this.options.foldProjections,
16854
+ exactMarks: this.options.exactMarks,
15884
16855
  sourceMap
15885
16856
  });
15886
16857
  let code = generator.compile(sexpr);
@@ -15952,8 +16923,8 @@ if (typeof globalThis !== 'undefined') {
15952
16923
  return new CodeEmitter({}).getComponentRuntime();
15953
16924
  }
15954
16925
  // src/browser.js
15955
- var VERSION = "3.16.1";
15956
- var BUILD_DATE = "2026-06-19@18:03:41GMT";
16926
+ var VERSION = "3.17.0-wip.1";
16927
+ var BUILD_DATE = "2026-06-28@00:08:17GMT";
15957
16928
  if (typeof globalThis !== "undefined") {
15958
16929
  if (!globalThis.__rip)
15959
16930
  new Function(getReactiveRuntime())();
@@ -16051,18 +17022,28 @@ ${tagged}
16051
17022
  sanitizeSourceURL
16052
17023
  };
16053
17024
  }
17025
+ function flag(el, name, def, enums = []) {
17026
+ const raw = el?.getAttribute(name);
17027
+ if (raw == null)
17028
+ return def;
17029
+ const v = raw.trim().toLowerCase();
17030
+ if (v === "" || v === "true" || v === "on" || v === "yes" || v === "1")
17031
+ return true;
17032
+ if (v === "false" || v === "off" || v === "no" || v === "0")
17033
+ return false;
17034
+ if (enums.includes(v))
17035
+ return v;
17036
+ console.error(`Rip: invalid ${name}="${raw}" (expected ${["true", "false", ...enums].join(" | ")}); using ${JSON.stringify(def)}`);
17037
+ return def;
17038
+ }
16054
17039
  async function processRipScripts() {
16055
17040
  const sources = [];
16056
17041
  let lastBundle;
16057
17042
  const runtimeTag = document.querySelector('script[src$="rip.min.js"], script[src$="rip.js"]');
16058
- const dataSrc = runtimeTag?.getAttribute("data-src");
16059
- if (dataSrc !== null && dataSrc !== undefined) {
16060
- for (const url of dataSrc.trim().split(/\s+/)) {
16061
- if (url)
16062
- sources.push({ url });
16063
- }
16064
- } else if (runtimeTag && /^https?:$/.test(location.protocol)) {
16065
- sources.push({ url: "/app", optional: true });
17043
+ const dataSrc = runtimeTag?.getAttribute("data-src")?.trim();
17044
+ if (dataSrc) {
17045
+ for (const url of dataSrc.split(/\s+/))
17046
+ sources.push({ url });
16066
17047
  }
16067
17048
  for (const script of document.querySelectorAll('script[type="text/rip"]')) {
16068
17049
  if (script.src) {
@@ -16101,18 +17082,18 @@ ${tagged}
16101
17082
  else if (s.code)
16102
17083
  individual.push(s);
16103
17084
  }
16104
- const routerAttr = runtimeTag?.getAttribute("data-router");
16105
17085
  lastBundle = bundles[bundles.length - 1];
17086
+ const router = flag(runtimeTag, "data-router", "auto", ["hash", "history"]);
16106
17087
  let hasRouter, hashRouter;
16107
- if (routerAttr != null) {
16108
- hasRouter = routerAttr !== "false";
16109
- hashRouter = routerAttr === "hash";
16110
- } else {
17088
+ if (router === "auto") {
16111
17089
  hasRouter = !!lastBundle?.data?.router;
16112
17090
  hashRouter = false;
17091
+ } else {
17092
+ hasRouter = router !== false;
17093
+ hashRouter = router === "hash";
16113
17094
  }
16114
17095
  if (hasRouter && bundles.length > 0) {
16115
- const debug = runtimeTag?.getAttribute("data-debug") !== "false";
17096
+ const debug = flag(runtimeTag, "data-debug", true);
16116
17097
  if (globalThis.__ripDebug)
16117
17098
  globalThis.__ripDebug.enabled = debug;
16118
17099
  const baseOpts = { skipRuntimes: true, skipExports: true, skipImports: true };
@@ -16137,10 +17118,10 @@ ${js}
16137
17118
  }
16138
17119
  const app = importRip.modules?.["app.rip"];
16139
17120
  if (app?.launch) {
16140
- const persistAttr = runtimeTag.getAttribute("data-persist");
17121
+ const persist = flag(runtimeTag, "data-persist", false, ["session", "local"]);
16141
17122
  const launchOpts = { bundle: lastBundle, hash: hashRouter };
16142
- if (persistAttr != null)
16143
- launchOpts.persist = persistAttr === "local" ? "local" : true;
17123
+ if (persist)
17124
+ launchOpts.persist = persist === "local" ? "local" : true;
16144
17125
  await app.launch(launchOpts);
16145
17126
  }
16146
17127
  } else {
@@ -16176,7 +17157,7 @@ ${js}
16176
17157
  window.__RIP__.components = sourceStore;
16177
17158
  }
16178
17159
  }
16179
- const debug = runtimeTag?.getAttribute("data-debug") !== "false";
17160
+ const debug = flag(runtimeTag, "data-debug", true);
16180
17161
  if (globalThis.__ripDebug)
16181
17162
  globalThis.__ripDebug.enabled = debug;
16182
17163
  const baseOpts = { skipRuntimes: true, skipExports: true, skipImports: true };
@@ -16210,9 +17191,9 @@ ${js}
16210
17191
  globalThis.__ripApp = app;
16211
17192
  if (typeof window !== "undefined")
16212
17193
  window.app = app;
16213
- const persistAttr = runtimeTag.getAttribute("data-persist");
16214
- if (persistAttr != null && globalThis.persistStash) {
16215
- globalThis.persistStash(app, { local: persistAttr === "local" });
17194
+ const persist = flag(runtimeTag, "data-persist", false, ["session", "local"]);
17195
+ if (persist && globalThis.persistStash) {
17196
+ globalThis.persistStash(app, { local: persist === "local" });
16216
17197
  }
16217
17198
  }
16218
17199
  }
@@ -16241,8 +17222,8 @@ ${wrapped}
16241
17222
  }
16242
17223
  }
16243
17224
  }
16244
- const reloadAttr = runtimeTag?.getAttribute("data-reload");
16245
- const shouldReload = reloadAttr != null ? reloadAttr !== "false" : !!lastBundle?.data?.watch;
17225
+ const reload = flag(runtimeTag, "data-reload", "auto");
17226
+ const shouldReload = reload === "auto" ? !!lastBundle?.data?.watch : reload === true;
16246
17227
  if (shouldReload && !globalThis.__ripLaunched) {
16247
17228
  let ready = false;
16248
17229
  let retryDelay = 1000;
@@ -17429,24 +18410,29 @@ ${indented}`);
17429
18410
  _pending.value = true;
17430
18411
  _succeeded.value = false;
17431
18412
  _error.value = null;
17432
- return await (async () => {
18413
+ try {
18414
+ r = await fn(...args);
18415
+ } catch (e) {
18416
+ if (!(me === generation))
18417
+ return;
18418
+ _error.value = e;
17433
18419
  try {
17434
- r = await fn(...args);
17435
- if (me === generation) {
17436
- _succeeded.value = true;
17437
- await opts.onSuccess?.(r);
17438
- }
17439
- return r;
17440
- } catch (e) {
17441
- if (!(me === generation))
17442
- return;
17443
- _error.value = e;
17444
18420
  if (opts.onError) {
17445
- await opts.onError(e);
18421
+ return await opts.onError(e);
17446
18422
  } else {
17447
18423
  throw e;
17448
18424
  }
17449
- return;
18425
+ } finally {
18426
+ _pending.value = false;
18427
+ }
18428
+ }
18429
+ if (!(me === generation))
18430
+ return;
18431
+ return await (async () => {
18432
+ try {
18433
+ _succeeded.value = true;
18434
+ await opts.onSuccess?.(r);
18435
+ return r;
17450
18436
  } finally {
17451
18437
  if (me === generation)
17452
18438
  _pending.value = false;
@@ -19142,6 +20128,7 @@ ${indented}`);
19142
20128
  return console.error(`[Rip] Error ${err.status}: ${err.message || err.path}`);
19143
20129
  }
19144
20130
  });
20131
+ globalThis.__ripRouter = router;
19145
20132
  renderer = createRenderer({
19146
20133
  router,
19147
20134
  app,
@@ -19171,6 +20158,7 @@ ${indented}`);
19171
20158
  persistDisposer?.();
19172
20159
  delete globalThis[classesKey];
19173
20160
  delete globalThis.__ripApp;
20161
+ delete globalThis.__ripRouter;
19174
20162
  delete globalThis.__ripLaunched;
19175
20163
  if (win.app === app) {
19176
20164
  delete win.app;