__rlrr array lacking extern
[fw/sdcc] / src / SDCC.lex
index 510981ad443219c2eb18a9f56ff926c4746134a6..8d2dc055ce846c7f682e7ab8c05c51b05f4dac92 100644 (file)
@@ -33,23 +33,17 @@ IS       (u|U|l|L)*
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include "SDCCglobl.h"
-#include "SDCCsymt.h"
-#include "SDCCval.h"
-#include "SDCCast.h"
-#include "SDCCy.h"
-#include "SDCChasht.h"
-#include "SDCCmem.h"
+#include "common.h"
+#include "newalloc.h"
     
 char *stringLiteral();
 char *currFname;
 
-extern int lineno                      ;
+extern int lineno, column;
 extern char *filename ;
 extern char *fullSrcFileName ;
 int   yylineno = 1               ;
 void count()                     ;
-void comment();
 int process_pragma(char *);
 #undef yywrap
 
@@ -57,10 +51,13 @@ int yywrap YY_PROTO((void))
 {
    return(1);
 }
-
-char asmbuff[MAX_INLINEASM]                    ;
+#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
+                               check_type(yytext))
+char *asmbuff=NULL;
+int asmbuffSize=0;
 char *asmp ;
-extern int check_type          (          );
+extern int check_type          ();
+ extern int isTargetKeyword     ();
 extern int checkCurrFile       (char *);
 extern int processPragma       (char *);
 extern int printListing                (int   );
@@ -85,51 +82,82 @@ struct options  save_options  ;
 %}
 %x asm
 %%
-"_asm"        {  count(); asmp = asmbuff ;BEGIN(asm) ;}
-<asm>"_endasm" { count()               ; 
-                  *asmp = '\0'                         ; 
-                  strcpy(yylval.yyinline,asmbuff)              ; 
-                  BEGIN(INITIAL)       ;
-                  return (INLINEASM)                   ; }
-<asm>.         { *asmp++ = yytext[0]   ; }
-<asm>\n        { count(); *asmp++ = '\n' ;}
-"/*"          { comment(); }
-"at"          { count(); return(AT)  ; }
-"auto"     { count(); return(AUTO); }
-"bit"         { count(); return(BIT) ; }
-"break"      { count(); return(BREAK); }
-"case"       { count(); return(CASE); }
+"_asm"         {  
+  count(); 
+  asmp = asmbuff = Safe_realloc (asmbuff, INITIAL_INLINEASM);
+  asmbuffSize=INITIAL_INLINEASM;
+  BEGIN(asm) ;
+}
+<asm>"_endasm" { 
+  count();
+  *asmp = '\0';
+  yylval.yyinline = Safe_calloc (1, strlen(asmbuff)+1);
+  strcpy(yylval.yyinline,asmbuff);
+  BEGIN(INITIAL);
+  return (INLINEASM);
+}
+<asm>.         { 
+  if (asmp-asmbuff >= asmbuffSize-2) {
+    // increase the buffersize with 50%
+    int size=asmp-asmbuff;
+    asmbuffSize=asmbuffSize*3/2;
+    asmbuff = Safe_realloc (asmbuff, asmbuffSize); 
+    asmp=asmbuff+size;
+  }
+  *asmp++ = yytext[0];
+}
+<asm>\n        { 
+  count(); 
+  if (asmp-asmbuff >= asmbuffSize-3) {
+    // increase the buffersize with 50%
+    int size=asmp-asmbuff;
+    asmbuffSize=asmbuffSize*3/2;
+    asmbuff = Safe_realloc (asmbuff, asmbuffSize); 
+    asmp=asmbuff+size;
+  }
+  *asmp++ = '\n' ;
+}
+"at"          { count(); TKEYWORD(AT)  ; }
+"auto"        { count(); return(AUTO); }
+"bit"         { count(); TKEYWORD(BIT) ; }
+"break"        { count(); return(BREAK); }
+"case"         { count(); return(CASE); }
 "char"         { count(); return(CHAR); }
-"code"         { count(); return(CODE); }
+"code"         { count(); TKEYWORD(CODE); }
 "const"        { count(); return(CONST); }
 "continue"     { count(); return(CONTINUE); }
