zig-pug 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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +346 -0
  3. package/binding.c +375 -0
  4. package/binding.gyp +28 -0
  5. package/common.gypi +5 -0
  6. package/include/zigpug.h +135 -0
  7. package/index.js +205 -0
  8. package/package.json +87 -0
  9. package/vendor/mujs/COPYING +16 -0
  10. package/vendor/mujs/README +50 -0
  11. package/vendor/mujs/astnames.h +92 -0
  12. package/vendor/mujs/jsarray.c +832 -0
  13. package/vendor/mujs/jsboolean.c +38 -0
  14. package/vendor/mujs/jsbuiltin.c +249 -0
  15. package/vendor/mujs/jscompile.c +1428 -0
  16. package/vendor/mujs/jsdate.c +861 -0
  17. package/vendor/mujs/jsdtoa.c +749 -0
  18. package/vendor/mujs/jserror.c +139 -0
  19. package/vendor/mujs/jsfunction.c +231 -0
  20. package/vendor/mujs/jsgc.c +284 -0
  21. package/vendor/mujs/jsi.h +870 -0
  22. package/vendor/mujs/jsintern.c +137 -0
  23. package/vendor/mujs/jslex.c +878 -0
  24. package/vendor/mujs/jsmath.c +194 -0
  25. package/vendor/mujs/jsnumber.c +198 -0
  26. package/vendor/mujs/jsobject.c +560 -0
  27. package/vendor/mujs/json.c +422 -0
  28. package/vendor/mujs/jsparse.c +1065 -0
  29. package/vendor/mujs/jsproperty.c +341 -0
  30. package/vendor/mujs/jsregexp.c +232 -0
  31. package/vendor/mujs/jsrepr.c +285 -0
  32. package/vendor/mujs/jsrun.c +2096 -0
  33. package/vendor/mujs/jsstate.c +334 -0
  34. package/vendor/mujs/jsstring.c +852 -0
  35. package/vendor/mujs/jsvalue.c +708 -0
  36. package/vendor/mujs/libmujs.a +0 -0
  37. package/vendor/mujs/main.c +396 -0
  38. package/vendor/mujs/mujs.h +253 -0
  39. package/vendor/mujs/one.c +25 -0
  40. package/vendor/mujs/opnames.h +85 -0
  41. package/vendor/mujs/pp.c +980 -0
  42. package/vendor/mujs/regexp.c +1277 -0
  43. package/vendor/mujs/regexp.h +46 -0
  44. package/vendor/mujs/utf.c +305 -0
  45. package/vendor/mujs/utf.h +52 -0
  46. package/vendor/mujs/utfdata.h +2209 -0
