New target "hc08" for the Motorola 68hc08 family of micros
[fw/sdcc] / src / SDCC.lex
index 87d26948fdf1574858ccc215282e721e941f7861..d27496983af877116d40853c61f5e2e6bef9b4bf 100644 (file)
    what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
 
-D        [0-9]
-L        [a-zA-Z_]
-H        [a-fA-F0-9]
-E        [Ee][+-]?{D}+
-FS       (f|F|l|L)
-IS       (u|U|l|L)*
-%{
+D       [0-9]
+L       [a-zA-Z_]
+H       [a-fA-F0-9]
+E       [Ee][+-]?{D}+
+FS      (f|F|l|L)
+IS      (u|U|l|L)*
 
+%{
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -37,68 +37,49 @@ IS       (u|U|l|L)*
 #include "newalloc.h"
 #include "dbuf.h"
 
-char *stringLiteral();
-char *currFname;
+#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
+                                check_type())
 
 extern int lineno, column;
-extern char *filename ;
-int   yylineno = 1               ;
-void count()                     ;
-int process_pragma(char *);
-#undef yywrap
+extern char *filename;
 
-int yywrap YY_PROTO((void))
-{
-   return(1);
-}
-#define TKEYWORD(token) return (isTargetKeyword(yytext) ? token :\
-                               check_type(yytext))
-char *asmbuff=NULL;
-int asmbuffSize=0;
-char *asmp ;
-extern int check_type          ();
- extern int isTargetKeyword     ();
-extern int checkCurrFile       (char *);
-extern int processPragma       (char *);
-extern int printListing                (int   );
-struct optimize save_optimize ;
-struct options  save_options  ;
+/* global definitions */
+char *currFname;
+int mylineno = 1;
+
+/* local definitions */
+static struct dbuf_s asmbuff;
+
+/* forward declarations */
+static char *stringLiteral(void);
+static void count(void);
+static int process_pragma(char *);
+static int check_type(void);
+static int isTargetKeyword(char *s);
+static int checkCurrFile(char *s);
 %}
+
 %x asm
 %%
