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