Remove all references to the GC library, replacing GC_malloc
[fw/sdcc] / src / SDCC.lex
1 /*-----------------------------------------------------------------------
2   SDCC.lex - lexical analyser for use with sdcc ( a freeware compiler for
3   8/16 bit microcontrollers)
4   Written by : Sandeep Dutta . sandeep.dutta@usa.net (1997)
5   
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     
20    In other words, you are welcome to use, share and improve this program.
21    You are forbidden to forbid anyone else to use, share and improve
22    what you give them.   Help stamp out software-hoarding!  
23 -------------------------------------------------------------------------*/
24
25 D        [0-9]
26 L        [a-zA-Z_]
27 H        [a-fA-F0-9]
28 E        [Ee][+-]?{D}+
29 FS       (f|F|l|L)
30 IS       (u|U|l|L)*
31 %{
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include "common.h"
37     
38 char *stringLiteral();
39 char *currFname;
40
41 extern int lineno                       ;
42 extern char *filename ;
43 extern char *fullSrcFileName ;
44 int   yylineno = 1               ;
45 void count()                     ;
46 void comment();
47 int process_pragma(char *);
48 #undef yywrap
49
50 int yywrap YY_PROTO((void))
51 {
52    return(1);
53 }
54 #define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
55                                 check_type(yytext))
56 char asmbuff[MAX_INLINEASM]                     ;
57 char *asmp ;
58 extern int check_type           ();
59  extern int isTargetKeyword     ();
60 extern int checkCurrFile        (char *);
61 extern int processPragma        (char *);
62 extern int printListing         (int   );
63 struct optimize save_optimize ;
64 struct options  save_options  ;
65
66  enum {
67      P_SAVE = 1,
68      P_RESTORE ,
69      P_NOINDUCTION,
70      P_NOINVARIANT,
71      P_INDUCTION ,
72      P_STACKAUTO ,
73      P_NOJTBOUND ,
74      P_NOOVERLAY ,
75      P_NOGCSE    ,
76      P_CALLEE_SAVES,
77      P_EXCLUDE   ,
78      P_LOOPREV
79  };
80
81 %}
82 %x asm
83 %%
84 "_asm"        {  count(); asmp = asmbuff ;BEGIN(asm) ;}
85 <asm>"_endasm" { count()                ; 
86                   *asmp = '\0'                          ; 
87                   strcpy(yylval.yyinline,asmbuff)               ; 
88                   BEGIN(INITIAL)        ;
89                   return (INLINEASM)                    ; }
90 <asm>.         { *asmp++ = yytext[0]    ; }
91 <asm>\n        { count(); *asmp++ = '\n' ;}
92 "/*"           { comment(); }
93 "at"           { count(); TKEYWORD(AT)  ; }
94 "auto"         { count(); return(AUTO); }
95 "bit"          { count(); TKEYWORD(BIT) ; }
96 "break"        { count(); return(BREAK); }
97 "case"         { count(); return(CASE); }
98 "char"         { count(); return(CHAR); }
99 "code"         { count(); TKEYWORD(CODE); }
100 "const"        { count(); return(CONST); }
101 "continue"     { count(); return(CONTINUE); }
102 "critical"     { count(); TKEYWORD(CRITICAL); } 
103 "data"         { count(); TKEYWORD(DATA);   }
104 "default"      { count(); return(DEFAULT); }
105 "do"           { count(); return(DO); }
106 "double"       { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
107 "else"         { count(); return(ELSE); }
108 "enum"         { count(); return(ENUM); }
109 "extern"       { count(); return(EXTERN); }
110 "far"          { count(); TKEYWORD(XDATA);  }
111 "eeprom"       { count(); TKEYWORD(EEPROM);  }
112 "float"        { count(); return(FLOAT); }
113 "flash"        { count(); TKEYWORD(CODE);}
114 "for"          { count(); return(FOR); }
115 "goto"         { count(); return(GOTO); }
116 "idata"        { count(); TKEYWORD(IDATA);}
117 "if"           { count(); return(IF); }
118 "int"          { count(); return(INT); }
119 "interrupt"    { count(); return(INTERRUPT);}
120 "nonbanked"    { count(); TKEYWORD(NONBANKED);}
121 "banked"       { count(); TKEYWORD(BANKED);}
122 "long"         { count(); return(LONG); }
123 "near"         { count(); TKEYWORD(DATA);}
124 "pdata"        { count(); TKEYWORD(PDATA); }
125 "reentrant"    { count(); TKEYWORD(REENTRANT);}
126 "register"     { count(); return(REGISTER); }
127 "return"       { count(); return(RETURN); }
128 "sfr"          { count(); TKEYWORD(SFR) ; }
129 "sbit"         { count(); TKEYWORD(SBIT)        ; }
130 "short"        { count(); return(SHORT); }
131 "signed"       { count(); return(SIGNED); }
132 "sizeof"       { count(); return(SIZEOF); }
133 "sram"         { count(); TKEYWORD(XDATA);}
134 "static"       { count(); return(STATIC); }
135 "struct"       { count(); return(STRUCT); }
136 "switch"       { count(); return(SWITCH); }
137 "typedef"      { count(); return(TYPEDEF); }
138 "union"        { count(); return(UNION); }
139 "unsigned"     { count(); return(UNSIGNED); }
140 "void"         { count(); return(VOID); }
141 "volatile"     { count(); return(VOLATILE); }
142 "using"        { count(); TKEYWORD(USING); }
143 "while"        { count(); return(WHILE); }
144 "xdata"        { count(); TKEYWORD(XDATA); }
145 "_data"        { count(); TKEYWORD(_NEAR); }
146 "_code"        { count(); TKEYWORD(_CODE); }
147 "_eeprom"      { count(); TKEYWORD(_EEPROM); }
148 "_flash"       { count(); TKEYWORD(_CODE); }
149 "_generic"     { count(); TKEYWORD(_GENERIC); }
150 "_near"        { count(); TKEYWORD(_NEAR); }
151 "_sram"        { count(); TKEYWORD(_XDATA);}
152 "_xdata"       { count(); TKEYWORD(_XDATA);}
153 "_pdata"       { count(); TKEYWORD(_PDATA); }
154 "_idata"       { count(); TKEYWORD(_IDATA); }
155 "..."          { count(); return(VAR_ARGS);}
156 {L}({L}|{D})*  { count(); return(check_type()); }
157 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
158 0{D}+{IS}?     { count(); yylval.val = constVal(yytext); return(CONSTANT); }
159 {D}+{IS}?      { count(); yylval.val = constVal(yytext); return(CONSTANT); }
160 '(\\.|[^\\'])+' { count();yylval.val = charVal (yytext); return(CONSTANT); }
161 {D}+{E}{FS}?   { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
162 {D}*"."{D}+({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
163 {D}+"."{D}*({E})?{FS}?  { count(); yylval.val = constFloatVal(yytext);return(CONSTANT); }
164 \"             { count(); yylval.val=strVal(stringLiteral()); return(STRING_LITERAL);}
165 ">>=" { count(); yylval.yyint = RIGHT_ASSIGN ; return(RIGHT_ASSIGN); }
166 "<<=" { count(); yylval.yyint = LEFT_ASSIGN  ; return(LEFT_ASSIGN) ; }
167 "+="  { count(); yylval.yyint = ADD_ASSIGN   ; return(ADD_ASSIGN)  ; }
168 "-="  { count(); yylval.yyint = SUB_ASSIGN   ; return(SUB_ASSIGN)  ; }
169 "*="  { count(); yylval.yyint = MUL_ASSIGN   ; return(MUL_ASSIGN)  ; }
170 "/="  { count(); yylval.yyint = DIV_ASSIGN   ; return(DIV_ASSIGN)  ; }
171 "%="  { count(); yylval.yyint = MOD_ASSIGN   ; return(MOD_ASSIGN)  ; }
172 "&="  { count(); yylval.yyint = AND_ASSIGN   ; return(AND_ASSIGN)  ; }
173 "^="  { count(); yylval.yyint = XOR_ASSIGN   ; return(XOR_ASSIGN)  ; }
174 "|="  { count(); yylval.yyint = OR_ASSIGN    ; return(OR_ASSIGN)   ; }
175 ">>"           { count(); return(RIGHT_OP); }
176 "<<"           { count(); return(LEFT_OP); }
177 "++"           { count(); return(INC_OP); }
178 "--"           { count(); return(DEC_OP); }
179 "->"           { count(); return(PTR_OP); }
180 "&&"           { count(); return(AND_OP); }
181 "||"           { count(); return(OR_OP); }
182 "<="           { count(); return(LE_OP); }
183 ">="           { count(); return(GE_OP); }
184 "=="           { count(); return(EQ_OP); }
185 "!="           { count(); return(NE_OP); }
186 ";"            { count(); return(';'); }
187 "{"            { count(); NestLevel++ ;  return('{'); }
188 "}"            { count(); NestLevel--; return('}'); }
189 ","            { count(); return(','); }
190 ":"            { count(); return(':'); }
191 "="            { count(); return('='); }
192 "("            { count(); return('('); }
193 ")"            { count(); return(')'); }
194 "["            { count(); return('['); }
195 "]"            { count(); return(']'); }
196 "."            { count(); return('.'); }
197 "&"            { count(); return('&'); }
198 "!"            { count(); return('!'); }
199 "~"            { count(); return('~'); }
200 "-"            { count(); return('-'); }
201 "+"            { count(); return('+'); }
202 "*"            { count(); return('*'); }
203 "/"            { count(); return('/'); }
204 "%"            { count(); return('%'); }
205 "<"            { count(); return('<'); }
206 ">"            { count(); return('>'); }
207 "^"            { count(); return('^'); }
208 "|"            { count(); return('|'); }
209 "?"            { count(); return('?'); }
210 ^#line.*"\n"       { count(); checkCurrFile(yytext); }
211 ^#pragma.*"\n"   { count(); process_pragma(yytext); }
212
213 ^[^(]+"("[0-9]+") : error"[^\n]+ { werror(E_PRE_PROC_FAILED,yytext);count(); }
214 ^[^(]+"("[0-9]+") : warning"[^\n]+ { werror(W_PRE_PROC_WARNING,yytext);count(); }
215 "\r\n"             { count(); }
216 "\n"               { count(); }
217 [ \t\v\f]      { count(); }
218 .                          { count()    ; }
219 %%
220    
221 int checkCurrFile ( char *s)
222 {
223     char lineNum[10]                    ;
224     int  lNum                           ;
225     char *tptr                          ;
226        
227     /* first check if this is a #line */
228     if ( strncmp(s,"#line",5) )
229         return  0                               ;
230     
231     /* get to the line number */
232     while (!isdigit(*s))
233         s++ ;
234     tptr = lineNum ;
235     while (isdigit(*s))
236         *tptr++ = *s++ ;
237     *tptr = '\0'; 
238     sscanf(lineNum,"%d",&lNum);
239     
240     /* now see if we have a file name */
241     while (*s != '\"' && *s) 
242         s++ ;
243     
244     /* if we don't have a filename then */
245     /* set the current line number to   */
246     /* line number if printFlag is on   */
247     if (!*s) {          
248         yylineno = lNum ;
249         return 0;
250     }
251     
252     /* if we have a filename then check */
253     /* if it is "standard in" if yes then */
254     /* get the currentfile name info    */
255     s++ ;
256
257     if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
258             yylineno = lNum - 2;                                        
259             currFname = fullSrcFileName ;
260     }  else {
261         char *sb = s;
262         /* mark the end of the filename */
263         while (*s != '"') s++;
264         *s = '\0';
265         ALLOC(currFname,strlen(sb)+1);
266         strcpy(currFname,sb);
267         yylineno = lNum - 2;
268     }
269     filename = currFname ;
270     return 0;
271 }
272     
273 void comment()
274 {
275         char c, c1;
276
277 loop:
278         while ((c = input()) != '*' && c != 0)
279                 if ( c == '\n')
280                         yylineno++ ;
281
282         if ((c1 = input()) != '/' && c != 0)  {
283                 if ( c1 == '\n' )
284                         yylineno++ ;
285
286                 unput(c1);
287                 goto loop;
288    }
289
290 }
291    
292    
293
294 int column = 0;
295 int plineIdx=0;
296
297 void count()
298 {
299         int i;
300         for (i = 0; yytext[i] != '\0'; i++)   {                         
301                 if (yytext[i] == '\n')      {         
302                    column = 0;
303                    lineno = ++yylineno ;
304                 }
305                 else 
306                         if (yytext[i] == '\t')
307                                 column += 8 - (column % 8);
308                         else
309                                 column++;
310    }
311          
312    /* ECHO; */
313 }
314
315 int check_type()
316 {
317         /* check if it is in the typedef table */
318         if (findSym(TypedefTab,NULL,yytext)) {
319                 strcpy(yylval.yychar,yytext);
320                 return (TYPE_NAME) ;
321         }
322         else   {
323                 strcpy (yylval.yychar,yytext);
324                 return(IDENTIFIER);
325         }
326 }
327
328 char strLitBuff[2048]                   ;
329
330 char *stringLiteral ()
331 {
332        int ch;
333        char *str = strLitBuff                   ;
334        
335        *str++ = '\"'                    ;
336        /* put into the buffer till we hit the */
337        /* first \" */
338        while (1) {
339
340           ch = input()                  ;
341           if (!ch)          break       ; /* end of input */
342           /* if it is a \ then everything allowed */
343           if (ch == '\\') {
344              *str++ = ch     ; /* backslash in place */
345              *str++ = input()           ; /* following char in place */
346              continue                   ;      /* carry on */
347              }
348              
349          /* if new line we have a new line break */
350          if (ch == '\n') break          ;
351          
352          /* if this is a quote then we have work to do */
353          /* find the next non whitespace character     */
354          /* if that is a double quote then carry on    */
355          if (ch == '\"') {
356          
357              while ((ch = input()) && isspace(ch)) ;
358              if (!ch) break             ; 
359              if (ch != '\"') {
360                   unput(ch)                     ;
361                   break                 ;
362                   }
363                   
364                   continue              ;
365         }
366         *str++  = ch;     
367      }  
368      *str++ = '\"'                      ;
369      *str = '\0';
370      return strLitBuff                  ;
371 }
372
373 void doPragma (int op, char *cp)
374 {
375     switch (op) {
376     case P_SAVE:
377         memcpy(&save_options,&options,sizeof(options));
378         memcpy(&save_optimize,&optimize,sizeof(optimize));
379         break;
380     case P_RESTORE:
381         memcpy(&options,&save_options,sizeof(options));
382         memcpy(&optimize,&save_optimize,sizeof(optimize));
383         break;
384     case P_NOINDUCTION:
385         optimize.loopInduction = 0 ;
386         break;
387     case P_NOINVARIANT:
388         optimize.loopInvariant = 0 ;
389         break;
390     case P_INDUCTION:
391         optimize.loopInduction = 1 ;
392         break;
393     case P_STACKAUTO:
394         options.stackAuto = 1;
395         break;
396     case P_NOJTBOUND:
397         optimize.noJTabBoundary = 1;
398         break;
399     case P_NOGCSE:
400         optimize.global_cse = 0;
401         break;
402     case P_NOOVERLAY:
403         options.noOverlay = 1;
404         break;
405     case P_CALLEE_SAVES:
406         {
407             int i=0;
408             /* append to the functions already listed
409                in callee-saves */
410             for (; options.calleeSaves[i] ;i++);
411             parseWithComma(&options.calleeSaves[i],strdup(cp));
412         }
413         break;
414     case P_EXCLUDE:
415         parseWithComma(options.excludeRegs,strdup(cp));
416         break;
417     case P_LOOPREV:
418         optimize.noLoopReverse = 1;
419         break;
420     }
421 }
422
423 int process_pragma(char *s)
424 {
425     char *cp ;
426     /* find the pragma */
427     while (strncmp(s,"#pragma",7))
428         s++;
429     s += 7;
430     
431     /* look for the directive */
432     while(isspace(*s)) s++;
433
434     cp = s;
435     /* look for the end of the directive */
436     while ((! isspace(*s)) && 
437            (*s != '\n')) 
438         s++ ;    
439
440     /* First give the port a chance */
441     if (port->process_pragma && !port->process_pragma(cp))
442         return 0;
443
444     /* now compare and do what needs to be done */
445     if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
446         doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
447         return 0;
448     }
449
450     if (strncmp(cp,PRAGMA_RESTORE,strlen(PRAGMA_RESTORE)) == 0) {
451         doPragma (P_RESTORE,cp+strlen(PRAGMA_RESTORE));
452         return 0;
453     }
454
455     if (strncmp(cp,PRAGMA_NOINDUCTION,strlen(PRAGMA_NOINDUCTION)) == 0) {
456         doPragma (P_NOINDUCTION,cp+strlen(PRAGMA_NOINDUCTION))  ;
457         return 0;
458     }
459
460     if (strncmp(cp,PRAGMA_NOINVARIANT,strlen(PRAGMA_NOINVARIANT)) == 0) {
461         doPragma (P_NOINVARIANT,NULL)   ;
462         return 0;
463     }
464
465     if (strncmp(cp,PRAGMA_INDUCTION,strlen(PRAGMA_INDUCTION)) == 0) {
466         doPragma (P_INDUCTION,NULL)     ;
467         return 0;
468     }
469
470     if (strncmp(cp,PRAGMA_STACKAUTO,strlen(PRAGMA_STACKAUTO)) == 0) {
471         doPragma (P_STACKAUTO,NULL);
472         return 0;
473     }
474
475     if (strncmp(cp,PRAGMA_NOJTBOUND,strlen(PRAGMA_NOJTBOUND)) == 0) {
476         doPragma (P_NOJTBOUND,NULL);
477         return 0;
478     }
479
480     if (strncmp(cp,PRAGMA_NOGCSE,strlen(PRAGMA_NOGCSE)) == 0) {
481         doPragma (P_NOGCSE,NULL);
482         return 0;
483     }
484
485     if (strncmp(cp,PRAGMA_NOOVERLAY,strlen(PRAGMA_NOOVERLAY)) == 0) {
486         doPragma (P_NOOVERLAY,NULL);
487         return 0;
488     }
489     
490     if (strncmp(cp,PRAGMA_CALLEESAVES,strlen(PRAGMA_CALLEESAVES)) == 0) {
491         doPragma(P_CALLEE_SAVES,cp+strlen(PRAGMA_CALLEESAVES));
492         return 0;
493     }
494     
495     if (strncmp(cp,PRAGMA_EXCLUDE,strlen(PRAGMA_EXCLUDE)) == 0) {
496         doPragma(P_EXCLUDE,cp+strlen(PRAGMA_EXCLUDE));
497         return 0;
498     }
499
500     if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
501         doPragma(P_EXCLUDE,NULL);
502         return 0;
503     }
504
505     werror(W_UNKNOWN_PRAGMA,cp);
506     return 0;
507 }
508
509 /* will return 1 if the string is a part
510    of a target specific keyword */
511 int isTargetKeyword(char *s)
512 {
513     int i;
514     
515     if (port->keywords == NULL)
516         return 0;
517     for ( i = 0 ; port->keywords[i] ; i++ ) {
518         if (strcmp(port->keywords[i],s) == 0)
519             return 1;
520     }
521     
522     return 0;
523 }
524
525 extern int fatalError;
526
527 int yyerror(char *s)
528 {
529    fflush(stdout);
530
531    if (yylineno && filename)
532         fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",
533                 filename,yylineno,
534                 s,yytext,column);
535    fatalError++;
536    return 0;
537 }