kadence-lang 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +208 -0
  3. package/bin/kadence.js +806 -0
  4. package/package.json +64 -0
  5. package/src/compiler.js +2291 -0
  6. package/src/vite-plugin-kadence.js +39 -0
  7. package/stdlib/check-helpers.js +13 -0
  8. package/stdlib/check.js +57 -0
  9. package/stdlib/check.kade +21 -0
  10. package/stdlib/color-helpers.js +34 -0
  11. package/stdlib/color.js +60 -0
  12. package/stdlib/color.kade +24 -0
  13. package/stdlib/console.js +57 -0
  14. package/stdlib/console.kade +21 -0
  15. package/stdlib/crypto-helpers.js +17 -0
  16. package/stdlib/crypto.js +46 -0
  17. package/stdlib/crypto.kade +11 -0
  18. package/stdlib/datetime.js +68 -0
  19. package/stdlib/datetime.kade +32 -0
  20. package/stdlib/encoding.js +55 -0
  21. package/stdlib/encoding.kade +19 -0
  22. package/stdlib/env.js +46 -0
  23. package/stdlib/env.kade +11 -0
  24. package/stdlib/file.js +94 -0
  25. package/stdlib/file.kade +57 -0
  26. package/stdlib/html.js +65 -0
  27. package/stdlib/html.kade +29 -0
  28. package/stdlib/json.js +63 -0
  29. package/stdlib/json.kade +28 -0
  30. package/stdlib/list.js +109 -0
  31. package/stdlib/list.kade +75 -0
  32. package/stdlib/math.js +76 -0
  33. package/stdlib/math.kade +39 -0
  34. package/stdlib/network.js +66 -0
  35. package/stdlib/network.kade +38 -0
  36. package/stdlib/number.js +53 -0
  37. package/stdlib/number.kade +17 -0
  38. package/stdlib/object-helpers.js +44 -0
  39. package/stdlib/object.js +59 -0
  40. package/stdlib/object.kade +23 -0
  41. package/stdlib/path.js +58 -0
  42. package/stdlib/path.kade +23 -0
  43. package/stdlib/process-helpers.js +18 -0
  44. package/stdlib/process.js +62 -0
  45. package/stdlib/process.kade +29 -0
  46. package/stdlib/promise-helpers.js +21 -0
  47. package/stdlib/promise.js +54 -0
  48. package/stdlib/promise.kade +19 -0
  49. package/stdlib/random.js +82 -0
  50. package/stdlib/random.kade +46 -0
  51. package/stdlib/regex-helpers.js +18 -0
  52. package/stdlib/regex.js +46 -0
  53. package/stdlib/regex.kade +11 -0
  54. package/stdlib/stream.js +58 -0
  55. package/stdlib/stream.kade +22 -0
  56. package/stdlib/string-helpers.js +16 -0
  57. package/stdlib/string.js +101 -0
  58. package/stdlib/string.kade +66 -0
  59. package/stdlib/system.js +66 -0
  60. package/stdlib/system.kade +31 -0
  61. package/stdlib/test-helpers.js +18 -0
  62. package/stdlib/test.js +72 -0
  63. package/stdlib/test.kade +37 -0
  64. package/stdlib/url.js +50 -0
  65. package/stdlib/url.kade +14 -0
  66. package/stdlib/uuid.js +70 -0
  67. package/stdlib/uuid.kade +35 -0
