nuttx-apps/interpreters/bas/bas_token.l

1939 lines
62 KiB
Plaintext
Raw Normal View History

/* Tokens and token sequence arrays. */
%{
#include <nuttx/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>
2014-11-08 14:19:29 +01:00
#include <termios.h>
#include "bas_auto.h"
#include "bas_token.h"
#include "bas_statement.h"
2014-11-08 18:47:35 +01:00
static int g_matchdata;
static int g_backslash_colon;
static int g_uppercase;
int yylex(void);
2014-11-08 18:47:35 +01:00
static struct Token *g_cur;
static void string(const char *text)
{
2014-11-08 18:47:35 +01:00
if (g_cur)
{
const char *t;
char *q;
size_t l;
for (t=text+1,l=0; *(t+1); ++t,++l)
{
if (*t=='"') ++t;
}
2014-11-08 18:47:35 +01:00
g_cur->u.string=malloc(sizeof(struct String));
String_size(String_new(g_cur->u.string),l);
for (t=text+1,q=g_cur->u.string->character; *(t+1); ++t,++q)
{
*q=*t;
if (*t=='"') ++t;
}
}
}
static void string2(void)
{
2014-11-08 18:47:35 +01:00
if (g_cur)
{
char *t,*q;
size_t l;
for (t=yytext+1,l=0; *t; ++t,++l)
{
if (*t=='"') ++t;
}
2014-11-08 18:47:35 +01:00
g_cur->u.string=malloc(sizeof(struct String));
String_size(String_new(g_cur->u.string),l);
for (t=yytext+1,q=g_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 */
2014-11-08 18:47:35 +01:00
if (g_matchdata) BEGIN(DATAINPUT);
"#" return T_CHANNEL;
{REAL} {
int overflow;
double d;
d=Value_vald(yytext,(char**)0,&overflow);
if (overflow)
{
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.junk=yytext[0];
yyless(1);
return T_JUNK;
}
2014-11-08 18:47:35 +01:00
if (g_cur) g_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)
{
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.junk=yytext[0];
yyless(1);
return T_JUNK;
}
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.real=d;
return T_REAL;
}
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.integer=n;
return T_INTEGER;
}
{HEXINTEGER} {
int overflow;
long int n;
n=Value_vali(yytext,(char**)0,&overflow);
if (overflow)
{
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.junk=yytext[0];
yyless(1);
return T_JUNK;
}
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.hexinteger=n;
return T_HEXINTEGER;
}
{OCTINTEGER} {
int overflow;
long int n;
n=Value_vali(yytext,(char**)0,&overflow);
if (overflow)
{
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.junk=yytext[0];
yyless(1);
return T_JUNK;
}
2014-11-08 18:47:35 +01:00
if (g_cur) g_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;
"\\" {
2014-11-08 18:47:35 +01:00
if (g_backslash_colon)
{
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->statement=stmt_COLON_EOL;
return T_COLON;
}
return T_IDIV;
}
":" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_COLON_EOL;
}
return T_COLON;
}
";" return T_SEMICOLON;
"<" return T_LT;
"<=" return T_LE;
"=<" return T_LE;
"<>"|"><" return T_NE;
"=" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_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" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CALL;
}
return T_CALL;
}
"case"[ \t]+"else" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CASE;
g_cur->u.casevalue=malloc(sizeof(struct Casevalue));
}
return T_CASEELSE;
}
"case" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CASE;
g_cur->u.casevalue=malloc(sizeof(struct Casevalue));
}
return T_CASEVALUE;
}
"chdir" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CHDIR_MKDIR;
}
return T_CHDIR;
}
"clear" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CLEAR;
}
return T_CLEAR;
}
"close" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CLOSE;
}
return T_CLOSE;
}
"close"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CLOSE;
}
return T_CLOSE;
}
"cls"|"home" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CLS;
}
return T_CLS;
}
"color" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_COLOR;
}
return T_COLOR;
}
"con" return T_CON;
"copy" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_COPY_RENAME;
}
return T_COPY;
}
"data"|"d." {
BEGIN(DATAINPUT);
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_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} {
2014-11-08 18:47:35 +01:00
if (g_cur) g_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" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEC_INC;
}
return T_DEC;
}
"defdbl" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
}
return T_DEFDBL;
}
"defint" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
}
return T_DEFINT;
}
"defstr" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFINT_DEFDBL_DEFSTR;
}
return T_DEFSTR;
}
"def"/[ \t]+fn[ \t]*[A-Z_0-9\.] {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
g_cur->u.localSyms=(struct Symbol*)0;
}
return T_DEFFN;
}
"def"/[ \t]+proc[A-Z_0-9\.] {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
g_cur->u.localSyms=(struct Symbol*)0;
}
return T_DEFPROC;
}
"delete" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DELETE;
}
return T_DELETE;
}
"dim" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DIM;
}
return T_DIM;
}
"display" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DISPLAY;
}
return T_DISPLAY;
}
"do" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DO;
}
return T_DO;
}
{DOUNTIL} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DOcondition;
}
return T_DOUNTIL;
}
{DOWHILE} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DOcondition;
}
return T_DOWHILE;
}
"edit" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_EDIT;
}
return T_EDIT;
}
"else"|"el." {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ELSE_ELSEIFELSE;
}
return T_ELSE;
}
"else"/"if" {
BEGIN(ELSEIF);
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ELSE_ELSEIFELSE;
}
return T_ELSEIFELSE;
}
<ELSEIF>"if" {
BEGIN(INITIAL);
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_IF_ELSEIFIF;
}
return T_ELSEIFIF;
}
end[ \t]+function {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDFN;
}
return T_ENDFN;
}
{ENDIF} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDIF;
}
return T_ENDIF;
}
{ENDPROC} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDPROC_SUBEND;
}
return T_ENDPROC;
}
{ENDSELECT} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDSELECT;
}
return T_ENDSELECT;
}
"end"[ \t]*"sub" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDPROC_SUBEND;
}
return T_SUBEND;
}
"end" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_END;
}
return T_END;
}
"environ" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENVIRON;
}
return T_ENVIRON;
}
"erase" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ERASE;
}
return T_ERASE;
}
"eqv" return T_EQV;
{EXITDO} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_EXITDO;
}
return T_EXITDO;
}
{EXITFOR} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_EXITFOR;
}
return T_EXITFOR;
}
"exit"[ \t]+"function" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_FNEXIT;
}
return T_FNEXIT;
}
"exit"[ \t]+"sub" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SUBEXIT;
}
return T_SUBEXIT;
}
"field" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_FIELD;
}
return T_FIELD;
}
"field"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_FIELD;
}
return T_FIELD;
}
"fnend" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_EQ_FNRETURN_FNEND;
}
return T_FNEND;
}
"fnreturn" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_EQ_FNRETURN_FNEND;
}
return T_FNRETURN;
}
"for" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_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" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
g_cur->u.localSyms=(struct Symbol*)0;
}
return T_FUNCTION;
}
"get" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_GET_PUT;
}
return T_GET;
}
"get"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_GET_PUT;
}
return T_GET;
}
"go"[ \t]*"sub" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_GOSUB;
}
return T_GOSUB;
}
"go"[ \t]*"to" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RESUME_GOTO;
}
return T_GOTO;
}
"idn" return T_IDN;
"if" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_IF_ELSEIFIF;
}
return T_IF;
}
"image"[ \t]*/[^"\n \t] {
BEGIN(IMAGEFMT);
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_IMAGE;
}
return T_IMAGE;
}
<IMAGEFMT>.*$ {
BEGIN(INITIAL);
2014-11-08 18:47:35 +01:00
if (g_cur)
{
size_t l;
l=strlen(yytext);
2014-11-08 18:47:35 +01:00
g_cur->u.string=malloc(sizeof(struct String));
String_size(String_new(g_cur->u.string),l);
memcpy(g_cur->u.string->character,yytext,l);
}
return T_STRING;
}
"image" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_IMAGE;
}
return T_IMAGE;
}
"imp" return T_IMP;
"inc" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEC_INC;
}
return T_INC;
}
"input" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_INPUT;
}
return T_INPUT;
}
"input"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_INPUT;
}
return T_INPUT;
}
"inv" return T_INV;
"is" return T_IS;
"kill" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_KILL;
}
return T_KILL;
}
"let" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LET;
}
return T_LET;
}
"list" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LIST_LLIST;
}
return T_LIST;
}
"llist" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LIST_LLIST;
}
return T_LLIST;
}
"load" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOAD;
}
return T_LOAD;
}
"local" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOCAL;
}
return T_LOCAL;
}
"locate" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOCATE;
}
return T_LOCATE;
}
"lock" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOCK_UNLOCK;
}
return T_LOCK;
}
"lock"[ \t]+"read" return T_LOCK_READ;
"lock"[ \t]+"write" return T_LOCK_WRITE;
"loop" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOOP;
}
return T_LOOP;
}
{LOOPUNTIL} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOOPUNTIL;
}
return T_LOOPUNTIL;
}
"lprint" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_PRINT_LPRINT;
}
return T_LPRINT;
}
"lset" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LSET_RSET;
}
return T_LSET;
}
"mat"[ \t]+"input" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MATINPUT;
}
return T_MATINPUT;
}
"mat"[ \t]+"print" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MATPRINT;
}
return T_MATPRINT;
}
"mat"[ \t]+"read" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MATREAD;
}
return T_MATREAD;
}
"mat"[ \t]+"redim" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MATREDIM;
}
return T_MATREDIM;
}
"mat"[ \t]+"write" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MATWRITE;
}
return T_MATWRITE;
}
"mat" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_MAT;
}
return T_MAT;
}
"mkdir" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_CHDIR_MKDIR;
}
return T_MKDIR;
}
"mod" return T_MOD;
"new" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_NEW;
}
return T_NEW;
}
"name" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_NAME;
}
return T_NAME;
}
"next" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_NEXT;
g_cur->u.next=malloc(sizeof(struct Next));
}
return T_NEXT;
}
"not" return T_NOT;
{ONERROROFF} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ONERROROFF;
}
return T_ONERROROFF;
}
{ONERRORGOTO0} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ONERRORGOTO0;
}
return T_ONERRORGOTO0;
}
{ONERROR} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ONERROR;
}
return T_ONERROR;
}
"on" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ON;
g_cur->u.on.pcLength=1;
g_cur->u.on.pc=(struct Pc*)0;
}
return T_ON;
}
"open" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OPEN;
}
return T_OPEN;
}
"option"[ \t]+"base" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OPTIONBASE;
}
return T_OPTIONBASE;
}
"option"[ \t]+"run" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OPTIONRUN;
}
return T_OPTIONRUN;
}
"option"[ \t]+"stop" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OPTIONSTOP;
}
return T_OPTIONSTOP;
}
"or" return T_OR;
"out" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OUT_POKE;
}
return T_OUT;
}
"print"|"p."|"?" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_PRINT_LPRINT;
}
return T_PRINT;
}
("print"|"p."|"?")/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_PRINT_LPRINT;
}
return T_PRINT;
}
"poke" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_OUT_POKE;
}
return T_POKE;
}
"put" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_GET_PUT;
}
return T_PUT;
}
"put"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_GET_PUT;
}
return T_PUT;
}
"randomize" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RANDOMIZE;
}
return T_RANDOMIZE;
}
"read" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_READ;
}
return T_READ;
}
"renum"|"ren." {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RENUM;
}
return T_RENUM;
}
"repeat"|"rep." {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_REPEAT;
}
return T_REPEAT;
}
"restore"|"res." {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RESTORE;
}
return T_RESTORE;
}
"resume" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RESUME_GOTO;
}
return T_RESUME;
}
"return"|"r." {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RETURN;
}
return T_RETURN;
}
"rset" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LSET_RSET;
}
return T_RSET;
}
"run" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_RUN;
}
return T_RUN;
}
"save" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SAVE;
}
return T_SAVE;
}
{SELECTCASE} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SELECTCASE;
g_cur->u.selectcase=malloc(sizeof(struct Selectcase));
}
return T_SELECTCASE;
}
"shared" return T_SHARED;
"shell" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SHELL;
}
return T_SHELL;
}
"sleep" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SLEEP;
}
return T_SLEEP;
}
"spc" return T_SPC;
"step" return T_STEP;
"stop" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_STOP;
}
return T_STOP;
}
"sub"[ \t]*"end" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ENDPROC_SUBEND;
}
return T_SUBEND;
}
"sub"[ \t]*"exit" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SUBEXIT;
}
return T_SUBEXIT;
}
"sub" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_DEFFN_DEFPROC_FUNCTION_SUB;
g_cur->u.localSyms=(struct Symbol*)0;
}
return T_SUB;
}
"swap" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_SWAP;
}
return T_SWAP;
}
"system"|"bye" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_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" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_TROFF;
}
return T_TROFF;
}
"tron" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_TRON;
}
return T_TRON;
}
"truncate" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_TRUNCATE;
}
return T_TRUNCATE;
}
"unlock" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LOCK_UNLOCK;
}
return T_UNLOCK;
}
"unnum" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_UNNUM;
}
return T_UNNUM;
}
"until" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_UNTIL;
}
return T_UNTIL;
}
"using" return T_USING;
"wait" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WAIT;
}
return T_WAIT;
}
"wend" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WEND;
g_cur->u.whilepc=malloc(sizeof(struct Pc));
}
return T_WEND;
}
"while" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WHILE;
g_cur->u.afterwend=malloc(sizeof(struct Pc));
}
return T_WHILE;
}
"width" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WIDTH;
}
return T_WIDTH;
}
"width"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WIDTH;
}
return T_WIDTH;
}
"write" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WRITE;
}
return T_WRITE;
}
"write"/"#" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_WRITE;
}
return T_WRITE;
}
"xor" return T_XOR;
"xref" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_XREF;
}
return T_XREF;
}
"zer" return T_ZER;
"zone" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_ZONE;
}
return T_ZONE;
}
{REM} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_QUOTE_REM;
g_cur->u.rem=strcpy(malloc(strlen(yytext+3)+1),yytext+3);
}
return T_REM;
}
"rename" {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_COPY_RENAME;
}
return T_RENAME;
}
{QUOTE} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_QUOTE_REM;
strcpy(g_cur->u.rem=malloc(strlen(yytext+1)+1),yytext+1);
2014-11-08 14:19:29 +01:00
}
return T_QUOTE;
}
{LINEINPUT} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
2014-11-08 18:47:35 +01:00
g_cur->statement=stmt_LINEINPUT;
}
return T_LINEINPUT;
}
{IDENTIFIER} {
2014-11-08 18:47:35 +01:00
if (g_cur)
{
size_t len;
char *s;
int fn;
2014-11-08 18:47:35 +01:00
g_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);
2014-11-08 18:47:35 +01:00
g_cur->u.identifier=malloc(offsetof(struct Identifier,name)+len+1);
if (fn)
{
2014-11-08 18:47:35 +01:00
memcpy(g_cur->u.identifier->name,yytext,2);
strcpy(g_cur->u.identifier->name+2,s);
}
else
{
2014-11-08 18:47:35 +01:00
strcpy(g_cur->u.identifier->name,s);
}
switch (yytext[yyleng-1])
{
2014-11-08 18:47:35 +01:00
case '$': g_cur->u.identifier->defaultType=V_STRING; break;
case '%': g_cur->u.identifier->defaultType=V_INTEGER; break;
default: g_cur->u.identifier->defaultType=V_REAL; break;
}
}
return T_IDENTIFIER;
}
[ \t\n]+
. {
2014-11-08 18:47:35 +01:00
if (g_cur) g_cur->u.junk=yytext[0];
return T_JUNK;
}
%%
2014-11-08 18:47:35 +01:00
int g_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;
2014-11-08 18:47:35 +01:00
g_cur=(struct Token*)0;
buf=yy_scan_string(ln);
/* determine number of tokens */
2014-11-08 18:47:35 +01:00
g_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);
2014-11-08 18:47:35 +01:00
g_cur=result=malloc(sizeof(struct Token)*l);
if (addNumber)
{
2014-11-08 18:47:35 +01:00
g_cur->type=T_UNNUMBERED;
++g_cur;
}
buf=yy_scan_string(ln);
lasttok=T_EOL;
2014-11-08 18:47:35 +01:00
g_matchdata=sawif=0;
while (g_cur->statement=NULL,(g_cur->type=yylex()))
{
2014-11-08 18:47:35 +01:00
if (g_cur->type==T_IF) sawif=1;
if (g_cur->type==T_THEN) sawif=0;
if (g_cur->type==T_GOTO && sawif)
{
sawif=0;
2014-11-08 18:47:35 +01:00
*(g_cur+1)=*g_cur;
g_cur->type=T_THEN;
lasttok=T_GOTO;
2014-11-08 18:47:35 +01:00
g_cur+=2;
}
2014-11-08 18:47:35 +01:00
else if ((lasttok==T_THEN || lasttok==T_ELSE) && g_cur->type==T_INTEGER)
{
2014-11-08 18:47:35 +01:00
*(g_cur+1)=*g_cur;
g_cur->type=T_GOTO;
g_cur->statement=stmt_RESUME_GOTO;
lasttok=T_INTEGER;
2014-11-08 18:47:35 +01:00
g_cur+=2;
}
else
{
2014-11-08 18:47:35 +01:00
lasttok=g_cur->type;
++g_cur;
}
}
2014-11-08 18:47:35 +01:00
g_cur->type=T_EOL;
g_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;
2014-11-08 18:47:35 +01:00
g_cur=(struct Token*)0;
buf=yy_scan_string(ln);
2014-11-08 18:47:35 +01:00
g_matchdata=1;
for (l=1; yylex(); ++l);
yy_delete_buffer(buf);
2014-11-08 18:47:35 +01:00
g_cur=result=malloc(sizeof(struct Token)*l);
buf=yy_scan_string(ln);
2014-11-08 18:47:35 +01:00
g_matchdata=1;
while (g_cur->statement=NULL,(g_cur->type=yylex())) ++g_cur;
g_cur->type=T_EOL;
g_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;
2014-11-08 14:19:29 +01:00
}
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;
}
2014-11-08 18:47:35 +01:00
case T_REM: String_appendPrintf(s,"%s%s",g_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:
{
2014-11-08 18:47:35 +01:00
if (g_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) \
2014-11-08 18:47:35 +01:00
g_token_property[t]=(assoc<<8)|(unary_priority<<5)|(binary_priority<<2)|(is_unary<<1)|is_binary
2014-11-08 18:47:35 +01:00
g_backslash_colon=b_c;
g_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);
}