jsparse.c 24 KB

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