ReactOS  0.4.14-dev-49-gfb4591c
lex.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "config.h"
20 #include "wine/port.h"
21 
22 #include <limits.h>
23 
24 #include "jscript.h"
25 #include "activscp.h"
26 #include "objsafe.h"
27 #include "engine.h"
28 #include "parser.h"
29 
30 #include "parser.tab.h"
31 
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
34 
35 #ifdef __REACTOS__
36 /* FIXME: Inspect - For some reason these exist in the generated header but are not picked up */
37 #define kGET (270)
38 #define kSET (272)
39 #endif
40 
42 
43 static const WCHAR breakW[] = {'b','r','e','a','k',0};
44 static const WCHAR caseW[] = {'c','a','s','e',0};
45 static const WCHAR catchW[] = {'c','a','t','c','h',0};
46 static const WCHAR continueW[] = {'c','o','n','t','i','n','u','e',0};
47 static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
48 static const WCHAR deleteW[] = {'d','e','l','e','t','e',0};
49 static const WCHAR doW[] = {'d','o',0};
50 static const WCHAR elseW[] = {'e','l','s','e',0};
51 static const WCHAR falseW[] = {'f','a','l','s','e',0};
52 static const WCHAR finallyW[] = {'f','i','n','a','l','l','y',0};
53 static const WCHAR forW[] = {'f','o','r',0};
54 static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0};
55 static const WCHAR getW[] = {'g','e','t',0};
56 static const WCHAR ifW[] = {'i','f',0};
57 static const WCHAR inW[] = {'i','n',0};
58 static const WCHAR instanceofW[] = {'i','n','s','t','a','n','c','e','o','f',0};
59 static const WCHAR newW[] = {'n','e','w',0};
60 static const WCHAR nullW[] = {'n','u','l','l',0};
61 static const WCHAR returnW[] = {'r','e','t','u','r','n',0};
62 static const WCHAR setW[] = {'s','e','t',0};
63 static const WCHAR switchW[] = {'s','w','i','t','c','h',0};
64 static const WCHAR thisW[] = {'t','h','i','s',0};
65 static const WCHAR throwW[] = {'t','h','r','o','w',0};
66 static const WCHAR trueW[] = {'t','r','u','e',0};
67 static const WCHAR tryW[] = {'t','r','y',0};
68 static const WCHAR typeofW[] = {'t','y','p','e','o','f',0};
69 static const WCHAR varW[] = {'v','a','r',0};
70 static const WCHAR voidW[] = {'v','o','i','d',0};
71 static const WCHAR whileW[] = {'w','h','i','l','e',0};
72 static const WCHAR withW[] = {'w','i','t','h',0};
73 
74 static const WCHAR elifW[] = {'e','l','i','f',0};
75 static const WCHAR endW[] = {'e','n','d',0};
76 
77 static const struct {
78  const WCHAR *word;
79  int token;
81  unsigned min_version;
82 } keywords[] = {
83  {breakW, kBREAK, TRUE},
84  {caseW, kCASE},
85  {catchW, kCATCH},
87  {defaultW, kDEFAULT},
88  {deleteW, kDELETE},
89  {doW, kDO},
90  {elseW, kELSE},
91  {falseW, kFALSE},
92  {finallyW, kFINALLY},
93  {forW, kFOR},
96  {ifW, kIF},
97  {inW, kIN},
99  {newW, kNEW},
100  {nullW, kNULL},
101  {returnW, kRETURN, TRUE},
103  {switchW, kSWITCH},
104  {thisW, kTHIS},
105  {throwW, kTHROW},
106  {trueW, kTRUE},
107  {tryW, kTRY},
108  {typeofW, kTYPEOF},
109  {varW, kVAR},
110  {voidW, kVOID},
111  {whileW, kWHILE},
112  {withW, kWITH}
113 };
114 
116 {
117  ctx->hres = hres;
118  ctx->lexer_error = TRUE;
119  return -1;
120 }
121 
122 /* ECMA-262 3rd Edition 7.6 */
124 {
125  return isalnumW(c) || c == '$' || c == '_' || c == '\\';
126 }
127 
129 {
130  return isalphaW(c) || c == '$' || c == '_' || c == '\\';
131 }
132 
133 static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
134 {
135  const WCHAR *p1 = ctx->ptr;
136  const WCHAR *p2 = word;
137 
138  while(p1 < ctx->end && *p2) {
139  if(*p1 != *p2)
140  return *p1 - *p2;
141  p1++;
142  p2++;
143  }
144 
145  if(*p2 || (p1 < ctx->end && is_identifier_char(*p1)))
146  return 1;
147 
148  if(lval)
149  *lval = word;
150  ctx->ptr = p1;
151  return 0;
152 }
153 
154 /* ECMA-262 3rd Edition 7.3 */
156 {
157  return c == '\n' || c == '\r' || c == 0x2028 || c == 0x2029;
158 }
159 
160 static int hex_to_int(WCHAR c)
161 {
162  if('0' <= c && c <= '9')
163  return c-'0';
164 
165  if('a' <= c && c <= 'f')
166  return c-'a'+10;
167 
168  if('A' <= c && c <= 'F')
169  return c-'A'+10;
170 
171  return -1;
172 }
173 
174 static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
175 {
176  int min = 0, max = ARRAY_SIZE(keywords)-1, r, i;
177 
178  while(min <= max) {
179  i = (min+max)/2;
180 
181  r = check_keyword(ctx, keywords[i].word, lval);
182  if(!r) {
183  if(ctx->script->version < keywords[i].min_version) {
184  TRACE("ignoring keyword %s in incompatible mode\n",
186  ctx->ptr -= strlenW(keywords[i].word);
187  return 0;
188  }
189  ctx->implicit_nl_semicolon = keywords[i].no_nl;
190  return keywords[i].token;
191  }
192 
193  if(r > 0)
194  min = i+1;
195  else
196  max = i-1;
197  }
198 
199  return 0;
200 }
201 
203 {
204  const WCHAR html_commentW[] = {'<','!','-','-',0};
205 
206  if(!ctx->is_html || ctx->ptr+3 >= ctx->end ||
207  memcmp(ctx->ptr, html_commentW, sizeof(WCHAR)*4))
208  return FALSE;
209 
210  ctx->nl = TRUE;
211  while(ctx->ptr < ctx->end && !is_endline(*ctx->ptr++));
212 
213  return TRUE;
214 }
215 
217 {
218  if(ctx->ptr+1 >= ctx->end)
219  return FALSE;
220 
221  if(*ctx->ptr != '/') {
222  if(*ctx->ptr == '@' && ctx->ptr+2 < ctx->end && ctx->ptr[1] == '*' && ctx->ptr[2] == '/') {
223  ctx->ptr += 3;
224  return TRUE;
225  }
226 
227  return FALSE;
228  }
229 
230  switch(ctx->ptr[1]) {
231  case '*':
232  ctx->ptr += 2;
233  if(ctx->ptr+2 < ctx->end && *ctx->ptr == '@' && is_identifier_char(ctx->ptr[1]))
234  return FALSE;
235  while(ctx->ptr+1 < ctx->end && (ctx->ptr[0] != '*' || ctx->ptr[1] != '/'))
236  ctx->ptr++;
237 
238  if(ctx->ptr[0] == '*' && ctx->ptr[1] == '/') {
239  ctx->ptr += 2;
240  }else {
241  WARN("unexpected end of file (missing end of comment)\n");
242  ctx->ptr = ctx->end;
243  }
244  break;
245  case '/':
246  ctx->ptr += 2;
247  if(ctx->ptr+2 < ctx->end && *ctx->ptr == '@' && is_identifier_char(ctx->ptr[1]))
248  return FALSE;
249  while(ctx->ptr < ctx->end && !is_endline(*ctx->ptr))
250  ctx->ptr++;
251  break;
252  default:
253  return FALSE;
254  }
255 
256  return TRUE;
257 }
258 
260 {
261  while(ctx->ptr < ctx->end && (isspaceW(*ctx->ptr) || *ctx->ptr == 0xFEFF /* UTF16 BOM */)) {
262  if(is_endline(*ctx->ptr++))
263  ctx->nl = TRUE;
264  }
265 
266  return ctx->ptr != ctx->end;
267 }
268 
270 {
271  WCHAR *pd, *p, c;
272  int i;
273 
274  pd = p = str;
275  while(*p) {
276  if(*p != '\\') {
277  *pd++ = *p++;
278  continue;
279  }
280 
281  p++;
282 
283  switch(*p) {
284  case '\'':
285  case '\"':
286  case '\\':
287  c = *p;
288  break;
289  case 'b':
290  c = '\b';
291  break;
292  case 't':
293  c = '\t';
294  break;
295  case 'n':
296  c = '\n';
297  break;
298  case 'f':
299  c = '\f';
300  break;
301  case 'r':
302  c = '\r';
303  break;
304  case 'x':
305  i = hex_to_int(*++p);
306  if(i == -1)
307  return FALSE;
308  c = i << 4;
309 
310  i = hex_to_int(*++p);
311  if(i == -1)
312  return FALSE;
313  c += i;
314  break;
315  case 'u':
316  i = hex_to_int(*++p);
317  if(i == -1)
318  return FALSE;
319  c = i << 12;
320 
321  i = hex_to_int(*++p);
322  if(i == -1)
323  return FALSE;
324  c += i << 8;
325 
326  i = hex_to_int(*++p);
327  if(i == -1)
328  return FALSE;
329  c += i << 4;
330 
331  i = hex_to_int(*++p);
332  if(i == -1)
333  return FALSE;
334  c += i;
335  break;
336  default:
337  if(isdigitW(*p)) {
338  c = *p++ - '0';
339  if(isdigitW(*p)) {
340  c = c*8 + (*p++ - '0');
341  if(isdigitW(*p))
342  c = c*8 + (*p++ - '0');
343  }
344  p--;
345  }
346  else
347  c = *p;
348  }
349 
350  *pd++ = c;
351  p++;
352  }
353 
354  *pd = 0;
355  return TRUE;
356 }
357 
358 static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
359 {
360  const WCHAR *ptr = ctx->ptr++;
361  WCHAR *wstr;
362  int len;
363 
364  while(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr))
365  ctx->ptr++;
366 
367  len = ctx->ptr-ptr;
368 
369  *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
370  memcpy(wstr, ptr, len*sizeof(WCHAR));
371  wstr[len] = 0;
372 
373  /* FIXME: unescape */
374  return tIdentifier;
375 }
376 
377 static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endch)
378 {
379  const WCHAR *ptr = ++ctx->ptr;
380  WCHAR *wstr;
381  int len;
382 
383  while(ctx->ptr < ctx->end && *ctx->ptr != endch) {
384  if(*ctx->ptr++ == '\\')
385  ctx->ptr++;
386  }
387 
388  if(ctx->ptr == ctx->end)
389  return lex_error(ctx, JS_E_UNTERMINATED_STRING);
390 
391  len = ctx->ptr-ptr;
392 
393  *ret = wstr = parser_alloc(ctx, (len+1)*sizeof(WCHAR));
394  memcpy(wstr, ptr, len*sizeof(WCHAR));
395  wstr[len] = 0;
396 
397  ctx->ptr++;
398 
399  if(!unescape(wstr)) {
400  WARN("unescape failed\n");
401  return lex_error(ctx, E_FAIL);
402  }
403 
404  return tStringLiteral;
405 }
406 
408 {
409  literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
410 
411  ret->type = LT_DOUBLE;
412  ret->u.dval = d;
413  return ret;
414 }
415 
417 {
418  literal_t *ret = parser_alloc(ctx, sizeof(literal_t));
419 
420  ret->type = LT_BOOL;
421  ret->u.bval = bval;
422 
423  return ret;
424 }
425 
426 HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
427 {
428  const WCHAR *ptr = *iter;
429  LONGLONG d = 0, hlp;
430  int exp = 0;
431 
432  while(ptr < end && isdigitW(*ptr)) {
433  hlp = d*10 + *(ptr++) - '0';
434  if(d>MAXLONGLONG/10 || hlp<0) {
435  exp++;
436  break;
437  }
438  else
439  d = hlp;
440  }
441  while(ptr < end && isdigitW(*ptr)) {
442  exp++;
443  ptr++;
444  }
445 
446  if(*ptr == '.') {
447  ptr++;
448 
449  while(ptr < end && isdigitW(*ptr)) {
450  hlp = d*10 + *(ptr++) - '0';
451  if(d>MAXLONGLONG/10 || hlp<0)
452  break;
453 
454  d = hlp;
455  exp--;
456  }
457  while(ptr < end && isdigitW(*ptr))
458  ptr++;
459  }
460 
461  if(ptr < end && (*ptr == 'e' || *ptr == 'E')) {
462  int sign = 1, e = 0;
463 
464  if(++ptr < end) {
465  if(*ptr == '+') {
466  ptr++;
467  }else if(*ptr == '-') {
468  sign = -1;
469  ptr++;
470  }else if(!isdigitW(*ptr)) {
471  WARN("Expected exponent part\n");
472  return E_FAIL;
473  }
474  }
475 
476  if(ptr == end) {
477  WARN("unexpected end of file\n");
478  return E_FAIL;
479  }
480 
481  while(ptr < end && isdigitW(*ptr)) {
482  if(e > INT_MAX/10 || (e = e*10 + *ptr++ - '0')<0)
483  e = INT_MAX;
484  }
485  e *= sign;
486 
487  if(exp<0 && e<0 && e+exp>0) exp = INT_MIN;
488  else if(exp>0 && e>0 && e+exp<0) exp = INT_MAX;
489  else exp += e;
490  }
491 
492  if(is_identifier_char(*ptr)) {
493  WARN("wrong char after zero\n");
494  return JS_E_MISSING_SEMICOLON;
495  }
496 
497  *ret = exp>=0 ? d*pow(10, exp) : d/pow(10, -exp);
498  *iter = ptr;
499  return S_OK;
500 }
501 
503 {
504  HRESULT hres;
505 
506  if(*ctx->ptr == '0') {
507  ctx->ptr++;
508 
509  if(*ctx->ptr == 'x' || *ctx->ptr == 'X') {
510  double r = 0;
511  int d;
512  if(++ctx->ptr == ctx->end) {
513  ERR("unexpected end of file\n");
514  return FALSE;
515  }
516 
517  while(ctx->ptr < ctx->end && (d = hex_to_int(*ctx->ptr)) != -1) {
518  r = r*16 + d;
519  ctx->ptr++;
520  }
521 
522  if(ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr)) {
523  WARN("unexpected identifier char\n");
525  return FALSE;
526  }
527 
528  *ret = r;
529  return TRUE;
530  }
531 
532  if(isdigitW(*ctx->ptr)) {
533  unsigned base = 8;
534  const WCHAR *ptr;
535  double val = 0;
536 
537  for(ptr = ctx->ptr; ptr < ctx->end && isdigitW(*ptr); ptr++) {
538  if(*ptr > '7') {
539  base = 10;
540  break;
541  }
542  }
543 
544  do {
545  val = val*base + *ctx->ptr-'0';
546  }while(++ctx->ptr < ctx->end && isdigitW(*ctx->ptr));
547 
548  /* FIXME: Do we need it here? */
549  if(ctx->ptr < ctx->end && (is_identifier_char(*ctx->ptr) || *ctx->ptr == '.')) {
550  WARN("wrong char after octal literal: '%c'\n", *ctx->ptr);
552  return FALSE;
553  }
554 
555  *ret = val;
556  return TRUE;
557  }
558 
559  if(is_identifier_char(*ctx->ptr)) {
560  WARN("wrong char after zero\n");
562  return FALSE;
563  }
564  }
565 
566  hres = parse_decimal(&ctx->ptr, ctx->end, ret);
567  if(FAILED(hres)) {
568  lex_error(ctx, hres);
569  return FALSE;
570  }
571 
572  return TRUE;
573 }
574 
575 static int next_token(parser_ctx_t *ctx, void *lval)
576 {
577  do {
578  if(!skip_spaces(ctx))
579  return tEOF;
580  }while(skip_comment(ctx) || skip_html_comment(ctx));
581 
582  if(ctx->implicit_nl_semicolon) {
583  if(ctx->nl)
584  return ';';
585  ctx->implicit_nl_semicolon = FALSE;
586  }
587 
588  if(isalphaW(*ctx->ptr)) {
589  int ret = check_keywords(ctx, lval);
590  if(ret)
591  return ret;
592 
593  return parse_identifier(ctx, lval);
594  }
595 
596  if(isdigitW(*ctx->ptr)) {
597  double n;
598 
599  if(!parse_numeric_literal(ctx, &n))
600  return -1;
601 
602  *(literal_t**)lval = new_double_literal(ctx, n);
603  return tNumericLiteral;
604  }
605 
606  switch(*ctx->ptr) {
607  case '{':
608  case '(':
609  case ')':
610  case '[':
611  case ']':
612  case ';':
613  case ',':
614  case '~':
615  case '?':
616  return *ctx->ptr++;
617 
618  case '}':
619  *(const WCHAR**)lval = ctx->ptr++;
620  return '}';
621 
622  case '.':
623  if(ctx->ptr+1 < ctx->end && isdigitW(ctx->ptr[1])) {
624  double n;
625  HRESULT hres;
626  hres = parse_decimal(&ctx->ptr, ctx->end, &n);
627  if(FAILED(hres)) {
628  lex_error(ctx, hres);
629  return -1;
630  }
631  *(literal_t**)lval = new_double_literal(ctx, n);
632  return tNumericLiteral;
633  }
634  ctx->ptr++;
635  return '.';
636 
637  case '<':
638  if(++ctx->ptr == ctx->end) {
639  *(int*)lval = EXPR_LESS;
640  return tRelOper;
641  }
642 
643  switch(*ctx->ptr) {
644  case '=': /* <= */
645  ctx->ptr++;
646  *(int*)lval = EXPR_LESSEQ;
647  return tRelOper;
648  case '<': /* << */
649  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* <<= */
650  ctx->ptr++;
651  *(int*)lval = EXPR_ASSIGNLSHIFT;
652  return tAssignOper;
653  }
654  *(int*)lval = EXPR_LSHIFT;
655  return tShiftOper;
656  default: /* < */
657  *(int*)lval = EXPR_LESS;
658  return tRelOper;
659  }
660 
661  case '>':
662  if(++ctx->ptr == ctx->end) { /* > */
663  *(int*)lval = EXPR_GREATER;
664  return tRelOper;
665  }
666 
667  switch(*ctx->ptr) {
668  case '=': /* >= */
669  ctx->ptr++;
670  *(int*)lval = EXPR_GREATEREQ;
671  return tRelOper;
672  case '>': /* >> */
673  if(++ctx->ptr < ctx->end) {
674  if(*ctx->ptr == '=') { /* >>= */
675  ctx->ptr++;
676  *(int*)lval = EXPR_ASSIGNRSHIFT;
677  return tAssignOper;
678  }
679  if(*ctx->ptr == '>') { /* >>> */
680  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* >>>= */
681  ctx->ptr++;
682  *(int*)lval = EXPR_ASSIGNRRSHIFT;
683  return tAssignOper;
684  }
685  *(int*)lval = EXPR_RRSHIFT;
686  return tRelOper;
687  }
688  }
689  *(int*)lval = EXPR_RSHIFT;
690  return tShiftOper;
691  default:
692  *(int*)lval = EXPR_GREATER;
693  return tRelOper;
694  }
695 
696  case '+':
697  ctx->ptr++;
698  if(ctx->ptr < ctx->end) {
699  switch(*ctx->ptr) {
700  case '+': /* ++ */
701  ctx->ptr++;
702  return tINC;
703  case '=': /* += */
704  ctx->ptr++;
705  *(int*)lval = EXPR_ASSIGNADD;
706  return tAssignOper;
707  }
708  }
709  return '+';
710 
711  case '-':
712  ctx->ptr++;
713  if(ctx->ptr < ctx->end) {
714  switch(*ctx->ptr) {
715  case '-': /* -- or --> */
716  ctx->ptr++;
717  if(ctx->is_html && ctx->nl && ctx->ptr < ctx->end && *ctx->ptr == '>') {
718  ctx->ptr++;
719  return tHTMLCOMMENT;
720  }
721  return tDEC;
722  case '=': /* -= */
723  ctx->ptr++;
724  *(int*)lval = EXPR_ASSIGNSUB;
725  return tAssignOper;
726  }
727  }
728  return '-';
729 
730  case '*':
731  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* *= */
732  ctx->ptr++;
733  *(int*)lval = EXPR_ASSIGNMUL;
734  return tAssignOper;
735  }
736  return '*';
737 
738  case '%':
739  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* %= */
740  ctx->ptr++;
741  *(int*)lval = EXPR_ASSIGNMOD;
742  return tAssignOper;
743  }
744  return '%';
745 
746  case '&':
747  if(++ctx->ptr < ctx->end) {
748  switch(*ctx->ptr) {
749  case '=': /* &= */
750  ctx->ptr++;
751  *(int*)lval = EXPR_ASSIGNAND;
752  return tAssignOper;
753  case '&': /* && */
754  ctx->ptr++;
755  return tANDAND;
756  }
757  }
758  return '&';
759 
760  case '|':
761  if(++ctx->ptr < ctx->end) {
762  switch(*ctx->ptr) {
763  case '=': /* |= */
764  ctx->ptr++;
765  *(int*)lval = EXPR_ASSIGNOR;
766  return tAssignOper;
767  case '|': /* || */
768  ctx->ptr++;
769  return tOROR;
770  }
771  }
772  return '|';
773 
774  case '^':
775  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* ^= */
776  ctx->ptr++;
777  *(int*)lval = EXPR_ASSIGNXOR;
778  return tAssignOper;
779  }
780  return '^';
781 
782  case '!':
783  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* != */
784  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* !== */
785  ctx->ptr++;
786  *(int*)lval = EXPR_NOTEQEQ;
787  return tEqOper;
788  }
789  *(int*)lval = EXPR_NOTEQ;
790  return tEqOper;
791  }
792  return '!';
793 
794  case '=':
795  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* == */
796  if(++ctx->ptr < ctx->end && *ctx->ptr == '=') { /* === */
797  ctx->ptr++;
798  *(int*)lval = EXPR_EQEQ;
799  return tEqOper;
800  }
801  *(int*)lval = EXPR_EQ;
802  return tEqOper;
803  }
804  return '=';
805 
806  case '/':
807  if(++ctx->ptr < ctx->end) {
808  if(*ctx->ptr == '=') { /* /= */
809  ctx->ptr++;
810  *(int*)lval = EXPR_ASSIGNDIV;
811  return kDIVEQ;
812  }
813  }
814  return '/';
815 
816  case ':':
817  if(++ctx->ptr < ctx->end && *ctx->ptr == ':') {
818  ctx->ptr++;
819  return kDCOL;
820  }
821  return ':';
822 
823  case '\"':
824  case '\'':
825  return parse_string_literal(ctx, lval, *ctx->ptr);
826 
827  case '_':
828  case '$':
829  return parse_identifier(ctx, lval);
830 
831  case '@':
832  return '@';
833  }
834 
835  WARN("unexpected char '%c' %d\n", *ctx->ptr, *ctx->ptr);
836  return 0;
837 }
838 
839 struct _cc_var_t {
841  struct _cc_var_t *next;
842  unsigned name_len;
844 };
845 
847 {
848  cc_var_t *iter, *next;
849 
850  for(iter = cc->vars; iter; iter = next) {
851  next = iter->next;
852  heap_free(iter);
853  }
854 
855  heap_free(cc);
856 }
857 
858 static BOOL new_cc_var(cc_ctx_t *cc, const WCHAR *name, int len, ccval_t v)
859 {
860  cc_var_t *new_v;
861 
862  if(len == -1)
863  len = strlenW(name);
864 
865  new_v = heap_alloc(sizeof(cc_var_t) + (len+1)*sizeof(WCHAR));
866  if(!new_v)
867  return FALSE;
868 
869  new_v->val = v;
870  memcpy(new_v->name, name, (len+1)*sizeof(WCHAR));
871  new_v->name_len = len;
872  new_v->next = cc->vars;
873  cc->vars = new_v;
874  return TRUE;
875 }
876 
877 static cc_var_t *find_cc_var(cc_ctx_t *cc, const WCHAR *name, unsigned name_len)
878 {
879  cc_var_t *iter;
880 
881  for(iter = cc->vars; iter; iter = iter->next) {
882  if(iter->name_len == name_len && !memcmp(iter->name, name, name_len*sizeof(WCHAR)))
883  return iter;
884  }
885 
886  return NULL;
887 }
888 
890 {
891  cc_ctx_t *cc;
892 
893  static const WCHAR _win32W[] = {'_','w','i','n','3','2',0};
894  static const WCHAR _win64W[] = {'_','w','i','n','6','4',0};
895  static const WCHAR _x86W[] = {'_','x','8','6',0};
896  static const WCHAR _amd64W[] = {'_','a','m','d','6','4',0};
897  static const WCHAR _jscriptW[] = {'_','j','s','c','r','i','p','t',0};
898  static const WCHAR _jscript_buildW[] = {'_','j','s','c','r','i','p','t','_','b','u','i','l','d',0};
899  static const WCHAR _jscript_versionW[] = {'_','j','s','c','r','i','p','t','_','v','e','r','s','i','o','n',0};
900 
901  if(ctx->script->cc)
902  return TRUE;
903 
904  cc = heap_alloc(sizeof(cc_ctx_t));
905  if(!cc) {
906  lex_error(ctx, E_OUTOFMEMORY);
907  return FALSE;
908  }
909 
910  cc->vars = NULL;
911 
912  if(!new_cc_var(cc, _jscriptW, -1, ccval_bool(TRUE))
913  || !new_cc_var(cc, sizeof(void*) == 8 ? _win64W : _win32W, -1, ccval_bool(TRUE))
914  || !new_cc_var(cc, sizeof(void*) == 8 ? _amd64W : _x86W, -1, ccval_bool(TRUE))
915  || !new_cc_var(cc, _jscript_versionW, -1, ccval_num(JSCRIPT_MAJOR_VERSION + (DOUBLE)JSCRIPT_MINOR_VERSION/10.0))
916  || !new_cc_var(cc, _jscript_buildW, -1, ccval_num(JSCRIPT_BUILD_VERSION))) {
917  release_cc(cc);
918  lex_error(ctx, E_OUTOFMEMORY);
919  return FALSE;
920  }
921 
922  ctx->script->cc = cc;
923  return TRUE;
924 }
925 
926 static BOOL parse_cc_identifier(parser_ctx_t *ctx, const WCHAR **ret, unsigned *ret_len)
927 {
928  if(*ctx->ptr != '@') {
930  return FALSE;
931  }
932 
933  if(!is_identifier_first_char(*++ctx->ptr)) {
935  return FALSE;
936  }
937 
938  *ret = ctx->ptr;
939  while(++ctx->ptr < ctx->end && is_identifier_char(*ctx->ptr));
940  *ret_len = ctx->ptr - *ret;
941  return TRUE;
942 }
943 
945 {
946  if(!skip_spaces(ctx))
947  return -1;
948 
949  if(isdigitW(*ctx->ptr)) {
950  double n;
951 
952  if(!parse_numeric_literal(ctx, &n))
953  return -1;
954 
955  *r = ccval_num(n);
956  return 1;
957  }
958 
959  if(*ctx->ptr == '@') {
960  const WCHAR *ident;
961  unsigned ident_len;
962  cc_var_t *cc_var;
963 
964  if(!parse_cc_identifier(ctx, &ident, &ident_len))
965  return -1;
966 
967  cc_var = find_cc_var(ctx->script->cc, ident, ident_len);
968  *r = cc_var ? cc_var->val : ccval_num(NAN);
969  return 1;
970  }
971 
972  if(!check_keyword(ctx, trueW, NULL)) {
973  *r = ccval_bool(TRUE);
974  return 1;
975  }
976 
977  if(!check_keyword(ctx, falseW, NULL)) {
978  *r = ccval_bool(FALSE);
979  return 1;
980  }
981 
982  return 0;
983 }
984 
985 static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
986 {
987  int if_depth = 1;
988  const WCHAR *ptr;
989 
990  while(1) {
991  ptr = strchrW(ctx->ptr, '@');
992  if(!ptr) {
993  WARN("No @end\n");
994  return lex_error(ctx, JS_E_EXPECTED_CCEND);
995  }
996  ctx->ptr = ptr+1;
997 
998  if(!check_keyword(ctx, endW, NULL)) {
999  if(--if_depth)
1000  continue;
1001  return 0;
1002  }
1003 
1004  if(exec_else && !check_keyword(ctx, elifW, NULL)) {
1005  if(if_depth > 1)
1006  continue;
1007 
1008  if(!skip_spaces(ctx) || *ctx->ptr != '(')
1009  return lex_error(ctx, JS_E_MISSING_LBRACKET);
1010 
1011  if(!parse_cc_expr(ctx))
1012  return -1;
1013 
1014  if(!get_ccbool(ctx->ccval))
1015  continue; /* skip block of code */
1016 
1017  /* continue parsing */
1018  ctx->cc_if_depth++;
1019  return 0;
1020  }
1021 
1022  if(exec_else && !check_keyword(ctx, elseW, NULL)) {
1023  if(if_depth > 1)
1024  continue;
1025 
1026  /* parse else block */
1027  ctx->cc_if_depth++;
1028  return 0;
1029  }
1030 
1031  if(!check_keyword(ctx, ifW, NULL)) {
1032  if_depth++;
1033  continue;
1034  }
1035 
1036  ctx->ptr++;
1037  }
1038 }
1039 
1040 static int cc_token(parser_ctx_t *ctx, void *lval)
1041 {
1042  unsigned id_len = 0;
1043  cc_var_t *var;
1044 
1045  static const WCHAR cc_onW[] = {'c','c','_','o','n',0};
1046  static const WCHAR setW[] = {'s','e','t',0};
1047 
1048  ctx->ptr++;
1049 
1050  if(!check_keyword(ctx, cc_onW, NULL))
1051  return init_cc(ctx) ? 0 : -1;
1052 
1053  if(!check_keyword(ctx, setW, NULL)) {
1054  const WCHAR *ident;
1055  unsigned ident_len;
1056  cc_var_t *var;
1057 
1058  if(!init_cc(ctx))
1059  return -1;
1060 
1061  if(!skip_spaces(ctx))
1062  return lex_error(ctx, JS_E_EXPECTED_AT);
1063 
1064  if(!parse_cc_identifier(ctx, &ident, &ident_len))
1065  return -1;
1066 
1067  if(!skip_spaces(ctx) || *ctx->ptr != '=')
1068  return lex_error(ctx, JS_E_EXPECTED_ASSIGN);
1069  ctx->ptr++;
1070 
1071  if(!parse_cc_expr(ctx)) {
1072  WARN("parsing CC expression failed\n");
1073  return -1;
1074  }
1075 
1076  var = find_cc_var(ctx->script->cc, ident, ident_len);
1077  if(var) {
1078  var->val = ctx->ccval;
1079  }else {
1080  if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval))
1081  return lex_error(ctx, E_OUTOFMEMORY);
1082  }
1083 
1084  return 0;
1085  }
1086 
1087  if(!check_keyword(ctx, ifW, NULL)) {
1088  if(!init_cc(ctx))
1089  return -1;
1090 
1091  if(!skip_spaces(ctx) || *ctx->ptr != '(')
1092  return lex_error(ctx, JS_E_MISSING_LBRACKET);
1093 
1094  if(!parse_cc_expr(ctx))
1095  return -1;
1096 
1097  if(get_ccbool(ctx->ccval)) {
1098  /* continue parsing block inside if */
1099  ctx->cc_if_depth++;
1100  return 0;
1101  }
1102 
1103  return skip_code(ctx, TRUE);
1104  }
1105 
1106  if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) {
1107  if(!ctx->cc_if_depth)
1108  return lex_error(ctx, JS_E_SYNTAX);
1109 
1110  return skip_code(ctx, FALSE);
1111  }
1112 
1113  if(!check_keyword(ctx, endW, NULL)) {
1114  if(!ctx->cc_if_depth)
1115  return lex_error(ctx, JS_E_SYNTAX);
1116 
1117  ctx->cc_if_depth--;
1118  return 0;
1119  }
1120 
1121  if(!ctx->script->cc)
1122  return lex_error(ctx, JS_E_DISABLED_CC);
1123 
1124  while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len]))
1125  id_len++;
1126  if(!id_len)
1127  return '@';
1128 
1129  TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len));
1130 
1131  var = find_cc_var(ctx->script->cc, ctx->ptr, id_len);
1132  ctx->ptr += id_len;
1133  if(!var || var->val.is_num) {
1134  *(literal_t**)lval = new_double_literal(ctx, var ? var->val.u.n : NAN);
1135  return tNumericLiteral;
1136  }
1137 
1138  *(literal_t**)lval = new_boolean_literal(ctx, var->val.u.b);
1139  return tBooleanLiteral;
1140 }
1141 
1142 int parser_lex(void *lval, parser_ctx_t *ctx)
1143 {
1144  int ret;
1145 
1146  ctx->nl = ctx->ptr == ctx->begin;
1147 
1148  do {
1149  ret = next_token(ctx, lval);
1150  } while(ret == '@' && !(ret = cc_token(ctx, lval)));
1151 
1152  return ret;
1153 }
1154 
1156 {
1157  const WCHAR *re, *flags_ptr;
1158  BOOL in_class = FALSE;
1159  DWORD re_len, flags;
1160  literal_t *ret;
1161  HRESULT hres;
1162 
1163  TRACE("\n");
1164 
1165  while(*--ctx->ptr != '/');
1166 
1167  /* Simple regexp pre-parser; '/' if used in char class does not terminate regexp literal */
1168  re = ++ctx->ptr;
1169  while(ctx->ptr < ctx->end) {
1170  if(*ctx->ptr == '\\') {
1171  if(++ctx->ptr == ctx->end)
1172  break;
1173  }else if(in_class) {
1174  if(*ctx->ptr == '\n')
1175  break;
1176  if(*ctx->ptr == ']')
1177  in_class = FALSE;
1178  }else {
1179  if(*ctx->ptr == '/')
1180  break;
1181 
1182  if(*ctx->ptr == '[')
1183  in_class = TRUE;
1184  }
1185  ctx->ptr++;
1186  }
1187 
1188  if(ctx->ptr == ctx->end || *ctx->ptr != '/') {
1189  WARN("pre-parsing failed\n");
1190  return NULL;
1191  }
1192 
1193  re_len = ctx->ptr-re;
1194 
1195  flags_ptr = ++ctx->ptr;
1196  while(ctx->ptr < ctx->end && isalnumW(*ctx->ptr))
1197  ctx->ptr++;
1198 
1199  hres = parse_regexp_flags(flags_ptr, ctx->ptr-flags_ptr, &flags);
1200  if(FAILED(hres))
1201  return NULL;
1202 
1203  ret = parser_alloc(ctx, sizeof(literal_t));
1204  ret->type = LT_REGEXP;
1205  ret->u.regexp.str = re;
1206  ret->u.regexp.str_len = re_len;
1207  ret->u.regexp.flags = flags;
1208  return ret;
1209 }
static const struct @422 keywords[]
static size_t double int int int * sign
Definition: printf.c:64
HRESULT parse_regexp_flags(const WCHAR *, DWORD, DWORD *) DECLSPEC_HIDDEN
Definition: jsregexp.c:1022
#define JS_E_EXPECTED_ASSIGN
Definition: jscript.h:545
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define INT_MAX
Definition: limits.h:40
static int hex_to_int(WCHAR c)
Definition: lex.c:160
static cc_var_t * find_cc_var(cc_ctx_t *cc, const WCHAR *name, unsigned name_len)
Definition: lex.c:877
BOOL is_identifier_char(WCHAR c)
Definition: lex.c:123
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
union ccval_t::@423 u
WINE_UNICODE_INLINE int isspaceW(WCHAR wc)
Definition: unicode.h:165
#define JS_E_EXPECTED_CCEND
Definition: jscript.h:553
static const WCHAR defaultW[]
Definition: lex.c:47
static int parse_string_literal(parser_ctx_t *ctx, const WCHAR **ret, WCHAR endch)
Definition: lex.c:377
unsigned name_len
Definition: lex.c:842
#define WARN(fmt,...)
Definition: debug.h:111
HRESULT parse_decimal(const WCHAR **iter, const WCHAR *end, double *ret)
Definition: lex.c:426
GLdouble n
Definition: glext.h:7729
static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret)
Definition: lex.c:358
BOOL is_num
Definition: parser.h:26
static const WCHAR tryW[]
Definition: lex.c:67
int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r)
Definition: lex.c:944
static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret)
Definition: lex.c:502
literal_t * new_boolean_literal(parser_ctx_t *ctx, BOOL bval)
Definition: lex.c:416
Definition: parser.h:74
GLuint GLuint end
Definition: gl.h:1545
#define MAXLONGLONG
static ccval_t ccval_bool(BOOL b)
Definition: parser.h:387
#define in_class(found, pat, c)
Definition: match.c:168
static const WCHAR whileW[]
Definition: lex.c:71
#define JSCRIPT_MAJOR_VERSION
Definition: resource.h:23
#define E_FAIL
Definition: ddrawi.h:102
static literal_t * new_double_literal(parser_ctx_t *ctx, DOUBLE d)
Definition: lex.c:407
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define JSCRIPT_BUILD_VERSION
Definition: resource.h:25
static const WCHAR continueW[]
Definition: lex.c:46
void release_cc(cc_ctx_t *cc)
Definition: lex.c:846
static const WCHAR elseW[]
Definition: lex.c:50
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
WCHAR name[0]
Definition: lex.c:843
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
int token
Definition: lex.c:79
static const WCHAR inW[]
Definition: lex.c:57
static const WCHAR thisW[]
Definition: lex.c:64
unsigned int BOOL
Definition: ntddk_ex.h:94
float pow(float __x, int __y)
Definition: _cmath.h:458
#define e
Definition: ke_i.h:82
static const WCHAR instanceofW[]
Definition: lex.c:58
#define debugstr_w
Definition: kernel32.h:32
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR endW[]
Definition: lex.c:75
static ccval_t ccval_num(double n)
Definition: parser.h:379
const WCHAR * str
const WCHAR * ptr
Definition: parse.h:256
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR catchW[]
Definition: lex.c:45
static const WCHAR deleteW[]
Definition: lex.c:48
#define JS_E_MISSING_LBRACKET
Definition: jscript.h:542
static int skip_code(parser_ctx_t *ctx, BOOL exec_else)
Definition: lex.c:985
BOOL parse_cc_expr(parser_ctx_t *ctx)
static int cc_token(parser_ctx_t *ctx, void *lval)
Definition: lex.c:1040
literal_t * parse_regexp(parser_ctx_t *ctx)
Definition: lex.c:1155
static const WCHAR throwW[]
Definition: lex.c:65
BOOL unescape(WCHAR *str)
Definition: lex.c:269
GLuint GLfloat * val
Definition: glext.h:7180
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
static const WCHAR setW[]
Definition: lex.c:62
static const WCHAR caseW[]
Definition: lex.c:44
BOOL no_nl
Definition: lex.c:80
static const WCHAR doW[]
Definition: lex.c:49
int64_t LONGLONG
Definition: typedefs.h:66
static const WCHAR forW[]
Definition: lex.c:53
BOOL b
Definition: parser.h:28
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
#define d
Definition: ke_i.h:81
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static const WCHAR breakW[]
Definition: lex.c:43
static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval)
Definition: lex.c:174
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
ccval_t val
Definition: lex.c:840
#define NAN
Definition: misc.c:46
static BOOL skip_html_comment(parser_ctx_t *ctx)
Definition: lex.c:202
struct _cc_var_t * next
Definition: lex.c:841
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
GLbitfield flags
Definition: glext.h:7161
#define SCRIPTLANGUAGEVERSION_ES5
Definition: jscript.h:49
#define JS_E_MISSING_SEMICOLON
Definition: jscript.h:541
static const WCHAR nullW[]
Definition: lex.c:60
int ret
#define JS_E_DISABLED_CC
Definition: jscript.h:554
unsigned min_version
Definition: lex.c:81
static int lex_error(parser_ctx_t *ctx, HRESULT hres)
Definition: lex.c:115
static const WCHAR switchW[]
Definition: lex.c:63
static const WCHAR typeofW[]
Definition: lex.c:68
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
const WCHAR * end
Definition: parse.h:257
static const WCHAR withW[]
Definition: lex.c:72
static INT ident_len(LPCTSTR p)
Definition: set.c:208
static BOOL is_endline(WCHAR c)
Definition: lex.c:155
static BOOL init_cc(parser_ctx_t *ctx)
Definition: lex.c:889
#define debugstr_wn
Definition: kernel32.h:33
WINE_UNICODE_INLINE int isalnumW(WCHAR wc)
Definition: unicode.h:190
static BOOL parse_cc_identifier(parser_ctx_t *ctx, const WCHAR **ret, unsigned *ret_len)
Definition: lex.c:926
#define INT_MIN
Definition: limits.h:39
#define JS_E_UNTERMINATED_STRING
Definition: jscript.h:547
#define ERR(fmt,...)
Definition: debug.h:109
uint32_t cc
Definition: isohybrid.c:75
static BOOL is_identifier_first_char(WCHAR c)
Definition: lex.c:128
static void * parser_alloc(parser_ctx_t *ctx, DWORD size)
Definition: parser.h:57
double n
Definition: parser.h:29
#define S_OK
Definition: intsafe.h:59
static const WCHAR falseW[]
Definition: lex.c:51
static unsigned __int64 next
Definition: rand_nt.c:6
#define JS_E_EXPECTED_AT
Definition: jscript.h:555
const GLdouble * v
Definition: gl.h:2040
static const WCHAR finallyW[]
Definition: lex.c:52
static const WCHAR ifW[]
Definition: lex.c:56
#define JSCRIPT_MINOR_VERSION
Definition: resource.h:24
#define ARRAY_SIZE(a)
Definition: main.h:24
static int next_token(parser_ctx_t *ctx, void *lval)
Definition: lex.c:575
static const WCHAR elifW[]
Definition: lex.c:74
Definition: lex.c:839
int parser_lex(void *lval, parser_ctx_t *ctx)
Definition: lex.c:1142
static BOOL get_ccbool(ccval_t v)
Definition: parser.h:395
WINE_UNICODE_INLINE int isdigitW(WCHAR wc)
Definition: unicode.h:170
#define min(a, b)
Definition: monoChain.cc:55
static BOOL skip_spaces(parser_ctx_t *ctx)
Definition: lex.c:259
DWORD exp
Definition: msg.c:15681
Definition: parser.h:25
const WCHAR * word
Definition: lex.c:78
static const WCHAR returnW[]
Definition: lex.c:61
#define JS_E_SYNTAX
Definition: jscript.h:540
Definition: name.c:36
static const WCHAR trueW[]
Definition: lex.c:66
static BOOL skip_comment(parser_ctx_t *ctx)
Definition: lex.c:216
#define c
Definition: ke_i.h:80
double DOUBLE
Definition: typedefs.h:68
float bval
Definition: cylfrac.c:48
static const WCHAR functionW[]
Definition: lex.c:54
WINE_UNICODE_INLINE int isalphaW(WCHAR wc)
Definition: unicode.h:195
#define JS_E_EXPECTED_IDENTIFIER
Definition: jscript.h:544
HRESULT hres
Definition: parse.h:262
GLfloat GLfloat p
Definition: glext.h:8902
BOOL is_html
Definition: parse.h:261
static const WCHAR newW[]
Definition: lex.c:59
static const WCHAR getW[]
Definition: lex.c:55
static BOOL new_cc_var(cc_ctx_t *cc, const WCHAR *name, int len, ccval_t v)
Definition: lex.c:858
static const WCHAR varW[]
Definition: lex.c:69
static const WCHAR voidW[]
Definition: lex.c:70
WINE_DEFAULT_DEBUG_CHANNEL(jscript)
static int check_keyword(parser_ctx_t *ctx, const WCHAR *word, const WCHAR **lval)
Definition: lex.c:133
static BOOL heap_free(void *mem)
Definition: appwiz.h:75