-"critical"     { count(); return(CRITICAL); } 
-"data"        { count(); return(DATA);   }
+"critical"     { count(); TKEYWORD(CRITICAL); } 
+"data"        { count(); TKEYWORD(DATA);   }
 "default"      { count(); return(DEFAULT); }
 "do"           { count(); return(DO); }
 "double"       { count(); werror(W_DOUBLE_UNSUPPORTED);return(FLOAT); }
 "else"         { count(); return(ELSE); }
 "enum"         { count(); return(ENUM); }
 "extern"       { count(); return(EXTERN); }
-"far"          { count(); return(XDATA);  }
+"far"          { count(); TKEYWORD(XDATA);  }
+"eeprom"       { count(); TKEYWORD(EEPROM);  }
 "float"        { count(); return(FLOAT); }
+"flash"        { count(); TKEYWORD(CODE);}
 "for"          { count(); return(FOR); }
 "goto"        { count(); return(GOTO); }
-"idata"        { count(); return(IDATA);}
+"idata"        { count(); TKEYWORD(IDATA);}
 "if"           { count(); return(IF); }
 "int"          { count(); return(INT); }
 "interrupt"    { count(); return(INTERRUPT);}
+"nonbanked"    { count(); TKEYWORD(NONBANKED);}
+"banked"       { count(); TKEYWORD(BANKED);}
 "long"        { count(); return(LONG); }
-"near"            { count(); return(DATA);}
-"pdata"        { count(); return(PDATA); }
-"reentrant"    { count(); return(REENTRANT);}
+"near"        { count(); TKEYWORD(DATA);}
+"pdata"        { count(); TKEYWORD(PDATA); }
+"reentrant"    { count(); TKEYWORD(REENTRANT);}
 "register"     { count(); return(REGISTER); }
 "return"       { count(); return(RETURN); }
-"sfr"         { count(); return(SFR)   ; }
-"sbit"        { count(); return(SBIT)  ; }
+"sfr"         { count(); TKEYWORD(SFR) ; }
+"sbit"        { count(); TKEYWORD(SBIT)        ; }
 "short"        { count(); return(SHORT); }
 "signed"       { count(); return(SIGNED); }
 "sizeof"       { count(); return(SIZEOF); }
+"sram"         { count(); TKEYWORD(XDATA);}
 "static"       { count(); return(STATIC); }
 "struct"       { count(); return(STRUCT); }
 "switch"       { count(); return(SWITCH); }
@@ -138,17 +166,11 @@ struct options  save_options  ;
 "unsigned"     { count(); return(UNSIGNED); }
 "void"         { count(); return(VOID); }
 "volatile"     { count(); return(VOLATILE); }
-"using"        { count(); return(USING); }
+"using"        { count(); TKEYWORD(USING); }
+"_naked"       { count(); TKEYWORD(NAKED); }
 "while"        { count(); return(WHILE); }
-"xdata"        { count(); return(XDATA); }
-"_data"                   { count(); return(_NEAR); }
-"_code"                   { count(); return(_CODE); }
-"_generic"        { count(); return(_GENERIC); }
-"_near"                   { count(); return(_NEAR); }
-"_xdata"       { count(); return(_XDATA);}
-"_pdata" { count () ; return(_PDATA); }
-"_idata" { count () ; return(_IDATA); }
-"..."             { count(); return(VAR_ARGS);}
+"xdata"        { count(); TKEYWORD(XDATA); }
+"..."         { count(); return(VAR_ARGS);}
 {L}({L}|{D})*  { count(); return(check_type()); }
 0[xX]{H}+{IS}? { count(); yylval.val = constVal(yytext); return(CONSTANT); }
 0{D}+{IS}?     { count(); yylval.val = constVal(yytext); return(CONSTANT); }
@@ -180,8 +202,8 @@ struct options  save_options  ;
 "=="           { count(); return(EQ_OP); }
 "!="           { count(); return(NE_OP); }
 ";"            { count(); return(';'); }
