implemented two-pass compiling
[swftools.git] / lib / as3 / tokenizer.lex
1 /* tokenizer.lex
2
3    Routines for compiling Flash2 AVM2 ABC Actionscript
4
5    Extension module for the rfxswf library.
6    Part of the swftools package.
7
8    Copyright (c) 2008 Matthias Kramm <kramm@quiss.org>
9  
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
23 %{
24
25
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include "../utf8.h"
31 #include "tokenizer.h"
32 #include "files.h"
33
34 int as3_pass = 0;
35
36 int as3_verbosity = 1;
37 void as3_error(const char*format, ...)
38 {
39     char buf[1024];
40     int l;
41     va_list arglist;
42     if(as3_verbosity<0)
43         exit(1);
44     va_start(arglist, format);
45     vsprintf(buf, format, arglist);
46     va_end(arglist);
47     fprintf(stderr, "%s:%d:%d: error: %s\n", current_filename_short, current_line, current_column, buf);
48     fflush(stderr);
49     exit(1);
50 }
51 void as3_warning(const char*format, ...)
52 {
53     char buf[1024];
54     int l;
55     va_list arglist;
56     if(as3_verbosity<1)
57         return;
58     va_start(arglist, format);
59     vsprintf(buf, format, arglist);
60     va_end(arglist);
61     fprintf(stderr, "%s:%d:%d: warning: %s\n", current_filename_short, current_line, current_column, buf);
62     fflush(stderr);
63 }
64 void as3_softwarning(const char*format, ...)
65 {
66     char buf[1024];
67     int l;
68     va_list arglist;
69     if(as3_verbosity<2)
70         return;
71     va_start(arglist, format);
72     vsprintf(buf, format, arglist);
73     va_end(arglist);
74     fprintf(stderr, "%s:%d:%d: warning: %s\n", current_filename_short, current_line, current_column, buf);
75     fflush(stderr);
76 }
77 static void dbg(const char*format, ...)
78 {
79     char buf[1024];
80     int l;
81     va_list arglist;
82     if(as3_verbosity<3)
83         return;
84     va_start(arglist, format);
85     vsprintf(buf, format, arglist);
86     va_end(arglist);
87     l = strlen(buf);
88     while(l && buf[l-1]=='\n') {
89         buf[l-1] = 0;
90         l--;
91     }
92     printf("(tokenizer) ");
93     printf("%s\n", buf);
94     fflush(stdout);
95 }
96
97
98
99 #ifndef YY_CURRENT_BUFFER
100 #define YY_CURRENT_BUFFER yy_current_buffer
101 #endif
102
103 void handleInclude(char*text, int len, char quotes)
104 {
105     char*filename = 0;
106     if(quotes) {
107         char*p1 = strchr(text, '"');
108         char*p2 = strrchr(text, '"');
109         if(!p1 || !p2 || p1==p2) {
110             syntaxerror("Invalid include in line %d\n", current_line);
111         }
112         *p2 = 0;
113         filename = strdup(p1+1);
114     } else {
115         int i1=0,i2=len;
116         // find start
117         while(!strchr(" \n\r\t", text[i1])) i1++;
118         // strip
119         while(strchr(" \n\r\t", text[i1])) i1++;
120         while(strchr(" \n\r\t", text[i2-1])) i2--;
121         if(i2!=len) text[i2]=0;
122         filename = strdup(&text[i1]);
123     }
124     
125     char*fullfilename = enter_file(filename, YY_CURRENT_BUFFER);
126     yyin = fopen(fullfilename, "rb");
127     if (!yyin) {
128         syntaxerror("Couldn't open include file \"%s\"\n", fullfilename);
129     }
130
131     yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
132     //BEGIN(INITIAL); keep context
133 }
134
135 static int do_unescape(const char*s, const char*end, char*n) 
136 {
137     char*o = n;
138     int len=0;
139     while(s<end) {
140         if(*s!='\\') {
141             if(o) o[len] = *s;len++;
142             s++;
143             continue;
144         }
145         s++; //skip past '\'
146         if(s==end) syntaxerror("invalid \\ at end of string");
147
148         /* handle the various line endings (mac, dos, unix) */
149         if(*s=='\r') { 
150             s++; 
151             if(s==end) break;
152             if(*s=='\n') 
153                 s++;
154             continue;
155         }
156         if(*s=='\n')  {
157             s++;
158             continue;
159         }
160         switch(*s) {
161             case '\\': if(o) o[len] = '\\';s++;len++; break;
162             case '"': if(o) o[len] = '"';s++;len++; break;
163             case '\'': if(o) o[len] = '\'';s++;len++; break;
164             case 'b': if(o) o[len] = '\b';s++;len++; break;
165             case 'f': if(o) o[len] = '\f';s++;len++; break;
166             case 'n': if(o) o[len] = '\n';s++;len++; break;
167             case 'r': if(o) o[len] = '\r';s++;len++; break;
168             case 't': if(o) o[len] = '\t';s++;len++; break;
169             case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
170                 unsigned int num=0;
171                 int nr = 0;
172                 while(strchr("01234567", *s) && nr<3 && s<end) {
173                     num <<= 3;
174                     num |= *s-'0';
175                     nr++;
176                     s++;
177                 }
178                 if(num>256) 
179                     syntaxerror("octal number out of range (0-255): %d", num);
180                 if(o) o[len] = num;len++;
181                 continue;
182             }
183             case 'x': case 'u': {
184                 int max=2;
185                 char bracket = 0;
186                 char unicode = 0;
187                 if(*s == 'u') {
188                     max = 6;
189                     unicode = 1;
190                 }
191                 s++;
192                 if(s==end) syntaxerror("invalid \\u or \\x at end of string");
193                 if(*s == '{')  {
194                     s++;
195                     if(s==end) syntaxerror("invalid \\u{ at end of string");
196                     bracket=1;
197                 }
198                 unsigned int num=0;
199                 int nr = 0;
200                 while(strchr("0123456789abcdefABCDEF", *s) && (bracket || nr < max) && s<end) {
201                     num <<= 4;
202                     if(*s>='0' && *s<='9') num |= *s - '0';
203                     if(*s>='a' && *s<='f') num |= *s - 'a' + 10;
204                     if(*s>='A' && *s<='F') num |= *s - 'A' + 10;
205                     nr++;
206                     s++;
207                 }
208                 if(bracket) {
209                     if(*s=='}' && s<end) {
210                         s++;
211                     } else {
212                         syntaxerror("missing terminating '}'");
213                     }
214                 }
215                 if(unicode) {
216                     char*utf8 = getUTF8(num);
217                     while(*utf8) {
218                         if(o) o[len] = *utf8;utf8++;len++;
219                     }
220                 } else {
221                     if(num>256) 
222                         syntaxerror("byte out of range (0-255): %d", num);
223                     if(o) o[len] = num;len++;
224                 }
225                 break;
226             }
227             default:
228                 syntaxerror("unknown escape sequence: \"\\%c\"", *s);
229         }
230     }
231     if(o) o[len]=0;
232     return len;
233 }
234
235 static string_t string_unescape(const char*in, int l)
236 {
237     const char*s = in;
238     const char*end = &in[l];
239
240     int len = do_unescape(s, end, 0);
241     char*n = (char*)malloc(len+1);
242     do_unescape(s, end, n);
243     string_t out = string_new(n, len);
244     return out; 
245 }
246
247 static void handleString(char*s, int len)
248 {
249     if(s[0]=='"') {
250         if(s[len-1]!='"') syntaxerror("String doesn't end with '\"'");
251         s++;len-=2;
252     }
253     else if(s[0]=='\'') {
254         if(s[len-1]!='\'') syntaxerror("String doesn't end with '\"'");
255         s++;len-=2;
256     }
257     else syntaxerror("String incorrectly terminated");
258
259     
260     avm2_lval.str = string_unescape(s, len);
261 }
262
263
264 char start_of_expression;
265
266 static inline int mkid(int type)
267 {
268     char*s = malloc(yyleng+1);
269     memcpy(s, yytext, yyleng);
270     s[yyleng]=0;
271     avm2_lval.id = s;
272     return type;
273 }
274
275 static inline int m(int type)
276 {
277     avm2_lval.token = type;
278     return type;
279 }
280
281
282 static char numberbuf[64];
283 static char*nrbuf()
284 {
285     if(yyleng>sizeof(numberbuf)-1)
286         syntaxerror("decimal number overflow");
287     char*s = numberbuf;
288     memcpy(s, yytext, yyleng);
289     s[yyleng]=0;
290     return s;
291 }
292
293 static inline int setint(int v)
294 {
295     avm2_lval.number_int = v;
296     if(v>-128)
297         return T_BYTE;
298     else if(v>=-32768)
299         return T_SHORT;
300     else
301         return T_INT;
302 }
303 static inline int setuint(unsigned int v)
304 {
305     avm2_lval.number_uint = v;
306     if(v<128)
307         return T_BYTE;
308     else if(v<32768)
309         return T_SHORT;
310     else
311         return T_UINT;
312 }
313 static inline int setfloat(double v)
314 {
315     avm2_lval.number_float = v;
316     return T_FLOAT;
317 }
318
319 static inline int handlefloat()
320 {
321     char*s = nrbuf();
322     avm2_lval.number_float = atof(s);
323     return T_FLOAT;
324 }
325
326 static inline int handleint()
327 {
328     char*s = nrbuf();
329     char l = (yytext[0]=='-');
330
331     char*max = l?"1073741824":"2147483647";
332     if(yyleng-l>10) {
333         as3_warning("integer overflow: %s (converted to Number)", s);
334         return handlefloat();
335     }
336     if(yyleng-l==10) {
337         int t;
338         for(t=0;t<yyleng-l;t++) {
339             if(yytext[l+t]>max[t]) {
340                 as3_warning("integer overflow: %s (converted to Number)", s);
341                 return handlefloat();
342             }
343             else if(yytext[l+t]<max[t])
344                 break;
345         }
346     }
347     if(yytext[0]=='-') {
348         int v = atoi(s);
349         return setint(v);
350     } else {
351         unsigned int v = 0;
352         int t;
353         for(t=0;t<yyleng;t++) {
354             v*=10;
355             v+=yytext[t]-'0';
356         }
357         return setuint(v);
358     }
359 }
360
361 static inline int handlehexfloat()
362 {
363     char l = (yytext[0]=='-')+2;
364     double d=0;
365     char dot=0;
366     double base=1;
367     int t;
368     for(t=l;t<yyleng;t++) {
369         char c = yytext[t];
370         if(c=='.') {
371             dot=1;
372             continue;
373         }
374         if(!dot) {
375             d*=16;
376         } else {
377             base*=1/16.0;
378         }
379         if(c>='0' && c<='9')
380             d+=(c&15)*base;
381         else if((c>='a' && c<='f') || (c>='A' && c<='F'))
382             d+=((c&0x0f)+9)*base;
383     }
384     return setfloat(d);
385 }
386 static inline int handlehex()
387 {
388     char l = (yytext[0]=='-')+2;
389     int len = yyleng;
390
391     if(len-l>8) {
392         char*s = nrbuf();
393         syntaxerror("integer overflow %s", s);
394     }
395
396     int t;
397     unsigned int v = 0;
398     for(t=l;t<len;t++) {
399         v<<=4;
400         char c = yytext[t];
401         if(c>='0' && c<='9')
402             v|=(c&15);
403         else if((c>='a' && c<='f') || (c>='A' && c<='F'))
404             v|=(c&0x0f)+9;
405     }
406     if(l && v>1073741824) {
407         char*s = nrbuf();
408         as3_warning("signed integer overflow: %s (converted to Number)", s);
409         return setfloat(v);
410     }
411     if(!l && v>2147483647) {
412         char*s = nrbuf();
413         as3_warning("unsigned integer overflow: %s (converted to Number)", s);
414         return setfloat(v);
415     }
416
417     if(l==3) {
418         return setint(-(int)v);
419     } else {
420         return setuint(v);
421     }
422 }
423
424 void handleLabel(char*text, int len)
425 {
426     int t;
427     for(t=len-1;t>=0;--t) {
428         if(text[t]!=' ' &&
429            text[t]!=':')
430             break;
431     }
432     char*s = malloc(t+1);
433     memcpy(s, yytext, t);
434     s[t]=0;
435     avm2_lval.id = s;
436 }
437
438 static int handleregexp()
439 {
440     char*s = malloc(yyleng);
441     int len=yyleng-1;
442     memcpy(s, yytext+1, len);
443     s[len] = 0;
444     int t;
445     for(t=len;t>=0;--t) {
446         if(s[t]=='/') {
447             s[t] = 0;
448             break;
449         }
450     }
451     avm2_lval.regexp.pattern = s;
452     if(t==len) {
453         avm2_lval.regexp.options = 0;
454     } else {
455         avm2_lval.regexp.options = s+t+1;
456     }
457     return T_REGEXP;
458 }
459
460 void initialize_scanner();
461 #define YY_USER_INIT initialize_scanner();
462
463 /* count the number of lines+columns consumed by this token */
464 static inline void l() {
465     int t;
466     for(t=0;t<yyleng;t++) {
467         if(yytext[t]=='\n') {
468             current_line++;
469             current_column=0;
470         } else {
471             current_column++;
472         }
473     }
474 }
475 /* count the number of columns consumed by this token */
476 static inline void c() {
477     current_column+=yyleng;
478 }
479
480 //Boolean                      {c();return m(KW_BOOLEAN);}
481 //int                          {c();return m(KW_INT);}
482 //uint                         {c();return m(KW_UINT);}
483 //Number                       {c();return m(KW_NUMBER);}
484
485
486 %}
487
488 %s REGEXPOK
489 %s BEGINNING
490
491 NAME     [a-zA-Z_][a-zA-Z0-9_\\]*
492 _        [^a-zA-Z0-9_\\]
493
494 HEXINT    0x[a-zA-Z0-9]+
495 HEXFLOAT  0x[a-zA-Z0-9]*\.[a-zA-Z0-9]*
496 INT       [0-9]+
497 FLOAT     [0-9]+(\.[0-9]*)?|\.[0-9]+
498
499 HEXWITHSIGN [+-]?({HEXINT})
500 HEXFLOATWITHSIGN [+-]?({HEXFLOAT})
501 INTWITHSIGN [+-]?({INT})
502 FLOATWITHSIGN [+-]?({FLOAT})
503
504 STRING   ["](\\[\x00-\xff]|[^\\"\n])*["]|['](\\[\x00-\xff]|[^\\'\n])*[']
505 S        [ \n\r\t]
506 MULTILINE_COMMENT [/][*]+([*][^/]|[^/*]|[^*][/]|[\x00-\x1f])*[*]+[/]
507 SINGLELINE_COMMENT \/\/[^\n]*\n
508 REGEXP   [/]([^/\n]|\\[/])*[/][a-zA-Z]*
509 %%
510
511
512 {SINGLELINE_COMMENT}         {l(); /* single line comment */}
513 {MULTILINE_COMMENT}          {l(); /* multi line comment */}
514 [/][*]                       {syntaxerror("syntax error: unterminated comment", yytext);}
515
516 ^include{S}+{STRING}{S}*/\n    {l();handleInclude(yytext, yyleng, 1);}
517 ^include{S}+[^" \t\r\n][\x20-\xff]*{S}*/\n    {l();handleInclude(yytext, yyleng, 0);}
518 {STRING}                     {l(); BEGIN(INITIAL);handleString(yytext, yyleng);return T_STRING;}
519
520 <BEGINNING,REGEXPOK>{
521 {REGEXP}                     {c(); BEGIN(INITIAL);return handleregexp();} 
522 {HEXWITHSIGN}                {c(); BEGIN(INITIAL);return handlehex();}
523 {HEXFLOATWITHSIGN}                {c(); BEGIN(INITIAL);return handlehexfloat();}
524 {INTWITHSIGN}                {c(); BEGIN(INITIAL);return handleint();}
525 {FLOATWITHSIGN}              {c(); BEGIN(INITIAL);return handlefloat();}
526 }
527
528 \xef\xbb\xbf                 {/* utf 8 bom */}
529 {S}                          {l();}
530
531 {HEXINT}                     {c(); BEGIN(INITIAL);return handlehex();}
532 {HEXFLOAT}                   {c(); BEGIN(INITIAL);return handlehexfloat();}
533 {INT}                        {c(); BEGIN(INITIAL);return handleint();}
534 {FLOAT}                      {c(); BEGIN(INITIAL);return handlefloat();}
535
536 3rr0r                        {/* for debugging: generates a tokenizer-level error */
537                               syntaxerror("3rr0r");}
538
539 {NAME}{S}*:{S}*for/{_}        {l();handleLabel(yytext, yyleng-3);return T_FOR;}
540 {NAME}{S}*:{S}*do/{_}         {l();handleLabel(yytext, yyleng-2);return T_DO;}
541 {NAME}{S}*:{S}*while/{_}      {l();handleLabel(yytext, yyleng-5);return T_WHILE;}
542 {NAME}{S}*:{S}*switch/{_}     {l();handleLabel(yytext, yyleng-6);return T_SWITCH;}
543 for                          {c();avm2_lval.id="";return T_FOR;}
544 do                           {c();avm2_lval.id="";return T_DO;}
545 while                        {c();avm2_lval.id="";return T_WHILE;}
546 switch                       {c();avm2_lval.id="";return T_SWITCH;}
547
548 [&][&]                       {c();BEGIN(REGEXPOK);return m(T_ANDAND);}
549 [|][|]                       {c();BEGIN(REGEXPOK);return m(T_OROR);}
550 [!][=]                       {c();BEGIN(REGEXPOK);return m(T_NE);}
551 [!][=][=]                    {c();BEGIN(REGEXPOK);return m(T_NEE);}
552 [=][=][=]                    {c();BEGIN(REGEXPOK);return m(T_EQEQEQ);}
553 [=][=]                       {c();BEGIN(REGEXPOK);return m(T_EQEQ);}
554 [>][=]                       {c();return m(T_GE);}
555 [<][=]                       {c();return m(T_LE);}
556 [-][-]                       {c();BEGIN(INITIAL);return m(T_MINUSMINUS);}
557 [+][+]                       {c();BEGIN(INITIAL);return m(T_PLUSPLUS);}
558 [+][=]                       {c();return m(T_PLUSBY);}
559 [-][=]                       {c();return m(T_MINUSBY);}
560 [/][=]                       {c();return m(T_DIVBY);}
561 [%][=]                       {c();return m(T_MODBY);}
562 [*][=]                       {c();return m(T_MULBY);}
563 [|][=]                       {c();return m(T_ORBY);}
564 [>][>][=]                    {c();return m(T_SHRBY);}
565 [<][<][=]                    {c();return m(T_SHLBY);}
566 [>][>][>][=]                 {c();return m(T_USHRBY);}
567 [<][<]                       {c();return m(T_SHL);}
568 [>][>][>]                    {c();return m(T_USHR);}
569 [>][>]                       {c();return m(T_SHR);}
570 \.\.\.                       {c();return m(T_DOTDOTDOT);}
571 \.\.                         {c();return m(T_DOTDOT);}
572 \.                           {c();return m('.');}
573 ::                           {c();return m(T_COLONCOLON);}
574 :                            {c();return m(':');}
575 instanceof                   {c();return m(KW_INSTANCEOF);}
576 implements                   {c();return m(KW_IMPLEMENTS);}
577 interface                    {c();return m(KW_INTERFACE);}
578 namespace                    {c();return m(KW_NAMESPACE);}
579 protected                    {c();return m(KW_PROTECTED);}
580 undefined                    {c();return m(KW_UNDEFINED);}
581 continue                     {c();return m(KW_CONTINUE);}
582 override                     {c();return m(KW_OVERRIDE);}
583 internal                     {c();return m(KW_INTERNAL);}
584 function                     {c();return m(KW_FUNCTION);}
585 finally                      {c();return m(KW_FINALLY);}
586 default                      {c();return m(KW_DEFAULT);}
587 package                      {c();return m(KW_PACKAGE);}
588 private                      {c();return m(KW_PRIVATE);}
589 dynamic                      {c();return m(KW_DYNAMIC);}
590 extends                      {c();return m(KW_EXTENDS);}
591 delete                       {c();return m(KW_DELETE);}
592 return                       {c();return m(KW_RETURN);}
593 public                       {c();return m(KW_PUBLIC);}
594 native                       {c();return m(KW_NATIVE);}
595 static                       {c();return m(KW_STATIC);}
596 import                       {c();return m(KW_IMPORT);}
597 typeof                       {c();return m(KW_TYPEOF);}
598 throw                        {c();return m(KW_THROW);}
599 class                        {c();return m(KW_CLASS);}
600 const                        {c();return m(KW_CONST);}
601 catch                        {c();return m(KW_CATCH);}
602 final                        {c();return m(KW_FINAL);}
603 false                        {c();return m(KW_FALSE);}
604 break                        {c();return m(KW_BREAK);}
605 super                        {c();return m(KW_SUPER);}
606 each                         {c();return m(KW_EACH);}
607 void                         {c();return m(KW_VOID);}
608 true                         {c();return m(KW_TRUE);}
609 null                         {c();return m(KW_NULL);}
610 else                         {c();return m(KW_ELSE);}
611 case                         {c();return m(KW_CASE);}
612 with                         {c();return m(KW_WITH);}
613 use                          {c();return m(KW_USE);}
614 new                          {c();return m(KW_NEW);}
615 get                          {c();return m(KW_GET);}
616 set                          {c();return m(KW_SET);}
617 var                          {c();return m(KW_VAR);}
618 try                          {c();return m(KW_TRY);}
619 is                           {c();return m(KW_IS) ;}
620 in                           {c();return m(KW_IN) ;}
621 if                           {c();return m(KW_IF) ;}
622 as                           {c();return m(KW_AS);}
623 {NAME}                       {c();BEGIN(INITIAL);return mkid(T_IDENTIFIER);}
624
625 [+-\/*^~@$!%&\(=\[\]\{\}|?:;,<>] {c();BEGIN(REGEXPOK);return m(yytext[0]);}
626 [\)\]]                           {c();BEGIN(INITIAL);return m(yytext[0]);}
627
628 .                            {char c1=yytext[0];
629                               char buf[128];
630                               buf[0] = yytext[0];
631                               int t;
632                               for(t=1;t<128;t++) {
633                                   char c = buf[t]=input();
634                                   if(c=='\n' || c==EOF)  {
635                                       buf[t] = 0;
636                                       break;
637                                   }
638                               }
639                               if(c1>='0' && c1<='9')
640                                   syntaxerror("syntax error: %s (identifiers must not start with a digit)");
641                               else
642                                   syntaxerror("syntax error: %s", buf);
643                               printf("\n");
644                               exit(1);
645                               yyterminate();
646                              }
647 <<EOF>>                      {l();
648                               void*b = leave_file();
649                               if (!b) {
650                                  yyterminate();
651                                  yy_delete_buffer(YY_CURRENT_BUFFER);
652                                  return m(T_EOF);
653                               } else {
654                                   yy_delete_buffer(YY_CURRENT_BUFFER);
655                                   yy_switch_to_buffer(b);
656                               }
657                              }
658
659 %%
660
661 int yywrap()
662 {
663     return 1;
664 }
665
666 static char mbuf[256];
667 char*token2string(enum yytokentype nr, YYSTYPE v)
668 {
669     if(nr==T_STRING)     return "<string>";
670     else if(nr==T_INT)     return "<int>";
671     else if(nr==T_UINT)     return "<uint>";
672     else if(nr==T_BYTE)     return "<byte>";
673     else if(nr==T_FLOAT)     return "<float>";
674     else if(nr==T_REGEXP)     return "REGEXP";
675     else if(nr==T_EOF)        return "***END***";
676     else if(nr==T_GE)         return ">=";
677     else if(nr==T_LE)         return "<=";
678     else if(nr==T_MINUSMINUS) return "--";
679     else if(nr==T_PLUSPLUS)   return "++";
680     else if(nr==KW_IMPLEMENTS) return "implements";
681     else if(nr==KW_INTERFACE)  return "interface";
682     else if(nr==KW_NAMESPACE)  return "namespace";
683     else if(nr==KW_PROTECTED)  return "protected";
684     else if(nr==KW_OVERRIDE)   return "override";
685     else if(nr==KW_INTERNAL)   return "internal";
686     else if(nr==KW_FUNCTION)   return "function";
687     else if(nr==KW_PACKAGE)    return "package";
688     else if(nr==KW_PRIVATE)    return "private";
689     else if(nr==KW_BOOLEAN)    return "Boolean";
690     else if(nr==KW_DYNAMIC)    return "dynamic";
691     else if(nr==KW_EXTENDS)    return "extends";
692     else if(nr==KW_PUBLIC)     return "public";
693     else if(nr==KW_NATIVE)     return "native";
694     else if(nr==KW_STATIC)     return "static";
695     else if(nr==KW_IMPORT)     return "import";
696     else if(nr==KW_NUMBER)     return "number";
697     else if(nr==KW_CLASS)      return "class";
698     else if(nr==KW_CONST)      return "const";
699     else if(nr==KW_FINAL)      return "final";
700     else if(nr==KW_FALSE)      return "False";
701     else if(nr==KW_TRUE)       return "True";
702     else if(nr==KW_UINT)       return "uint";
703     else if(nr==KW_NULL)       return "null";
704     else if(nr==KW_ELSE)       return "else";
705     else if(nr==KW_USE)        return "use";
706     else if(nr==KW_INT)        return "int";
707     else if(nr==KW_NEW)        return "new";
708     else if(nr==KW_GET)        return "get";
709     else if(nr==KW_SET)        return "set";
710     else if(nr==KW_VAR)        return "var";
711     else if(nr==KW_IS)         return "is";
712     else if(nr==KW_AS)         return "as";
713     else if(nr==T_IDENTIFIER)  return "ID";
714     else {
715         sprintf(mbuf, "%d", nr);
716         return mbuf;
717     }
718 }
719
720 void initialize_scanner()
721 {
722     BEGIN(BEGINNING);
723 }
724