convert integers to float if they're too large
[swftools.git] / lib / as3 / tokenizer.lex
index 34b13b1..d2e277c 100644 (file)
@@ -129,16 +129,13 @@ void handleInclude(char*text, int len, char quotes)
     //BEGIN(INITIAL); keep context
 }
 
-string_t string_unescape(const char*in, int l)
+static int do_unescape(const char*s, const char*end, char*n) 
 {
-    int len=0;
-    const char*s = in;
-    const char*end = &in[l];
-    char*n = (char*)malloc(l);
     char*o = n;
+    int len=0;
     while(s<end) {
         if(*s!='\\') {
-            o[len++] = *s;
+            if(o) o[len] = *s;len++;
             s++;
             continue;
         }
@@ -158,13 +155,13 @@ string_t string_unescape(const char*in, int l)
             continue;
         }
         switch(*s) {
-           case '\\': o[len++] = '\\';s++; break;
-           case '"': o[len++] = '"';s++; break;
-           case 'b': o[len++] = '\b';s++; break;
-           case 'f': o[len++] = '\f';s++; break;
-           case 'n': o[len++] = '\n';s++; break;
-           case 'r': o[len++] = '\r';s++; break;
-           case 't': o[len++] = '\t';s++; break;
+           case '\\': if(o) o[len] = '\\';s++;len++; break;
+           case '"': if(o) o[len] = '"';s++;len++; break;
+           case 'b': if(o) o[len] = '\b';s++;len++; break;
+           case 'f': if(o) o[len] = '\f';s++;len++; break;
+           case 'n': if(o) o[len] = '\n';s++;len++; break;
+           case 'r': if(o) o[len] = '\r';s++;len++; break;
+           case 't': if(o) o[len] = '\t';s++;len++; break;
             case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': {
                 unsigned int num=0;
                 int nr = 0;
@@ -176,7 +173,7 @@ string_t string_unescape(const char*in, int l)
                 }
                 if(num>256) 
                     syntaxerror("octal number out of range (0-255): %d", num);
-                o[len++] = num;
+                if(o) o[len] = num;len++;
                 continue;
             }
            case 'x': case 'u': {
@@ -214,12 +211,12 @@ string_t string_unescape(const char*in, int l)
                 if(unicode) {
                     char*utf8 = getUTF8(num);
                     while(*utf8) {
-                        o[len++] = *utf8++;
+                        if(o) o[len] = *utf8;utf8++;len++;
                     }
                 } else {
                     if(num>256) 
                         syntaxerror("byte out of range (0-255): %d", num);
-                    o[len++] = num;
+                    if(o) o[len] = num;len++;
                 }
                break;
            }
@@ -227,8 +224,19 @@ string_t string_unescape(const char*in, int l)
                 syntaxerror("unknown escape sequence: \"\\%c\"", *s);
         }
     }
+    if(o) o[len]=0;
+    return len;
+}
+
+static string_t string_unescape(const char*in, int l)
+{
+    const char*s = in;
+    const char*end = &in[l];
+
+    int len = do_unescape(s, end, 0);
+    char*n = (char*)malloc(len+1);
+    do_unescape(s, end, n);
     string_t out = string_new(n, len);
-    o[len]=0;
     return out; 
 }
 
@@ -298,6 +306,11 @@ static inline int setuint(unsigned int v)
     else
         return T_UINT;
 }