-"{"                       { count()    ; NestLevel++ ;  return('{'); }
-"}"                       { count(); NestLevel--; return('}'); }
+"{"           { count(); NestLevel++ ;  return('{'); }
+"}"           { count(); NestLevel--; return('}'); }
 ","            { count(); return(','); }
 ":"            { count(); return(':'); }
 "="            { count(); return('='); }
@@ -211,6 +233,14 @@ struct options  save_options  ;
 "\r\n"            { count(); }
 "\n"              { count(); }
 [ \t\v\f]      { count(); }
+\\ {
+  char ch=input();
+  if (ch!='\n') {
+    // that could have been removed by the preprocessor anyway
+    werror (W_STRAY_BACKSLASH, column);
+    unput(ch);
+  }
+}
 .                         { count()    ; }
 %%
    
@@ -241,8 +271,8 @@ int checkCurrFile ( char *s)
     /* set the current line number to   */
     /* line number if printFlag is on   */
     if (!*s) {         
-       yylineno = lNum ;
-       return 0;
+      lineno = yylineno = lNum ;
+      return 0;
     }
     
     /* if we have a filename then check */
@@ -251,61 +281,39 @@ int checkCurrFile ( char *s)
     s++ ;
 
     if ( strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
-           yylineno = lNum - 2;                                        
-           currFname = fullSrcFileName ;
+      lineno = yylineno = lNum;                                        
+      currFname = fullSrcFileName ;
     }  else {
        char *sb = s;
        /* mark the end of the filename */
        while (*s != '"') s++;
        *s = '\0';
-       ALLOC_ATOMIC(currFname,strlen(sb)+1);
+       currFname = Safe_calloc(1,strlen(sb)+1);
        strcpy(currFname,sb);
-       yylineno = lNum - 2;
+       lineno = yylineno = lNum;
     }
     filename = currFname ;
     return 0;
 }
     
-void comment()
-{
-       char c, c1;
-
-loop:
-       while ((c = input()) != '*' && c != 0)
-               if ( c == '\n')
-                       yylineno++ ;
-
-       if ((c1 = input()) != '/' && c != 0)  {
-               if ( c1 == '\n' )
-                       yylineno++ ;
-
-               unput(c1);
-               goto loop;
-   }
-
-}
-   
-   
-
 int column = 0;
 int plineIdx=0;
 
 void count()
 {
-       int i;
-       for (i = 0; yytext[i] != '\0'; i++)   {                         
-               if (yytext[i] == '\n')      {         
-                  column = 0;
-                  lineno = ++yylineno ;
-               }
-               else 
-                       if (yytext[i] == '\t')
-                               column += 8 - (column % 8);
-                       else
-                               column++;
-   }
-         
-   /* ECHO; */
+  int i;
+  for (i = 0; yytext[i] != '\0'; i++)   {                              
+    if (yytext[i] == '\n')      {         
+      column = 0;
+      lineno = ++yylineno ;
+    }
+    else 
+      if (yytext[i] == '\t')
+       column += 8 - (column % 8);
+      else
+       column++;
+  }
+  /* ECHO; */
 }
 
 int check_type()
@@ -321,49 +329,84 @@ int check_type()
        }
 }
 
-char strLitBuff[2048]                  ;
+char strLitBuff[2048]; // TODO: this is asking for the next bug :)
 
