Advertisement
Guest User

Untitled

a guest
Mar 8th, 2019
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 64.11 KB | None | 0 0
  1. # HG changeset patch
  2. # User hongzhidao <hongzhidao@gmail.com>
  3. # Date 1551688026 -28800
  4. # Node ID 5fef4dc24686c4294632ae94514c635f355ce7b4
  5. # Parent 1096977570942e418ee93e500166a953421ee19b
  6. Style.
  7.  
  8. diff -r 109697757094 -r 5fef4dc24686 njs/njs_lexer.c
  9. --- a/njs/njs_lexer.c Tue Mar 05 08:32:54 2019 +0800
  10. +++ b/njs/njs_lexer.c Mon Mar 04 16:27:06 2019 +0800
  11. @@ -273,7 +273,7 @@ static const njs_lexer_multi_t njs_assi
  12.  
  13.  
  14. njs_token_t
  15. -njs_lexer_token(njs_lexer_t *lexer)
  16. +njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer)
  17. {
  18. njs_token_t token;
  19.  
  20. diff -r 109697757094 -r 5fef4dc24686 njs/njs_parser.c
  21. --- a/njs/njs_parser.c Tue Mar 05 08:32:54 2019 +0800
  22. +++ b/njs/njs_parser.c Mon Mar 04 16:27:06 2019 +0800
  23. @@ -126,7 +126,7 @@ njs_parser(njs_vm_t *vm, njs_parser_t *p
  24. }
  25. }
  26.  
  27. - token = njs_parser_token(parser);
  28. + token = njs_parser_token(vm, parser);
  29.  
  30. while (token != NJS_TOKEN_END) {
  31.  
  32. @@ -295,7 +295,7 @@ njs_parser_statement_chain(njs_vm_t *vm,
  33. *dest = node;
  34.  
  35. while (token == NJS_TOKEN_SEMICOLON) {
  36. - token = njs_parser_token(parser);
  37. + token = njs_parser_token(vm, parser);
  38. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  39. break;
  40. }
  41. @@ -336,7 +336,7 @@ njs_parser_statement(njs_vm_t *vm, njs_p
  42. return njs_parser_try_statement(vm, parser);
  43.  
  44. case NJS_TOKEN_SEMICOLON:
  45. - return njs_parser_token(parser);
  46. + return njs_parser_token(vm, parser);
  47.  
  48. case NJS_TOKEN_OPEN_BRACE:
  49. return njs_parser_block_statement(vm, parser);
  50. @@ -392,7 +392,7 @@ njs_parser_statement(njs_vm_t *vm, njs_p
  51. switch (token) {
  52.  
  53. case NJS_TOKEN_SEMICOLON:
  54. - return njs_parser_token(parser);
  55. + return njs_parser_token(vm, parser);
  56.  
  57. case NJS_TOKEN_CLOSE_BRACE:
  58. case NJS_TOKEN_END:
  59. @@ -416,7 +416,7 @@ njs_parser_block_statement(njs_vm_t *vm,
  60. njs_token_t token;
  61. njs_parser_node_t *node;
  62.  
  63. - token = njs_parser_token(parser);
  64. + token = njs_parser_token(vm, parser);
  65. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  66. return token;
  67. }
  68. @@ -451,7 +451,7 @@ njs_parser_block_statement(njs_vm_t *vm,
  69.  
  70. njs_parser_scope_end(vm, parser);
  71.  
  72. - return njs_parser_token(parser);
  73. + return njs_parser_token(vm, parser);
  74. }
  75.  
  76.  
  77. @@ -482,7 +482,7 @@ njs_parser_match(njs_vm_t *vm, njs_parse
  78. njs_token_t match)
  79. {
  80. if (nxt_fast_path(token == match)) {
  81. - return njs_parser_token(parser);
  82. + return njs_parser_token(vm, parser);
  83. }
  84.  
  85. return njs_parser_unexpected_token(vm, parser, token);
  86. @@ -530,7 +530,7 @@ njs_parser_labelled_statement(njs_vm_t *
  87. return NJS_TOKEN_ERROR;
  88. }
  89.  
  90. - token = njs_parser_token(parser);
  91. + token = njs_parser_token(vm, parser);
  92. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  93. return token;
  94. }
  95. @@ -606,7 +606,7 @@ njs_parser_function_declaration(njs_vm_t
  96.  
  97. node->token_line = parser->lexer->token_line;
  98.  
  99. - token = njs_parser_token(parser);
  100. + token = njs_parser_token(vm, parser);
  101. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  102. return token;
  103. }
  104. @@ -631,7 +631,7 @@ njs_parser_function_declaration(njs_vm_t
  105. return NJS_TOKEN_ERROR;
  106. }
  107.  
  108. - token = njs_parser_token(parser);
  109. + token = njs_parser_token(vm, parser);
  110. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  111. return token;
  112. }
  113. @@ -667,7 +667,7 @@ njs_parser_function_expression(njs_vm_t
  114. node->token_line = parser->lexer->token_line;
  115. parser->node = node;
  116.  
  117. - token = njs_parser_token(parser);
  118. + token = njs_parser_token(vm, parser);
  119. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  120. return token;
  121. }
  122. @@ -687,7 +687,7 @@ njs_parser_function_expression(njs_vm_t
  123. return NJS_TOKEN_ERROR;
  124. }
  125.  
  126. - token = njs_parser_token(parser);
  127. + token = njs_parser_token(vm, parser);
  128. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  129. return token;
  130. }
  131. @@ -750,7 +750,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
  132. if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  133. lambda->rest_parameters = 1;
  134.  
  135. - token = njs_parser_token(parser);
  136. + token = njs_parser_token(vm, parser);
  137. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  138. return NJS_TOKEN_ILLEGAL;
  139. }
  140. @@ -773,13 +773,13 @@ njs_parser_function_lambda(njs_vm_t *vm,
  141. return NJS_TOKEN_ERROR;
  142. }
  143.  
  144. - token = njs_parser_token(parser);
  145. + token = njs_parser_token(vm, parser);
  146. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  147. return token;
  148. }
  149.  
  150. if (token == NJS_TOKEN_COMMA) {
  151. - token = njs_parser_token(parser);
  152. + token = njs_parser_token(vm, parser);
  153. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  154. return token;
  155. }
  156. @@ -788,7 +788,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
  157.  
  158. lambda->nargs = njs_scope_offset(index) / sizeof(njs_value_t) - 1;
  159.  
  160. - token = njs_parser_token(parser);
  161. + token = njs_parser_token(vm, parser);
  162. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  163. return token;
  164. }
  165. @@ -797,7 +797,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
  166. return NJS_TOKEN_ILLEGAL;
  167. }
  168.  
  169. - token = njs_parser_token(parser);
  170. + token = njs_parser_token(vm, parser);
  171. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  172. return token;
  173. }
  174. @@ -813,7 +813,7 @@ njs_parser_function_lambda(njs_vm_t *vm,
  175. }
  176. }
  177.  
  178. - token = njs_parser_token(parser);
  179. + token = njs_parser_token(vm, parser);
  180. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  181. return token;
  182. }
  183. @@ -892,7 +892,7 @@ njs_parser_return_statement(njs_vm_t *vm
  184.  
  185. parser->node = node;
  186.  
  187. - token = njs_lexer_token(parser->lexer);
  188. + token = njs_lexer_token(vm, parser->lexer);
  189. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  190. return token;
  191. }
  192. @@ -900,7 +900,7 @@ njs_parser_return_statement(njs_vm_t *vm
  193. switch (token) {
  194.  
  195. case NJS_TOKEN_LINE_END:
  196. - return njs_parser_token(parser);
  197. + return njs_parser_token(vm, parser);
  198.  
  199. case NJS_TOKEN_SEMICOLON:
  200. case NJS_TOKEN_CLOSE_BRACE:
  201. @@ -937,7 +937,7 @@ njs_parser_var_statement(njs_vm_t *vm, n
  202. left = NULL;
  203.  
  204. do {
  205. - token = njs_parser_token(parser);
  206. + token = njs_parser_token(vm, parser);
  207. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  208. return token;
  209. }
  210. @@ -967,7 +967,7 @@ njs_parser_var_statement(njs_vm_t *vm, n
  211. return NJS_TOKEN_ERROR;
  212. }
  213.  
  214. - token = njs_parser_token(parser);
  215. + token = njs_parser_token(vm, parser);
  216. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  217. return token;
  218. }
  219. @@ -976,7 +976,7 @@ njs_parser_var_statement(njs_vm_t *vm, n
  220.  
  221. if (token == NJS_TOKEN_ASSIGNMENT) {
  222.  
  223. - token = njs_parser_token(parser);
  224. + token = njs_parser_token(vm, parser);
  225. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  226. return token;
  227. }
  228. @@ -1037,7 +1037,7 @@ njs_parser_if_statement(njs_vm_t *vm, nj
  229.  
  230. stmt = parser->node;
  231.  
  232. - token = njs_parser_token(parser);
  233. + token = njs_parser_token(vm, parser);
  234. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  235. return token;
  236. }
  237. @@ -1109,7 +1109,7 @@ njs_parser_switch_statement(njs_vm_t *vm
  238. }
  239.  
  240. if (token == NJS_TOKEN_CASE) {
  241. - token = njs_parser_token(parser);
  242. + token = njs_parser_token(vm, parser);
  243. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  244. return token;
  245. }
  246. @@ -1141,7 +1141,7 @@ njs_parser_switch_statement(njs_vm_t *vm
  247. branch->token = NJS_TOKEN_DEFAULT;
  248. dflt = branch;
  249.  
  250. - token = njs_parser_token(parser);
  251. + token = njs_parser_token(vm, parser);
  252. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  253. return token;
  254. }
  255. @@ -1179,7 +1179,7 @@ njs_parser_switch_statement(njs_vm_t *vm
  256.  
  257. parser->node = swtch;
  258.  
  259. - return njs_parser_token(parser);
  260. + return njs_parser_token(vm, parser);
  261. }
  262.  
  263.  
  264. @@ -1220,7 +1220,7 @@ njs_parser_do_while_statement(njs_vm_t *
  265. njs_token_t token;
  266. njs_parser_node_t *node, *stmt;
  267.  
  268. - token = njs_parser_token(parser);
  269. + token = njs_parser_token(vm, parser);
  270. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  271. return token;
  272. }
  273. @@ -1265,7 +1265,7 @@ njs_parser_for_statement(njs_vm_t *vm, n
  274. condition = NULL;
  275. update = NULL;
  276.  
  277. - token = njs_parser_token(parser);
  278. + token = njs_parser_token(vm, parser);
  279. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  280. return token;
  281. }
  282. @@ -1389,7 +1389,7 @@ njs_parser_for_var_statement(njs_vm_t *v
  283. left = NULL;
  284.  
  285. do {
  286. - token = njs_parser_token(parser);
  287. + token = njs_parser_token(vm, parser);
  288. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  289. return token;
  290. }
  291. @@ -1419,7 +1419,7 @@ njs_parser_for_var_statement(njs_vm_t *v
  292. return NJS_TOKEN_ERROR;
  293. }
  294.  
  295. - token = njs_parser_token(parser);
  296. + token = njs_parser_token(vm, parser);
  297. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  298. return token;
  299. }
  300. @@ -1432,7 +1432,7 @@ njs_parser_for_var_statement(njs_vm_t *v
  301.  
  302. if (token == NJS_TOKEN_ASSIGNMENT) {
  303.  
  304. - token = njs_parser_token(parser);
  305. + token = njs_parser_token(vm, parser);
  306. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  307. return token;
  308. }
  309. @@ -1478,7 +1478,7 @@ njs_parser_for_var_in_statement(njs_vm_t
  310. njs_token_t token;
  311. njs_parser_node_t *node, *foreach;
  312.  
  313. - token = njs_parser_token(parser);
  314. + token = njs_parser_token(vm, parser);
  315. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  316. return token;
  317. }
  318. @@ -1576,12 +1576,12 @@ njs_parser_brk_statement(njs_vm_t *vm, n
  319. node->token_line = parser->lexer->token_line;
  320. parser->node = node;
  321.  
  322. - token = njs_lexer_token(parser->lexer);
  323. + token = njs_lexer_token(vm, parser->lexer);
  324.  
  325. switch (token) {
  326.  
  327. case NJS_TOKEN_LINE_END:
  328. - return njs_parser_token(parser);
  329. + return njs_parser_token(vm, parser);
  330.  
  331. case NJS_TOKEN_NAME:
  332. name = parser->lexer->text;
  333. @@ -1598,7 +1598,7 @@ njs_parser_brk_statement(njs_vm_t *vm, n
  334. return NJS_TOKEN_ERROR;
  335. }
  336.  
  337. - return njs_parser_token(parser);
  338. + return njs_parser_token(vm, parser);
  339.  
  340. case NJS_TOKEN_SEMICOLON:
  341. case NJS_TOKEN_CLOSE_BRACE:
  342. @@ -1633,7 +1633,7 @@ njs_parser_try_statement(njs_vm_t *vm, n
  343. try->left = parser->node;
  344.  
  345. if (token == NJS_TOKEN_CATCH) {
  346. - token = njs_parser_token(parser);
  347. + token = njs_parser_token(vm, parser);
  348. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  349. return token;
  350. }
  351. @@ -1680,7 +1680,7 @@ njs_parser_try_statement(njs_vm_t *vm, n
  352.  
  353. catch->left = node;
  354.  
  355. - token = njs_parser_token(parser);
  356. + token = njs_parser_token(vm, parser);
  357. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  358. return token;
  359. }
  360. @@ -1739,7 +1739,7 @@ njs_parser_try_block(njs_vm_t *vm, njs_p
  361. njs_token_t token;
  362. njs_parser_node_t *node;
  363.  
  364. - token = njs_parser_token(parser);
  365. + token = njs_parser_token(vm, parser);
  366. if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
  367. return NJS_TOKEN_ILLEGAL;
  368. }
  369. @@ -1772,7 +1772,7 @@ njs_parser_throw_statement(njs_vm_t *vm,
  370. return NJS_TOKEN_ERROR;
  371. }
  372.  
  373. - token = njs_lexer_token(parser->lexer);
  374. + token = njs_lexer_token(vm, parser->lexer);
  375. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  376. return token;
  377. }
  378. @@ -1802,7 +1802,7 @@ njs_parser_grouping_expression(njs_vm_t
  379. {
  380. njs_token_t token;
  381.  
  382. - token = njs_parser_token(parser);
  383. + token = njs_parser_token(vm, parser);
  384. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  385. return token;
  386. }
  387. @@ -1830,7 +1830,7 @@ njs_parser_property_token(njs_vm_t *vm,
  388.  
  389. parser->lexer->property = 1;
  390.  
  391. - token = njs_parser_token(parser);
  392. + token = njs_parser_token(vm, parser);
  393.  
  394. parser->lexer->property = 0;
  395.  
  396. @@ -1853,12 +1853,12 @@ njs_parser_property_token(njs_vm_t *vm,
  397.  
  398.  
  399. njs_token_t
  400. -njs_parser_token(njs_parser_t *parser)
  401. +njs_parser_token(njs_vm_t *vm, njs_parser_t *parser)
  402. {
  403. njs_token_t token;
  404.  
  405. do {
  406. - token = njs_lexer_token(parser->lexer);
  407. + token = njs_lexer_token(vm, parser->lexer);
  408.  
  409. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  410. return token;
  411. @@ -1882,7 +1882,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
  412.  
  413. if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  414.  
  415. - token = njs_parser_token(parser);
  416. + token = njs_parser_token(vm, parser);
  417. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  418. return token;
  419. }
  420. @@ -2037,7 +2037,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
  421.  
  422. parser->node = node;
  423.  
  424. - return njs_parser_token(parser);
  425. + return njs_parser_token(vm, parser);
  426. }
  427.  
  428.  
  429. @@ -2316,13 +2316,13 @@ njs_parser_object(njs_vm_t *vm, njs_pars
  430. switch (token) {
  431.  
  432. case NJS_TOKEN_CLOSE_BRACE:
  433. - return njs_parser_token(parser);
  434. + return njs_parser_token(vm, parser);
  435.  
  436. case NJS_TOKEN_NAME:
  437. name = lexer->text;
  438. hash = lexer->key_hash;
  439.  
  440. - token = njs_parser_token(parser);
  441. + token = njs_parser_token(vm, parser);
  442. break;
  443.  
  444. case NJS_TOKEN_NUMBER:
  445. @@ -2394,7 +2394,7 @@ njs_parser_object(njs_vm_t *vm, njs_pars
  446. left = stmt;
  447.  
  448. if (token == NJS_TOKEN_CLOSE_BRACE) {
  449. - return njs_parser_token(parser);
  450. + return njs_parser_token(vm, parser);
  451. }
  452.  
  453. if (nxt_slow_path(token != NJS_TOKEN_COMMA)) {
  454. @@ -2415,7 +2415,7 @@ njs_parser_array(njs_vm_t *vm, njs_parse
  455. left = NULL;
  456.  
  457. for ( ;; ) {
  458. - token = njs_parser_token(parser);
  459. + token = njs_parser_token(vm, parser);
  460. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  461. return token;
  462. }
  463. @@ -2493,7 +2493,7 @@ njs_parser_array(njs_vm_t *vm, njs_parse
  464.  
  465. obj->u.length = index;
  466.  
  467. - return njs_parser_token(parser);
  468. + return njs_parser_token(vm, parser);
  469. }
  470.  
  471.  
  472. diff -r 109697757094 -r 5fef4dc24686 njs/njs_parser.h
  473. --- a/njs/njs_parser.h Tue Mar 05 08:32:54 2019 +0800
  474. +++ b/njs/njs_parser.h Mon Mar 04 16:27:06 2019 +0800
  475. @@ -307,7 +307,7 @@ typedef struct {
  476. } njs_keyword_t;
  477.  
  478.  
  479. -njs_token_t njs_lexer_token(njs_lexer_t *lexer);
  480. +njs_token_t njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer);
  481. void njs_lexer_rollback(njs_lexer_t *lexer);
  482. njs_token_t njs_lexer_peek_token(njs_lexer_t *lexer);
  483. nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
  484. @@ -326,7 +326,7 @@ njs_token_t njs_parser_assignment_expres
  485. njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser,
  486. njs_token_t token);
  487. njs_token_t njs_parser_property_token(njs_vm_t *vm, njs_parser_t *parser);
  488. -njs_token_t njs_parser_token(njs_parser_t *parser);
  489. +njs_token_t njs_parser_token(njs_vm_t *vm, njs_parser_t *parser);
  490. njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node);
  491. njs_index_t njs_variable_typeof(njs_vm_t *vm, njs_parser_node_t *node);
  492. njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node);
  493. diff -r 109697757094 -r 5fef4dc24686 njs/njs_parser_expression.c
  494. --- a/njs/njs_parser_expression.c Tue Mar 05 08:32:54 2019 +0800
  495. +++ b/njs/njs_parser_expression.c Mon Mar 04 16:27:06 2019 +0800
  496. @@ -243,7 +243,7 @@ njs_parser_var_expression(njs_vm_t *vm,
  497. node->u.operation = operation;
  498. node->left = parser->node;
  499.  
  500. - token = njs_parser_token(parser);
  501. + token = njs_parser_token(vm, parser);
  502. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  503. return token;
  504. }
  505. @@ -376,7 +376,7 @@ njs_parser_assignment_expression(njs_vm_
  506. node->u.operation = operation;
  507. node->left = parser->node;
  508.  
  509. - token = njs_parser_token(parser);
  510. + token = njs_parser_token(vm, parser);
  511. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  512. return token;
  513. }
  514. @@ -410,7 +410,7 @@ njs_parser_conditional_expression(njs_vm
  515. return token;
  516. }
  517.  
  518. - token = njs_parser_token(parser);
  519. + token = njs_parser_token(vm, parser);
  520. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  521. return token;
  522. }
  523. @@ -441,7 +441,7 @@ njs_parser_conditional_expression(njs_vm
  524. node->left = parser->node;
  525. node->left->dest = cond;
  526.  
  527. - token = njs_parser_token(parser);
  528. + token = njs_parser_token(vm, parser);
  529. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  530. return token;
  531. }
  532. @@ -499,7 +499,7 @@ njs_parser_binary_expression(njs_vm_t *v
  533. node->left = parser->node;
  534. node->left->dest = node;
  535.  
  536. - token = njs_parser_token(parser);
  537. + token = njs_parser_token(vm, parser);
  538. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  539. return token;
  540. }
  541. @@ -538,7 +538,7 @@ njs_parser_exponential_expression(njs_vm
  542. node->left = parser->node;
  543. node->left->dest = node;
  544.  
  545. - token = njs_parser_token(parser);
  546. + token = njs_parser_token(vm, parser);
  547. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  548. return token;
  549. }
  550. @@ -602,7 +602,7 @@ njs_parser_unary_expression(njs_vm_t *vm
  551. return njs_parser_inc_dec_expression(vm, parser, token);
  552. }
  553.  
  554. - next = njs_parser_token(parser);
  555. + next = njs_parser_token(vm, parser);
  556. if (nxt_slow_path(next <= NJS_TOKEN_ILLEGAL)) {
  557. return next;
  558. }
  559. @@ -698,7 +698,7 @@ njs_parser_inc_dec_expression(njs_vm_t *
  560. return njs_parser_post_inc_dec_expression(vm, parser, token);
  561. }
  562.  
  563. - next = njs_parser_token(parser);
  564. + next = njs_parser_token(vm, parser);
  565. if (nxt_slow_path(next <= NJS_TOKEN_ILLEGAL)) {
  566. return next;
  567. }
  568. @@ -777,7 +777,7 @@ njs_parser_post_inc_dec_expression(njs_v
  569. node->left = parser->node;
  570. parser->node = node;
  571.  
  572. - return njs_parser_token(parser);
  573. + return njs_parser_token(vm, parser);
  574. }
  575.  
  576.  
  577. @@ -863,7 +863,7 @@ njs_parser_call_expression(njs_vm_t *vm,
  578.  
  579. parser->node = func;
  580.  
  581. - token = njs_parser_token(parser);
  582. + token = njs_parser_token(vm, parser);
  583. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  584. return token;
  585. }
  586. @@ -877,7 +877,7 @@ njs_parser_new_expression(njs_vm_t *vm,
  587. {
  588. njs_parser_node_t *func, *node;
  589.  
  590. - token = njs_parser_token(parser);
  591. + token = njs_parser_token(vm, parser);
  592. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  593. return token;
  594. }
  595. @@ -957,7 +957,7 @@ njs_parser_new_expression(njs_vm_t *vm,
  596.  
  597. parser->node = func;
  598.  
  599. - return njs_parser_token(parser);
  600. + return njs_parser_token(vm, parser);
  601. }
  602.  
  603.  
  604. @@ -993,10 +993,10 @@ njs_parser_property_expression(njs_vm_t
  605. return NJS_TOKEN_ILLEGAL;
  606. }
  607.  
  608. - token = njs_parser_token(parser);
  609. + token = njs_parser_token(vm, parser);
  610.  
  611. } else {
  612. - token = njs_parser_token(parser);
  613. + token = njs_parser_token(vm, parser);
  614. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  615. return token;
  616. }
  617. @@ -1027,7 +1027,7 @@ njs_parser_property_brackets(njs_vm_t *v
  618. return NJS_TOKEN_ERROR;
  619. }
  620.  
  621. - return njs_parser_token(parser);
  622. + return njs_parser_token(vm, parser);
  623. }
  624.  
  625.  
  626. @@ -1042,7 +1042,7 @@ njs_parser_arguments(njs_vm_t *vm, njs_p
  627. index = NJS_SCOPE_CALLEE_ARGUMENTS;
  628.  
  629. do {
  630. - token = njs_parser_token(parser);
  631. + token = njs_parser_token(vm, parser);
  632. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  633. return token;
  634. }
  635. # HG changeset patch
  636. # User hongzhidao <hongzhidao@gmail.com>
  637. # Date 1551688482 -28800
  638. # Node ID 52960032fe5688efa96ed0189bcba6cd39ccca52
  639. # Parent 5fef4dc24686c4294632ae94514c635f355ce7b4
  640. Improved lexer.
  641.  
  642. diff -r 5fef4dc24686 -r 52960032fe56 njs/njs_lexer.c
  643. --- a/njs/njs_lexer.c Mon Mar 04 16:27:06 2019 +0800
  644. +++ b/njs/njs_lexer.c Mon Mar 04 16:34:42 2019 +0800
  645. @@ -275,16 +275,22 @@ static const njs_lexer_multi_t njs_assi
  646. njs_token_t
  647. njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer)
  648. {
  649. - njs_token_t token;
  650. -
  651. lexer->prev_start = lexer->start;
  652. lexer->prev_token = lexer->token;
  653.  
  654. - token = njs_lexer_next_token(lexer);
  655. + lexer->token = njs_lexer_next_token(lexer);
  656. + lexer->token_line = lexer->line;
  657.  
  658. - lexer->token = token;
  659. + if (lexer->token == NJS_TOKEN_NAME) {
  660. + njs_lexer_keyword(lexer);
  661.  
  662. - return token;
  663. + if (lexer->property) {
  664. + lexer->property_token = lexer->token;
  665. + lexer->token = NJS_TOKEN_NAME;
  666. + }
  667. + }
  668. +
  669. + return lexer->token;
  670. }
  671.  
  672.  
  673. @@ -485,8 +491,7 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  674. static njs_token_t
  675. njs_lexer_word(njs_lexer_t *lexer, u_char c)
  676. {
  677. - u_char *p;
  678. - njs_token_t token;
  679. + u_char *p;
  680.  
  681. /* TODO: UTF-8 */
  682.  
  683. @@ -508,7 +513,6 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha
  684. 0x00, 0x00, 0x00, 0x00, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
  685. };
  686.  
  687. - lexer->token_line = lexer->line;
  688. lexer->key_hash = nxt_djb_hash_add(NXT_DJB_HASH_INIT, c);
  689. lexer->text.start = lexer->start - 1;
  690.  
  691. @@ -525,14 +529,7 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha
  692. lexer->start = p;
  693. lexer->text.length = p - lexer->text.start;
  694.  
  695. - token = njs_lexer_keyword(lexer);
  696. -
  697. - if (lexer->property) {
  698. - lexer->property_token = token;
  699. - return NJS_TOKEN_NAME;
  700. - }
  701. -
  702. - return token;
  703. + return NJS_TOKEN_NAME;
  704. }
  705.  
  706.  
  707. diff -r 5fef4dc24686 -r 52960032fe56 njs/njs_lexer_keyword.c
  708. --- a/njs/njs_lexer_keyword.c Mon Mar 04 16:27:06 2019 +0800
  709. +++ b/njs/njs_lexer_keyword.c Mon Mar 04 16:34:42 2019 +0800
  710. @@ -173,7 +173,7 @@ njs_lexer_keywords_init(nxt_mp_t *mp, nx
  711. }
  712.  
  713.  
  714. -njs_token_t
  715. +void
  716. njs_lexer_keyword(njs_lexer_t *lexer)
  717. {
  718. njs_keyword_t *keyword;
  719. @@ -185,10 +185,7 @@ njs_lexer_keyword(njs_lexer_t *lexer)
  720.  
  721. if (nxt_lvlhsh_find(&lexer->keywords_hash, &lhq) == NXT_OK) {
  722. keyword = lhq.value;
  723. + lexer->token = keyword->token;
  724. lexer->number = keyword->number;
  725. -
  726. - return keyword->token;
  727. }
  728. -
  729. - return NJS_TOKEN_NAME;
  730. }
  731. diff -r 5fef4dc24686 -r 52960032fe56 njs/njs_parser.c
  732. --- a/njs/njs_parser.c Mon Mar 04 16:27:06 2019 +0800
  733. +++ b/njs/njs_parser.c Mon Mar 04 16:34:42 2019 +0800
  734. @@ -2776,9 +2776,9 @@ njs_parser_trace_handler(nxt_trace_t *tr
  735.  
  736. if (lexer->file.length != 0) {
  737. njs_internal_error(vm, "%s in %V:%uD", start, &lexer->file,
  738. - lexer->line);
  739. + lexer->token_line);
  740. } else {
  741. - njs_internal_error(vm, "%s in %uD", start, lexer->line);
  742. + njs_internal_error(vm, "%s in %uD", start, lexer->token_line);
  743. }
  744.  
  745. } else {
  746. @@ -2833,8 +2833,8 @@ njs_parser_lexer_error(njs_vm_t *vm, njs
  747. }
  748.  
  749. va_start(args, fmt);
  750. - njs_parser_scope_error(vm, parser->scope, type, parser->lexer->line, fmt,
  751. - args);
  752. + njs_parser_scope_error(vm, parser->scope, type, parser->lexer->token_line,
  753. + fmt, args);
  754. va_end(args);
  755. }
  756.  
  757. diff -r 5fef4dc24686 -r 52960032fe56 njs/njs_parser.h
  758. --- a/njs/njs_parser.h Mon Mar 04 16:27:06 2019 +0800
  759. +++ b/njs/njs_parser.h Mon Mar 04 16:34:42 2019 +0800
  760. @@ -311,7 +311,7 @@ njs_token_t njs_lexer_token(njs_vm_t *vm
  761. void njs_lexer_rollback(njs_lexer_t *lexer);
  762. njs_token_t njs_lexer_peek_token(njs_lexer_t *lexer);
  763. nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
  764. -njs_token_t njs_lexer_keyword(njs_lexer_t *lexer);
  765. +void njs_lexer_keyword(njs_lexer_t *lexer);
  766.  
  767. nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
  768. njs_parser_t *prev);
  769. # HG changeset patch
  770. # User hongzhidao <hongzhidao@gmail.com>
  771. # Date 1551806725 -28800
  772. # Node ID 049c1a5fa4fa9771031253616a6ced9163b52ccb
  773. # Parent 52960032fe5688efa96ed0189bcba6cd39ccca52
  774. arrow function support.
  775.  
  776. diff -r 52960032fe56 -r 049c1a5fa4fa njs/njs.c
  777. --- a/njs/njs.c Mon Mar 04 16:34:42 2019 +0800
  778. +++ b/njs/njs.c Wed Mar 06 01:25:25 2019 +0800
  779. @@ -234,13 +234,10 @@ njs_vm_compile(njs_vm_t *vm, u_char **st
  780. prev = vm->parser;
  781. vm->parser = parser;
  782.  
  783. - nxt_memzero(&lexer, sizeof(njs_lexer_t));
  784. -
  785. - lexer.start = *start;
  786. - lexer.end = end;
  787. - lexer.line = 1;
  788. - lexer.file = vm->options.file;
  789. - lexer.keywords_hash = vm->shared->keywords_hash;
  790. + ret = njs_lexer_init(vm, &lexer, &vm->options.file, *start, end);
  791. + if (nxt_slow_path(ret != NXT_OK)) {
  792. + return NJS_ERROR;
  793. + }
  794.  
  795. parser->lexer = &lexer;
  796.  
  797. diff -r 52960032fe56 -r 049c1a5fa4fa njs/njs_lexer.c
  798. --- a/njs/njs_lexer.c Mon Mar 04 16:34:42 2019 +0800
  799. +++ b/njs/njs_lexer.c Wed Mar 06 01:25:25 2019 +0800
  800. @@ -18,6 +18,7 @@ struct njs_lexer_multi_s {
  801. };
  802.  
  803.  
  804. +static nxt_int_t njs_lexer_preread_token(njs_vm_t *vm, njs_lexer_t *lexer);
  805. static njs_token_t njs_lexer_next_token(njs_lexer_t *lexer);
  806. static njs_token_t njs_lexer_word(njs_lexer_t *lexer, u_char c);
  807. static njs_token_t njs_lexer_string(njs_lexer_t *lexer, u_char quote);
  808. @@ -27,6 +28,9 @@ static njs_token_t njs_lexer_multi(njs_l
  809. static njs_token_t njs_lexer_division(njs_lexer_t *lexer,
  810. njs_token_t token);
  811.  
  812. +#define njs_lexer_last_token(lexer) \
  813. + nxt_array_last((lexer)->preread)
  814. +
  815.  
  816. static const uint8_t njs_tokens[256] nxt_aligned(64) = {
  817.  
  818. @@ -269,17 +273,63 @@ static const njs_lexer_multi_t njs_grea
  819.  
  820. static const njs_lexer_multi_t njs_assignment_token[] = {
  821. { '=', NJS_TOKEN_EQUAL, 1, njs_strict_equal_token },
  822. + { '>', NJS_TOKEN_ARROW, 0, NULL },
  823. };
  824.  
  825.  
  826. +nxt_int_t
  827. +njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, nxt_str_t *file,
  828. + u_char *start, u_char *end)
  829. +{
  830. + nxt_memzero(lexer, sizeof(njs_lexer_t));
  831. +
  832. + lexer->file = *file;
  833. + lexer->start = start;
  834. + lexer->end = end;
  835. + lexer->line = 1;
  836. + lexer->keywords_hash = vm->shared->keywords_hash;
  837. +
  838. + lexer->preread = nxt_array_create(2, sizeof(njs_lexer_token_t),
  839. + &njs_array_mem_proto, vm->mem_pool);
  840. + if (nxt_slow_path(lexer->preread == NULL)) {
  841. + return NXT_ERROR;
  842. + }
  843. +
  844. + lexer->pos = 0;
  845. +
  846. + return NXT_OK;
  847. +}
  848. +
  849. +
  850. njs_token_t
  851. njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer)
  852. {
  853. + nxt_int_t ret;
  854. + nxt_array_t *preread;
  855. + njs_lexer_token_t *lt;
  856. +
  857. lexer->prev_start = lexer->start;
  858. lexer->prev_token = lexer->token;
  859.  
  860. - lexer->token = njs_lexer_next_token(lexer);
  861. - lexer->token_line = lexer->line;
  862. + preread = lexer->preread;
  863. +
  864. + if (lexer->pos == preread->items) {
  865. + nxt_array_reset(preread);
  866. + lexer->pos = 0;
  867. +
  868. + ret = njs_lexer_preread_token(vm, lexer);
  869. + if (nxt_slow_path(ret != NXT_OK)) {
  870. + return NJS_TOKEN_ERROR;
  871. + }
  872. + }
  873. +
  874. + lt = nxt_array_item(preread, lexer->pos++);
  875. +
  876. + lexer->token = lt->token;
  877. + lexer->token_line = lt->token_line;
  878. + lexer->key_hash = lt->key_hash;
  879. + lexer->text = lt->text;
  880. + lexer->number = lt->number;
  881.  
  882. if (lexer->token == NJS_TOKEN_NAME) {
  883. njs_lexer_keyword(lexer);
  884. @@ -294,36 +344,104 @@ njs_lexer_token(njs_vm_t *vm, njs_lexer_
  885. }
  886.  
  887.  
  888. -void
  889. -njs_lexer_rollback(njs_lexer_t *lexer)
  890. +njs_token_t
  891. +njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset)
  892. {
  893. - lexer->start = lexer->prev_start;
  894. - lexer->token = lexer->prev_token;
  895. -}
  896. + size_t i, n;
  897. + nxt_int_t ret;
  898. + nxt_array_t *preread;
  899. + njs_lexer_token_t *lt;
  900.  
  901. + lexer->prev_start = lexer->start;
  902. + lexer->prev_token = lexer->token;
  903.  
  904. -njs_token_t
  905. -njs_lexer_peek_token(njs_lexer_t *lexer)
  906. -{
  907. - u_char *start;
  908. - njs_token_t token;
  909. + preread = lexer->preread;
  910.  
  911. - start = lexer->start;
  912. + n = 0;
  913.  
  914. - while (start < lexer->end) {
  915. - token = njs_tokens[*start++];
  916. + offset = lexer->pos + offset;
  917.  
  918. - switch (token) {
  919. - case NJS_TOKEN_SPACE:
  920. - case NJS_TOKEN_LINE_END:
  921. - continue;
  922. + if (offset + 1 > preread->items) {
  923. + n = offset + 1 - preread->items;
  924. + }
  925.  
  926. - default:
  927. - return token;
  928. + for (i = 0; i < n; i++) {
  929. +
  930. + ret = njs_lexer_preread_token(vm, lexer);
  931. +
  932. + if (ret == NXT_DECLINED) {
  933. + offset = preread->items;
  934. + break;
  935. + }
  936. +
  937. + if (nxt_slow_path(ret != NXT_OK)) {
  938. + return NJS_TOKEN_ERROR;
  939. }
  940. }
  941.  
  942. - return NJS_TOKEN_END;
  943. + lt = nxt_array_item(preread, offset);
  944. +
  945. + return lt->token;
  946. +}
  947. +
  948. +
  949. +ssize_t
  950. +njs_lexer_match(njs_vm_t *vm, njs_lexer_t *lexer, njs_token_t target)
  951. +{
  952. + size_t offset;
  953. + njs_token_t token;
  954. +
  955. + offset = 0;
  956. +
  957. + while (1) {
  958. + token = njs_lexer_peek_token(vm, lexer, offset);
  959. + if (token <= NJS_TOKEN_ILLEGAL) {
  960. + return -1;
  961. + }
  962. +
  963. + if (token == target) {
  964. + return offset;
  965. + }
  966. +
  967. + if (token == NJS_TOKEN_END || token == NJS_TOKEN_DIVISION) {
  968. + return -1;
  969. + }
  970. +
  971. + offset++;
  972. + }
  973. +
  974. + return offset;
  975. +}
  976. +
  977. +
  978. +static nxt_int_t
  979. +njs_lexer_preread_token(njs_vm_t *vm, njs_lexer_t *lexer)
  980. +{
  981. + nxt_array_t *preread;
  982. + njs_lexer_token_t *lt, *last;
  983. +
  984. + preread = lexer->preread;
  985. +
  986. + if (lexer->token == NJS_TOKEN_END) {
  987. + return NXT_DECLINED;
  988. + }
  989. +
  990. + if (lexer->pos < preread->items) {
  991. + last = nxt_array_last(preread);
  992. + if (last->token == NJS_TOKEN_DIVISION) {
  993. + return NXT_DECLINED;
  994. + }
  995. + }
  996. +
  997. + lt = nxt_array_add(preread, &njs_array_mem_proto, vm->mem_pool);
  998. + if (nxt_slow_path(lt == NULL)) {
  999. + return NXT_ERROR;
  1000. + }
  1001. +
  1002. + lt->token = njs_lexer_next_token(lexer);
  1003. + lt->token_line = lexer->line;
  1004. +
  1005. + return NXT_OK;
  1006. }
  1007.  
  1008.  
  1009. @@ -333,9 +451,12 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1010. u_char c, *p;
  1011. nxt_uint_t n;
  1012. njs_token_t token;
  1013. + njs_lexer_token_t *lt;
  1014. const njs_lexer_multi_t *multi;
  1015.  
  1016. - lexer->text.start = lexer->start;
  1017. + lt = njs_lexer_last_token(lexer);
  1018. +
  1019. + lt->text.start = lexer->start;
  1020.  
  1021. while (lexer->start < lexer->end) {
  1022. c = *lexer->start++;
  1023. @@ -345,7 +466,7 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1024. switch (token) {
  1025.  
  1026. case NJS_TOKEN_SPACE:
  1027. - lexer->text.start = lexer->start;
  1028. + lt->text.start = lexer->start;
  1029. continue;
  1030.  
  1031. case NJS_TOKEN_LETTER:
  1032. @@ -362,13 +483,13 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1033. && njs_tokens[p[0]] == NJS_TOKEN_DOT
  1034. && njs_tokens[p[1]] == NJS_TOKEN_DOT)
  1035. {
  1036. - lexer->text.length = (p - lexer->text.start) + 2;
  1037. + lt->text.length = (p - lt->text.start) + 2;
  1038. lexer->start += 2;
  1039. return NJS_TOKEN_ELLIPSIS;
  1040. }
  1041.  
  1042. if (p == lexer->end || njs_tokens[*p] != NJS_TOKEN_DIGIT) {
  1043. - lexer->text.length = p - lexer->text.start;
  1044. + lt->text.length = p - lt->text.start;
  1045. return NJS_TOKEN_DOT;
  1046. }
  1047.  
  1048. @@ -468,7 +589,7 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1049. case NJS_TOKEN_COLON:
  1050. case NJS_TOKEN_SEMICOLON:
  1051. case NJS_TOKEN_CONDITIONAL:
  1052. - lexer->text.length = lexer->start - lexer->text.start;
  1053. + lt->text.length = lexer->start - lt->text.start;
  1054. return token;
  1055.  
  1056. case NJS_TOKEN_ILLEGAL:
  1057. @@ -482,7 +603,7 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1058. return njs_lexer_multi(lexer, token, n, multi);
  1059. }
  1060.  
  1061. - lexer->text.length = lexer->start - lexer->text.start;
  1062. + lt->text.length = lexer->start - lt->text.start;
  1063.  
  1064. return NJS_TOKEN_END;
  1065. }
  1066. @@ -491,7 +612,10 @@ njs_lexer_next_token(njs_lexer_t *lexer)
  1067. static njs_token_t
  1068. njs_lexer_word(njs_lexer_t *lexer, u_char c)
  1069. {
  1070. - u_char *p;
  1071. + u_char *p;
  1072. + njs_lexer_token_t *lt;
  1073. +
  1074. + lt = njs_lexer_last_token(lexer);
  1075.  
  1076. /* TODO: UTF-8 */
  1077.  
  1078. @@ -513,8 +637,8 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha
  1079. 0x00, 0x00, 0x00, 0x00, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
  1080. };
  1081.  
  1082. - lexer->key_hash = nxt_djb_hash_add(NXT_DJB_HASH_INIT, c);
  1083. - lexer->text.start = lexer->start - 1;
  1084. + lt->key_hash = nxt_djb_hash_add(NXT_DJB_HASH_INIT, c);
  1085. + lt->text.start = lexer->start - 1;
  1086.  
  1087. for (p = lexer->start; p < lexer->end; p++) {
  1088. c = *p;
  1089. @@ -523,11 +647,11 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha
  1090. break;
  1091. }
  1092.  
  1093. - lexer->key_hash = nxt_djb_hash_add(lexer->key_hash, c);
  1094. + lt->key_hash = nxt_djb_hash_add(lt->key_hash, c);
  1095. }
  1096.  
  1097. lexer->start = p;
  1098. - lexer->text.length = p - lexer->text.start;
  1099. + lt->text.length = p - lt->text.start;
  1100.  
  1101. return NJS_TOKEN_NAME;
  1102. }
  1103. @@ -536,11 +660,14 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha
  1104. static njs_token_t
  1105. njs_lexer_string(njs_lexer_t *lexer, u_char quote)
  1106. {
  1107. - u_char *p, c;
  1108. - nxt_bool_t escape;
  1109. + u_char *p, c;
  1110. + nxt_bool_t escape;
  1111. + njs_lexer_token_t *lt;
  1112. +
  1113. + lt = njs_lexer_last_token(lexer);
  1114.  
  1115. escape = 0;
  1116. - lexer->text.start = lexer->start;
  1117. + lt->text.start = lexer->start;
  1118. p = lexer->start;
  1119.  
  1120. while (p < lexer->end) {
  1121. @@ -571,7 +698,7 @@ njs_lexer_string(njs_lexer_t *lexer, u_c
  1122.  
  1123. if (c == quote) {
  1124. lexer->start = p;
  1125. - lexer->text.length = (p - 1) - lexer->text.start;
  1126. + lt->text.length = (p - 1) - lt->text.start;
  1127.  
  1128. if (escape == 0) {
  1129. return NJS_TOKEN_STRING;
  1130. @@ -581,8 +708,8 @@ njs_lexer_string(njs_lexer_t *lexer, u_c
  1131. }
  1132. }
  1133.  
  1134. - lexer->text.start--;
  1135. - lexer->text.length = p - lexer->text.start;
  1136. + lt->text.start--;
  1137. + lt->text.length = p - lt->text.start;
  1138.  
  1139. return NJS_TOKEN_UNTERMINATED_STRING;
  1140. }
  1141. @@ -591,9 +718,12 @@ njs_lexer_string(njs_lexer_t *lexer, u_c
  1142. static njs_token_t
  1143. njs_lexer_number(njs_lexer_t *lexer, u_char c)
  1144. {
  1145. - const u_char *p;
  1146. + const u_char *p;
  1147. + njs_lexer_token_t *lt;
  1148.  
  1149. - lexer->text.start = lexer->start - 1;
  1150. + lt = njs_lexer_last_token(lexer);
  1151. +
  1152. + lt->text.start = lexer->start - 1;
  1153.  
  1154. p = lexer->start;
  1155.  
  1156. @@ -608,7 +738,7 @@ njs_lexer_number(njs_lexer_t *lexer, u_c
  1157. goto illegal_token;
  1158. }
  1159.  
  1160. - lexer->number = njs_number_hex_parse(&p, lexer->end);
  1161. + lt->number = njs_number_hex_parse(&p, lexer->end);
  1162.  
  1163. goto done;
  1164. }
  1165. @@ -622,7 +752,7 @@ njs_lexer_number(njs_lexer_t *lexer, u_c
  1166. goto illegal_token;
  1167. }
  1168.  
  1169. - lexer->number = njs_number_oct_parse(&p, lexer->end);
  1170. + lt->number = njs_number_oct_parse(&p, lexer->end);
  1171.  
  1172. if (p < lexer->end && (*p == '8' || *p == '9')) {
  1173. goto illegal_trailer;
  1174. @@ -640,7 +770,7 @@ njs_lexer_number(njs_lexer_t *lexer, u_c
  1175. goto illegal_token;
  1176. }
  1177.  
  1178. - lexer->number = njs_number_bin_parse(&p, lexer->end);
  1179. + lt->number = njs_number_bin_parse(&p, lexer->end);
  1180.  
  1181. if (p < lexer->end && (*p >= '2' && *p <= '9')) {
  1182. goto illegal_trailer;
  1183. @@ -657,12 +787,12 @@ njs_lexer_number(njs_lexer_t *lexer, u_c
  1184. }
  1185.  
  1186. p--;
  1187. - lexer->number = njs_number_dec_parse(&p, lexer->end);
  1188. + lt->number = njs_number_dec_parse(&p, lexer->end);
  1189.  
  1190. done:
  1191.  
  1192. lexer->start = (u_char *) p;
  1193. - lexer->text.length = p - lexer->text.start;
  1194. + lt->text.length = p - lt->text.start;
  1195.  
  1196. return NJS_TOKEN_NUMBER;
  1197.  
  1198. @@ -672,7 +802,7 @@ illegal_trailer:
  1199.  
  1200. illegal_token:
  1201.  
  1202. - lexer->text.length = p - lexer->text.start;
  1203. + lt->text.length = p - lt->text.start;
  1204.  
  1205. return NJS_TOKEN_ILLEGAL;
  1206. }
  1207. @@ -682,7 +812,10 @@ static njs_token_t
  1208. njs_lexer_multi(njs_lexer_t *lexer, njs_token_t token, nxt_uint_t n,
  1209. const njs_lexer_multi_t *multi)
  1210. {
  1211. - u_char c;
  1212. + u_char c;
  1213. + njs_lexer_token_t *lt;
  1214. +
  1215. + lt = njs_lexer_last_token(lexer);
  1216.  
  1217. if (lexer->start < lexer->end) {
  1218. c = lexer->start[0];
  1219. @@ -706,7 +839,7 @@ njs_lexer_multi(njs_lexer_t *lexer, njs_
  1220. } while (n != 0);
  1221. }
  1222.  
  1223. - lexer->text.length = lexer->start - lexer->text.start;
  1224. + lt->text.length = lexer->start - lt->text.start;
  1225.  
  1226. return token;
  1227. }
  1228. diff -r 52960032fe56 -r 049c1a5fa4fa njs/njs_parser.c
  1229. --- a/njs/njs_parser.c Mon Mar 04 16:34:42 2019 +0800
  1230. +++ b/njs/njs_parser.c Wed Mar 06 01:25:25 2019 +0800
  1231. @@ -353,7 +353,7 @@ njs_parser_statement(njs_vm_t *vm, njs_p
  1232. default:
  1233.  
  1234. if (token == NJS_TOKEN_NAME
  1235. - && njs_lexer_peek_token(parser->lexer) == NJS_TOKEN_COLON)
  1236. + && njs_lexer_peek_token(vm, parser->lexer, 0) == NJS_TOKEN_COLON)
  1237. {
  1238. return njs_parser_labelled_statement(vm, parser);
  1239. }
  1240. @@ -1870,10 +1870,204 @@ njs_parser_token(njs_vm_t *vm, njs_parse
  1241. }
  1242.  
  1243.  
  1244. +static njs_token_t
  1245. +njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1246. +{
  1247. + njs_ret_t ret;
  1248. + njs_index_t index;
  1249. + njs_variable_t *arg;
  1250. + njs_parser_node_t *node, *body, *last, *parent, *return_node;
  1251. + njs_function_lambda_t *lambda;
  1252. +
  1253. + node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION);
  1254. + if (nxt_slow_path(node == NULL)) {
  1255. + return NJS_TOKEN_ERROR;
  1256. + }
  1257. +
  1258. + node->token_line = parser->lexer->token_line;
  1259. + parser->node = node;
  1260. +
  1261. + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
  1262. + if (nxt_slow_path(lambda == NULL)) {
  1263. + return NJS_TOKEN_ERROR;
  1264. + }
  1265. +
  1266. + node->u.value.data.u.lambda = lambda;
  1267. +
  1268. + ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
  1269. + if (nxt_slow_path(ret != NXT_OK)) {
  1270. + return NJS_TOKEN_ERROR;
  1271. + }
  1272. +
  1273. + index = NJS_SCOPE_ARGUMENTS;
  1274. +
  1275. + /* A "this" reservation. */
  1276. + index += sizeof(njs_value_t);
  1277. +
  1278. + if (token == NJS_TOKEN_NAME) {
  1279. + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
  1280. + if (nxt_slow_path(arg == NULL)) {
  1281. + return NJS_TOKEN_ERROR;
  1282. + }
  1283. +
  1284. + arg->index = index;
  1285. + index += sizeof(njs_value_t);
  1286. +
  1287. + ret = njs_name_copy(vm, &arg->name, &parser->lexer->text);
  1288. + if (nxt_slow_path(ret != NXT_OK)) {
  1289. + return NJS_TOKEN_ERROR;
  1290. + }
  1291. +
  1292. + goto arrow;
  1293. + }
  1294. +
  1295. + token = njs_parser_token(vm, parser);
  1296. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1297. + return token;
  1298. + }
  1299. +
  1300. + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
  1301. +
  1302. + if (nxt_slow_path(lambda->rest_parameters)) {
  1303. + return NJS_TOKEN_ILLEGAL;
  1304. + }
  1305. +
  1306. + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  1307. + lambda->rest_parameters = 1;
  1308. +
  1309. + token = njs_parser_token(vm, parser);
  1310. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1311. + return NJS_TOKEN_ILLEGAL;
  1312. + }
  1313. + }
  1314. +
  1315. + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
  1316. + return NJS_TOKEN_ILLEGAL;
  1317. + }
  1318. +
  1319. + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
  1320. + if (nxt_slow_path(arg == NULL)) {
  1321. + return NJS_TOKEN_ERROR;
  1322. + }
  1323. +
  1324. + arg->index = index;
  1325. + index += sizeof(njs_value_t);
  1326. +
  1327. + ret = njs_name_copy(vm, &arg->name, &parser->lexer->text);
  1328. + if (nxt_slow_path(ret != NXT_OK)) {
  1329. + return NJS_TOKEN_ERROR;
  1330. + }
  1331. +
  1332. + token = njs_parser_token(vm, parser);
  1333. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1334. + return token;
  1335. + }
  1336. +
  1337. + if (token == NJS_TOKEN_COMMA) {
  1338. + token = njs_parser_token(vm, parser);
  1339. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1340. + return token;
  1341. + }
  1342. + }
  1343. + }
  1344. +
  1345. +arrow:
  1346. +
  1347. + lambda->nargs = njs_scope_offset(index) / sizeof(njs_value_t) - 1;
  1348. +
  1349. + token = njs_parser_token(vm, parser);
  1350. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1351. + return token;
  1352. + }
  1353. +
  1354. + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
  1355. + return NJS_TOKEN_ILLEGAL;
  1356. + }
  1357. +
  1358. + token = njs_parser_token(vm, parser);
  1359. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1360. + return token;
  1361. + }
  1362. +
  1363. + if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
  1364. + return NJS_TOKEN_ILLEGAL;
  1365. + }
  1366. +
  1367. + token = njs_parser_token(vm, parser);
  1368. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1369. + return token;
  1370. + }
  1371. +
  1372. + parent = parser->node;
  1373. + parser->node = NULL;
  1374. +
  1375. + while (token != NJS_TOKEN_CLOSE_BRACE) {
  1376. + token = njs_parser_statement_chain(vm, parser, token,
  1377. + &njs_parser_chain_top(parser));
  1378. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1379. + return token;
  1380. + }
  1381. + }
  1382. +
  1383. + token = njs_parser_token(vm, parser);
  1384. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1385. + return token;
  1386. + }
  1387. +
  1388. + last = NULL;
  1389. + body = njs_parser_chain_top(parser);
  1390. +
  1391. + if (body != NULL) {
  1392. + /* Take the last function body statement. */
  1393. + last = body->right;
  1394. +
  1395. + if (last == NULL) {
  1396. + /*
  1397. + * The last statement is terminated by semicolon.
  1398. + * Take the last statement itself.
  1399. + */
  1400. + last = body->left;
  1401. + }
  1402. + }
  1403. +
  1404. + if (last == NULL || last->token != NJS_TOKEN_RETURN) {
  1405. + /*
  1406. + * There is no function body or the last function body
  1407. + * body statement is not "return" statement.
  1408. + */
  1409. + return_node = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN);
  1410. + if (nxt_slow_path(return_node == NULL)) {
  1411. + return NJS_TOKEN_ERROR;
  1412. + }
  1413. +
  1414. + node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
  1415. + if (nxt_slow_path(node == NULL)) {
  1416. + return NJS_TOKEN_ERROR;
  1417. + }
  1418. +
  1419. + node->left = body;
  1420. + node->right = return_node;
  1421. +
  1422. + njs_parser_chain_top_set(parser, node);
  1423. +
  1424. + body = node;
  1425. + }
  1426. +
  1427. + parent->right = body;
  1428. +
  1429. + parser->node = parent;
  1430. +
  1431. + njs_parser_scope_end(vm, parser);
  1432. +
  1433. + return token;
  1434. +}
  1435. +
  1436. +
  1437. njs_token_t
  1438. njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1439. {
  1440. double num;
  1441. + ssize_t pos;
  1442. njs_ret_t ret;
  1443. njs_lexer_t *lexer;
  1444. njs_parser_node_t *node;
  1445. @@ -1881,6 +2075,32 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
  1446. lexer = parser->lexer;
  1447.  
  1448. if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1449. + pos = njs_lexer_match(vm, lexer, NJS_TOKEN_CLOSE_PARENTHESIS);
  1450. + if (pos >= 0 && njs_lexer_peek_token(vm, lexer, pos + 1) == NJS_TOKEN_ARROW) {
  1451. + return njs_parser_arrow_expression(vm, parser, token);
  1452. + }
  1453. + }
  1454. +
  1455. + if (token == NJS_TOKEN_NAME) {
  1456. + if (njs_lexer_peek_token(vm, lexer, 0) == NJS_TOKEN_ARROW) {
  1457. + return njs_parser_arrow_expression(vm, parser, token);
  1458. + }
  1459. + }
  1460. +
  1461. + if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1462. +
  1463. + if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1464. + pos = njs_lexer_match(vm, lexer, NJS_TOKEN_CLOSE_PARENTHESIS);
  1465. + if (pos >= 0 && njs_lexer_peek_token(vm, lexer, pos + 1) == NJS_TOKEN_ARROW) {
  1466. + return njs_parser_arrow_expression(vm, parser, token);
  1467. + }
  1468. + }
  1469. +
  1470. + if (token == NJS_TOKEN_NAME) {
  1471. + if (njs_lexer_peek_token(vm, lexer, 0) == NJS_TOKEN_ARROW) {
  1472. + return njs_parser_arrow_expression(vm, parser, token);
  1473. + }
  1474. + }
  1475.  
  1476. token = njs_parser_token(vm, parser);
  1477. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1478. diff -r 52960032fe56 -r 049c1a5fa4fa njs/njs_parser.h
  1479. --- a/njs/njs_parser.h Mon Mar 04 16:34:42 2019 +0800
  1480. +++ b/njs/njs_parser.h Wed Mar 06 01:25:25 2019 +0800
  1481. @@ -36,6 +36,7 @@ typedef enum {
  1482. NJS_TOKEN_CONDITIONAL,
  1483.  
  1484. NJS_TOKEN_ASSIGNMENT,
  1485. + NJS_TOKEN_ARROW,
  1486. NJS_TOKEN_ADDITION_ASSIGNMENT,
  1487. NJS_TOKEN_SUBSTRACTION_ASSIGNMENT,
  1488. NJS_TOKEN_MULTIPLICATION_ASSIGNMENT,
  1489. @@ -209,26 +210,33 @@ typedef enum {
  1490.  
  1491. typedef struct {
  1492. njs_token_t token:16;
  1493. - njs_token_t prev_token:16;
  1494. + uint32_t token_line;
  1495. + uint32_t key_hash;
  1496. + nxt_str_t text;
  1497. + double number;
  1498. +} njs_lexer_token_t;
  1499. +
  1500. +
  1501. +typedef struct {
  1502. + size_t pos;
  1503. + nxt_array_t *preread;
  1504. +
  1505. + njs_token_t token:16;
  1506. + uint32_t token_line;
  1507. + uint32_t key_hash;
  1508. + nxt_str_t text;
  1509. + double number;
  1510.  
  1511. uint8_t property; /* 1 bit */
  1512. njs_token_t property_token:16;
  1513.  
  1514. - uint32_t key_hash;
  1515. -
  1516. - uint32_t token_line;
  1517. + u_char *start;
  1518. + u_char *end;
  1519. uint32_t line;
  1520. -
  1521. - nxt_str_t text;
  1522. - double number;
  1523. -
  1524. + nxt_str_t file;
  1525. nxt_lvlhsh_t keywords_hash;
  1526. -
  1527. - nxt_str_t file;
  1528. -
  1529. - u_char *start;
  1530. u_char *prev_start;
  1531. - u_char *end;
  1532. + njs_token_t prev_token:16;
  1533. } njs_lexer_t;
  1534.  
  1535.  
  1536. @@ -307,12 +315,17 @@ typedef struct {
  1537. } njs_keyword_t;
  1538.  
  1539.  
  1540. +nxt_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, nxt_str_t *file,
  1541. + u_char *start, u_char *end);
  1542. njs_token_t njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer);
  1543. -void njs_lexer_rollback(njs_lexer_t *lexer);
  1544. -njs_token_t njs_lexer_peek_token(njs_lexer_t *lexer);
  1545. +njs_token_t njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset);
  1546. +ssize_t njs_lexer_match(njs_vm_t *vm, njs_lexer_t *lexer, njs_token_t token);
  1547. nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
  1548. void njs_lexer_keyword(njs_lexer_t *lexer);
  1549.  
  1550. +#define njs_lexer_rollback(lexer) \
  1551. + (lexer)->start = (lexer)->prev_start
  1552. +
  1553. nxt_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser,
  1554. njs_parser_t *prev);
  1555. njs_token_t njs_parser_arguments(njs_vm_t *vm, njs_parser_t *parser,
  1556. diff -r 52960032fe56 -r 049c1a5fa4fa njs/test/njs_unit_test.c
  1557. --- a/njs/test/njs_unit_test.c Mon Mar 04 16:34:42 2019 +0800
  1558. +++ b/njs/test/njs_unit_test.c Wed Mar 06 01:25:25 2019 +0800
  1559. @@ -99,6 +99,21 @@ static njs_unit_test_t njs_test[] =
  1560. { nxt_string("var f = 1; function f() {}; f"),
  1561. nxt_string("1") },
  1562.  
  1563. + { nxt_string("var f = f => {return 1;}; f()"),
  1564. + nxt_string("1") },
  1565. +
  1566. + { nxt_string("var f = (f) => {return 1;}; f()"),
  1567. + nxt_string("1") },
  1568. +
  1569. + { nxt_string("var f = (f, a, b) => {return 1;}; f()"),
  1570. + nxt_string("1") },
  1571. +
  1572. + { nxt_string("var f = () => {return 1;}; f()"),
  1573. + nxt_string("1") },
  1574. +
  1575. + { nxt_string("(f => {return 1;})()"),
  1576. + nxt_string("1") },
  1577. +
  1578. #if 0 /* TODO */
  1579. { nxt_string("var a; Object.getOwnPropertyDescriptor(this, 'a').value"),
  1580. nxt_string("undefined") },
  1581. # HG changeset patch
  1582. # User hongzhidao <hongzhidao@gmail.com>
  1583. # Date 1551885105 -28800
  1584. # Node ID 1f13e316a93cd44ffbe55ac319d77d0dca32ea37
  1585. # Parent 049c1a5fa4fa9771031253616a6ced9163b52ccb
  1586. arrow function 2.
  1587.  
  1588. diff -r 049c1a5fa4fa -r 1f13e316a93c njs/njs_parser.c
  1589. --- a/njs/njs_parser.c Wed Mar 06 01:25:25 2019 +0800
  1590. +++ b/njs/njs_parser.c Wed Mar 06 23:11:45 2019 +0800
  1591. @@ -1870,6 +1870,72 @@ njs_parser_token(njs_vm_t *vm, njs_parse
  1592. }
  1593.  
  1594.  
  1595. +static nxt_int_t
  1596. +njs_parser_try_arrow_function(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1597. +{
  1598. + size_t offset;
  1599. + nxt_bool_t rest_parameters;
  1600. +
  1601. + offset = 0;
  1602. +
  1603. + if (token == NJS_TOKEN_NAME) {
  1604. + goto arrow;
  1605. + }
  1606. +
  1607. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1608. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1609. + return NXT_DECLINED;
  1610. + }
  1611. +
  1612. + rest_parameters = 0;
  1613. +
  1614. + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
  1615. +
  1616. + if (rest_parameters) {
  1617. + return NXT_DECLINED;
  1618. + }
  1619. +
  1620. + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  1621. + rest_parameters = 1;
  1622. +
  1623. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1624. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1625. + return NXT_DECLINED;
  1626. + }
  1627. + }
  1628. +
  1629. + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
  1630. + return NXT_DECLINED;
  1631. + }
  1632. +
  1633. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1634. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1635. + return token;
  1636. + }
  1637. +
  1638. + if (token == NJS_TOKEN_COMMA) {
  1639. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1640. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1641. + return NXT_DECLINED;
  1642. + }
  1643. + }
  1644. + }
  1645. +
  1646. +arrow:
  1647. +
  1648. + token = njs_lexer_peek_token(vm, parser->lexer, offset);
  1649. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1650. + return NXT_DECLINED;
  1651. + }
  1652. +
  1653. + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
  1654. + return NXT_DECLINED;
  1655. + }
  1656. +
  1657. + return NXT_OK;
  1658. +}
  1659. +
  1660. +
  1661. static njs_token_t
  1662. njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1663. {
  1664. @@ -2067,41 +2133,19 @@ njs_token_t
  1665. njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1666. {
  1667. double num;
  1668. - ssize_t pos;
  1669. njs_ret_t ret;
  1670. njs_lexer_t *lexer;
  1671. njs_parser_node_t *node;
  1672.  
  1673. lexer = parser->lexer;
  1674.  
  1675. - if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1676. - pos = njs_lexer_match(vm, lexer, NJS_TOKEN_CLOSE_PARENTHESIS);
  1677. - if (pos >= 0 && njs_lexer_peek_token(vm, lexer, pos + 1) == NJS_TOKEN_ARROW) {
  1678. + if (token == NJS_TOKEN_OPEN_PARENTHESIS || token == NJS_TOKEN_NAME) {
  1679. + if (njs_parser_try_arrow_function(vm, parser, token) == NXT_OK) {
  1680. return njs_parser_arrow_expression(vm, parser, token);
  1681. }
  1682. }
  1683.  
  1684. - if (token == NJS_TOKEN_NAME) {
  1685. - if (njs_lexer_peek_token(vm, lexer, 0) == NJS_TOKEN_ARROW) {
  1686. - return njs_parser_arrow_expression(vm, parser, token);
  1687. - }
  1688. - }
  1689. -
  1690. if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1691. -
  1692. - if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  1693. - pos = njs_lexer_match(vm, lexer, NJS_TOKEN_CLOSE_PARENTHESIS);
  1694. - if (pos >= 0 && njs_lexer_peek_token(vm, lexer, pos + 1) == NJS_TOKEN_ARROW) {
  1695. - return njs_parser_arrow_expression(vm, parser, token);
  1696. - }
  1697. - }
  1698. -
  1699. - if (token == NJS_TOKEN_NAME) {
  1700. - if (njs_lexer_peek_token(vm, lexer, 0) == NJS_TOKEN_ARROW) {
  1701. - return njs_parser_arrow_expression(vm, parser, token);
  1702. - }
  1703. - }
  1704. -
  1705. token = njs_parser_token(vm, parser);
  1706. if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1707. return token;
  1708. diff -r 049c1a5fa4fa -r 1f13e316a93c njs/test/njs_unit_test.c
  1709. --- a/njs/test/njs_unit_test.c Wed Mar 06 01:25:25 2019 +0800
  1710. +++ b/njs/test/njs_unit_test.c Wed Mar 06 23:11:45 2019 +0800
  1711. @@ -114,6 +114,16 @@ static njs_unit_test_t njs_test[] =
  1712. { nxt_string("(f => {return 1;})()"),
  1713. nxt_string("1") },
  1714.  
  1715. + { nxt_string("((f) => {return 1;})()"),
  1716. + nxt_string("1") },
  1717. +
  1718. + { nxt_string("(((f) => {return 1;}))()"),
  1719. + nxt_string("1") },
  1720. +
  1721. + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium' ]; "
  1722. + "materials.map(material => { return material.length; });"),
  1723. + nxt_string("8,6,7,9") },
  1724. +
  1725. #if 0 /* TODO */
  1726. { nxt_string("var a; Object.getOwnPropertyDescriptor(this, 'a').value"),
  1727. nxt_string("undefined") },
  1728. # HG changeset patch
  1729. # User hongzhidao <hongzhidao@gmail.com>
  1730. # Date 1551939317 -28800
  1731. # Node ID 81dce12c56612fcc8810aee81dae3a40886dde4e
  1732. # Parent 5829884f0e956c7f85c7377305815f34fe59f8be
  1733. LL(k): improved njs_lexer_peek_token().
  1734.  
  1735. diff -r 5829884f0e95 -r 81dce12c5661 njs/njs_lexer.c
  1736. --- a/njs/njs_lexer.c Thu Mar 07 14:04:37 2019 +0800
  1737. +++ b/njs/njs_lexer.c Thu Mar 07 14:15:17 2019 +0800
  1738. @@ -341,27 +341,43 @@ njs_lexer_token(njs_vm_t *vm, njs_lexer_
  1739.  
  1740.  
  1741. njs_token_t
  1742. -njs_lexer_peek_token(njs_lexer_t *lexer)
  1743. +njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset)
  1744. {
  1745. - u_char *start;
  1746. - njs_token_t token;
  1747. + size_t i, n;
  1748. + nxt_int_t ret;
  1749. + nxt_array_t *preread;
  1750. + njs_lexer_token_t *lt;
  1751.  
  1752. - start = lexer->start;
  1753. + lexer->prev_start = lexer->start;
  1754. + lexer->prev_token = lexer->token;
  1755. +
  1756. + preread = lexer->preread;
  1757. +
  1758. + n = 0;
  1759. +
  1760. + offset = lexer->pos + offset;
  1761. +
  1762. + if (offset + 1 > preread->items) {
  1763. + n = offset + 1 - preread->items;
  1764. + }
  1765. +
  1766. + for (i = 0; i < n; i++) {
  1767.  
  1768. - while (start < lexer->end) {
  1769. - token = njs_tokens[*start++];
  1770. + ret = njs_lexer_preread_token(vm, lexer);
  1771.  
  1772. - switch (token) {
  1773. - case NJS_TOKEN_SPACE:
  1774. - case NJS_TOKEN_LINE_END:
  1775. - continue;
  1776. + if (ret == NXT_DECLINED) {
  1777. + offset = preread->items;
  1778. + break;
  1779. + }
  1780.  
  1781. - default:
  1782. - return token;
  1783. + if (nxt_slow_path(ret != NXT_OK)) {
  1784. + return NJS_TOKEN_ERROR;
  1785. }
  1786. }
  1787.  
  1788. - return NJS_TOKEN_END;
  1789. + lt = nxt_array_item(preread, offset);
  1790. +
  1791. + return lt->token;
  1792. }
  1793.  
  1794.  
  1795. diff -r 5829884f0e95 -r 81dce12c5661 njs/njs_parser.c
  1796. --- a/njs/njs_parser.c Thu Mar 07 14:04:37 2019 +0800
  1797. +++ b/njs/njs_parser.c Thu Mar 07 14:15:17 2019 +0800
  1798. @@ -365,7 +365,7 @@ njs_parser_statement(njs_vm_t *vm, njs_p
  1799. default:
  1800.  
  1801. if (token == NJS_TOKEN_NAME
  1802. - && njs_lexer_peek_token(parser->lexer) == NJS_TOKEN_COLON)
  1803. + && njs_lexer_peek_token(vm, parser->lexer, 0) == NJS_TOKEN_COLON)
  1804. {
  1805. return njs_parser_labelled_statement(vm, parser);
  1806. }
  1807. diff -r 5829884f0e95 -r 81dce12c5661 njs/njs_parser.h
  1808. --- a/njs/njs_parser.h Thu Mar 07 14:04:37 2019 +0800
  1809. +++ b/njs/njs_parser.h Thu Mar 07 14:15:17 2019 +0800
  1810. @@ -316,7 +316,7 @@ nxt_int_t njs_lexer_init(njs_vm_t *vm, n
  1811. u_char *start, u_char *end);
  1812. njs_token_t njs_lexer_token(njs_vm_t *vm, njs_lexer_t *lexer);
  1813. void njs_lexer_rollback(njs_lexer_t *lexer);
  1814. -njs_token_t njs_lexer_peek_token(njs_lexer_t *lexer);
  1815. +njs_token_t njs_lexer_peek_token(njs_vm_t *vm, njs_lexer_t *lexer, size_t offset);
  1816. nxt_int_t njs_lexer_keywords_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash);
  1817. void njs_lexer_keyword(njs_lexer_t *lexer, njs_lexer_token_t *lt);
  1818. # HG changeset patch
  1819. # User hongzhidao <hongzhidao@gmail.com>
  1820. # Date 1551941209 -28800
  1821. # Node ID fd5fbf7c1a563212631d4fc1321b5843a40f8614
  1822. # Parent 8094a62c38a4e060f26f6636f6a1e75abeacba14
  1823. LL(k): introduced arrow function.
  1824.  
  1825. diff -r 8094a62c38a4 -r fd5fbf7c1a56 njs/njs_lexer.c
  1826. --- a/njs/njs_lexer.c Thu Mar 07 14:23:45 2019 +0800
  1827. +++ b/njs/njs_lexer.c Thu Mar 07 14:46:49 2019 +0800
  1828. @@ -270,6 +270,7 @@ static const njs_lexer_multi_t njs_grea
  1829.  
  1830. static const njs_lexer_multi_t njs_assignment_token[] = {
  1831. { '=', NJS_TOKEN_EQUAL, 1, njs_strict_equal_token },
  1832. + { '>', NJS_TOKEN_ARROW, 0, NULL },
  1833. };
  1834.  
  1835.  
  1836. diff -r 8094a62c38a4 -r fd5fbf7c1a56 njs/njs_parser.c
  1837. --- a/njs/njs_parser.c Thu Mar 07 14:23:45 2019 +0800
  1838. +++ b/njs/njs_parser.c Thu Mar 07 14:46:49 2019 +0800
  1839. @@ -1886,6 +1886,265 @@ njs_parser_token(njs_vm_t *vm, njs_parse
  1840. }
  1841.  
  1842.  
  1843. +static nxt_int_t
  1844. +njs_parser_try_arrow_function(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1845. +{
  1846. + size_t offset;
  1847. + nxt_bool_t rest_parameters;
  1848. +
  1849. + offset = 0;
  1850. +
  1851. + if (token == NJS_TOKEN_NAME) {
  1852. + goto arrow;
  1853. + }
  1854. +
  1855. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1856. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1857. + return NXT_DECLINED;
  1858. + }
  1859. +
  1860. + rest_parameters = 0;
  1861. +
  1862. + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
  1863. +
  1864. + if (rest_parameters) {
  1865. + return NXT_DECLINED;
  1866. + }
  1867. +
  1868. + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  1869. + rest_parameters = 1;
  1870. +
  1871. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1872. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1873. + return NXT_DECLINED;
  1874. + }
  1875. + }
  1876. +
  1877. + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
  1878. + return NXT_DECLINED;
  1879. + }
  1880. +
  1881. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1882. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1883. + return token;
  1884. + }
  1885. +
  1886. + if (token == NJS_TOKEN_COMMA) {
  1887. + token = njs_lexer_peek_token(vm, parser->lexer, offset++);
  1888. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1889. + return NXT_DECLINED;
  1890. + }
  1891. + }
  1892. + }
  1893. +
  1894. +arrow:
  1895. +
  1896. + token = njs_lexer_peek_token(vm, parser->lexer, offset);
  1897. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1898. + return NXT_DECLINED;
  1899. + }
  1900. +
  1901. + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
  1902. + return NXT_DECLINED;
  1903. + }
  1904. +
  1905. + return NXT_OK;
  1906. +}
  1907. +
  1908. +
  1909. +static njs_token_t
  1910. +njs_parser_arrow_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  1911. +{
  1912. + njs_ret_t ret;
  1913. + njs_index_t index;
  1914. + njs_variable_t *arg;
  1915. + njs_parser_node_t *node, *body, *last, *parent, *return_node;
  1916. + njs_function_lambda_t *lambda;
  1917. +
  1918. + node = njs_parser_node_new(vm, parser, NJS_TOKEN_FUNCTION_EXPRESSION);
  1919. + if (nxt_slow_path(node == NULL)) {
  1920. + return NJS_TOKEN_ERROR;
  1921. + }
  1922. +
  1923. + node->token_line = njs_parser_token_line(parser);
  1924. + parser->node = node;
  1925. +
  1926. + lambda = nxt_mp_zalloc(vm->mem_pool, sizeof(njs_function_lambda_t));
  1927. + if (nxt_slow_path(lambda == NULL)) {
  1928. + return NJS_TOKEN_ERROR;
  1929. + }
  1930. +
  1931. + node->u.value.data.u.lambda = lambda;
  1932. +
  1933. + ret = njs_parser_scope_begin(vm, parser, NJS_SCOPE_FUNCTION);
  1934. + if (nxt_slow_path(ret != NXT_OK)) {
  1935. + return NJS_TOKEN_ERROR;
  1936. + }
  1937. +
  1938. + index = NJS_SCOPE_ARGUMENTS;
  1939. +
  1940. + /* A "this" reservation. */
  1941. + index += sizeof(njs_value_t);
  1942. +
  1943. + if (token == NJS_TOKEN_NAME) {
  1944. + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
  1945. + if (nxt_slow_path(arg == NULL)) {
  1946. + return NJS_TOKEN_ERROR;
  1947. + }
  1948. +
  1949. + arg->index = index;
  1950. + index += sizeof(njs_value_t);
  1951. +
  1952. + ret = njs_name_copy(vm, &arg->name, njs_parser_text(parser));
  1953. + if (nxt_slow_path(ret != NXT_OK)) {
  1954. + return NJS_TOKEN_ERROR;
  1955. + }
  1956. +
  1957. + goto arrow;
  1958. + }
  1959. +
  1960. + token = njs_parser_token(vm, parser);
  1961. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1962. + return token;
  1963. + }
  1964. +
  1965. + while (token != NJS_TOKEN_CLOSE_PARENTHESIS) {
  1966. +
  1967. + if (nxt_slow_path(lambda->rest_parameters)) {
  1968. + return NJS_TOKEN_ILLEGAL;
  1969. + }
  1970. +
  1971. + if (nxt_slow_path(token == NJS_TOKEN_ELLIPSIS)) {
  1972. + lambda->rest_parameters = 1;
  1973. +
  1974. + token = njs_parser_token(vm, parser);
  1975. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1976. + return NJS_TOKEN_ILLEGAL;
  1977. + }
  1978. + }
  1979. +
  1980. + if (nxt_slow_path(token != NJS_TOKEN_NAME)) {
  1981. + return NJS_TOKEN_ILLEGAL;
  1982. + }
  1983. +
  1984. + arg = njs_parser_variable_add(vm, parser, NJS_VARIABLE_VAR);
  1985. + if (nxt_slow_path(arg == NULL)) {
  1986. + return NJS_TOKEN_ERROR;
  1987. + }
  1988. +
  1989. + arg->index = index;
  1990. + index += sizeof(njs_value_t);
  1991. +
  1992. + ret = njs_name_copy(vm, &arg->name, njs_parser_text(parser));
  1993. + if (nxt_slow_path(ret != NXT_OK)) {
  1994. + return NJS_TOKEN_ERROR;
  1995. + }
  1996. +
  1997. + token = njs_parser_token(vm, parser);
  1998. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  1999. + return token;
  2000. + }
  2001. +
  2002. + if (token == NJS_TOKEN_COMMA) {
  2003. + token = njs_parser_token(vm, parser);
  2004. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2005. + return token;
  2006. + }
  2007. + }
  2008. + }
  2009. +
  2010. +arrow:
  2011. +
  2012. + lambda->nargs = njs_scope_offset(index) / sizeof(njs_value_t) - 1;
  2013. +
  2014. + token = njs_parser_token(vm, parser);
  2015. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2016. + return token;
  2017. + }
  2018. +
  2019. + if (nxt_slow_path(token != NJS_TOKEN_ARROW)) {
  2020. + return NJS_TOKEN_ILLEGAL;
  2021. + }
  2022. +
  2023. + token = njs_parser_token(vm, parser);
  2024. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2025. + return token;
  2026. + }
  2027. +
  2028. + if (nxt_slow_path(token != NJS_TOKEN_OPEN_BRACE)) {
  2029. + return NJS_TOKEN_ILLEGAL;
  2030. + }
  2031. +
  2032. + token = njs_parser_token(vm, parser);
  2033. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2034. + return token;
  2035. + }
  2036. +
  2037. + parent = parser->node;
  2038. + parser->node = NULL;
  2039. +
  2040. + while (token != NJS_TOKEN_CLOSE_BRACE) {
  2041. + token = njs_parser_statement_chain(vm, parser, token,
  2042. + &njs_parser_chain_top(parser));
  2043. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2044. + return token;
  2045. + }
  2046. + }
  2047. +
  2048. + token = njs_parser_token(vm, parser);
  2049. + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) {
  2050. + return token;
  2051. + }
  2052. +
  2053. + last = NULL;
  2054. + body = njs_parser_chain_top(parser);
  2055. +
  2056. + if (body != NULL) {
  2057. + /* Take the last function body statement. */
  2058. + last = body->right;
  2059. +
  2060. + if (last == NULL) {
  2061. + /*
  2062. + * The last statement is terminated by semicolon.
  2063. + * Take the last statement itself.
  2064. + */
  2065. + last = body->left;
  2066. + }
  2067. + }
  2068. +
  2069. + if (last == NULL || last->token != NJS_TOKEN_RETURN) {
  2070. + /*
  2071. + * There is no function body or the last function body
  2072. + * body statement is not "return" statement.
  2073. + */
  2074. + return_node = njs_parser_node_new(vm, parser, NJS_TOKEN_RETURN);
  2075. + if (nxt_slow_path(return_node == NULL)) {
  2076. + return NJS_TOKEN_ERROR;
  2077. + }
  2078. +
  2079. + node = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT);
  2080. + if (nxt_slow_path(node == NULL)) {
  2081. + return NJS_TOKEN_ERROR;
  2082. + }
  2083. +
  2084. + node->left = body;
  2085. + node->right = return_node;
  2086. +
  2087. + njs_parser_chain_top_set(parser, node);
  2088. +
  2089. + body = node;
  2090. + }
  2091. +
  2092. + parent->right = body;
  2093. +
  2094. + parser->node = parent;
  2095. +
  2096. + njs_parser_scope_end(vm, parser);
  2097. +
  2098. + return token;
  2099. +}
  2100. +
  2101. +
  2102. njs_token_t
  2103. njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token)
  2104. {
  2105. @@ -1896,6 +2155,12 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa
  2106.  
  2107. lexer = parser->lexer;
  2108.  
  2109. + if (token == NJS_TOKEN_OPEN_PARENTHESIS || token == NJS_TOKEN_NAME) {
  2110. + if (njs_parser_try_arrow_function(vm, parser, token) == NXT_OK) {
  2111. + return njs_parser_arrow_expression(vm, parser, token);
  2112. + }
  2113. + }
  2114. +
  2115. if (token == NJS_TOKEN_OPEN_PARENTHESIS) {
  2116.  
  2117. token = njs_parser_token(vm, parser);
  2118. diff -r 8094a62c38a4 -r fd5fbf7c1a56 njs/njs_parser.h
  2119. --- a/njs/njs_parser.h Thu Mar 07 14:23:45 2019 +0800
  2120. +++ b/njs/njs_parser.h Thu Mar 07 14:46:49 2019 +0800
  2121. @@ -36,6 +36,7 @@ typedef enum {
  2122. NJS_TOKEN_CONDITIONAL,
  2123.  
  2124. NJS_TOKEN_ASSIGNMENT,
  2125. + NJS_TOKEN_ARROW,
  2126. NJS_TOKEN_ADDITION_ASSIGNMENT,
  2127. NJS_TOKEN_SUBSTRACTION_ASSIGNMENT,
  2128. NJS_TOKEN_MULTIPLICATION_ASSIGNMENT,
  2129. diff -r 8094a62c38a4 -r fd5fbf7c1a56 njs/test/njs_unit_test.c
  2130. --- a/njs/test/njs_unit_test.c Thu Mar 07 14:23:45 2019 +0800
  2131. +++ b/njs/test/njs_unit_test.c Thu Mar 07 14:46:49 2019 +0800
  2132. @@ -99,6 +99,31 @@ static njs_unit_test_t njs_test[] =
  2133. { nxt_string("var f = 1; function f() {}; f"),
  2134. nxt_string("1") },
  2135.  
  2136. + { nxt_string("var f = f => {return 1;}; f()"),
  2137. + nxt_string("1") },
  2138. +
  2139. + { nxt_string("var f = (f) => {return 1;}; f()"),
  2140. + nxt_string("1") },
  2141. +
  2142. + { nxt_string("var f = (f, a, b) => {return 1;}; f()"),
  2143. + nxt_string("1") },
  2144. +
  2145. + { nxt_string("var f = () => {return 1;}; f()"),
  2146. + nxt_string("1") },
  2147. +
  2148. + { nxt_string("(f => {return 1;})()"),
  2149. + nxt_string("1") },
  2150. +
  2151. + { nxt_string("((f) => {return 1;})()"),
  2152. + nxt_string("1") },
  2153. +
  2154. + { nxt_string("(((f) => {return 1;}))()"),
  2155. + nxt_string("1") },
  2156. +
  2157. + { nxt_string("var materials = ['Hydrogen', 'Helium', 'Lithium', 'Beryllium' ]; "
  2158. + "materials.map(material => { return material.length; });"),
  2159. + nxt_string("8,6,7,9") },
  2160. +
  2161. #if 0 /* TODO */
  2162. { nxt_string("var a; Object.getOwnPropertyDescriptor(this, 'a').value"),
  2163. nxt_string("undefined") },
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement