gofront 0.0.7 → 0.0.9

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.
@@ -2,8 +2,6 @@
2
2
 
3
3
  import { ERROR, isComplex } from "../typechecker/types.js";
4
4
 
5
- const globalError = ERROR;
6
-
7
5
  const INT_TYPE_NAMES = new Set([
8
6
  "int",
9
7
  "uint",
@@ -163,7 +161,7 @@ export const expressionGenMethods = {
163
161
  return "process.argv";
164
162
  }
165
163
  }
166
- // time constants (nanosecond durations)
164
+ // time constants (nanosecond durations and layout strings)
167
165
  if (expr.expr.kind === "Ident" && expr.expr.name === "time") {
168
166
  switch (expr.field) {
169
167
  case "Millisecond":
@@ -174,6 +172,68 @@ export const expressionGenMethods = {
174
172
  return "60000000000";
175
173
  case "Hour":
176
174
  return "3600000000000";
175
+ case "RFC3339":
176
+ return '"2006-01-02T15:04:05Z07:00"';
177
+ case "RFC3339Nano":
178
+ return '"2006-01-02T15:04:05.999999999Z07:00"';
179
+ case "DateOnly":
180
+ return '"2006-01-02"';
181
+ case "TimeOnly":
182
+ return '"15:04:05"';
183
+ case "DateTime":
184
+ return '"2006-01-02 15:04:05"';
185
+ case "UTC":
186
+ case "Local":
187
+ return "null";
188
+ case "January":
189
+ return "1";
190
+ case "February":
191
+ return "2";
192
+ case "March":
193
+ return "3";
194
+ case "April":
195
+ return "4";
196
+ case "May":
197
+ return "5";
198
+ case "June":
199
+ return "6";
200
+ case "July":
201
+ return "7";
202
+ case "August":
203
+ return "8";
204
+ case "September":
205
+ return "9";
206
+ case "October":
207
+ return "10";
208
+ case "November":
209
+ return "11";
210
+ case "December":
211
+ return "12";
212
+ case "Sunday":
213
+ return "0";
214
+ case "Monday":
215
+ return "1";
216
+ case "Tuesday":
217
+ return "2";
218
+ case "Wednesday":
219
+ return "3";
220
+ case "Thursday":
221
+ return "4";
222
+ case "Friday":
223
+ return "5";
224
+ case "Saturday":
225
+ return "6";
226
+ }
227
+ }
228
+ // utf8 constants
229
+ if (expr.expr.kind === "Ident" && expr.expr.name === "utf8") {
230
+ switch (expr.field) {
231
+ case "RuneError":
232
+ return "0xFFFD";
233
+ case "MaxRune":
234
+ return "0x10FFFF";
235
+ case "UTFMax":
236
+ return "4";
177
237
  }
178
238
  }
179
239
  const base = this.genExpr(expr.expr);
@@ -456,7 +516,7 @@ export const expressionGenMethods = {
456
516
  expr.func.kind === "SelectorExpr" &&
457
517
  expr.func.field === "Error" &&
458
518
  expr.func.expr._type &&
459
- (expr.func.expr._type === globalError ||
519
+ (expr.func.expr._type === ERROR ||
460
520
  expr.func.expr._type?.name === "error" ||
461
521
  (expr.func.expr._type?.kind === "named" &&
462
522
  expr.func.expr._type?.underlying?.kind === "interface"))
@@ -485,6 +545,9 @@ export const expressionGenMethods = {
485
545
  if (recvName === "regexp.Regexp") {
486
546
  return this._genRegexpMethodCall(expr.func.field, expr);
487
547
  }
548
+ if (recvName === "time.Time") {
549
+ return this._genTimeMethodCall(expr.func.field, expr);
550
+ }
488
551
  }
489
552
 
490
553
  // Mark the callee so SelectorExpr knows it's being called, not used as a value
@@ -1096,6 +1159,10 @@ export const expressionGenMethods = {
1096
1159
  // strings.Builder has { _buf: string }, bytes.Buffer has { _buf: [] }.
1097
1160
  return `((b,s) => { const w = b?.value ?? b; if (typeof w.WriteString === "function") return [w.WriteString(s), null]; if (typeof w._buf === "string") { w._buf += s; return [s.length, null]; } if (Array.isArray(w._buf)) { w._buf.push(...new TextEncoder().encode(s)); return [s.length, null]; } return [0, "io.WriteString: unsupported writer"]; })(${w}, ${s})`;
1098
1161
  }
1162
+ case "ReadAll": {
1163
+ const r = this.genExpr(expr.args[0]);
1164
+ return `((r) => { const w = r?.value ?? r; if (typeof w._src === "string") { const s = w._src.slice(w._pos); w._pos = w._src.length; return [[...s].map(c => c.charCodeAt(0)), null]; } if (Array.isArray(w._src)) { const b = w._src.slice(w._pos); w._pos = w._src.length; return [b, null]; } const chunks = []; const buf = new Array(4096); let err = null; while (!err) { const [n, e] = w.Read(buf); if (n > 0) chunks.push(...buf.slice(0, n)); err = e; } return [chunks, err === "EOF" ? null : err]; })(${r})`;
1165
+ }
1099
1166
  }
1100
1167
  return undefined;
1101
1168
  },
@@ -1202,6 +1269,12 @@ export const expressionGenMethods = {
1202
1269
  return this._genHtml(fn, a);
1203
1270
  case "io":
1204
1271
  return this._genIo(fn, a, expr);
1272
+ case "rand":
1273
+ return this._genRand(fn, a);
1274
+ case "utf8":
1275
+ return this._genUtf8(fn, a);
1276
+ case "path":
1277
+ return this._genPath(fn, a, expr);
1205
1278
  case "gom":
1206
1279
  return this._genGom(fn, expr);
1207
1280
  default:
@@ -1425,6 +1498,31 @@ export const expressionGenMethods = {
1425
1498
  return `(${buf} += __sprintf("%v\\n", ${restJs}))`;
1426
1499
  return `(${buf} += __sprintf("%v", ${restJs}))`;
1427
1500
  }
1501
+ case "Sscan": {
1502
+ const strArg = this.genExpr(expr.args[0]);
1503
+ const restArgs = expr.args
1504
+ .slice(1)
1505
+ .map((e) => this.genExpr(e))
1506
+ .join(", ");
1507
+ return `((str, ...ptrs) => { const tokens = str.trim().split(/\\s+/).filter(Boolean); let n = 0; for (let i = 0; i < ptrs.length && i < tokens.length; i++) { const t = tokens[i]; const p = ptrs[i]; if (typeof p.value === "number") p.value = Number(t); else if (typeof p.value === "boolean") p.value = t === "true"; else p.value = t; n++; } return [n, n < ptrs.length ? "unexpected EOF" : null]; })(${strArg}, ${restArgs})`;
1508
+ }
1509
+ case "Sscanln": {
1510
+ const strArg = this.genExpr(expr.args[0]);
1511
+ const restArgs = expr.args
1512
+ .slice(1)
1513
+ .map((e) => this.genExpr(e))
1514
+ .join(", ");
1515
+ return `((str, ...ptrs) => { const line = str.split("\\n")[0]; const tokens = line.trim().split(/\\s+/).filter(Boolean); let n = 0; for (let i = 0; i < ptrs.length && i < tokens.length; i++) { const t = tokens[i]; const p = ptrs[i]; if (typeof p.value === "number") p.value = Number(t); else if (typeof p.value === "boolean") p.value = t === "true"; else p.value = t; n++; } return [n, n < ptrs.length ? "unexpected EOF" : null]; })(${strArg}, ${restArgs})`;
1516
+ }
1517
+ case "Sscanf": {
1518
+ const strArg = this.genExpr(expr.args[0]);
1519
+ const fmtArg = this.genExpr(expr.args[1]);
1520
+ const restArgs = expr.args
1521
+ .slice(2)
1522
+ .map((e) => this.genExpr(e))
1523
+ .join(", ");
1524
+ return `((str, _fmt, ...ptrs) => { const tokens = str.trim().split(/\\s+/).filter(Boolean); let n = 0; for (let i = 0; i < ptrs.length && i < tokens.length; i++) { const t = tokens[i]; const p = ptrs[i]; if (typeof p.value === "number") p.value = Number(t); else if (typeof p.value === "boolean") p.value = t === "true"; else p.value = t; n++; } return [n, n < ptrs.length ? "input does not match format" : null]; })(${strArg}, ${fmtArg}, ${restArgs})`;
1525
+ }
1428
1526
  default:
1429
1527
  return undefined;
1430
1528
  }
@@ -1473,6 +1571,56 @@ export const expressionGenMethods = {
1473
1571
  return `${args[0]}.join(${args[1]})`;
1474
1572
  case "EqualFold":
1475
1573
  return `${args[0]}.toLowerCase() === ${args[1]}.toLowerCase()`;
1574
+ case "Fields":
1575
+ return `(${args[0]}).trim() === '' ? [] : (${args[0]}).trim().split(/\\s+/)`;
1576
+ case "Cut":
1577
+ return `((s, sep) => { const i = s.indexOf(sep); return i < 0 ? [s, "", false] : [s.slice(0, i), s.slice(i + sep.length), true]; })(${args[0]}, ${args[1]})`;
1578
+ case "CutPrefix":
1579
+ return `(${args[0]}).startsWith(${args[1]}) ? [(${args[0]}).slice((${args[1]}).length), true] : [${args[0]}, false]`;
1580
+ case "CutSuffix":
1581
+ return `(${args[0]}).endsWith(${args[1]}) ? [(${args[0]}).slice(0, -(${args[1]}).length), true] : [${args[0]}, false]`;
1582
+ case "SplitN":
1583
+ return `((s, sep, n) => { if (n === 0) return []; if (n < 0) return s.split(sep); const r = []; let cur = s; for (let i = 1; i < n && cur.length; i++) { const j = cur.indexOf(sep); if (j < 0) break; r.push(cur.slice(0, j)); cur = cur.slice(j + sep.length); } r.push(cur); return r; })(${args[0]}, ${args[1]}, ${args[2]})`;
1584
+ case "SplitAfter":
1585
+ return `((s, sep) => { if (sep === "") return [...s]; const r = []; let cur = s; while (cur.length) { const j = cur.indexOf(sep); if (j < 0) { r.push(cur); break; } r.push(cur.slice(0, j + sep.length)); cur = cur.slice(j + sep.length); } return r; })(${args[0]}, ${args[1]})`;
1586
+ case "SplitAfterN":
1587
+ return `((s, sep, n) => { if (n === 0) return []; if (n < 0 || sep === "") return ((s, sep) => { if (sep === "") return [...s]; const r = []; let cur = s; while (cur.length) { const j = cur.indexOf(sep); if (j < 0) { r.push(cur); break; } r.push(cur.slice(0, j + sep.length)); cur = cur.slice(j + sep.length); } return r; })(s, sep); const r = []; let cur = s; for (let i = 1; i < n && cur.length; i++) { const j = cur.indexOf(sep); if (j < 0) break; r.push(cur.slice(0, j + sep.length)); cur = cur.slice(j + sep.length); } r.push(cur); return r; })(${args[0]}, ${args[1]}, ${args[2]})`;
1588
+ case "IndexAny":
1589
+ return `((s, chars) => { let m = -1; for (const c of chars) { const i = s.indexOf(c); if (i >= 0 && (m < 0 || i < m)) m = i; } return m; })(${args[0]}, ${args[1]})`;
1590
+ case "LastIndexAny":
1591
+ return `((s, chars) => { let m = -1; for (const c of chars) { const i = s.lastIndexOf(c); if (i > m) m = i; } return m; })(${args[0]}, ${args[1]})`;
1592
+ case "ContainsAny":
1593
+ return `[...(${args[1]})].some(c => (${args[0]}).includes(c))`;
1594
+ case "ContainsRune":
1595
+ return `(${args[0]}).includes(String.fromCodePoint(${args[1]}))`;
1596
+ case "IndexRune":
1597
+ return `(${args[0]}).indexOf(String.fromCodePoint(${args[1]}))`;
1598
+ case "IndexByte":
1599
+ return `(${args[0]}).indexOf(String.fromCharCode(${args[1]}))`;
1600
+ case "LastIndexByte":
1601
+ return `(${args[0]}).lastIndexOf(String.fromCharCode(${args[1]}))`;
1602
+ case "Map":
1603
+ return `[...(${args[1]})].map(c => String.fromCodePoint((${args[0]})(c.codePointAt(0)))).join("")`;
1604
+ case "Title":
1605
+ return `(${args[0]}).replace(/\\b\\w/g, c => c.toUpperCase())`;
1606
+ case "ToTitle":
1607
+ return `(${args[0]}).toUpperCase()`;
1608
+ case "TrimFunc":
1609
+ return `((s, f) => { let l = 0, r = s.length; while (l < r && f(s.codePointAt(l))) l++; while (r > l && f(s.codePointAt(r - 1))) r--; return s.slice(l, r); })(${args[0]}, ${args[1]})`;
1610
+ case "TrimLeftFunc":
1611
+ return `((s, f) => { let l = 0; while (l < s.length && f(s.codePointAt(l))) l++; return s.slice(l); })(${args[0]}, ${args[1]})`;
1612
+ case "TrimRightFunc":
1613
+ return `((s, f) => { let r = s.length; while (r > 0 && f(s.codePointAt(r - 1))) r--; return s.slice(0, r); })(${args[0]}, ${args[1]})`;
1614
+ case "IndexFunc":
1615
+ return `((s, f) => { for (let i = 0; i < s.length; i++) { const cp = s.codePointAt(i); if (f(cp)) return i; if (cp > 0xFFFF) i++; } return -1; })(${args[0]}, ${args[1]})`;
1616
+ case "LastIndexFunc":
1617
+ return `((s, f) => { for (let i = s.length - 1; i >= 0; i--) { const cp = s.codePointAt(i); if (f(cp)) return i; } return -1; })(${args[0]}, ${args[1]})`;
1618
+ case "NewReader":
1619
+ return `{_src: ${args[0]}, _pos: 0, Read(p) { const n = Math.min(p.length, this._src.length - this._pos); for (let i = 0; i < n; i++) p[i] = this._src.charCodeAt(this._pos + i); this._pos += n; return [n, n === 0 ? "EOF" : null]; }, Len() { return this._src.length - this._pos; }, Reset(s) { this._src = s; this._pos = 0; }}`;
1620
+ case "NewReplacer": {
1621
+ const allArgs = args.join(", ");
1622
+ return `((...pairs) => { const p = []; for (let i = 0; i < pairs.length; i += 2) p.push([pairs[i], pairs[i+1]]); return { _p: p, Replace(s) { let r = s; for (const [o, n] of this._p) r = r.split(o).join(n); return r; } }; })(${allArgs})`;
1623
+ }
1476
1624
  default:
1477
1625
  return undefined;
1478
1626
  }
@@ -1511,6 +1659,38 @@ export const expressionGenMethods = {
1511
1659
  return `${__bs}(${args[0]}).split(${__bs}(${args[1]})).map(p => ${__sb}(p))`;
1512
1660
  case "Join":
1513
1661
  return `${__sb}(${args[0]}.map(p => ${__bs}(p)).join(${__bs}(${args[1]})))`;
1662
+ case "ReplaceAll":
1663
+ return `((b, o, n) => { const r = []; let i = 0; while (i <= b.length - o.length) { if (o.every((v, j) => b[i + j] === v)) { r.push(...n); i += o.length; } else r.push(b[i++]); } return r.concat(b.slice(i)); })(${args[0]}, ${args[1]}, ${args[2]})`;
1664
+ case "TrimPrefix":
1665
+ return `((b, p) => p.every((v, i) => b[i] === v) ? b.slice(p.length) : b.slice())(${args[0]}, ${args[1]})`;
1666
+ case "TrimSuffix":
1667
+ return `((b, s) => s.length && s.every((v, i) => b[b.length - s.length + i] === v) ? b.slice(0, -s.length) : b.slice())(${args[0]}, ${args[1]})`;
1668
+ case "TrimLeft":
1669
+ return `((b, c) => { let i = 0; while (i < b.length && c.includes(String.fromCharCode(b[i]))) i++; return b.slice(i); })(${args[0]}, ${args[1]})`;
1670
+ case "TrimRight":
1671
+ return `((b, c) => { let i = b.length; while (i > 0 && c.includes(String.fromCharCode(b[i - 1]))) i--; return b.slice(0, i); })(${args[0]}, ${args[1]})`;
1672
+ case "TrimFunc":
1673
+ return `((b, f) => { let l = 0, r = b.length; while (l < r && f(b[l])) l++; while (r > l && f(b[r - 1])) r--; return b.slice(l, r); })(${args[0]}, ${args[1]})`;
1674
+ case "IndexByte":
1675
+ return `(${args[0]}).indexOf(${args[1]})`;
1676
+ case "LastIndex":
1677
+ return `((b, s) => { for (let i = b.length - s.length; i >= 0; i--) if (s.every((v, j) => b[i + j] === v)) return i; return -1; })(${args[0]}, ${args[1]})`;
1678
+ case "LastIndexByte":
1679
+ return `(${args[0]}).lastIndexOf(${args[1]})`;
1680
+ case "Fields":
1681
+ return `((b) => { const s = String.fromCharCode(...b).trim(); return s === '' ? [] : s.split(/\\s+/).map(w => [...w].map(c => c.charCodeAt(0))); })(${args[0]})`;
1682
+ case "Cut":
1683
+ return `((b, sep) => { for (let i = 0; i <= b.length - sep.length; i++) if (sep.every((v, j) => b[i + j] === v)) return [b.slice(0, i), b.slice(i + sep.length), true]; return [b.slice(), [], false]; })(${args[0]}, ${args[1]})`;
1684
+ case "ContainsAny":
1685
+ return `[...(${args[1]})].some(c => (${args[0]}).includes(c.charCodeAt(0)))`;
1686
+ case "ContainsRune":
1687
+ return `(${args[0]}).includes(${args[1]})`;
1688
+ case "Map":
1689
+ return `(${args[1]}).map(v => (${args[0]})(v))`;
1690
+ case "SplitN":
1691
+ return `((b, sep, n) => { if (n === 0) return []; if (n < 0) return ((b, sep) => { const r = []; let i = 0; while (i <= b.length) { const j = b.findIndex((_, k) => k >= i && sep.every((v, l) => b[k + l] === sep[l])); if (j < 0 || j >= b.length) break; r.push(b.slice(i, j)); i = j + sep.length; } r.push(b.slice(i)); return r; })(b, sep); const r = []; let i = 0; for (let c = 1; c < n; c++) { const j = b.findIndex((_, k) => k >= i && sep.every((v, l) => b[k + l] === sep[l])); if (j < 0) break; r.push(b.slice(i, j)); i = j + sep.length; } r.push(b.slice(i)); return r; })(${args[0]}, ${args[1]}, ${args[2]})`;
1692
+ case "NewReader":
1693
+ return `{_src: ${args[0]}, _pos: 0, Read(p) { const n = Math.min(p.length, this._src.length - this._pos); for (let i = 0; i < n; i++) p[i] = this._src[this._pos + i]; this._pos += n; return [n, n === 0 ? "EOF" : null]; }, Len() { return this._src.length - this._pos; }, Reset(b) { this._src = b; this._pos = 0; }}`;
1514
1694
  default:
1515
1695
  return undefined;
1516
1696
  }
@@ -1535,6 +1715,14 @@ export const expressionGenMethods = {
1535
1715
  return `(Number.isNaN(parseInt(${args[0]}, ${args[1]} || 10)) ? [0, "invalid syntax"] : [parseInt(${args[0]}, ${args[1]} || 10), null])`;
1536
1716
  case "ParseBool":
1537
1717
  return `(${args[0]} === "true" || ${args[0]} === "1" ? [true, null] : ${args[0]} === "false" || ${args[0]} === "0" ? [false, null] : [false, "invalid syntax"])`;
1718
+ case "Quote":
1719
+ return `JSON.stringify(${args[0]})`;
1720
+ case "Unquote":
1721
+ return `((s) => { try { const v = JSON.parse(s); return [v, null]; } catch(e) { return ["", "invalid syntax"]; } })(${args[0]})`;
1722
+ case "AppendInt":
1723
+ return `[...(${args[0]}), ...new TextEncoder().encode((${args[1]}).toString(${args[2]}))]`;
1724
+ case "AppendFloat":
1725
+ return `[...(${args[0]}), ...new TextEncoder().encode(${args[1]}.toFixed(${args[3]} < 0 ? 6 : ${args[3]}))]`;
1538
1726
  default:
1539
1727
  return undefined;
1540
1728
  }
@@ -1553,6 +1741,12 @@ export const expressionGenMethods = {
1553
1741
  return `${args[0]}.sort((a, b) => ${args[1]}(a, b) ? -1 : ${args[1]}(b, a) ? 1 : 0)`;
1554
1742
  case "SliceIsSorted":
1555
1743
  return `${args[0]}.every((v, i, a) => i === 0 || ${args[1]}(a[i - 1], v))`;
1744
+ case "Search":
1745
+ return `((n, f) => { let lo = 0, hi = n; while (lo < hi) { const mid = (lo + hi) >>> 1; if (f(mid)) hi = mid; else lo = mid + 1; } return lo; })(${args[0]}, ${args[1]})`;
1746
+ case "IntsAreSorted":
1747
+ case "Float64sAreSorted":
1748
+ case "StringsAreSorted":
1749
+ return `(${args[0]}).every((v, i, a) => i === 0 || a[i - 1] <= v)`;
1556
1750
  default:
1557
1751
  return undefined;
1558
1752
  }
@@ -1601,6 +1795,30 @@ export const expressionGenMethods = {
1601
1795
  return `(${args[1]} > 0 ? ${args[0]} === Infinity : ${args[1]} < 0 ? ${args[0]} === -Infinity : !Number.isFinite(${args[0]}))`;
1602
1796
  case "NaN":
1603
1797
  return "NaN";
1798
+ case "Atan":
1799
+ return `Math.atan(${args[0]})`;
1800
+ case "Atan2":
1801
+ return `Math.atan2(${args[0]}, ${args[1]})`;
1802
+ case "Asin":
1803
+ return `Math.asin(${args[0]})`;
1804
+ case "Acos":
1805
+ return `Math.acos(${args[0]})`;
1806
+ case "Exp":
1807
+ return `Math.exp(${args[0]})`;
1808
+ case "Exp2":
1809
+ return `Math.pow(2, ${args[0]})`;
1810
+ case "Trunc":
1811
+ return `Math.trunc(${args[0]})`;
1812
+ case "Hypot":
1813
+ return `Math.hypot(${args[0]}, ${args[1]})`;
1814
+ case "Signbit":
1815
+ return `(${args[0]} < 0 || Object.is(${args[0]}, -0))`;
1816
+ case "Copysign":
1817
+ return `(Math.abs(${args[0]}) * (${args[1]} < 0 || Object.is(${args[1]}, -0) ? -1 : 1))`;
1818
+ case "Dim":
1819
+ return `Math.max(${args[0]} - ${args[1]}, 0)`;
1820
+ case "Remainder":
1821
+ return `(${args[0]} - Math.round(${args[0]} / ${args[1]}) * ${args[1]})`;
1604
1822
  default:
1605
1823
  return undefined;
1606
1824
  }
@@ -1665,15 +1883,142 @@ export const expressionGenMethods = {
1665
1883
  }
1666
1884
  },
1667
1885
 
1886
+ _genTimeMethodCall(method, expr) {
1887
+ const recv = expr.func.expr;
1888
+ const recvJs = this.genExpr(recv);
1889
+ const args = expr.args.map((a) => this.genExpr(a));
1890
+ switch (method) {
1891
+ case "Format":
1892
+ this._usesTimeFmt = true;
1893
+ return `__timeFmt(${recvJs}._d, ${args[0]})`;
1894
+ case "String":
1895
+ this._usesTimeFmt = true;
1896
+ return `__timeFmt(${recvJs}._d, "2006-01-02T15:04:05Z07:00")`;
1897
+ case "Year":
1898
+ return `${recvJs}._d.getFullYear()`;
1899
+ case "Month":
1900
+ return `${recvJs}._d.getMonth() + 1`;
1901
+ case "Day":
1902
+ return `${recvJs}._d.getDate()`;
1903
+ case "Hour":
1904
+ return `${recvJs}._d.getHours()`;
1905
+ case "Minute":
1906
+ return `${recvJs}._d.getMinutes()`;
1907
+ case "Second":
1908
+ return `${recvJs}._d.getSeconds()`;
1909
+ case "Weekday":
1910
+ return `${recvJs}._d.getDay()`;
1911
+ case "Unix":
1912
+ return `Math.floor(${recvJs}._d.getTime() / 1000)`;
1913
+ case "UnixMilli":
1914
+ return `${recvJs}._d.getTime()`;
1915
+ case "Add":
1916
+ return `{_d: new Date(${recvJs}._d.getTime() + (${args[0]}))}`;
1917
+ case "Sub":
1918
+ return `${recvJs}._d.getTime() - (${args[0]})._d.getTime()`;
1919
+ case "Before":
1920
+ return `${recvJs}._d < (${args[0]})._d`;
1921
+ case "After":
1922
+ return `${recvJs}._d > (${args[0]})._d`;
1923
+ case "Equal":
1924
+ return `${recvJs}._d.getTime() === (${args[0]})._d.getTime()`;
1925
+ default:
1926
+ return undefined;
1927
+ }
1928
+ },
1929
+
1668
1930
  _genTime(fn, a) {
1669
1931
  const args = a();
1670
1932
  switch (fn) {
1671
1933
  case "Now":
1672
- return "Date.now()";
1934
+ return "{_d: new Date()}";
1673
1935
  case "Since":
1674
- return `(Date.now() - ${args[0]})`;
1936
+ return `(Date.now() - (${args[0]})._d.getTime())`;
1675
1937
  case "Sleep":
1676
1938
  return `await new Promise(r => setTimeout(r, ${args[0]} / 1000000))`;
1939
+ case "Parse":
1940
+ this._usesTimeParse = true;
1941
+ return `__timeParse(${args[0]}, ${args[1]})`;
1942
+ case "Unix":
1943
+ return `{_d: new Date((${args[0]}) * 1000)}`;
1944
+ case "Date":
1945
+ return `{_d: new Date(${args[0]}, ${args[1]} - 1, ${args[2]}, ${args[3]}, ${args[4]}, ${args[5]})}`;
1946
+ default:
1947
+ return undefined;
1948
+ }
1949
+ },
1950
+
1951
+ _genRand(fn, a) {
1952
+ const args = a();
1953
+ switch (fn) {
1954
+ case "Intn":
1955
+ case "Int63n":
1956
+ case "Int31n":
1957
+ return `Math.floor(Math.random() * ${args[0]})`;
1958
+ case "Float64":
1959
+ case "Float32":
1960
+ return "Math.random()";
1961
+ case "Int":
1962
+ case "Int31":
1963
+ return "Math.floor(Math.random() * 2147483647)";
1964
+ case "Int63":
1965
+ return "Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)";
1966
+ case "Seed":
1967
+ return "(void 0)";
1968
+ case "Shuffle":
1969
+ return `((n, f) => { for (let i = n - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); f(i, j); } })(${args[0]}, ${args[1]})`;
1970
+ case "Perm":
1971
+ return `((n) => { const a = Array.from({length: n}, (_, i) => i); for (let i = n - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; })(${args[0]})`;
1972
+ default:
1973
+ return undefined;
1974
+ }
1975
+ },
1976
+
1977
+ _genUtf8(fn, a) {
1978
+ const args = a();
1979
+ switch (fn) {
1980
+ case "RuneCountInString":
1981
+ return `[...(${args[0]})].length`;
1982
+ case "RuneLen":
1983
+ return `((r) => r < 0 ? -1 : r <= 0x7F ? 1 : r <= 0x7FF ? 2 : r <= 0xFFFF ? (r >= 0xD800 && r <= 0xDFFF ? -1 : 3) : r <= 0x10FFFF ? 4 : -1)(${args[0]})`;
1984
+ case "ValidString":
1985
+ return `/[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/.test(${args[0]}) === false`;
1986
+ case "ValidRune":
1987
+ return `(${args[0]}) >= 0 && (${args[0]}) <= 0x10FFFF && !((${args[0]}) >= 0xD800 && (${args[0]}) <= 0xDFFF)`;
1988
+ case "DecodeRuneInString":
1989
+ return `((s) => { if (!s) return [0xFFFD, 0]; const cp = s.codePointAt(0); return [cp, cp > 0xFFFF ? 2 : 1]; })(${args[0]})`;
1990
+ case "DecodeLastRuneInString":
1991
+ return `((s) => { if (!s) return [0xFFFD, 0]; const i = s.length > 1 && s.charCodeAt(s.length - 1) >= 0xDC00 && s.charCodeAt(s.length - 1) <= 0xDFFF ? s.length - 2 : s.length - 1; const cp = s.codePointAt(i); return [cp, cp > 0xFFFF ? 2 : 1]; })(${args[0]})`;
1992
+ case "FullRuneInString":
1993
+ return `(${args[0]}).length > 0`;
1994
+ default:
1995
+ return undefined;
1996
+ }
1997
+ },
1998
+
1999
+ _genPath(fn, a, expr) {
2000
+ const args = a();
2001
+ switch (fn) {
2002
+ case "Base":
2003
+ return `((p) => { if (!p) return "."; const stripped = p.replace(/\\/+$/, ""); if (!stripped) return "/"; const i = stripped.lastIndexOf("/"); return i < 0 ? stripped : stripped.slice(i + 1) || "/"; })(${args[0]})`;
2004
+ case "Dir":
2005
+ return `((p) => { const i = p.lastIndexOf("/"); if (i < 0) return "."; if (i === 0) return "/"; return p.slice(0, i); })(${args[0]})`;
2006
+ case "Ext":
2007
+ return `((p) => { const b = p.slice(p.lastIndexOf("/") + 1); const i = b.lastIndexOf("."); return i <= 0 ? "" : b.slice(i); })(${args[0]})`;
2008
+ case "Join": {
2009
+ this._usesPathClean = true;
2010
+ const allArgs = expr.args.map((e) => this.genExpr(e)).join(", ");
2011
+ return `__pathClean([${allArgs}].filter(x => x !== "").join("/"))`;
2012
+ }
2013
+ case "Clean":
2014
+ this._usesPathClean = true;
2015
+ return `__pathClean(${args[0]})`;
2016
+ case "IsAbs":
2017
+ return `(${args[0]}).startsWith("/")`;
2018
+ case "Split":
2019
+ return `((p) => { const i = p.lastIndexOf("/"); return i < 0 ? ["", p] : [p.slice(0, i + 1), p.slice(i + 1)]; })(${args[0]})`;
2020
+ case "Match":
2021
+ return `((pat, name) => { try { const sp=/[.+^$()|[\\]\\\\]/g; const re = new RegExp("^" + pat.replace(sp, "\\\\$&").replace(/\\*/g, "[^/]*").replace(/\\?/g, "[^/]") + "$"); return [re.test(name), null]; } catch(e) { return [false, "syntax error in pattern"]; } })(${args[0]}, ${args[1]})`;
1677
2022
  default:
1678
2023
  return undefined;
1679
2024
  }
@@ -16,9 +16,10 @@ function vlqEncode(value) {
16
16
  return result;
17
17
  }
18
18
 
19
- export function buildSourceMap(sources, mappings) {
20
- // sources: string[]
21
- // mappings: Array<{ genLine: number, srcLine: number, srcFileIdx?: number }> (0-based)
19
+ export function buildSourceMap(sources, mappings, sourcesContent) {
20
+ // sources: string[]
21
+ // mappings: Array<{ genLine: number, srcLine: number, srcFileIdx?: number }> (0-based)
22
+ // sourcesContent: string[] | undefined — original file contents, embedded for DevTools
22
23
  // Emits one segment per generated line, column 0 → source line (delta-encoded).
23
24
  const lines = [];
24
25
  let prevSrcLine = 0;
@@ -44,10 +45,12 @@ export function buildSourceMap(sources, mappings) {
44
45
  lines.push(""); // no mapping for this generated line
45
46
  }
46
47
  }
47
- return JSON.stringify({
48
+ const map = {
48
49
  version: 3,
49
50
  sources,
50
51
  names: [],
51
52
  mappings: lines.join(";"),
52
- });
53
+ };
54
+ if (sourcesContent) map.sourcesContent = sourcesContent;
55
+ return JSON.stringify(map);
53
56
  }