/* TACKER: xmanmonk (Russ Mannex)
* DATE: 10-Aug-16 22:39:17
*
* Here's another little BASIC interpreter for you all. Credit goes to:
*
* Diomidis Spinellis
* Imperial College, University of London
* Myrsinis 1
* GR-145 62 Kifissia
* Greece
*
* "manual" upon request.
*/
int E [ SMAX ] ; /* subroutine line number stack */
int L [ CMAX ] ; /* FOR loop beginning line number */
int M [ CMAX ] ; /* FOR loop maximum index value */
int P [ CMAX ] ; /* program variable value */
int l , i , j ;
int * C ; /* subroutine stack pointer */
char B [ BMAX ] ; /* command input buffer */
char F [ 2 ] ; /* temporary search string */
STRPTR m [ 1 + LMAX ] ; /* pointers to lines of program */
STRPTR p , q , x , y , z , s , d ;
FILE * f ; /* file pointer for input and output */
STRPTR strstr ( STRPTR s , STRPTR o )
{
STRPTR x , y , z ;
for ( x = s ; * x ; x ++ ) {
for ( y = x , z = o ; * z && * y == * z ; y ++ ) z ++ ;
if ( z > o && ! * z ) return x ;
} return 0 ;
} /* end strstr */
void G ( void ) ;
int S ( void ) ;
int J ( void ) ;
int K ( void ) ;
int V ( void ) ;
int W ( void ) ;
int Y ( void ) ;
int main ( void ) {
int tmp ; /* temp var to fix bug 07Sep2005 Somos */
m [ LMAX ] = "E" ; /* "END" */
while ( puts ( "Ok" ) , gets ( B ) )
switch ( * B ) {
case 'R' : /* "RUN" command */
C = E ;
l = 1 ;
for ( i = 0 ; i < CMAX ; P [ i ++ ] = 0 ) ; /* initialize variables */
while ( l ) {
while ( ! ( s = m [ l ] ) ) l ++ ;
if ( ! strstr ( s , "\"" ) ) {
while ( ( p = strstr ( s , "<>" ) ) ) * p ++ = '#' , * p = ' ' ;
while ( ( p = strstr ( s , "<=" ) ) ) * p ++ = '$' , * p = ' ' ;
while ( ( p = strstr ( s , ">=" ) ) ) * p ++ = '!' , * p = ' ' ;
}
d = B ;
while ( ( * F = * s ) ) {
if ( * s == '"' ) j ++ ;
if ( j & 1 || ! strstr ( " \t" , F ) )
* d ++ = * s ;
s ++ ;
}
* d -- = j = 0 ;
if ( B [ 1 ] != '=' ) switch ( * B ) {
case 'E' : /* "END" */
l = - 1 ;
break ;
case 'R' : /* "REM" */
if ( B [ 2 ] != 'M' ) l = * -- C ; /* "RETURN" */
break ;
case 'I' :
if ( B [ 1 ] == 'N' ) { /* "INPUT" */
tmp = *d ; /* save for bug fix next line 07Sep2005 Somos */
gets ( p = B ) ; P [ tmp ] = S ( ) ;
} else { /* "IF" */
* ( q = strstr ( B , "TH" ) ) = 0 ; /* "THEN" */
p = B + 2 ;
if ( S ( ) ) { p = q + 4 ; l = S ( ) - 1 ; }
}
break ;
case 'P' : /* "PRINT" */
if ( B [ 5 ] == '"' ) {
* d = 0 ; puts ( B + 6 ) ;
} else {
p = B + 5 ;
printf ( "%d\n" , S ( ) ) ;
}
break ;
case 'G' : /* "GOTO" */
p = B + 4 ;
if ( B [ 2 ] == 'S' ) { /* "GOSUB" */
* C ++ = l ; p ++ ; }
l = S ( ) - 1 ;
break ;
case 'F' : /* "FOR" */
* ( q = strstr ( B , "TO" ) ) = 0 ; /* "TO" */
p = B + 5 ;
P [ i = B [ 3 ] ] = S ( ) ;
p = q + 2 ;
M [ i ] = S ( ) ;
L [ i ] = l ;
break ;
case 'N' : /* "NEXT" */
if ( ++ P [ * d ] <= M [ * d ] ) l = L [ * d ] ;
} else {
p = B + 2 ;
P [ * B ] = S ( ) ; }
l ++ ;
} /* end while l */
break ;
case 'L' : /* "LIST" command */
for ( i = 0 ; i < LMAX ; i ++ )
if ( m [ i ] ) printf ( "%d %s\n", i , m [ i ] ) ;
break ;
case 'N' : /* "NEW" command */
for ( i = 0 ; i < LMAX ; i ++ )
if ( m [ i ] ) { free ( m [ i ] ) ; m [ i ] = 0 ; }
break ;
case 'B' : /* "BYE" command */
return 0 ;
break ;
case 'S' : /* "SAVE" command */
f = fopen ( B + 5 , "w" ) ;
for ( i = 0 ; i < LMAX ; i ++ )
if ( m [ i ] ) fprintf ( f , "%d %s\n" , i , m [ i ] ) ;
fclose ( f ) ;
break ;
case 'O' : /* "OLD" command */
f = fopen ( B + 4 , "r" ) ;
while ( fgets ( B , BMAX , f ) ) {
* strstr ( B , "\n" ) = 0 ;
G ( ) ;
}
fclose ( f ) ;
break ;
case 0 :
default :
G ( ) ;
} /* end switch *B */
return 0 ;
} /* end main */
void G ( void ) { /* get program line from buffer */
l = atoi ( B ) ;
if ( m [ l ] ) free ( m [ l ] ) ;
if ( ( p = strstr ( B , " " ) ) )
strcpy ( m [ l ] = malloc ( strlen ( p ) ) , p + 1 ) ;
else m [ l ] = 0 ;
} /* end G */
/* recursive descent parser for arithmetic/logical expressions */
int S ( void ) {
int o = J ( ) ;
switch ( * p ++ ) {
case '=' : return o == S ( ) ;
break ;
case '#' : return o != S ( ) ;
default : p -- ; return o ;
}
} /* end S */
int J ( void ) {
int o = K ( ) ;
switch ( * p ++ ) {
case '<' : return o < J ( ) ;
break ;
case '>' : return o > J ( ) ;
default : p -- ; return o ;
}
} /* end J */
int K ( void ) {
int o = V ( ) ;
switch ( * p ++ ) {
case '$' : return o <= K ( ) ;
break ;
case '!' : return o >= K ( ) ;
default : p -- ; return o ;
}
} /* end K */
int V ( void ) {
int o = W ( ) ;
switch ( * p ++ ) {
case '+' : return o + V ( ) ;
break ;
case '-' : return o - V ( ) ;
default : p -- ; return o ;
}
} /* end V */
int W ( void ) {
int o = Y ( ) ;
switch ( * p ++ ) {
case '*' : return o * W ( ) ;
break ;
case '/' : return o / W ( ) ;
default : p -- ; return o ;
}
} /* end W */
int Y ( void ) {
int o ;
return
( * p == '-' ) ? ( p ++ , - Y ( ) ) :
( * p >= '0' && * p <= '9' ) ? strtol ( p , & p , 0 ) :
( * p == '(' ) ?
( p ++ , o = S ( ) , p ++ , o ) :
P [ * p ++ ] ;
} /* end Y */