file copied from ming 0.3alpha2
[swftools.git] / lib / action / swf4compiler.flex
diff --git a/lib/action/swf4compiler.flex b/lib/action/swf4compiler.flex
new file mode 100755 (executable)
index 0000000..6a6dddd
--- /dev/null
@@ -0,0 +1,403 @@
+%{
+
+#include <math.h>
+#include <string.h>
+
+#include "compile.h"
+#include "action.h"
+#include "blocks/error.h"
+#include "swf4compiler.tab.h" /* defines token types */
+
+static int swf4debug;
+
+static const char *lexBuffer = NULL;
+static int lexBufferLen = 0;
+
+static int  sLineNumber = 0;
+static char szLine[1024];
+static char msgbufs[2][1024] = { {0}, {0} }, *msgline = {0};
+static int  column = 0;
+
+static void comment();
+static void comment1();
+static void count();
+static void warning(char *msg);
+
+#define YY_INPUT(buf,result,max_size) result=lexBufferInput(buf, max_size)
+
+/* thanks to the prolific and brilliant Raff: */
+static int lexBufferInput(char *buf, int max_size)
+{
+  int l = lexBufferLen > max_size ? max_size : lexBufferLen;
+  
+  if (lexBufferLen <= 0)
+    return YY_NULL;
+
+  memcpy(buf, lexBuffer, l);
+  lexBuffer += l;
+  lexBufferLen -= l;
+  return l;
+}
+
+        /* very inefficient method of unescaping strings */
+static void unescape(char *buf)
+{
+  char *p, *p1;
+
+  for (p1=buf; (p=strchr(p1, '\\')) != 0; p1 = p+1) {
+    switch(p[1])
+    {
+    case 'b' : p[1] = '\b'; break;
+    case 'f' : p[1] = '\f'; break;
+    case 'n' : p[1] = '\n'; break;
+    case 'r' : p[1] = '\r'; break;
+    case 't' : p[1] = '\t'; break;
+    case 'x' :
+    case 'u' : warning("unsupported escape sequence");
+    }
+    strcpy(p, p+1);
+  }
+}
+
+void swf4ParseInit(const char *script, int debug)
+{
+  checkByteOrder();
+  yyrestart(NULL);
+
+  swf4debug = debug;
+
+  lexBuffer = script;
+  lexBufferLen = strlen(script);
+  sLineNumber = 0;
+  column = 0;
+  msgline = msgbufs[0];
+}
+
+%}
+
+%{
+ // forward declaration needed by the following function
+#ifndef YY_PROTO
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+#endif
+ static void yyunput YY_PROTO(( int c, char *buf_ptr ));
+
+ void do_unput4(const char c) { unput(c); }
+%}
+
+DIGIT    [0-9]
+ID       [a-zA-Z_][a-zA-Z0-9_]*
+LEVEL   \.\.?
+
+%%
+
+{DIGIT}+               { count();      swf4lval.str = strdup(yytext);
+                                       return NUMBER;          }
+{DIGIT}+"."{DIGIT}*    { count();      swf4lval.str = strdup(yytext);
+                                       return NUMBER;          }
+true                   { count();      swf4lval.str = strdup("1");
+                                       return NUMBER;          }
+false                  { count();      swf4lval.str = strdup("0");
+                                       return NUMBER;          }
+break                  { count();      return BREAK;           }
+continue               { count();      return CONTINUE;        }
+else                   { count();      return ELSE;            }
+for                    { count();      return FOR;             }
+if                     { count();      return IF;              }
+while                  { count();      return WHILE;           }
+do                     { count();      return DO;              }
+valueOf                        { count();      return EVAL;            }
+
+  /* functions */
+random         { count();      return RANDOM;  }
+time           { count();      return TIME;    }
+length         { count();      return LENGTH;  }
+int            { count();      return INT;     }
+concat         { count();      return CONCAT;  }
+duplicateClip  { count();      return DUPLICATECLIP;   }
+removeClip     { count();      return REMOVECLIP;      }
+trace          { count();      return TRACE;   }
+startDrag      { count();      return STARTDRAG;       }
+stopDrag       { count();      return STOPDRAG;        }
+ord            { count();      return ORD;     }
+chr            { count();      return CHR;     }
+callFrame      { count();      return CALLFRAME;       }
+getURL         { count();      return GETURL;  }
+getURL1                { count();      return GETURL1; }
+loadMovie      { count();      return LOADMOVIE;       }
+loadVariables  { count();      return LOADVARIABLES;   }
+substr         { count();      return SUBSTR;  }
+
+getProperty    { count();      return GETPROPERTY;     }
+
+  /* getURL2 methods */
+post           { count();      swf4lval.getURLMethod = GETURL_METHOD_POST;
+                               return GETURL_METHOD;   }
+get            { count();      swf4lval.getURLMethod = GETURL_METHOD_GET;
+                               return GETURL_METHOD;   }
+nosend         { count();      swf4lval.getURLMethod = GETURL_METHOD_NOSEND;
+                               return GETURL_METHOD;   }
+
+
+  /* v3 functions */
+nextFrame      { count();      return NEXTFRAME;       }
+prevFrame      { count();      return PREVFRAME;       }
+play           { count();      return PLAY;            }
+stop           { count();      return STOP;            }
+toggleQuality  { count();      return TOGGLEQUALITY;   }
+stopSounds     { count();      return STOPSOUNDS;      }
+gotoFrame      { count();      return GOTOFRAME;       }
+gotoAndPlay    { count();      return GOTOANDPLAY;     }
+frameLoaded    { count();      return FRAMELOADED;     }
+setTarget      { count();      return SETTARGET;       }
+
+  /* high level functions */
+tellTarget     { count();      return TELLTARGET;      }
+
+
+this                   { count();      return THIS;    }
+
+{ID}                   { count();      swf4lval.str = strdup(yytext);
+                                       return IDENTIFIER;      }
+
+{LEVEL}?("/"({ID}|{LEVEL}))+ { count();        swf4lval.str = strdup(yytext);
+                                       return PATH;    }
+                    
+{ID}("/"({ID}|{LEVEL}))+ { count();    swf4lval.str = strdup(yytext);
+                                       return PATH;    }
+
+\"(\\.|[^\\"])*\"      { count();      swf4lval.str = strdup(yytext+1);
+                                       swf4lval.str[strlen(swf4lval.str)-1]=0;
+                                        unescape(swf4lval.str);
+                                       return STRING;          }
+
+\'(\\.|[^\\'])*\'      { count();      swf4lval.str = strdup(yytext+1);
+                                       swf4lval.str[strlen(swf4lval.str)-1]=0;
+                                        unescape(swf4lval.str);
+                                       return STRING;          }
+
+\"(\\.|[^\\"])*$       { count();      swf4lval.str = strdup("");
+                                       warning("Unterminated string!");
+                                       return STRING;          }
+
+\'(\\.|[^\\'])*$       { count();      swf4lval.str = strdup("");
+                                       warning("Unterminated string!");
+                                       return STRING;          }
+
+"/*"                   { count();      comment();              }
+"//"                   { count();      comment1();             }
+[ \t\v\f]              { count(); }
+
+"++"                   { count();      return INC; }
+"--"                   { count();      return DEC; }
+"<"                    { count();      return '<'; }
+">"                    { count();      return '>'; }
+"<="                   { count();      return LE; }
+">="                   { count();      return GE; }
+"=="                   { count();      return EQ; }
+"!="                   { count();      return NE; }
+"&&"                   { count();      return LAN; }
+"||"                   { count();      return LOR; }
+"*="                   { count();      return MEQ; }
+"/="                   { count();      return DEQ; }
+"+="                   { count();      return IEQ; }
+"-="                   { count();      return SEQ; }
+"==="                  { count();      return STREQ; }
+"!=="                  { count();      return STRNE; }
+"<=>"                  { count();      return STRCMP; }
+".."                   { count();      return PARENT; }
+
+";"                    { count();      return ';'; }
+"="                    { count();      return '='; }
+"+"                    { count();      return '+'; }
+"-"                    { count();      return '-'; }
+"&"                    { count();      return '&'; }
+"*"                    { count();      return '*'; }
+"/"                    { count();      return '/'; }
+"!"                    { count();      return '!'; }
+"("                    { count();      return '('; }
+")"                    { count();      return ')'; }
+"["                    { count();      return '['; }
+"]"                    { count();      return ']'; }
+"{"                    { count();      return '{'; }
+"}"                    { count();      return '}'; }
+","                    { count();      return ','; }
+"."                    { count();      return '.'; }
+"?"                    { count();      return '?'; }
+":"                    { count();      return ':'; }
+
+\r?\n                  { count();      column = 0;
+                                       strcpy(szLine, yytext + 1);
+                                       ++sLineNumber;  yyless(1);      }
+
+.                      printf( "Unrecognized character: %s\n", yytext );
+
+%%
+static int getinput() {
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+}
+
+int swf4wrap()
+{
+  return 1;
+}
+
+static void countline()
+{
+  if(sLineNumber != 0)
+    msgline[column] = 0;
+
+  ++sLineNumber;
+  column = 0;
+  msgline = msgbufs[sLineNumber & 1];
+}
+
+static int LineNumber(void)
+{
+   return (sLineNumber + 1);
+}
+
+static int ColumnNumber(void)
+{
+   return column;
+}
+
+static char *LineText(void)
+{
+  msgline[column] = 0;
+  return msgline;
+}
+
+static void comment(void)
+{
+   // Handle block comments
+
+   int c, c1;
+
+loop:
+   // We have the start of a comment so look skip everything up to the
+   // end of the comment character
+   while ((c = getinput()) != '*' && c != EOF)
+   {
+      if(column < 1023)
+         msgline[column] = c;
+
+      ++column;
+
+      // keep the line number in synch
+      if (c == '\n')
+      {
+         // start the output (matches the algorithim in the lexx above)
+        countline();
+      }
+
+      if (swf4debug) putchar(c);
+   }
+
+   // is this the end of comment character
+   if ((c1 = getinput()) != '/' && c != EOF)
+   {
+      // false start as this was no end of comment
+      do_unput4(c1);
+      goto loop;
+   }
+
+   // write out the start of the end of comment
+   if (c != EOF)
+      if (swf4debug) putchar(c);
+
+   // write out the end of the end of comment
+   if (c1 != EOF) 
+      if (swf4debug) putchar(c1);
+}
+
+static void comment1(void)
+{
+   // Handle comment of type 1 (ie '//')
+
+   int c;
+
+   // this is a line comment
+   while ((c = getinput()) != '\n' && c != EOF)
+   {
+      if (swf4debug) putchar(c);
+
+      if(column < 1023)
+         msgline[column] = c;
+
+      ++column;
+   };
+
+   // keep the line number in synch
+   if (c == '\n')
+   {
+      if (swf4debug) putchar(c);
+
+      countline();
+   }
+}
+
+static void count(void)
+{
+   int n;
+
+   // Count the characters to maintain the current column position
+   if (yytext[0] == '\n')
+   {
+      if (swf4debug) printf("\n");
+   }
+   else
+   {
+      if (swf4debug) printf("%s", yytext);
+
+      for(n=0; n<yyleng; ++n, ++column)
+      {
+       if(column < 1023)
+         msgline[column] = yytext[n];
+      }
+
+      //-- keep writing the stuff to standard output
+      //column += yyleng;
+   }
+}
+
+static void printprog()
+{
+  if(sLineNumber)
+    SWF_warn("\n%s", msgbufs[(sLineNumber-1)&1]);
+
+  if(column < 1023)
+    msgline[column] = 0;
+
+  SWF_warn("\n%s", msgline);
+}
+
+static void warning(char *msg)
+{
+   // print a warning message
+   printprog();
+   SWF_warn("\n%*s", ColumnNumber(), "^");
+   SWF_warn("\nLine %4.4d:  Reason: '%s' \n", LineNumber(), msg);
+}
+
+void swf4error(char *msg)
+{
+  // report a error
+  if(strlen(yytext))
+  {
+    SWF_error("\n%s\n%*s\nLine %i:  Reason: '%s'\n",
+             LineText(), ColumnNumber(), "^", LineNumber(), msg);
+  }
+  else
+  {
+    SWF_error("\nLine %d: Reason: 'Unexpected EOF found while looking for input.'\n", LineNumber());
+  }
+}