@@ -0,0 +1,1065 @@
1
+ #include "jsi.h"
2
+
3
+ #define LIST(h) jsP_newnode(J, AST_LIST, 0, h, 0, 0, 0)
4
+
5
+ #define EXP0(x) jsP_newnode(J, EXP_ ## x, line, 0, 0, 0, 0)
6
+ #define EXP1(x,a) jsP_newnode(J, EXP_ ## x, line, a, 0, 0, 0)
7
+ #define EXP2(x,a,b) jsP_newnode(J, EXP_ ## x, line, a, b, 0, 0)
8
+ #define EXP3(x,a,b,c) jsP_newnode(J, EXP_ ## x, line, a, b, c, 0)
9
+
10
+ #define STM0(x) jsP_newnode(J, STM_ ## x, line, 0, 0, 0, 0)
11
+ #define STM1(x,a) jsP_newnode(J, STM_ ## x, line, a, 0, 0, 0)
12
+ #define STM2(x,a,b) jsP_newnode(J, STM_ ## x, line, a, b, 0, 0)
13
+ #define STM3(x,a,b,c) jsP_newnode(J, STM_ ## x, line, a, b, c, 0)
14
+ #define STM4(x,a,b,c,d) jsP_newnode(J, STM_ ## x, line, a, b, c, d)
15
+
16
+ static js_Ast *expression(js_State *J, int notin);
17
+ static js_Ast *assignment(js_State *J, int notin);
18
+ static js_Ast *memberexp(js_State *J);
19
+ static js_Ast *statement(js_State *J);
20
+ static js_Ast *funbody(js_State *J);
21
+
22
+ JS_NORETURN static void jsP_error(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
23
+
24
+ #define INCREC() if (++J->astdepth > JS_ASTLIMIT) jsP_error(J, "too much recursion")
25
+ #define DECREC() --J->astdepth
26
+ #define SAVEREC() int SAVE=J->astdepth
27
+ #define POPREC() J->astdepth=SAVE
28
+
29
+ static void jsP_error(js_State *J, const char *fmt, ...)
30
+ {
31
+ va_list ap;
32
+ char buf[512];
33
+ char msgbuf[256];
34
+
35
+ va_start(ap, fmt);
36
+ vsnprintf(msgbuf, 256, fmt, ap);
37
+ va_end(ap);
38
+
39
+ snprintf(buf, 256, "%s:%d: ", J->filename, J->lexline);
40
+ strcat(buf, msgbuf);
41
+
42
+ js_newsyntaxerror(J, buf);
43
+ js_throw(J);
44
+ }
45
+
46
+ static void jsP_warning(js_State *J, const char *fmt, ...)
47
+ {
48
+ va_list ap;
49
+ char buf[512];
50
+ char msg[256];
51
+
52
+ va_start(ap, fmt);
53
+ vsnprintf(msg, sizeof msg, fmt, ap);
54
+ va_end(ap);
55
+
56
+ snprintf(buf, sizeof buf, "%s:%d: warning: %s", J->filename, J->lexline, msg);
57
+ js_report(J, buf);
58
+ }
59
+
60
+ static js_Ast *jsP_newnode(js_State *J, enum js_AstType type, int line, js_Ast *a, js_Ast *b, js_Ast *c, js_Ast *d)
61
+ {
62
+ js_Ast *node = js_malloc(J, sizeof *node);
63
+
64
+ node->type = type;
65
+ node->line = line;
66
+ node->a = a;
67
+ node->b = b;
68
+ node->c = c;
69
+ node->d = d;
70
+ node->number = 0;
71
+ node->string = NULL;
72
+ node->jumps = NULL;
73
+ node->casejump = 0;
74
+
75
+ node->parent = NULL;
76
+ if (a) a->parent = node;
77
+ if (b) b->parent = node;
78
+ if (c) c->parent = node;
79
+ if (d) d->parent = node;
80
+
81
+ node->gcnext = J->gcast;
82
+ J->gcast = node;
83
+
84
+ return node;
85
+ }
86
+
87
+ static js_Ast *jsP_list(js_Ast *head)
88
+ {
89
+ /* set parent pointers in list nodes */
90
+ js_Ast *prev = head, *node = head->b;
91
+ while (node) {
92
+ node->parent = prev;
93
+ prev = node;
94
+ node = node->b;
95
+ }
96
+ return head;
97
+ }
98
+
99
+ static js_Ast *jsP_newstrnode(js_State *J, enum js_AstType type, const char *s)
100
+ {
101
+ js_Ast *node = jsP_newnode(J, type, J->lexline, 0, 0, 0, 0);
102
+ node->string = s;
103
+ return node;
104
+ }
105
+
106
+ static js_Ast *jsP_newnumnode(js_State *J, enum js_AstType type, double n)
107
+ {
108
+ js_Ast *node = jsP_newnode(J, type, J->lexline, 0, 0, 0, 0);
109
+ node->number = n;
110
+ return node;
111
+ }
112
+
113
+ static void jsP_freejumps(js_State *J, js_JumpList *node)
114
+ {
115
+ while (node) {
116
+ js_JumpList *next = node->next;
117
+ js_free(J, node);
118
+ node = next;
119
+ }
120
+ }
121
+
122
+ void jsP_freeparse(js_State *J)
123
+ {
124
+ js_Ast *node = J->gcast;
125
+ while (node) {
126
+ js_Ast *next = node->gcnext;
127
+ jsP_freejumps(J, node->jumps);
128
+ js_free(J, node);
129
+ node = next;
130
+ }
131
+ J->gcast = NULL;
132
+ }
133
+
134
+ /* Lookahead */
135
+
136
+ static void jsP_next(js_State *J)
137
+ {
138
+ J->lookahead = jsY_lex(J);
139
+ }
140
+
141
+ #define jsP_accept(J,x) (J->lookahead == x ? (jsP_next(J), 1) : 0)
142
+
143
+ #define jsP_expect(J,x) if (!jsP_accept(J, x)) jsP_error(J, "unexpected token: %s (expected %s)", jsY_tokenstring(J->lookahead), jsY_tokenstring(x))
144
+
145
+ static void semicolon(js_State *J)
146
+ {
147
+ if (J->lookahead == ';') {
148
+ jsP_next(J);
149
+ return;
150
+ }
151
+ if (J->newline || J->lookahead == '}' || J->lookahead == 0)
152
+ return;
153
+ jsP_error(J, "unexpected token: %s (expected ';')", jsY_tokenstring(J->lookahead));
154
+ }
155
+
156
+ /* Literals */
157
+
158
+ static js_Ast *identifier(js_State *J)
159
+ {
160
+ js_Ast *a;
161
+ if (J->lookahead == TK_IDENTIFIER) {
162
+ a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
163
+ jsP_next(J);
164
+ return a;
165
+ }
166
+ jsP_error(J, "unexpected token: %s (expected identifier)", jsY_tokenstring(J->lookahead));
167
+ }
168
+
169
+ static js_Ast *identifieropt(js_State *J)
170
+ {
171
+ if (J->lookahead == TK_IDENTIFIER)
172
+ return identifier(J);
173
+ return NULL;
174
+ }
175
+
176
+ static js_Ast *identifiername(js_State *J)
177
+ {
178
+ if (J->lookahead == TK_IDENTIFIER || J->lookahead >= TK_BREAK) {
179
+ js_Ast *a = jsP_newstrnode(J, AST_IDENTIFIER, J->text);
180
+ jsP_next(J);
181
+ return a;
182
+ }
183
+ jsP_error(J, "unexpected token: %s (expected identifier or keyword)", jsY_tokenstring(J->lookahead));
184
+ }
185
+
186
+ static js_Ast *arrayelement(js_State *J)
187
+ {
188
+ int line = J->lexline;
189
+ if (J->lookahead == ',')
190
+ return EXP0(ELISION);
191
+ return assignment(J, 0);
192
+ }
193
+
194
+ static js_Ast *arrayliteral(js_State *J)
195
+ {
196
+ js_Ast *head, *tail;
197
+ if (J->lookahead == ']')
198
+ return NULL;
199
+ head = tail = LIST(arrayelement(J));
200
+ while (jsP_accept(J, ',')) {
201
+ if (J->lookahead != ']')
202
+ tail = tail->b = LIST(arrayelement(J));
203
+ }
204
+ return jsP_list(head);
205
+ }
206
+
207
+ static js_Ast *propname(js_State *J)
208
+ {
209
+ js_Ast *name;
210
+ if (J->lookahead == TK_NUMBER) {
211
+ name = jsP_newnumnode(J, EXP_NUMBER, J->number);
212
+ jsP_next(J);
213
+ } else if (J->lookahead == TK_STRING) {
214
+ name = jsP_newstrnode(J, EXP_STRING, J->text);
215
+ jsP_next(J);
216
+ } else {
217
+ name = identifiername(J);
218
+ }
219
+ return name;
220
+ }
221
+
222
+ static js_Ast *propassign(js_State *J)
223
+ {
224
+ js_Ast *name, *value, *arg, *body;
225
+ int line = J->lexline;
226
+
227
+ name = propname(J);
228
+
229
+ if (J->lookahead != ':' && name->type == AST_IDENTIFIER) {
230
+ if (!strcmp(name->string, "get")) {
231
+ name = propname(J);
232
+ jsP_expect(J, '(');
233
+ jsP_expect(J, ')');
234
+ body = funbody(J);
235
+ return EXP3(PROP_GET, name, NULL, body);
236
+ }
237
+ if (!strcmp(name->string, "set")) {
238
+ name = propname(J);
239
+ jsP_expect(J, '(');
240
+ arg = identifier(J);
241
+ jsP_expect(J, ')');
242
+ body = funbody(J);
243
+ return EXP3(PROP_SET, name, LIST(arg), body);
244
+ }
245
+ }
246
+
247
+ jsP_expect(J, ':');
248
+ value = assignment(J, 0);
249
+ return EXP2(PROP_VAL, name, value);
250
+ }
251
+
252
+ static js_Ast *objectliteral(js_State *J)
253
+ {
254
+ js_Ast *head, *tail;
255
+ if (J->lookahead == '}')
256
+ return NULL;
257
+ head = tail = LIST(propassign(J));
258
+ while (jsP_accept(J, ',')) {
259
+ if (J->lookahead == '}')
260
+ break;
261
+ tail = tail->b = LIST(propassign(J));
262
+ }
263
+ return jsP_list(head);
264
+ }
265
+
266
+ /* Functions */
267
+
268
+ static js_Ast *parameters(js_State *J)
269
+ {
270
+ js_Ast *head, *tail;
271
+ if (J->lookahead == ')')
272
+ return NULL;
273
+ head = tail = LIST(identifier(J));
274
+ while (jsP_accept(J, ',')) {
275
+ tail = tail->b = LIST(identifier(J));
276
+ }
277
+ return jsP_list(head);
278
+ }
279
+
280
+ static js_Ast *fundec(js_State *J, int line)
281
+ {
282
+ js_Ast *a, *b, *c;
283
+ a = identifier(J);
284
+ jsP_expect(J, '(');
285
+ b = parameters(J);
286
+ jsP_expect(J, ')');
287
+ c = funbody(J);
288
+ return jsP_newnode(J, AST_FUNDEC, line, a, b, c, 0);
289
+ }
290
+
291
+ static js_Ast *funstm(js_State *J, int line)
292
+ {
293
+ js_Ast *a, *b, *c;
294
+ a = identifier(J);
295
+ jsP_expect(J, '(');
296
+ b = parameters(J);
297
+ jsP_expect(J, ')');
298
+ c = funbody(J);
299
+ /* rewrite function statement as "var X = function X() {}" */
300
+ return STM1(VAR, LIST(EXP2(VAR, a, EXP3(FUN, a, b, c))));
301
+ }
302
+
303
+ static js_Ast *funexp(js_State *J, int line)
304
+ {
305
+ js_Ast *a, *b, *c;
306
+ a = identifieropt(J);
307
+ jsP_expect(J, '(');
308
+ b = parameters(J);
309
+ jsP_expect(J, ')');
310
+ c = funbody(J);
311
+ return EXP3(FUN, a, b, c);
312
+ }
313
+
314
+ /* Expressions */
315
+
316
+ static js_Ast *primary(js_State *J)
317
+ {
318
+ js_Ast *a;
319
+ int line = J->lexline;
320
+
321
+ if (J->lookahead == TK_IDENTIFIER) {
322
+ a = jsP_newstrnode(J, EXP_IDENTIFIER, J->text);
323
+ jsP_next(J);
324
+ return a;
325
+ }
326
+ if (J->lookahead == TK_STRING) {
327
+ a = jsP_newstrnode(J, EXP_STRING, J->text);
328
+ jsP_next(J);
329
+ return a;
330
+ }
331
+ if (J->lookahead == TK_REGEXP) {
332
+ a = jsP_newstrnode(J, EXP_REGEXP, J->text);
333
+ a->number = J->number;
334
+ jsP_next(J);
335
+ return a;
336
+ }
337
+ if (J->lookahead == TK_NUMBER) {
338
+ a = jsP_newnumnode(J, EXP_NUMBER, J->number);
339
+ jsP_next(J);
340
+ return a;
341
+ }
342
+
343
+ if (jsP_accept(J, TK_THIS)) return EXP0(THIS);
344
+ if (jsP_accept(J, TK_NULL)) return EXP0(NULL);
345
+ if (jsP_accept(J, TK_TRUE)) return EXP0(TRUE);
346
+ if (jsP_accept(J, TK_FALSE)) return EXP0(FALSE);
347
+ if (jsP_accept(J, '{')) {
348
+ a = EXP1(OBJECT, objectliteral(J));
349
+ jsP_expect(J, '}');
350
+ return a;
351
+ }
352
+ if (jsP_accept(J, '[')) {
353
+ a = EXP1(ARRAY, arrayliteral(J));
354
+ jsP_expect(J, ']');
355
+ return a;
356
+ }
357
+ if (jsP_accept(J, '(')) {
358
+ a = expression(J, 0);
359
+ jsP_expect(J, ')');
360
+ return a;
361
+ }
362
+
363
+ jsP_error(J, "unexpected token in expression: %s", jsY_tokenstring(J->lookahead));
364
+ }
365
+
366
+ static js_Ast *arguments(js_State *J)
367
+ {
368
+ js_Ast *head, *tail;
369
+ if (J->lookahead == ')')
370
+ return NULL;
371
+ head = tail = LIST(assignment(J, 0));
372
+ while (jsP_accept(J, ',')) {
373
+ tail = tail->b = LIST(assignment(J, 0));
374
+ }
375
+ return jsP_list(head);
376
+ }
377
+
378
+ static js_Ast *newexp(js_State *J)
379
+ {
380
+ js_Ast *a, *b;
381
+ int line = J->lexline;
382
+
383
+ if (jsP_accept(J, TK_NEW)) {
384
+ a = memberexp(J);
385
+ if (jsP_accept(J, '(')) {
386
+ b = arguments(J);
387
+ jsP_expect(J, ')');
388
+ return EXP2(NEW, a, b);
389
+ }
390
+ return EXP1(NEW, a);
391
+ }
392
+
393
+ if (jsP_accept(J, TK_FUNCTION))
394
+ return funexp(J, line);
395
+
396
+ return primary(J);
397
+ }
398
+
399
+ static js_Ast *memberexp(js_State *J)
400
+ {
401
+ js_Ast *a = newexp(J);
402
+ int line;
403
+ SAVEREC();
404
+ loop:
405
+ INCREC();
406
+ line = J->lexline;
407
+ if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; }
408
+ if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; }
409
+ POPREC();
410
+ return a;
411
+ }
412
+
413
+ static js_Ast *callexp(js_State *J)
414
+ {
415
+ js_Ast *a = newexp(J);
416
+ int line;
417
+ SAVEREC();
418
+ loop:
419
+ INCREC();
420
+ line = J->lexline;
421
+ if (jsP_accept(J, '.')) { a = EXP2(MEMBER, a, identifiername(J)); goto loop; }
422
+ if (jsP_accept(J, '[')) { a = EXP2(INDEX, a, expression(J, 0)); jsP_expect(J, ']'); goto loop; }
423
+ if (jsP_accept(J, '(')) { a = EXP2(CALL, a, arguments(J)); jsP_expect(J, ')'); goto loop; }
424
+ POPREC();
425
+ return a;
426
+ }
427
+
428
+ static js_Ast *postfix(js_State *J)
429
+ {
430
+ js_Ast *a = callexp(J);
431
+ int line = J->lexline;
432
+ if (!J->newline && jsP_accept(J, TK_INC)) return EXP1(POSTINC, a);
433
+ if (!J->newline && jsP_accept(J, TK_DEC)) return EXP1(POSTDEC, a);
434
+ return a;
435
+ }
436
+
437
+ static js_Ast *unary(js_State *J)
438
+ {
439
+ js_Ast *a;
440
+ int line = J->lexline;
441
+ INCREC();
442
+ if (jsP_accept(J, TK_DELETE)) a = EXP1(DELETE, unary(J));
443
+ else if (jsP_accept(J, TK_VOID)) a = EXP1(VOID, unary(J));
444
+ else if (jsP_accept(J, TK_TYPEOF)) a = EXP1(TYPEOF, unary(J));
445
+ else if (jsP_accept(J, TK_INC)) a = EXP1(PREINC, unary(J));
446
+ else if (jsP_accept(J, TK_DEC)) a = EXP1(PREDEC, unary(J));
447
+ else if (jsP_accept(J, '+')) a = EXP1(POS, unary(J));
448
+ else if (jsP_accept(J, '-')) a = EXP1(NEG, unary(J));
449
+ else if (jsP_accept(J, '~')) a = EXP1(BITNOT, unary(J));
450
+ else if (jsP_accept(J, '!')) a = EXP1(LOGNOT, unary(J));
451
+ else a = postfix(J);
452
+ DECREC();
453
+ return a;
454
+ }
455
+
456
+ static js_Ast *multiplicative(js_State *J)
457
+ {
458
+ js_Ast *a = unary(J);
459
+ int line;
460
+ SAVEREC();
461
+ loop:
462
+ INCREC();
463
+ line = J->lexline;
464
+ if (jsP_accept(J, '*')) { a = EXP2(MUL, a, unary(J)); goto loop; }
465
+ if (jsP_accept(J, '/')) { a = EXP2(DIV, a, unary(J)); goto loop; }
466
+ if (jsP_accept(J, '%')) { a = EXP2(MOD, a, unary(J)); goto loop; }
467
+ POPREC();
468
+ return a;
469
+ }
470
+
471
+ static js_Ast *additive(js_State *J)
472
+ {
473
+ js_Ast *a = multiplicative(J);
474
+ int line;
475
+ SAVEREC();
476
+ loop:
477
+ INCREC();
478
+ line = J->lexline;
479
+ if (jsP_accept(J, '+')) { a = EXP2(ADD, a, multiplicative(J)); goto loop; }
480
+ if (jsP_accept(J, '-')) { a = EXP2(SUB, a, multiplicative(J)); goto loop; }
481
+ POPREC();
482
+ return a;
483
+ }
484
+
485
+ static js_Ast *shift(js_State *J)
486
+ {
487
+ js_Ast *a = additive(J);
488
+ int line;
489
+ SAVEREC();
490
+ loop:
491
+ INCREC();
492
+ line = J->lexline;
493
+ if (jsP_accept(J, TK_SHL)) { a = EXP2(SHL, a, additive(J)); goto loop; }
494
+ if (jsP_accept(J, TK_SHR)) { a = EXP2(SHR, a, additive(J)); goto loop; }
495
+ if (jsP_accept(J, TK_USHR)) { a = EXP2(USHR, a, additive(J)); goto loop; }
496
+ POPREC();
497
+ return a;
498
+ }
499
+
500
+ static js_Ast *relational(js_State *J, int notin)
501
+ {
502
+ js_Ast *a = shift(J);
503
+ int line;
504
+ SAVEREC();
505
+ loop:
506
+ INCREC();
507
+ line = J->lexline;
508
+ if (jsP_accept(J, '<')) { a = EXP2(LT, a, shift(J)); goto loop; }
509
+ if (jsP_accept(J, '>')) { a = EXP2(GT, a, shift(J)); goto loop; }
510
+ if (jsP_accept(J, TK_LE)) { a = EXP2(LE, a, shift(J)); goto loop; }
511
+ if (jsP_accept(J, TK_GE)) { a = EXP2(GE, a, shift(J)); goto loop; }
512
+ if (jsP_accept(J, TK_INSTANCEOF)) { a = EXP2(INSTANCEOF, a, shift(J)); goto loop; }
513
+ if (!notin && jsP_accept(J, TK_IN)) { a = EXP2(IN, a, shift(J)); goto loop; }
514
+ POPREC();
515
+ return a;
516
+ }
517
+
518
+ static js_Ast *equality(js_State *J, int notin)
519
+ {
520
+ js_Ast *a = relational(J, notin);
521
+ int line;
522
+ SAVEREC();
523
+ loop:
524
+ INCREC();
525
+ line = J->lexline;
526
+ if (jsP_accept(J, TK_EQ)) { a = EXP2(EQ, a, relational(J, notin)); goto loop; }
527
+ if (jsP_accept(J, TK_NE)) { a = EXP2(NE, a, relational(J, notin)); goto loop; }
528
+ if (jsP_accept(J, TK_STRICTEQ)) { a = EXP2(STRICTEQ, a, relational(J, notin)); goto loop; }
529
+ if (jsP_accept(J, TK_STRICTNE)) { a = EXP2(STRICTNE, a, relational(J, notin)); goto loop; }
530
+ POPREC();
531
+ return a;
532
+ }
533
+
534
+ static js_Ast *bitand(js_State *J, int notin)
535
+ {
536
+ js_Ast *a = equality(J, notin);
537
+ SAVEREC();
538
+ int line = J->lexline;
539
+ while (jsP_accept(J, '&')) {
540
+ INCREC();
541
+ a = EXP2(BITAND, a, equality(J, notin));
542
+ line = J->lexline;
543
+ }
544
+ POPREC();
545
+ return a;
546
+ }
547
+
548
+ static js_Ast *bitxor(js_State *J, int notin)
549
+ {
550
+ js_Ast *a = bitand(J, notin);
551
+ SAVEREC();
552
+ int line = J->lexline;
553
+ while (jsP_accept(J, '^')) {
554
+ INCREC();
555
+ a = EXP2(BITXOR, a, bitand(J, notin));
556
+ line = J->lexline;
557
+ }
558
+ POPREC();
559
+ return a;
560
+ }
561
+
562
+ static js_Ast *bitor(js_State *J, int notin)
563
+ {
564
+ js_Ast *a = bitxor(J, notin);
565
+ SAVEREC();
566
+ int line = J->lexline;
567
+ while (jsP_accept(J, '|')) {
568
+ INCREC();
569
+ a = EXP2(BITOR, a, bitxor(J, notin));
570
+ line = J->lexline;
571
+ }
572
+ POPREC();
573
+ return a;
574
+ }
575
+
576
+ static js_Ast *logand(js_State *J, int notin)
577
+ {
578
+ js_Ast *a = bitor(J, notin);
579
+ int line = J->lexline;
580
+ if (jsP_accept(J, TK_AND)) {
581
+ INCREC();
582
+ a = EXP2(LOGAND, a, logand(J, notin));
583
+ DECREC();
584
+ }
585
+ return a;
586
+ }
587
+
588
+ static js_Ast *logor(js_State *J, int notin)
589
+ {
590
+ js_Ast *a = logand(J, notin);
591
+ int line = J->lexline;
592
+ if (jsP_accept(J, TK_OR)) {
593
+ INCREC();
594
+ a = EXP2(LOGOR, a, logor(J, notin));
595
+ DECREC();
596
+ }
597
+ return a;
598
+ }
599
+
600
+ static js_Ast *conditional(js_State *J, int notin)
601
+ {
602
+ js_Ast *a = logor(J, notin);
603
+ int line = J->lexline;
604
+ if (jsP_accept(J, '?')) {
605
+ js_Ast *b, *c;
606
+ INCREC();
607
+ b = assignment(J, 0);
608
+ jsP_expect(J, ':');
609
+ c = assignment(J, notin);
610
+ DECREC();
611
+ return EXP3(COND, a, b, c);
612
+ }
613
+ return a;
614
+ }
615
+
616
+ static js_Ast *assignment(js_State *J, int notin)
617
+ {
618
+ js_Ast *a = conditional(J, notin);
619
+ int line = J->lexline;
620
+ INCREC();
621
+ if (jsP_accept(J, '=')) a = EXP2(ASS, a, assignment(J, notin));
622
+ else if (jsP_accept(J, TK_MUL_ASS)) a = EXP2(ASS_MUL, a, assignment(J, notin));
623
+ else if (jsP_accept(J, TK_DIV_ASS)) a = EXP2(ASS_DIV, a, assignment(J, notin));
624
+ else if (jsP_accept(J, TK_MOD_ASS)) a = EXP2(ASS_MOD, a, assignment(J, notin));
625
+ else if (jsP_accept(J, TK_ADD_ASS)) a = EXP2(ASS_ADD, a, assignment(J, notin));
626
+ else if (jsP_accept(J, TK_SUB_ASS)) a = EXP2(ASS_SUB, a, assignment(J, notin));
627
+ else if (jsP_accept(J, TK_SHL_ASS)) a = EXP2(ASS_SHL, a, assignment(J, notin));
628
+ else if (jsP_accept(J, TK_SHR_ASS)) a = EXP2(ASS_SHR, a, assignment(J, notin));
629
+ else if (jsP_accept(J, TK_USHR_ASS)) a = EXP2(ASS_USHR, a, assignment(J, notin));
630
+ else if (jsP_accept(J, TK_AND_ASS)) a = EXP2(ASS_BITAND, a, assignment(J, notin));
631
+ else if (jsP_accept(J, TK_XOR_ASS)) a = EXP2(ASS_BITXOR, a, assignment(J, notin));
632
+ else if (jsP_accept(J, TK_OR_ASS)) a = EXP2(ASS_BITOR, a, assignment(J, notin));
633
+ DECREC();
634
+ return a;
635
+ }
636
+
637
+ static js_Ast *expression(js_State *J, int notin)
638
+ {
639
+ js_Ast *a = assignment(J, notin);
640
+ SAVEREC();
641
+ int line = J->lexline;
642
+ while (jsP_accept(J, ',')) {
643
+ INCREC();
644
+ a = EXP2(COMMA, a, assignment(J, notin));
645
+ line = J->lexline;
646
+ }
647
+ POPREC();
648
+ return a;
649
+ }
650
+
651
+ /* Statements */
652
+
653
+ static js_Ast *vardec(js_State *J, int notin)
654
+ {
655
+ js_Ast *a = identifier(J);
656
+ int line = J->lexline;
657
+ if (jsP_accept(J, '='))
658
+ return EXP2(VAR, a, assignment(J, notin));
659
+ return EXP1(VAR, a);
660
+ }
661
+
662
+ static js_Ast *vardeclist(js_State *J, int notin)
663
+ {
664
+ js_Ast *head, *tail;
665
+ head = tail = LIST(vardec(J, notin));
666
+ while (jsP_accept(J, ','))
667
+ tail = tail->b = LIST(vardec(J, notin));
668
+ return jsP_list(head);
669
+ }
670
+
671
+ static js_Ast *statementlist(js_State *J)
672
+ {
673
+ js_Ast *head, *tail;
674
+ if (J->lookahead == '}' || J->lookahead == TK_CASE || J->lookahead == TK_DEFAULT)
675
+ return NULL;
676
+ head = tail = LIST(statement(J));
677
+ while (J->lookahead != '}' && J->lookahead != TK_CASE && J->lookahead != TK_DEFAULT)
678
+ tail = tail->b = LIST(statement(J));
679
+ return jsP_list(head);
680
+ }
681
+
682
+ static js_Ast *caseclause(js_State *J)
683
+ {
684
+ js_Ast *a, *b;
685
+ int line = J->lexline;
686
+
687
+ if (jsP_accept(J, TK_CASE)) {
688
+ a = expression(J, 0);
689
+ jsP_expect(J, ':');
690
+ b = statementlist(J);
691
+ return STM2(CASE, a, b);
692
+ }
693
+
694
+ if (jsP_accept(J, TK_DEFAULT)) {
695
+ jsP_expect(J, ':');
696
+ a = statementlist(J);
697
+ return STM1(DEFAULT, a);
698
+ }
699
+
700
+ jsP_error(J, "unexpected token in switch: %s (expected 'case' or 'default')", jsY_tokenstring(J->lookahead));
701
+ }
702
+
703
+ static js_Ast *caselist(js_State *J)
704
+ {
705
+ js_Ast *head, *tail;
706
+ if (J->lookahead == '}')
707
+ return NULL;
708
+ head = tail = LIST(caseclause(J));
709
+ while (J->lookahead != '}')
710
+ tail = tail->b = LIST(caseclause(J));
711
+ return jsP_list(head);
712
+ }
713
+
714
+ static js_Ast *block(js_State *J)
715
+ {
716
+ js_Ast *a;
717
+ int line = J->lexline;
718
+ jsP_expect(J, '{');
719
+ a = statementlist(J);
720
+ jsP_expect(J, '}');
721
+ return STM1(BLOCK, a);
722
+ }
723
+
724
+ static js_Ast *forexpression(js_State *J, int end)
725
+ {
726
+ js_Ast *a = NULL;
727
+ if (J->lookahead != end)
728
+ a = expression(J, 0);
729
+ jsP_expect(J, end);
730
+ return a;
731
+ }
732
+
733
+ static js_Ast *forstatement(js_State *J, int line)
734
+ {
735
+ js_Ast *a, *b, *c, *d;
736
+ jsP_expect(J, '(');
737
+ if (jsP_accept(J, TK_VAR)) {
738
+ a = vardeclist(J, 1);
739
+ if (jsP_accept(J, ';')) {
740
+ b = forexpression(J, ';');
741
+ c = forexpression(J, ')');
742
+ d = statement(J);
743
+ return STM4(FOR_VAR, a, b, c, d);
744
+ }
745
+ if (jsP_accept(J, TK_IN)) {
746
+ b = expression(J, 0);
747
+ jsP_expect(J, ')');
748
+ c = statement(J);
749
+ return STM3(FOR_IN_VAR, a, b, c);
750
+ }
751
+ jsP_error(J, "unexpected token in for-var-statement: %s", jsY_tokenstring(J->lookahead));
752
+ }
753
+
754
+ if (J->lookahead != ';')
755
+ a = expression(J, 1);
756
+ else
757
+ a = NULL;
758
+ if (jsP_accept(J, ';')) {
759
+ b = forexpression(J, ';');
760
+ c = forexpression(J, ')');
761
+ d = statement(J);
762
+ return STM4(FOR, a, b, c, d);
763
+ }
764
+ if (jsP_accept(J, TK_IN)) {
765
+ b = expression(J, 0);
766
+ jsP_expect(J, ')');
767
+ c = statement(J);
768
+ return STM3(FOR_IN, a, b, c);
769
+ }
770
+ jsP_error(J, "unexpected token in for-statement: %s", jsY_tokenstring(J->lookahead));
771
+ }
772
+
773
+ static js_Ast *statement(js_State *J)
774
+ {
775
+ js_Ast *a, *b, *c, *d;
776
+ js_Ast *stm;
777
+ int line = J->lexline;
778
+
779
+ INCREC();
780
+
781
+ if (J->lookahead == '{') {
782
+ stm = block(J);
783
+ }
784
+
785
+ else if (jsP_accept(J, TK_VAR)) {
786
+ a = vardeclist(J, 0);
787
+ semicolon(J);
788
+ stm = STM1(VAR, a);
789
+ }
790
+
791
+ /* empty statement */
792
+ else if (jsP_accept(J, ';')) {
793
+ stm = STM0(EMPTY);
794
+ }
795
+
796
+ else if (jsP_accept(J, TK_IF)) {
797
+ jsP_expect(J, '(');
798
+ a = expression(J, 0);
799
+ jsP_expect(J, ')');
800
+ b = statement(J);
801
+ if (jsP_accept(J, TK_ELSE))
802
+ c = statement(J);
803
+ else
804
+ c = NULL;
805
+ stm = STM3(IF, a, b, c);
806
+ }
807
+
808
+ else if (jsP_accept(J, TK_DO)) {
809
+ a = statement(J);
810
+ jsP_expect(J, TK_WHILE);
811
+ jsP_expect(J, '(');
812
+ b = expression(J, 0);
813
+ jsP_expect(J, ')');
814
+ semicolon(J);
815
+ stm = STM2(DO, a, b);
816
+ }
817
+
818
+ else if (jsP_accept(J, TK_WHILE)) {
819
+ jsP_expect(J, '(');
820
+ a = expression(J, 0);
821
+ jsP_expect(J, ')');
822
+ b = statement(J);
823
+ stm = STM2(WHILE, a, b);
824
+ }
825
+
826
+ else if (jsP_accept(J, TK_FOR)) {
827
+ stm = forstatement(J, line);
828
+ }
829
+
830
+ else if (jsP_accept(J, TK_CONTINUE)) {
831
+ a = identifieropt(J);
832
+ semicolon(J);
833
+ stm = STM1(CONTINUE, a);
834
+ }
835
+
836
+ else if (jsP_accept(J, TK_BREAK)) {
837
+ a = identifieropt(J);
838
+ semicolon(J);
839
+ stm = STM1(BREAK, a);
840
+ }
841
+
842
+ else if (jsP_accept(J, TK_RETURN)) {
843
+ if (J->lookahead != ';' && J->lookahead != '}' && J->lookahead != 0)
844
+ a = expression(J, 0);
845
+ else
846
+ a = NULL;
847
+ semicolon(J);
848
+ stm = STM1(RETURN, a);
849
+ }
850
+
851
+ else if (jsP_accept(J, TK_WITH)) {
852
+ jsP_expect(J, '(');
853
+ a = expression(J, 0);
854
+ jsP_expect(J, ')');
855
+ b = statement(J);
856
+ stm = STM2(WITH, a, b);
857
+ }
858
+
859
+ else if (jsP_accept(J, TK_SWITCH)) {
860
+ jsP_expect(J, '(');
861
+ a = expression(J, 0);
862
+ jsP_expect(J, ')');
863
+ jsP_expect(J, '{');
864
+ b = caselist(J);
865
+ jsP_expect(J, '}');
866
+ stm = STM2(SWITCH, a, b);
867
+ }
868
+
869
+ else if (jsP_accept(J, TK_THROW)) {
870
+ a = expression(J, 0);
871
+ semicolon(J);
872
+ stm = STM1(THROW, a);
873
+ }
874
+
875
+ else if (jsP_accept(J, TK_TRY)) {
876
+ a = block(J);
877
+ b = c = d = NULL;
878
+ if (jsP_accept(J, TK_CATCH)) {
879
+ jsP_expect(J, '(');
880
+ b = identifier(J);
881
+ jsP_expect(J, ')');
882
+ c = block(J);
883
+ }
884
+ if (jsP_accept(J, TK_FINALLY)) {
885
+ d = block(J);
886
+ }
887
+ if (!b && !d)
888
+ jsP_error(J, "unexpected token in try: %s (expected 'catch' or 'finally')", jsY_tokenstring(J->lookahead));
889
+ stm = STM4(TRY, a, b, c, d);
890
+ }
891
+
892
+ else if (jsP_accept(J, TK_DEBUGGER)) {
893
+ semicolon(J);
894
+ stm = STM0(DEBUGGER);
895
+ }
896
+
897
+ else if (jsP_accept(J, TK_FUNCTION)) {
898
+ jsP_warning(J, "function statements are not standard");
899
+ stm = funstm(J, line);
900
+ }
901
+
902
+ /* labelled statement or expression statement */
903
+ else if (J->lookahead == TK_IDENTIFIER) {
904
+ a = expression(J, 0);
905
+ if (a->type == EXP_IDENTIFIER && jsP_accept(J, ':')) {
906
+ a->type = AST_IDENTIFIER;
907
+ b = statement(J);
908
+ stm = STM2(LABEL, a, b);
909
+ } else {
910
+ semicolon(J);
911
+ stm = a;
912
+ }
913
+ }
914
+
915
+ /* expression statement */
916
+ else {
917
+ stm = expression(J, 0);
918
+ semicolon(J);
919
+ }
920
+
921
+ DECREC();
922
+ return stm;
923
+ }
924
+
925
+ /* Program */
926
+
927
+ static js_Ast *scriptelement(js_State *J)
928
+ {
929
+ int line = J->lexline;
930
+ if (jsP_accept(J, TK_FUNCTION))
931
+ return fundec(J, line);
932
+ return statement(J);
933
+ }
934
+
935
+ static js_Ast *script(js_State *J, int terminator)
936
+ {
937
+ js_Ast *head, *tail;
938
+ if (J->lookahead == terminator)
939
+ return NULL;
940
+ head = tail = LIST(scriptelement(J));
941
+ while (J->lookahead != terminator)
942
+ tail = tail->b = LIST(scriptelement(J));
943
+ return jsP_list(head);
944
+ }
945
+
946
+ static js_Ast *funbody(js_State *J)
947
+ {
948
+ js_Ast *a;
949
+ jsP_expect(J, '{');
950
+ a = script(J, '}');
951
+ jsP_expect(J, '}');
952
+ return a;
953
+ }
954
+
955
+ /* Constant folding */
956
+
957
+ static int toint32(double d)
958
+ {
959
+ double two32 = 4294967296.0;
960
+ double two31 = 2147483648.0;
961
+
962
+ if (!isfinite(d) || d == 0)
963
+ return 0;
964
+
965
+ d = fmod(d, two32);
966
+ d = d >= 0 ? floor(d) : ceil(d) + two32;
967
+ if (d >= two31)
968
+ return d - two32;
969
+ else
970
+ return d;
971
+ }
972
+
973
+ static unsigned int touint32(double d)
974
+ {
975
+ return (unsigned int)toint32(d);
976
+ }
977
+
978
+ static int jsP_setnumnode(js_Ast *node, double x)
979
+ {
980
+ node->type = EXP_NUMBER;
981
+ node->number = x;
982
+ node->a = node->b = node->c = node->d = NULL;
983
+ return 1;
984
+ }
985
+
986
+ static int jsP_foldconst(js_Ast *node)
987
+ {
988
+ double x, y;
989
+ int a, b;
990
+
991
+ if (node->type == AST_LIST) {
992
+ while (node) {
993
+ jsP_foldconst(node->a);
994
+ node = node->b;
995
+ }
996
+ return 0;
997
+ }
998
+
999
+ if (node->type == EXP_NUMBER)
1000
+ return 1;
1001
+
1002
+ a = node->a ? jsP_foldconst(node->a) : 0;
1003
+ b = node->b ? jsP_foldconst(node->b) : 0;
1004
+ if (node->c) jsP_foldconst(node->c);
1005
+ if (node->d) jsP_foldconst(node->d);
1006
+
1007
+ if (a) {
1008
+ x = node->a->number;
1009
+ switch (node->type) {
1010
+ default: break;
1011
+ case EXP_NEG: return jsP_setnumnode(node, -x);
1012
+ case EXP_POS: return jsP_setnumnode(node, x);
1013
+ case EXP_BITNOT: return jsP_setnumnode(node, ~toint32(x));
1014
+ }
1015
+
1016
+ if (b) {
1017
+ y = node->b->number;
1018
+ switch (node->type) {
1019
+ default: break;
1020
+ case EXP_MUL: return jsP_setnumnode(node, x * y);
1021
+ case EXP_DIV: return jsP_setnumnode(node, x / y);
1022
+ case EXP_MOD: return jsP_setnumnode(node, fmod(x, y));
1023
+ case EXP_ADD: return jsP_setnumnode(node, x + y);
1024
+ case EXP_SUB: return jsP_setnumnode(node, x - y);
1025
+ case EXP_SHL: return jsP_setnumnode(node, toint32(x) << (touint32(y) & 0x1F));
1026
+ case EXP_SHR: return jsP_setnumnode(node, toint32(x) >> (touint32(y) & 0x1F));
1027
+ case EXP_USHR: return jsP_setnumnode(node, touint32(x) >> (touint32(y) & 0x1F));
1028
+ case EXP_BITAND: return jsP_setnumnode(node, toint32(x) & toint32(y));
1029
+ case EXP_BITXOR: return jsP_setnumnode(node, toint32(x) ^ toint32(y));
1030
+ case EXP_BITOR: return jsP_setnumnode(node, toint32(x) | toint32(y));
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ return 0;
1036
+ }
1037
+
1038
+ /* Main entry point */
1039
+
1040
+ js_Ast *jsP_parse(js_State *J, const char *filename, const char *source)
1041
+ {
1042
+ js_Ast *p;
1043
+
1044
+ jsY_initlex(J, filename, source);
1045
+ jsP_next(J);
1046
+ J->astdepth = 0;
1047
+ p = script(J, 0);
1048
+ if (p)
1049
+ jsP_foldconst(p);
1050
+
1051
+ return p;
1052
+ }
1053
+
1054
+ js_Ast *jsP_parsefunction(js_State *J, const char *filename, const char *params, const char *body)
1055
+ {
1056
+ js_Ast *p = NULL;
1057
+ int line = 0;
1058
+ if (params) {
1059
+ jsY_initlex(J, filename, params);
1060
+ jsP_next(J);
1061
+ J->astdepth = 0;
1062
+ p = parameters(J);
1063
+ }
1064
+ return EXP3(FUN, NULL, p, jsP_parse(J, filename, body));
1065
+ }