@@ -0,0 +1,2291 @@
1
+ const ohm = require("ohm-js");
2
+ const { SourceNode } = require("source-map");
3
+
4
+ /**
5
+ * Pre-processor to convert indentation-based blocks into brace-based blocks.
6
+ * Handles both standard indentation and 'end'-terminated blocks.
7
+ */
8
+ function preprocess(code) {
9
+ // Strip carriage returns to handle Windows line endings consistently
10
+ code = code.replace(/\r/g, "");
11
+ const lines = code.split("\n");
12
+ let result = "";
13
+ let indentStack = [0];
14
+ let inBacktickString = false;
15
+
16
+ for (let i = 0; i < lines.length; i++) {
17
+ const line = lines[i];
18
+
19
+ // Check for backticks to toggle string state
20
+ // We remove escaped backticks to avoid false counts
21
+ const cleanLine = line.replace(/\\`/g, "__");
22
+ const backTickCount = (cleanLine.match(/`/g) || []).length;
23
+
24
+ const wasInString = inBacktickString;
25
+ if (backTickCount % 2 !== 0) {
26
+ inBacktickString = !inBacktickString;
27
+ }
28
+ const willBeInString = inBacktickString;
29
+
30
+ // If we started inside a string, preserve it exactly and skip indentation logic
31
+ if (wasInString) {
32
+ result += line + "\n";
33
+ continue;
34
+ }
35
+
36
+ const trimmed = line.trim();
37
+
38
+ if (trimmed.length === 0) {
39
+ result += "\n";
40
+ continue;
41
+ }
42
+
43
+ const currentIndent = line.search(/\S/);
44
+ let lastIndent = indentStack[indentStack.length - 1];
45
+
46
+ // Block-continuation keywords (else, elif, when) stay inside the current block - don't pop when dedenting to them
47
+ const _isBlockContinuation = /^(else|elif|when\s)/.test(trimmed);
48
+
49
+ // Handle dedentation based on indentation level or 'end' keyword
50
+ if (currentIndent < lastIndent || trimmed === "end") {
51
+ while (
52
+ indentStack.length > 1 &&
53
+ (currentIndent < indentStack[indentStack.length - 1] || trimmed === "end")
54
+ ) {
55
+ result += "}\n";
56
+ indentStack.pop();
57
+ if (trimmed === "end" && indentStack[indentStack.length - 1] <= currentIndent) break;
58
+ }
59
+ if (trimmed === "end") continue;
60
+ // User wrote "}" or "})" on its own line; we already emitted "}" from the stack, so skip adding the line
61
+ if (trimmed === "}") continue;
62
+ if (trimmed === "})") {
63
+ result += ")\n";
64
+ continue;
65
+ }
66
+ }
67
+
68
+ // Add the line itself
69
+ result += line;
70
+
71
+ // If we are about to enter a multi-line string, DO NOT generate a block
72
+ if (willBeInString) {
73
+ result += "\n";
74
+ continue;
75
+ }
76
+
77
+ // Check if we should add an opening brace
78
+ let nextIndent = -1;
79
+ for (let j = i + 1; j < lines.length; j++) {
80
+ const nextTrimmed = lines[j].trim();
81
+
82
+ // We must handle the case where next line is inside a string?
83
+ // But we can't easily peek state.
84
+ // Simplified assumption: Indentation of next NON-EMPTY line determines block.
85
+
86
+ if (nextTrimmed.length > 0) {
87
+ if (nextTrimmed === "end") {
88
+ nextIndent = currentIndent;
89
+ } else {
90
+ nextIndent = lines[j].search(/\S/);
91
+ }
92
+ break;
93
+ }
94
+ }
95
+
96
+ if (nextIndent > currentIndent && !trimmed.endsWith("{")) {
97
+ result += " {\n";
98
+ indentStack.push(nextIndent);
99
+ } else if (nextIndent > currentIndent && trimmed.endsWith("{")) {
100
+ indentStack.push(nextIndent);
101
+ result += "\n";
102
+ } else {
103
+ result += "\n";
104
+ }
105
+ }
106
+
107
+ // Close any remaining blocks
108
+ while (indentStack.length > 1) {
109
+ result += "}\n";
110
+ indentStack.pop();
111
+ }
112
+
113
+ return result;
114
+ }
115
+
116
+ const grammarSource = `
117
+ Kadence {
118
+ Program = (FunctionDecl | Statement)+
119
+
120
+ Statement = ClassDecl
121
+ | AsyncFunctionDecl
122
+ | FunctionDecl
123
+ | VariableDecl
124
+ | ConstantDecl
125
+ | Assignment
126
+ | ImportStmt
127
+ | ExportStmt
128
+ | WebStmt
129
+ | ListStmt
130
+ | SetStmt
131
+ | FileStmt
132
+ | NavigateStmt
133
+ | TryStmt
134
+ | IfStmt
135
+ | MatchStmt
136
+ | WhileStmt
137
+ | ForStmt
138
+ | RepeatStmt
139
+ | WhenStmt
140
+ | WaitStmt
141
+ | IncrementStmt
142
+ | DecrementStmt
143
+ | BreakStmt
144
+ | ContinueStmt
145
+ | ReturnStmt
146
+ | EchoStmt
147
+ | ExpressionStmt
148
+
149
+ BreakStmt = "break"
150
+ ContinueStmt = "continue"
151
+
152
+ ImportStmt = "import" string "as" identifier -- all
153
+ | "import" "{" ListOf<identifier, ","> "}" "from" string -- named
154
+ ExportStmt = "export" "default" Expression -- default
155
+ | "export" Declaration -- named
156
+ Declaration = FunctionDecl | AsyncFunctionDecl | ClassDecl | VariableDecl | ConstantDecl
157
+
158
+ ClassDecl = "class" identifier ("extends" identifier)? "{" (MethodDecl | PropertyDecl)* "}"
159
+ MethodDecl = "static"? "private"? "function" identifier Param* Block
160
+ PropertyDecl = "static"? "private"? identifier "=" Expression
161
+
162
+ AsyncFunctionDecl = "async" "function" identifier "(" ListOf<Param, ","> ")" Block -- paren
163
+ | "async" "function" identifier Param* Block -- classic
164
+ FunctionDecl = "function" identifier "(" ListOf<Param, ","> ")" Block -- paren
165
+ | "function" identifier Param* Block -- classic
166
+
167
+ Param = "..." word -- rest
168
+ | word "=" Expression -- default
169
+ | word -- base
170
+
171
+ VariableDecl = "let" BindingPattern ("=" | "be") Expression
172
+ ConstantDecl = "const" BindingPattern ("=" | "be" | "is") Expression
173
+
174
+ BindingPattern = "{" ListOf<word, ","> "}" -- object
175
+ | "[" ListOf<word, ","> "]" -- list
176
+ | identifier -- base
177
+
178
+ Assignment = MemberAccess ("=" | "be") Expression -- simple
179
+ | BindingPattern ("=" | "be") Expression -- destructure
180
+
181
+ ReturnStmt = ("return" | "give") Expression
182
+ IncrementStmt = "increment" MemberAccess -- word
183
+ | MemberAccess "++" -- sym
184
+ DecrementStmt = "decrement" MemberAccess -- word
185
+ | MemberAccess "--" -- sym
186
+
187
+ WaitStmt = "wait" Expression ("seconds" | "second")
188
+ NavigateStmt = "go" "to" Expression
189
+ RepeatStmt = "repeat" Expression ("times" | "time") Block
190
+
191
+ TryStmt = "try" Block "catch" identifier Block
192
+ MatchStmt = "match" Expression "{" MatchCase+ MatchElse? "}"
193
+ MatchCase = "when" Expression "then" Statement
194
+ MatchElse = "else" Statement
195
+
196
+ SetStmt = "set" PropTerm "of" MemberAccess "to" Expression -- style
197
+ | "set" MemberAccess PropTerm "to" Expression -- prop
198
+ | "set" MemberAccess "to" Expression -- simple
199
+ PropTerm = "text" | "size" | "color" | "class" | "background" | "value" | identifier
200
+ FileStmt = "save" Expression "to" string -- save
201
+ | "read" "from" string -- read
202
+
203
+ ForStmt = "for" "each"? identifier "in" Expression Block
204
+ WhenStmt = "when" MemberAccess "is" identifier Block
205
+
206
+ ListStmt = "add" Expression "to" MemberAccess -- add
207
+ | "remove" "item" Expression "from" MemberAccess -- remove_at
208
+
209
+ WebStmt = "create" "element" string -- create
210
+ | "add" MemberAccess "to" MemberAccess -- add_child
211
+
212
+ IfStmt = "if" Expression Block ("elif" Expression Block)* ("else" Block)?
213
+ WhileStmt = "while" Expression Block
214
+ EchoStmt = ("echo" | "say" | "print" | "post") Expression
215
+ ExpressionStmt = Expression
216
+
217
+ Block = "{" Statement* "}"
218
+
219
+ Expression = AwaitExpr | NewExpr | CreateExpr | ObjectLiteral | SpreadExpr | TypeofExpr | CoalesceExpr
220
+
221
+ NewExpr = "new" identifier "(" ListOf<Expression, ","> ")" -- paren
222
+ | "new" identifier Arg* -- classic
223
+ CreateExpr = "create" "element" string -- call
224
+ AskExpr = "ask" string
225
+ SizeExpr = "size" "of" Expression
226
+ RandomExpr = "random" "number" "from" Expression "to" Expression -- range
227
+ | "random" -- float
228
+ TransformExpr = ("uppercase" | "lowercase") Primary
229
+
230
+ MathExpr = kw<"average"> kw<"of"> Expression -- average
231
+ | kw<"minimum"> kw<"of"> Expression -- min
232
+ | kw<"maximum"> kw<"of"> Expression -- max
233
+ | kw<"round"> Expression -- round
234
+ | kw<"floor"> Expression -- floor
235
+ | kw<"ceiling"> Expression -- ceil
236
+ | kw<"absolute"> Expression -- abs
237
+ | kw<"square"> kw<"root"> Expression -- sqrt
238
+ | kw<"power"> Expression kw<"to"> Expression -- pow
239
+ | kw<"sin"> Expression -- sin
240
+ | kw<"cos"> Expression -- cos
241
+ | kw<"tan"> Expression -- tan
242
+
243
+ ListExpr = kw<"sort"> Expression -- sort
244
+ | kw<"reverse"> Expression -- reverse
245
+ | kw<"push"> Expression kw<"to"> Expression -- push
246
+ | kw<"pop"> kw<"from"> Expression -- pop
247
+
248
+ ObjectExpr = kw<"keys"> kw<"of"> Expression -- keys
249
+ | kw<"values"> kw<"of"> Expression -- values
250
+ | kw<"merge"> Expression kw<"with"> Expression -- merge
251
+ ReadExpr = "read" "from" string
252
+ TimeExpr = "the" "time" "now" -- time
253
+ | "the" "date" "today" -- date
254
+ ConvertExpr = "convert" Expression "to" TypeTerm
255
+
256
+ // New feature expressions
257
+ AwaitExpr = "await" Expression
258
+ ObjectLiteral = "object"? "{" ListOf<ObjectPair, ","?> "}"
259
+ ObjectPair = (word | string) ":" Expression -- pair
260
+ | word -- shorthand
261
+ | SpreadExpr -- spread
262
+
263
+ ArrayMethod = map_kw Expression "with" Lambda -- map
264
+ | filter_kw Expression "where" Lambda -- filter
265
+ | reduce_kw Expression "from" Expression "with" Lambda -- reduce
266
+ | find_kw Expression "where" Lambda -- find
267
+ | some_kw Expression "where" Lambda -- some
268
+ | every_kw Expression "where" Lambda -- every
269
+
270
+ StringCmd = split_kw Expression "by" Expression -- split
271
+ | join_kw Expression "with" Expression -- join
272
+ | trim_kw Expression -- trim
273
+ | replace_kw Expression "with" Expression "in" Expression -- replace
274
+ | kw<"index"> kw<"of"> Expression kw<"in"> Expression -- indexOf
275
+ | kw<"last"> kw<"index"> kw<"of"> Expression kw<"in"> Expression -- lastIndexOf
276
+
277
+ HttpExpr = "get" "from" Expression -- get
278
+ | "post" "to" Expression "with" Expression -- post
279
+ | "put" "to" Expression "with" Expression -- put
280
+ | "delete" "from" Expression -- delete
281
+
282
+ JsonExpr = "parse" "json" "from" Expression -- parse
283
+ | "stringify" Expression "to" "json" -- stringify
284
+
285
+ RegexExpr = "regex" string -- create
286
+ | "extract" "all" Expression "from" Expression -- extractAll
287
+
288
+ SpreadExpr = "..." Expression
289
+ RangeExpr = "range" Expression "to" Expression
290
+
291
+ Lambda = identifier "=>" (Block | Expression) -- simple
292
+ | "(" ListOf<identifier, ","> ")" "=>" (Block | Expression) -- multi
293
+
294
+ TypeofExpr = "typeof" Expression
295
+
296
+ CoalesceExpr = CoalesceExpr "??" OrExpr -- coalesce
297
+ | OrExpr
298
+
299
+ OrExpr = OrExpr "or" AndExpr -- word
300
+ | OrExpr "||" AndExpr -- sym
301
+ | AndExpr
302
+
303
+ AndExpr = AndExpr "and" NotExpr -- word
304
+ | AndExpr "&&" NotExpr -- sym
305
+ | NotExpr
306
+
307
+ NotExpr = "not" Comparison -- word
308
+ | "!" Comparison -- sym
309
+ | Comparison
310
+
311
+ Comparison = StringCheck -- string_check
312
+ | PropertyCheck -- property_check
313
+ | TypeCheck -- type_check
314
+ | BitwiseOr CompareOp BitwiseOr -- full
315
+ | CompareOp BitwiseOr -- short
316
+ | BitwiseOr -- base
317
+
318
+ PropertyCheck = Additive "has" Additive
319
+
320
+ TypeCheck = Additive "is" article TypeTerm
321
+ TypeTerm = "number" | "string" | "list" | "bool" | "object" | identifier
322
+ article = ("an" | "a") ~idchar
323
+
324
+ StringCheck = Additive includes_kw Additive -- includes
325
+ | Additive "starts" "with" Additive -- startsWith
326
+ | Additive "ends" "with" Additive -- endsWith
327
+ | MatchCheck -- match
328
+
329
+ MatchCheck = Additive "matches" Additive
330
+
331
+ CompareOp = "==" -- eq_sym_double
332
+ | "=" -- eq_sym
333
+ | "equals" -- eq_word
334
+ | "!=" -- neq_sym
335
+ | "not" "equals" -- neq_word
336
+ | ">" -- gt_sym
337
+ | "more" "than" -- gt_word
338
+ | "<" -- lt_sym
339
+ | "less" "than" -- lt_word
340
+ | ">=" -- gte_sym
341
+ | "at" "least" -- gte_word
342
+ | "<=" -- lte_sym
343
+ | "at" "most" -- lte_word
344
+
345
+ Additive = Additive "plus" Multiplicative -- add_word
346
+ | Additive "+" Multiplicative -- add_sym
347
+ | Additive "minus" Multiplicative -- sub_word
348
+ | Additive "-" Multiplicative -- sub_sym
349
+ | Multiplicative
350
+
351
+ BitwiseShift = BitwiseShift "<<" Additive -- left
352
+ | BitwiseShift ">>" Additive -- right
353
+ | Additive
354
+
355
+ BitwiseAnd = BitwiseAnd "&" BitwiseShift -- bin
356
+ | BitwiseShift
357
+
358
+ BitwiseXor = BitwiseXor "^" BitwiseAnd -- bin
359
+ | BitwiseAnd
360
+
361
+ BitwiseOr = BitwiseOr "|" BitwiseXor -- bin
362
+ | BitwiseXor
363
+
364
+ Multiplicative = Multiplicative "*" Primary -- mul_sym
365
+ | Multiplicative "times" Primary -- mul_word
366
+ | Multiplicative "/" Primary -- div
367
+ | Multiplicative "divided" "by" Primary -- div_word
368
+ | Primary
369
+
370
+ Primary = List -- list
371
+ | Lambda -- lambda
372
+ | ItemAccess -- access
373
+ | Call -- call
374
+ | MathExpr -- math
375
+ | StringCmd -- string
376
+ | ArrayMethod -- arrayay
377
+ | ListExpr -- list_op
378
+ | ObjectExpr -- object
379
+ | JsonExpr -- json
380
+ | HttpExpr -- http
381
+ | AskExpr -- ask
382
+ | SizeExpr -- size
383
+ | RandomExpr -- random
384
+ | ReadExpr -- read
385
+ | TimeExpr -- time
386
+ | ConvertExpr -- convert
387
+ | RegexExpr -- regex
388
+ | RangeExpr -- range
389
+ | TransformExpr -- transform
390
+ | MemberAccess -- member
391
+ | "pi" -- pi
392
+ | number -- num
393
+ | bool -- bool
394
+ | string -- str
395
+ | "(" Expression ")" -- paren
396
+
397
+ MemberAccess = MemberAccess "?." word -- opt_prop
398
+ | MemberAccess "?." "[" Expression "]" -- opt_index
399
+ | MemberAccess "." word -- prop
400
+ | MemberAccess "[" Expression "]" -- index
401
+ | "this" -- this
402
+ | "super" -- super
403
+ | identifier -- base
404
+
405
+ List = "list" Arg*
406
+ ItemAccess = "item" Primary "from" Primary
407
+
408
+ // Call uses parentheses or 'run' keyword
409
+ Call = MemberAccess "(" ListOf<Expression, ","> ")" -- paren
410
+ | "run" MemberAccess Arg* -- run
411
+
412
+ Arg = Lambda | List | identifier | number | bool | string | "(" Expression ")" -- paren
413
+
414
+ bool = "true" | "false"
415
+ word = (letter | "_") (letter | digit | "_")*
416
+ identifier = ~keyword word
417
+ idchar = letter | digit | "_"
418
+ kw<word> = word ~idchar
419
+
420
+ // Lexical keywords for method-like expressions
421
+ map_kw = "map" ~idchar
422
+ filter_kw = "filter" ~idchar
423
+ reduce_kw = "reduce" ~idchar
424
+ find_kw = "find" ~idchar
425
+ some_kw = "some" ~idchar
426
+ every_kw = "every" ~idchar
427
+ split_kw = "split" ~idchar
428
+ join_kw = "join" ~idchar
429
+ trim_kw = "trim" ~idchar
430
+ includes_kw = "includes" ~idchar
431
+ replace_kw = "replace" ~idchar
432
+ keyword = ("function" | "let" | "const" | "echo" | "say" | "print" | "true" | "false" | "if" | "elif" | "else" | "end" | "while" | "for" | "each" | "in" | "when" | "is" | "and" | "or" | "not" | "equals" | "more" | "than" | "at" | "least" | "most" | "plus" | "minus" | "times" | "run" | "list" | "item" | "from" | "create" | "element" | "set" | "class" | "add" | "to" | "ask" | "of" | "size" | "remove" | "increment" | "decrement" | "random" | "return" | "give" | "be" | "has" | "say" | "number" | "wait" | "second" | "seconds" | "uppercase" | "lowercase" | "average" | "save" | "read" | "go" | "convert" | "the" | "time" | "now" | "date" | "today" | "background" | "async" | "await" | "try" | "catch" | "match" | "then" | "repeat" | "object" | "get" | "post" | "put" | "delete" | "parse" | "stringify" | "regex" | "all" | "range" | "by" | "where" | "with" | "new" | "this" | "super" | "trim" | "split" | "join" | "map" | "filter" | "reduce" | "find" | "some" | "every" | "includes" | "starts" | "ends" | "replace" | "matches" | "extract" | "import" | "export" | "as" | "minimum" | "maximum" | "index" | "last" | "private" | "static" | "extends" | "pi" | "floor" | "ceiling" | "round" | "absolute" | "square" | "root" | "power" | "sin" | "cos" | "tan" | "break" | "continue") ~(letter | digit | "_")
433
+ number = digit+ ("." digit+)?
434
+
435
+ string = doubleString | templateString
436
+ doubleString = "\\"" (escape | interpolation | textDouble)* "\\""
437
+ templateString = "\`" (escape | interpolation | textBacktick)* "\`"
438
+
439
+ escape = "\\\\" any
440
+ interpolation = "{" (~"}" any)* "}"
441
+
442
+ textDouble = (~("\\"" | "{" | "\\\\") any)+
443
+ textBacktick = (~("\`" | "{" | "\\\\") any)+
444
+
445
+ space += "//" (~"\\n" any)* -- comment
446
+ | "note" ":"? (~"\\n" any)* -- note_comment
447
+ }
448
+ `;
449
+
450
+ const grammar = ohm.grammar(grammarSource);
451
+
452
+ let compileOptions = { target: "node", sourceFile: "source.kade" };
453
+
454
+ let lineMap = [];
455
+ function initLineMap(code) {
456
+ lineMap = [0];
457
+ for (let i = 0; i < code.length; i++) {
458
+ if (code[i] === "\n") lineMap.push(i + 1);
459
+ }
460
+ }
461
+
462
+ function getLineCol(pos) {
463
+ let line = 0;
464
+ while (line + 1 < lineMap.length && lineMap[line + 1] <= pos) {
465
+ line++;
466
+ }
467
+ return { line: line + 1, col: pos - lineMap[line] };
468
+ }
469
+
470
+ function createNode(ohmNode, chunks) {
471
+ const { line, col } = getLineCol(ohmNode.source.startIdx);
472
+ return new SourceNode(line, col, compileOptions.sourceFile, chunks);
473
+ }
474
+
475
+ let currentSubject = null; // Tracks the current subject for chained comparisons
476
+
477
+ const semantics = grammar
478
+ .createSemantics()
479
+ .addOperation("hasAwait", {
480
+ AwaitExpr(_a, _e) {
481
+ return true;
482
+ },
483
+ TypeofExpr(_t, e) {
484
+ return e.hasAwait();
485
+ },
486
+ _iter(...children) {
487
+ return children.some((c) => c.hasAwait());
488
+ },
489
+ _nonterminal(...children) {
490
+ return children.some((c) => c.hasAwait());
491
+ },
492
+ _terminal() {
493
+ return false;
494
+ },
495
+ })
496
+ .addOperation("toNode", {
497
+ Program(statements) {
498
+ const target = compileOptions.target || "node";
499
+ const helper = `
500
+ function __kadence_echo(val) {
501
+ const s = String(val);
502
+ const low = s.toLowerCase();
503
+ if (typeof process !== 'undefined' && process.stdout && process.stdout.isTTY) {
504
+ if (low.includes('error')) console.log("\\x1b[31m" + s + "\\x1b[0m");
505
+ else if (low.includes('warning')) console.log("\\x1b[33m" + s + "\\x1b[0m");
506
+ else if (low.includes('success')) console.log("\\x1b[32m" + s + "\\x1b[0m");
507
+ else console.log(s);
508
+ } else {
509
+ console.log(s);
510
+ }
511
+ }
512
+ function __kadence_min(val) {
513
+ if (Array.isArray(val)) return Math.min(...val);
514
+ return val;
515
+ }
516
+ function __kadence_max(val) {
517
+ if (Array.isArray(val)) return Math.max(...val);
518
+ return val;
519
+ }
520
+ function __kadence_add(parent, child) {
521
+ if (Array.isArray(parent)) {
522
+ parent.push(child);
523
+ return parent;
524
+ }
525
+ if (typeof parent === 'object' && parent !== null && typeof parent.appendChild === 'function') {
526
+ parent.appendChild(child);
527
+ return parent;
528
+ }
529
+ throw new Error("Runtime Error: Cannot add item to " + typeof parent);
530
+ }
531
+ `;
532
+ let topNodes = [];
533
+ let iifeNodes = [];
534
+
535
+ statements.children.forEach((s) => {
536
+ const node = s.toNode();
537
+ const js = node.toString();
538
+ const hasAwait = s.hasAwait();
539
+ const isFuncOrClass = js.includes("function ") || js.includes("class ");
540
+ const isDecl =
541
+ isFuncOrClass ||
542
+ js.includes("require(") ||
543
+ js.includes("let ") ||
544
+ js.includes("const ") ||
545
+ js.includes("exports.");
546
+
547
+ if (hasAwait && !isFuncOrClass) iifeNodes.push(node);
548
+ else if (isDecl) topNodes.push(node);
549
+ else iifeNodes.push(node);
550
+ });
551
+
552
+ const errHandler = 'err => { if (err) console.error("\\x1b[31mRuntime Error:\\x1b[0m", err.stack || err.message); }';
553
+
554
+ if (target === "browser") {
555
+ const browserPreamble = `(function () {\n var fs = { writeFileSync: function () { }, readFileSync: function () { return ""; } };\n var require = typeof require === "function" ? require : function () { return {}; };\n`;
556
+ return createNode(this, [
557
+ browserPreamble,
558
+ helper,
559
+ ...topNodes.map(n => [n, "\n"]),
560
+ "(async function() {\n",
561
+ ...iifeNodes.map(n => [n, "\n"]),
562
+ "\n})().catch(" + errHandler + ");\n})();"
563
+ ]);
564
+ }
565
+ return createNode(this, [
566
+ 'const fs = require("fs"); \n',
567
+ helper,
568
+ ...topNodes.map(n => [n, "\n"]),
569
+ "(async () => { \n",
570
+ ...iifeNodes.map(n => [n, "\n"]),
571
+ " })().catch(" + errHandler + "); "
572
+ ]);
573
+ },
574
+ FunctionDecl_paren(_fn, id, _lp, params, _rp, block) {
575
+ const ps = params.asIteration().children.map(p => p.toNode());
576
+ const paramList = [];
577
+ ps.forEach((p, i) => {
578
+ paramList.push(p);
579
+ if (i < ps.length - 1) paramList.push(", ");
580
+ });
581
+ return createNode(this, ["function ", id.toNode(), " (", ...paramList, ") ", block.toNode()]);
582
+ },
583
+ FunctionDecl_classic(_fn, id, params, block) {
584
+ const ps = params.children.map(p => p.toNode());
585
+ const paramList = [];
586
+ ps.forEach((p, i) => {
587
+ paramList.push(p);
588
+ if (i < ps.length - 1) paramList.push(", ");
589
+ });
590
+ return createNode(this, ["function ", id.toNode(), " (", ...paramList, ") ", block.toNode()]);
591
+ },
592
+ AsyncFunctionDecl_paren(_async, _fn, id, _lp, params, _rp, block) {
593
+ const ps = params.asIteration().children.map(p => p.toNode());
594
+ const paramList = [];
595
+ ps.forEach((p, i) => {
596
+ paramList.push(p);
597
+ if (i < ps.length - 1) paramList.push(", ");
598
+ });
599
+ return createNode(this, ["async function ", id.toNode(), " (", ...paramList, ") ", block.toNode()]);
600
+ },
601
+ AsyncFunctionDecl_classic(_async, _fn, id, params, block) {
602
+ const ps = params.children.map(p => p.toNode());
603
+ const paramList = [];
604
+ ps.forEach((p, i) => {
605
+ paramList.push(p);
606
+ if (i < ps.length - 1) paramList.push(", ");
607
+ });
608
+ return createNode(this, ["async function ", id.toNode(), " (", ...paramList, ") ", block.toNode()]);
609
+ },
610
+ ClassDecl(_class, id, _extends, superId, _lb, members, _rb) {
611
+ const extension = superId.children.length > 0 ? ["extends ", superId.toNode(), " "] : "";
612
+ return createNode(this, ["class ", id.toNode(), " ", ...extension, "{ \n ", ...members.children.map(m => [m.toNode(), "\n"]), " \n } "]);
613
+ },
614
+ ImportStmt_all(_import, path, _as, id) {
615
+ let p = path.toJS();
616
+ p = p.replace(/\.kade([`"'])$/, ".js$1");
617
+ const inner = p.replace(/^["'`]|["'`]$/g, "");
618
+ if (inner.includes("/") && !/^\.\.?\//.test(inner)) p = p.replace(/^(["`'])(.*)(["`'])$/, "$1./$2$3");
619
+ return createNode(this, ["const ", id.toNode(), " = require(", p, ");"]);
620
+ },
621
+ ImportStmt_named(_import, _lb, ids, _rb, _from, path) {
622
+ let p = path.toJS();
623
+ p = p.replace(/\.kade([`"'])$/, ".js$1");
624
+ const inner = p.replace(/^["'`]|["'`]$/g, "");
625
+ if (inner.includes("/") && !/^\.\.?\//.test(inner)) p = p.replace(/^(["`'])(.*)(["`'])$/, "$1./$2$3");
626
+ const idList = [];
627
+ const children = ids.asIteration().children;
628
+ children.forEach((c, i) => {
629
+ idList.push(c.toNode());
630
+ if (i < children.length - 1) idList.push(", ");
631
+ });
632
+ return createNode(this, ["const { ", ...idList, " } = require(", p, ");"]);
633
+ },
634
+ ExportStmt_default(_export, _default, expr) {
635
+ return createNode(this, ["if (typeof exports !== 'undefined') exports.default = ", expr.toNode(), "; else export default ", expr.toNode(), ";"]);
636
+ },
637
+ ExportStmt_named(_export, decl) {
638
+ const name = decl.getName();
639
+ return createNode(this, [decl.toNode(), "\nif (typeof exports !== 'undefined') exports.", name, " = ", name, ";"]);
640
+ },
641
+ Declaration(decl) { return decl.toNode(); },
642
+ MethodDecl(staticKw, privateKw, _fn, id, params, block) {
643
+ const ps = params.children.map(p => p.toNode());
644
+ const paramList = [];
645
+ ps.forEach((p, i) => {
646
+ paramList.push(p);
647
+ if (i < ps.length - 1) paramList.push(", ");
648
+ });
649
+ const prefix = (staticKw.sourceString ? "static " : "") + (privateKw.sourceString ? "#" : "");
650
+ return createNode(this, [" ", prefix, id.toNode(), " (", ...paramList, ") ", block.toNode()]);
651
+ },
652
+ PropertyDecl(staticKw, privateKw, id, _eq, expr) {
653
+ const prefix = (staticKw.sourceString ? "static " : "") + (privateKw.sourceString ? "#" : "");
654
+ return createNode(this, [" ", prefix, id.toNode(), " = ", expr.toNode(), "; "]);
655
+ },
656
+ Param_rest(_dots, id) { return createNode(this, ["...", id.toNode()]); },
657
+ Param_default(id, _eq, expr) { return createNode(this, [id.toNode(), " = ", expr.toNode()]); },
658
+ Param_base(id) { return id.toNode(); },
659
+ VariableDecl(_let, pattern, _eq, expr) { return createNode(this, ["let ", pattern.toNode(), " = ", expr.toNode(), "; "]); },
660
+ ConstantDecl(_const, pattern, _eq, expr) { return createNode(this, ["const ", pattern.toNode(), " = ", expr.toNode(), "; "]); },
661
+ BindingPattern_object(_lb, ids, _rb) {
662
+ const idList = [];
663
+ const children = ids.asIteration().children;
664
+ children.forEach((c, i) => {
665
+ idList.push(c.toNode());
666
+ if (i < children.length - 1) idList.push(", ");
667
+ });
668
+ return createNode(this, ["{ ", ...idList, " }"]);
669
+ },
670
+ BindingPattern_list(_lb, ids, _rb) {
671
+ const idList = [];
672
+ const children = ids.asIteration().children;
673
+ children.forEach((c, i) => {
674
+ idList.push(c.toNode());
675
+ if (i < children.length - 1) idList.push(", ");
676
+ });
677
+ return createNode(this, ["[ ", ...idList, " ]"]);
678
+ },
679
+ BindingPattern_base(id) { return id.toNode(); },
680
+ Assignment_simple(member, _op, expr) { return createNode(this, [member.toNode(), " = ", expr.toNode(), "; "]); },
681
+ Assignment_destructure(pattern, _op, expr) { return createNode(this, [pattern.toNode(), " = ", expr.toNode(), "; "]); },
682
+ TryStmt(_try, tryBlock, _catch, errorId, catchBlock) {
683
+ return createNode(this, ["try ", tryBlock.toNode(), " catch(", errorId.toNode(), ") ", catchBlock.toNode()]);
684
+ },
685
+ MatchStmt(_match, expr, _open, cases, elseCase, _close) {
686
+ return createNode(this, [
687
+ "(() => { const __match = ", expr.toNode(), "; ",
688
+ ...cases.children.map((c, i) => [i === 0 ? "if " : " else if ", c.toNode()]),
689
+ elseCase.children.length > 0 ? [" else { ", elseCase.children[0].toNode(), " } "] : "",
690
+ "})(); "
691
+ ]);
692
+ },
693
+ MatchCase(_when, condition, _then, statement) {
694
+ return createNode(this, ["(__match === ", condition.toNode(), ") { ", statement.toNode(), " }"]);
695
+ },
696
+ MatchElse(_else, statement) { return statement.toNode(); },
697
+ RepeatStmt(_repeat, count, _unit, block) {
698
+ return createNode(this, ["for (let __i = 0; __i < ", count.toNode(), "; __i++) ", block.toNode()]);
699
+ },
700
+ WebStmt_create(_create, _elem, str) { return createNode(this, ["document.createElement(", str.toNode(), "); "]); },
701
+ WebStmt_add_child(_add, child, _to, parent) { return createNode(this, ["__kadence_add(", parent.toNode(), ", ", child.toNode(), ");"]); },
702
+ SetStmt_style(_set, prop, _of, target, _to, val) {
703
+ let p = prop.toJS();
704
+ if (p === "text") return createNode(this, [target.toNode(), ".innerText = ", val.toNode(), ";"]);
705
+ if (p === "class") return createNode(this, [target.toNode(), ".className = ", val.toNode(), ";"]);
706
+ return createNode(this, [target.toNode(), ".style.", p, " = ", val.toNode(), ";"]);
707
+ },
708
+ SetStmt_prop(_set, target, prop, _to, val) {
709
+ let p = prop.toJS();
710
+ if (p === "class") p = "className";
711
+ if (p === "text") p = "innerText";
712
+ return createNode(this, [target.toNode(), ".", p, " = ", val.toNode(), ";"]);
713
+ },
714
+ SetStmt_simple(_set, target, _to, val) { return createNode(this, [target.toNode(), " = ", val.toNode(), ";"]); },
715
+ ListStmt_add(_add, val, _to, list) { return createNode(this, ["__kadence_add(", list.toNode(), ", ", val.toNode(), ");"]); },
716
+ ListStmt_remove_at(_rem, _item, idx, _from, list) { return createNode(this, [list.toNode(), ".splice(", idx.toNode(), ", 1);"]); },
717
+ PropTerm(node) { return node.sourceString; },
718
+ FileStmt_save(_save, content, _to, path) { return createNode(this, ["fs.writeFileSync(", path.toNode(), ", ", content.toNode(), ");"]); },
719
+ FileStmt_read(_read, _from, path) { return createNode(this, ["fs.readFileSync(", path.toNode(), ", 'utf8');"]); },
720
+ NavigateStmt(_go, _to, expr) { return createNode(this, ["window.location.href = ", expr.toNode(), ";"]); },
721
+ AskExpr(_ask, str) { return createNode(this, ["prompt(", str.toNode(), ")"]); },
722
+ SizeExpr(_size, _of, id) { return createNode(this, [id.toNode(), ".length"]); },
723
+ MathExpr_average(_avg, _of, id) {
724
+ return createNode(this, ["(", id.toNode(), ".reduce((a, b) => a + b, 0) / ", id.toNode(), ".length)"]);
725
+ },
726
+ MathExpr_min(_min, _of, id) { return createNode(this, ["__kadence_min(", id.toNode(), ")"]); },
727
+ MathExpr_max(_max, _of, id) { return createNode(this, ["__kadence_max(", id.toNode(), ")"]); },
728
+ MathExpr_round(_round, expr) { return createNode(this, ["Math.round(", expr.toNode(), ")"]); },
729
+ MathExpr_floor(_floor, expr) { return createNode(this, ["Math.floor(", expr.toNode(), ")"]); },
730
+ MathExpr_ceil(_ceil, expr) { return createNode(this, ["Math.ceil(", expr.toNode(), ")"]); },
731
+ MathExpr_abs(_abs, expr) { return createNode(this, ["Math.abs(", expr.toNode(), ")"]); },
732
+ MathExpr_sqrt(_sqrt, _root, expr) { return createNode(this, ["Math.sqrt(", expr.toNode(), ")"]); },
733
+ MathExpr_pow(_pow, base, _to, exp) { return createNode(this, ["Math.pow(", base.toNode(), ", ", exp.toNode(), ")"]); },
734
+ MathExpr_sin(_sin, expr) { return createNode(this, ["Math.sin(", expr.toNode(), ")"]); },
735
+ MathExpr_cos(_cos, expr) { return createNode(this, ["Math.cos(", expr.toNode(), ")"]); },
736
+ MathExpr_tan(_tan, expr) { return createNode(this, ["Math.tan(", expr.toNode(), ")"]); },
737
+ ListExpr_sort(_sort, expr) { return createNode(this, ["([...", expr.toNode(), "].sort())"]); },
738
+ ListExpr_reverse(_reverse, expr) { return createNode(this, ["([...", expr.toNode(), "].reverse())"]); },
739
+ ListExpr_push(_push, val, _to, array) {
740
+ return createNode(this, ["(() => { const _a = ", array.toNode(), "; _a.push(", val.toNode(), "); return _a; })()"]);
741
+ },
742
+ ListExpr_pop(_pop, _from, array) { return createNode(this, [array.toNode(), ".pop()"]); },
743
+ ObjectExpr_keys(_keys, _of, expr) { return createNode(this, ["Object.keys(", expr.toNode(), ")"]); },
744
+ ObjectExpr_values(_values, _of, expr) { return createNode(this, ["Object.values(", expr.toNode(), ")"]); },
745
+ ObjectExpr_merge(_merge, a, _with, b) { return createNode(this, ["Object.assign({}, ", a.toNode(), ", ", b.toNode(), ")"]); },
746
+ ReadExpr(_read, _from, path) { return createNode(this, ["fs.readFileSync(", path.toNode(), ", 'utf8')"]); },
747
+ TimeExpr_time(_the, _time, _now) { return createNode(this, ["new Date().toLocaleTimeString()"]); },
748
+ TimeExpr_date(_the, _date, _today) { return createNode(this, ["new Date().toLocaleDateString()"]); },
749
+ ConvertExpr(_convert, expr, _to, type) {
750
+ const t = type.sourceString;
751
+ if (t === "number") return createNode(this, ["Number(", expr.toNode(), ")"]);
752
+ if (t === "string") return createNode(this, ["String(", expr.toNode(), ")"]);
753
+ if (t === "bool") return createNode(this, ["Boolean(", expr.toNode(), ")"]);
754
+ if (t === "object") return createNode(this, ["Object(", expr.toNode(), ")"]);
755
+ return createNode(this, [t, "(", expr.toNode(), ")"]);
756
+ },
757
+ AwaitExpr(_await, expr) { return createNode(this, ["await ", expr.toNode()]); },
758
+ NewExpr_paren(_new, id, _lp, args, _rp) {
759
+ const children = args.asIteration().children;
760
+ const argList = [];
761
+ children.forEach((c, i) => {
762
+ argList.push(c.toNode());
763
+ if (i < children.length - 1) argList.push(", ");
764
+ });
765
+ return createNode(this, ["new ", id.sourceString, "(", ...argList, ")"]);
766
+ },
767
+ NewExpr_classic(_new, id, args) {
768
+ const children = args.children;
769
+ const argList = [];
770
+ children.forEach((c, i) => {
771
+ argList.push(c.toNode());
772
+ if (i < children.length - 1) argList.push(", ");
773
+ });
774
+ return createNode(this, ["new ", id.sourceString, "(", ...argList, ")"]);
775
+ },
776
+ ObjectLiteral(_objKw, _lb, pairs, _rb) {
777
+ const children = pairs.asIteration().children;
778
+ const pairList = [];
779
+ children.forEach((c, i) => {
780
+ pairList.push(c.toNode());
781
+ if (i < children.length - 1) pairList.push(", ");
782
+ });
783
+ return createNode(this, ["{ ", ...pairList, " }"]);
784
+ },
785
+ ObjectPair_pair(key, _colon, value) { return createNode(this, [key.toNode(), ": ", value.toNode()]); },
786
+ ObjectPair_shorthand(id) { return id.toNode(); },
787
+ ObjectPair_spread(spread) { return spread.toNode(); },
788
+ ArrayMethod_map(_map, array, _with, lambda) { return createNode(this, [array.toNode(), ".map(", lambda.toNode(), ")"]); },
789
+ ArrayMethod_filter(_filter, array, _where, lambda) { return createNode(this, [array.toNode(), ".filter(", lambda.toNode(), ")"]); },
790
+ ArrayMethod_reduce(_reduce, array, _from, init, _with, lambda) { return createNode(this, [array.toNode(), ".reduce(", lambda.toNode(), ", ", init.toNode(), ")"]); },
791
+ ArrayMethod_find(_find, array, _where, lambda) { return createNode(this, [array.toNode(), ".find(", lambda.toNode(), ")"]); },
792
+ ArrayMethod_some(_some, array, _where, lambda) { return createNode(this, [array.toNode(), ".some(", lambda.toNode(), ")"]); },
793
+ ArrayMethod_every(_every, array, _where, lambda) { return createNode(this, [array.toNode(), ".every(", lambda.toNode(), ")"]); },
794
+ HttpExpr_get(_get, _from, url) { return createNode(this, ["fetch(", url.toNode(), ").then(r => r.json())"]); },
795
+ HttpExpr_post(_post, _to, url, _with, data) {
796
+ return createNode(this, ["fetch(", url.toNode(), ", {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(", data.toNode(), ")}).then(r => r.json())"]);
797
+ },
798
+ HttpExpr_put(_put, _to, url, _with, data) {
799
+ return createNode(this, ["fetch(", url.toNode(), ", {method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(", data.toNode(), ")}).then(r => r.json())"]);
800
+ },
801
+ HttpExpr_delete(_delete, _from, url) { return createNode(this, ["fetch(", url.toNode(), ", {method: 'DELETE'}).then(r => r.json())"]); },
802
+ JsonExpr_parse(_parse, _json, _from, str) { return createNode(this, ["JSON.parse(", str.toNode(), ")"]); },
803
+ JsonExpr_stringify(_stringify, obj, _to, _json) { return createNode(this, ["JSON.stringify(", obj.toNode(), ")"]); },
804
+ RegexExpr_create(_regex, pattern) { return createNode(this, ["new RegExp(", pattern.toNode(), ")"]); },
805
+ RegexExpr_extractAll(_extract, _all, pattern, _from, str) { return createNode(this, [str.toNode(), ".match(", pattern.toNode(), ")"]); },
806
+ StringCheck(child) { return child.toNode(); },
807
+ MatchCheck(str, _matches, pattern) { return createNode(this, [pattern.toNode(), ".test(", str.toNode(), ")"]); },
808
+ StringCmd_split(_split, str, _by, delim) { return createNode(this, [str.toNode(), ".split(", delim.toNode(), ")"]); },
809
+ StringCmd_join(_join, array, _with, delim) { return createNode(this, [array.toNode(), ".join(", delim.toNode(), ")"]); },
810
+ StringCmd_trim(_trim, str) { return createNode(this, [str.toNode(), ".trim()"]); },
811
+ StringCmd_replace(_replace, search, _with, replacement, _in, str) { return createNode(this, [str.toNode(), ".replace(", search.toNode(), ", ", replacement.toNode(), ")"]); },
812
+ StringCmd_indexOf(_index, _of, search, _in, str) { return createNode(this, [str.toNode(), ".indexOf(", search.toNode(), ")"]); },
813
+ StringCmd_lastIndexOf(_last, _index, _of, search, _in, str) { return createNode(this, [str.toNode(), ".lastIndexOf(", search.toNode(), ")"]); },
814
+ StringCheck_includes(str, _includes, search) { return createNode(this, [str.toNode(), ".includes(", search.toNode(), ")"]); },
815
+ StringCheck_startsWith(str, _starts, _with, search) { return createNode(this, [str.toNode(), ".startsWith(", search.toNode(), ")"]); },
816
+ StringCheck_endsWith(str, _ends, _with, search) { return createNode(this, [str.toNode(), ".endsWith(", search.toNode(), ")"]); },
817
+ Comparison_string_check(child) { return child.toNode(); },
818
+ Comparison_property_check(child) { return child.toNode(); },
819
+ PropertyCheck(obj, _has, prop) { return createNode(this, ["(", prop.toNode(), " in ", obj.toNode(), ")"]); },
820
+ SpreadExpr(_dots, expr) { return createNode(this, ["...", expr.toNode()]); },
821
+ RangeExpr(_range, start, _to, end) {
822
+ return createNode(this, ["Array.from({length: ", end.toNode(), " - ", start.toNode(), " + 1}, (_, i) => i + ", start.toNode(), ")"]);
823
+ },
824
+ Lambda_simple(param, _arrow, body) {
825
+ const asyncKw = body.hasAwait() ? "async " : "";
826
+ return createNode(this, [asyncKw, param.toNode(), " => ", body.toNode()]);
827
+ },
828
+ Lambda_multi(_lp, params, _rp, _arrow, body) {
829
+ const asyncKw = body.hasAwait() ? "async " : "";
830
+ const ps = params.asIteration().children.map(p => p.toNode());
831
+ const paramList = [];
832
+ ps.forEach((p, i) => {
833
+ paramList.push(p);
834
+ if (i < ps.length - 1) paramList.push(", ");
835
+ });
836
+ return createNode(this, [asyncKw, "(", ...paramList, ") => ", body.toNode()]);
837
+ },
838
+ MemberAccess_prop(obj, _dot, prop) { return createNode(this, [obj.toNode(), ".", prop.toNode()]); },
839
+ MemberAccess_index(obj, _lb, index, _rb) { return createNode(this, [obj.toNode(), "[", index.toNode(), "]"]); },
840
+ MemberAccess_base(id) { return id.toNode(); },
841
+ CreateExpr_call(_create, _elem, str) { return createNode(this, ["document.createElement(", str.toNode(), ")"]); },
842
+ BreakStmt(_break) { return createNode(this, ["break;"]); },
843
+ ContinueStmt(_continue) { return createNode(this, ["continue;"]); },
844
+ ReturnStmt(_ret, expr) { return createNode(this, ["return ", expr.toNode(), ";"]); },
845
+ IncrementStmt_word(_inc, id) { return createNode(this, [id.toNode(), "++;"]); },
846
+ IncrementStmt_sym(id, _sym) { return createNode(this, [id.toNode(), "++;"]); },
847
+ DecrementStmt_word(_dec, id) { return createNode(this, [id.toNode(), "--;"]); },
848
+ DecrementStmt_sym(id, _sym) { return createNode(this, [id.toNode(), "--;"]); },
849
+ WaitStmt(_wait, expr, _unit) { return createNode(this, ["await new Promise(r => setTimeout(r, ", expr.toNode(), " * 1000));"]); },
850
+ RandomExpr_range(_rand, _num, _from, min, _to, max) {
851
+ return createNode(this, ["Math.floor(Math.random() * (", max.toNode(), " - ", min.toNode(), " + 1)) + ", min.toNode()]);
852
+ },
853
+ RandomExpr_float(_rand) {
854
+ return createNode(this, ["Math.random()"]);
855
+ },
856
+ TypeCheck(expr, _is, _a, type) {
857
+ const t = type.sourceString;
858
+ if (t === "number") return createNode(this, ["typeof ", expr.toNode(), " === 'number'"]);
859
+ if (t === "string") return createNode(this, ["typeof ", expr.toNode(), " === 'string'"]);
860
+ if (t === "bool") return createNode(this, ["typeof ", expr.toNode(), " === 'boolean'"]);
861
+ if (t === "list") return createNode(this, ["Array.isArray(", expr.toNode(), ")"]);
862
+ return createNode(this, ["typeof ", expr.toNode(), " === '", t, "'"]);
863
+ },
864
+ TypeTerm(node) { return node.sourceString; },
865
+ Primary_transform(child) { return child.toNode(); },
866
+ TransformExpr(op, expr) {
867
+ const o = op.sourceString;
868
+ if (o === "uppercase") return createNode(this, ["(", expr.toNode(), ").toString().toUpperCase()"]);
869
+ if (o === "lowercase") return createNode(this, ["(", expr.toNode(), ").toString().toLowerCase()"]);
870
+ return expr.toNode();
871
+ },
872
+ Comparison_type_check(child) { return child.toNode(); },
873
+ Primary_regex(child) { return child.toNode(); },
874
+ Primary_range(child) { return child.toNode(); },
875
+ IfStmt(_if, cond, block, elifKws, elifConds, elifBlocks, _elseKw, elseBlock) {
876
+ const res = ["if (", cond.toNode(), ") ", block.toNode()];
877
+ const elifC = elifConds.children;
878
+ const elifB = elifBlocks.children;
879
+ for (let i = 0; i < elifC.length; i++) {
880
+ res.push(" else if (", elifC[i].toNode(), ") ", elifB[i].toNode());
881
+ }
882
+ if (_elseKw.children.length > 0) {
883
+ res.push(" else ", elseBlock.children[0].toNode());
884
+ }
885
+ return createNode(this, res);
886
+ },
887
+ WhileStmt(_while, cond, block) { return createNode(this, ["while (", cond.toNode(), ") ", block.toNode()]); },
888
+ ForStmt(_for, _each, id, _in, expr, block) { return createNode(this, ["for (let ", id.toJS(), " of ", expr.toNode(), ") ", block.toNode()]); },
889
+ WhenStmt(_when, target, _is, event, block) {
890
+ let eventName = event.sourceString;
891
+ if (eventName === "clicked") eventName = "click";
892
+ const asyncKw = block.hasAwait() ? "async " : "";
893
+ return createNode(this, [target.toNode(), ".addEventListener('", eventName, "', ", asyncKw, "() => ", block.toNode(), ");"]);
894
+ },
895
+ EchoStmt(_echo, expr) { return createNode(this, ["__kadence_echo(", expr.toNode(), "); "]); },
896
+ ExpressionStmt(expr) { return createNode(this, [expr.toNode(), "; "]); },
897
+ Block(_lb, statements, _rb) {
898
+ return createNode(this, ["{ \n", ...statements.children.map(s => [" ", s.toNode(), "\n"]), " \n } "]);
899
+ },
900
+ CoalesceExpr_coalesce(left, _op, right) { return createNode(this, [left.toNode(), " ?? ", right.toNode()]); },
901
+ CoalesceExpr(child) { return child.toNode(); },
902
+ OrExpr_word(left, _or, right) { return createNode(this, [left.toNode(), " || ", right.toNode()]); },
903
+ OrExpr_sym(left, _op, right) { return createNode(this, [left.toNode(), " || ", right.toNode()]); },
904
+ OrExpr(child) { return child.toNode(); },
905
+ AndExpr_word(left, _and, right) { return createNode(this, [left.toNode(), " && ", right.toNode()]); },
906
+ AndExpr_sym(left, _op, right) { return createNode(this, [left.toNode(), " && ", right.toNode()]); },
907
+ AndExpr(child) { return child.toNode(); },
908
+ NotExpr_word(_not, expr) { return createNode(this, ["!(", expr.toNode(), ")"]); },
909
+ NotExpr_sym(_op, expr) { return createNode(this, ["!(", expr.toNode(), ")"]); },
910
+ NotExpr(child) { return child.toNode(); },
911
+ Comparison_full(left, op, right) {
912
+ const l = left.toNode();
913
+ currentSubject = l.toString();
914
+ return createNode(this, [l, " ", op.toNode(), " ", right.toNode()]);
915
+ },
916
+ Comparison_short(op, right) {
917
+ return createNode(this, [currentSubject, " ", op.toNode(), " ", right.toNode()]);
918
+ },
919
+ Comparison_base(child) {
920
+ const n = child.toNode();
921
+ currentSubject = n.toString();
922
+ return n;
923
+ },
924
+ CompareOp_eq_sym_double(_op) { return "==="; },
925
+ CompareOp_eq_sym(_op) { return "==="; },
926
+ CompareOp_eq_word(_op) { return "==="; },
927
+ CompareOp_neq_sym(_op) { return "!=="; },
928
+ CompareOp_neq_word(_not, _equals) { return "!=="; },
929
+ CompareOp_gt_sym(_op) { return ">"; },
930
+ CompareOp_gt_word(_more, _than) { return ">"; },
931
+ CompareOp_lt_sym(_op) { return "<"; },
932
+ CompareOp_lt_word(_less, _than) { return "<"; },
933
+ CompareOp_gte_sym(_op) { return ">="; },
934
+ CompareOp_gte_word(_at, _least) { return ">="; },
935
+ CompareOp_lte_sym(_op) { return "<="; },
936
+ CompareOp_lte_word(_at, _most) { return "<="; },
937
+ Additive_add_word(left, _plus, right) { return createNode(this, [left.toNode(), " + ", right.toNode()]); },
938
+ Additive_add_sym(left, _plus, right) { return createNode(this, [left.toNode(), " + ", right.toNode()]); },
939
+ Additive_sub_word(left, _minus, right) { return createNode(this, [left.toNode(), " - ", right.toNode()]); },
940
+ Additive_sub_sym(left, _minus, right) { return createNode(this, [left.toNode(), " - ", right.toNode()]); },
941
+ Additive(child) { return child.toNode(); },
942
+ BitwiseShift_left(l, _op, r) { return createNode(this, [l.toNode(), " << ", r.toNode()]); },
943
+ BitwiseShift_right(l, _op, r) { return createNode(this, [l.toNode(), " >> ", r.toNode()]); },
944
+ BitwiseShift(child) { return child.toNode(); },
945
+ BitwiseAnd_bin(l, _op, r) { return createNode(this, [l.toNode(), " & ", r.toNode()]); },
946
+ BitwiseAnd(child) { return child.toNode(); },
947
+ BitwiseXor_bin(l, _op, r) { return createNode(this, [l.toNode(), " ^ ", r.toNode()]); },
948
+ BitwiseXor(child) { return child.toNode(); },
949
+ BitwiseOr_bin(l, _op, r) { return createNode(this, [l.toNode(), " | ", r.toNode()]); },
950
+ BitwiseOr(child) { return child.toNode(); },
951
+ Multiplicative_mul_sym(left, _times, right) { return createNode(this, [left.toNode(), " * ", right.toNode()]); },
952
+ Multiplicative_mul_word(left, _times, right) { return createNode(this, [left.toNode(), " * ", right.toNode()]); },
953
+ Multiplicative_div(left, _op, right) { return createNode(this, [left.toNode(), " / ", right.toNode()]); },
954
+ Multiplicative_div_word(left, _divided, _by, right) { return createNode(this, [left.toNode(), " / ", right.toNode()]); },
955
+ Multiplicative(child) { return child.toNode(); },
956
+ Primary_list(child) { return child.toNode(); },
957
+ Primary_lambda(child) { return child.toNode(); },
958
+ Primary_access(child) { return child.toNode(); },
959
+ Primary_call(child) { return child.toNode(); },
960
+ Primary_math(child) { return child.toNode(); },
961
+ Primary_string(child) { return child.toNode(); },
962
+ Primary_arrayay(child) { return child.toNode(); },
963
+ Primary_list_op(child) { return child.toNode(); },
964
+ Primary_object(child) { return child.toNode(); },
965
+ Primary_json(child) { return child.toNode(); },
966
+ Primary_http(child) { return child.toNode(); },
967
+ Primary_ask(child) { return child.toNode(); },
968
+ Primary_size(child) { return child.toNode(); },
969
+ Primary_random(child) { return child.toNode(); },
970
+ Primary_read(child) { return child.toNode(); },
971
+ Primary_time(child) { return child.toNode(); },
972
+ Primary_convert(child) { return child.toNode(); },
973
+ Primary_member(child) { return child.toNode(); },
974
+ Primary_pi(_pi) { return "Math.PI"; },
975
+ Primary_num(child) { return child.toNode(); },
976
+ Primary_bool(child) { return child.toNode(); },
977
+ Primary_str(child) { return child.toNode(); },
978
+ Primary_paren(_lp, expr, _rp) { return createNode(this, ["(", expr.toNode(), ")"]); },
979
+ Call_paren(id, _lp, args, _rp) {
980
+ const ps = args.asIteration().children.map(a => a.toNode());
981
+ const argList = [];
982
+ ps.forEach((p, i) => {
983
+ argList.push(p);
984
+ if (i < ps.length - 1) argList.push(", ");
985
+ });
986
+ return createNode(this, [id.toNode(), "(", ...argList, ")"]);
987
+ },
988
+ Call_run(_run, id, args) {
989
+ const ps = args.children.map(a => a.toNode());
990
+ const argList = [];
991
+ ps.forEach((p, i) => {
992
+ argList.push(p);
993
+ if (i < ps.length - 1) argList.push(", ");
994
+ });
995
+ return createNode(this, [id.toNode(), "(", ...argList, ")"]);
996
+ },
997
+ Arg(child) { return child.toNode(); },
998
+ Arg_paren(_lp, expr, _rp) { return createNode(this, ["(", expr.toNode(), ")"]); },
999
+ List(_list, args) {
1000
+ const ps = args.children.map(a => a.toNode());
1001
+ const argList = [];
1002
+ ps.forEach((p, i) => {
1003
+ argList.push(p);
1004
+ if (i < ps.length - 1) argList.push(", ");
1005
+ });
1006
+ return createNode(this, ["[", ...argList, "]"]);
1007
+ },
1008
+ ItemAccess(_item, index, _from, list) { return createNode(this, [list.toNode(), "[", index.toNode(), "]"]); },
1009
+ MemberAccess_opt_prop(obj, _dot, prop) { return createNode(this, [obj.toNode(), "?.", prop.toNode()]); },
1010
+ MemberAccess_opt_index(obj, _dot, _lb, index, _rb) { return createNode(this, [obj.toNode(), "?.[", index.toNode(), "]"]); },
1011
+ MemberAccess_this(_this) { return "this"; },
1012
+ MemberAccess_super(_super) { return "super"; },
1013
+ string(child) { return child.toNode(); },
1014
+ doubleString(_l, parts, _r) { return createNode(this, ["`", ...parts.children.map(p => p.toNode()), "`"]); },
1015
+ templateString(_l, parts, _r) { return createNode(this, ["`", ...parts.children.map(p => p.toNode()), "`"]); },
1016
+ escape(_slash, char) {
1017
+ const c = char.sourceString;
1018
+ if (c === "n") return "\\n";
1019
+ if (c === "t") return "\\t";
1020
+ if (c === "r") return "\\r";
1021
+ if (c === '"') return '\\"';
1022
+ if (c === "\\") return "\\\\";
1023
+ if (c === "`") return "\\`";
1024
+ return "\\" + c;
1025
+ },
1026
+ textDouble(char) { return char.sourceString; },
1027
+ textBacktick(char) { return char.sourceString; },
1028
+ interpolation(_l, content, _r) {
1029
+ const exprMatch = grammar.match(content.sourceString, "Expression");
1030
+ if (exprMatch.failed()) throw new Error(`Invalid expression in string interpolation: ${exprMatch.message}`);
1031
+ return createNode(this, ["${", semantics(exprMatch).toNode(), "}"]);
1032
+ },
1033
+ bool(val) { return val.sourceString; },
1034
+ word(_first, _rest) { return this.sourceString; },
1035
+ identifier(w) { return w.toNode(); },
1036
+ number(_digits, _dot, _fract) { return this.sourceString; },
1037
+ _iter(...children) { return children.map(c => c.toNode()); },
1038
+ _terminal() { return this.sourceString; },
1039
+ })
1040
+ .addOperation("toJS", {
1041
+ Program(statements) {
1042
+ const target = compileOptions.target || "node";
1043
+ const helper = `
1044
+ function __kadence_echo(val) {
1045
+ const s = String(val);
1046
+ const low = s.toLowerCase();
1047
+ if (typeof process !== 'undefined' && process.stdout && process.stdout.isTTY) {
1048
+ if (low.includes('error')) console.log("\\x1b[31m" + s + "\\x1b[0m");
1049
+ else if (low.includes('warning')) console.log("\\x1b[33m" + s + "\\x1b[0m");
1050
+ else if (low.includes('success')) console.log("\\x1b[32m" + s + "\\x1b[0m");
1051
+ else console.log(s);
1052
+ } else {
1053
+ console.log(s);
1054
+ }
1055
+ }
1056
+ function __kadence_min(val) {
1057
+ if (Array.isArray(val)) return Math.min(...val);
1058
+ return val;
1059
+ }
1060
+ function __kadence_max(val) {
1061
+ if (Array.isArray(val)) return Math.max(...val);
1062
+ return val;
1063
+ }
1064
+ function __kadence_add(parent, child) {
1065
+ if (Array.isArray(parent)) {
1066
+ parent.push(child);
1067
+ return parent;
1068
+ }
1069
+ if (typeof parent === 'object' && parent !== null && typeof parent.appendChild === 'function') {
1070
+ parent.appendChild(child);
1071
+ return parent;
1072
+ }
1073
+ throw new Error("Runtime Error: Cannot add item to " + typeof parent);
1074
+ }
1075
+ `;
1076
+ let topLevel = [];
1077
+ let iifeLevel = [];
1078
+
1079
+ statements.children.forEach((s) => {
1080
+ const js = s.toJS();
1081
+ const hasAwait = s.hasAwait();
1082
+ const isFuncOrClass = js.includes("function ") || js.includes("class ");
1083
+ const isDecl =
1084
+ isFuncOrClass ||
1085
+ js.includes("require(") ||
1086
+ js.includes("let ") ||
1087
+ js.includes("const ") ||
1088
+ js.includes("exports.");
1089
+
1090
+ if (hasAwait && !isFuncOrClass) {
1091
+ iifeLevel.push(js);
1092
+ } else if (isDecl) {
1093
+ topLevel.push(js);
1094
+ } else {
1095
+ iifeLevel.push(js);
1096
+ }
1097
+ });
1098
+
1099
+ const topCode = topLevel.join("\n");
1100
+ const iifeCode = iifeLevel.join("\n");
1101
+ const errHandler =
1102
+ 'err => { if (err) console.error("Runtime Error:", err.stack || err.message); }';
1103
+
1104
+ if (target === "browser") {
1105
+ const browserPreamble = `(function () {
1106
+ var fs = { writeFileSync: function () { }, readFileSync: function () { return ""; } };
1107
+ var require = typeof require === "function" ? require : function () { return {}; };
1108
+ `;
1109
+ return (
1110
+ browserPreamble +
1111
+ helper +
1112
+ topCode +
1113
+ "\n(async function() {\n" +
1114
+ iifeCode +
1115
+ "\n})().catch(" +
1116
+ errHandler +
1117
+ ");\n})();"
1118
+ );
1119
+ }
1120
+ return `const fs = require("fs"); \n${helper} \n${topCode} \n(async () => { \n${iifeCode} \n })().catch(err => { if (err) console.error("\\x1b[31mRuntime Error:\\x1b[0m", err.stack || err.message); }); `;
1121
+ },
1122
+ FunctionDecl_paren(_fn, id, _lp, params, _rp, block) {
1123
+ const paramNames = params.asIteration().children.map((p) => p.toJS()).join(", ");
1124
+ return `function ${id.toJS()} (${paramNames}) ${block.toJS()} `;
1125
+ },
1126
+ FunctionDecl_classic(_fn, id, params, block) {
1127
+ const paramNames = params.children.map((p) => p.toJS()).join(", ");
1128
+ return `function ${id.toJS()} (${paramNames}) ${block.toJS()} `;
1129
+ },
1130
+ AsyncFunctionDecl_paren(_async, _fn, id, _lp, params, _rp, block) {
1131
+ const paramNames = params.asIteration().children.map((p) => p.toJS()).join(", ");
1132
+ return `async function ${id.toJS()} (${paramNames}) ${block.toJS()} `;
1133
+ },
1134
+ AsyncFunctionDecl_classic(_async, _fn, id, params, block) {
1135
+ const paramNames = params.children.map((p) => p.toJS()).join(", ");
1136
+ return `async function ${id.toJS()} (${paramNames}) ${block.toJS()} `;
1137
+ },
1138
+ ClassDecl(_class, id, _extends, superId, _lb, members, _rb) {
1139
+ const extension = superId.children.length > 0 ? `extends ${superId.toJS()} ` : "";
1140
+ return `class ${id.toJS()} ${extension}{ \n ${members.children.map((m) => m.toJS()).join("\n")} \n } `;
1141
+ },
1142
+ ImportStmt_all(_import, path, _as, id) {
1143
+ let p = path.toJS();
1144
+ p = p.replace(/\.kade([`"'])$/, ".js$1");
1145
+ const inner = p.replace(/^["'`]|["'`]$/g, "");
1146
+ if (inner.includes("/") && !/^\.\.?\//.test(inner))
1147
+ p = p.replace(/^(["`'])(.*)(["`'])$/, "$1./$2$3");
1148
+ return `const ${id.toJS()} = require(${p});`;
1149
+ },
1150
+ ImportStmt_named(_import, _lb, ids, _rb, _from, path) {
1151
+ let p = path.toJS();
1152
+ p = p.replace(/\.kade([`"'])$/, ".js$1");
1153
+ const inner = p.replace(/^["'`]|["'`]$/g, "");
1154
+ if (inner.includes("/") && !/^\.\.?\//.test(inner))
1155
+ p = p.replace(/^(["`'])(.*)(["`'])$/, "$1./$2$3");
1156
+ const idList = ids
1157
+ .asIteration()
1158
+ .children.map((i) => i.toJS())
1159
+ .join(", ");
1160
+ return `const { ${idList} } = require(${p});`;
1161
+ },
1162
+ ExportStmt_default(_export, _default, expr) {
1163
+ return `if (typeof exports !== 'undefined') exports.default = ${expr.toJS()}; else export default ${expr.toJS()};`;
1164
+ },
1165
+ ExportStmt_named(_export, decl) {
1166
+ const js = decl.toJS().trim();
1167
+ const name = decl.getName();
1168
+ return `${js}\nif (typeof exports !== 'undefined') exports.${name} = ${name};`;
1169
+ },
1170
+ Declaration(decl) {
1171
+ return decl.toJS();
1172
+ },
1173
+ MethodDecl(staticKw, privateKw, _fn, id, params, block) {
1174
+ const paramNames = params.children.map((p) => p.toJS()).join(", ");
1175
+ const name = id.toJS();
1176
+ const prefix = (staticKw.sourceString ? "static " : "") + (privateKw.sourceString ? "#" : "");
1177
+ return ` ${prefix}${name} (${paramNames}) ${block.toJS()} `;
1178
+ },
1179
+ PropertyDecl(staticKw, privateKw, id, _eq, expr) {
1180
+ const prefix = (staticKw.sourceString ? "static " : "") + (privateKw.sourceString ? "#" : "");
1181
+ return ` ${prefix}${id.toJS()} = ${expr.toJS()}; `;
1182
+ },
1183
+ Param_rest(_dots, id) {
1184
+ return `...${id.toJS()}`;
1185
+ },
1186
+ Param_default(id, _eq, expr) {
1187
+ return `${id.toJS()} = ${expr.toJS()}`;
1188
+ },
1189
+ Param_base(id) {
1190
+ return id.toJS();
1191
+ },
1192
+ VariableDecl(_let, pattern, _eq, expr) {
1193
+ return `let ${pattern.toJS()} = ${expr.toJS()}; `;
1194
+ },
1195
+ ConstantDecl(_const, pattern, _eq, expr) {
1196
+ return `const ${pattern.toJS()} = ${expr.toJS()}; `;
1197
+ },
1198
+ BindingPattern_object(_lb, ids, _rb) {
1199
+ return `{ ${ids.asIteration().children.map(i => i.toJS()).join(", ")} }`;
1200
+ },
1201
+ BindingPattern_list(_lb, ids, _rb) {
1202
+ return `[ ${ids.asIteration().children.map(i => i.toJS()).join(", ")} ]`;
1203
+ },
1204
+ BindingPattern_base(id) {
1205
+ return id.toJS();
1206
+ },
1207
+ Assignment_simple(member, _op, expr) {
1208
+ return `${member.toJS()} = ${expr.toJS()}; `;
1209
+ },
1210
+ Assignment_destructure(pattern, _op, expr) {
1211
+ return `${pattern.toJS()} = ${expr.toJS()}; `;
1212
+ },
1213
+ TryStmt(_try, tryBlock, _catch, errorId, catchBlock) {
1214
+ return `try ${tryBlock.toJS()} catch(${errorId.toJS()}) ${catchBlock.toJS()} `;
1215
+ },
1216
+ MatchStmt(_match, expr, _open, cases, elseCase, _close) {
1217
+ const val = expr.toJS();
1218
+ let result = `(() => { const __match = ${val}; `;
1219
+ const caseNodes = cases.children;
1220
+ for (let i = 0; i < caseNodes.length; i++) {
1221
+ const caseCode = caseNodes[i].toJS();
1222
+ if (i === 0) result += `if ${caseCode} `;
1223
+ else result += `else if ${caseCode} `;
1224
+ }
1225
+ if (elseCase.children.length > 0) {
1226
+ result += `else { ${elseCase.children[0].toJS()} } `;
1227
+ }
1228
+ result += `})(); `;
1229
+ return result;
1230
+ },
1231
+ MatchCase(_when, condition, _then, statement) {
1232
+ return `(__match === ${condition.toJS()}) { ${statement.toJS()} }`;
1233
+ },
1234
+ MatchElse(_else, statement) {
1235
+ return statement.toJS();
1236
+ },
1237
+ RepeatStmt(_repeat, count, _unit, block) {
1238
+ return `for (let __i = 0; __i < ${count.toJS()}; __i++) ${block.toJS()} `;
1239
+ },
1240
+ WebStmt_create(_create, _elem, str) {
1241
+ return `document.createElement(${str.toJS()}); `;
1242
+ },
1243
+ WebStmt_add_child(_add, child, _to, parent) {
1244
+ return `__kadence_add(${parent.toJS()}, ${child.toJS()});`;
1245
+ },
1246
+ SetStmt_style(_set, prop, _of, target, _to, val) {
1247
+ let p = prop.toJS();
1248
+ if (p === "text") return `${target.toJS()}.innerText = ${val.toJS()};`;
1249
+ if (p === "class") return `${target.toJS()}.className = ${val.toJS()};`;
1250
+ return `${target.toJS()}.style.${p} = ${val.toJS()};`;
1251
+ },
1252
+ SetStmt_prop(_set, target, prop, _to, val) {
1253
+ let p = prop.toJS();
1254
+ if (p === "class") p = "className";
1255
+ if (p === "text") p = "innerText";
1256
+ if (p === "value") p = "value";
1257
+ return `${target.toJS()}.${p} = ${val.toJS()};`;
1258
+ },
1259
+ SetStmt_simple(_set, target, _to, val) {
1260
+ return `${target.toJS()} = ${val.toJS()};`;
1261
+ },
1262
+ ListStmt_add(_add, val, _to, list) {
1263
+ return `__kadence_add(${list.toJS()}, ${val.toJS()});`;
1264
+ },
1265
+ ListStmt_remove_at(_rem, _item, idx, _from, list) {
1266
+ return `${list.toJS()}.splice(${idx.toJS()}, 1);`;
1267
+ },
1268
+ PropTerm(node) {
1269
+ return node.sourceString;
1270
+ },
1271
+ FileStmt_save(_save, content, _to, path) {
1272
+ return `fs.writeFileSync(${path.toJS()}, ${content.toJS()});`;
1273
+ },
1274
+ FileStmt_read(_read, _from, path) {
1275
+ return `fs.readFileSync(${path.toJS()}, 'utf8');`;
1276
+ },
1277
+ NavigateStmt(_go, _to, expr) {
1278
+ return `window.location.href = ${expr.toJS()};`;
1279
+ },
1280
+ AskExpr(_ask, str) {
1281
+ return `prompt(${str.toJS()})`;
1282
+ },
1283
+ SizeExpr(_size, _of, id) {
1284
+ return `${id.toJS()}.length`;
1285
+ },
1286
+ MathExpr_average(_avg, _of, id) {
1287
+ const i = id.toJS();
1288
+ return `(${i}.reduce((a, b) => a + b, 0) / ${i}.length)`;
1289
+ },
1290
+ MathExpr_min(_min, _of, id) {
1291
+ return `__kadence_min(${id.toJS()})`;
1292
+ },
1293
+ MathExpr_max(_max, _of, id) {
1294
+ return `__kadence_max(${id.toJS()})`;
1295
+ },
1296
+ MathExpr_round(_round, expr) {
1297
+ return `Math.round(${expr.toJS()})`;
1298
+ },
1299
+ MathExpr_floor(_floor, expr) {
1300
+ return `Math.floor(${expr.toJS()})`;
1301
+ },
1302
+ MathExpr_ceil(_ceil, expr) {
1303
+ return `Math.ceil(${expr.toJS()})`;
1304
+ },
1305
+ MathExpr_abs(_abs, expr) {
1306
+ return `Math.abs(${expr.toJS()})`;
1307
+ },
1308
+ MathExpr_sqrt(_sqrt, _root, expr) {
1309
+ return `Math.sqrt(${expr.toJS()})`;
1310
+ },
1311
+ MathExpr_pow(_pow, base, _to, exp) {
1312
+ return `Math.pow(${base.toJS()}, ${exp.toJS()})`;
1313
+ },
1314
+ MathExpr_sin(_sin, expr) {
1315
+ return `Math.sin(${expr.toJS()})`;
1316
+ },
1317
+ MathExpr_cos(_cos, expr) {
1318
+ return `Math.cos(${expr.toJS()})`;
1319
+ },
1320
+ MathExpr_tan(_tan, expr) {
1321
+ return `Math.tan(${expr.toJS()})`;
1322
+ },
1323
+
1324
+ ListExpr_sort(_sort, expr) {
1325
+ return `[...${expr.toJS()}].sort()`;
1326
+ },
1327
+ ListExpr_reverse(_reverse, expr) {
1328
+ return `[...${expr.toJS()}].reverse()`;
1329
+ },
1330
+ ListExpr_push(_push, val, _to, array) {
1331
+ return `(() => { const _a = ${array.toJS()}; _a.push(${val.toJS()}); return _a; })()`;
1332
+ },
1333
+ ListExpr_pop(_pop, _from, array) {
1334
+ return `${array.toJS()}.pop()`;
1335
+ },
1336
+
1337
+ ObjectExpr_keys(_keys, _of, expr) {
1338
+ return `Object.keys(${expr.toJS()})`;
1339
+ },
1340
+ ObjectExpr_values(_values, _of, expr) {
1341
+ return `Object.values(${expr.toJS()})`;
1342
+ },
1343
+ ObjectExpr_merge(_merge, a, _with, b) {
1344
+ return `Object.assign({}, ${a.toJS()}, ${b.toJS()})`;
1345
+ },
1346
+ ReadExpr(_read, _from, path) {
1347
+ return `fs.readFileSync(${path.toJS()}, 'utf8')`;
1348
+ },
1349
+ TimeExpr_time(_the, _time, _now) {
1350
+ return `new Date().toLocaleTimeString()`;
1351
+ },
1352
+ TimeExpr_date(_the, _date, _today) {
1353
+ return `new Date().toLocaleDateString()`;
1354
+ },
1355
+ ConvertExpr(_convert, expr, _to, type) {
1356
+ const t = type.toJS();
1357
+ if (t === "number") return `Number(${expr.toJS()})`;
1358
+ if (t === "string") return `String(${expr.toJS()})`;
1359
+ if (t === "bool") return `Boolean(${expr.toJS()})`;
1360
+ if (t === "object") return `Object(${expr.toJS()})`;
1361
+ return `${t}(${expr.toJS()})`;
1362
+ },
1363
+ AwaitExpr(_await, expr) {
1364
+ return `await ${expr.toJS()}`;
1365
+ },
1366
+ NewExpr_paren(_new, id, _lp, args, _rp) {
1367
+ return `new ${id.sourceString}(${args
1368
+ .asIteration()
1369
+ .children.map((a) => a.toJS())
1370
+ .join(", ")})`;
1371
+ },
1372
+ NewExpr_classic(_new, id, args) {
1373
+ return `new ${id.sourceString}(${args
1374
+ .children.map((a) => a.toJS())
1375
+ .join(", ")})`;
1376
+ },
1377
+ ObjectLiteral(_objKw, _lb, pairs, _rb) {
1378
+ const pairStrs = pairs
1379
+ .asIteration()
1380
+ .children.map((p) => p.toJS())
1381
+ .join(", ");
1382
+ return `{ ${pairStrs} }`;
1383
+ },
1384
+ ObjectPair_pair(key, _colon, value) {
1385
+ return `${key.toJS()}: ${value.toJS()}`;
1386
+ },
1387
+ ObjectPair_shorthand(id) {
1388
+ return id.toJS();
1389
+ },
1390
+ ObjectPair_spread(spread) {
1391
+ return spread.toJS();
1392
+ },
1393
+ ArrayMethod_map(_map, array, _with, lambda) {
1394
+ return `${array.toJS()}.map(${lambda.toJS()})`;
1395
+ },
1396
+ ArrayMethod_filter(_filter, array, _where, lambda) {
1397
+ return `${array.toJS()}.filter(${lambda.toJS()})`;
1398
+ },
1399
+ ArrayMethod_reduce(_reduce, array, _from, init, _with, lambda) {
1400
+ return `${array.toJS()}.reduce(${lambda.toJS()}, ${init.toJS()})`;
1401
+ },
1402
+ ArrayMethod_find(_find, array, _where, lambda) {
1403
+ return `${array.toJS()}.find(${lambda.toJS()})`;
1404
+ },
1405
+ ArrayMethod_some(_some, array, _where, lambda) {
1406
+ return `${array.toJS()}.some(${lambda.toJS()})`;
1407
+ },
1408
+ ArrayMethod_every(_every, array, _where, lambda) {
1409
+ return `${array.toJS()}.every(${lambda.toJS()})`;
1410
+ },
1411
+ HttpExpr_get(_get, _from, url) {
1412
+ return `fetch(${url.toJS()}).then(r => r.json())`;
1413
+ },
1414
+ HttpExpr_post(_post, _to, url, _with, data) {
1415
+ return `fetch(${url.toJS()}, {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(${data.toJS()})}).then(r => r.json())`;
1416
+ },
1417
+ HttpExpr_put(_put, _to, url, _with, data) {
1418
+ return `fetch(${url.toJS()}, {method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(${data.toJS()})}).then(r => r.json())`;
1419
+ },
1420
+ HttpExpr_delete(_delete, _from, url) {
1421
+ return `fetch(${url.toJS()}, {method: 'DELETE'}).then(r => r.json())`;
1422
+ },
1423
+ JsonExpr_parse(_parse, _json, _from, str) {
1424
+ return `JSON.parse(${str.toJS()})`;
1425
+ },
1426
+ JsonExpr_stringify(_stringify, obj, _to, _json) {
1427
+ return `JSON.stringify(${obj.toJS()})`;
1428
+ },
1429
+ RegexExpr_create(_regex, pattern) {
1430
+ return `new RegExp(${pattern.toJS()})`;
1431
+ },
1432
+ RegexExpr_extractAll(_extract, _all, pattern, _from, str) {
1433
+ return `${str.toJS()}.match(${pattern.toJS()})`;
1434
+ },
1435
+ StringCheck(child) {
1436
+ return child.toJS();
1437
+ },
1438
+ MatchCheck(str, _matches, pattern) {
1439
+ return `${pattern.toJS()}.test(${str.toJS()})`;
1440
+ },
1441
+ StringCmd_split(_split, str, _by, delim) {
1442
+ return `${str.toJS()}.split(${delim.toJS()})`;
1443
+ },
1444
+ StringCmd_join(_join, array, _with, delim) {
1445
+ return `${array.toJS()}.join(${delim.toJS()})`;
1446
+ },
1447
+ StringCmd_trim(_trim, str) {
1448
+ return `${str.toJS()}.trim()`;
1449
+ },
1450
+ StringCmd_replace(_replace, search, _with, replacement, _in, str) {
1451
+ return `${str.toJS()}.replace(${search.toJS()}, ${replacement.toJS()})`;
1452
+ },
1453
+ StringCmd_indexOf(_index, _of, search, _in, str) {
1454
+ return `${str.toJS()}.indexOf(${search.toJS()})`;
1455
+ },
1456
+ StringCmd_lastIndexOf(_last, _index, _of, search, _in, str) {
1457
+ return `${str.toJS()}.lastIndexOf(${search.toJS()})`;
1458
+ },
1459
+
1460
+ StringCheck_includes(str, _includes, search) {
1461
+ return `${str.toJS()}.includes(${search.toJS()})`;
1462
+ },
1463
+ StringCheck_startsWith(str, _starts, _with, search) {
1464
+ return `${str.toJS()}.startsWith(${search.toJS()})`;
1465
+ },
1466
+ StringCheck_endsWith(str, _ends, _with, search) {
1467
+ return `${str.toJS()}.endsWith(${search.toJS()})`;
1468
+ },
1469
+ Comparison_string_check(child) {
1470
+ return child.toJS();
1471
+ },
1472
+ Comparison_property_check(child) {
1473
+ return child.toJS();
1474
+ },
1475
+ PropertyCheck(obj, _has, prop) {
1476
+ return `(${prop.toJS()} in ${obj.toJS()})`;
1477
+ },
1478
+
1479
+ SpreadExpr(_dots, expr) {
1480
+ return `...${expr.toJS()}`;
1481
+ },
1482
+ RangeExpr(_range, start, _to, end) {
1483
+ return `Array.from({length: ${end.toJS()} - ${start.toJS()} + 1}, (_, i) => i + ${start.toJS()})`;
1484
+ },
1485
+ Lambda_simple(param, _arrow, body) {
1486
+ const asyncKw = body.hasAwait() ? "async " : "";
1487
+ return `${asyncKw}${param.toJS()} => ${body.toJS()}`;
1488
+ },
1489
+ Lambda_multi(_lp, params, _rp, _arrow, body) {
1490
+ const asyncKw = body.hasAwait() ? "async " : "";
1491
+ return `${asyncKw}(${params
1492
+ .asIteration()
1493
+ .children.map((p) => p.toJS())
1494
+ .join(", ")}) => ${body.toJS()}`;
1495
+ },
1496
+ MemberAccess_prop(obj, _dot, prop) {
1497
+ return `${obj.toJS()}.${prop.toJS()}`;
1498
+ },
1499
+ MemberAccess_index(obj, _lb, index, _rb) {
1500
+ return `${obj.toJS()}[${index.toJS()}]`;
1501
+ },
1502
+ MemberAccess_base(id) {
1503
+ return id.toJS();
1504
+ },
1505
+ CreateExpr_call(_create, _elem, str) {
1506
+ return `document.createElement(${str.toJS()})`;
1507
+ },
1508
+ ReturnStmt(_ret, expr) {
1509
+ return `return ${expr.toJS()};`;
1510
+ },
1511
+ IncrementStmt_word(_inc, id) {
1512
+ return `${id.toJS()}++;`;
1513
+ },
1514
+ IncrementStmt_sym(id, _sym) {
1515
+ return `${id.toJS()}++;`;
1516
+ },
1517
+ DecrementStmt_word(_dec, id) {
1518
+ return `${id.toJS()}--;`;
1519
+ },
1520
+ DecrementStmt_sym(id, _sym) {
1521
+ return `${id.toJS()}--;`;
1522
+ },
1523
+ WaitStmt(_wait, expr, _unit) {
1524
+ return `await new Promise(r => setTimeout(r, ${expr.toJS()} * 1000));`;
1525
+ },
1526
+ RandomExpr_range(_rand, _num, _from, min, _to, max) {
1527
+ return `Math.floor(Math.random() * (${max.toJS()} - ${min.toJS()} + 1)) + ${min.toJS()}`;
1528
+ },
1529
+ RandomExpr_float(_rand) {
1530
+ return `Math.random()`;
1531
+ },
1532
+ TypeCheck(expr, _is, _a, type) {
1533
+ const t = type.toJS();
1534
+ if (t === "number") return `typeof ${expr.toJS()} === 'number'`;
1535
+ if (t === "string") return `typeof ${expr.toJS()} === 'string'`;
1536
+ if (t === "bool") return `typeof ${expr.toJS()} === 'boolean'`;
1537
+ if (t === "list") return `Array.isArray(${expr.toJS()})`;
1538
+ return `typeof ${expr.toJS()} === '${t}'`;
1539
+ },
1540
+ TypeTerm(node) {
1541
+ return node.sourceString;
1542
+ },
1543
+ Primary_transform(child) {
1544
+ return child.toJS();
1545
+ },
1546
+ TransformExpr(op, expr) {
1547
+ const o = op.toJS();
1548
+ if (o === "uppercase") return `(${expr.toJS()}).toString().toUpperCase()`;
1549
+ if (o === "lowercase") return `(${expr.toJS()}).toString().toLowerCase()`;
1550
+ return expr.toJS();
1551
+ },
1552
+ Comparison_type_check(child) {
1553
+ return child.toJS();
1554
+ },
1555
+ Primary_regex(child) {
1556
+ return child.toJS();
1557
+ },
1558
+ Primary_range(child) {
1559
+ return child.toJS();
1560
+ },
1561
+ IfStmt(_if, cond, block, elifKws, elifConds, elifBlocks, _elseKw, elseBlock) {
1562
+ let result = `if (${cond.toJS()}) ${block.toJS()} `;
1563
+
1564
+ const elifC = elifConds.children;
1565
+ const elifB = elifBlocks.children;
1566
+ for (let i = 0; i < elifC.length; i++) {
1567
+ result += ` else if (${elifC[i].toJS()}) ${elifB[i].toJS()} `;
1568
+ }
1569
+
1570
+ if (_elseKw.children.length > 0) {
1571
+ result += ` else ${elseBlock.children[0].toJS()} `;
1572
+ }
1573
+
1574
+ return result;
1575
+ },
1576
+ WhileStmt(_while, cond, block) {
1577
+ return `while (${cond.toJS()}) ${block.toJS()} `;
1578
+ },
1579
+ ForStmt(_for, _each, id, _in, expr, block) {
1580
+ return `for (let ${id.toJS()} of ${expr.toJS()}) ${block.toJS()}`;
1581
+ },
1582
+ WhenStmt(_when, target, _is, event, block) {
1583
+ let eventName = event.toJS();
1584
+ if (eventName === "clicked") eventName = "click";
1585
+ const asyncKw = block.hasAwait() ? "async " : "";
1586
+ return `${target.toJS()}.addEventListener('${eventName}', ${asyncKw}() => ${block.toJS()});`;
1587
+ },
1588
+ EchoStmt(_echo, expr) {
1589
+ return `__kadence_echo(${expr.toJS()}); `;
1590
+ },
1591
+ ExpressionStmt(expr) {
1592
+ return `${expr.toJS()}; `;
1593
+ },
1594
+ BreakStmt(_break) {
1595
+ return "break; ";
1596
+ },
1597
+ ContinueStmt(_continue) {
1598
+ return "continue; ";
1599
+ },
1600
+ Block(_lb, statements, _rb) {
1601
+ return `{ \n${statements.children.map((s) => " " + s.toJS()).join("\n")} \n } `;
1602
+ },
1603
+ CoalesceExpr_coalesce(left, _op, right) {
1604
+ return `${left.toJS()} ?? ${right.toJS()}`;
1605
+ },
1606
+ TypeofExpr(_typeof, expr) {
1607
+ return `typeof ${expr.toJS()}`;
1608
+ },
1609
+ CoalesceExpr(child) {
1610
+ return child.toJS();
1611
+ },
1612
+ OrExpr_word(left, _or, right) {
1613
+ return `${left.toJS()} || ${right.toJS()}`;
1614
+ },
1615
+ OrExpr_sym(left, _op, right) {
1616
+ return `${left.toJS()} || ${right.toJS()} `;
1617
+ },
1618
+ OrExpr(child) {
1619
+ return child.toJS();
1620
+ },
1621
+ AndExpr_word(left, _and, right) {
1622
+ return `${left.toJS()} && ${right.toJS()} `;
1623
+ },
1624
+ AndExpr_sym(left, _op, right) {
1625
+ return `${left.toJS()} && ${right.toJS()} `;
1626
+ },
1627
+ AndExpr(child) {
1628
+ return child.toJS();
1629
+ },
1630
+ NotExpr_word(_not, expr) {
1631
+ return `!(${expr.toJS()})`;
1632
+ },
1633
+ NotExpr_sym(_op, expr) {
1634
+ return `!(${expr.toJS()})`;
1635
+ },
1636
+ NotExpr(child) {
1637
+ return child.toJS();
1638
+ },
1639
+ Comparison_full(left, op, right) {
1640
+ const l = left.toJS();
1641
+ currentSubject = l; // UPDATE SUBJECT
1642
+ return `${l} ${op.toJS()} ${right.toJS()} `;
1643
+ },
1644
+ Comparison_short(op, right) {
1645
+ return `${currentSubject} ${op.toJS()} ${right.toJS()} `;
1646
+ },
1647
+ Comparison_base(child) {
1648
+ const res = child.toJS();
1649
+ currentSubject = res; // UPDATE SUBJECT
1650
+ return res;
1651
+ },
1652
+ CompareOp_eq_sym_double(_op) {
1653
+ return "===";
1654
+ },
1655
+ CompareOp_eq_sym(_op) {
1656
+ return "===";
1657
+ },
1658
+ CompareOp_eq_word(_op) {
1659
+ return "===";
1660
+ },
1661
+ CompareOp_neq_sym(_op) {
1662
+ return "!==";
1663
+ },
1664
+ CompareOp_neq_word(_not, _equals) {
1665
+ return "!==";
1666
+ },
1667
+ CompareOp_gt_sym(_op) {
1668
+ return ">";
1669
+ },
1670
+ CompareOp_gt_word(_more, _than) {
1671
+ return ">";
1672
+ },
1673
+ CompareOp_lt_sym(_op) {
1674
+ return "<";
1675
+ },
1676
+ CompareOp_lt_word(_less, _than) {
1677
+ return "<";
1678
+ },
1679
+ CompareOp_gte_sym(_op) {
1680
+ return ">=";
1681
+ },
1682
+ CompareOp_gte_word(_at, _least) {
1683
+ return ">=";
1684
+ },
1685
+ CompareOp_lte_sym(_op) {
1686
+ return "<=";
1687
+ },
1688
+ CompareOp_lte_word(_at, _most) {
1689
+ return "<=";
1690
+ },
1691
+ Additive_add_word(left, _plus, right) {
1692
+ return `${left.toJS()} + ${right.toJS()} `;
1693
+ },
1694
+ Additive_add_sym(left, _plus, right) {
1695
+ return `${left.toJS()} + ${right.toJS()} `;
1696
+ },
1697
+ Additive_sub_word(left, _minus, right) {
1698
+ return `${left.toJS()} - ${right.toJS()} `;
1699
+ },
1700
+ Additive_sub_sym(left, _minus, right) {
1701
+ return `${left.toJS()} - ${right.toJS()} `;
1702
+ },
1703
+ Additive(child) {
1704
+ return child.toJS();
1705
+ },
1706
+ BitwiseShift_left(l, _op, r) { return `${l.toJS()} << ${r.toJS()}`; },
1707
+ BitwiseShift_right(l, _op, r) { return `${l.toJS()} >> ${r.toJS()}`; },
1708
+ BitwiseShift(child) { return child.toJS(); },
1709
+ BitwiseAnd_bin(l, _op, r) { return `${l.toJS()} & ${r.toJS()}`; },
1710
+ BitwiseAnd(child) { return child.toJS(); },
1711
+ BitwiseXor_bin(l, _op, r) { return `${l.toJS()} ^ ${r.toJS()}`; },
1712
+ BitwiseXor(child) { return child.toJS(); },
1713
+ BitwiseOr_bin(l, _op, r) { return `${l.toJS()} | ${r.toJS()}`; },
1714
+ BitwiseOr(child) { return child.toJS(); },
1715
+ Multiplicative_mul_sym(left, _times, right) {
1716
+ return `${left.toJS()} * ${right.toJS()} `;
1717
+ },
1718
+ Multiplicative_mul_word(left, _times, right) {
1719
+ return `${left.toJS()} * ${right.toJS()} `;
1720
+ },
1721
+ Multiplicative_div(left, _op, right) {
1722
+ return `${left.toJS()} / ${right.toJS()}`;
1723
+ },
1724
+ Multiplicative_div_word(left, _divided, _by, right) {
1725
+ return `${left.toJS()} / ${right.toJS()}`;
1726
+ },
1727
+ Multiplicative(child) {
1728
+ return child.toJS();
1729
+ },
1730
+ Primary_list(child) {
1731
+ return child.toJS();
1732
+ },
1733
+ Primary_lambda(child) {
1734
+ return child.toJS();
1735
+ },
1736
+ Primary_access(child) {
1737
+ return child.toJS();
1738
+ },
1739
+ Primary_call(child) {
1740
+ return child.toJS();
1741
+ },
1742
+ Primary_math(child) {
1743
+ return child.toJS();
1744
+ },
1745
+ Primary_string(child) {
1746
+ return child.toJS();
1747
+ },
1748
+ Primary_arrayay(child) {
1749
+ return child.toJS();
1750
+ },
1751
+ Primary_list_op(child) {
1752
+ return child.toJS();
1753
+ },
1754
+ Primary_object(child) {
1755
+ return child.toJS();
1756
+ },
1757
+ Primary_json(child) {
1758
+ return child.toJS();
1759
+ },
1760
+ Primary_http(child) {
1761
+ return child.toJS();
1762
+ },
1763
+ Primary_ask(child) {
1764
+ return child.toJS();
1765
+ },
1766
+ Primary_size(child) {
1767
+ return child.toJS();
1768
+ },
1769
+ Primary_random(child) {
1770
+ return child.toJS();
1771
+ },
1772
+ Primary_read(child) {
1773
+ return child.toJS();
1774
+ },
1775
+ Primary_time(child) {
1776
+ return child.toJS();
1777
+ },
1778
+ Primary_convert(child) {
1779
+ return child.toJS();
1780
+ },
1781
+ Primary_member(child) {
1782
+ return child.toJS();
1783
+ },
1784
+ Primary_pi(_pi) {
1785
+ return `Math.PI`;
1786
+ },
1787
+ Primary_num(child) {
1788
+ return child.toJS();
1789
+ },
1790
+ Primary_bool(child) {
1791
+ return child.toJS();
1792
+ },
1793
+ Primary_str(child) {
1794
+ return child.toJS();
1795
+ },
1796
+ Primary_paren(_lp, expr, _rp) {
1797
+ return `(${expr.toJS()})`;
1798
+ },
1799
+ Call_paren(id, _lp, args, _rp) {
1800
+ const argList = args.asIteration().children.map((a) => a.toJS()).join(", ");
1801
+ return `${id.toJS()}(${argList})`;
1802
+ },
1803
+ Call_run(_run, id, args) {
1804
+ const argList = args.children.map((a) => a.toJS()).join(", ");
1805
+ return `${id.toJS()}(${argList})`;
1806
+ },
1807
+ Arg(child) {
1808
+ return child.toJS();
1809
+ },
1810
+ Arg_paren(_lp, expr, _rp) {
1811
+ return `(${expr.toJS()})`;
1812
+ },
1813
+ List(_list, args) {
1814
+ const argList = args.children.map((a) => a.toJS()).join(", ");
1815
+ return `[${argList}]`;
1816
+ },
1817
+ ItemAccess(_item, index, _from, list) {
1818
+ return `${list.toJS()}[${index.toJS()}]`;
1819
+ },
1820
+ MemberAccess_opt_prop(obj, _dot, prop) {
1821
+ return `${obj.toJS()}?.${prop.toJS()}`;
1822
+ },
1823
+ MemberAccess_opt_index(obj, _dot, _lb, index, _rb) {
1824
+ return `${obj.toJS()}?.[${index.toJS()}]`;
1825
+ },
1826
+ MemberAccess_this(_this) {
1827
+ return "this";
1828
+ },
1829
+ MemberAccess_super(_super) {
1830
+ return "super";
1831
+ },
1832
+ string(child) {
1833
+ return child.toJS();
1834
+ },
1835
+ doubleString(_l, parts, _r) {
1836
+ return "`" + parts.children.map((p) => p.toJS()).join("") + "`";
1837
+ },
1838
+ templateString(_l, parts, _r) {
1839
+ return "`" + parts.children.map((p) => p.toJS()).join("") + "`";
1840
+ },
1841
+ escape(_slash, char) {
1842
+ const c = char.sourceString;
1843
+ if (c === "n") return "\\n";
1844
+ if (c === "t") return "\\t";
1845
+ if (c === "r") return "\\r";
1846
+ if (c === '"') return '\\"';
1847
+ if (c === "\\") return "\\\\";
1848
+ if (c === "`") return "\\`";
1849
+ return "\\" + c;
1850
+ },
1851
+ textDouble(char) {
1852
+ return char.sourceString;
1853
+ },
1854
+ textBacktick(char) {
1855
+ return char.sourceString;
1856
+ },
1857
+ interpolation(_l, content, _r) {
1858
+ const exprMatch = grammar.match(content.sourceString, "Expression");
1859
+ if (exprMatch.failed()) {
1860
+ throw new Error(`Invalid expression in string interpolation: ${exprMatch.message}`);
1861
+ }
1862
+ return "${" + semantics(exprMatch).toJS() + "}";
1863
+ },
1864
+ bool(val) {
1865
+ return val.sourceString;
1866
+ },
1867
+ word(_first, _rest) {
1868
+ return this.sourceString;
1869
+ },
1870
+ identifier(w) {
1871
+ return w.toJS();
1872
+ },
1873
+ number(_digits, _dot, _fract) {
1874
+ return this.sourceString;
1875
+ },
1876
+ _iter(...children) {
1877
+ return children.map((c) => c.toJS());
1878
+ },
1879
+ _terminal() {
1880
+ return this.sourceString;
1881
+ },
1882
+ });
1883
+
1884
+ semantics.addOperation("getName", {
1885
+ Program(_statements) {
1886
+ return "";
1887
+ },
1888
+ FunctionDecl_paren(_fn, id, _lp, _params, _rp, _block) {
1889
+ return id.sourceString;
1890
+ },
1891
+ FunctionDecl_classic(_fn, id, _params, _block) {
1892
+ return id.sourceString;
1893
+ },
1894
+ AsyncFunctionDecl_paren(_async, _fn, id, _lp, _params, _rp, _block) {
1895
+ return id.sourceString;
1896
+ },
1897
+ AsyncFunctionDecl_classic(_async, _fn, id, _params, _block) {
1898
+ return id.sourceString;
1899
+ },
1900
+ ClassDecl(_class, id, _extendsKw, _superId, _lb, _members, _rb) {
1901
+ return id.sourceString;
1902
+ },
1903
+ VariableDecl(_let, pattern, _eq, _expr) {
1904
+ return pattern.getName();
1905
+ },
1906
+ ConstantDecl(_const, pattern, _eq, _expr) {
1907
+ return pattern.getName();
1908
+ },
1909
+ BindingPattern_object(_lb, ids, _rb) {
1910
+ return ids.asIteration().children.map(i => i.sourceString).join(", ");
1911
+ },
1912
+ BindingPattern_list(_lb, ids, _rb) {
1913
+ return ids.asIteration().children.map(i => i.sourceString).join(", ");
1914
+ },
1915
+ BindingPattern_base(id) {
1916
+ return id.getName();
1917
+ },
1918
+ word(_first, _rest) {
1919
+ return this.sourceString;
1920
+ },
1921
+ identifier(w) {
1922
+ return w.sourceString;
1923
+ },
1924
+ Declaration(decl) {
1925
+ return decl.getName();
1926
+ },
1927
+ _iter(...children) {
1928
+ return children.map((c) => c.getName());
1929
+ },
1930
+ _terminal() {
1931
+ return this.sourceString;
1932
+ },
1933
+ });
1934
+
1935
+ const analyzer = grammar.createSemantics();
1936
+
1937
+ analyzer.addOperation("getName", {
1938
+ Program(_statements) {
1939
+ return "";
1940
+ },
1941
+ FunctionDecl_paren(_fn, id, _lp, _params, _rp, _block) {
1942
+ return id.sourceString;
1943
+ },
1944
+ FunctionDecl_classic(_fn, id, _params, _block) {
1945
+ return id.sourceString;
1946
+ },
1947
+ AsyncFunctionDecl_paren(_async, _fn, id, _lp, _params, _rp, _block) {
1948
+ return id.sourceString;
1949
+ },
1950
+ AsyncFunctionDecl_classic(_async, _fn, id, _params, _block) {
1951
+ return id.sourceString;
1952
+ },
1953
+ ClassDecl(_class, id, _ext, _superId, _lb, _members, _rb) {
1954
+ return id.sourceString;
1955
+ },
1956
+ VariableDecl(_let, pattern, _eq, _expr) {
1957
+ return pattern.getName();
1958
+ },
1959
+ ConstantDecl(_const, pattern, _eq, _expr) {
1960
+ return pattern.getName();
1961
+ },
1962
+ BindingPattern_object(_lb, ids, _rb) {
1963
+ return ids.asIteration().children.map(i => i.sourceString).join(", ");
1964
+ },
1965
+ BindingPattern_list(_lb, ids, _rb) {
1966
+ return ids.asIteration().children.map(i => i.sourceString).join(", ");
1967
+ },
1968
+ BindingPattern_base(id) {
1969
+ return id.sourceString;
1970
+ },
1971
+ Param_rest(_dots, id) {
1972
+ return id.sourceString;
1973
+ },
1974
+ Param_default(id, _eq, _expr) {
1975
+ return id.sourceString;
1976
+ },
1977
+ Param_base(id) {
1978
+ return id.sourceString;
1979
+ },
1980
+ Declaration(decl) {
1981
+ return decl.getName();
1982
+ },
1983
+ });
1984
+
1985
+ analyzer.addOperation("analyze(context)", {
1986
+ Program(statements) {
1987
+ statements.analyze(this.args.context);
1988
+ },
1989
+ FunctionDecl_paren(_fn, id, _lp, params, _rp, block) {
1990
+ const context = this.args.context;
1991
+ context.symbols.add(id.sourceString);
1992
+ const funcContext = { symbols: new Set(context.symbols) };
1993
+ params.asIteration().children.forEach((p) => funcContext.symbols.add(p.getName()));
1994
+ block.analyze(funcContext);
1995
+ },
1996
+ FunctionDecl_classic(_fn, id, params, block) {
1997
+ const context = this.args.context;
1998
+ context.symbols.add(id.sourceString);
1999
+ const funcContext = { symbols: new Set(context.symbols) };
2000
+ params.children.forEach((p) => funcContext.symbols.add(p.getName()));
2001
+ block.analyze(funcContext);
2002
+ },
2003
+ ClassDecl(_class, id, _extends, superId, _lb, members, _rb) {
2004
+ const context = this.args.context;
2005
+ context.symbols.add(id.sourceString);
2006
+ members.analyze(context);
2007
+ },
2008
+ MethodDecl(_static, _private, _fn, _id, params, block) {
2009
+ const context = this.args.context;
2010
+ const methodContext = { symbols: new Set(context.symbols) };
2011
+ methodContext.symbols.add("this");
2012
+ params.children.forEach((p) => methodContext.symbols.add(p.getName()));
2013
+ block.analyze(methodContext);
2014
+ },
2015
+ PropertyDecl(_static, _private, _id, _eq, expr) {
2016
+ expr.analyze(this.args.context);
2017
+ },
2018
+ ImportStmt_all(_import, _path, _as, id) {
2019
+ this.args.context.symbols.add(id.sourceString);
2020
+ },
2021
+ ImportStmt_named(_import, _lb, ids, _rb, _from, _path) {
2022
+ ids.asIteration().children.forEach((id) => {
2023
+ this.args.context.symbols.add(id.sourceString);
2024
+ });
2025
+ },
2026
+ ExportStmt_default(_export, _default, expr) {
2027
+ expr.analyze(this.args.context);
2028
+ },
2029
+ ExportStmt_named(_export, decl) {
2030
+ decl.analyze(this.args.context);
2031
+ },
2032
+ AsyncFunctionDecl_paren(_async, _fn, id, _lp, params, _rp, block) {
2033
+ const context = this.args.context;
2034
+ context.symbols.add(id.sourceString);
2035
+ const funcContext = { symbols: new Set(context.symbols) };
2036
+ params.asIteration().children.forEach((p) => funcContext.symbols.add(p.getName()));
2037
+ block.analyze(funcContext);
2038
+ },
2039
+ AsyncFunctionDecl_classic(_async, _fn, id, params, block) {
2040
+ const context = this.args.context;
2041
+ context.symbols.add(id.sourceString);
2042
+ const funcContext = { symbols: new Set(context.symbols) };
2043
+ params.children.forEach((p) => funcContext.symbols.add(p.getName()));
2044
+ block.analyze(funcContext);
2045
+ },
2046
+ NewExpr_paren(_new, id, _lp, args, _rp) {
2047
+ const context = this.args.context;
2048
+ const className = id.sourceString;
2049
+ if (!context.symbols.has(className) && className !== "Date" && className !== "RegExp" && className !== "URL" && className !== "Promise") {
2050
+ semanticError(this, `Semantic Error: Unknown class "${className}" (use a declared class or check spelling)`);
2051
+ }
2052
+ args.analyze(context);
2053
+ },
2054
+ NewExpr_classic(_new, id, args) {
2055
+ const context = this.args.context;
2056
+ const className = id.sourceString;
2057
+ if (!context.symbols.has(className) && className !== "Date" && className !== "RegExp" && className !== "URL" && className !== "Promise") {
2058
+ semanticError(this, `Semantic Error: Unknown class "${className}" (use a declared class or check spelling)`);
2059
+ }
2060
+ args.analyze(context);
2061
+ },
2062
+ VariableDecl(_let, pattern, _eq, expr) {
2063
+ const context = this.args.context;
2064
+ expr.analyze(context);
2065
+ pattern.analyze(context);
2066
+ },
2067
+ ConstantDecl(_const, pattern, _eq, expr) {
2068
+ const context = this.args.context;
2069
+ expr.analyze(context);
2070
+ pattern.analyze(context);
2071
+ },
2072
+ BindingPattern_object(_lb, ids, _rb) {
2073
+ const context = this.args.context;
2074
+ ids.asIteration().children.forEach(id => context.symbols.add(id.sourceString));
2075
+ },
2076
+ BindingPattern_list(_lb, ids, _rb) {
2077
+ const context = this.args.context;
2078
+ ids.asIteration().children.forEach(id => context.symbols.add(id.sourceString));
2079
+ },
2080
+ BindingPattern_base(id) {
2081
+ this.args.context.symbols.add(id.sourceString);
2082
+ },
2083
+ Assignment_simple(member, _op, expr) {
2084
+ const context = this.args.context;
2085
+ member.analyze(context);
2086
+ expr.analyze(context);
2087
+ },
2088
+ Assignment_destructure(pattern, _op, expr) {
2089
+ const context = this.args.context;
2090
+ expr.analyze(context);
2091
+ pattern.getName().split(", ").forEach(name => {
2092
+ if (!context.symbols.has(name.trim())) {
2093
+ semanticError(this, `Semantic Error: Undefined variable "${name.trim()}" in destructuring`);
2094
+ }
2095
+ });
2096
+ },
2097
+ Block(_lb, statements, _rb) {
2098
+ statements.analyze(this.args.context);
2099
+ },
2100
+ TryStmt(_try, tryBlock, _catch, errorId, catchBlock) {
2101
+ const context = this.args.context;
2102
+ tryBlock.analyze(context);
2103
+ const catchContext = { symbols: new Set(context.symbols) };
2104
+ catchContext.symbols.add(errorId.sourceString);
2105
+ catchBlock.analyze(catchContext);
2106
+ },
2107
+ MatchStmt(_match, expr, _open, cases, elseCase, _close) {
2108
+ const context = this.args.context;
2109
+ expr.analyze(context);
2110
+ cases.analyze(context);
2111
+ if (elseCase.children.length > 0) elseCase.analyze(context);
2112
+ },
2113
+ MatchCase(_when, expr, _then, stmt) {
2114
+ const context = this.args.context;
2115
+ expr.analyze(context);
2116
+ stmt.analyze(context);
2117
+ },
2118
+ MatchElse(_else, stmt) {
2119
+ stmt.analyze(this.args.context);
2120
+ },
2121
+ RepeatStmt(_repeat, count, _unit, block) {
2122
+ count.analyze(this.args.context);
2123
+ block.analyze(this.args.context);
2124
+ },
2125
+ IfStmt(_if, cond, block, elifKws, elifConds, elifBlocks, _elseKw, elseBlock) {
2126
+ const context = this.args.context;
2127
+ cond.analyze(context);
2128
+ block.analyze(context);
2129
+ elifConds.analyze(context);
2130
+ elifBlocks.analyze(context);
2131
+ if (elseBlock.children.length > 0) elseBlock.analyze(context);
2132
+ },
2133
+ WhileStmt(_while, cond, block) {
2134
+ const context = this.args.context;
2135
+ cond.analyze(context);
2136
+ block.analyze(context);
2137
+ },
2138
+ ForStmt(_for, _each, id, _in, expr, block) {
2139
+ const context = this.args.context;
2140
+ expr.analyze(context);
2141
+ const forContext = { symbols: new Set(context.symbols) };
2142
+ forContext.symbols.add(id.sourceString);
2143
+ block.analyze(forContext);
2144
+ },
2145
+ WhenStmt(_when, target, _is, event, block) {
2146
+ block.analyze(this.args.context);
2147
+ },
2148
+ Call_paren(id, _lp, args, _rp) {
2149
+ const context = this.args.context;
2150
+ id.analyze(context);
2151
+ args.analyze(context);
2152
+ },
2153
+ Call_run(_run, id, args) {
2154
+ const context = this.args.context;
2155
+ id.analyze(context);
2156
+ args.analyze(context);
2157
+ },
2158
+ SetStmt_style(_set, _prop, _of, target, _to, val) {
2159
+ target.analyze(this.args.context);
2160
+ val.analyze(this.args.context);
2161
+ },
2162
+ SetStmt_prop(_set, target, _prop, _to, val) {
2163
+ target.analyze(this.args.context);
2164
+ val.analyze(this.args.context);
2165
+ },
2166
+ SetStmt_simple(_set, target, _to, val) {
2167
+ target.analyze(this.args.context);
2168
+ val.analyze(this.args.context);
2169
+ },
2170
+ PropertyCheck(obj, _has, prop) {
2171
+ const context = this.args.context;
2172
+ obj.analyze(context);
2173
+ prop.analyze(context);
2174
+ },
2175
+ ObjectPair_shorthand(id) {
2176
+ id.analyze(this.args.context);
2177
+ },
2178
+ Lambda_simple(param, _arrayow, body) {
2179
+ const context = this.args.context;
2180
+ const lambdaContext = { symbols: new Set(context.symbols) };
2181
+ lambdaContext.symbols.add(param.sourceString);
2182
+ body.analyze(lambdaContext);
2183
+ },
2184
+ Lambda_multi(_lp, params, _rp, _arrayow, body) {
2185
+ const context = this.args.context;
2186
+ const lambdaContext = { symbols: new Set(context.symbols) };
2187
+ params.asIteration().children.forEach((p) => lambdaContext.symbols.add(p.sourceString));
2188
+ body.analyze(lambdaContext);
2189
+ },
2190
+ MemberAccess_prop(parent, _dot, _id) {
2191
+ parent.analyze(this.args.context);
2192
+ },
2193
+ MemberAccess_index(parent, _lb, expr, _rb) {
2194
+ parent.analyze(this.args.context);
2195
+ expr.analyze(this.args.context);
2196
+ },
2197
+ MemberAccess_this(_this) {
2198
+ // 'this' is always allowed
2199
+ },
2200
+ MemberAccess_base(id) {
2201
+ const context = this.args.context;
2202
+ const name = id.sourceString;
2203
+ const globals = [
2204
+ "document",
2205
+ "window",
2206
+ "console",
2207
+ "game",
2208
+ "Math",
2209
+ "fs",
2210
+ "Array",
2211
+ "Number",
2212
+ "String",
2213
+ "Boolean",
2214
+ "alert",
2215
+ "prompt",
2216
+ "confirm",
2217
+ "location",
2218
+ "localStorage",
2219
+ "sessionStorage",
2220
+ "fetch",
2221
+ "setTimeout",
2222
+ "setInterval",
2223
+ "clearTimeout",
2224
+ "clearInterval",
2225
+ "JSON",
2226
+ "Object",
2227
+ "RegExp",
2228
+ "Date",
2229
+ "pi",
2230
+ "it",
2231
+ "null",
2232
+ "undefined",
2233
+ "require",
2234
+ "process",
2235
+ "Buffer",
2236
+ "URL",
2237
+ "Promise",
2238
+ "encodeURIComponent",
2239
+ "decodeURIComponent",
2240
+ "globalThis",
2241
+ ];
2242
+ if (!context.symbols.has(name) && !globals.includes(name)) {
2243
+ semanticError(id, `Semantic Error: Using undefined variable "${name}"`);
2244
+ }
2245
+ },
2246
+ word(_first, _rest) { },
2247
+ identifier(w) { w.analyze(this.args.context); },
2248
+ _iter(...children) {
2249
+ children.forEach((c) => c.analyze(this.args.context));
2250
+ },
2251
+ _terminal() { },
2252
+ _nonterminal(...children) {
2253
+ children.forEach((c) => c.analyze(this.args.context));
2254
+ },
2255
+ });
2256
+
2257
+ function semanticError(node, msg) {
2258
+ const { line, col } = getLineCol(node.source.startIdx);
2259
+ throw new Error(`${msg} (line ${line}, col ${col})`);
2260
+ }
2261
+
2262
+ function compile(source, options) {
2263
+ compileOptions = Object.assign({ target: "node", sourceFile: "source.kade" }, options);
2264
+ source = source.replace(/^\\uFEFF/, "");
2265
+ const preprocessed = preprocess(source);
2266
+ initLineMap(preprocessed);
2267
+ const match = grammar.match(preprocessed);
2268
+ if (match.failed()) {
2269
+ throw new Error(match.message);
2270
+ }
2271
+
2272
+ const root = match;
2273
+ try {
2274
+ analyzer(root).analyze({ symbols: new Set() });
2275
+ } catch (e) {
2276
+ throw new Error(e.message);
2277
+ }
2278
+
2279
+ if (compileOptions.sourcemap) {
2280
+ const node = semantics(match).toNode();
2281
+ const result = node.toStringWithSourceMap();
2282
+ return {
2283
+ code: result.code,
2284
+ map: result.map.toString()
2285
+ };
2286
+ }
2287
+
2288
+ return semantics(match).toJS();
2289
+ }
2290
+
2291
+ module.exports = { compile, preprocess };