-char *stringLiteral ()
-{
-       int ch;
-       char *str = strLitBuff                  ;
-       
-       *str++ = '\"'                   ;
-       /* put into the buffer till we hit the */
-       /* first \" */
-       while (1) {
-
-          ch = input()                 ;
-          if (!ch)         break       ; /* end of input */
-         /* if it is a \ then everything allowed */
-         if (ch == '\\') {
-            *str++ = ch     ; /* backslash in place */
-            *str++ = input()           ; /* following char in place */
-            continue                   ;      /* carry on */
-            }
-            
-        /* if new line we have a new line break */
-        if (ch == '\n') break          ;
-        
-        /* if this is a quote then we have work to do */
-        /* find the next non whitespace character     */
-        /* if that is a double quote then carry on    */
-        if (ch == '\"') {
-        
-            while ((ch = input()) && isspace(ch)) ;
-            if (!ch) break             ; 
-            if (ch != '\"') {
-                 unput(ch)                     ;
-                 break                 ;
-                 }
-                 
-                 continue              ;
-        }
-       *str++  = ch;     
-     }  
-     *str++ = '\"'                     ;
-     *str = '\0';
-     return strLitBuff                 ;
+/*
+ * Change by JTV 2001-05-19 to not concantenate strings
+ * to support ANSI hex and octal escape sequences in string liteals 
+ */
+
+char *stringLiteral () {
+  int ch;
+  char *str = strLitBuff;
+  
+  *str++ = '\"';
+  /* put into the buffer till we hit the first \" */
+  
+  while (1) {
+    ch = input();
+    
+    if (!ch)
+      break; /* end of input */
+    
+    /* if it is a \ then escape char's are allowed */
+    if (ch == '\\') {
+      ch=input();
+      if (ch=='\n') {
+       /* \<newline> is a continuator */
+       lineno=++yylineno;
+       column=0;
+       continue;
+      }
+      *str++ = '\\'; /* backslash in place */
+      *str++ = ch; /* get the escape char, no further check */
+      continue; /* carry on */
+    }
+    
+    /* if new line we have a new line break, which is illegal */
+    if (ch == '\n') {
+      werror (W_NEWLINE_IN_STRING);
+      *str++ = '\n';
+      lineno=++yylineno;
+      column=0;
+      continue;
+    }
+    
+    /* if this is a quote then we have work to do */
+    /* find the next non whitespace character     */
+    /* if that is a double quote then carry on    */
+    if (ch == '\"') {
+      *str++  = ch ; /* Pass end of this string or substring to evaluator */
+      while ((ch = input()) && (isspace(ch) || ch=='\\')) {
+       switch (ch) {
+       case '\\':
+         if ((ch=input())!='\n') {
+           werror (W_STRAY_BACKSLASH, column);
+           unput(ch);
+         } else {
+           lineno=++yylineno;
+           column=0;
+         }
+         break;
+       case '\n':
+         yylineno++;
+         break;
+       }
+      }
+
+      if (!ch) 
+       break; 
+
+      if (ch != '\"') {
+       unput(ch) ;
+       break ;
+      }
+    }
+    *str++  = ch; /* Put next substring introducer into output string */
+  }  
+  *str = '\0';
+  
+  return strLitBuff;
 }
 
 void doPragma (int op, char *cp)
@@ -433,6 +476,10 @@ int process_pragma(char *s)
           (*s != '\n')) 
        s++ ;    
 
+    /* First give the port a chance */
+    if (port->process_pragma && !port->process_pragma(cp))
+       return 0;
+
     /* now compare and do what needs to be done */
     if (strncmp(cp,PRAGMA_SAVE,strlen(PRAGMA_SAVE)) == 0) {
        doPragma(P_SAVE,cp+strlen(PRAGMA_SAVE));
@@ -490,10 +537,40 @@ int process_pragma(char *s)
     }
 
     if (strncmp(cp,PRAGMA_NOLOOPREV,strlen(PRAGMA_NOLOOPREV)) == 0) {
-       doPragma(P_EXCLUDE,NULL);
+       doPragma(P_LOOPREV,NULL);
        return 0;
     }
 
     werror(W_UNKNOWN_PRAGMA,cp);
     return 0;
 }
+
+/* will return 1 if the string is a part
+   of a target specific keyword */
+int isTargetKeyword(char *s)
+{
+    int i;
+    
+    if (port->keywords == NULL)
+       return 0;
+    for ( i = 0 ; port->keywords[i] ; i++ ) {
+       if (strcmp(port->keywords[i],s) == 0)
+           return 1;
+    }
+    
+    return 0;
+}
+
+extern int fatalError;
+
+int yyerror(char *s)
+{
+   fflush(stdout);
+
+   if (yylineno && filename)
+       fprintf(stdout,"\n%s(%d) %s: token -> '%s' ; column %d\n",
+               filename,yylineno,
+               s,yytext,column);
+   fatalError++;
+   return 0;
+}