-"_asm"         {  
-  count(); 
-  asmp = asmbuff = realloc (asmbuff, INITIAL_INLINEASM);
-  asmbuffSize=INITIAL_INLINEASM;
-  BEGIN(asm) ;
+"_asm"         {
+  count();
+  assert(asmbuff.alloc == 0 && asmbuff.len == 0 && asmbuff.buf == NULL);
+  dbuf_init(&asmbuff, INITIAL_INLINEASM);
+  BEGIN(asm);
 }
-<asm>"_endasm" { 
+<asm>"_endasm" {
   count();
-  *asmp = '\0';
-  yylval.yyinline = strdup (asmbuff);
+  yylval.yyinline = dbuf_c_str(&asmbuff);
+  dbuf_detach(&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 = realloc (asmbuff, asmbuffSize); 
-    asmp=asmbuff+size;
-  }
-  *asmp++ = yytext[0];
+<asm>\n        {
+  count();
+  dbuf_append(&asmbuff, yytext, 1);
 }
-<asm>\n        { 
-  count(); 
-  if (asmp-asmbuff >= asmbuffSize-3) {
-    // increase the buffersize with 50%
-    int size=asmp-asmbuff;
-    asmbuffSize=asmbuffSize*3/2;
-    asmbuff = realloc (asmbuff, asmbuffSize); 
-    asmp=asmbuff+size;
-  }
-  *asmp++ = '\n' ;
+<asm>.         {
+  dbuf_append(&asmbuff, yytext, 1);
 }
 "at"          { count(); TKEYWORD(AT)  ; }
 "auto"        { count(); return(AUTO); }
@@ -220,9 +201,9 @@ struct options  save_options  ;
 "\n"              { count(); }
 [ \t\v\f]      { count(); }
 \\ {
-  char ch=input();
-  if (ch!='\n') {
-    // that could have been removed by the preprocessor anyway
+  int ch = input();
+  if (ch != '\n') {
+    /* that could have been removed by the preprocessor anyway */
     werror (W_STRAY_BACKSLASH, column);
     unput(ch);
   }
@@ -230,7 +211,7 @@ struct options  save_options  ;
 .                         { count()    ; }
 %%
 
-int checkCurrFile ( char *s)
+static int checkCurrFile (char *s)
 {
     char lineNum[10]                   ;
     int  lNum                          ;
@@ -257,7 +238,7 @@ int checkCurrFile ( char *s)
     /* set the current line number to   */
     /* line number if printFlag is on   */
     if (!*s) {         
-      lineno = yylineno = lNum ;
+      lineno = mylineno = lNum ;
       return 0;
     }
     
@@ -269,7 +250,7 @@ int checkCurrFile ( char *s)
     /* in c1mode fullSrcFileName is NULL */
     if ( fullSrcFileName &&
          strncmp(s,fullSrcFileName,strlen(fullSrcFileName)) == 0) {
-      lineno = yylineno = lNum;                                        
+      lineno = mylineno = lNum;                                        
       currFname = fullSrcFileName ;
     }  else {
        char *sb = s;
@@ -277,22 +258,22 @@ int checkCurrFile ( char *s)
        while (*s != '"') s++;
        *s = '\0';
        currFname = strdup (sb);
-       lineno = yylineno = lNum;
+       lineno = mylineno = lNum;
     }
     filename = currFname ;
     return 0;
 }
     
 int column = 0;
-int plineIdx=0;
+int plineIdx =0;
 
-void count()
+static void count(void)
 {
   int i;
   for (i = 0; yytext[i] != '\0'; i++)   {                              
     if (yytext[i] == '\n')      {         
       column = 0;
-      lineno = ++yylineno ;
+      lineno = ++mylineno ;
     }
     else 
       if (yytext[i] == '\t')
@@ -303,7 +284,7 @@ void count()
   /* ECHO; */
 }
 
-int check_type()
+static int check_type(void)
 {
        /* check if it is in the typedef table */
        if (findSym(TypedefTab,NULL,yytext)) {
@@ -321,7 +302,7 @@ int check_type()
  * to support ANSI hex and octal escape sequences in string liteals 
  */
 
-char *stringLiteral()
+static char *stringLiteral(void)
 {
 #define STR_BUF_CHUNCK_LEN  1024
   int ch;
@@ -344,7 +325,7 @@ char *stringLiteral()
       ch = input();
       if (ch == '\n') {
         /* \<newline> is a continuator */
-        lineno = ++yylineno;
+        lineno = ++mylineno;
         column = 0;
       }
       else {
@@ -358,7 +339,7 @@ char *stringLiteral()
       /* if new line we have a new line break, which is illegal */
       werror(W_NEWLINE_IN_STRING);
       dbuf_append(&dbuf, "\n", 1);
-      lineno = ++yylineno;
+      lineno = ++mylineno;
       column = 0;
       break;
 
@@ -367,7 +348,7 @@ char *stringLiteral()
       /* find the next non whitespace character     */
       /* if that is a double quote then carry on    */
       dbuf_append(&dbuf, "\"", 1);  /* Pass end of this string or substring to evaluator */
-      while ((ch = input()) && (isspace(ch) || ch=='\\')) {
+      while ((ch = input()) && (isspace(ch) || ch == '\\')) {
         switch (ch) {
         case '\\':
           if ((ch = input()) != '\n') {
@@ -375,13 +356,13 @@ char *stringLiteral()
             unput(ch);
           }
           else {
-            lineno = ++yylineno;
+            lineno = ++mylineno;
             column = 0;
           }
           break;
 
         case '\n':
-          yylineno++;
+          mylineno++;
           break;
         }
       }
@@ -432,22 +413,70 @@ enum pragma_id {
 STACK_DCL(options_stack, struct options *, SAVE_RESTORE_SIZE)
 STACK_DCL(optimize_stack, struct optimize *, SAVE_RESTORE_SIZE)
 
+/*
+ * cloneXxx functions should be updated every time a new set is
+ * added to the options or optimize structure!
+ */
+
+static struct options *cloneOptions(struct options *opt)
+{
+  struct options *new_opt;
+
+  new_opt = Safe_malloc(sizeof (struct options));
+
+  /* clone scalar values */
+  *new_opt = *opt;
+
+  /* clone sets */
+  new_opt->calleeSavesSet = setFromSetNonRev(opt->calleeSavesSet);
+  new_opt->excludeRegsSet = setFromSetNonRev(opt->excludeRegsSet);
+  /* not implemented yet: */
+  /* new_opt->olaysSet = setFromSetNonRev(opt->olaysSet); */
+
+  return new_opt;
+}
+
+static struct optimize *cloneOptimize(struct optimize *opt)
+{
+  struct optimize *new_opt;
+
+  new_opt = Safe_malloc(sizeof (struct options));
+
+  /* clone scalar values */
+  *new_opt = *opt;
+
+  return new_opt;
+}
+
+static void copyAndFreeOptions(struct options *dest, struct options *src)
+{
+  /* delete dest sets */
+  deleteSet(&dest->calleeSavesSet);
+  deleteSet(&dest->excludeRegsSet);
+  /* not implemented yet: */
+  /* deleteSet(&dest->olaysSet); */
+
+  /* dopy src to dest */
+  *dest = *src;
+
+  Safe_free(src);
+}
+
+static void copyAndFreeOptimize(struct optimize *dest, struct optimize *src)
+{
+  /* dopy src to dest */
+  *dest = *src;
+
+  Safe_free(src);
+}
 
-void doPragma (int op, char *cp)
+static void doPragma(int op, char *cp)
 {
   switch (op) {
   case P_SAVE:
     {
-      struct options *optionsp;
-      struct optimize *optimizep;
-
-      optionsp = Safe_malloc(sizeof (struct options));
-      *optionsp = options;
-      STACK_PUSH(options_stack, optionsp);
-
-      optimizep = Safe_malloc(sizeof (struct optimize));
-      *optimizep = optimize;
-      STACK_PUSH(optimize_stack, optimizep);
+      STACK_PUSH(options_stack, cloneOptions(&options));
+      STACK_PUSH(optimize_stack, cloneOptimize(&optimize));
     }
     break;
 
@@ -457,12 +486,10 @@ void doPragma (int op, char *cp)
       struct optimize *optimizep;
 
       optionsp = STACK_POP(options_stack);
-      options = *optionsp;
-      Safe_free(optionsp);
+      copyAndFreeOptions(&options, optionsp);
 
       optimizep = STACK_POP(optimize_stack);
-      optimize = *optimizep;
-      Safe_free(optimizep);
+      copyAndFreeOptimize(&optimize, optimizep);
     }
     break;
 
@@ -499,17 +526,16 @@ void doPragma (int op, char *cp)
     break;
 
   case P_CALLEE_SAVES:
-    {
-      int i=0;
-      /* append to the functions already listed
-         in callee-saves */
-      for (; options.calleeSaves[i] ;i++);
-        parseWithComma(&options.calleeSaves[i], Safe_strdup(cp));
-    }
+    /* append to the functions already listed
+       in callee-saves */
+    setParseWithComma(&options.calleeSavesSet, cp);
     break;
 
   case P_EXCLUDE:
-    parseWithComma(options.excludeRegs, Safe_strdup(cp));
+    {
+      deleteSet(&options.excludeRegsSet);
+      setParseWithComma(&options.excludeRegsSet, cp);
+    }
     break;
 
   case P_NOIV:
@@ -525,7 +551,7 @@ void doPragma (int op, char *cp)
   }
 }
 
-int process_pragma(char *s)
+static int process_pragma(char *s)
 {
 #define NELEM(x)  (sizeof (x) / sizeof (x)[0])
 #define PRAGMA    "#pragma"
@@ -587,7 +613,7 @@ int process_pragma(char *s)
 
 /* will return 1 if the string is a part
    of a target specific keyword */
-int isTargetKeyword(char *s)
+static int isTargetKeyword(char *s)
 {
     int i;
     
@@ -601,19 +627,30 @@ int isTargetKeyword(char *s)
     return 0;
 }
 
-extern int fatalError;
+int yywrap(void)
+{
+  if (!STACK_EMPTY(options_stack) || !STACK_EMPTY(optimize_stack))
+    werror(W_SAVE_RESTORE);
+
+  return 1;
+}
 
 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);
+   if (mylineno && filename) {
+        if(options.vc_err_style)
+               fprintf(stderr,"\n%s(%d) : %s: token -> '%s' ; column %d\n",
+                       filename,mylineno,
+                       s,yytext,column);
+         else
+               fprintf(stderr,"\n%s:%d: %s: token -> '%s' ; column %d\n",
+                       filename,mylineno,
+                       s,yytext,column);
      fatalError++;
    } else {
-     // this comes from an empy file, no problem
+     /* this comes from an empy file, no problem */
    }
    return 0;
 }