1%{ 2 3#include <math.h> 4#include <string.h> 5#include <stdlib.h> 6 7#include "compile.h" 8#include "actiontypes.h" 9#include "blocks/error.h" 10#include "swf4compiler.tab.h" /* defines token types */ 11 12int swf4debug; 13 14static const char *lexBuffer = NULL; 15static int lexBufferLen = 0; 16 17static int sLineNumber = 0; 18static char szLine[1024]; 19static char msgbufs[2][1024] = { {0}, {0} }, *msgline = {0}; 20static int column = 0; 21 22static void comment(); 23static void comment1(); 24static void count(); 25static void warning(char *msg); 26 27#define YY_INPUT(buf,result,max_size) result=lexBufferInput(buf, max_size) 28#define YY_NO_UNISTD_H 29#define YY_USE_PROTOS 30 31/* thanks to the prolific and brilliant Raff: */ 32static int lexBufferInput(char *buf, int max_size) 33{ 34 int l = lexBufferLen > max_size ? max_size : lexBufferLen; 35 36 if (lexBufferLen <= 0) 37 return YY_NULL; 38 39 memcpy(buf, lexBuffer, l); 40 lexBuffer += l; 41 lexBufferLen -= l; 42 return l; 43} 44 45static void unescape(char *buf) 46{ 47 char *r, *w; 48 49 r=buf; // read 50 w=buf; // write 51 while (*r) 52 { 53 if ( *r == '\\' ) 54 { 55 r++; 56 switch(*r) 57 { 58 case 'b' : *w = '\b'; break; 59 case 'f' : *w = '\f'; break; 60 case 'n' : *w = '\n'; break; 61 case 'r' : *w = '\r'; break; 62 case 't' : *w = '\t'; break; 63 case 'x' : 64 case 'u' : fprintf(stderr,"unsupported escape sequence\n"); 65 } 66 w++; 67 r++; 68 } 69 else 70 { 71 *w++ = *r++; 72 } 73 } 74 *w='\0'; 75} 76 77void swf4ParseInit(const char *script, int debug, int version) 78{ 79 yyrestart(NULL); 80 81 swf4debug = debug; 82 83 lexBuffer = script; 84 lexBufferLen = strlen(script); 85 sLineNumber = 0; 86 column = 0; 87 msgline = msgbufs[0]; 88 swfVersion = version; 89} 90 91%} 92%option never-interactive 93%s asm 94 95%{ 96 // forward declaration needed by the following function 97#ifndef YY_PROTO 98#ifdef YY_USE_PROTOS 99#define YY_PROTO(proto) proto 100#else 101#define YY_PROTO(proto) () 102#endif 103#endif 104 static void yyunput YY_PROTO(( int c, char *buf_ptr )); 105 106 void do_unput4(const char c) { unput(c); } 107%} 108 109DIGIT [0-9] 110ID [$a-zA-Z_][$a-zA-Z0-9_]* 111LEVEL \.\.? 112 113%% 114 115{DIGIT}+ { count(); swf4lval.str = strdup(yytext); 116 return NUMBER; } 117{DIGIT}+"."{DIGIT}* { count(); swf4lval.str = strdup(yytext); 118 return NUMBER; } 119true { count(); swf4lval.str = strdup("1"); 120 return NUMBER; } 121false { count(); swf4lval.str = strdup("0"); 122 return NUMBER; } 123break { count(); return BREAK; } 124continue { count(); return CONTINUE; } 125else { count(); return ELSE; } 126for { count(); return FOR; } 127if { count(); return IF; } 128while { count(); return WHILE; } 129do { count(); return DO; } 130valueOf { count(); return EVAL; } 131 132 /* functions */ 133random { count(); return RANDOM; } 134time { count(); return TIME; } 135length { count(); return LENGTH; } 136int { count(); return INT; } 137concat { count(); return CONCAT; } 138duplicateClip { count(); return DUPLICATECLIP; } 139removeClip { count(); return REMOVECLIP; } 140trace { count(); return TRACE; } 141startDrag { count(); return STARTDRAG; } 142stopDrag { count(); return STOPDRAG; } 143ord { count(); return ORD; } 144chr { count(); return CHR; } 145callFrame { count(); return CALLFRAME; } 146get[uU][rR][lL] { count(); return GETURL; } 147get[uU][rR][lL]1 { count(); return GETURL1; } 148loadMovie { count(); return LOADMOVIE; } 149loadMovieNum { count(); return LOADMOVIENUM; } 150loadVariables { count(); return LOADVARIABLES; } 151substr { count(); return SUBSTR; } 152 153getProperty { count(); return GETPROPERTY; } 154 155 /* v3 functions */ 156nextFrame { count(); return NEXTFRAME; } 157prevFrame { count(); return PREVFRAME; } 158play { count(); return PLAY; } 159stop { count(); return STOP; } 160toggleQuality { count(); return TOGGLEQUALITY; } 161stopSounds { count(); return STOPSOUNDS; } 162gotoFrame { count(); return GOTOFRAME; } 163gotoAndPlay { count(); return GOTOANDPLAY; } 164frameLoaded { count(); return FRAMELOADED; } 165setTarget { count(); return SETTARGET; } 166 167 /* high level functions */ 168tellTarget { count(); return TELLTARGET; } 169 170 171this { count(); return THIS; } 172 173asm { count(); BEGIN(asm); return ASM; } 174 175 /* assembler v4 ops */ 176<asm>{ 177add { count(); return ASMADD; } 178substract { count(); return ASMSUBSTRACT; } 179divide { count(); return ASMDIVIDE; } 180multiply { count(); return ASMMULTIPLY; } 181equals { count(); return ASMEQUALS; } 182less { count(); return ASMLESS; } 183logicaland { count(); return ASMLOGICALAND; } 184logicalor { count(); return ASMLOGICALOR; } 185logicalnot { count(); return ASMLOGICALNOT; } 186stringand { count(); return ASMSTRINGAND; } 187stringequals { count(); return ASMSTRINGEQUALS; } 188stringextract { count(); return ASMSTRINGEXTRACT; } 189stringlength { count(); return ASMSTRINGLENGTH; } 190mbstringextract { count(); return ASMMBSTRINGEXTRACT; } 191mbstringlength { count(); return ASMMBSTRINGLENGTH; } 192stringless { count(); return ASMSTRINGLESS; } 193pop { count(); return ASMPOP; } 194push { count(); return ASMPUSH; } 195asciitochar { count(); return ASMASCIITOCHAR; } 196chartoascii { count(); return ASMCHARTOASCII; } 197tointeger { count(); return ASMTOINTEGER; } 198mbasciitochar { count(); return ASMMBASCIITOCHAR; } 199mbchartoascii { count(); return ASMMBCHARTOASCII; } 200call { count(); return ASMCALL; } 201asmif { count(); return ASMIF; } 202jump { count(); return ASMJUMP; } 203getvariable { count(); return ASMGETVARIABLE; } 204setvariable { count(); return ASMSETVARIABLE; } 205geturl2 { count(); return ASMGETURL2; } 206getproperty { count(); return ASMGETPROPERTY; } 207gotoframe2 { count(); return ASMGOTOFRAME2; } 208removesprite { count(); return ASMREMOVESPRITE; } 209setproperty { count(); return ASMSETPROPERTY; } 210settarget2 { count(); return ASMSETTARGET2; } 211startdrag { count(); return ASMSTARTDRAG; } 212waitforframe2 { count(); return ASMWAITFORFRAME2; } 213clonesprite { count(); return ASMCLONESPRITE; } 214enddrag { count(); return ASMENDDRAG; } 215gettime { count(); return ASMGETTIME; } 216randomnumber { count(); return ASMRANDOMNUMBER; } 217asmtrace { count(); return ASMTRACE; } 218} 219 220{ID} { count(); swf4lval.str = strdup(yytext); 221 return IDENTIFIER; } 222 223{LEVEL}?("/"({ID}|{LEVEL}))+ { count(); swf4lval.str = strdup(yytext); 224 return PATH; } 225 226{ID}("/"({ID}|{LEVEL}))+ { count(); swf4lval.str = strdup(yytext); 227 return PATH; } 228 229\"(\\.|[^\\"])*\" { count(); swf4lval.str = strdup(yytext+1); 230 swf4lval.str[strlen(swf4lval.str)-1]=0; 231 unescape(swf4lval.str); 232 return STRING; } 233 234\'(\\.|[^\\'])*\' { count(); swf4lval.str = strdup(yytext+1); 235 swf4lval.str[strlen(swf4lval.str)-1]=0; 236 unescape(swf4lval.str); 237 return STRING; } 238 239\"(\\.|[^\\"])*$ { count(); swf4lval.str = NULL; 240 warning("Unterminated string!"); 241 return BROKENSTRING; } 242 243\'(\\.|[^\\'])*$ { count(); swf4lval.str = NULL; 244 warning("Unterminated string!"); 245 return BROKENSTRING; } 246 247"/*" { count(); comment(); } 248"//" { count(); comment1(); } 249[ \t\v\f] { count(); } 250 251"++" { count(); return INC; } 252"--" { count(); return DEC; } 253"<" { count(); return '<'; } 254">" { count(); return '>'; } 255"<=" { count(); return LE; } 256">=" { count(); return GE; } 257"==" { count(); return EQ; } 258"!=" { count(); return NE; } 259"&&" { count(); return LAN; } 260"||" { count(); return LOR; } 261"*=" { count(); return MEQ; } 262"/=" { count(); return DEQ; } 263"+=" { count(); return IEQ; } 264"-=" { count(); return SEQ; } 265"===" { count(); return STREQ; } 266"!==" { count(); return STRNE; } 267"<=>" { count(); return STRCMP; } 268".." { count(); return PARENT; } 269 270";" { count(); return ';'; } 271"=" { count(); return '='; } 272"+" { count(); return '+'; } 273"-" { count(); return '-'; } 274"&" { count(); return '&'; } 275"*" { count(); return '*'; } 276"/" { count(); return '/'; } 277"!" { count(); return '!'; } 278"(" { count(); return '('; } 279")" { count(); return ')'; } 280"[" { count(); return '['; } 281"]" { count(); return ']'; } 282"{" { count(); return '{'; } 283"}" { count(); return '}'; } 284"," { count(); return ','; } 285"." { count(); return '.'; } 286"?" { count(); return '?'; } 287":" { count(); return ':'; } 288 289\r?\n { count(); column = 0; 290 strcpy(szLine, yytext + 1); 291 ++sLineNumber; yyless(1); } 292 293. printf( "Unrecognized character: %s\n", yytext ); 294 295%% 296static int getinput() { 297#ifdef __cplusplus 298 return yyinput(); 299#else 300 return input(); 301#endif 302} 303 304int swf4wrap() 305{ 306 return 1; 307} 308 309static void countline() 310{ 311 if(sLineNumber != 0) 312 msgline[column] = 0; 313 314 ++sLineNumber; 315 column = 0; 316 msgline = msgbufs[sLineNumber & 1]; 317} 318 319static int LineNumber(void) 320{ 321 return (sLineNumber + 1); 322} 323 324static int ColumnNumber(void) 325{ 326 return column; 327} 328 329static char *LineText(void) 330{ 331 msgline[column] = 0; 332 return msgline; 333} 334 335static void comment(void) 336{ 337 // Handle block comments 338 339 int c, c1; 340 341loop: 342 // We have the start of a comment so look skip everything up to the 343 // end of the comment character 344 while ((c = getinput()) != '*' && c != EOF) 345 { 346 if(column < 1023) 347 msgline[column] = c; 348 349 ++column; 350 351 // keep the line number in synch 352 if (c == '\n') 353 { 354 // start the output (matches the algorithim in the lexx above) 355 countline(); 356 } 357 358 if (swf4debug) putchar(c); 359 } 360 361 // is this the end of comment character 362 if ((c1 = getinput()) != '/' && c != EOF) 363 { 364 // false start as this was no end of comment 365 do_unput4(c1); 366 goto loop; 367 } 368 369 // write out the start of the end of comment 370 if (c != EOF) 371 if (swf4debug) putchar(c); 372 373 // write out the end of the end of comment 374 if (c1 != EOF) 375 if (swf4debug) putchar(c1); 376} 377 378static void comment1(void) 379{ 380 // Handle comment of type 1 (ie '//') 381 382 int c; 383 384 // this is a line comment 385 while ((c = getinput()) != '\n' && c != EOF) 386 { 387 if (swf4debug) putchar(c); 388 389 if(column < 1023) 390 msgline[column] = c; 391 392 ++column; 393 }; 394 395 // keep the line number in synch 396 if (c == '\n') 397 { 398 if (swf4debug) putchar(c); 399 400 countline(); 401 } 402} 403 404static void count(void) 405{ 406 int n; 407 408 // Count the characters to maintain the current column position 409 if (yytext[0] == '\n') 410 { 411 if (swf4debug) printf("\n"); 412 } 413 else 414 { 415 if (swf4debug) printf("%s", yytext); 416 417 for(n=0; n<yyleng; ++n, ++column) 418 { 419 if(column < 1023) 420 msgline[column] = yytext[n]; 421 } 422 423 //-- keep writing the stuff to standard output 424 //column += yyleng; 425 } 426} 427 428static void printprog() 429{ 430 if(sLineNumber) 431 SWF_warn("\n%s", msgbufs[(sLineNumber-1)&1]); 432 433 if(column < 1023) 434 msgline[column] = 0; 435 436 SWF_warn("\n%s", msgline); 437} 438 439static void warning(char *msg) 440{ 441 // print a warning message 442 printprog(); 443 SWF_warn("\n%*s", ColumnNumber(), "^"); 444 SWF_warn("\nLine %4.4d: Reason: '%s' \n", LineNumber(), msg); 445} 446 447void swf4error(char *msg) 448{ 449 // report a error 450 if(strlen(yytext)) 451 { 452 SWF_error("\n%s\n%*s\nLine %i: Reason: '%s'\n", 453 LineText(), ColumnNumber(), "^", LineNumber(), msg); 454 } 455 else 456 { 457 SWF_error("\nLine %d: Reason: 'Unexpected EOF found while looking for input.'\n", LineNumber()); 458 } 459} 460