From: Alan Cox Date: Thu, 2 Jun 2016 22:56:23 +0000 (+0100) Subject: pilot: Add rpilot, an implementation of the pilot programming language X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=646b730b2e6f82286267b767b74bed073ed7f02f;p=FUZIX.git pilot: Add rpilot, an implementation of the pilot programming language Taken from http://rpilot.sourceforge.net/pilot.html and cleaned up to fix various non-ANSIisms, missing includes and other mess. Could still do with more of a tidy up and space optimisations, but hey it fits, it's silly and it's in keeping with the period. --- diff --git a/Applications/rpilot-1.4.2/INSTALL b/Applications/rpilot-1.4.2/INSTALL new file mode 100644 index 00000000..115f6cfb --- /dev/null +++ b/Applications/rpilot-1.4.2/INSTALL @@ -0,0 +1,5 @@ + +To compile RPilot, run `make'. + +To install it, run `make install'. To install under a directory other than +/usr/local/, run `make install INSTALL_DIR=/the/new/dir'. diff --git a/Applications/rpilot-1.4.2/Makefile b/Applications/rpilot-1.4.2/Makefile new file mode 100644 index 00000000..255e8f52 --- /dev/null +++ b/Applications/rpilot-1.4.2/Makefile @@ -0,0 +1,40 @@ +CC = sdcc +ASM = sdasz80 +AR = sdar +LINKER = sdcc +FCC = ../../Library/tools/fcc -O2 +PLATFORM = +#PLATFORM = -tzx128 + +.SUFFIXES: .c .rel + +SRCS = bind.c calc.c cmds.c condex.c debug.c err.c interact.c label.c \ + line.c main.c math.c rpilot.c rpinfo.c rstring.c stack.c var.c + +INCS = bind.h calc.h cmds.h condex.h debug.h err.h interact.h label.h \ + line.h main.h math.h rpilot.h rpinfo.h rstring.h stack.h var.h + + +OBJS = $(SRCS:.c=.rel) + +LIBS = ../../Library/libs/syslib.lib + +all: rpilot + +rpilot: $(OBJS) + $(FCC) $(PLATFORM) $(OBJS) -o $@ + +$(OBJS): $(INCS) + +.c.rel: + $(FCC) $(PLATFORM) -DNO_INTER -DIGNORE_HASH -c $< + +%: %.rel + $(FCC) $(PLATFORM) $< -o $@ + +clean: + rm -f $(OBJS) rpilot $(SRCS:.c=) core *~ *.asm *.lst *.sym *.map *.noi *.lk *.ihx *.tmp *.bin + +rmbak: + rm -f *~ core + diff --git a/Applications/rpilot-1.4.2/Makefile.gcc b/Applications/rpilot-1.4.2/Makefile.gcc new file mode 100644 index 00000000..5c28c555 --- /dev/null +++ b/Applications/rpilot-1.4.2/Makefile.gcc @@ -0,0 +1,30 @@ +.SUFFIXES: .c .o + +SRCS = bind.c calc.c cmds.c condex.c debug.c err.c interact.c label.c \ + line.c main.c math.c rpilot.c rpinfo.c rstring.c stack.c var.c + +INCS = bind.h calc.h cmds.h condex.h debug.h err.h interact.h label.h \ + line.h main.h math.h rpilot.h rpinfo.h rstring.h stack.h var.h + + +OBJS = $(SRCS:.c=.o) + +all: rpilotgcc + +rpilotgcc: $(OBJS) + $(CC) $(PLATFORM) $(OBJS) -o $@ + +$(OBJS): $(INCS) + +.c.o: + $(CC) $(PLATFORM) -DNO_INTER -DIGNORE_HASH -c $< + +%: %.o + $(CC) $(PLATFORM) $< -o $@ + +clean: + rm -f $(OBJS) rpilot $(SRCS:.c=) core *~ *.asm *.lst *.sym *.map *.noi *.lk *.ihx *.tmp *.bin + +rmbak: + rm -f *~ core + diff --git a/Applications/rpilot-1.4.2/bind.c b/Applications/rpilot-1.4.2/bind.c new file mode 100644 index 00000000..061ee7e0 --- /dev/null +++ b/Applications/rpilot-1.4.2/bind.c @@ -0,0 +1,157 @@ +#include "rpilot.h" +#include "bind.h" +#include + +char *filebase( char *filename ) +{ + int dotpos, i; + + dotpos = -1; + for( i=strlen(filename)-1; i>=0; i-- ) { + if( filename[i] == '.' ) { + dotpos = i; + break; + } + } + + if( dotpos == -1 ) { + return filename; + } else { + return new_string_from( filename, 0, dotpos ); + } +} + +void bindfile( char *filename, char *outfile, char *dataname, char *funcname, + int mainfunc ) +{ + FILE *header, *source; + char *base, *hfile, *srcfile; + line *curr; + char *buffer; + int i; + + if( outfile == NULL ) { + base = filebase( filename ); + } else { + base = outfile; + } + + + hfile = (char *)malloc(strlen(base)+3); + strcpy( hfile, base ); + strcat( hfile, ".h" ); + srcfile = (char *)malloc(strlen(base)+3); + strcpy( srcfile, base ); + strcat( srcfile, ".c" ); + + if( (header = fopen(hfile, "w")) == NULL ) { + err( ERR_FILE, hfile ); + } + if( (source = fopen(srcfile, "w")) == NULL ) { + err( ERR_FILE, srcfile ); + } + + if( dataname == NULL ) { + dataname = new_string( "pilot_data" ); + } + if( funcname == NULL ) { + funcname = new_string( "run_pilot" ); + } + + + init(); + readfile( filename ); + + + // start outputting to files + + fprintf( header, "/* PILOT code datafile - generated by RPilot %s */\n\n", + VERSION ); + fprintf( header, "#ifndef _%s_h_\n#define _%s_h_\n\n", base, base ); + fprintf( header, "#include \n\n" ); + + fprintf( header, "void %s(void);\n", funcname ); + fprintf( header, "\n\n#endif" ); + + fclose( header ); + + + fprintf( source, "/* PILOT code source file - generated by RPilot %s */\n\n", + VERSION ); + fprintf( source, "#include \"%s\"\n\n", hfile ); + fprintf( source, "extern void run_bound( char *code[] );\n\n" ); + fprintf( source, "void %s(void)\n{\n", funcname ); + + fprintf( source, "char *%s[] = {\n", dataname ); + + curr = (line *)rpi->linehead; + curr = (line *)curr->next; // first entry is always blank, so skip it + + while( curr != NULL ) { + + print_line( curr ); + printf( "\n" ); + + buffer = get_line( curr ); + fprintf( source, "\"" ); + for( i = 0; inext; + } + + fprintf( source, "NULL\n};\n\n" ); + + fprintf( source, "run_bound( %s );\n}\n\n", dataname ); + + if( mainfunc == TRUE ) { + fprintf( source, "int main( int argc, char *argv[] )\n{\n" ); + fprintf( source, " %s();\n return 0;\n}\n\n", funcname ); + } + + fclose( source ); + +} + + +// run some bound code +void run_bound( char *code[] ) +{ + line *curr; + int i = 0; + + init(); + rpi->filename = new_string( "<>" ); + + curr = (line *)rpi->linehead; + + while( code[i] != NULL ) { + printf( "code[%d] is \"%s\"\n", i, code[i] ); + curr->next = (struct line *)new_line( code[i], '!', i+1 ); + curr = (line *)curr->next; + i++; + } + + curr = (line *)rpi->linehead; + rpi->linehead = curr->next; + interp(); +} + diff --git a/Applications/rpilot-1.4.2/bind.h b/Applications/rpilot-1.4.2/bind.h new file mode 100644 index 00000000..633a19b3 --- /dev/null +++ b/Applications/rpilot-1.4.2/bind.h @@ -0,0 +1,14 @@ +// header for bind.c + +#ifndef _bind_h_ +#define _bind_h_ + +#define BIND_HEADER "bind.h" + +void bindfile( char *filename, char *outfile, char *dataname, char *funcname, + int manifunc ); + +void run_bound( char *code[] ); + + +#endif diff --git a/Applications/rpilot-1.4.2/calc.c b/Applications/rpilot-1.4.2/calc.c new file mode 100644 index 00000000..5d6970cb --- /dev/null +++ b/Applications/rpilot-1.4.2/calc.c @@ -0,0 +1,198 @@ +/* + * calc.c - handle simple mathematical expressions + * rob - started july.25.2000 + * + * updates: + * - got around to finishing it - aug.11.2000 + * - RPilot special code - aug.11.2000 + */ + +#include "rpilot.h" +#include "rstring.h" +#include "calc.h" +#include "var.h" + +#include +#include +#include +#include + +int next_num( char *str, int *pos, int *status ); +char next_tok( char *str, int *pos ); +int find_match( char *str, int pos, char what, char match ); +int read_num( char *str, int *pos ); +int read_var( char *str, int *pos ); + +int calc( char *expr, int *status ) +{ + int pos = 0; + int num = 0, result = 0; + char op = 0; + + total_trim( expr ); + + result = next_num( expr, &pos, status ); + + while( pos < strlen(expr) ) { + + + op = next_tok( expr, &pos ); + num = next_num( expr, &pos, status ); + + + switch( op ) { + case 0 : // invalid operand + *status = CALC_NO_OP; + return 0; + break; + case '+' : + result += num; + break; + case '-' : + result -= num; + break; + case '/' : + result /= num; + break; + case '*' : + result *= num; + break; + case '%' : + result %= num; + break; + case '&' : + result &= num; + break; + case '|' : + result |= num; + break; + case '^' : + result ^= num; + break; + default: + *status = CALC_BAD_OP; + return 0; + break; + } + } + + *status = CALC_SUCCESS; + return result; +} + + + + +int next_num( char *str, int *pos, int *status ) +{ + char *inparen, *tempstr; + int result, rparen; + int mult = 1; + + *pos = wspace( str, *pos ); + + if( str[*pos] == '-' ) { + mult = -1; + *pos += 1; + } + if( str[*pos] == '(' ) { + rparen = find_match( str, *pos+1, ')', '(' ); + inparen = new_string_from( str, *pos+1, rparen-*pos-1 ); + + *pos = rparen+1; + + result = calc( inparen, status ); + free( inparen ); + } else if( str[*pos] == '#' ) { // variable + result = read_var( str, pos ); + } else { + result = read_num( str, pos ); + } + + return result * mult; +} + +/* + * find_match() + * Returns the position in the string `str' of the matching character. + * Example: find_match( "((8*8)+9)/2", 1, ')', '(' ) => 8 + */ +int find_match( char *str, int pos, char what, char match ) +{ + int levels = 1; + int i = pos; + + do { + if( str[i] == what ) { + levels--; + } else if( str[i] == match ) { + levels++; + } + i++; + } while( levels != 0 ); + + return i-1; +} + + +int read_num( char *str, int *pos ) +{ + int start; + int numchars; + char *num; + int result; + + start = wspace( str, *pos ); + numchars = start; + + while( isdigit(str[numchars]) ) { + numchars++; + } + + num = new_string_from( str, start, numchars - start ); + + *pos = numchars; + + result = atoi( num ); + free( num ); + + return result; +} + + +char next_tok( char *str, int *pos ) +{ + int nows = wspace( str, *pos ); + *pos = nows; + + *pos += 1; // increment position counter + return str[nows]; +} + + + +int read_var( char *str, int *pos ) +{ + int start; + int numchars; + char *var; + int result; + + start = *pos; + numchars = start + 1; + + while( isalpha(str[numchars]) ) { + numchars++; + } + + var = new_string_from( str, start, numchars - start ); + + // printf( "*** read_var(): var = \"%s\"\n", var ); + + *pos = numchars; + + result = get_numvar( var ); + free( var ); + + return result; +} diff --git a/Applications/rpilot-1.4.2/calc.h b/Applications/rpilot-1.4.2/calc.h new file mode 100644 index 00000000..1518d9fb --- /dev/null +++ b/Applications/rpilot-1.4.2/calc.h @@ -0,0 +1,16 @@ +/* + * calc.h - header file for the calc package + * rob linwood (rcl211@nyu.edu) + * see README for more information + */ + +#ifndef _calc_h_ +#define _calc_h_ + +#define CALC_SUCCESS 0 /* Indicates success */ +#define CALC_NO_OP 1 /* No mathematical operator in expression */ +#define CALC_BAD_OP 2 /* Unknown mathematical operator in expression */ + +int calc( char *expr, int *status ); + +#endif diff --git a/Applications/rpilot-1.4.2/cmds.c b/Applications/rpilot-1.4.2/cmds.c new file mode 100644 index 00000000..0de38142 --- /dev/null +++ b/Applications/rpilot-1.4.2/cmds.c @@ -0,0 +1,341 @@ +/* + cmds.c - RPilot commands functions +*/ + + +#include "rpilot.h" +#include "math.h" + +#include +#include +#include +#include + +#ifndef isblank +#define isblank(ch) (ch==' ' || ch == '\t') +#endif + +/* FIXME: move this into the C headers where it belongs */ +#ifndef RAND_MAX +#define RAND_MAX 32767 +#endif + +/* + * internal_type takes a string and formats it like it would be for a T: + * statement, but returning a string rather than printing it to the screen + */ +char *internal_type( char *str ) +{ + int i; + int nextsp; + char *varname; + char output[500], *ret; + + + if( str == NULL ) { + return new_string(""); + } + + + // output = (char *)malloc(5000); + strcpy( output, "" ); + + for( i=0; ilastacc ); + rpi->lastacc = new_string( "$ACCEPT" ); + } else if( str[0] == '$' ) { // we need to read a string variable + fgets( inbuf, MAXLINE-1, stdin ); + chop( inbuf ); + if( !strcmp(inbuf, "") ) { // did the user enter a blank line? + strcpy( inbuf, "[BLANK]" ); // FIXME ....maybe + } + set_strvar( str, inbuf ); + free( rpi->lastacc ); + rpi->lastacc = new_string( str ); + } else if( str[0] == '#' ) { // read a numeric var + fgets( inbuf, MAXLINE-1, stdin ); + chop( inbuf ); + i = atoi( inbuf ); + // scanf( "%d", &i ); + set_numvar( str, i ); + free( rpi->lastacc ); + rpi->lastacc = new_string( str ); + } + + fflush(stdin); +} + + +void cmd_type( char *str ) +{ +/* int i; */ +/* int nextsp; */ +/* char *varname; */ + +/* if( str == NULL ) { */ +/* //puts( "T: empty arguments (str == NULL)" ); */ +/* return; */ +/* } */ + +/* for( i=0; icurrline = (struct line *)stk_pop( (stack *)rpi->stk ); + +} + + +void cmd_match( char *str ) +{ + int count = numstr( str ); + int i; + // char *temp = (char *)malloc( strlen(str)+1 ); + char *temp = NULL; + + strupr( str ); + for( i=1; ilastacc)), temp) ) { + set_numvar( "#MATCHED", 1 ); + set_numvar( "#WHICH", i ); + return; + } + } + + free( temp ); + + set_numvar( "#MATCHED", 0 ); + set_numvar( "#WHICH", 0 ); +} + + + +void cmd_jump( char *str ) +{ + jump( str ); +} + + +void cmd_execute( char *str ) +{ + execute( str ); +} + +// Types a line if #matched == TRUE +void cmd_yes( char *str ) +{ + + if( get_numvar( "#MATCHED") == TRUE ) { + cmd_type( str ); + } +} + + +// Types a line if #matched == FALSE +void cmd_no( char *str ) +{ + + if( get_numvar("#MATCHED") == FALSE ) { + cmd_type( str ); + } +} + + + +// call a shell +void cmd_shell( char *str ) +{ + int retcode; + + retcode = system( get_strval(str) ); + set_numvar( "#RETCODE", retcode ); +} + + + +void cmd_debug( char *str ) +{ + debug(); +} + + +void cmd_generate( char *str ) +{ + int upper, lower, rnd; + char *exp, *var; + + if( !strcmp(str, "") ) { + // do what? + } else { + trim( str ); + } + + var = parse( str, 1 ); + exp = parse( str, 2 ); + lower = get_numval( exp ); + free( exp ); + exp = parse( str, 3 ); + upper = get_numval( exp ); + + srand( (unsigned)time(NULL) ); + + // rnd = lower + (int)( (upper * rand()) / RAND_MAX ); + rnd = lower+(int) ((float)upper*rand()/(RAND_MAX+1.0)); + + set_numvar( var, rnd ); + free( exp ); + free( var ); +} diff --git a/Applications/rpilot-1.4.2/cmds.h b/Applications/rpilot-1.4.2/cmds.h new file mode 100644 index 00000000..46ea2f01 --- /dev/null +++ b/Applications/rpilot-1.4.2/cmds.h @@ -0,0 +1,43 @@ +/* + cmds.h - header for cmds.c +*/ + +#ifndef _cmds_h_ +#define _cmds_h_ + +#include "rpilot.h" + +// use() implememnts PILOT's version of GOSUB +void cmd_use( char *str ); +// Handles variable assignment +void cmd_compute( char *str ); +// Handles user input +void cmd_accept( char *str ); +// Displays data +void cmd_type( char *str ); +// Marks the end of a subroutine +void cmd_end( char *str ); +// Does string matching +void cmd_match( char *str ); +// PILOT's version of GOTO +void cmd_jump( char *str ); +// Displays text if #matched equals YES +void cmd_yes( char *str ); +// Displays text if #matched equals NO +void cmd_no( char *str ); + + +// The following are nonstandard functions available in rpilot programs + +// Executes a line of PILOT code +void cmd_execute( char *str ); +// Allows access to the operating system +void cmd_shell( char *str ); +// Gives debugging info from inside a PILOT programs +void cmd_debug( char *str ); +// Puts a random number in a given variable +void cmd_generate( char *str ); + + +#endif + diff --git a/Applications/rpilot-1.4.2/condex.c b/Applications/rpilot-1.4.2/condex.c new file mode 100644 index 00000000..71b8e253 --- /dev/null +++ b/Applications/rpilot-1.4.2/condex.c @@ -0,0 +1,182 @@ +// condex.c - conditional expression handling + +#include "rpilot.h" +#include +#include + + +condex *new_condex( char *str ) +{ + int i = -1; + condex *c; + + c = (condex *)malloc( sizeof(condex) ); + c->next = NULL; + + if( !strcmp(str, "") ) { + c->lside = NULL; + c->rside = NULL; + c->op = OP_NULL; + return c; + } + + if( !strcmp(str, "Y") ) { + c->op = OP_YES; + return c; + } else if( !strcmp(str, "N") ) { + c->op = OP_NO; + return c; + } + + for(i=0; i') || (str[i]=='<') || (str[i]=='!') ) { + break; + } + } + + // we can't find a relational operator + if( i == strlen(str) ) { + printf("str=\"%s\"\n", str ); + err( NO_RELAT, str ); + return NULL; + } + + if( str[i] == '=' ) { + c->op = OP_EQL; + } else if( (str[i] == '>') && (str[i+1] != '=') ) { + c->op = OP_GT; + } else if( (str[i] == '<') && (str[i+1] != '=') && (str[i+1] != '>') ) { + c->op = OP_LT; + } else if( (str[i] == '>') && (str[i+1] == '=') ) { + c->op = OP_GE; + } else if( (str[i] == '<') && (str[i+1] == '=') ) { + c->op = OP_LE; + } else if( (str[i] == '<') && (str[i+1] == '>') ) { + c->op = OP_NEQL; + } else { // Unknown operation + err( BAD_RELAT, str ); + } + + if( (c->op==OP_EQL) || (c->op==OP_GT) || (c->op==OP_LT) ) { + c->lside = new_string_from( str, 0, i ); + c->rside = new_string_from( str, i+1, strlen(str)-i ); + } else { + c->lside = new_string_from( str, 0, i ); + c->rside = new_string_from( str, i+2, strlen(str)-i-1 ); + } + + return c; +} + +/* hack to support binding */ +void print_condex_to( condex *curr, FILE *stream ) +{ + fprintf( stream, "%s ", curr->lside ); + switch( curr->op ) { + case OP_EQL : fprintf( stream, "=" ); + break; + case OP_NEQL : fprintf( stream, "<>" ); + break; + case OP_GT : fprintf( stream, ">" ); + break; + case OP_LT : fprintf( stream, "<" ); + break; + case OP_GE : fprintf( stream, ">=" ); + break; + case OP_LE : fprintf( stream, "<=" ); + break; + case OP_YES : fprintf( stream, "Y" ); + break; + case OP_NO : fprintf( stream, "N" ); + break; + } + fprintf( stream, " %s", curr->rside ); +} + + +char *get_condex( condex *curr ) +{ + char *buffer; + + buffer = (char *)malloc(1024); + + sprintf( buffer, "%s ", curr->lside ); + + switch( curr->op ) { + case OP_EQL : strcat( buffer, "=" ); + break; + case OP_NEQL : strcat( buffer, "<>" ); + break; + case OP_GT : strcat( buffer, ">" ); + break; + case OP_LT : strcat( buffer, "<" ); + break; + case OP_GE : strcat( buffer, ">=" ); + break; + case OP_LE : strcat( buffer, "<=" ); + break; + case OP_YES : strcat( buffer, "Y" ); + break; + case OP_NO : strcat( buffer, "N" ); + break; + } + sprintf( buffer, " %s", curr->rside ); + + return buffer; +} + +void print_condex( condex *curr ) +{ + print_condex_to( curr, stdout ); +} + + +void print_condex_list( condex *head ) +{ + condex *curr = head; + + while( curr ) { + print_condex( curr ); + printf( "\n" ); + curr = (condex *)curr->next; + } +} + + +#ifdef TEST + +int main( int argc, char *argv[] ) +{ + + FILE *f; + char buf[256]; + condex *head, *curr; + + if( argc < 2 ) { + puts( "condex: Usage condex filename" ); + return 0; + } + + f = fopen( argv[1], "r" ); + + head = new_condex(""); + curr = head; + + do { + strset( buf, 0 ); + fgets( buf, 255, f ); + chop( buf ); + if( strcmp(buf, "") ) { + curr->next = (struct condex *)new_condex( buf ); + curr = (condex *)curr->next; + } + } while( !feof(f) ); + + + print_condex_list( head ); + + return 0; +} + +#endif + diff --git a/Applications/rpilot-1.4.2/condex.h b/Applications/rpilot-1.4.2/condex.h new file mode 100644 index 00000000..abe8d31b --- /dev/null +++ b/Applications/rpilot-1.4.2/condex.h @@ -0,0 +1,33 @@ +// condex.h - condex type and functions + +#ifndef _condex_h_ +#define _condex_h_ + +#include "rpilot.h" +#include + +#define OP_NULL 0 +#define OP_EQL 1 +#define OP_LT 2 +#define OP_GT 3 +#define OP_NEQL 4 +#define OP_LE 5 +#define OP_GE 6 +#define OP_YES 7 +#define OP_NO 8 + +typedef struct { + int op; + char *rside; + char *lside; + struct condex *next; +} condex; + +condex *new_condex( char *str ); + +void print_condex_to( condex *curr, FILE *stream ); +void print_condex( condex *curr ); +void print_condex_list( condex *head ); +char *get_condex( condex *curr ); + +#endif diff --git a/Applications/rpilot-1.4.2/debug.c b/Applications/rpilot-1.4.2/debug.c new file mode 100644 index 00000000..b4b2f1b2 --- /dev/null +++ b/Applications/rpilot-1.4.2/debug.c @@ -0,0 +1,73 @@ +// debug.c - RPilot's interactive debugger + +#include + +#include "rpilot.h" +#include "debug.h" + +void debug(void) +{ + char inbuf[MAXLINE]; + char lastcmd[MAXLINE]; + + do { + strset( inbuf, 0 ); + printf( "debug> " ); + fgets( inbuf, MAXLINE-1, stdin ); + proc( inbuf, lastcmd ); + } while( strcasecmp(inbuf, "exit") ); + +} + +void proc( char *inbuf, char *lastcmd ) +{ + + char *tok; + + if( !strcmp(inbuf, "" ) ) { + strncpy( inbuf, lastcmd, MAXLINE-1 ); + } + + tok = parse( inbuf, 1 ); + + if( !strcasecmp(tok, "step") ) { + // step( rpi ); + } else if( !strcasecmp(tok, "skip") ) { + // skip( rpi ); + } else if( !strcasecmp(tok, "print") ) { + // print( rpi, inbuf ); + } else if( !strcasecmp(tok, "set") ) { + // set( rpi, inbuf ); + } else if( !strcasecmp(tok, "list") ) { + // list( rpi, inbuf ); + } else if( !strcasecmp(tok, "run") ) { + // run( rpi, inbuf ); + } else if( !strcasecmp(tok, "stop") ) { + // stop( rpi ); + } else if( !strcasecmp(tok, "help") ) { + // help(); + } else if( !strcasecmp(tok, "jump") ) { + // jump( rpi, inbuf ); + } else if( !strcasecmp(tok, "exec" ) ) { + // exec( rpi, inbuf ); + } else if( !strcasecmp(tok, "use") ) { + // use( rpi, inbuf ); + } else if( !strcasecmp(tok, "restart") ) { + // restart( rpi ); + } + + free( tok ); + +} + + +void dump_numvars(void) +{ + numvar *n = (numvar *)rpi->numhead; + + while( n != NULL ) { + printf( "\"%s\" = %d\n", n->name, n->val ); + n = (numvar *)n->next; + } + +} diff --git a/Applications/rpilot-1.4.2/debug.h b/Applications/rpilot-1.4.2/debug.h new file mode 100644 index 00000000..a006ee40 --- /dev/null +++ b/Applications/rpilot-1.4.2/debug.h @@ -0,0 +1,10 @@ +#ifndef _debug_h_ +#define _debug_h_ + +#include "rpilot.h" + +void debug(void); +void proc( char *inbuf, char *lastcmd ); +void dump_numvars(void); + +#endif diff --git a/Applications/rpilot-1.4.2/doc/CHANGELOG b/Applications/rpilot-1.4.2/doc/CHANGELOG new file mode 100644 index 00000000..f4776e74 --- /dev/null +++ b/Applications/rpilot-1.4.2/doc/CHANGELOG @@ -0,0 +1,41 @@ +Change log for RPilot +--------------------- + +1.4.2 (Released June 21st, 2002) + - Fix usage of `isblank()', a GNU extension (Thanks to Patrick Eaton) + - Add some #defines to rpilot.h to replace a few hard-coded constants + - RPilot is over 4 years old. Wow. + +1.4.1 (Released August 13th, 2000) + - New math system! I think that was the only remaining code from the 1.0 + releases, so the 1.4 versions now represent a complete rewrite. + - Added Unix man page. + - First version to use RPM and BSD packages. + +1.4: (Released July 4th, 2000) + - Rewrote everything except the math system (which needs it bad!) + - Merged parse.c and rstring.c + - Fixed a few examples. + - Added an interactive mode. + - Added the special variables $prompt, #rpilot, and #retcode + - Revised documentation. + - Changed contact info in all files. + +1.01: (Released July 4th, 1998) + - Fixed two bugs in rpilot.c, so it will now work when compiled by gcc. The + lines read "strcpy( string, '\0')" when that should have been + "strset( string, 0)". Thanks to Ken M who pointed this out. + - Fixed a few bugs in parse.c - see that file for more info. + - Revised documentation to point out differences in the size of numbers based + on what compiler the program was compiled with, and correct a few typos. + - Added a new example program, fact.p, for calculating factorials. + - Included a DJGPP-compiled version of RPilot in the DOS distribution. + - Released the first native OS/2 version. + - Added this file. + +1.0: (Released Apr 17th, 1998) + - First version for DOS and Linux. + + + + diff --git a/Applications/rpilot-1.4.2/doc/COPYING b/Applications/rpilot-1.4.2/doc/COPYING new file mode 100644 index 00000000..3358a7be --- /dev/null +++ b/Applications/rpilot-1.4.2/doc/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/Applications/rpilot-1.4.2/doc/examples.txt b/Applications/rpilot-1.4.2/doc/examples.txt new file mode 100644 index 00000000..530847e3 --- /dev/null +++ b/Applications/rpilot-1.4.2/doc/examples.txt @@ -0,0 +1,13 @@ +The following examples are included with RPilot: +dosmenu.p - A program which displays a menu of commands for DOS users +unixmenu.p - The same as above, only it's for Linux users +french.p - A quiz on your knowledge of French +guess.p - A simple number-guessing game +hello.p - "Hello World!", the cannonical first trial program +jump-use.p - An example of Jumps and Using subroutines +math.p - A demonstration of RPilot's mathematical capabilities +name.p - A simple program which asks for your name and age +recurse.p - A recursive PILOT program which calls itself +crazy.p - An example of overusing the "X" command +fact.p - A program which recursively solves factorials +inter.p - Run RPilot interactively, by reading statements and running them diff --git a/Applications/rpilot-1.4.2/doc/rpilot.1 b/Applications/rpilot-1.4.2/doc/rpilot.1 new file mode 100644 index 00000000..04f68b91 --- /dev/null +++ b/Applications/rpilot-1.4.2/doc/rpilot.1 @@ -0,0 +1,60 @@ +.\" RPilot man page +.TH RPILOT 1 + +.SH NAME +rpilot \- Rob's PILOT interpreter + + +.SH SYNOPSIS +.B rpilot +.RI [ -options ] +.I file + + +.SH DESCRIPTION + +.BR rpilot +is an intepreter for the IEEE-standard language PILOT. + +.SH OPTIONS + +.TP +.BI \-b \ +Don't print the banner when starting up +.BR rpilot + +.TP +.B \-i +Enters an interactive mode when no file names are given on the command line. +To do so, it first looks for a file called +.B interact.p +in the current directory. If that cannot be found, the file pointed to by the +.B RPILOT_INTERACT +variable will be tried. If either of these can be found, they will be loaded +and run. Finally, if neither of these can be loaded, an error will be +reported. + +.TP +.B \-? +Prints a short summary of command line options. + +.SH SEE ALSO +The RPilot web site at http://rpilot.sourceforge.net/ + +.SH BUGS +Please report any bugs to the author at rcl211@nyu.edu + +.SH COPYING +.B RPilot +is Copyright 1998,2002 Rob Linwood + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + + +.SH AUTHOR +Rob Linwood +.br +http://homepages.nyu.edu/~rcl211/ diff --git a/Applications/rpilot-1.4.2/doc/rpilot.txt b/Applications/rpilot-1.4.2/doc/rpilot.txt new file mode 100644 index 00000000..5fa542b3 --- /dev/null +++ b/Applications/rpilot-1.4.2/doc/rpilot.txt @@ -0,0 +1,438 @@ + + -- RPilot: Rob's PILOT Version 1.4.2 -- + -- Copyright 1998,2002 Rob Linwood (rcl211@nyu.edu) -- + -- WWW: http://rpilot.sourceforge.net/ -- + +Intro:: + RPilot is an interpreter for the PILOT programming language. PILOT, + the Programmed Inquiry, Learning, Or Teaching language, was originally + designed to be used by teachers as an aid in instruction. PILOT is + easy to learn, and most people should be able to in a very short amount + of time. PILOT was first developed in 1962, and was standardized by + the IEEE in 1991. RPilot probably isn't completely standard, but it + is very close. It also adds a few extensions not found in standard + PILOT interpretors, such as rudimentry debugging and the ability to + call other programs. RPilot was written in 100% ANSI standard C, and + should be easily portable to any platform with a standard C compiler. + + +Programming:: + PILOT programs consist of a series of statements, which are either + labels or function calls. PILOT statements all end with a newline, and + the lines themselves may be no longer than 127 characters long. PILOT + is case insensitive when it comes to label and variable names, $name, + $NaMe, and $NAME all refer to the same variable. Speaking of variables, + PILOT has only two different types: string, and numeric. + + Variables:: + String variables consist of a list of characters which can be up to + 127 bytes long. Numeric variables are equivilent to C's int. They + can be any number in the range of -2,147,483,648 to 2,147,483,648 + (with 32 bit rpilot) or -32,768 to 32,768 (with 16 bit DOS rpilot). + Variables are referenced by their names, which can be up to 10 + characters in length, and consist of a type designator followed by + any non-whitespace characters. When I say "type designator", I mean + that all string variables have a "$" as their first character, and all + numerics use "#". Thus, $count refers to a string, and #count to + a number. This leads to another point: a string variable and a + numeric one can have the same name, so both $count and #count could + exist at the same time. They are independent of each other, however. + + PILOT also implements labels, which are used just like in any other + language, and are declared in the following way: + + *labelname + + This would define a label called "labelname". All label definitions + start with an asterisk (the "*"), and follow that with the label name. + Label names, like variable names, are case insensitive. + + PILOT statements that do not declare labels have the following syntax: + + [conditional] : [arguments] + + is any of RPilot's internal commands, which I will cover + shortly. [conditional] is an optional conditional expression which + determines whether the statement will be executed. This is different + from more contemporary languages which use "if" clauses and the like, in + that the "if" clause is implemented in every function, in a way. + [arguments] is an optional list of arguments to be passed to the function. + Some functions require arguments; others don't. + + Commands:: + Commands in RPilot are exactly one character long. This may seem + a little wierd, but that's the way things are. Even if you are a + PILOT expert, you will find it beneficial to read ALL of the command + descriptions, to learn the nuances of RPilot. On to the commands: + + R :: + The "R" (Remark) command flags the rest of the line as a comment, + and therefore the interpreter ignores it. This is a good way to + add reminders to yourself about what you have typed. Example: + + R: This is a comment + + A :: + The "A" (Accept) command takes input from the user. It can + take the name of a string or numeric variable as an argument, in + which case it will store the input into the given variable. If + no arguments are given, it stores input into the string variable + "$answer". Examples: + + R: The next line gets a string from the user and puts it in + : "$answer" + A: + + R: This gets a number and stores it in "#group" + A: #group + + Note that you can only name one variable for each A command + + T :: + The "T" (Type) command is used to display information. If any + arguments are given, it displays the string, substituting + variables as needed. With no arguments, it prints a blank line. + Examples: + + R: The next line prints the contents of the variables "$name", + : "$rank", and "#serialnum" + T: Name: $name Rank: $rank Serial Number: #serialnum + + T: Note that instead of using the same command over and over + T: again, as I have just done, you can skip the command name + T: and just use the colon, as I have done in a few examples, + : like this. + : It saves time, and makes things look nicer. + + J :: + The "J" (Jump) command is like GOTO in BASIC and other languages. + It causes the interpreter to jump to the label given to it as + an argument. When giving a label name, do not add on the + initial "*". Example: + + R: The next line causes a jump to the label "done" + J: done + + U :: + The "U" (Use) command is used to implement a sort of primitive + subroutine. It causes the interpreter to jump to the given + label, just like J, but first it pushes to current file offset + onto a stack. When the E command is reached, that value is + popped off and jumped to. This is like GOSUB in BASIC. + Example: + + U: sub + T: Back from the sub! + J: done + + *sub + T: Now we're in the sub. + R: We'll look at the "E" command next + E: + + *done + + E :: + The "E" (End) command is used with U to return from subroutines. + If no subroutines were called, E ends the program. Example: + + T: The next line ends this program + E: + T: This is never executed + + Also note the example for the U command. + + M :: + The "M" (Match) command is used to handle user input. It + compares a given list of strings to the last string which was + used to hold input from the A command. This also is very wierd, + and it would probably help to check some of the example programs. + If RPilot finds a match, it sets the variable "#matched" to 1, + and the variable "#which" to the position of the matched string + in the argument list. Example: + + T: What is your favorite flavor of ice cream? + A: $icecream + + R: The next line checks to see if "vanilla" or "mint" were + : entered during the last A command + M: vanilla mint + + If $icecream = "vanilla" then #which would equal 1. If the answer + was "mint", then #which would equal 2. In either case, #matched + would be set to 1. If neither matched what the user typed, then + #matched would be set to 0, and so would #which + + C :: + The "C" (Compute) command sets variables. The argument string + contains a variable name followed by an equal sign ("="), + followed by a value to assign tot he variable. For numerics, + this is a mathematical expression which can contain one or more + terms, and variables as well as constants. See the section on + math for more info on expressions. For strings, it is a list + of strings and variables which will be copied into the given + variable. For example: + + R: This causes "#number" to be incremented by 5 + C: #number = 5 + #number + + R: This copies the contents of "$firstname" and "$lastname" + : to the variable "$fullname" + C: $fullname = $firstname $lastname + + Y :: + The "Y" (Yes) command works like T, except that it only prints + if the variable "#matched" equals 1. This is usually used in + conjunction with M. Example: + + A: + M: Herbert Floyd + Y: You typed "Herbert" or "Floyd" + N: You entered some other name. + + N :: + The "N" (No) command is just the opposite of Y, it only prints + if "#matched" equals 0. For an example, see above. + + That's it for the standard PILOT. Next we take a look at RPilot's + extensions. + + X :: + The "X" (eXecute) command runs a line of PILOT code which you + pass to it. The argument(s) are either a constant string, + (ie, "T: Hello!"), or a string variable. Try the following: + + A: + X: $answer + + It will wait for you to input a string, and then will try to run + it. If you were to type "T: Boo!", that command would take + place, and "Boo!" would be displayed + + S :: + The "S" (Shell) command allows you to execute other programs. + This gives you access to the operating system and all other + programs on the user's machine. For example: + + S: dir + OR + S: /bin/ls + + will display a list of files, depending on what operating system + you are running. + + The return code of the program which you ran is stored in the + variable `#retcode'. If a program runs succesfully, this should + be zero. If not, it usually means that something went wrong. + + D :: + The "D" (Debug) command is used as a way to quickly and easily + get a list of all variables and labels. It takes a string as an + argument, and checks for two characters. If it sees an "l" or + an "L" (case is unimportant), it will dump a list of all labels + and their offsets. If it sees a "v" or a "V", it will do a + variable dump, listing all variables and their values. This is + useful when something goes wrong, and you need to check + everything at once. Example: + + D: Lv + + Lists all labels, followed by all variables + + G :: + The "G" (Generate) command is used to generate random numbers, + and place them in a variable. It takes three arguments, first + a numeric variable, then two numbers. It randomly creates a + number between the second and third arguments, and places it + in the variable specified by the first. Example: + + G: #rand 23 56 + + This generates a number between 23 and 56, and stores it in #rand + + This is especially useful when making things that require random + values, such as games. (See the example programs for a few games + that use G) + + + Math:: + RPilot supports the following mathematical operators (math ops): + + Standard: + + :: Adds two things together + - :: Subtracts one number from another + * :: Multiplies two numbers + / :: Divides one number by another + + RPilot Extensions: + % :: Gets the modulo (remainder after division) of two numbers + & :: Gets the bitwise AND of two numbers + | :: Bitwise OR of two numbers + ^ :: Bitwise XOR of two numbers + + I'm not sure how useful all the bitwise operators are, but they + were easy enough to add, so why not? RPilot works all expressions + from left to right, and currently ignores operator precedence. + + + Conditionals:: + RPilot statements can contain "conditional expressions" (condexs), + which are evaluated and checked to see if they are true. If so, + the rest of the statement is run. They are placed after the command, + such as in this example: + + J(#answer > 45): menu1 + + In this case, the condex is "(#answer > 45)" The J (Jump) will only + take place if the value of "#answer" is more than 45. If not, RPilot + goes on to the next line. RPilot understands the following + "relational operators" (relat ops): + + = :: True if two numbers are equal + < :: True if the first number is less than the second + > :: True if the first is greater than the second + <> :: True if the two numbers are not equal + <= :: True if the first is less than or equal to the second + >= :: True if the first is greater than or equal to the second + + Of course, you are free to use all the math ops in a condex, such as: + + T(#score + 10 >= 50): You made it by at least 10 points! + + Note, however, that you can have only one relational operator per + condex. + + In addition to standard condexs, there are also two other methods + of testing a condition, Y and N. If the condex of a statement is + a captial "Y", then RPilot checks to see if "#matched" is equal to + 1. If so, the condition is true, and is then executed. "N" is the + opposite, and checks whether "#matched" equals 0. If so, the + statement is executed. These are ususally used after an "M" command, + for example: + + A: $answer + M: 1776 1812 1968 1998 + R: The following line jumps to "correct" if "#matched" equals 1. + : That would be true if "M" matched any dates listed + JY: correct + R: If "#matched" equals 0, then "N" statements are true, and are + : then executed + TN: You did not answer correctly + + + Special Variables:: + RPilot has two special variables which you can use. They are special + because they are set by the interpreter itself, so you can use them + without assigning a value first. The two special variables are: + + $prompt - This is the prompt which is printed out for an A: (Accept) + command. The default value is ">". If you run the following + program: + + T: Please enter a number + C: $prompt = rpilot> + A: #number + + You would see that when you are asked for a number, the + prompt is "rpilot>" rather than ">". + + #rpilot - This is the version number of RPilot. For version 1.4, + it's value is 14. RPilot 1.5 would be 15, and 2.0 would + be 20. + + + Interactive Mode:: + If RPilot is invoked with the "-i" command line switch, it will + attempt to enter an interactive mode, where you type commands in, and + have them executed immediately. + + Interactive mode is not a part of the `rpilot' program, but rather + it should be written as an external PILOT program. Therefore, in + order for RPilot to use interactive mode, it needs a program to run. + It will find one in one of two ways: + + 1) Look for a program called "interact.p" in the current directory. + 2) Run the program specified by the RPILOT_INTERACT environment + variable. + + The `inter.p' file located in the examples directory is a good + program to use. Feel free to customize it by editing the source code. + + Note:: + I think that the best way to learn RPilot is to look through all the + example programs after reading this, and hopefully it will make more + sense. They are all fully commented, and are meant to serve as + learning aids. + + +Where to get RPilot:: + + The RPilot web site is located at http://rpilot.sourceforge.net/ All + new versions are released there first. + + RPilot for DOS will (hopefully) be found at the following places: + Note that the XX stands for the version number, ie rpilot10.zip for + version 1.0. + + ftp.simtel.net/pub/simtelnet/msdos/misclang/rpilotXX.zip + and it's many mirrors + + RPilot for Linux will be found at + + sunsite.unc.edu/pub/Linux/devel/lang/misc/rpilot-XX.tar.gz + and it's many mirrors + + RPilot for OS/2 2.0 and above wil l be at + + hobbes.nmsu.edu/pub/os2/dev/misc/rpos2xx.zip + and it's many mirrors + + The source code will in be all of the packages, along with makefiles and + tips relevant to the particular platform. Since RPilot is portable, all + of the versions were built from the exact same source. + + Also, check out my home page at http://auntfloyd.home.ml.org/ Updates + will always be available there, along with other cool stuff. + + +Contacting the Author:: + + If you find any bugs or have any questions/comments, write me at + rcl211@nyu.edu + + +Special Thanks to:: + + Ken Martwick - for sending me a bug report. So now you can run gcc- + compiled versions of RPilot. + + +License:: + Since Linux people seem to be big on licenses and garbage like that, + here's info on RPilot's license: + + ********************************************************************** + RPilot: Rob's PILOT Interpreter + Copyright 1998 Rob Linwood + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ********************************************************************** + + See the COPYING file for the full text. + +---------- +Rob Linwood (rcl211@nyu.edu) +http://homepages.nyu.edu/~rcl211/ + diff --git a/Applications/rpilot-1.4.2/err.c b/Applications/rpilot-1.4.2/err.c new file mode 100644 index 00000000..73802460 --- /dev/null +++ b/Applications/rpilot-1.4.2/err.c @@ -0,0 +1,79 @@ +/* + err.c - Error handling code for RPilot +*/ + +#include "rpilot.h" +#include + +int yesno( char *msg ) +{ + char buf[MAXLINE]; + + printf( "%s (Y/N) ", msg ); + fgets( buf, MAXLINE-1, stdin ); + + chop( buf ); + if( (!strcmp(strupr(buf), "Y")) || (!strcmp(strupr(buf), "YES")) ) { + return YES; + } else { + return NO; + } +} + +int err( int errnum, char *msg ) +{ + char *errbuf; + int linenum; + line *l; + + if( rpi != NULL ) { + l = (line *)rpi->currline; + linenum = l->linenum; + } else { + linenum = -1; + } + + errbuf = (char *)malloc( strlen(errstr(errnum)) + strlen(msg) ); + sprintf( errbuf, errstr(errnum), msg ); + + if( rpi != NULL ) { + printf( "RPilot Error in %s, line %d\n %s\n", + rpi->filename, linenum, errbuf ); + } else { + printf( "RPilot Error : %s\n", errbuf ); + } + + + + exit( errnum ); +} + +char *errstr( int errnum ) +{ + + char *errlist[] = { + "Duplicate label `%s'", // DUP_LABEL + "No file name specified", // NO_FILE + "Can't open file `%s'", // ERR_FILE + "Unknown command `%s'", // UNKNWN_CMD + "Out of memory!", // NO_MEM + "Duplicate variable `%s'", // DUP_VAR + "Unknown variable `%s'", // BAD_VAR + "Expected math symbol, not `%s'", // EXP_MATH + "Missing relational operator", // NO_RELAT + "Missing colon in statement", // NO_COLON + "Unknown label: `%s'", // BAD_LABEL + "Unknown relational operator: `%s'", // BAD_RELAT + "No equal sign in assignment", // NO_EQL + "Missing right parentheses in conditional expression", // NO_RPAREN + "Cannot assign value to constant `%s'", // CONS_ASGN + "Missing command line argument after `%s'" // NO_CLARG + }; + + if( errnum >= 0 ) { + return errlist[errnum]; + } else { + return ""; + } +} + diff --git a/Applications/rpilot-1.4.2/err.h b/Applications/rpilot-1.4.2/err.h new file mode 100644 index 00000000..f9053e6f --- /dev/null +++ b/Applications/rpilot-1.4.2/err.h @@ -0,0 +1,41 @@ +/* + err.h - prototypes and #defines for err.c +*/ + +#ifndef _err_h_ +#define _err_h_ + +#include "rpilot.h" + +/* Error message number definitions -- see err() for more */ +#define ERR_NONE -1 // No error +#define DUP_LABEL 0 // If there are two labels with the same name +#define NO_FILE 1 // If no file was given on the command line +#define ERR_FILE 2 // If the file given can't be opened +#define UNKWN_CMD 3 // If there is an unknown command in the source +#define NO_MEM 4 // If we run out of memory +#define DUP_VAR 5 // If there are two variables that share a name +#define BAD_VAR 6 // If a non-existantant variable is used +#define EXP_MATH 7 // When a non-math symbol where it shouldn't +#define NO_RELAT 8 // When a relational op is missing +#define NO_COLON 9 // statement is missing a colon +#define BAD_LABEL 10 // when an unknown label is called +#define BAD_RELAT 11 // a bad relational operator is used +#define NO_EQL 12 // no equal sign in an assignment +#define NO_RPAREN 13 // a condex is missing a right parenthese +#define CONS_ASGN 14 // attempt to assign a constant a value +#define NO_CLARGS 15 + +// Used to determine whether the program will halt on an error +#define FATAL 1 // Used when the error causes a call to exit() +#define NONFATAL 2 // Used when we can still go on + +#define YES TRUE +#define NO FALSE + +// Displays a given error message and optionally halts execution +//int err( rpinfo *rpi, int errnum ); +int err( int errnum, char *msg ); +char *errstr( int errnum ); + +#endif diff --git a/Applications/rpilot-1.4.2/examples/crazy.p b/Applications/rpilot-1.4.2/examples/crazy.p new file mode 100644 index 00000000..41a4b485 --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/crazy.p @@ -0,0 +1,4 @@ +R: crazy.p - A wierd way of printing stuff + : Written by Rob Linwood (auntfloyd@biosys.net) + +X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:T:Hi! diff --git a/Applications/rpilot-1.4.2/examples/dosmenu.p b/Applications/rpilot-1.4.2/examples/dosmenu.p new file mode 100644 index 00000000..6fa8dc69 --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/dosmenu.p @@ -0,0 +1,112 @@ +R: dosmenu.p - A simple DOS menu program + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: We put this label here so we can jump back to it later +*menu + +R: Print out the menu +T: ˙˙˙˙˙DOS Menu + : ================== + : 1. List Files + : 2. Edit some Files + : 3. Play Ultima VI + : 4. Find a file + : 5. Delete a file + : 6. Rename a file + : 7. Copy a file + : 8. Move a file + : 9. Quit + : + : What to do? (Enter 1, 2, 3, 4, 5, 6, 7, 8, or 9) + +R: Get the user's response +A: #what + +R: Jump to the specified labels + +J(#what = 1): list +J(#what = 2): edit +J(#what = 3): play +J(#what = 4): find +J(#what = 5): delete +J(#what = 6): rename +J(#what = 7): copy +J(#what = 8): move +J(#what = 9): quit + +R: If nothing above works, print an error message +T: + : I don't understand! + : +J: menu + +*list +R: First off, list the files +S: dir +R: then return +J: menu + +*edit +T: Edit which File? +A: $file + +R: Here we make $command equal to "edit" plus whatever is in $files +C: $command = edit $file + +T: $command + +R: Run the newly-constructed command +S: $command +J: menu + +*play +S: C:\ULTIMA\U6\ULTIMA6 +J: menu + +*find +R: Requires "Whereis" of some sort + : This is just like what happens in "edit" + +T: Find which file? +A: $file +C: $command = whereis $file +S: $command +J: menu + +*delete +T: Delete which file? +A: $file +C: $command = del $file +S: $command +J: menu + +*rename +T: Rename which file? +A: $file +T: To what? +A: $newname +C: $command = ren $file $newname +S: $command +J: menu + +*copy +T: Copy which file? +A: $file +T: To where? +A: $newname +C: $command = copy $file $newname +S: $command +J: menu + +*move +T: Move which file? +A: $file +T: To where? +A: $newname +C: $command = move $file $newname +S: $command +J: menu + +*quit +E: + diff --git a/Applications/rpilot-1.4.2/examples/fact.p b/Applications/rpilot-1.4.2/examples/fact.p new file mode 100644 index 00000000..3fa50f5b --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/fact.p @@ -0,0 +1,52 @@ +R: fact.p - A recursive PILOT program for solving factorials + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: A factorial of number n is written as n! It is the equal to the expression + : n! = n * (n-1) * (n-2) * (n - 3) * ... * (n - (n-1)) + : For example, 4! = 4 * 3 * 2 * 1 = 24. The way we solve this in PILOT is to + : use a programming technique called "recursion". In a recursive program, + : one part of the program (generally a subroutine) calls itself. This a + : powerful technique which is crucial in handling numerical sequences. Note + : that this is a simple example of recursion, but a useful one. + +T: This program can generate factorials of a number (n!) which you give it. + : Because the value of n! rises very rapidly with respect to n, RPilot will + : not be able to handle the result of n! for values of n larger than a + : certain number. On 32-bit systems, this number is 16. + : + : So please give me a number. +A: #num + +R: If #num is 0, 1, or 2, we don't need to solve. Instead, we go straight to + : the end. + : These are "special cases" which can be handled more quickly than others +J( #num = 0 ): zero +J( #num = 1): one +J( #num = 2): two + +R: Initialize the result (#res) to 0 +C: #res = #num + +*bang +J( #num = 1 ): done +C: #tmp = #num - 1 +C: #res = #tmp * #res +C: #num = #num -1 +J: bang + +*zero +T: The answer is Zero +E: + +*one +T: The answer is One +E: + +*two +T: The answer is Two +E: + +*done +T: The answer is #res + + diff --git a/Applications/rpilot-1.4.2/examples/french.p b/Applications/rpilot-1.4.2/examples/french.p new file mode 100644 index 00000000..b72c799e --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/french.p @@ -0,0 +1,152 @@ +R: french.p - A quiz on your skills in the French language + : Written by Rob Linwood (auntfloyd@biosys.net) + +T: Welcome to the French Quiz! + : You will be given a word in French, and asked to pick the BEST + : translation for it. + : + : Example: + : + : Fromage + : + : 1. Cat + : 2. Dog + : 3. Cheese + : 4. Mouse + : + : Here you would enter 1, 2, 3, or 4 depending on what you think + : the best translation for the word "Fromage" is. (btw, the answer is 3) + : + : Hit "Enter" to get started! + : +A: $junk + +R: Initialize the variables +C: #right = 0 +C: #wrong = 0 + +R: Let's get started with the quiz... + +T: + : Q1. Porte + : + : 1. Ring + : 2. Cup + : 3. Belt + : 4. Door +U: answer +C(#ans = 4): #right = #right + 1 +C(#ans <> 4): #wrong = #wrong + 1 + +T: + : Q2. Ceinture + : + : 1. Helmet + : 2. Belt + : 3. Bicycle + : 4. Cat +U: answer +C(#ans = 2): #right = #right + 1 +C(#ans <> 2): #wrong = #wrong + 1 + +T: + : Q3. Cambriolage + : + : 1. Floor wax + : 2. Robbery + : 3. Bus station + : 4. Expression +U: answer +C(#ans = 2): #right = #right + 1 +C(#ans <> 2): #wrong = #wrong + 1 + +T: + : Q4. Chapeau + : + : 1. Hat + : 2. Chair + : 3. Earring + : 4. Wig +U: answer +C(#ans = 1): #right = #right + 1 +C(#ans <> 1): #wrong = #wrong + 1 + +T: + : Q5. Conduire + : + : 1. To run + : 2. To remove + : 3. To drive + : 4. To type +U: answer +C(#ans = 3): #right = #right + 1 +C(#ans <> 3): #wrong = #wrong + 1 + +T: + : Q6. Chien + : + : 1. Cat + : 2. Rabbit + : 3. Mouse + : 4. Dog +U: answer +C(#ans = 4): #right = #right + 1 +C(#ans <> 4): #wrong = #wrong + 1 + +T: + : Q7. Jeterai + : + : 1. Will speak + : 2. Will run + : 3. Will throw + : 4. Will eat +U: answer +C(#ans = 3): #right = #right + 1 +C(#ans <> 3): #wrong = #wrong + 1 + +T: + : Q8. Irais + : + : 1. Will go + : 2. Will become + : 3. Will have + : 4. Will be +U: answer +C(#ans = 1): #right = #right + 1 +C(#ans <> 1): #wrong = #wrong + 1 + +T: + : Q9. Zut Alors! + : + : 1. Shucks! + : 2. Darn! + : 3. Oh my! + : 4. Sacre' Bleu! +U: answer +C: #right = #right + 1 + +T: + : Q10. Parlez-vous anglais? + : + : 1. I am lost. + : 2. I am a tourist. + : 3. I am looking to be mugged. + : 4. Do you speak English? +U: answer +C(#ans = 4): #right = #right + 1 +C(#ans <> 4): #wrong = #wrong + 1 +J: done + +*answer +A: #ans +T(#ans > 4): Please enter a number between 1 and 4 +T(#ans < 1): Please enter a number between 1 and 4 +J(#ans < 1): answer +J(#ans > 4): answer +E: + +*done + +C: #percent = #right * 10 +T: You got #right out of 10. This is #percent percent correct. + diff --git a/Applications/rpilot-1.4.2/examples/guess.p b/Applications/rpilot-1.4.2/examples/guess.p new file mode 100644 index 00000000..c7566f3b --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/guess.p @@ -0,0 +1,50 @@ +brtR: guess.p - A simple number guessing game + : Written by Rob Linwood (auntfloyd@biosys.net) + +*start + +T: I will think of a random number between 1 and 100. Can you guess it? + : + +R: Get a random number between 1 and 100 and put it in #rand +G: #rand 1 100 +r:T: #rand +R: Initialize the #tries variable, which holds the number of tries +C: #tries = 0 + +*guess + +R: Get the player's guess +T: Guess! +A: #guess + +R: Increase the number of tries +C: #tries = #tries + 1 + +R: Jump to the proper place based on whether the player guessed the number, + : guessed too high, or guessed too low +J(#guess = #rand): win +J(#guess > #rand): toobig +J(#guess < #rand): toosmall + +*toobig +T: Too big! + : +J: guess + +*toosmall +T: Too small! + : +J: guess + +*win +T(#tries > 1): Congratulations! You guessed it in #tries guesses! +T(#tries = 1): Congratulations! You guessed it in 1 guess! Lucky! +T: Play again? (Y/N) +A: +M: y yes yep sure +R: If any of the above match, (ie #matched = 1), jump to start +JY: start +E: + + diff --git a/Applications/rpilot-1.4.2/examples/hello.p b/Applications/rpilot-1.4.2/examples/hello.p new file mode 100644 index 00000000..56dba993 --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/hello.p @@ -0,0 +1,6 @@ +R: hello.p - Classic first program in any language + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: The next line simply displays "Hello, World!" + +T: Hello, World! diff --git a/Applications/rpilot-1.4.2/examples/inter.p b/Applications/rpilot-1.4.2/examples/inter.p new file mode 100644 index 00000000..6ad4a20f --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/inter.p @@ -0,0 +1,17 @@ +R: -*- Text -*- + +T: Welcome to interactive RPilot! + : + : Simply enter your commands, or `quit' to exit. + +*input +A: $command +M: quit +JY: done +X: $command +J: input + +*done + + + diff --git a/Applications/rpilot-1.4.2/examples/jump-use.p b/Applications/rpilot-1.4.2/examples/jump-use.p new file mode 100644 index 00000000..46160aef --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/jump-use.p @@ -0,0 +1,26 @@ +R: jump-use.p - An example of J and U + : Written by Rob Linwood (auntfloyd@biosys.net) + +T: We are about to jump far away to label1 +J: label1 +T: This text is never seen! If you can see this, you've got problems! +E: + +*label1 + +T: Now, we're going to call the subroutine "Woof" +U: woof +T: We're back from the subroutine! +E: + +*woof +T: Now we're in "Woof" +E: + + + + + + + + diff --git a/Applications/rpilot-1.4.2/examples/math.p b/Applications/rpilot-1.4.2/examples/math.p new file mode 100644 index 00000000..cc41ab3c --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/math.p @@ -0,0 +1,37 @@ +R: math.p - A demonstration of RPilot's math features + : Written by Rob Linwood (auntfloyd@biosys.net) + +T: This program is meant to show how good RPILOT is at math. I want + : you to give me two numbers, and I'll show you what I can do with them + : + : Ok, I'm ready for the first number + : + +A: #first + +T: + : Now the second + : + +A: #second + +C: #add = #first + #second +C: #sub = #first - #second +C: #mul = #first * #second +C: #div = #first / #second +C: #mod = #first % #second +C: #and = #first & #second +C: #or = #first | #second +C: #xor = #first ^ #second + +T: + : #first + #second = #add + : #first - #second = #sub + : #first * #second = #mul + : #first / #second = #div + : #first modulo #second = #mod + : #first AND #second = #and + : #first OR #second = #or + : #first XOR #second = #xor + : + diff --git a/Applications/rpilot-1.4.2/examples/name.p b/Applications/rpilot-1.4.2/examples/name.p new file mode 100644 index 00000000..0caac642 --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/name.p @@ -0,0 +1,22 @@ +R: name.p - Simple question & answer type program + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: Ask the user what their name is +T: What is your name? + +R: Get their answer and put it in $name +A: $name + +R: Ask for their age +T: How old are you? I won't tell! + +R: Get their answer to that question, and put it in #age +A: #age + +R: Display the information +T: Your name is $name and you are #age years old. + +R: We don't need an E: here because the file ends + + + diff --git a/Applications/rpilot-1.4.2/examples/recurse.p b/Applications/rpilot-1.4.2/examples/recurse.p new file mode 100644 index 00000000..3d4ffc2e --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/recurse.p @@ -0,0 +1,41 @@ +R: recures.p - an example of a recursive PILOT program + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: Ask a question + +T: Would you like to recurse again? (Y/N) + +R: Get the answer and put it in $answer, + : because no variable name was given + +A: + +R: Try to match any of the strings listed after the "M:" + +M: y yes sure yep + +R: If any of them matched, then #matched was set to 1 + : Next we Jump to "*recurse" if #matched equals 1 + +JY: recurse + +R: If nothing matched, we end the program + +E: + +R: Define a label called "recurse" + +*recurse + +R: Call rpilot again, and start running this file again + : Note: whether this will work or not depends on where the `recurse.p' file + : is located. We'll check in two locations. + +S: rpilot examples/recurse.p +J( #retcode = 0 ): done +S: rpilot recurse.p +J( #retcode = 0 ): done + +T: Sorry, I can't run the program! Return code: #retcode + +*done diff --git a/Applications/rpilot-1.4.2/examples/unixmenu.p b/Applications/rpilot-1.4.2/examples/unixmenu.p new file mode 100644 index 00000000..30093873 --- /dev/null +++ b/Applications/rpilot-1.4.2/examples/unixmenu.p @@ -0,0 +1,112 @@ +R: unixmenu.p - A simple Unix menu program + : Written by Rob Linwood (auntfloyd@biosys.net) + +R: We put this label here so we can jump back to it later +*menu + +R: Print out the menu +T: Unix Menu + : ================== + : 1. List Files + : 2. Edit some Files + : 3. Play Hack + : 4. Find a file + : 5. Delete a file + : 6. Rename a file + : 7. Copy a file + : 8. Move a file + : 9. Quit + : + : What to do? (Enter 1, 2, 3, 4, 5, 6, 7, 8, or 9) + +R: Get the user's response +A: #what + +R: Jump to the specified labels + +J(#what = 1): list +J(#what = 2): edit +J(#what = 3): play +J(#what = 4): find +J(#what = 5): delete +J(#what = 6): rename +J(#what = 7): copy +J(#what = 8): move +J(#what = 9): quit + +R: If nothing above works, print an error message +T: + : I don't understand! + : +J: menu + +*list +R: First off, list the files +S: /bin/ls -la +R: then return +J: menu + +*edit +T: Edit which File? +A: $file + +R: Here we make $command equal to "edit" plus whatever is in $files +C: $command = /bin/vi $file + +T: $command + +R: Run the newly-constructed command +S: $command +J: menu + +*play +R: You may have to change this, perhaps to /usr/local/games/hack +S: /usr/games/hack +J: menu + +*find +R: This is just like what happens in "edit" + +T: Find which file? +A: $file +C: $command = find / -name $file +S: $command +J: menu + +*delete +T: Delete which file? +A: $file +C: $command = rm -f $file +S: $command +J: menu + +*rename +T: Rename which file? +A: $file +T: What's its new name? +A: $newname +C: $command = mv $file $newname +S: $command +J: menu + +*copy +T: Copy which file? +A: $file +T: To where? +A: $newname +C: $command = cp $file $newname +S: $command +J: menu + +*move +T: Move which file? +A: $file +T: To where? +A: $newname +C: $command = mv $file $newname +S: $command +J: menu + +*quit +E: + diff --git a/Applications/rpilot-1.4.2/foo.c b/Applications/rpilot-1.4.2/foo.c new file mode 100644 index 00000000..84a53662 --- /dev/null +++ b/Applications/rpilot-1.4.2/foo.c @@ -0,0 +1,29 @@ +/* PILOT code source file - generated by RPilot 1.4 */ + +#include "foo.h" + +extern void run_bound( char *code[] ); + +void run_pilot(void) +{ +char *pilot_data[] = { +": Welcome to interactive RPilot!", +": ", +": Simply enter your commands, or `quit\' to exit.", +": $command", +": quit", +": done", +": $command", +": input", +NULL +}; + +run_bound( pilot_data ); +} + +int main( int argc, char *argv[] ) +{ + run_pilot(); + return 0; +} + diff --git a/Applications/rpilot-1.4.2/foo.h b/Applications/rpilot-1.4.2/foo.h new file mode 100644 index 00000000..e1cc8bbf --- /dev/null +++ b/Applications/rpilot-1.4.2/foo.h @@ -0,0 +1,11 @@ +/* PILOT code datafile - generated by RPilot 1.4 */ + +#ifndef _foo_h_ +#define _foo_h_ + +#include + +void run_pilot(void); + + +#endif \ No newline at end of file diff --git a/Applications/rpilot-1.4.2/interact.c b/Applications/rpilot-1.4.2/interact.c new file mode 100644 index 00000000..12b093c4 --- /dev/null +++ b/Applications/rpilot-1.4.2/interact.c @@ -0,0 +1,31 @@ +// interact.c - handle interactive mode + +#include "rpilot.h" + +#ifndef NO_INTER + + #include "inter.h" + +#endif + +void interact() +{ + FILE *f; + + if( (f = fopen("interact.p", "r")) == NULL ) { + if( (f = fopen(getenv(ENV_VAR), "r")) == NULL ) { +#ifndef NO_INTER + inter(); +#else + puts( "Can't run interactive mode. RPilot was compiled with NO_INTER." ); + exit( 1 ); +#endif + } else { + run( getenv(ENV_VAR) ); + } + } else { + run( "interact.p" ); + } +} + + diff --git a/Applications/rpilot-1.4.2/interact.h b/Applications/rpilot-1.4.2/interact.h new file mode 100644 index 00000000..9508888c --- /dev/null +++ b/Applications/rpilot-1.4.2/interact.h @@ -0,0 +1,8 @@ +#ifndef _interact_h_ +#define _interact_h_ + +#define ENV_VAR "RPILOT_INTERACT" + +void interact(); + +#endif diff --git a/Applications/rpilot-1.4.2/label.c b/Applications/rpilot-1.4.2/label.c new file mode 100644 index 00000000..aae1d1c9 --- /dev/null +++ b/Applications/rpilot-1.4.2/label.c @@ -0,0 +1,57 @@ +/* + * label.c - label handling code + */ + +#include "rpilot.h" + +#include + +label *new_label( char *name, line *lne, int linenum ) +{ + label *l; + + l = (label *)malloc( sizeof(label) ); + l->linenum = linenum; + l->stmnt = lne; + l->name = new_string( name ); + l->next = NULL; + + return l; +} + + +label *get_label( char *name ) +{ + label *l = (label *)rpi->lblhead; + + while( l != NULL ) { + if( !strcasecmp(l->name, name) ) { + return l; + } + l = (label *)l->next; + } + + err( BAD_LABEL, name ); +} + + +void print_label( label *l ) +{ + printf( "[line %d] %s: ", l->linenum, l->name ); + print_line( l->stmnt ); + printf( "\n" ); +} + +void print_label_list() +{ + label *l = (label *)rpi->lblhead; + + while( l != NULL ) { + print_label( l ); + l = (label *)l->next; + } + +} + + + diff --git a/Applications/rpilot-1.4.2/label.h b/Applications/rpilot-1.4.2/label.h new file mode 100644 index 00000000..3c6db593 --- /dev/null +++ b/Applications/rpilot-1.4.2/label.h @@ -0,0 +1,23 @@ +/* + label.h - header for label.c +*/ + +#ifndef _label_h_ +#define _label_h_ + +/* #include "line.h" */ +#include "rpilot.h" + +typedef struct { + char *name; + line *stmnt; + int linenum; + struct label *next; +} label; + +label *get_label( char *name ); +label *new_label( char *name, line *lne, int linenum ); +void print_label( label *l ); +void print_label_list(); + +#endif diff --git a/Applications/rpilot-1.4.2/line.c b/Applications/rpilot-1.4.2/line.c new file mode 100644 index 00000000..256022ec --- /dev/null +++ b/Applications/rpilot-1.4.2/line.c @@ -0,0 +1,246 @@ +/* + * line.c - RPilot syntax handling routines + */ + +#include "rpilot.h" + +#include +#include +#include +#include + + +// the input str should already be trim()ed + +line *new_line( char *str, char lastcmd, int linenum ) +{ + line *l = (line *)malloc( sizeof(line) ); + int colon; + int rparen, lparen; + int i; + char *contemp = NULL; // temp variable for condex string + + + colon = findchar( str, ':' ); // get the position of the colon + l->next = NULL; + l->linenum = linenum; + + // is it a blank string? + if( !strcmp(str, "") ) { + l->cmd = lastcmd; + l->args = NULL; + l->cond = NULL; + return l; + } + + if( colon == -1 ) { // if there is no colon, it's an error + err( NO_COLON, str ); + } + + + /* Notes for the 3/3/00 rewrite + * There are 3 different possiblities for what will be the first character + * in the line: + * + * 1) A letter signifing the command name (this includes 'Y' and 'N') + * 2) A colon, meaning that we should use the last command for this one, too + * 3) A left parentheses, like above, but with a conditional expression + * + */ + + if( colon != strlen(str)-1 ) { + l->args = new_string_from( str, colon+1, strlen(str)-colon+1 ); + ltrim( l->args ); + } else { + l->args = new_string( "" ); + } + + + /* + * Here, we'll handle the second case first, because it is the easiest. + * The command is the same as the last command, and everything after the + * first character constitutes the arguments. + */ + + if( str[0] == ':' ) { + l->cmd = lastcmd; + l->cond = NULL; + return l; + } + + + /* + * Now the third case. Like the second case, everything after the colon + * forms the arguments. But we have to find the right parentheses in order + * to create a conditional expression. The command is the same as the + * previous one. + */ + + if( str[0] == '(' ) { + l->cmd = lastcmd; + + rparen = findchar( str, ')' ); + if( rparen == -1 ) { + // If there is no right parentheses, we signal an error + err( NO_RPAREN, str ); + } + // otherwise, create a temporary string, and make a new condex + // contemp = new_string_from( str, 1, rparen-1 ); + contemp = new_string_from( str, 1, rparen-1 ); + l->cond = new_condex( contemp ); + free( contemp ); + + return l; + } + + + /* + * Finally, the first case. This itself has four possibilities: + * + * 1) There is no conditional expression + * 2) There is a conditional expression in parentheses + * 3) There is a 'Y' as the conditional + * 4) There is an 'N' as the conditional + */ + + l->cmd = str[0]; + // l->args = new_string_from( str, colon+1, strlen(str)-colon+1 ); + + lparen = findchar( str, '(' ); + if( (lparen == -1)|| (lparen > colon) ) { + // Now, we can see if there is a Y or N somehwere.. + for( i=1; icond = new_condex( "Y" ); + return l; + } else if( toupper(str[i]) == 'N' ) { + l->cond = new_condex( "N" ); + return l; + } + } + // If we didn't find Y or N, there is no condex, so just return + l->cond = NULL; + return l; + + } + + // Now we have a conditional expression, so create a new condex and return + rparen = findchar( str, ')' ); + if( rparen == -1 ) { + err( NO_RPAREN, str ); + } + // contemp = new_string_from( str, lparen+1, rparen-1 ); + contemp = new_string_from( str, lparen+1, rparen-2 ); + l->cond = new_condex( contemp ); + free( contemp ); + + return l; +} + +/* support binding */ +void print_line_to( line *curr, FILE *stream ) +{ + if( curr == NULL ) { + fprintf( stream, "[NULL]" ); + return; + } + fprintf( stream, "%c", curr->cmd ); + if( curr->cond != NULL ) { + if( (curr->cond->op == OP_YES) || (curr->cond->op == OP_NO) ) { + print_condex_to( curr->cond, stream ); + } else { + fprintf( stream, "(" ); + print_condex_to( curr->cond, stream ); + fprintf( stream, ")" ); + } + } + fprintf( stream, ": %s", curr->args ); +} + +char *get_line( line *curr ) +{ + char *buffer; + char *cond; + + buffer = (char *)malloc(1024); + + if( curr == NULL ) { + return "(null)"; + } + + sprintf( buffer, "%c", curr->cmd ); + if( curr->cond != NULL ) { + if( (curr->cond->op == OP_YES) || (curr->cond->op == OP_NO) ) { + sprintf( buffer, "%c", curr->cond->op ); + } else { + cond = get_condex( curr->cond ); + sprintf( buffer, "(%s)", cond ); + free( cond ); + } + } + + sprintf( buffer, ": %s", curr->args ); + + return buffer; +} + + +void print_line( line *curr ) +{ + print_line_to( curr, stdout ); +} + + +void print_line_list( line *head ) +{ + line *curr = head; + + while( curr ) { + printf( "#%d ", curr->linenum ); + print_line( curr ); + printf( "\n" ); + curr = (line *)curr->next; + } +} + + +#ifdef TEST + +int main( int argc, char *argv[] ) +{ + + FILE *f; + char buf[256]; + line *head, *curr; + int linenum = 0; + + if( argc < 2 ) { + puts( "line: Usage line filename" ); + return 0; + } + + f = fopen( argv[1], "r" ); + + head = new_line("", ' ', 0 ); + curr = head; + + do { + strset( buf, 0 ); + fgets( buf, 255, f ); + chop( buf ); + trim( buf ); +puts( buf ); + if( strcmp(buf, "") ) { + curr->next = (struct line *)new_line( buf, 'Q', ++linenum ); + curr = (line *)curr->next; + } + } while( !feof(f) ); + + + print_line_list( head ); + + return 0; +} + + +#endif diff --git a/Applications/rpilot-1.4.2/line.h b/Applications/rpilot-1.4.2/line.h new file mode 100644 index 00000000..2f16f33f --- /dev/null +++ b/Applications/rpilot-1.4.2/line.h @@ -0,0 +1,22 @@ +#ifndef _line_h_ +#define _line_h_ + +#include "condex.h" +#include "rpilot.h" +#include + +typedef struct { + char cmd; // name of the command (C,A,M, etc) + condex *cond; // Conditional expression, w/o the outer parens + char *args; // argument to the command + int linenum; // line number (from the source file) + struct line *next; // next line +} line; + +line *new_line( char *str, char lastcmd, int linenum ); +void print_line_to( line *curr, FILE *stream ); +void print_line( line *curr ); +void print_line_list( line *head ); +char *get_line( line *curr ); + +#endif diff --git a/Applications/rpilot-1.4.2/main.c b/Applications/rpilot-1.4.2/main.c new file mode 100644 index 00000000..ada96828 --- /dev/null +++ b/Applications/rpilot-1.4.2/main.c @@ -0,0 +1,107 @@ +/* + * main.c - main() function for RPilot + */ + +#include "rpilot.h" +#include "main.h" +#include +#include +#include + + + +int main( int argc, char *argv[] ) +{ + int i; + int showban = TRUE, inter = FALSE, bind = FALSE, mainfunc = FALSE, + showhelp = FALSE; + char *filename=NULL, *outfile=NULL, *dataname=NULL, *funcname=NULL; + + for( i=1; i + +int express( char *form ) +{ + int result, status; + + result = calc( form, &status ); + + if( status != 0 ) { // error + err( EXP_MATH, "" ); + } + + return result; + +} + diff --git a/Applications/rpilot-1.4.2/math.h b/Applications/rpilot-1.4.2/math.h new file mode 100644 index 00000000..adf36859 --- /dev/null +++ b/Applications/rpilot-1.4.2/math.h @@ -0,0 +1,12 @@ +/* + * math.h - header for math.c + */ + +#ifndef _math_h_ +#define _math_h_ + + +// Returns the value of a given mathematical formula +int express( char *form ); + +#endif diff --git a/Applications/rpilot-1.4.2/rpilot.c b/Applications/rpilot-1.4.2/rpilot.c new file mode 100644 index 00000000..00e63353 --- /dev/null +++ b/Applications/rpilot-1.4.2/rpilot.c @@ -0,0 +1,292 @@ +/* + * rpilot.c -- A simple PILOT interpretor in ANSI C + * Copyright 1998, 2000 Rob Linwood (rob@auntfloyd.com) + * Visit http://www.auntfloyd.com/ for more cool stuff + * + * See the file rpilot.txt for user documentation. + */ + + +#include +#include +#include +#include +#include + +#include "rpilot.h" +#include "math.h" + +rpinfo *rpi; + +int readfile( char *filename ) +{ + char inbuf[MAXLINE]; // 256-char limit on line width + line *currline; + line *templine = NULL; + label *currlbl; + label *templbl = NULL; + int linenum = 0; + char lastcmd = '!'; + FILE *f; + + + if( (f = fopen(filename, "r")) == NULL ) { + rpi = NULL; /* kludge around the error printing */ + err( ERR_FILE, filename ); + } + + rpi->filename = new_string( filename ); + + currline = (line *)rpi->linehead; + currlbl = (label *)rpi->lblhead; + do { + strset( inbuf, 0 ); + fgets( inbuf, MAXLINE-1, f ); + chop( inbuf ); + linenum++; + trim( inbuf ); + if( strcmp(inbuf, "") ) { // if the line isn't blank + +#ifdef IGNORE_HASH + if( (linenum == 1) && (inbuf[0] == '#') ) { + break; + } +#endif + + if( inbuf[0] == '*' ) { // label + currlbl->next = (struct label *)new_label( inbuf+1, NULL, linenum ); + templbl = (label *)currlbl->next; + currlbl = (label *)currlbl->next; + } else if( (toupper(inbuf[0]) != 'R') && + !((inbuf[0] == ':') && (lastcmd == 'R')) ) { + *(line **)&currline->next = new_line( inbuf, currline->cmd, linenum ); + currline = (line *)currline->next; + if( templbl != NULL ) { + templbl->stmnt = (line *)currline; + templbl = NULL; + } + lastcmd = currline->cmd; // next->cmd; + } else { + lastcmd = 'R'; + } + } + } while( !feof(f) ); +} + + + + +void handle( line *l ) +{ + + switch( toupper(l->cmd) ) { + case 'A' : cmd_accept( l->args ); + break; + case 'T' : cmd_type( l->args ); + break; + case 'J' : cmd_jump( l->args ); + break; + case 'U' : cmd_use( l->args ); + break; + case 'E' : cmd_end( l->args ); + break; + case 'M' : cmd_match( l->args ); + break; + case 'C' : cmd_compute( l->args ); + break; + case 'Y' : cmd_yes( l->args ); + break; + case 'N' : cmd_no( l->args ); + break; + case 'X' : cmd_execute( l->args ); + break; + case 'S' : cmd_shell( l->args ); + break; + case 'D' : cmd_debug( l->args ); + break; + case 'G' : cmd_generate( l->args ); + break; + } +} + + + +int test( condex *cond ) +{ + + if( (cond->op == OP_YES) && (get_numvar("#MATCHED") == TRUE) ) { + return TRUE; + } else if( (cond->op == OP_NO) && (get_numvar("#MATCHED")==FALSE) ) { + return TRUE; + } else if( cond->op == OP_EQL ) { + if( express(cond->lside) == express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } else if( cond->op == OP_LT ) { + if( express(cond->lside) < express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } else if( cond->op == OP_GT ) { + if( express(cond->lside) > express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } else if( cond->op == OP_NEQL ) { + if( express(cond->lside) != express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } else if( cond->op == OP_LE ) { + if( express(cond->lside) <= express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } else if( cond->op == OP_GE ) { + if( express(cond->lside) >= express(cond->rside) ) { + return TRUE; + } else { + return FALSE; + } + } + return FALSE; +} + + +void init() +{ + line *linehead; + label *lblhead; + strvar *svar; + numvar *nvar; + + rpi = NULL; + + linehead = new_line( "", ' ', -1 ); + lblhead = new_label( "", NULL, -1 ); + rpi = (rpinfo *)malloc( sizeof(rpinfo) ); + + rpi->linehead = (struct line *)linehead; + rpi->lblhead = (struct label *)lblhead; + rpi->numhead = (struct numvar *)new_numvar( "", -1 ); + rpi->strhead = (struct strvar *)new_strvar( "", "" ); + rpi->stk = (struct stack *)new_stack( NULL ); + rpi->status = STAT_RUN; + rpi->error = -1; + rpi->strict = TRUE; + rpi->currline = rpi->linehead; + + svar = (strvar *)rpi->strhead; + nvar = (numvar *)rpi->numhead; + nvar->next = (struct numvar *)new_numvar( "#RPILOT", RP_VERSION ); + svar->next = (struct strvar *)new_strvar( "$PROMPT", ACCEPT_STR ); + +} + +int interp() +{ + line *curr; + + while( rpi->currline != NULL ) { + curr = (line *)rpi->currline; + if( curr->cond != NULL ) { // is there a conditional expression? + if( test(curr->cond) == TRUE ) { // if so, test it + handle( curr ); + } + } else { + handle( curr ); + } + // have any other functions changed the value of rpi->currline? + if( (line *)rpi->currline == curr ) { + rpi->currline = (struct line *)curr->next; + } // Otherwise, keep the value of rpi->currline, cuz it's been modified + } +} + + +int run( char *filename ) +{ + + init(); + readfile( filename ); + interp(); +} + + +/* + * the routines below are used in both commands (cmds.c) and the debugger + * (debug.c), so are made as common procedures to both. + */ + +void set_var( char *name, char *val ) +{ + + if( name[0] == '$' ) { // string variable + set_strvar( name, val ); + } else if( name[0] == '#' ) { // numeric variable + set_numvar( name, atoi(val) ); + } else { + err( BAD_VAR, name ); + } + +} + + +int get_numval( char *str ) +{ + if( str[0] == '#' ) { + return( get_numvar(str) ); + } else { + return( atoi( str ) ); + } +} + +char *get_strval( char *str ) +{ + if( str[0] == '$' ) { + return get_strvar(str); + } else { + return str; + } +} + + +void jump( char *str ) +{ + label *l; + + l = get_label( get_strval(str) ); + + rpi->currline = (struct line *)l->stmnt; +} + + +void use( char *str ) +{ + label *l; + line *curr; + + l = get_label( trim(get_strval(str)) ); + + // push next command onto stack + curr = (line *)rpi->currline; + curr = (line *)curr->next; + stk_push( (stack *)rpi->stk, curr ); + rpi->currline = (struct line *)l->stmnt; +} + + +void execute( char *str ) +{ + line *lne = new_line( trim(get_strval(str)), ' ', -1 ); + + lne->cmd = toupper( lne->cmd ); + handle( lne ); +} + diff --git a/Applications/rpilot-1.4.2/rpilot.h b/Applications/rpilot-1.4.2/rpilot.h new file mode 100644 index 00000000..a06ecf3e --- /dev/null +++ b/Applications/rpilot-1.4.2/rpilot.h @@ -0,0 +1,64 @@ +/* + rpilot.h - universal macros and the like. +*/ + +#ifndef _rpilot_h_ +#define _rpilot_h_ + +#include "line.h" +#include "stack.h" +#include "label.h" +#include "var.h" +#include "cmds.h" +#include "condex.h" +#include "debug.h" +#include "err.h" +#include "rstring.h" +#include "rpinfo.h" +#include "bind.h" +#include "interact.h" + +#include +#include + +#define MAXLINE 256 // Max length of a source line + +// Status indicators +#define STAT_RUN 1 +#define STAT_HALT 2 +#define STAT_END 3 + + +// Used to check conditional values +#define FALSE 0 +#define TRUE 1 + +// What string is displayed for an accept command? +#define ACCEPT_STR ">" + + +// Remove a terminating newline +#define chop( str ) if(str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0' + +// Initialize randon number based on time +//#define srandom() srand( (unsigned)time(NULL) ); + + +// The version number, of course +#define VERSION "1.4.2" +// The version number which can be gotten with the #RPILOT variable +#define RP_VERSION 14 + +// exported functions +int get_numval( char *str ); +void set_var( char *name, char *val ); +int run( char *filename ); +void jump( char *str ); +void use( char *str ); +void execute( char *str ); +char *get_strval( char *str ); +void init(); +int readfile( char *filename ); +extern rpinfo *rpi; + +#endif diff --git a/Applications/rpilot-1.4.2/rpinfo.c b/Applications/rpilot-1.4.2/rpinfo.c new file mode 100644 index 00000000..c934fb9f --- /dev/null +++ b/Applications/rpilot-1.4.2/rpinfo.c @@ -0,0 +1,25 @@ +#include "rpinfo.h" +#include +#include "err.h" +#include "rpilot.h" + +rpinfo *new_rpinfo() +{ + rpinfo *r; + + r = (rpinfo *)malloc( sizeof(rpinfo) ); + + r->currline = NULL; + r->linehead = NULL; + r->lblhead = NULL; + r->numhead = NULL; + r->strhead = NULL; + r->stk = NULL; + r->error = ERR_NONE; + r->status = 0; + r->lastacc = NULL; + r->strict = TRUE; + r->filename = NULL; + + return r; +} diff --git a/Applications/rpilot-1.4.2/rpinfo.h b/Applications/rpilot-1.4.2/rpinfo.h new file mode 100644 index 00000000..d8989045 --- /dev/null +++ b/Applications/rpilot-1.4.2/rpinfo.h @@ -0,0 +1,26 @@ +#ifndef _rpinfo_h_ +#define _rpinfo_h_ + +//#include "line.h" +//#include "label.h" +//#include "var.h" +//#include "stack.h" + +// contains info about the currently running interpreter +typedef struct { + struct line *currline; // the line of code that is currently being executed + struct line *linehead; // the head of the line list + struct label *lblhead; // head of the label list + struct numvar *numhead; + struct strvar *strhead; + struct stack *stk; + int error; // the last error that occured + int status; // the status of the program (one of the STAT_ values) + char *lastacc; // the name of the last variable to be accepted + int strict; // should we be strict about undeclared variables? + char *filename; // name of file being run +} rpinfo; + +//rpinfo *new_rpinfo(); + +#endif diff --git a/Applications/rpilot-1.4.2/rstring.c b/Applications/rpilot-1.4.2/rstring.c new file mode 100644 index 00000000..f6f680d3 --- /dev/null +++ b/Applications/rpilot-1.4.2/rstring.c @@ -0,0 +1,439 @@ +/* + * rstring.c - generic string-handling functions + * as of version 1.49, this contains the contents of the `parse' library + */ + +#include +#include +#include +#include +#include "rstring.h" + +/* + * Name : strupr + * Descrip : Changes s to all uppercase + * Input : s = pointer to a string to uppercase + * Output : returns a pointer to s + * Notes : none + * Example : strupr( "proper-noun" ) - returns "PROPER-NOUN" + */ + +char *strupr( char *s ) +{ + int i; + + for(i=0; i strlen(src) ) { + str[strlen(src)] = 0; + } + + return str; +} + +// make a new string from src, starting at char index and going for count chars +char *new_string_from( char *src, int index, int count ) +{ + char *str; + + str = (char *)malloc( count + 1 ); + memset( str, 0, count+1 ); + strncpy( str, src+index, count ); + + // str[strlen(str)+1] = 0; + // str[count+1] = 0; + + return str; +} + +/* + * Name: firstnot - Finds first instance of a character which is not the + * one specified + * Input: d - Pointer to string to search through + * e - Char to search against + * first - Position in d to start the search at + * Output: Returns the position of the first character which is not e. + * Returns -1 if there was an error + * Example: firstnot( "ggggXgggX", "g", 0 ) returns 4 + */ + +int firstnot( const char *d, const char e, int first ) +{ + char k; + + for(k=first; k=0) ) + str[i--] = '\0'; + + return str; +} + +/* + * Name : ltrim + * Descrip : Removes all leading whitespace from a string + * Input : str = pointer to a string to strip + * Output : Retruns a pointer to str + * Notes : None + * Example : ltrim( " Woof! " ) - returns "Woof! " + */ + +char *ltrim( char *str ) +{ + int i; + int spc = ws( str ); + + if( spc == -1 ) { // blank line + return ""; + } + + for( i=0; i-1;k--) { + if( (str[k] != ' ') && (str[k] != '\t') ) + return k; + } + return -1; +} + + +/* + * Name : ws + * Descrip : WhiteSpace: finds the first character which isn't a tab or space + * Input : str = pointer to string to use as input + * Output : Returns position of fitsrt non-whitespace character + * Notes : none + * Example : ws( " Howdy, world!" ) - returns 3 + */ + +int ws( const char *str) +{ + int k; + + for(k=0;k + +stkitem *new_stkitem( line *lne ) +{ + stkitem *si; + + si = (stkitem *)malloc( sizeof(stkitem) ); + si->item = lne; + si->prev = NULL; + +} + + +stack *new_stack( line *lne ) +{ + stack *s; + stkitem *si; + + s = (stack *)malloc( sizeof(stack) ); + si = new_stkitem( lne ); + + s->head = si; + s->tail = si; + + return s; +} + + +// returns the new tail of the list +stack *stk_push( stack *stk, line *lne ) +{ + stkitem *si; + + si = new_stkitem( lne ); + *(stkitem **)&si->prev = stk->tail; // worthless cast + stk->tail = si; + + return stk; +} + + +line *stk_pop( stack *stk ) +{ + stkitem *si; + line *lne; + + si = stk->tail; + + stk->tail = (stkitem *)stk->tail->prev; // worthless cast + lne = si->item; + free( si ); + + return lne; +} diff --git a/Applications/rpilot-1.4.2/stack.h b/Applications/rpilot-1.4.2/stack.h new file mode 100644 index 00000000..aada045f --- /dev/null +++ b/Applications/rpilot-1.4.2/stack.h @@ -0,0 +1,24 @@ +#ifndef _stack_h_ +#define _stack_h_ + +/* #include "line.h" */ +#include "rpilot.h" + + +typedef struct { + line *item; + struct stkitem *prev; +} stkitem; + +typedef struct { + stkitem *head, *tail; +} stack; + +stkitem *new_stkitem( line *lne ); +stack *new_stack( line *lne ); +stack *stk_push( stack *stk, line *lne ); +line *stk_pop( stack *stk ); + + + +#endif diff --git a/Applications/rpilot-1.4.2/var.c b/Applications/rpilot-1.4.2/var.c new file mode 100644 index 00000000..4a7e21e4 --- /dev/null +++ b/Applications/rpilot-1.4.2/var.c @@ -0,0 +1,144 @@ +/* + var.c - RPilot variable support +*/ + +#include +#include "rpilot.h" + +strvar *new_strvar( char *name, char *val ) +{ + strvar *ret; + + if( (ret = (strvar *)malloc(sizeof(strvar))) == NULL ) { + err( NO_MEM, "" ); + } + + ret->name = new_string( name ); + ret->val = new_string( val ); + ret->next = NULL; + + return ret; +} + +numvar *new_numvar( char *name, int val ) +{ + numvar *ret; + + if( (ret = (numvar *)malloc(sizeof(numvar))) == NULL ) { + err( NO_MEM, "" ); + } + + ret->name = new_string_from( name, 0, strlen(name) ); + ret->val = val; + ret->next = NULL; + return ret; +} + +void set_strvar( char *name, char *val ) +{ + strvar *s = (strvar *)rpi->strhead; + strvar *prev; + + while( s != NULL ) { + if( !strcasecmp(s->name, name) ) { + free( s->val ); + s->val = new_string( val ); + return; + } + prev = s; + s = (strvar *)s->next; + } + + // if we can't find the variable, make a new one + *(strvar **)&prev->next = new_strvar( name, val ); +} + +void set_numvar( char *name, int val ) +{ + numvar *n = (numvar *)rpi->numhead; + numvar *prev; + + while( n != NULL ) { + if( !strcasecmp(n->name, name) ) { + n->val = val; + return; + } + prev = n; + n = (numvar *)n->next; + } + + *(numvar **)&prev->next = new_numvar( name, val ); +} + +char *get_strvar( char *name ) +{ + strvar *s = (strvar *)rpi->strhead; + + while( s != NULL ) { + if( !strcasecmp(s->name, name) ) { + return s->val; + } else { + s = (strvar *)s->next; + } + } + + if( rpi->strict == TRUE ) { + err( BAD_VAR, name ); + } else { + set_strvar( name, "" ); + return ""; + } + + return NULL; +} + +int get_numvar( char *name ) +{ + numvar *n = (numvar *)rpi->numhead; + + while( n != NULL ) { + if( !strcasecmp(n->name, name) ) { + return n->val; + } else { + n = (numvar *)n->next; + } + } + + if( rpi->strict == TRUE ) { + err( BAD_VAR, name ); + } else { + set_numvar( name, 0 ); + return 0; + } + +} + +void print_strvar( strvar *var ) +{ + printf( "%s = \"%s\"\n", var->name, var->val ); +} + +void print_numvar( numvar *var ) +{ + printf( "%s = %d\n", var->name, var->val ); +} + +void print_strvar_list( void ) +{ + strvar *var = (strvar *)rpi->strhead; + + while( var != NULL ) { + print_strvar( var ); + var = (strvar *)var->next; + } +} + +void print_numvar_list( void ) +{ + numvar *var = (numvar *)rpi->numhead; + + while( var != NULL ) { + print_numvar( var ); + var = (numvar *)var->next; + } +} diff --git a/Applications/rpilot-1.4.2/var.h b/Applications/rpilot-1.4.2/var.h new file mode 100644 index 00000000..fa5305b8 --- /dev/null +++ b/Applications/rpilot-1.4.2/var.h @@ -0,0 +1,42 @@ +/* + var.h - variable datatypes and prototypes for var.c +*/ + +#ifndef _var_h_ +#define _var_h_ + +#include "rpilot.h" + +// string variables +typedef struct { + char *name; + char *val; + struct strvar *next; +} strvar; + +// numeric variables +typedef struct { + char *name; + int val; + struct numvar *next; +} numvar; + + +// make new variables +strvar *new_strvar( char *name, char *val ); +numvar *new_numvar( char *name, int val ); + +// Sets the value of a given variable +void set_strvar( char *name, char *val ); +void set_numvar( char *name, int val ); + +// Returns the value of a given variable +int get_numvar( char *name ); +char *get_strvar( char *name ); + +void print_strvar( strvar *var ); +void print_numvar( numvar *var ); +void print_strvar_list( void ); +void print_numvar_list( void ); + +#endif