"Fossies" - the Fresh Open Source Software Archive

Member "bas-2.6/token.l" (2 Jul 2019, 63727 Bytes) of package /linux/privat/bas-2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "token.l": 2.5_vs_2.6.

    1 /* Tokens and token sequence arrays. */
    2 %{
    3 /* #includes */ /*{{{C}}}*//*{{{*/
    4 #include "config.h"
    5 
    6 #include <assert.h>
    7 #include <ctype.h>
    8 #include <float.h>
    9 #include <limits.h>
   10 #include <math.h>
   11 #include <stddef.h>
   12 #include <stdlib.h>
   13 #include <string.h>
   14 
   15 #include "auto.h"
   16 #include "token.h"
   17 #include "statement.h"
   18 
   19 #ifdef DMALLOC
   20 #include "dmalloc.h"
   21 #endif
   22 /*}}}*/
   23 
   24 static int matchdata;
   25 static int backslash_colon;
   26 static int uppercase;
   27 int yylex(void);
   28 static struct Token *cur;
   29 
   30 static void string(const char *text) /*{{{*/
   31 {
   32   if (cur)
   33   {
   34     const char *t;
   35     char *q;
   36     size_t l;
   37 
   38     for (t=text+1,l=0; *(t+1); ++t,++l)
   39     {
   40       if (*t=='"') ++t;
   41     }
   42     cur->u.string=malloc(sizeof(struct String));
   43     String_size(String_new(cur->u.string),l);
   44     for (t=text+1,q=cur->u.string->character; *(t+1); ++t,++q)
   45     {
   46       *q=*t;
   47       if (*t=='"') ++t;
   48     }
   49   }
   50 }
   51 /*}}}*/
   52 static void string2(void) /*{{{*/
   53 {
   54   if (cur)
   55   {
   56     char *t,*q;
   57     size_t l;
   58 
   59     for (t=yytext+1,l=0; *t; ++t,++l)
   60     {
   61       if (*t=='"') ++t;
   62     }
   63     cur->u.string=malloc(sizeof(struct String));
   64     String_size(String_new(cur->u.string),l);
   65     for (t=yytext+1,q=cur->u.string->character; *t; ++t,++q)
   66     {
   67       *q=*t;
   68       if (*t=='"') ++t;
   69     }
   70   }
   71 }
   72 /*}}}*/
   73 %}
   74  /* flex options and definitions */ /*{{{*/
   75 %option noyywrap
   76 %option nounput
   77 %x DATAINPUT ELSEIF IMAGEFMT
   78 REAL        ([0-9]+("!"|"#"))|([0-9]+\.[0-9]*(e("+"|"-")?[0-9]+)?("!"|"#")?)|([0-9]*\.[0-9]+(e("+"|"-")?[0-9]+)?("!"|"#")?|([0-9]+e("+"|"-")?[0-9]+("!"|"#")?))
   79 INTEGER     [0-9]+%?
   80 HEXINTEGER  &H[0-9A-F]+
   81 OCTINTEGER  &O[0-7]+
   82 IDENTIFIER      ("fn"[ \t]+)?[A-Z][A-Z_0-9\.]*("$"|"%"|"#")?
   83 STRING          \"([^"]|\"\")*\"
   84 STRING2     \"([^"]|\"\")*$
   85 REM     rem([^0-9A-Z_\.\n][^\n]*)?
   86 QUOTE       ("'"|"!")[^\n]*
   87 ENDIF           end[ \t]*if
   88 ENDPROC         end[ \t]*proc
   89 ENDSELECT   end[ \t]*select
   90 DOUNTIL     do[ \t]+until
   91 DOWHILE     do[ \t]+while
   92 EXITDO      exit[ \t]+do
   93 EXITFOR     exit[ \t]+for
   94 LINEINPUT   (line[ \t]+input)|linput
   95 LOOPUNTIL   loop[ \t]+until
   96 DATAITEM    [^ \t\n,:][^,:\n]*
   97 ONERROR     on[ \t]+error
   98 ONERROROFF  on[ \t]+error[ \t]+off
   99 ONERRORGOTO0    on[ \t]+error[ \t]+goto[ \t]+0
  100 SELECTCASE  select[ \t]+case
  101  /*}}}*/
  102 %%
  103  /* flex rules */ /*{{{*/
  104   if (matchdata) BEGIN(DATAINPUT);
  105 
  106 "#"         return T_CHANNEL;
  107 {REAL}              {
  108               int overflow;
  109               double d;
  110 
  111                       d=Value_vald(yytext,(char**)0,&overflow);
  112                       if (overflow)
  113               {
  114                 if (cur) cur->u.junk=yytext[0];
  115                 yyless(1);
  116                 return T_JUNK;
  117               }
  118               if (cur) cur->u.real=d;
  119                       return T_REAL;
  120                     }
  121 {INTEGER}           {
  122               int overflow;
  123               long int n;
  124 
  125                       n=Value_vali(yytext,(char**)0,&overflow);
  126               if (overflow)
  127               {
  128                 double d;
  129 
  130                 d=Value_vald(yytext,(char**)0,&overflow);
  131                 if (overflow)
  132                 {
  133                   if (cur) cur->u.junk=yytext[0];
  134                   yyless(1);
  135                   return T_JUNK;
  136                 }
  137                 if (cur) cur->u.real=d;
  138                 return T_REAL;
  139               }
  140                       if (cur) cur->u.integer=n;
  141                       return T_INTEGER;
  142                     }
  143 {HEXINTEGER}        {
  144               int overflow;
  145               long int n;
  146 
  147               n=Value_vali(yytext,(char**)0,&overflow);
  148                       if (overflow)
  149                       {
  150                         if (cur) cur->u.junk=yytext[0];
  151                         yyless(1);
  152                             return T_JUNK;
  153                       }
  154                       if (cur) cur->u.hexinteger=n;
  155                       return T_HEXINTEGER;
  156                     }
  157 {OCTINTEGER}        {
  158               int overflow;
  159               long int n;
  160 
  161                       n=Value_vali(yytext,(char**)0,&overflow);
  162                       if (overflow)
  163                       {
  164                         if (cur) cur->u.junk=yytext[0];
  165                         yyless(1);
  166                             return T_JUNK;
  167                       }
  168                       if (cur) cur->u.octinteger=n;
  169                       return T_OCTINTEGER;
  170                     }
  171 {STRING}            string(yytext); return T_STRING;
  172 {STRING2}           string2(); return T_STRING;
  173 "("|"["                 return T_OP;
  174 ")"|"]"                 return T_CP;
  175 "*"                 return T_MULT;
  176 "+"                 return T_PLUS;
  177 "-"                 return T_MINUS;
  178 ","                 return T_COMMA;
  179 "/"                 return T_DIV;
  180 "\\"            {
  181                           if (backslash_colon)
  182                           {
  183                             if (cur) cur->statement=stmt_COLON_EOL;
  184                             return T_COLON;
  185                           }
  186                           return T_IDIV;
  187                         }
  188 ":"                 {
  189                           if (cur)
  190                           {
  191                             cur->statement=stmt_COLON_EOL;
  192                           }
  193                           return T_COLON;
  194                         }
  195 ";"                 return T_SEMICOLON;
  196 "<"                 return T_LT;
  197 "<="                return T_LE;
  198 "=<"                return T_LE;
  199 "<>"|"><"               return T_NE;
  200 "="                 {
  201                           if (cur)
  202                           {
  203                             cur->statement=stmt_EQ_FNRETURN_FNEND;
  204                           }
  205                           return T_EQ;
  206                         }
  207 ">"                 return T_GT;
  208 ">="                return T_GE;
  209 "=>"                return T_GE;
  210 "^"                 return T_POW;
  211 "access"[ \t]+"read"    return T_ACCESS_READ;
  212 "access"[ \t]+"read"[ \t]+"write"    return T_ACCESS_READ_WRITE;
  213 "access"[ \t]+"write"   return T_ACCESS_WRITE;
  214 "and"           return T_AND;
  215 "as"            return T_AS;
  216 "call"          {
  217                           if (cur)
  218                           {
  219                             cur->statement=stmt_CALL;
  220                           }
  221                           return T_CALL;
  222                         }
  223 "case"[ \t]+"else"  {
  224               if (cur)
  225               {
  226                 cur->statement=stmt_CASE;
  227                 cur->u.casevalue=malloc(sizeof(struct Casevalue));
  228               }
  229               return T_CASEELSE;
  230             }
  231 "case"          {
  232               if (cur)
  233               {
  234                 cur->statement=stmt_CASE;
  235                 cur->u.casevalue=malloc(sizeof(struct Casevalue));
  236               }
  237               return T_CASEVALUE;
  238             }
  239 "chdir"         {
  240                           if (cur)
  241                           {
  242                             cur->statement=stmt_CHDIR_MKDIR;
  243                           }
  244                           return T_CHDIR;
  245                         }
  246 "clear"             {
  247                           if (cur)
  248                           {
  249                             cur->statement=stmt_CLEAR;
  250                           }
  251                           return T_CLEAR;
  252                         }
  253 "close"         {
  254                           if (cur)
  255                           {
  256                             cur->statement=stmt_CLOSE;
  257                           }
  258                           return T_CLOSE;
  259                         }
  260 "close"/"#"     {
  261                           if (cur)
  262                           {
  263                             cur->statement=stmt_CLOSE;
  264                           }
  265                           return T_CLOSE;
  266                         }
  267 "cls"|"home"        {
  268                           if (cur)
  269                           {
  270                             cur->statement=stmt_CLS;
  271                           }
  272                           return T_CLS;
  273                         }
  274 "color"         {
  275                           if (cur)
  276                           {
  277                             cur->statement=stmt_COLOR;
  278                           }
  279                           return T_COLOR;
  280                         }
  281 "con"           return T_CON;
  282 "copy"          {
  283                           if (cur)
  284                           {
  285                             cur->statement=stmt_COPY_RENAME;
  286                           }
  287                           return T_COPY;
  288                         }
  289 "data"|"d."     {
  290                           BEGIN(DATAINPUT);
  291                           if (cur)
  292                           {
  293                             cur->statement=stmt_DATA;
  294                           }
  295                           return T_DATA;
  296                         }
  297 <DATAINPUT>{STRING} string(yytext); return T_STRING;
  298 <DATAINPUT>{STRING2}    string2(); return T_STRING;
  299 <DATAINPUT>","      return T_COMMA;
  300 <DATAINPUT>{DATAITEM}   {
  301                       if (cur) cur->u.datainput=strcpy(malloc(strlen(yytext)+1),yytext);
  302               return T_DATAINPUT;
  303             }
  304 <DATAINPUT>[ \t]+
  305 <DATAINPUT>\n       BEGIN(INITIAL);
  306 <DATAINPUT>:        BEGIN(INITIAL); return T_COLON;
  307 "dec"           {
  308                           if (cur)
  309                           {
  310                             cur->statement=stmt_DEC_INC;
  311                           }
  312                           return T_DEC;
  313                         }
  314 "defdbl"            {
  315                           if (cur)
  316                           {
  317                             cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
  318                           }
  319                           return T_DEFDBL;
  320                         }
  321 "defint"            {
  322                           if (cur)
  323                           {
  324                             cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
  325                           }
  326                           return T_DEFINT;
  327                         }
  328 "defstr"        {
  329                           if (cur)
  330                           {
  331                             cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
  332                           }
  333                           return T_DEFSTR;
  334                         }
  335 "def"/[ \t]+fn[ \t]*[A-Z_0-9\.] {
  336                       if (cur)
  337                       {
  338                         cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
  339                         cur->u.localSyms=(struct Symbol*)0;
  340                       }
  341                       return T_DEFFN;
  342                     }
  343 "def"/[ \t]+proc[A-Z_0-9\.] {
  344                       if (cur)
  345                       {
  346                         cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
  347                         cur->u.localSyms=(struct Symbol*)0;
  348                       }
  349                       return T_DEFPROC;
  350                     }
  351 "delete"        {
  352                           if (cur)
  353                           {
  354                             cur->statement=stmt_DELETE;
  355                           }
  356                           return T_DELETE;
  357                         }
  358 "dim"               {
  359                           if (cur)
  360                           {
  361                             cur->statement=stmt_DIM;
  362                           }
  363                           return T_DIM;
  364                         }
  365 "display"       {
  366                           if (cur)
  367                           {
  368                             cur->statement=stmt_DISPLAY;
  369                           }
  370                           return T_DISPLAY;
  371                         }
  372 "do"            {
  373                           if (cur)
  374                           {
  375                             cur->statement=stmt_DO;
  376                           }
  377                           return T_DO;
  378                         }
  379 {DOUNTIL}       {
  380                           if (cur)
  381                           {
  382                             cur->statement=stmt_DOcondition;
  383                           }
  384                           return T_DOUNTIL;
  385                         }
  386 {DOWHILE}       {
  387                           if (cur)
  388                           {
  389                             cur->statement=stmt_DOcondition;
  390                           }
  391                           return T_DOWHILE;
  392                         }
  393 "edit"          {
  394                           if (cur)
  395                           {
  396                             cur->statement=stmt_EDIT;
  397                           }
  398                           return T_EDIT;
  399                         }
  400 "else"|"el."        {
  401                           if (cur)
  402                           {
  403                             cur->statement=stmt_ELSE_ELSEIFELSE;
  404                           }
  405                           return T_ELSE;
  406                         }
  407 "else"/"if"     {
  408                           BEGIN(ELSEIF);
  409                           if (cur)
  410                           {
  411                             cur->statement=stmt_ELSE_ELSEIFELSE;
  412                           }
  413                           return T_ELSEIFELSE;
  414                         }
  415 <ELSEIF>"if"        {
  416                           BEGIN(INITIAL);
  417                           if (cur)
  418                           {
  419                             cur->statement=stmt_IF_ELSEIFIF;
  420                           }
  421                           return T_ELSEIFIF;
  422                         }
  423 end[ \t]+function   {
  424                           if (cur)
  425                           {
  426                             cur->statement=stmt_ENDFN;
  427                           }
  428                           return T_ENDFN;
  429                         }
  430 {ENDIF}             {
  431                           if (cur)
  432                           {
  433                             cur->statement=stmt_ENDIF;
  434                           }
  435                           return T_ENDIF;
  436                         }
  437 {ENDPROC}       {
  438                           if (cur)
  439                           {
  440                             cur->statement=stmt_ENDPROC_SUBEND;
  441                           }
  442                           return T_ENDPROC;
  443                         }
  444 {ENDSELECT}     {
  445                           if (cur)
  446                           {
  447                             cur->statement=stmt_ENDSELECT;
  448                           }
  449                           return T_ENDSELECT;
  450                         }
  451 "end"[ \t]*"sub"    {
  452                           if (cur)
  453                           {
  454                             cur->statement=stmt_ENDPROC_SUBEND;
  455                           }
  456                           return T_SUBEND;
  457                         }
  458 "end"               {
  459                           if (cur)
  460                           {
  461                             cur->statement=stmt_END;
  462                           }
  463                           return T_END;
  464                         }
  465 "environ"       {
  466                           if (cur)
  467                           {
  468                             cur->statement=stmt_ENVIRON;
  469                           }
  470                           return T_ENVIRON;
  471                         }
  472 "erase"             {
  473                           if (cur)
  474                           {
  475                             cur->statement=stmt_ERASE;
  476                           }
  477                           return T_ERASE;
  478                         }
  479 "eqv"           return T_EQV;
  480 {EXITDO}        {
  481                           if (cur)
  482                           {
  483                             cur->statement=stmt_EXITDO;
  484                           }
  485                           return T_EXITDO;
  486                         }
  487 {EXITFOR}       {
  488                           if (cur)
  489                           {
  490                             cur->statement=stmt_EXITFOR;
  491                           }
  492                           return T_EXITFOR;
  493                         }
  494 "exit"[ \t]+"function"  {
  495                           if (cur)
  496                           {
  497                             cur->statement=stmt_FNEXIT;
  498                           }
  499                           return T_FNEXIT;
  500                         }
  501 "exit"[ \t]+"sub"   {
  502                           if (cur)
  503                           {
  504                             cur->statement=stmt_SUBEXIT;
  505                           }
  506                           return T_SUBEXIT;
  507                         }
  508 "field"         {
  509                           if (cur)
  510                           {
  511                             cur->statement=stmt_FIELD;
  512                           }
  513                           return T_FIELD;
  514                         }
  515 "field"/"#"     {
  516                           if (cur)
  517                           {
  518                             cur->statement=stmt_FIELD;
  519                           }
  520                           return T_FIELD;
  521                         }
  522 "files"         {
  523                           if (cur)
  524                           {
  525                             cur->statement=stmt_FILES;
  526                           }
  527                           return T_FILES;
  528                         }
  529 "fnend"         {
  530                           if (cur)
  531                           {
  532                             cur->statement=stmt_EQ_FNRETURN_FNEND;
  533                           }
  534                           return T_FNEND;
  535                         }
  536 "fnreturn"      {
  537                           if (cur)
  538                           {
  539                             cur->statement=stmt_EQ_FNRETURN_FNEND;
  540                           }
  541                           return T_FNRETURN;
  542                         }
  543 "for"               {
  544                           if (cur)
  545                           {
  546                             cur->statement=stmt_FOR;
  547                           }
  548                           return T_FOR;
  549                         }
  550 "for"[ \t]+"input"      return T_FOR_INPUT;
  551 "for"[ \t]+"output"     return T_FOR_OUTPUT;
  552 "for"[ \t]+"append"     return T_FOR_APPEND;
  553 "for"[ \t]+"random"     return T_FOR_RANDOM;
  554 "for"[ \t]+"binary"     return T_FOR_BINARY;
  555 "function"      {
  556                       if (cur)
  557                       {
  558                         cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
  559                         cur->u.localSyms=(struct Symbol*)0;
  560                       }
  561                       return T_FUNCTION;
  562                     }
  563 "get"           {
  564                           if (cur)
  565                           {
  566                             cur->statement=stmt_GET_PUT;
  567                           }
  568                           return T_GET;
  569                         }
  570 "get"/"#"       {
  571                           if (cur)
  572                           {
  573                             cur->statement=stmt_GET_PUT;
  574                           }
  575                           return T_GET;
  576                         }
  577 "go"[ \t]*"sub"         {
  578                           if (cur)
  579                           {
  580                             cur->statement=stmt_GOSUB;
  581                           }
  582                           return T_GOSUB;
  583                         }
  584 "go"[ \t]*"to"      {
  585                           if (cur)
  586                           {
  587                             cur->statement=stmt_RESUME_GOTO;
  588                           }
  589                           return T_GOTO;
  590                         }
  591 "idn"           return T_IDN;
  592 "if"                {
  593                           if (cur)
  594                           {
  595                             cur->statement=stmt_IF_ELSEIFIF;
  596                           }
  597                           return T_IF;
  598                         }
  599 "image"[ \t]*/[^"\n \t] {
  600               BEGIN(IMAGEFMT);
  601                       if (cur)
  602                       {
  603                         cur->statement=stmt_IMAGE;
  604                       }
  605                       return T_IMAGE;
  606             }
  607 <IMAGEFMT>.*$       {
  608               BEGIN(INITIAL);
  609                       if (cur)
  610                       {
  611                             size_t l;
  612 
  613                         l=strlen(yytext);
  614                             cur->u.string=malloc(sizeof(struct String));
  615                             String_size(String_new(cur->u.string),l);
  616                             memcpy(cur->u.string->character,yytext,l);
  617                       }
  618                       return T_STRING;
  619                     }
  620 "image"         {
  621                       if (cur)
  622                       {
  623                         cur->statement=stmt_IMAGE;
  624                       }
  625                       return T_IMAGE;
  626                     }
  627 "imp"           return T_IMP;
  628 "inc"           {
  629                           if (cur)
  630                           {
  631                             cur->statement=stmt_DEC_INC;
  632                           }
  633                           return T_INC;
  634                         }
  635 "input"         {
  636                           if (cur)
  637                           {
  638                             cur->statement=stmt_INPUT;
  639                           }
  640                           return T_INPUT;
  641                         }
  642 "input"/"#"     {
  643                           if (cur)
  644                           {
  645                             cur->statement=stmt_INPUT;
  646                           }
  647                           return T_INPUT;
  648                         }
  649 "inv"           return T_INV;
  650 "is"            return T_IS;
  651 "kill"          {
  652                           if (cur)
  653                           {
  654                             cur->statement=stmt_KILL;
  655                           }
  656                           return T_KILL;
  657                         }
  658 "let"               {
  659                           if (cur)
  660                           {
  661                             cur->statement=stmt_LET;
  662                           }
  663                           return T_LET;
  664                         }
  665 "list"              {
  666                           if (cur)
  667                           {
  668                             cur->statement=stmt_LIST_LLIST;
  669                           }
  670                           return T_LIST;
  671                         }
  672 "llist"         {
  673                           if (cur)
  674                           {
  675                             cur->statement=stmt_LIST_LLIST;
  676                           }
  677                           return T_LLIST;
  678                         }
  679 "load"              {
  680                           if (cur)
  681                           {
  682                             cur->statement=stmt_LOAD;
  683                           }
  684                           return T_LOAD;
  685                         }
  686 "local"         {
  687                           if (cur)
  688                           {
  689                             cur->statement=stmt_LOCAL;
  690                           }
  691                           return T_LOCAL;
  692                         }
  693 "locate"        {
  694                           if (cur)
  695                           {
  696                             cur->statement=stmt_LOCATE;
  697                           }
  698                           return T_LOCATE;
  699                         }
  700 "lock"          {
  701                           if (cur)
  702                           {
  703                             cur->statement=stmt_LOCK_UNLOCK;
  704                           }
  705                           return T_LOCK;
  706                         }
  707 "lock"[ \t]+"read"  return T_LOCK_READ;
  708 "lock"[ \t]+"write" return T_LOCK_WRITE;
  709 "loop"          {
  710                           if (cur)
  711                           {
  712                             cur->statement=stmt_LOOP;
  713                           }
  714                           return T_LOOP;
  715                         }
  716 {LOOPUNTIL}     {
  717                           if (cur)
  718                           {
  719                             cur->statement=stmt_LOOPUNTIL;
  720                           }
  721                           return T_LOOPUNTIL;
  722                         }
  723 "lprint"        {
  724                           if (cur)
  725                           {
  726                             cur->statement=stmt_PRINT_LPRINT;
  727                           }
  728                           return T_LPRINT;
  729                         }
  730 "lset"          {
  731                           if (cur)
  732                           {
  733                             cur->statement=stmt_LSET_RSET;
  734                           }
  735                           return T_LSET;
  736                         }
  737 "mat"[ \t]+"input"  {
  738                           if (cur)
  739                           {
  740                             cur->statement=stmt_MATINPUT;
  741                           }
  742                           return T_MATINPUT;
  743                         }
  744 "mat"[ \t]+"print"  {
  745                           if (cur)
  746                           {
  747                             cur->statement=stmt_MATPRINT;
  748                           }
  749                           return T_MATPRINT;
  750                         }
  751 "mat"[ \t]+"read"   {
  752                           if (cur)
  753                           {
  754                             cur->statement=stmt_MATREAD;
  755                           }
  756                           return T_MATREAD;
  757                         }
  758 "mat"[ \t]+"redim"  {
  759                           if (cur)
  760                           {
  761                             cur->statement=stmt_MATREDIM;
  762                           }
  763                           return T_MATREDIM;
  764                         }
  765 "mat"[ \t]+"write"  {
  766                           if (cur)
  767                           {
  768                             cur->statement=stmt_MATWRITE;
  769                           }
  770                           return T_MATWRITE;
  771                         }
  772 "mat"           {
  773                           if (cur)
  774                           {
  775                             cur->statement=stmt_MAT;
  776                           }
  777                           return T_MAT;
  778                         }
  779 "mkdir"         {
  780                           if (cur)
  781                           {
  782                             cur->statement=stmt_CHDIR_MKDIR;
  783                           }
  784                           return T_MKDIR;
  785                         }
  786 "mod"               return T_MOD;
  787 "new"               {
  788                           if (cur)
  789                           {
  790                             cur->statement=stmt_NEW;
  791                           }
  792                           return T_NEW;
  793                         }
  794 "name"          {
  795                           if (cur)
  796                           {
  797                             cur->statement=stmt_NAME;
  798                           }
  799                           return T_NAME;
  800                         }
  801 "next"              {
  802                       if (cur)
  803                       {
  804                             cur->statement=stmt_NEXT;
  805                         cur->u.next=malloc(sizeof(struct Next));
  806                       }
  807               return T_NEXT;
  808                     }
  809 "not"           return T_NOT;
  810 {ONERROROFF}        {
  811                           if (cur)
  812                           {
  813                             cur->statement=stmt_ONERROROFF;
  814                           }
  815                           return T_ONERROROFF;
  816                         }
  817 {ONERRORGOTO0}      {
  818                           if (cur)
  819                           {
  820                             cur->statement=stmt_ONERRORGOTO0;
  821                           }
  822                           return T_ONERRORGOTO0;
  823                         }
  824 {ONERROR}       {
  825                           if (cur)
  826                           {
  827                             cur->statement=stmt_ONERROR;
  828                           }
  829                           return T_ONERROR;
  830                         }
  831 "on"            {
  832               if (cur)
  833               {
  834                 cur->statement=stmt_ON;
  835                 cur->u.on.pcLength=1;
  836                 cur->u.on.pc=(struct Pc*)0;
  837               }
  838               return T_ON;
  839             }
  840 "open"          {
  841                           if (cur)
  842                           {
  843                             cur->statement=stmt_OPEN;
  844                           }
  845                           return T_OPEN;
  846                         }
  847 "option"[ \t]+"base"    {
  848                           if (cur)
  849                           {
  850                             cur->statement=stmt_OPTIONBASE;
  851                           }
  852                           return T_OPTIONBASE;
  853                         }
  854 "option"[ \t]+"run" {
  855                           if (cur)
  856                           {
  857                             cur->statement=stmt_OPTIONRUN;
  858                           }
  859                           return T_OPTIONRUN;
  860                         }
  861 "option"[ \t]+"stop"    {
  862                           if (cur)
  863                           {
  864                             cur->statement=stmt_OPTIONSTOP;
  865                           }
  866                           return T_OPTIONSTOP;
  867                         }
  868 "or"            return T_OR;
  869 "out"           {
  870                           if (cur)
  871                           {
  872                             cur->statement=stmt_OUT_POKE;
  873                           }
  874                           return T_OUT;
  875                         }
  876 "print"|"p."|"?"    {
  877                           if (cur)
  878                           {
  879                             cur->statement=stmt_PRINT_LPRINT;
  880                           }
  881                           return T_PRINT;
  882                         }
  883 ("print"|"p."|"?")/"#"  {
  884                           if (cur)
  885                           {
  886                             cur->statement=stmt_PRINT_LPRINT;
  887                           }
  888                           return T_PRINT;
  889                         }
  890 "poke"          {
  891                           if (cur)
  892                           {
  893                             cur->statement=stmt_OUT_POKE;
  894                           }
  895                           return T_POKE;
  896                         }
  897 "put"           {
  898                           if (cur)
  899                           {
  900                             cur->statement=stmt_GET_PUT;
  901                           }
  902                           return T_PUT;
  903                         }
  904 "put"/"#"       {
  905                           if (cur)
  906                           {
  907                             cur->statement=stmt_GET_PUT;
  908                           }
  909                           return T_PUT;
  910                         }
  911 "randomize"         {
  912                           if (cur)
  913                           {
  914                             cur->statement=stmt_RANDOMIZE;
  915                           }
  916                           return T_RANDOMIZE;
  917                         }
  918 "read"          {
  919                           if (cur)
  920                           {
  921                             cur->statement=stmt_READ;
  922                           }
  923                           return T_READ;
  924                         }
  925 "renum"|"ren."      {
  926                           if (cur)
  927                           {
  928                             cur->statement=stmt_RENUM;
  929                           }
  930                           return T_RENUM;
  931                         }
  932 "repeat"|"rep."     {
  933                           if (cur)
  934                           {
  935                             cur->statement=stmt_REPEAT;
  936                           }
  937                           return T_REPEAT;
  938                         }
  939 "restore"|"res."    {
  940                           if (cur)
  941                           {
  942                             cur->statement=stmt_RESTORE;
  943                           }
  944                           return T_RESTORE;
  945                         }
  946 "resume"        {
  947                           if (cur)
  948                           {
  949                             cur->statement=stmt_RESUME_GOTO;
  950                           }
  951                           return T_RESUME;
  952                         }
  953 "return"|"r."       {
  954                           if (cur)
  955                           {
  956                             cur->statement=stmt_RETURN;
  957                           }
  958                           return T_RETURN;
  959                         }
  960 "rset"          {
  961                           if (cur)
  962                           {
  963                             cur->statement=stmt_LSET_RSET;
  964                           }
  965                           return T_RSET;
  966                         }
  967 "run"               {
  968                           if (cur)
  969                           {
  970                             cur->statement=stmt_RUN;
  971                           }
  972                           return T_RUN;
  973                         }
  974 "save"          {
  975                           if (cur)
  976                           {
  977                             cur->statement=stmt_SAVE;
  978                           }
  979                           return T_SAVE;
  980                         }
  981 {SELECTCASE}        {
  982               if (cur)
  983               {
  984                 cur->statement=stmt_SELECTCASE;
  985                 cur->u.selectcase=malloc(sizeof(struct Selectcase));
  986               }
  987               return T_SELECTCASE;
  988             }
  989 "shared"        return T_SHARED;
  990 "shell"         {
  991                           if (cur)
  992                           {
  993                             cur->statement=stmt_SHELL;
  994                           }
  995                           return T_SHELL;
  996                         }
  997 "sleep"         {
  998                           if (cur)
  999                           {
 1000                             cur->statement=stmt_SLEEP;
 1001                           }
 1002                           return T_SLEEP;
 1003                         }
 1004 "spc"           return T_SPC;
 1005 "step"          {
 1006                           if (cur)
 1007                           {
 1008                             Value_new_NIL(&cur->u.step);
 1009                           }
 1010                           return T_STEP;
 1011                         }
 1012 "stop"              {
 1013                           if (cur)
 1014                           {
 1015                             cur->statement=stmt_STOP;
 1016                           }
 1017                           return T_STOP;
 1018                         }
 1019 "sub"[ \t]*"end"    {
 1020                           if (cur)
 1021                           {
 1022                             cur->statement=stmt_ENDPROC_SUBEND;
 1023                           }
 1024                           return T_SUBEND;
 1025                         }
 1026 "sub"[ \t]*"exit"   {
 1027                           if (cur)
 1028                           {
 1029                             cur->statement=stmt_SUBEXIT;
 1030                           }
 1031                           return T_SUBEXIT;
 1032                         }
 1033 "sub"           {
 1034                       if (cur)
 1035                       {
 1036                         cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
 1037                         cur->u.localSyms=(struct Symbol*)0;
 1038                       }
 1039                       return T_SUB;
 1040                     }
 1041 "swap"          {
 1042                           if (cur)
 1043                           {
 1044                             cur->statement=stmt_SWAP;
 1045                           }
 1046                           return T_SWAP;
 1047                         }
 1048 "system"|"bye"          {
 1049                           if (cur)
 1050                           {
 1051                             cur->statement=stmt_SYSTEM;
 1052                           }
 1053                           return T_SYSTEM;
 1054                         }
 1055 "then"|"th."        return T_THEN;
 1056 "tab"           return T_TAB;
 1057 "to"                return T_TO;
 1058 "trn"           return T_TRN;
 1059 "troff"             {
 1060                           if (cur)
 1061                           {
 1062                             cur->statement=stmt_TROFF;
 1063                           }
 1064                           return T_TROFF;
 1065                         }
 1066 "tron"              {
 1067                           if (cur)
 1068                           {
 1069                             cur->statement=stmt_TRON;
 1070                           }
 1071                           return T_TRON;
 1072                         }
 1073 "truncate"      {
 1074                           if (cur)
 1075                           {
 1076                             cur->statement=stmt_TRUNCATE;
 1077                           }
 1078                           return T_TRUNCATE;
 1079                         }
 1080 "unlock"        {
 1081                           if (cur)
 1082                           {
 1083                             cur->statement=stmt_LOCK_UNLOCK;
 1084                           }
 1085                           return T_UNLOCK;
 1086                         }
 1087 "unnum"         {
 1088                           if (cur)
 1089                           {
 1090                             cur->statement=stmt_UNNUM;
 1091                           }
 1092                           return T_UNNUM;
 1093                         }
 1094 "until"             {
 1095                           if (cur)
 1096                           {
 1097                             cur->statement=stmt_UNTIL;
 1098                           }
 1099                           return T_UNTIL;
 1100                         }
 1101 "using"         return T_USING;
 1102 "wait"          {
 1103                           if (cur)
 1104                           {
 1105                             cur->statement=stmt_WAIT;
 1106                           }
 1107                           return T_WAIT;
 1108                         }
 1109 "wend"              {
 1110                       if (cur)
 1111                       {
 1112                         cur->statement=stmt_WEND;
 1113                         cur->u.whilepc=malloc(sizeof(struct Pc));
 1114                       }
 1115                       return T_WEND;
 1116                     }
 1117 "while"             {
 1118                       if (cur)
 1119                       {
 1120                         cur->statement=stmt_WHILE;
 1121                         cur->u.afterwend=malloc(sizeof(struct Pc));
 1122                       }
 1123                       return T_WHILE;
 1124                     }
 1125 "width"         {
 1126                           if (cur)
 1127                           {
 1128                             cur->statement=stmt_WIDTH;
 1129                           }
 1130                           return T_WIDTH;
 1131                         }
 1132 "width"/"#"     {
 1133                           if (cur)
 1134                           {
 1135                             cur->statement=stmt_WIDTH;
 1136                           }
 1137                           return T_WIDTH;
 1138                         }
 1139 "write"         {
 1140                           if (cur)
 1141                           {
 1142                             cur->statement=stmt_WRITE;
 1143                           }
 1144                           return T_WRITE;
 1145                         }
 1146 "write"/"#"     {
 1147                           if (cur)
 1148                           {
 1149                             cur->statement=stmt_WRITE;
 1150                           }
 1151                           return T_WRITE;
 1152                         }
 1153 "xor"           return T_XOR;
 1154 "xref"          {
 1155                           if (cur)
 1156                           {
 1157                             cur->statement=stmt_XREF;
 1158                           }
 1159                           return T_XREF;
 1160                         }
 1161 "zer"           return T_ZER;
 1162 "zone"          {
 1163                           if (cur)
 1164                           {
 1165                             cur->statement=stmt_ZONE;
 1166                           }
 1167                           return T_ZONE;
 1168                         }
 1169 {REM}               {
 1170                       if (cur)
 1171                       {
 1172                         cur->statement=stmt_QUOTE_REM;
 1173                         cur->u.rem=strcpy(malloc(strlen(yytext+3)+1),yytext+3);
 1174                       }
 1175                       return T_REM;
 1176                     }
 1177 "rename"        {
 1178                           if (cur)
 1179                           {
 1180                             cur->statement=stmt_COPY_RENAME;
 1181                           }
 1182                           return T_RENAME;
 1183                         }
 1184 {QUOTE}             {
 1185                       if (cur)
 1186                       {
 1187                         cur->statement=stmt_QUOTE_REM;
 1188                         strcpy(cur->u.rem=malloc(strlen(yytext+1)+1),yytext+1);
 1189                           }     
 1190                       return T_QUOTE;
 1191                     }
 1192 {LINEINPUT}     {
 1193                           if (cur)
 1194                           {
 1195                             cur->statement=stmt_LINEINPUT;
 1196                           }
 1197                           return T_LINEINPUT;
 1198                         }
 1199 {IDENTIFIER}        {
 1200               if (cur)
 1201               {
 1202                             size_t len;
 1203                             char *s;
 1204                             int fn;
 1205 
 1206                             cur->statement=stmt_IDENTIFIER;
 1207                             if (tolower(yytext[0])=='f' && tolower(yytext[1])=='n')
 1208                             {
 1209                               for (len=2,s=&yytext[2]; *s==' ' || *s=='\t'; ++s);
 1210                               fn=1;
 1211                             }
 1212                             else
 1213                             {
 1214                               len=0;
 1215                               s=yytext;
 1216                               fn=0;
 1217                             }
 1218                             len+=strlen(s);
 1219                 cur->u.identifier=malloc(offsetof(struct Identifier,name)+len+1);
 1220                             if (fn)
 1221                             {
 1222                               memcpy(cur->u.identifier->name,yytext,2);
 1223                               strcpy(cur->u.identifier->name+2,s);
 1224                             }
 1225                             else
 1226                             {
 1227                               strcpy(cur->u.identifier->name,s);
 1228                             }
 1229                 switch (yytext[yyleng-1])
 1230                 {
 1231                   case '$': cur->u.identifier->defaultType=V_STRING; break;
 1232                   case '%': cur->u.identifier->defaultType=V_INTEGER; break;
 1233                   default: cur->u.identifier->defaultType=V_REAL; break;
 1234                 }
 1235               }
 1236               return T_IDENTIFIER;
 1237             }
 1238 [ \t\n]+
 1239 .           {
 1240               if (cur) cur->u.junk=yytext[0];
 1241               return T_JUNK;
 1242             }
 1243  /*}}}*/
 1244 %%
 1245 
 1246 int Token_property[T_LASTTOKEN];
 1247 
 1248 struct Token *Token_newCode(const char *ln) /*{{{*/
 1249 {
 1250   int l,lasttok,thistok,addNumber=0,sawif;
 1251   struct Token *result;
 1252   YY_BUFFER_STATE buf;
 1253 
 1254   cur=(struct Token*)0;
 1255   buf=yy_scan_string(ln);
 1256   /* determine number of tokens */ /*{{{*/
 1257   matchdata=sawif=0;
 1258   for (lasttok=T_EOL,l=1; (thistok=yylex()); ++l)
 1259   {
 1260     if (l==1 && thistok!=T_INTEGER) { addNumber=1; ++l; }
 1261     if ((lasttok==T_THEN || lasttok==T_ELSE) && thistok==T_INTEGER) ++l;
 1262     if (thistok==T_IF) sawif=1;
 1263     if (thistok==T_THEN) sawif=0;
 1264     if (thistok==T_GOTO && sawif) ++l;
 1265     lasttok=thistok;
 1266   }
 1267   if (l==1) { addNumber=1; ++l; }
 1268   /*}}}*/
 1269   yy_delete_buffer(buf);
 1270   cur=result=malloc(sizeof(struct Token)*l);
 1271   if (addNumber)
 1272   {
 1273     cur->type=T_UNNUMBERED;
 1274     ++cur;
 1275   }
 1276   buf=yy_scan_string(ln);
 1277   lasttok=T_EOL;
 1278   matchdata=sawif=0;
 1279   while (cur->statement=NULL,(cur->type=yylex()))
 1280   {
 1281     if (cur->type==T_IF) sawif=1;
 1282     if (cur->type==T_THEN) sawif=0;
 1283     if (cur->type==T_GOTO && sawif)
 1284     {
 1285       sawif=0;
 1286       *(cur+1)=*cur;
 1287       cur->type=T_THEN;
 1288       lasttok=T_GOTO;
 1289       cur+=2;
 1290     }
 1291     else if ((lasttok==T_THEN || lasttok==T_ELSE) && cur->type==T_INTEGER)
 1292     {
 1293       *(cur+1)=*cur;
 1294       cur->type=T_GOTO;
 1295       cur->statement=stmt_RESUME_GOTO;
 1296       lasttok=T_INTEGER;
 1297       cur+=2;
 1298     }
 1299     else
 1300     {
 1301       lasttok=cur->type;
 1302       ++cur;
 1303     }
 1304   }
 1305   cur->type=T_EOL;
 1306   cur->statement=stmt_COLON_EOL;
 1307   yy_delete_buffer(buf);
 1308   return result;
 1309 }
 1310 /*}}}*/
 1311 struct Token *Token_newData(const char *ln) /*{{{*/
 1312 {
 1313   int l;
 1314   struct Token *result;
 1315   YY_BUFFER_STATE buf;
 1316 
 1317   cur=(struct Token*)0;
 1318   buf=yy_scan_string(ln);
 1319   matchdata=1;
 1320   for (l=1; yylex(); ++l);
 1321   yy_delete_buffer(buf);
 1322   cur=result=malloc(sizeof(struct Token)*l);
 1323   buf=yy_scan_string(ln);
 1324   matchdata=1;
 1325   while (cur->statement=NULL,(cur->type=yylex())) ++cur;
 1326   cur->type=T_EOL;
 1327   cur->statement=stmt_COLON_EOL;
 1328   yy_delete_buffer(buf);
 1329   return result;
 1330 }
 1331 /*}}}*/
 1332 void Token_destroy(struct Token *token) /*{{{*/
 1333 {
 1334   struct Token *r=token;
 1335 
 1336   do
 1337   {
 1338     switch (r->type)
 1339     {
 1340       case T_ACCESS_READ:       break;
 1341       case T_ACCESS_WRITE:      break;
 1342       case T_AND:               break;
 1343       case T_AS:                break;
 1344       case T_CALL:              break;
 1345       case T_CASEELSE:
 1346       case T_CASEVALUE:         free(r->u.casevalue); break;
 1347       case T_CHANNEL:           break;
 1348       case T_CHDIR:             break;
 1349       case T_CLEAR:             break;
 1350       case T_CLOSE:             break;
 1351       case T_CLS:               break;
 1352       case T_COLON:             break;
 1353       case T_COLOR:             break;
 1354       case T_COMMA:             break;
 1355       case T_CON:               break;
 1356       case T_COPY:              break;
 1357       case T_CP:                break;
 1358       case T_DATA:              break;
 1359       case T_DATAINPUT:         free(r->u.datainput); break;
 1360       case T_DEC:               break;
 1361       case T_DEFFN:             break;
 1362       case T_DEFDBL:            break;
 1363       case T_DEFINT:            break;
 1364       case T_DEFPROC:           break;
 1365       case T_DEFSTR:            break;
 1366       case T_DELETE:            break;
 1367       case T_DIM:               break;
 1368       case T_DISPLAY:           break;
 1369       case T_DIV:               break;
 1370       case T_DO:                break;
 1371       case T_DOUNTIL:           break;
 1372       case T_DOWHILE:           break;
 1373       case T_EDIT:              break;
 1374       case T_ELSE:              break;
 1375       case T_ELSEIFELSE:        break;
 1376       case T_ELSEIFIF:          break;
 1377       case T_END:               break;
 1378       case T_ENDFN:             break;
 1379       case T_ENDIF:             break;
 1380       case T_ENDPROC:           break;
 1381       case T_ENDSELECT:         break;
 1382       case T_ENVIRON:           break;
 1383       case T_EOL:               break;
 1384       case T_EQ:                break;
 1385       case T_EQV:               break;
 1386       case T_ERASE:             break;
 1387       case T_EXITDO:            break;
 1388       case T_EXITFOR:           break;
 1389       case T_FIELD:             break;
 1390       case T_FILES:             break;
 1391       case T_FNEND:             break;
 1392       case T_FNEXIT:            break;
 1393       case T_FNRETURN:          break;
 1394       case T_FOR:               break;
 1395       case T_FOR_INPUT:         break;
 1396       case T_FOR_OUTPUT:        break;
 1397       case T_FOR_APPEND:        break;
 1398       case T_FOR_RANDOM:        break;
 1399       case T_FOR_BINARY:        break;
 1400       case T_FUNCTION:          break;
 1401       case T_GE:                break;
 1402       case T_GET:               break;
 1403       case T_GOSUB:             break;
 1404       case T_GOTO:              break;
 1405       case T_GT:                break;
 1406       case T_HEXINTEGER:        break;
 1407       case T_OCTINTEGER:        break;
 1408       case T_IDENTIFIER:        free(r->u.identifier); break;
 1409       case T_IDIV:              break;
 1410       case T_IDN:               break;
 1411       case T_IF:                break;
 1412       case T_IMAGE:             break;
 1413       case T_IMP:               break;
 1414       case T_INC:               break;
 1415       case T_INPUT:             break;
 1416       case T_INTEGER:           break;
 1417       case T_INV:               break;
 1418       case T_IS:                break;
 1419       case T_JUNK:              break;
 1420       case T_KILL:              break;
 1421       case T_LE:                break;
 1422       case T_LET:               break;
 1423       case T_LINEINPUT:         break;
 1424       case T_LIST:              break;
 1425       case T_LLIST:             break;
 1426       case T_LOAD:              break;
 1427       case T_LOCAL:             break;
 1428       case T_LOCATE:            break;
 1429       case T_LOCK:              break;
 1430       case T_LOCK_READ:         break;
 1431       case T_LOCK_WRITE:        break;
 1432       case T_LOOP:              break;
 1433       case T_LOOPUNTIL:         break;
 1434       case T_LPRINT:            break;
 1435       case T_LSET:              break;
 1436       case T_LT:                break;
 1437       case T_MAT:               break;
 1438       case T_MATINPUT:          break;
 1439       case T_MATPRINT:          break;
 1440       case T_MATREAD:           break;
 1441       case T_MATREDIM:          break;
 1442       case T_MATWRITE:          break;
 1443       case T_MINUS:             break;
 1444       case T_MKDIR:             break;
 1445       case T_MOD:               break;
 1446       case T_MULT:              break;
 1447       case T_NAME:              break;
 1448       case T_NE:                break;
 1449       case T_NEW:               break;
 1450       case T_NEXT:              free(r->u.next); break;
 1451       case T_NOT:               break;
 1452       case T_ON:                if (r->u.on.pc) free(r->u.on.pc); break;
 1453       case T_ONERROR:           break;
 1454       case T_ONERRORGOTO0:      break;
 1455       case T_ONERROROFF:        break;
 1456       case T_OP:                break;
 1457       case T_OPEN:              break;
 1458       case T_OPTIONBASE:        break;
 1459       case T_OPTIONRUN:         break;
 1460       case T_OPTIONSTOP:        break;
 1461       case T_OR:                break;
 1462       case T_OUT:       break;
 1463       case T_PLUS:              break;
 1464       case T_POKE:      break;
 1465       case T_POW:               break;
 1466       case T_PRINT:             break;
 1467       case T_PUT:               break;
 1468       case T_QUOTE:             free(r->u.rem); break;
 1469       case T_RANDOMIZE:         break;
 1470       case T_READ:              break;
 1471       case T_REAL:              break;
 1472       case T_REM:               free(r->u.rem); break;
 1473       case T_RENAME:            break;
 1474       case T_RENUM:             break;
 1475       case T_REPEAT:            break;
 1476       case T_RESTORE:           break;
 1477       case T_RESUME:            break;
 1478       case T_RETURN:            break;
 1479       case T_RSET:              break;
 1480       case T_RUN:               break;
 1481       case T_SAVE:              break;
 1482       case T_SELECTCASE:        free(r->u.selectcase); break;
 1483       case T_SEMICOLON:         break;
 1484       case T_SHARED:            break;
 1485       case T_SHELL:             break;
 1486       case T_SLEEP:             break;
 1487       case T_SPC:               break;
 1488       case T_STEP:              Value_destroy(&r->u.step); break;
 1489       case T_STOP:              break;
 1490       case T_STRING:            String_destroy(r->u.string); free(r->u.string); break;
 1491       case T_SUB:               break;
 1492       case T_SUBEND:            break;
 1493       case T_SUBEXIT:           break;
 1494       case T_SWAP:              break;
 1495       case T_SYSTEM:            break;
 1496       case T_TAB:               break;
 1497       case T_THEN:              break;
 1498       case T_TO:                break;
 1499       case T_TRN:               break;
 1500       case T_TROFF:             break;
 1501       case T_TRON:              break;
 1502       case T_TRUNCATE:          break;
 1503       case T_UNLOCK:            break;
 1504       case T_UNNUM:             break;
 1505       case T_UNNUMBERED:        break;
 1506       case T_UNTIL:             break;
 1507       case T_USING:             break;
 1508       case T_WAIT:              break;
 1509       case T_WEND:              free(r->u.whilepc); break;
 1510       case T_WHILE:             free(r->u.afterwend); break;
 1511       case T_WIDTH:             break;
 1512       case T_WRITE:             break;
 1513       case T_XOR:               break;
 1514       case T_XREF:              break;
 1515       case T_ZER:               break;
 1516       case T_ZONE:              break;
 1517       default:                  assert(0);
 1518     }
 1519   } while ((r++)->type!=T_EOL);
 1520   free(token);
 1521 }
 1522 /*}}}*/
 1523 struct String *Token_toString(struct Token *token, struct Token *spaceto, struct String *s, int *indent, int width) /*{{{*/
 1524 {
 1525   int ns=0,infn=0;
 1526   int thisindent=0,thisnotindent=0,nextindent=0;
 1527   size_t oldlength=s->length;
 1528   struct Token *t;
 1529   static struct
 1530   {
 1531     const char *text;
 1532     char space;
 1533   } table[]=
 1534   {
 1535     /* 0                    */ {(const char*)0,-1},
 1536     /* T_ACCESS_READ        */ {"access read",1},
 1537     /* T_ACCESS_READ_WRITE  */ {"access read write",1},
 1538     /* T_ACCESS_WRITE       */ {"access write",1},
 1539     /* T_AND                */ {"and",1},
 1540     /* T_AS                 */ {"as",1},
 1541     /* T_CALL               */ {"call",1},
 1542     /* T_CASEELSE           */ {"case else",1},
 1543     /* T_CASEVALUE          */ {"case",1},
 1544     /* T_CHANNEL            */ {"#",0},
 1545     /* T_CHDIR              */ {"chdir",1},
 1546     /* T_CLEAR              */ {"clear",1},
 1547     /* T_CLOSE              */ {"close",1},
 1548     /* T_CLS                */ {"cls",1},
 1549     /* T_COLON              */ {":",1},
 1550     /* T_COLOR              */ {"color",1},
 1551     /* T_COMMA              */ {",",0},
 1552     /* T_CON                */ {"con",0},
 1553     /* T_COPY               */ {"copy",1},
 1554     /* T_CP                 */ {")",0},
 1555     /* T_DATA               */ {"data",1},
 1556     /* T_DATAINPUT          */ {(const char*)0,0},
 1557     /* T_DEC                */ {"dec",1},
 1558     /* T_DEFDBL             */ {"defdbl",1},
 1559     /* T_DEFFN              */ {"def",1},
 1560     /* T_DEFINT             */ {"defint",1},
 1561     /* T_DEFPROC            */ {"def",1},
 1562     /* T_DEFSTR             */ {"defstr",1},
 1563     /* T_DELETE             */ {"delete",1},
 1564     /* T_DIM                */ {"dim",1},
 1565     /* T_DISPLAY            */ {"display",1},
 1566     /* T_DIV                */ {"/",0},
 1567     /* T_DO                 */ {"do",1},
 1568     /* T_DOUNTIL            */ {"do until",1},
 1569     /* T_DOWHILE            */ {"do while",1},
 1570     /* T_EDIT               */ {"edit",1},
 1571     /* T_ELSE               */ {"else",1},
 1572     /* T_ELSEIFELSE         */ {"elseif",1},
 1573     /* T_ELSEIFIF           */ {(const char*)0,0},
 1574     /* T_END                */ {"end",1},
 1575     /* T_ENDFN              */ {"end function",1},
 1576     /* T_ENDIF              */ {"end if",1},
 1577     /* T_ENDPROC            */ {"end proc",1},
 1578     /* T_ENDSELECT          */ {"end select",1},
 1579     /* T_ENVIRON            */ {"environ",1},
 1580     /* T_EOL                */ {"\n",0},
 1581     /* T_EQ                 */ {"=",0},
 1582     /* T_EQV                */ {"eqv",0},
 1583     /* T_ERASE              */ {"erase",1},
 1584     /* T_EXITDO             */ {"exit do",1},
 1585     /* T_EXITFOR            */ {"exit for",1},
 1586     /* T_FIELD              */ {"field",1},
 1587     /* T_FILES              */ {"files",1},
 1588     /* T_FNEND              */ {"fnend",1},
 1589     /* T_FNEXIT             */ {"exit function",1},
 1590     /* T_FNRETURN           */ {"fnreturn",1},
 1591     /* T_FOR                */ {"for",1},
 1592     /* T_FOR_INPUT          */ {"for input",1},
 1593     /* T_FOR_OUTPUT         */ {"for output",1},
 1594     /* T_FOR_APPEND         */ {"for append",1},
 1595     /* T_FOR_RANDOM         */ {"for random",1},
 1596     /* T_FOR_BINARY         */ {"for binary",1},
 1597     /* T_FUNCTION           */ {"function",1},
 1598     /* T_GE                 */ {">=",0},
 1599     /* T_GET                */ {"get",1},
 1600     /* T_GOSUB              */ {"gosub",1},
 1601     /* T_GOTO               */ {"goto",1},
 1602     /* T_GT                 */ {">",0},
 1603     /* T_HEXINTEGER         */ {(const char*)0,0},
 1604     /* T_OCTINTEGER         */ {(const char*)0,0},
 1605     /* T_IDENTIFIER         */ {(const char*)0,0},
 1606     /* T_IDIV               */ {"\\",0},
 1607     /* T_IDN                */ {"idn",0},
 1608     /* T_IF                 */ {"if",1},
 1609     /* T_IMAGE              */ {"image",1},
 1610     /* T_IMP                */ {"imp",0},
 1611     /* T_INC                */ {"inc",1},
 1612     /* T_INPUT              */ {"input",1},
 1613     /* T_INTEGER            */ {(const char*)0,0},
 1614     /* T_INV                */ {"inv",0},
 1615     /* T_IS                 */ {"is",1},
 1616     /* T_JUNK               */ {(const char*)0,0},
 1617     /* T_KILL               */ {"kill",1},
 1618     /* T_LE                 */ {"<=",0},
 1619     /* T_LET                */ {"let",1},
 1620     /* T_LINEINPUT          */ {"line input",1},
 1621     /* T_LIST               */ {"list",1},
 1622     /* T_LLIST              */ {"llist",1},
 1623     /* T_LOAD               */ {"load",1},
 1624     /* T_LOCAL              */ {"local",1},
 1625     /* T_LOCATE             */ {"locate",1},
 1626     /* T_LOCK               */ {"lock",1},
 1627     /* T_LOCK_READ          */ {"lock read",1},
 1628     /* T_LOCK_WRITE         */ {"lock write",1},
 1629     /* T_LOOP               */ {"loop",1},
 1630     /* T_LOOPUNTIL          */ {"loop until",1},
 1631     /* T_LPRINT             */ {"lprint",1},
 1632     /* T_LSET               */ {"lset",1},
 1633     /* T_LT                 */ {"<",0},
 1634     /* T_MAT                */ {"mat",1},
 1635     /* T_MATINPUT           */ {"mat input",1},
 1636     /* T_MATPRINT           */ {"mat print",1},
 1637     /* T_MATREAD            */ {"mat read",1},
 1638     /* T_MATREDIM           */ {"mat redim",1},
 1639     /* T_MATWRITE           */ {"mat write",1},
 1640     /* T_MINUS              */ {"-",0},
 1641     /* T_MKDIR              */ {"mkdir",1},
 1642     /* T_MOD                */ {"mod",0},
 1643     /* T_MULT               */ {"*",0},
 1644     /* T_NAME               */ {"name",1},
 1645     /* T_NE                 */ {"<>",0},
 1646     /* T_NEW                */ {"new",1},
 1647     /* T_NEXT               */ {"next",1},
 1648     /* T_NOT                */ {"not",0},
 1649     /* T_ON                 */ {"on",1},
 1650     /* T_ONERROR            */ {"on error",1},
 1651     /* T_ONERRORGOTO0       */ {"on error goto 0",1},
 1652     /* T_ONERROROFF         */ {"on error off",1},
 1653     /* T_OP                 */ {"(",0},
 1654     /* T_OPEN               */ {"open",1},
 1655     /* T_OPTIONBASE         */ {"option base",1},
 1656     /* T_OPTIONRUN          */ {"option run",1},
 1657     /* T_OPTIONSTOP         */ {"option stop",1},
 1658     /* T_OR                 */ {"or",1},
 1659     /* T_OUT                */ {"out",1},
 1660     /* T_PLUS               */ {"+",0},
 1661     /* T_POKE               */ {"poke",1},
 1662     /* T_POW                */ {"^",0},
 1663     /* T_PRINT              */ {"print",1},
 1664     /* T_PUT                */ {"put",1},
 1665     /* T_QUOTE              */ {(const char*)0,1},
 1666     /* T_RANDOMIZE          */ {"randomize",1},
 1667     /* T_READ               */ {"read",1},
 1668     /* T_REAL               */ {(const char*)0,0},
 1669     /* T_REM                */ {(const char*)0,1},
 1670     /* T_RENAME             */ {"rename",1},
 1671     /* T_RENUM              */ {"renum",1},
 1672     /* T_REPEAT             */ {"repeat",1},
 1673     /* T_RESTORE            */ {"restore",1},
 1674     /* T_RESUME             */ {"resume",1},
 1675     /* T_RETURN             */ {"return",1},
 1676     /* T_RSET               */ {"rset",1},
 1677     /* T_RUN                */ {"run",1},
 1678     /* T_SAVE               */ {"save",1},
 1679     /* T_SELECTCASE         */ {"select case",1},
 1680     /* T_SEMICOLON          */ {";",0},
 1681     /* T_SHARED             */ {"shared",1},
 1682     /* T_SHELL              */ {"shell",1},
 1683     /* T_SLEEP              */ {"sleep",1},
 1684     /* T_SPC                */ {"spc",0},
 1685     /* T_STEP               */ {"step",1},
 1686     /* T_STOP               */ {"stop",1},
 1687     /* T_STRING             */ {(const char*)0,0},
 1688     /* T_SUB                */ {"sub",1},
 1689     /* T_SUBEND             */ {"subend",1},
 1690     /* T_SUBEXIT            */ {"subexit",1},
 1691     /* T_SWAP               */ {"swap",1},
 1692     /* T_SYSTEM             */ {"system",1},
 1693     /* T_TAB                */ {"tab",0},
 1694     /* T_THEN               */ {"then",1},
 1695     /* T_TO                 */ {"to",1},
 1696     /* T_TRN                */ {"trn",0},
 1697     /* T_TROFF              */ {"troff",1},
 1698     /* T_TRON               */ {"tron",1},
 1699     /* T_TRUNCATE           */ {"truncate",1},
 1700     /* T_UNLOCK             */ {"unlock",1},
 1701     /* T_UNNUM              */ {"unnum",1},
 1702     /* T_UNNUMBERED         */ {"",0},
 1703     /* T_UNTIL              */ {"until",1},
 1704     /* T_USING              */ {"using",0},
 1705     /* T_WAIT               */ {"wait",1},
 1706     /* T_WEND               */ {"wend",1},
 1707     /* T_WHILE              */ {"while",1},
 1708     /* T_WIDTH              */ {"width",1},
 1709     /* T_WRITE              */ {"write",1},
 1710     /* T_XOR                */ {"xor",0},
 1711     /* T_XREF               */ {"xref",0},
 1712     /* T_ZER                */ {"zer",0},
 1713     /* T_ZONE               */ {"zone",1},
 1714   };
 1715 
 1716   /* precompute indentation */ /*{{{*/
 1717   if (indent) thisindent=nextindent=*indent;
 1718   t=token;
 1719   do
 1720   {
 1721     switch (t->type)
 1722     {
 1723       case T_CASEELSE:
 1724       case T_CASEVALUE:
 1725       {
 1726         if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1727         break;
 1728       }
 1729       case T_DEFFN:
 1730       case T_FUNCTION:
 1731       {
 1732         struct Token *cp;
 1733 
 1734         for (cp=t; cp->type!=T_EOL && cp->type!=T_CP; ++cp);
 1735         if ((cp+1)->type!=T_EQ)
 1736         {
 1737           ++thisnotindent;
 1738           ++nextindent;
 1739         }
 1740         infn=1;
 1741         break;
 1742       }
 1743       case T_COLON: infn=0; break;
 1744       case T_DEFPROC:
 1745       case T_DO:
 1746       case T_DOUNTIL:
 1747       case T_DOWHILE:
 1748       case T_REPEAT:
 1749       case T_SUB:
 1750       case T_WHILE: ++thisnotindent; ++nextindent; break;
 1751       case T_FOR:
 1752       {
 1753         if ((t>token && ((t-1)->type==T_COLON || (t-1)->type==T_INTEGER || (t-1)->type==T_UNNUMBERED)))
 1754         {
 1755           ++thisnotindent; ++nextindent;
 1756         }
 1757         break;
 1758       }       
 1759       case T_SELECTCASE: thisnotindent+=2; nextindent+=2; break;
 1760       case T_EQ:
 1761       {
 1762         if (infn || (t>token && ((t-1)->type==T_COLON || (t-1)->type==T_INTEGER || (t-1)->type==T_UNNUMBERED)))
 1763         {
 1764           if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1765           if (nextindent) --nextindent;
 1766         }
 1767         infn=0;
 1768         break;
 1769       }
 1770       case T_ENDFN:
 1771       case T_FNEND:
 1772       case T_ENDIF:
 1773       case T_ENDPROC:
 1774       case T_SUBEND:
 1775       case T_LOOP:
 1776       case T_LOOPUNTIL:
 1777       case T_UNTIL:
 1778       case T_WEND:
 1779       {
 1780         if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1781         if (nextindent) --nextindent;
 1782         break;
 1783       }
 1784       case T_ENDSELECT:
 1785       {
 1786         if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1787         if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1788         if (nextindent) --nextindent;
 1789         if (nextindent) --nextindent;
 1790         break;
 1791       }
 1792       case T_NEXT:
 1793       {
 1794         ++t;
 1795         while (1)
 1796         {
 1797           if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1798           if (nextindent) --nextindent;
 1799           if (t->type==T_IDENTIFIER)
 1800           {
 1801             ++t;
 1802             if (t->type==T_OP)
 1803             {
 1804               int par=0;
 1805 
 1806               do
 1807               {
 1808                 if (t->type==T_OP) ++par;
 1809                 else if (t->type==T_CP) --par;
 1810                 if (t->type!=T_EOL) ++t;
 1811                 else break;
 1812               } while (par);
 1813             }
 1814             if (t->type==T_COMMA) ++t;
 1815             else break;
 1816           }
 1817           else break;
 1818         }
 1819         break;
 1820       }
 1821       case T_THEN: if ((t+1)->type==T_EOL) { ++thisnotindent; ++nextindent; } break;
 1822       case T_ELSE:
 1823       {
 1824         if (t==token+1)
 1825         {
 1826           if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1827         }
 1828         break;
 1829       }
 1830       case T_ELSEIFELSE:
 1831       {
 1832         if (t==token+1)
 1833         {
 1834           if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
 1835         }
 1836         if (nextindent) --nextindent;
 1837         break;
 1838       }
 1839       default: break;
 1840     }
 1841   } while (t++->type!=T_EOL);
 1842   /*}}}*/
 1843   if (width>=0) /* whole line */
 1844   {
 1845     if (width) /* nicely formatted listing */
 1846     {
 1847       assert (token->type==T_UNNUMBERED || token->type==T_INTEGER);
 1848       if (token->type==T_INTEGER) String_appendPrintf(s,"%*ld ",width,token->u.integer);
 1849       else String_appendPrintf(s,"%*s ",width,"");
 1850     }
 1851     else assert (token->type==T_UNNUMBERED);
 1852     ++token;
 1853   }
 1854   while (thisindent--) String_appendPrintf(s,"  ");
 1855   do
 1856   {
 1857     if (s->length>oldlength && token->type!=T_EOL)
 1858     {
 1859       const char *keyword;
 1860 
 1861       if ((keyword=table[token->type].text)==(const char*)0) keyword="X";
 1862       if (ns && s->character[s->length-1]!=' ')
 1863       {
 1864         String_appendPrintf(s," ");
 1865       }
 1866       else if (isalnum((int)(s->character[s->length-1])) && isalnum((int)*keyword))
 1867       {
 1868         String_appendPrintf(s," ");
 1869       }
 1870       else if (s->character[s->length-1]!=' ' && table[token->type].space)
 1871       {
 1872         String_appendChar(s,' ');
 1873       }
 1874     }
 1875     if (spaceto && token==spaceto) break;
 1876     switch (token->type)
 1877     {
 1878       case T_DATAINPUT: String_appendChars(s,token->u.datainput); break;
 1879       case T_ELSEIFIF: break;
 1880       case T_IDENTIFIER: String_appendChars(s,token->u.identifier->name); break;
 1881       case T_INTEGER: String_appendPrintf(s,"%ld",token->u.integer); break;
 1882       case T_HEXINTEGER: String_appendPrintf(s,"&h%lx",token->u.hexinteger); break;
 1883       case T_OCTINTEGER: String_appendPrintf(s,"&o%lo",token->u.octinteger); break;
 1884       case T_JUNK: String_appendChar(s,token->u.junk); break;
 1885       case T_REAL:
 1886       {
 1887         String_appendPrintf(s,"%.*g",DBL_DIG,token->u.real);
 1888         if ((token->u.real<((double)LONG_MIN)) || (token->u.real>((double)LONG_MAX))) String_appendChar(s,'!');
 1889         break;
 1890       }
 1891       case T_REM: String_appendPrintf(s,"%s%s",uppercase?"REM":"rem",token->u.rem); break;
 1892       case T_QUOTE: String_appendPrintf(s,"'%s",token->u.rem); break;
 1893       case T_STRING: /*{{{*/
 1894       {
 1895         size_t l=token->u.string->length;
 1896         char *data=token->u.string->character;
 1897 
 1898         String_appendPrintf(s,"\"");
 1899         while (l--)
 1900         {
 1901           if (*data=='"') String_appendPrintf(s,"\"");
 1902           String_appendPrintf(s,"%c",*data);
 1903           ++data;
 1904         }
 1905         String_appendPrintf(s,"\"");
 1906         break;
 1907       }
 1908       /*}}}*/
 1909       default:
 1910       {
 1911         if (uppercase)
 1912         {
 1913           struct String u;
 1914 
 1915           String_new(&u);
 1916           String_appendChars(&u,table[token->type].text);
 1917           String_ucase(&u);
 1918           String_appendString(s,&u);
 1919           String_destroy(&u);
 1920         }
 1921         else String_appendChars(s,table[token->type].text);
 1922       }
 1923     }
 1924     ns=table[token->type].space;
 1925   } while (token++->type!=T_EOL);
 1926   if (indent) *indent=nextindent;
 1927   if (spaceto && s->length>oldlength) memset(s->character+oldlength,' ',s->length-oldlength);
 1928   return s;
 1929 }
 1930 /*}}}*/
 1931 void Token_init(int b_c, int uc) /*{{{*/
 1932 {
 1933 #define PROPERTY(t,assoc,unary_priority,binary_priority,is_unary,is_binary) \
 1934   Token_property[t]=(assoc<<8)|(unary_priority<<5)|(binary_priority<<2)|(is_unary<<1)|is_binary
 1935 
 1936   backslash_colon=b_c;
 1937   uppercase=uc;
 1938   PROPERTY(T_POW,  1,0,7,0,1);
 1939   PROPERTY(T_MULT, 0,0,5,0,1);
 1940   PROPERTY(T_DIV,  0,0,5,0,1);
 1941   PROPERTY(T_IDIV, 0,0,5,0,1);
 1942   PROPERTY(T_MOD,  0,0,5,0,1);
 1943   PROPERTY(T_PLUS, 0,6,4,1,1);
 1944   PROPERTY(T_MINUS,0,6,4,1,1);
 1945   PROPERTY(T_LT,   0,0,3,0,1);
 1946   PROPERTY(T_LE,   0,0,3,0,1);
 1947   PROPERTY(T_EQ,   0,0,3,0,1);
 1948   PROPERTY(T_GE,   0,0,3,0,1);
 1949   PROPERTY(T_GT,   0,0,3,0,1);
 1950   PROPERTY(T_NE,   0,0,3,0,1);
 1951   PROPERTY(T_NOT,  0,2,0,1,0);
 1952   PROPERTY(T_AND,  0,0,1,0,1);
 1953   PROPERTY(T_OR,   0,0,0,0,1);
 1954   PROPERTY(T_XOR,  0,0,0,0,1);
 1955   PROPERTY(T_EQV,  0,0,0,0,1);
 1956   PROPERTY(T_IMP,  0,0,0,0,1);
 1957 }
 1958 /*}}}*/