+static inline int setfloat(double v)
+{
+    avm2_lval.number_float = v;
+    return T_FLOAT;
+}
 
 static inline int handlefloat()
 {
@@ -312,8 +325,10 @@ static inline int handleint()
     char l = (yytext[0]=='-');
 
     char*max = l?"1073741824":"2147483647";
-    if(yyleng-l>10)
-        syntaxerror("integer overflow");
+    if(yyleng-l>10) {
+        warning("integer overflow: %s", s);
+        return handlefloat();
+    }
     if(yyleng-l==10) {
         int t;
         for(t=0;t<yyleng-l;t++) {
@@ -341,8 +356,11 @@ static inline int handlehex()
 {
     char l = (yytext[0]=='-')+2;
 
-    if(yyleng-l>8)
-        syntaxerror("integer overflow");
+    if(yyleng-l>8) {
+        char*s = nrbuf();
+        syntaxerror("integer overflow %s", s);
+    }
+
     int t;
     unsigned int v = 0;
     for(t=l;t<yyleng;t++) {
@@ -354,10 +372,16 @@ static inline int handlehex()
                 c>='A' && c<='F')
             v|=(c&0x0f)+9;
     }
-    if(l && v>1073741824)
-        syntaxerror("signed integer overflow");
-    if(!l && v>2147483647)
-        syntaxerror("unsigned integer overflow");
+    if(l && v>1073741824) {
+        char*s = nrbuf();
+        warning("signed integer overflow: %s", s);
+        return setfloat(v);
+    }
+    if(!l && v>2147483647) {
+        char*s = nrbuf();
+        warning("unsigned integer overflow: %s", s);
+        return setfloat(v);
+    }
 
     if(l==3) {
         return setint(-(int)v);
@@ -397,6 +421,7 @@ void initialize_scanner();
 %s BEGINNING
 
 NAME    [a-zA-Z_][a-zA-Z0-9_\\]*
+_        [^a-zA-Z0-9_\\]
 
 HEXINT    0x[a-zA-Z0-9]+
 INT       [0-9]+
@@ -439,12 +464,14 @@ REGEXP   [/]([^/\n]|\\[/])*[/][a-zA-Z]*
 3rr0r                        {/* for debugging: generates a tokenizer-level error */
                               syntaxerror("3rr0r");}
 
-{NAME}{S}*:{S}*for           {c();handleLabel(yytext, yyleng-3);return T_FOR;}
-{NAME}{S}*:{S}*do            {c();handleLabel(yytext, yyleng-2);return T_DO;}
-{NAME}{S}*:{S}*while         {c();handleLabel(yytext, yyleng-5);return T_WHILE;}
+{NAME}{S}*:{S}*for/{_}        {c();handleLabel(yytext, yyleng-3);return T_FOR;}
+{NAME}{S}*:{S}*do/{_}         {c();handleLabel(yytext, yyleng-2);return T_DO;}
+{NAME}{S}*:{S}*while/{_}      {c();handleLabel(yytext, yyleng-5);return T_WHILE;}
+{NAME}{S}*:{S}*switch/{_}     {c();handleLabel(yytext, yyleng-6);return T_SWITCH;}
 for                          {c();avm2_lval.id="";return T_FOR;}
 do                           {c();avm2_lval.id="";return T_DO;}
 while                        {c();avm2_lval.id="";return T_WHILE;}
+switch                       {c();avm2_lval.id="";return T_SWITCH;}
 
 [&][&]                       {c();BEGIN(REGEXPOK);return m(T_ANDAND);}
 [|][|]                       {c();BEGIN(REGEXPOK);return m(T_OROR);}
@@ -461,6 +488,7 @@ while                        {c();avm2_lval.id="";return T_WHILE;}
 [/][=]                       {c();return m(T_DIVBY);}
 [%][=]                       {c();return m(T_MODBY);}
 [*][=]                       {c();return m(T_MULBY);}
+[|][=]                       {c();return m(T_ORBY);}
 [>][>][=]                    {c();return m(T_SHRBY);}
 [<][<][=]                    {c();return m(T_SHLBY);}
 [>][>][>][=]                 {c();return m(T_USHRBY);}
@@ -482,6 +510,7 @@ continue                     {c();return m(KW_CONTINUE);}
 override                     {c();return m(KW_OVERRIDE);}
 internal                     {c();return m(KW_INTERNAL);}
 function                     {c();return m(KW_FUNCTION);}
+default                      {c();return m(KW_DEFAULT);}
 package                      {c();return m(KW_PACKAGE);}
 private                      {c();return m(KW_PRIVATE);}
 dynamic                      {c();return m(KW_DYNAMIC);}
@@ -493,22 +522,29 @@ native                       {c();return m(KW_NATIVE);}
 static                       {c();return m(KW_STATIC);}
 import                       {c();return m(KW_IMPORT);}
 typeof                       {c();return m(KW_TYPEOF);}
+throw                        {c();return m(KW_THROW);}
 class                        {c();return m(KW_CLASS);}
 const                        {c();return m(KW_CONST);}
+catch                        {c();return m(KW_CATCH);}
 final                        {c();return m(KW_FINAL);}
 false                        {c();return m(KW_FALSE);}
 break                        {c();return m(KW_BREAK);}
 super                        {c();return m(KW_SUPER);}
+each                         {c();return m(KW_EACH);}
 void                         {c();return m(KW_VOID);}
 true                         {c();return m(KW_TRUE);}
 null                         {c();return m(KW_NULL);}
 else                         {c();return m(KW_ELSE);}
+case                         {c();return m(KW_CASE);}
+with                         {c();return m(KW_WITH);}
 use                          {c();return m(KW_USE);}
 new                          {c();return m(KW_NEW);}
 get                          {c();return m(KW_GET);}
 set                          {c();return m(KW_SET);}
 var                          {c();return m(KW_VAR);}
+try                          {c();return m(KW_TRY);}
 is                           {c();return m(KW_IS) ;}
+in                           {c();return m(KW_IN) ;}
 if                           {c();return m(KW_IF) ;}
 as                           {c();return m(KW_AS);}
 {NAME}                       {c();BEGIN(INITIAL);return mkid(T_IDENTIFIER);}