summaryrefslogtreecommitdiff
path: root/apps/interpreters/bas/token.l
diff options
context:
space:
mode:
Diffstat (limited to 'apps/interpreters/bas/token.l')
-rw-r--r--apps/interpreters/bas/token.l1943
1 files changed, 1943 insertions, 0 deletions
diff --git a/apps/interpreters/bas/token.l b/apps/interpreters/bas/token.l
new file mode 100644
index 000000000..54179765a
--- /dev/null
+++ b/apps/interpreters/bas/token.l
@@ -0,0 +1,1943 @@
+/* Tokens and token sequence arrays. */
+%{
+/* #includes */ /*{{{C}}}*//*{{{*/
+#include "config.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "auto.h"
+#include "token.h"
+#include "statement.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+/*}}}*/
+
+static int matchdata;
+static int backslash_colon;
+static int uppercase;
+int yylex(void);
+static struct Token *cur;
+
+static void string(const char *text) /*{{{*/
+{
+ if (cur)
+ {
+ const char *t;
+ char *q;
+ size_t l;
+
+ for (t=text+1,l=0; *(t+1); ++t,++l)
+ {
+ if (*t=='"') ++t;
+ }
+ cur->u.string=malloc(sizeof(struct String));
+ String_size(String_new(cur->u.string),l);
+ for (t=text+1,q=cur->u.string->character; *(t+1); ++t,++q)
+ {
+ *q=*t;
+ if (*t=='"') ++t;
+ }
+ }
+}
+/*}}}*/
+static void string2(void) /*{{{*/
+{
+ if (cur)
+ {
+ char *t,*q;
+ size_t l;
+
+ for (t=yytext+1,l=0; *t; ++t,++l)
+ {
+ if (*t=='"') ++t;
+ }
+ cur->u.string=malloc(sizeof(struct String));
+ String_size(String_new(cur->u.string),l);
+ for (t=yytext+1,q=cur->u.string->character; *t; ++t,++q)
+ {
+ *q=*t;
+ if (*t=='"') ++t;
+ }
+ }
+}
+/*}}}*/
+%}
+ /* flex options and definitions */ /*{{{*/
+%option noyywrap
+%option nounput
+%x DATAINPUT ELSEIF IMAGEFMT
+REAL ([0-9]+("!"|"#"))|([0-9]+\.[0-9]*(e("+"|"-")?[0-9]+)?("!"|"#")?)|([0-9]*\.[0-9]+(e("+"|"-")?[0-9]+)?("!"|"#")?|([0-9]+e("+"|"-")?[0-9]+("!"|"#")?))
+INTEGER [0-9]+%?
+HEXINTEGER &H[0-9A-F]+
+OCTINTEGER &O[0-7]+
+IDENTIFIER ("fn"[ \t]+)?[A-Z][A-Z_0-9\.]*("$"|"%"|"#")?
+STRING \"([^"]|\"\")*\"
+STRING2 \"([^"]|\"\")*$
+REM rem([^0-9A-Z_\.\n][^\n]*)?
+QUOTE ("'"|"!")[^\n]*
+ENDIF end[ \t]*if
+ENDPROC end[ \t]*proc
+ENDSELECT end[ \t]*select
+DOUNTIL do[ \t]+until
+DOWHILE do[ \t]+while
+EXITDO exit[ \t]+do
+EXITFOR exit[ \t]+for
+LINEINPUT (line[ \t]+input)|linput
+LOOPUNTIL loop[ \t]+until
+DATAITEM [^ \t\n,:][^,:\n]*
+ONERROR on[ \t]+error
+ONERROROFF on[ \t]+error[ \t]+off
+ONERRORGOTO0 on[ \t]+error[ \t]+goto[ \t]+0
+SELECTCASE select[ \t]+case
+ /*}}}*/
+%%
+ /* flex rules */ /*{{{*/
+ if (matchdata) BEGIN(DATAINPUT);
+
+"#" return T_CHANNEL;
+{REAL} {
+ int overflow;
+ double d;
+
+ d=Value_vald(yytext,(char**)0,&overflow);
+ if (overflow)
+ {
+ if (cur) cur->u.junk=yytext[0];
+ yyless(1);
+ return T_JUNK;
+ }
+ if (cur) cur->u.real=d;
+ return T_REAL;
+ }
+{INTEGER} {
+ int overflow;
+ long int n;
+
+ n=Value_vali(yytext,(char**)0,&overflow);
+ if (overflow)
+ {
+ double d;
+
+ d=Value_vald(yytext,(char**)0,&overflow);
+ if (overflow)
+ {
+ if (cur) cur->u.junk=yytext[0];
+ yyless(1);
+ return T_JUNK;
+ }
+ if (cur) cur->u.real=d;
+ return T_REAL;
+ }
+ if (cur) cur->u.integer=n;
+ return T_INTEGER;
+ }
+{HEXINTEGER} {
+ int overflow;
+ long int n;
+
+ n=Value_vali(yytext,(char**)0,&overflow);
+ if (overflow)
+ {
+ if (cur) cur->u.junk=yytext[0];
+ yyless(1);
+ return T_JUNK;
+ }
+ if (cur) cur->u.hexinteger=n;
+ return T_HEXINTEGER;
+ }
+{OCTINTEGER} {
+ int overflow;
+ long int n;
+
+ n=Value_vali(yytext,(char**)0,&overflow);
+ if (overflow)
+ {
+ if (cur) cur->u.junk=yytext[0];
+ yyless(1);
+ return T_JUNK;
+ }
+ if (cur) cur->u.octinteger=n;
+ return T_OCTINTEGER;
+ }
+{STRING} string(yytext); return T_STRING;
+{STRING2} string2(); return T_STRING;
+"("|"[" return T_OP;
+")"|"]" return T_CP;
+"*" return T_MULT;
+"+" return T_PLUS;
+"-" return T_MINUS;
+"," return T_COMMA;
+"/" return T_DIV;
+"\\" {
+ if (backslash_colon)
+ {
+ if (cur) cur->statement=stmt_COLON_EOL;
+ return T_COLON;
+ }
+ return T_IDIV;
+ }
+":" {
+ if (cur)
+ {
+ cur->statement=stmt_COLON_EOL;
+ }
+ return T_COLON;
+ }
+";" return T_SEMICOLON;
+"<" return T_LT;
+"<=" return T_LE;
+"=<" return T_LE;
+"<>"|"><" return T_NE;
+"=" {
+ if (cur)
+ {
+ cur->statement=stmt_EQ_FNRETURN_FNEND;
+ }
+ return T_EQ;
+ }
+">" return T_GT;
+">=" return T_GE;
+"=>" return T_GE;
+"^" return T_POW;
+"access"[ \t]+"read" return T_ACCESS_READ;
+"access"[ \t]+"read"[ \t]+"write" return T_ACCESS_READ_WRITE;
+"access"[ \t]+"write" return T_ACCESS_WRITE;
+"and" return T_AND;
+"as" return T_AS;
+"call" {
+ if (cur)
+ {
+ cur->statement=stmt_CALL;
+ }
+ return T_CALL;
+ }
+"case"[ \t]+"else" {
+ if (cur)
+ {
+ cur->statement=stmt_CASE;
+ cur->u.casevalue=malloc(sizeof(struct Casevalue));
+ }
+ return T_CASEELSE;
+ }
+"case" {
+ if (cur)
+ {
+ cur->statement=stmt_CASE;
+ cur->u.casevalue=malloc(sizeof(struct Casevalue));
+ }
+ return T_CASEVALUE;
+ }
+"chdir" {
+ if (cur)
+ {
+ cur->statement=stmt_CHDIR_MKDIR;
+ }
+ return T_CHDIR;
+ }
+"clear" {
+ if (cur)
+ {
+ cur->statement=stmt_CLEAR;
+ }
+ return T_CLEAR;
+ }
+"close" {
+ if (cur)
+ {
+ cur->statement=stmt_CLOSE;
+ }
+ return T_CLOSE;
+ }
+"close"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_CLOSE;
+ }
+ return T_CLOSE;
+ }
+"cls"|"home" {
+ if (cur)
+ {
+ cur->statement=stmt_CLS;
+ }
+ return T_CLS;
+ }
+"color" {
+ if (cur)
+ {
+ cur->statement=stmt_COLOR;
+ }
+ return T_COLOR;
+ }
+"con" return T_CON;
+"copy" {
+ if (cur)
+ {
+ cur->statement=stmt_COPY_RENAME;
+ }
+ return T_COPY;
+ }
+"data"|"d." {
+ BEGIN(DATAINPUT);
+ if (cur)
+ {
+ cur->statement=stmt_DATA;
+ }
+ return T_DATA;
+ }
+<DATAINPUT>{STRING} string(yytext); return T_STRING;
+<DATAINPUT>{STRING2} string2(); return T_STRING;
+<DATAINPUT>"," return T_COMMA;
+<DATAINPUT>{DATAITEM} {
+ if (cur) cur->u.datainput=strcpy(malloc(strlen(yytext)+1),yytext);
+ return T_DATAINPUT;
+ }
+<DATAINPUT>[ \t]+
+<DATAINPUT>\n BEGIN(INITIAL);
+<DATAINPUT>: BEGIN(INITIAL); return T_COLON;
+"dec" {
+ if (cur)
+ {
+ cur->statement=stmt_DEC_INC;
+ }
+ return T_DEC;
+ }
+"defdbl" {
+ if (cur)
+ {
+ cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
+ }
+ return T_DEFDBL;
+ }
+"defint" {
+ if (cur)
+ {
+ cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
+ }
+ return T_DEFINT;
+ }
+"defstr" {
+ if (cur)
+ {
+ cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
+ }
+ return T_DEFSTR;
+ }
+"def"/[ \t]+fn[ \t]*[A-Z_0-9\.] {
+ if (cur)
+ {
+ cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
+ cur->u.localSyms=(struct Symbol*)0;
+ }
+ return T_DEFFN;
+ }
+"def"/[ \t]+proc[A-Z_0-9\.] {
+ if (cur)
+ {
+ cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
+ cur->u.localSyms=(struct Symbol*)0;
+ }
+ return T_DEFPROC;
+ }
+"delete" {
+ if (cur)
+ {
+ cur->statement=stmt_DELETE;
+ }
+ return T_DELETE;
+ }
+"dim" {
+ if (cur)
+ {
+ cur->statement=stmt_DIM;
+ }
+ return T_DIM;
+ }
+"display" {
+ if (cur)
+ {
+ cur->statement=stmt_DISPLAY;
+ }
+ return T_DISPLAY;
+ }
+"do" {
+ if (cur)
+ {
+ cur->statement=stmt_DO;
+ }
+ return T_DO;
+ }
+{DOUNTIL} {
+ if (cur)
+ {
+ cur->statement=stmt_DOcondition;
+ }
+ return T_DOUNTIL;
+ }
+{DOWHILE} {
+ if (cur)
+ {
+ cur->statement=stmt_DOcondition;
+ }
+ return T_DOWHILE;
+ }
+"edit" {
+ if (cur)
+ {
+ cur->statement=stmt_EDIT;
+ }
+ return T_EDIT;
+ }
+"else"|"el." {
+ if (cur)
+ {
+ cur->statement=stmt_ELSE_ELSEIFELSE;
+ }
+ return T_ELSE;
+ }
+"else"/"if" {
+ BEGIN(ELSEIF);
+ if (cur)
+ {
+ cur->statement=stmt_ELSE_ELSEIFELSE;
+ }
+ return T_ELSEIFELSE;
+ }
+<ELSEIF>"if" {
+ BEGIN(INITIAL);
+ if (cur)
+ {
+ cur->statement=stmt_IF_ELSEIFIF;
+ }
+ return T_ELSEIFIF;
+ }
+end[ \t]+function {
+ if (cur)
+ {
+ cur->statement=stmt_ENDFN;
+ }
+ return T_ENDFN;
+ }
+{ENDIF} {
+ if (cur)
+ {
+ cur->statement=stmt_ENDIF;
+ }
+ return T_ENDIF;
+ }
+{ENDPROC} {
+ if (cur)
+ {
+ cur->statement=stmt_ENDPROC_SUBEND;
+ }
+ return T_ENDPROC;
+ }
+{ENDSELECT} {
+ if (cur)
+ {
+ cur->statement=stmt_ENDSELECT;
+ }
+ return T_ENDSELECT;
+ }
+"end"[ \t]*"sub" {
+ if (cur)
+ {
+ cur->statement=stmt_ENDPROC_SUBEND;
+ }
+ return T_SUBEND;
+ }
+"end" {
+ if (cur)
+ {
+ cur->statement=stmt_END;
+ }
+ return T_END;
+ }
+"environ" {
+ if (cur)
+ {
+ cur->statement=stmt_ENVIRON;
+ }
+ return T_ENVIRON;
+ }
+"erase" {
+ if (cur)
+ {
+ cur->statement=stmt_ERASE;
+ }
+ return T_ERASE;
+ }
+"eqv" return T_EQV;
+{EXITDO} {
+ if (cur)
+ {
+ cur->statement=stmt_EXITDO;
+ }
+ return T_EXITDO;
+ }
+{EXITFOR} {
+ if (cur)
+ {
+ cur->statement=stmt_EXITFOR;
+ }
+ return T_EXITFOR;
+ }
+"exit"[ \t]+"function" {
+ if (cur)
+ {
+ cur->statement=stmt_FNEXIT;
+ }
+ return T_FNEXIT;
+ }
+"exit"[ \t]+"sub" {
+ if (cur)
+ {
+ cur->statement=stmt_SUBEXIT;
+ }
+ return T_SUBEXIT;
+ }
+"field" {
+ if (cur)
+ {
+ cur->statement=stmt_FIELD;
+ }
+ return T_FIELD;
+ }
+"field"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_FIELD;
+ }
+ return T_FIELD;
+ }
+"fnend" {
+ if (cur)
+ {
+ cur->statement=stmt_EQ_FNRETURN_FNEND;
+ }
+ return T_FNEND;
+ }
+"fnreturn" {
+ if (cur)
+ {
+ cur->statement=stmt_EQ_FNRETURN_FNEND;
+ }
+ return T_FNRETURN;
+ }
+"for" {
+ if (cur)
+ {
+ cur->statement=stmt_FOR;
+ }
+ return T_FOR;
+ }
+"for"[ \t]+"input" return T_FOR_INPUT;
+"for"[ \t]+"output" return T_FOR_OUTPUT;
+"for"[ \t]+"append" return T_FOR_APPEND;
+"for"[ \t]+"random" return T_FOR_RANDOM;
+"for"[ \t]+"binary" return T_FOR_BINARY;
+"function" {
+ if (cur)
+ {
+ cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
+ cur->u.localSyms=(struct Symbol*)0;
+ }
+ return T_FUNCTION;
+ }
+"get" {
+ if (cur)
+ {
+ cur->statement=stmt_GET_PUT;
+ }
+ return T_GET;
+ }
+"get"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_GET_PUT;
+ }
+ return T_GET;
+ }
+"go"[ \t]*"sub" {
+ if (cur)
+ {
+ cur->statement=stmt_GOSUB;
+ }
+ return T_GOSUB;
+ }
+"go"[ \t]*"to" {
+ if (cur)
+ {
+ cur->statement=stmt_RESUME_GOTO;
+ }
+ return T_GOTO;
+ }
+"idn" return T_IDN;
+"if" {
+ if (cur)
+ {
+ cur->statement=stmt_IF_ELSEIFIF;
+ }
+ return T_IF;
+ }
+"image"[ \t]*/[^"\n \t] {
+ BEGIN(IMAGEFMT);
+ if (cur)
+ {
+ cur->statement=stmt_IMAGE;
+ }
+ return T_IMAGE;
+ }
+<IMAGEFMT>.*$ {
+ BEGIN(INITIAL);
+ if (cur)
+ {
+ size_t l;
+
+ l=strlen(yytext);
+ cur->u.string=malloc(sizeof(struct String));
+ String_size(String_new(cur->u.string),l);
+ memcpy(cur->u.string->character,yytext,l);
+ }
+ return T_STRING;
+ }
+"image" {
+ if (cur)
+ {
+ cur->statement=stmt_IMAGE;
+ }
+ return T_IMAGE;
+ }
+"imp" return T_IMP;
+"inc" {
+ if (cur)
+ {
+ cur->statement=stmt_DEC_INC;
+ }
+ return T_INC;
+ }
+"input" {
+ if (cur)
+ {
+ cur->statement=stmt_INPUT;
+ }
+ return T_INPUT;
+ }
+"input"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_INPUT;
+ }
+ return T_INPUT;
+ }
+"inv" return T_INV;
+"is" return T_IS;
+"kill" {
+ if (cur)
+ {
+ cur->statement=stmt_KILL;
+ }
+ return T_KILL;
+ }
+"let" {
+ if (cur)
+ {
+ cur->statement=stmt_LET;
+ }
+ return T_LET;
+ }
+"list" {
+ if (cur)
+ {
+ cur->statement=stmt_LIST_LLIST;
+ }
+ return T_LIST;
+ }
+"llist" {
+ if (cur)
+ {
+ cur->statement=stmt_LIST_LLIST;
+ }
+ return T_LLIST;
+ }
+"load" {
+ if (cur)
+ {
+ cur->statement=stmt_LOAD;
+ }
+ return T_LOAD;
+ }
+"local" {
+ if (cur)
+ {
+ cur->statement=stmt_LOCAL;
+ }
+ return T_LOCAL;
+ }
+"locate" {
+ if (cur)
+ {
+ cur->statement=stmt_LOCATE;
+ }
+ return T_LOCATE;
+ }
+"lock" {
+ if (cur)
+ {
+ cur->statement=stmt_LOCK_UNLOCK;
+ }
+ return T_LOCK;
+ }
+"lock"[ \t]+"read" return T_LOCK_READ;
+"lock"[ \t]+"write" return T_LOCK_WRITE;
+"loop" {
+ if (cur)
+ {
+ cur->statement=stmt_LOOP;
+ }
+ return T_LOOP;
+ }
+{LOOPUNTIL} {
+ if (cur)
+ {
+ cur->statement=stmt_LOOPUNTIL;
+ }
+ return T_LOOPUNTIL;
+ }
+"lprint" {
+ if (cur)
+ {
+ cur->statement=stmt_PRINT_LPRINT;
+ }
+ return T_LPRINT;
+ }
+"lset" {
+ if (cur)
+ {
+ cur->statement=stmt_LSET_RSET;
+ }
+ return T_LSET;
+ }
+"mat"[ \t]+"input" {
+ if (cur)
+ {
+ cur->statement=stmt_MATINPUT;
+ }
+ return T_MATINPUT;
+ }
+"mat"[ \t]+"print" {
+ if (cur)
+ {
+ cur->statement=stmt_MATPRINT;
+ }
+ return T_MATPRINT;
+ }
+"mat"[ \t]+"read" {
+ if (cur)
+ {
+ cur->statement=stmt_MATREAD;
+ }
+ return T_MATREAD;
+ }
+"mat"[ \t]+"redim" {
+ if (cur)
+ {
+ cur->statement=stmt_MATREDIM;
+ }
+ return T_MATREDIM;
+ }
+"mat"[ \t]+"write" {
+ if (cur)
+ {
+ cur->statement=stmt_MATWRITE;
+ }
+ return T_MATWRITE;
+ }
+"mat" {
+ if (cur)
+ {
+ cur->statement=stmt_MAT;
+ }
+ return T_MAT;
+ }
+"mkdir" {
+ if (cur)
+ {
+ cur->statement=stmt_CHDIR_MKDIR;
+ }
+ return T_MKDIR;
+ }
+"mod" return T_MOD;
+"new" {
+ if (cur)
+ {
+ cur->statement=stmt_NEW;
+ }
+ return T_NEW;
+ }
+"name" {
+ if (cur)
+ {
+ cur->statement=stmt_NAME;
+ }
+ return T_NAME;
+ }
+"next" {
+ if (cur)
+ {
+ cur->statement=stmt_NEXT;
+ cur->u.next=malloc(sizeof(struct Next));
+ }
+ return T_NEXT;
+ }
+"not" return T_NOT;
+{ONERROROFF} {
+ if (cur)
+ {
+ cur->statement=stmt_ONERROROFF;
+ }
+ return T_ONERROROFF;
+ }
+{ONERRORGOTO0} {
+ if (cur)
+ {
+ cur->statement=stmt_ONERRORGOTO0;
+ }
+ return T_ONERRORGOTO0;
+ }
+{ONERROR} {
+ if (cur)
+ {
+ cur->statement=stmt_ONERROR;
+ }
+ return T_ONERROR;
+ }
+"on" {
+ if (cur)
+ {
+ cur->statement=stmt_ON;
+ cur->u.on.pcLength=1;
+ cur->u.on.pc=(struct Pc*)0;
+ }
+ return T_ON;
+ }
+"open" {
+ if (cur)
+ {
+ cur->statement=stmt_OPEN;
+ }
+ return T_OPEN;
+ }
+"option"[ \t]+"base" {
+ if (cur)
+ {
+ cur->statement=stmt_OPTIONBASE;
+ }
+ return T_OPTIONBASE;
+ }
+"option"[ \t]+"run" {
+ if (cur)
+ {
+ cur->statement=stmt_OPTIONRUN;
+ }
+ return T_OPTIONRUN;
+ }
+"option"[ \t]+"stop" {
+ if (cur)
+ {
+ cur->statement=stmt_OPTIONSTOP;
+ }
+ return T_OPTIONSTOP;
+ }
+"or" return T_OR;
+"out" {
+ if (cur)
+ {
+ cur->statement=stmt_OUT_POKE;
+ }
+ return T_OUT;
+ }
+"print"|"p."|"?" {
+ if (cur)
+ {
+ cur->statement=stmt_PRINT_LPRINT;
+ }
+ return T_PRINT;
+ }
+("print"|"p."|"?")/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_PRINT_LPRINT;
+ }
+ return T_PRINT;
+ }
+"poke" {
+ if (cur)
+ {
+ cur->statement=stmt_OUT_POKE;
+ }
+ return T_POKE;
+ }
+"put" {
+ if (cur)
+ {
+ cur->statement=stmt_GET_PUT;
+ }
+ return T_PUT;
+ }
+"put"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_GET_PUT;
+ }
+ return T_PUT;
+ }
+"randomize" {
+ if (cur)
+ {
+ cur->statement=stmt_RANDOMIZE;
+ }
+ return T_RANDOMIZE;
+ }
+"read" {
+ if (cur)
+ {
+ cur->statement=stmt_READ;
+ }
+ return T_READ;
+ }
+"renum"|"ren." {
+ if (cur)
+ {
+ cur->statement=stmt_RENUM;
+ }
+ return T_RENUM;
+ }
+"repeat"|"rep." {
+ if (cur)
+ {
+ cur->statement=stmt_REPEAT;
+ }
+ return T_REPEAT;
+ }
+"restore"|"res." {
+ if (cur)
+ {
+ cur->statement=stmt_RESTORE;
+ }
+ return T_RESTORE;
+ }
+"resume" {
+ if (cur)
+ {
+ cur->statement=stmt_RESUME_GOTO;
+ }
+ return T_RESUME;
+ }
+"return"|"r." {
+ if (cur)
+ {
+ cur->statement=stmt_RETURN;
+ }
+ return T_RETURN;
+ }
+"rset" {
+ if (cur)
+ {
+ cur->statement=stmt_LSET_RSET;
+ }
+ return T_RSET;
+ }
+"run" {
+ if (cur)
+ {
+ cur->statement=stmt_RUN;
+ }
+ return T_RUN;
+ }
+"save" {
+ if (cur)
+ {
+ cur->statement=stmt_SAVE;
+ }
+ return T_SAVE;
+ }
+{SELECTCASE} {
+ if (cur)
+ {
+ cur->statement=stmt_SELECTCASE;
+ cur->u.selectcase=malloc(sizeof(struct Selectcase));
+ }
+ return T_SELECTCASE;
+ }
+"shared" return T_SHARED;
+"shell" {
+ if (cur)
+ {
+ cur->statement=stmt_SHELL;
+ }
+ return T_SHELL;
+ }
+"sleep" {
+ if (cur)
+ {
+ cur->statement=stmt_SLEEP;
+ }
+ return T_SLEEP;
+ }
+"spc" return T_SPC;
+"step" return T_STEP;
+"stop" {
+ if (cur)
+ {
+ cur->statement=stmt_STOP;
+ }
+ return T_STOP;
+ }
+"sub"[ \t]*"end" {
+ if (cur)
+ {
+ cur->statement=stmt_ENDPROC_SUBEND;
+ }
+ return T_SUBEND;
+ }
+"sub"[ \t]*"exit" {
+ if (cur)
+ {
+ cur->statement=stmt_SUBEXIT;
+ }
+ return T_SUBEXIT;
+ }
+"sub" {
+ if (cur)
+ {
+ cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
+ cur->u.localSyms=(struct Symbol*)0;
+ }
+ return T_SUB;
+ }
+"swap" {
+ if (cur)
+ {
+ cur->statement=stmt_SWAP;
+ }
+ return T_SWAP;
+ }
+"system"|"bye" {
+ if (cur)
+ {
+ cur->statement=stmt_SYSTEM;
+ }
+ return T_SYSTEM;
+ }
+"then"|"th." return T_THEN;
+"tab" return T_TAB;
+"to" return T_TO;
+"trn" return T_TRN;
+"troff" {
+ if (cur)
+ {
+ cur->statement=stmt_TROFF;
+ }
+ return T_TROFF;
+ }
+"tron" {
+ if (cur)
+ {
+ cur->statement=stmt_TRON;
+ }
+ return T_TRON;
+ }
+"truncate" {
+ if (cur)
+ {
+ cur->statement=stmt_TRUNCATE;
+ }
+ return T_TRUNCATE;
+ }
+"unlock" {
+ if (cur)
+ {
+ cur->statement=stmt_LOCK_UNLOCK;
+ }
+ return T_UNLOCK;
+ }
+"unnum" {
+ if (cur)
+ {
+ cur->statement=stmt_UNNUM;
+ }
+ return T_UNNUM;
+ }
+"until" {
+ if (cur)
+ {
+ cur->statement=stmt_UNTIL;
+ }
+ return T_UNTIL;
+ }
+"using" return T_USING;
+"wait" {
+ if (cur)
+ {
+ cur->statement=stmt_WAIT;
+ }
+ return T_WAIT;
+ }
+"wend" {
+ if (cur)
+ {
+ cur->statement=stmt_WEND;
+ cur->u.whilepc=malloc(sizeof(struct Pc));
+ }
+ return T_WEND;
+ }
+"while" {
+ if (cur)
+ {
+ cur->statement=stmt_WHILE;
+ cur->u.afterwend=malloc(sizeof(struct Pc));
+ }
+ return T_WHILE;
+ }
+"width" {
+ if (cur)
+ {
+ cur->statement=stmt_WIDTH;
+ }
+ return T_WIDTH;
+ }
+"width"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_WIDTH;
+ }
+ return T_WIDTH;
+ }
+"write" {
+ if (cur)
+ {
+ cur->statement=stmt_WRITE;
+ }
+ return T_WRITE;
+ }
+"write"/"#" {
+ if (cur)
+ {
+ cur->statement=stmt_WRITE;
+ }
+ return T_WRITE;
+ }
+"xor" return T_XOR;
+"xref" {
+ if (cur)
+ {
+ cur->statement=stmt_XREF;
+ }
+ return T_XREF;
+ }
+"zer" return T_ZER;
+"zone" {
+ if (cur)
+ {
+ cur->statement=stmt_ZONE;
+ }
+ return T_ZONE;
+ }
+{REM} {
+ if (cur)
+ {
+ cur->statement=stmt_QUOTE_REM;
+ cur->u.rem=strcpy(malloc(strlen(yytext+3)+1),yytext+3);
+ }
+ return T_REM;
+ }
+"rename" {
+ if (cur)
+ {
+ cur->statement=stmt_COPY_RENAME;
+ }
+ return T_RENAME;
+ }
+{QUOTE} {
+ if (cur)
+ {
+ cur->statement=stmt_QUOTE_REM;
+ strcpy(cur->u.rem=malloc(strlen(yytext+1)+1),yytext+1);
+ }
+ return T_QUOTE;
+ }
+{LINEINPUT} {
+ if (cur)
+ {
+ cur->statement=stmt_LINEINPUT;
+ }
+ return T_LINEINPUT;
+ }
+{IDENTIFIER} {
+ if (cur)
+ {
+ size_t len;
+ char *s;
+ int fn;
+
+ cur->statement=stmt_IDENTIFIER;
+ if (tolower(yytext[0])=='f' && tolower(yytext[1])=='n')
+ {
+ for (len=2,s=&yytext[2]; *s==' ' || *s=='\t'; ++s);
+ fn=1;
+ }
+ else
+ {
+ len=0;
+ s=yytext;
+ fn=0;
+ }
+ len+=strlen(s);
+ cur->u.identifier=malloc(offsetof(struct Identifier,name)+len+1);
+ if (fn)
+ {
+ memcpy(cur->u.identifier->name,yytext,2);
+ strcpy(cur->u.identifier->name+2,s);
+ }
+ else
+ {
+ strcpy(cur->u.identifier->name,s);
+ }
+ switch (yytext[yyleng-1])
+ {
+ case '$': cur->u.identifier->defaultType=V_STRING; break;
+ case '%': cur->u.identifier->defaultType=V_INTEGER; break;
+ default: cur->u.identifier->defaultType=V_REAL; break;
+ }
+ }
+ return T_IDENTIFIER;
+ }
+[ \t\n]+
+. {
+ if (cur) cur->u.junk=yytext[0];
+ return T_JUNK;
+ }
+ /*}}}*/
+%%
+
+int Token_property[T_LASTTOKEN];
+
+struct Token *Token_newCode(const char *ln) /*{{{*/
+{
+ int l,lasttok,thistok,addNumber=0,sawif;
+ struct Token *result;
+ YY_BUFFER_STATE buf;
+
+ cur=(struct Token*)0;
+ buf=yy_scan_string(ln);
+ /* determine number of tokens */ /*{{{*/
+ matchdata=sawif=0;
+ for (lasttok=T_EOL,l=1; (thistok=yylex()); ++l)
+ {
+ if (l==1 && thistok!=T_INTEGER) { addNumber=1; ++l; }
+ if ((lasttok==T_THEN || lasttok==T_ELSE) && thistok==T_INTEGER) ++l;
+ if (thistok==T_IF) sawif=1;
+ if (thistok==T_THEN) sawif=0;
+ if (thistok==T_GOTO && sawif) ++l;
+ lasttok=thistok;
+ }
+ if (l==1) { addNumber=1; ++l; }
+ /*}}}*/
+ yy_delete_buffer(buf);
+ cur=result=malloc(sizeof(struct Token)*l);
+ if (addNumber)
+ {
+ cur->type=T_UNNUMBERED;
+ ++cur;
+ }
+ buf=yy_scan_string(ln);
+ lasttok=T_EOL;
+ matchdata=sawif=0;
+ while (cur->statement=NULL,(cur->type=yylex()))
+ {
+ if (cur->type==T_IF) sawif=1;
+ if (cur->type==T_THEN) sawif=0;
+ if (cur->type==T_GOTO && sawif)
+ {
+ sawif=0;
+ *(cur+1)=*cur;
+ cur->type=T_THEN;
+ lasttok=T_GOTO;
+ cur+=2;
+ }
+ else if ((lasttok==T_THEN || lasttok==T_ELSE) && cur->type==T_INTEGER)
+ {
+ *(cur+1)=*cur;
+ cur->type=T_GOTO;
+ cur->statement=stmt_RESUME_GOTO;
+ lasttok=T_INTEGER;
+ cur+=2;
+ }
+ else
+ {
+ lasttok=cur->type;
+ ++cur;
+ }
+ }
+ cur->type=T_EOL;
+ cur->statement=stmt_COLON_EOL;
+ yy_delete_buffer(buf);
+ return result;
+}
+/*}}}*/
+struct Token *Token_newData(const char *ln) /*{{{*/
+{
+ int l;
+ struct Token *result;
+ YY_BUFFER_STATE buf;
+
+ cur=(struct Token*)0;
+ buf=yy_scan_string(ln);
+ matchdata=1;
+ for (l=1; yylex(); ++l);
+ yy_delete_buffer(buf);
+ cur=result=malloc(sizeof(struct Token)*l);
+ buf=yy_scan_string(ln);
+ matchdata=1;
+ while (cur->statement=NULL,(cur->type=yylex())) ++cur;
+ cur->type=T_EOL;
+ cur->statement=stmt_COLON_EOL;
+ yy_delete_buffer(buf);
+ return result;
+}
+/*}}}*/
+void Token_destroy(struct Token *token) /*{{{*/
+{
+ struct Token *r=token;
+
+ do
+ {
+ switch (r->type)
+ {
+ case T_ACCESS_READ: break;
+ case T_ACCESS_WRITE: break;
+ case T_AND: break;
+ case T_AS: break;
+ case T_CALL: break;
+ case T_CASEELSE:
+ case T_CASEVALUE: free(r->u.casevalue); break;
+ case T_CHANNEL: break;
+ case T_CHDIR: break;
+ case T_CLEAR: break;
+ case T_CLOSE: break;
+ case T_CLS: break;
+ case T_COLON: break;
+ case T_COLOR: break;
+ case T_COMMA: break;
+ case T_CON: break;
+ case T_COPY: break;
+ case T_CP: break;
+ case T_DATA: break;
+ case T_DATAINPUT: free(r->u.datainput); break;
+ case T_DEC: break;
+ case T_DEFFN: break;
+ case T_DEFDBL: break;
+ case T_DEFINT: break;
+ case T_DEFPROC: break;
+ case T_DEFSTR: break;
+ case T_DELETE: break;
+ case T_DIM: break;
+ case T_DISPLAY: break;
+ case T_DIV: break;
+ case T_DO: break;
+ case T_DOUNTIL: break;
+ case T_DOWHILE: break;
+ case T_EDIT: break;
+ case T_ELSE: break;
+ case T_ELSEIFELSE: break;
+ case T_ELSEIFIF: break;
+ case T_END: break;
+ case T_ENDFN: break;
+ case T_ENDIF: break;
+ case T_ENDPROC: break;
+ case T_ENDSELECT: break;
+ case T_ENVIRON: break;
+ case T_EOL: break;
+ case T_EQ: break;
+ case T_EQV: break;
+ case T_ERASE: break;
+ case T_EXITDO: break;
+ case T_EXITFOR: break;
+ case T_FIELD: break;
+ case T_FNEND: break;
+ case T_FNEXIT: break;
+ case T_FNRETURN: break;
+ case T_FOR: break;
+ case T_FOR_INPUT: break;
+ case T_FOR_OUTPUT: break;
+ case T_FOR_APPEND: break;
+ case T_FOR_RANDOM: break;
+ case T_FOR_BINARY: break;
+ case T_FUNCTION: break;
+ case T_GE: break;
+ case T_GET: break;
+ case T_GOSUB: break;
+ case T_GOTO: break;
+ case T_GT: break;
+ case T_HEXINTEGER: break;
+ case T_OCTINTEGER: break;
+ case T_IDENTIFIER: free(r->u.identifier); break;
+ case T_IDIV: break;
+ case T_IDN: break;
+ case T_IF: break;
+ case T_IMAGE: break;
+ case T_IMP: break;
+ case T_INC: break;
+ case T_INPUT: break;
+ case T_INTEGER: break;
+ case T_INV: break;
+ case T_IS: break;
+ case T_JUNK: break;
+ case T_KILL: break;
+ case T_LE: break;
+ case T_LET: break;
+ case T_LINEINPUT: break;
+ case T_LIST: break;
+ case T_LLIST: break;
+ case T_LOAD: break;
+ case T_LOCAL: break;
+ case T_LOCATE: break;
+ case T_LOCK: break;
+ case T_LOCK_READ: break;
+ case T_LOCK_WRITE: break;
+ case T_LOOP: break;
+ case T_LOOPUNTIL: break;
+ case T_LPRINT: break;
+ case T_LSET: break;
+ case T_LT: break;
+ case T_MAT: break;
+ case T_MATINPUT: break;
+ case T_MATPRINT: break;
+ case T_MATREAD: break;
+ case T_MATREDIM: break;
+ case T_MATWRITE: break;
+ case T_MINUS: break;
+ case T_MKDIR: break;
+ case T_MOD: break;
+ case T_MULT: break;
+ case T_NAME: break;
+ case T_NE: break;
+ case T_NEW: break;
+ case T_NEXT: free(r->u.next); break;
+ case T_NOT: break;
+ case T_ON: if (r->u.on.pc) free(r->u.on.pc); break;
+ case T_ONERROR: break;
+ case T_ONERRORGOTO0: break;
+ case T_ONERROROFF: break;
+ case T_OP: break;
+ case T_OPEN: break;
+ case T_OPTIONBASE: break;
+ case T_OPTIONRUN: break;
+ case T_OPTIONSTOP: break;
+ case T_OR: break;
+ case T_OUT: break;
+ case T_PLUS: break;
+ case T_POKE: break;
+ case T_POW: break;
+ case T_PRINT: break;
+ case T_PUT: break;
+ case T_QUOTE: free(r->u.rem); break;
+ case T_RANDOMIZE: break;
+ case T_READ: break;
+ case T_REAL: break;
+ case T_REM: free(r->u.rem); break;
+ case T_RENAME: break;
+ case T_RENUM: break;
+ case T_REPEAT: break;
+ case T_RESTORE: break;
+ case T_RESUME: break;
+ case T_RETURN: break;
+ case T_RSET: break;
+ case T_RUN: break;
+ case T_SAVE: break;
+ case T_SELECTCASE: free(r->u.selectcase); break;
+ case T_SEMICOLON: break;
+ case T_SHARED: break;
+ case T_SHELL: break;
+ case T_SLEEP: break;
+ case T_SPC: break;
+ case T_STEP: break;
+ case T_STOP: break;
+ case T_STRING: String_destroy(r->u.string); free(r->u.string); break;
+ case T_SUB: break;
+ case T_SUBEND: break;
+ case T_SUBEXIT: break;
+ case T_SWAP: break;
+ case T_SYSTEM: break;
+ case T_TAB: break;
+ case T_THEN: break;
+ case T_TO: break;
+ case T_TRN: break;
+ case T_TROFF: break;
+ case T_TRON: break;
+ case T_TRUNCATE: break;
+ case T_UNLOCK: break;
+ case T_UNNUM: break;
+ case T_UNNUMBERED: break;
+ case T_UNTIL: break;
+ case T_USING: break;
+ case T_WAIT: break;
+ case T_WEND: free(r->u.whilepc); break;
+ case T_WHILE: free(r->u.afterwend); break;
+ case T_WIDTH: break;
+ case T_WRITE: break;
+ case T_XOR: break;
+ case T_XREF: break;
+ case T_ZER: break;
+ case T_ZONE: break;
+ default: assert(0);
+ }
+ } while ((r++)->type!=T_EOL);
+ free(token);
+}
+/*}}}*/
+struct String *Token_toString(struct Token *token, struct Token *spaceto, struct String *s, int *indent, int width) /*{{{*/
+{
+ int ns=0,infn=0;
+ int thisindent=0,thisnotindent=0,nextindent=0;
+ size_t oldlength=s->length;
+ struct Token *t;
+ static struct
+ {
+ const char *text;
+ char space;
+ } table[]=
+ {
+ /* 0 */ {(const char*)0,-1},
+ /* T_ACCESS_READ */ {"access read",1},
+ /* T_ACCESS_READ_WRITE */ {"access read write",1},
+ /* T_ACCESS_WRITE */ {"access write",1},
+ /* T_AND */ {"and",1},
+ /* T_AS */ {"as",1},
+ /* T_CALL */ {"call",1},
+ /* T_CASEELSE */ {"case else",1},
+ /* T_CASEVALUE */ {"case",1},
+ /* T_CHANNEL */ {"#",0},
+ /* T_CHDIR */ {"chdir",1},
+ /* T_CLEAR */ {"clear",1},
+ /* T_CLOSE */ {"close",1},
+ /* T_CLS */ {"cls",1},
+ /* T_COLON */ {":",1},
+ /* T_COLOR */ {"color",1},
+ /* T_COMMA */ {",",0},
+ /* T_CON */ {"con",0},
+ /* T_COPY */ {"copy",1},
+ /* T_CP */ {")",0},
+ /* T_DATA */ {"data",1},
+ /* T_DATAINPUT */ {(const char*)0,0},
+ /* T_DEC */ {"dec",1},
+ /* T_DEFDBL */ {"defdbl",1},
+ /* T_DEFFN */ {"def",1},
+ /* T_DEFINT */ {"defint",1},
+ /* T_DEFPROC */ {"def",1},
+ /* T_DEFSTR */ {"defstr",1},
+ /* T_DELETE */ {"delete",1},
+ /* T_DIM */ {"dim",1},
+ /* T_DISPLAY */ {"display",1},
+ /* T_DIV */ {"/",0},
+ /* T_DO */ {"do",1},
+ /* T_DOUNTIL */ {"do until",1},
+ /* T_DOWHILE */ {"do while",1},
+ /* T_EDIT */ {"edit",1},
+ /* T_ELSE */ {"else",1},
+ /* T_ELSEIFELSE */ {"elseif",1},
+ /* T_ELSEIFIF */ {(const char*)0,0},
+ /* T_END */ {"end",1},
+ /* T_ENDFN */ {"end function",1},
+ /* T_ENDIF */ {"end if",1},
+ /* T_ENDPROC */ {"end proc",1},
+ /* T_ENDSELECT */ {"end select",1},
+ /* T_ENVIRON */ {"environ",1},
+ /* T_EOL */ {"\n",0},
+ /* T_EQ */ {"=",0},
+ /* T_EQV */ {"eqv",0},
+ /* T_ERASE */ {"erase",1},
+ /* T_EXITDO */ {"exit do",1},
+ /* T_EXITFOR */ {"exit for",1},
+ /* T_FIELD */ {"field",1},
+ /* T_FNEND */ {"fnend",1},
+ /* T_FNEXIT */ {"exit function",1},
+ /* T_FNRETURN */ {"fnreturn",1},
+ /* T_FOR */ {"for",1},
+ /* T_FOR_INPUT */ {"for input",1},
+ /* T_FOR_OUTPUT */ {"for output",1},
+ /* T_FOR_APPEND */ {"for append",1},
+ /* T_FOR_RANDOM */ {"for random",1},
+ /* T_FOR_BINARY */ {"for binary",1},
+ /* T_FUNCTION */ {"function",1},
+ /* T_GE */ {">=",0},
+ /* T_GET */ {"get",1},
+ /* T_GOSUB */ {"gosub",1},
+ /* T_GOTO */ {"goto",1},
+ /* T_GT */ {">",0},
+ /* T_HEXINTEGER */ {(const char*)0,0},
+ /* T_OCTINTEGER */ {(const char*)0,0},
+ /* T_IDENTIFIER */ {(const char*)0,0},
+ /* T_IDIV */ {"\\",0},
+ /* T_IDN */ {"idn",0},
+ /* T_IF */ {"if",1},
+ /* T_IMAGE */ {"image",1},
+ /* T_IMP */ {"imp",0},
+ /* T_INC */ {"inc",1},
+ /* T_INPUT */ {"input",1},
+ /* T_INTEGER */ {(const char*)0,0},
+ /* T_INV */ {"inv",0},
+ /* T_IS */ {"is",1},
+ /* T_JUNK */ {(const char*)0,0},
+ /* T_KILL */ {"kill",1},
+ /* T_LE */ {"<=",0},
+ /* T_LET */ {"let",1},
+ /* T_LINEINPUT */ {"line input",1},
+ /* T_LIST */ {"list",1},
+ /* T_LLIST */ {"llist",1},
+ /* T_LOAD */ {"load",1},
+ /* T_LOCAL */ {"local",1},
+ /* T_LOCATE */ {"locate",1},
+ /* T_LOCK */ {"lock",1},
+ /* T_LOCK_READ */ {"lock read",1},
+ /* T_LOCK_WRITE */ {"lock write",1},
+ /* T_LOOP */ {"loop",1},
+ /* T_LOOPUNTIL */ {"loop until",1},
+ /* T_LPRINT */ {"lprint",1},
+ /* T_LSET */ {"lset",1},
+ /* T_LT */ {"<",0},
+ /* T_MAT */ {"mat",1},
+ /* T_MATINPUT */ {"mat input",1},
+ /* T_MATPRINT */ {"mat print",1},
+ /* T_MATREAD */ {"mat read",1},
+ /* T_MATREDIM */ {"mat redim",1},
+ /* T_MATWRITE */ {"mat write",1},
+ /* T_MINUS */ {"-",0},
+ /* T_MKDIR */ {"mkdir",1},
+ /* T_MOD */ {"mod",0},
+ /* T_MULT */ {"*",0},
+ /* T_NAME */ {"name",1},
+ /* T_NE */ {"<>",0},
+ /* T_NEW */ {"new",1},
+ /* T_NEXT */ {"next",1},
+ /* T_NOT */ {"not",0},
+ /* T_ON */ {"on",1},
+ /* T_ONERROR */ {"on error",1},
+ /* T_ONERRORGOTO0 */ {"on error goto 0",1},
+ /* T_ONERROROFF */ {"on error off",1},
+ /* T_OP */ {"(",0},
+ /* T_OPEN */ {"open",1},
+ /* T_OPTIONBASE */ {"option base",1},
+ /* T_OPTIONRUN */ {"option run",1},
+ /* T_OPTIONSTOP */ {"option stop",1},
+ /* T_OR */ {"or",1},
+ /* T_OUT */ {"out",1},
+ /* T_PLUS */ {"+",0},
+ /* T_POKE */ {"poke",1},
+ /* T_POW */ {"^",0},
+ /* T_PRINT */ {"print",1},
+ /* T_PUT */ {"put",1},
+ /* T_QUOTE */ {(const char*)0,1},
+ /* T_RANDOMIZE */ {"randomize",1},
+ /* T_READ */ {"read",1},
+ /* T_REAL */ {(const char*)0,0},
+ /* T_REM */ {(const char*)0,1},
+ /* T_RENAME */ {"rename",1},
+ /* T_RENUM */ {"renum",1},
+ /* T_REPEAT */ {"repeat",1},
+ /* T_RESTORE */ {"restore",1},
+ /* T_RESUME */ {"resume",1},
+ /* T_RETURN */ {"return",1},
+ /* T_RSET */ {"rset",1},
+ /* T_RUN */ {"run",1},
+ /* T_SAVE */ {"save",1},
+ /* T_SELECTCASE */ {"select case",1},
+ /* T_SEMICOLON */ {";",0},
+ /* T_SHARED */ {"shared",1},
+ /* T_SHELL */ {"shell",1},
+ /* T_SLEEP */ {"sleep",1},
+ /* T_SPC */ {"spc",0},
+ /* T_STEP */ {"step",1},
+ /* T_STOP */ {"stop",1},
+ /* T_STRING */ {(const char*)0,0},
+ /* T_SUB */ {"sub",1},
+ /* T_SUBEND */ {"subend",1},
+ /* T_SUBEXIT */ {"subexit",1},
+ /* T_SWAP */ {"swap",1},
+ /* T_SYSTEM */ {"system",1},
+ /* T_TAB */ {"tab",0},
+ /* T_THEN */ {"then",1},
+ /* T_TO */ {"to",1},
+ /* T_TRN */ {"trn",0},
+ /* T_TROFF */ {"troff",1},
+ /* T_TRON */ {"tron",1},
+ /* T_TRUNCATE */ {"truncate",1},
+ /* T_UNLOCK */ {"unlock",1},
+ /* T_UNNUM */ {"unnum",1},
+ /* T_UNNUMBERED */ {"",0},
+ /* T_UNTIL */ {"until",1},
+ /* T_USING */ {"using",0},
+ /* T_WAIT */ {"wait",1},
+ /* T_WEND */ {"wend",1},
+ /* T_WHILE */ {"while",1},
+ /* T_WIDTH */ {"width",1},
+ /* T_WRITE */ {"write",1},
+ /* T_XOR */ {"xor",0},
+ /* T_XREF */ {"xref",0},
+ /* T_ZER */ {"zer",0},
+ /* T_ZONE */ {"zone",1},
+ };
+
+ /* precompute indentation */ /*{{{*/
+ if (indent) thisindent=nextindent=*indent;
+ t=token;
+ do
+ {
+ switch (t->type)
+ {
+ case T_CASEELSE:
+ case T_CASEVALUE:
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ break;
+ }
+ case T_DEFFN:
+ case T_FUNCTION:
+ {
+ struct Token *cp;
+
+ for (cp=t; cp->type!=T_EOL && cp->type!=T_CP; ++cp);
+ if ((cp+1)->type!=T_EQ)
+ {
+ ++thisnotindent;
+ ++nextindent;
+ }
+ infn=1;
+ break;
+ }
+ case T_COLON: infn=0; break;
+ case T_DEFPROC:
+ case T_DO:
+ case T_DOUNTIL:
+ case T_DOWHILE:
+ case T_REPEAT:
+ case T_SUB:
+ case T_WHILE: ++thisnotindent; ++nextindent; break;
+ case T_FOR:
+ {
+ if ((t>token && ((t-1)->type==T_COLON || (t-1)->type==T_INTEGER || (t-1)->type==T_UNNUMBERED)))
+ {
+ ++thisnotindent; ++nextindent;
+ }
+ break;
+ }
+ case T_SELECTCASE: thisnotindent+=2; nextindent+=2; break;
+ case T_EQ:
+ {
+ if (infn || (t>token && ((t-1)->type==T_COLON || (t-1)->type==T_INTEGER || (t-1)->type==T_UNNUMBERED)))
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ if (nextindent) --nextindent;
+ }
+ infn=0;
+ break;
+ }
+ case T_ENDFN:
+ case T_FNEND:
+ case T_ENDIF:
+ case T_ENDPROC:
+ case T_SUBEND:
+ case T_LOOP:
+ case T_LOOPUNTIL:
+ case T_UNTIL:
+ case T_WEND:
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ if (nextindent) --nextindent;
+ break;
+ }
+ case T_ENDSELECT:
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ if (nextindent) --nextindent;
+ if (nextindent) --nextindent;
+ break;
+ }
+ case T_NEXT:
+ {
+ ++t;
+ while (1)
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ if (nextindent) --nextindent;
+ if (t->type==T_IDENTIFIER)
+ {
+ ++t;
+ if (t->type==T_OP)
+ {
+ int par=0;
+
+ do
+ {
+ if (t->type==T_OP) ++par;
+ else if (t->type==T_CP) --par;
+ if (t->type!=T_EOL) ++t;
+ else break;
+ } while (par);
+ }
+ if (t->type==T_COMMA) ++t;
+ else break;
+ }
+ else break;
+ }
+ break;
+ }
+ case T_THEN: if ((t+1)->type==T_EOL) { ++thisnotindent; ++nextindent; } break;
+ case T_ELSE:
+ {
+ if (t==token+1)
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ }
+ break;
+ }
+ case T_ELSEIFELSE:
+ {
+ if (t==token+1)
+ {
+ if (thisnotindent) --thisnotindent; else if (thisindent) --thisindent;
+ }
+ if (nextindent) --nextindent;
+ break;
+ }
+ default: break;
+ }
+ } while (t++->type!=T_EOL);
+ /*}}}*/
+ if (width>=0) /* whole line */
+ {
+ if (width) /* nicely formatted listing */
+ {
+ assert (token->type==T_UNNUMBERED || token->type==T_INTEGER);
+ if (token->type==T_INTEGER) String_appendPrintf(s,"%*ld ",width,token->u.integer);
+ else String_appendPrintf(s,"%*s ",width,"");
+ }
+ else assert (token->type==T_UNNUMBERED);
+ ++token;
+ }
+ while (thisindent--) String_appendPrintf(s," ");
+ do
+ {
+ if (s->length>oldlength && token->type!=T_EOL)
+ {
+ const char *keyword;
+
+ if ((keyword=table[token->type].text)==(const char*)0) keyword="X";
+ if (ns && s->character[s->length-1]!=' ')
+ {
+ String_appendPrintf(s," ");
+ }
+ else if (isalnum((int)(s->character[s->length-1])) && isalnum((int)*keyword))
+ {
+ String_appendPrintf(s," ");
+ }
+ else if (s->character[s->length-1]!=' ' && table[token->type].space)
+ {
+ String_appendChar(s,' ');
+ }
+ }
+ if (spaceto && token==spaceto) break;
+ switch (token->type)
+ {
+ case T_DATAINPUT: String_appendChars(s,token->u.datainput); break;
+ case T_ELSEIFIF: break;
+ case T_IDENTIFIER: String_appendChars(s,token->u.identifier->name); break;
+ case T_INTEGER: String_appendPrintf(s,"%ld",token->u.integer); break;
+ case T_HEXINTEGER: String_appendPrintf(s,"&h%lx",token->u.hexinteger); break;
+ case T_OCTINTEGER: String_appendPrintf(s,"&o%lo",token->u.octinteger); break;
+ case T_JUNK: String_appendChar(s,token->u.junk); break;
+ case T_REAL:
+ {
+ String_appendPrintf(s,"%.*g",DBL_DIG,token->u.real);
+ if ((token->u.real<((double)LONG_MIN)) || (token->u.real>((double)LONG_MAX))) String_appendChar(s,'!');
+ break;
+ }
+ case T_REM: String_appendPrintf(s,"%s%s",uppercase?"REM":"rem",token->u.rem); break;
+ case T_QUOTE: String_appendPrintf(s,"'%s",token->u.rem); break;
+ case T_STRING: /*{{{*/
+ {
+ size_t l=token->u.string->length;
+ char *data=token->u.string->character;
+
+ String_appendPrintf(s,"\"");
+ while (l--)
+ {
+ if (*data=='"') String_appendPrintf(s,"\"");
+ String_appendPrintf(s,"%c",*data);
+ ++data;
+ }
+ String_appendPrintf(s,"\"");
+ break;
+ }
+ /*}}}*/
+ default:
+ {
+ if (uppercase)
+ {
+ struct String u;
+
+ String_new(&u);
+ String_appendChars(&u,table[token->type].text);
+ String_ucase(&u);
+ String_appendString(s,&u);
+ String_destroy(&u);
+ }
+ else String_appendChars(s,table[token->type].text);
+ }
+ }
+ ns=table[token->type].space;
+ } while (token++->type!=T_EOL);
+ if (indent) *indent=nextindent;
+ if (spaceto && s->length>oldlength) memset(s->character+oldlength,' ',s->length-oldlength);
+ return s;
+}
+/*}}}*/
+void Token_init(int b_c, int uc) /*{{{*/
+{
+#define PROPERTY(t,assoc,unary_priority,binary_priority,is_unary,is_binary) \
+ Token_property[t]=(assoc<<8)|(unary_priority<<5)|(binary_priority<<2)|(is_unary<<1)|is_binary
+
+ backslash_colon=b_c;
+ uppercase=uc;
+ PROPERTY(T_POW, 1,0,7,0,1);
+ PROPERTY(T_MULT, 0,0,5,0,1);
+ PROPERTY(T_DIV, 0,0,5,0,1);
+ PROPERTY(T_IDIV, 0,0,5,0,1);
+ PROPERTY(T_MOD, 0,0,5,0,1);
+ PROPERTY(T_PLUS, 0,6,4,1,1);
+ PROPERTY(T_MINUS,0,6,4,1,1);
+ PROPERTY(T_LT, 0,0,3,0,1);
+ PROPERTY(T_LE, 0,0,3,0,1);
+ PROPERTY(T_EQ, 0,0,3,0,1);
+ PROPERTY(T_GE, 0,0,3,0,1);
+ PROPERTY(T_GT, 0,0,3,0,1);
+ PROPERTY(T_NE, 0,0,3,0,1);
+ PROPERTY(T_NOT, 0,2,0,1,0);
+ PROPERTY(T_AND, 0,0,1,0,1);
+ PROPERTY(T_OR, 0,0,0,0,1);
+ PROPERTY(T_XOR, 0,0,0,0,1);
+ PROPERTY(T_EQV, 0,0,0,0,1);
+ PROPERTY(T_IMP, 0,0,0,0,1);
+}
+/*}}}*/