/* 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. */ #include #include #define SMAX 999 #define CMAX 256 #define BMAX 999 #define LMAX 9999 typedef char * STRPTR ; 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 */ /* end of DDS-BASIC program */