pilot: Add rpilot, an implementation of the pilot programming language
authorAlan Cox <alan@linux.intel.com>
Thu, 2 Jun 2016 22:56:23 +0000 (23:56 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 2 Jun 2016 22:56:23 +0000 (23:56 +0100)
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.

54 files changed:
Applications/rpilot-1.4.2/INSTALL [new file with mode: 0644]
Applications/rpilot-1.4.2/Makefile [new file with mode: 0644]
Applications/rpilot-1.4.2/Makefile.gcc [new file with mode: 0644]
Applications/rpilot-1.4.2/bind.c [new file with mode: 0644]
Applications/rpilot-1.4.2/bind.h [new file with mode: 0644]
Applications/rpilot-1.4.2/calc.c [new file with mode: 0644]
Applications/rpilot-1.4.2/calc.h [new file with mode: 0644]
Applications/rpilot-1.4.2/cmds.c [new file with mode: 0644]
Applications/rpilot-1.4.2/cmds.h [new file with mode: 0644]
Applications/rpilot-1.4.2/condex.c [new file with mode: 0644]
Applications/rpilot-1.4.2/condex.h [new file with mode: 0644]
Applications/rpilot-1.4.2/debug.c [new file with mode: 0644]
Applications/rpilot-1.4.2/debug.h [new file with mode: 0644]
Applications/rpilot-1.4.2/doc/CHANGELOG [new file with mode: 0644]
Applications/rpilot-1.4.2/doc/COPYING [new file with mode: 0644]
Applications/rpilot-1.4.2/doc/examples.txt [new file with mode: 0644]
Applications/rpilot-1.4.2/doc/rpilot.1 [new file with mode: 0644]
Applications/rpilot-1.4.2/doc/rpilot.txt [new file with mode: 0644]
Applications/rpilot-1.4.2/err.c [new file with mode: 0644]
Applications/rpilot-1.4.2/err.h [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/crazy.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/dosmenu.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/fact.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/french.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/guess.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/hello.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/inter.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/jump-use.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/math.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/name.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/recurse.p [new file with mode: 0644]
Applications/rpilot-1.4.2/examples/unixmenu.p [new file with mode: 0644]
Applications/rpilot-1.4.2/foo.c [new file with mode: 0644]
Applications/rpilot-1.4.2/foo.h [new file with mode: 0644]
Applications/rpilot-1.4.2/interact.c [new file with mode: 0644]
Applications/rpilot-1.4.2/interact.h [new file with mode: 0644]
Applications/rpilot-1.4.2/label.c [new file with mode: 0644]
Applications/rpilot-1.4.2/label.h [new file with mode: 0644]
Applications/rpilot-1.4.2/line.c [new file with mode: 0644]
Applications/rpilot-1.4.2/line.h [new file with mode: 0644]
Applications/rpilot-1.4.2/main.c [new file with mode: 0644]
Applications/rpilot-1.4.2/main.h [new file with mode: 0644]
Applications/rpilot-1.4.2/math.c [new file with mode: 0644]
Applications/rpilot-1.4.2/math.h [new file with mode: 0644]
Applications/rpilot-1.4.2/rpilot.c [new file with mode: 0644]
Applications/rpilot-1.4.2/rpilot.h [new file with mode: 0644]
Applications/rpilot-1.4.2/rpinfo.c [new file with mode: 0644]
Applications/rpilot-1.4.2/rpinfo.h [new file with mode: 0644]
Applications/rpilot-1.4.2/rstring.c [new file with mode: 0644]
Applications/rpilot-1.4.2/rstring.h [new file with mode: 0644]
Applications/rpilot-1.4.2/stack.c [new file with mode: 0644]
Applications/rpilot-1.4.2/stack.h [new file with mode: 0644]
Applications/rpilot-1.4.2/var.c [new file with mode: 0644]
Applications/rpilot-1.4.2/var.h [new file with mode: 0644]

diff --git a/Applications/rpilot-1.4.2/INSTALL b/Applications/rpilot-1.4.2/INSTALL
new file mode 100644 (file)
index 0000000..115f6cf
--- /dev/null
@@ -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 (file)
index 0000000..255e8f5
--- /dev/null
@@ -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 (file)
index 0000000..5c28c55
--- /dev/null
@@ -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 (file)
index 0000000..061ee7e
--- /dev/null
@@ -0,0 +1,157 @@
+#include "rpilot.h"
+#include "bind.h"
+#include <string.h>
+
+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 <stdio.h>\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; i<strlen(buffer); i++ ) {
+      switch( buffer[i] ) {
+      case '\"' : 
+       fprintf( source, "\\\"" );
+       break;
+      case '\'' :
+       fprintf( source, "\\\'" );
+       break;
+      case '\\' : 
+       fprintf( source, "\\\\" );
+       break;
+      default:
+       fprintf( source, "%c",  buffer[i] );
+       break;
+      }
+    }
+    fprintf( source, "\",\n" );
+    free( buffer );
+    //    fprintf( source, "  \"" );
+    //    print_line_to( curr, source );
+    //    fprintf( source, "\",\n" );
+    curr = (line *)curr->next;
+  }
+    
+  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( "<<Bound Code>>" );
+
+  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 (file)
index 0000000..633a19b
--- /dev/null
@@ -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 (file)
index 0000000..5d6970c
--- /dev/null
@@ -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 <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+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 (file)
index 0000000..1518d9f
--- /dev/null
@@ -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 (file)
index 0000000..0de3814
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+  cmds.c - RPilot commands functions
+*/
+
+
+#include "rpilot.h"
+#include "math.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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; i<strlen(str); i++ ) {
+    if( (str[i] == '$') && (!isblank(str[i+1])) ) {
+      if( str[i+1] == '$' ) {
+       i+=2;
+      } else {
+       nextsp = find( str, " \t", i );  // find next space
+       if( nextsp == -1 ) {  // no more spaces, use the rest of the line
+         varname = new_string_from( str, i, strlen(str)-i );
+       } else {
+         varname = new_string_from( str, i, nextsp-i );
+       }
+       sprintf( output, "%s%s ", output, get_strvar( varname) );
+       i+=strlen( varname );
+       free( varname );
+      }
+    } else if( (str[i] == '#') && (!isblank(str[i+1])) ) {
+      if( str[i+1] == '#' ) {
+       i+=2;
+      } else {
+       nextsp = find( str, " \t", i );  // find next space;
+       if( nextsp == -1 ) {  // no more spaces, use the rest of the line
+         varname = new_string_from( str, i, strlen(str)-i );
+       } else {
+         varname = new_string_from( str, i, nextsp-i );
+       }
+       sprintf( output, "%s%d ", output, get_numvar( varname) );
+       i+=strlen( varname );
+       free( varname );
+      }
+    } else {
+      sprintf( output, "%s%c", output, str[i] );
+    }
+    //    printf( "output=\"%s\"\n", output );
+
+  }
+
+  ret = new_string( output );
+  //  free( output );
+  //  printf("!!output=\"%s\", len=%d\n", output, strlen(output) );
+  //  printf("!!ret=\"%s\", len=%d\n", ret, strlen(ret) );
+  
+  return ret;
+}
+
+
+/*
+ * the cmd_ functions implement the PILOT statements that they're named after
+ */
+
+void cmd_use( char *str )
+{
+  use( str );  
+}
+
+void cmd_compute( char *str )
+{
+  char *lside, *rside;
+  int eqlpos;
+  int i;
+
+  if( str == NULL ) {
+    return;
+  }
+
+  trim( str );
+
+  for( eqlpos=0; eqlpos<strlen(str); eqlpos++ ) {
+    if( str[eqlpos] == '=' ) {
+      break;
+    }
+  }
+
+  if( eqlpos == strlen(str) ) {
+    err( NO_EQL, str );
+  }
+
+  lside = new_string_from( str, 0, eqlpos );
+  rside = new_string_from( str, eqlpos+1, strlen(str)-eqlpos-1 );
+  trim( lside );
+  trim( rside );
+  
+  if( lside[0] == '#' ) { // numeric variable, so a simple assignment
+    set_numvar( lside, express(rside) );
+  } else if( lside[0] == '$' ) { // string var, copy all strings on the right
+    set_strvar( lside, internal_type(rside) );
+  } else {
+    err( CONS_ASGN, lside );
+  }
+      
+
+  free( lside );
+  free( rside );
+}
+
+
+
+void cmd_accept( char *str )
+{
+  char inbuf[MAXLINE];
+  int i;
+
+  fflush( stdin );
+  printf( "%s ", get_strvar("$PROMPT") );  // print the prompt
+
+  trim( str );
+
+  if( !strcmp(str, "") ) { // blank args, so we put it in $accept
+    fgets( inbuf, MAXLINE-1, stdin );
+    chop( inbuf );  // remove trailing LF
+    set_strvar( "$ACCEPT", inbuf );
+    free( rpi->lastacc );
+    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; i<strlen(str); i++ ) { */
+/*     if( (str[i] == '$') && (!isblank(str[i+1])) ) { */
+/*       if( str[i+1] == '$' ) { */
+/*     i+=2; */
+/*       } else { */
+/*     nextsp = find( str, " \t", i );  // find next space */
+/*     if( nextsp == -1 ) {  // no more spaces, use the rest of the line */
+/*       varname = new_string_from( str, i, strlen(str)-i ); */
+/*     } else { */
+/*       varname = new_string_from( str, i, nextsp-i ); */
+/*     } */
+/*     printf( "%s ", get_strvar( varname) ); */
+/*     i+=strlen( varname ); */
+/*     free( varname ); */
+/*       } */
+/*     } else if( (str[i] == '#') && (!isblank(str[i+1])) ) { */
+/*       if( str[i+1] == '#' ) { */
+/*     i+=2; */
+/*       } else { */
+/*     nextsp = find( str, " \t", i );  // find next space; */
+/*     if( nextsp == -1 ) {  // no more spaces, use the rest of the line */
+/*       varname = new_string_from( str, i, strlen(str)-i ); */
+/*     } else { */
+/*       varname = new_string_from( str, i, nextsp-i ); */
+/*     } */
+/*     printf( "%d ", get_numvar( varname) ); */
+/*     i+=strlen( varname ); */
+/*     free( varname ); */
+/*       } */
+/*     } else { */
+/*       putchar( str[i] ); */
+/*     } */
+/*   } */
+  
+  char *output;
+
+  output = internal_type( str );
+  printf( "%s\n", output );
+  free( output );
+  
+}
+
+
+void cmd_end( char *str )
+{
+  
+  rpi->currline = (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; i<count+1; i++ ) { // count;
+    //    strset( temp, 0 );
+    temp = parse( str, i );
+    if( !strcmp(strupr(get_strvar(rpi->lastacc)), 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 (file)
index 0000000..46ea2f0
--- /dev/null
@@ -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 (file)
index 0000000..71b8e25
--- /dev/null
@@ -0,0 +1,182 @@
+// condex.c - conditional expression handling
+
+#include "rpilot.h"
+#include <string.h>
+#include <stdio.h>
+
+
+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<strlen(str); i++) {
+    if( (str[i]=='=') || (str[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 (file)
index 0000000..abe8d31
--- /dev/null
@@ -0,0 +1,33 @@
+// condex.h - condex type and functions
+
+#ifndef _condex_h_
+#define _condex_h_
+
+#include "rpilot.h"
+#include <stdio.h>
+
+#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 (file)
index 0000000..b4b2f1b
--- /dev/null
@@ -0,0 +1,73 @@
+// debug.c - RPilot's interactive debugger
+
+#include <string.h>
+
+#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 (file)
index 0000000..a006ee4
--- /dev/null
@@ -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 (file)
index 0000000..f4776e7
--- /dev/null
@@ -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 (file)
index 0000000..3358a7b
--- /dev/null
@@ -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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+       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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
index 0000000..530847e
--- /dev/null
@@ -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 (file)
index 0000000..04f68b9
--- /dev/null
@@ -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 <rcl211@nyu.edu>
+.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 (file)
index 0000000..5fa542b
--- /dev/null
@@ -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:
+
+    <command>[conditional] : [arguments]
+
+    <command> 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 (file)
index 0000000..7380246
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+  err.c - Error handling code for RPilot
+*/
+
+#include "rpilot.h"
+#include <string.h>
+
+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 (file)
index 0000000..f9053e6
--- /dev/null
@@ -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 (file)
index 0000000..41a4b48
--- /dev/null
@@ -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 (file)
index 0000000..6fa8dc6
--- /dev/null
@@ -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 (file)
index 0000000..3fa50f5
--- /dev/null
@@ -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 (file)
index 0000000..b72c799
--- /dev/null
@@ -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 (file)
index 0000000..c7566f3
--- /dev/null
@@ -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 (file)
index 0000000..56dba99
--- /dev/null
@@ -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 (file)
index 0000000..6ad4a20
--- /dev/null
@@ -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 (file)
index 0000000..46160ae
--- /dev/null
@@ -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 (file)
index 0000000..cc41ab3
--- /dev/null
@@ -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 (file)
index 0000000..0caac64
--- /dev/null
@@ -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 (file)
index 0000000..3d4ffc2
--- /dev/null
@@ -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 (file)
index 0000000..3009387
--- /dev/null
@@ -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 (file)
index 0000000..84a5366
--- /dev/null
@@ -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 (file)
index 0000000..e1cc8bb
--- /dev/null
@@ -0,0 +1,11 @@
+/* PILOT code datafile - generated by RPilot 1.4 */
+
+#ifndef _foo_h_
+#define _foo_h_
+
+#include <stdio.h>
+
+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 (file)
index 0000000..12b093c
--- /dev/null
@@ -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 (file)
index 0000000..9508888
--- /dev/null
@@ -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 (file)
index 0000000..aae1d1c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * label.c - label handling code
+ */
+
+#include "rpilot.h"
+
+#include <string.h>
+
+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 (file)
index 0000000..3c6db59
--- /dev/null
@@ -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 (file)
index 0000000..256022e
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * line.c - RPilot syntax handling routines
+ */
+
+#include "rpilot.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+
+// 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; i<colon; i++ ) {
+      if( toupper(str[i]) == 'Y' ) {
+       l->cond = 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 (file)
index 0000000..2f16f33
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _line_h_
+#define _line_h_
+
+#include "condex.h"
+#include "rpilot.h"
+#include <stdio.h>
+
+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 (file)
index 0000000..ada9682
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * main.c - main() function for RPilot
+ */
+
+#include "rpilot.h"
+#include "main.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+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<argc; i++ ) {
+
+    /*    printf("argv[%d] = %s\n", i, argv[i] ); */
+
+    if( !strcasecmp(argv[i], "-b") ) {
+      showban = FALSE;
+    } else if( !strcasecmp(argv[i], "-i") ) {
+      inter = TRUE;
+    } else if( !strcasecmp(argv[i], "-?") ) {
+      showhelp = TRUE;
+    } else if( !strcasecmp(argv[i], "-c") ) {
+      bind = TRUE;
+    } else if( !strcasecmp(argv[i], "-o") ) {
+
+      if( argc == i+1 ) {
+       err( NO_CLARGS, "-o" );
+      } else {
+       outfile = new_string( argv[i+1] );
+       i++;
+      }
+    } else if( !strcasecmp(argv[i], "-d") ) {
+      if( argc == i+1 ) {
+       err( NO_CLARGS, "-d" );
+      } else {
+       dataname = new_string( argv[i+1] );
+       i++;
+      }
+    } else if( !strcasecmp(argv[i], "-f") ) {
+      if( argc == i+1 ) {
+       err( NO_CLARGS, "-f" );
+      } else {
+       funcname = new_string( argv[i+1] );
+       i++;
+      }
+    } else if( !strcasecmp(argv[i], "-m") ) {
+      mainfunc = TRUE;
+    } else {
+      filename = new_string( argv[i] );
+    }
+  }
+
+/*    printf("filename=\"%s\", outfile=\"%s\", dataname=\"%s\", funcname=\"%s\"\n", */
+/*      filename, outfile, dataname, funcname ); */
+/*    printf("showban=%d, inter=%d, mainfunc=%d\n", showban, inter, mainfunc ); */
+
+
+  if( argc == 1 ) {  // no arguments
+    banner();
+  } else {  // there were arguments
+    if( showhelp == TRUE ) {
+      if( showban == TRUE ) { banner(); }
+      help(); 
+    } else if( inter == TRUE ) {
+      if( showban == TRUE ) { banner(); }
+      interact();
+    } else if( filename == NULL ) {
+      if( showban == TRUE ) { banner(); }
+      err( NO_FILE, "" );
+    } else if( bind == TRUE ) {
+      bindfile( filename, outfile, dataname, funcname, mainfunc );
+    } else {
+      run( filename );
+    }
+  }
+
+  return 0;
+}
+
+
+void help() 
+{
+  printf( "Usage: rpilot [switch] filename\n" );
+  printf( "Switch \t Action\n" );
+  printf( "-b \t Suppress banner printing on startup\n" );
+  printf( "-i \t Enter interactive mode when no file names are given\n");
+  //  printf( "-c \t Bind a file as a C program\n" );
+  printf( "-? \t Print this help message, then exit\n\n" );
+
+}
+
+void banner()
+{
+  printf( "RPilot: Rob's PILOT Interpreter, version %s\n", VERSION );
+  printf( "Copyright 1998,2002 Rob Linwood (rcl211@nyu.edu)\n" );
+  printf( "RPilot is Free Software. Please see http://rpilot.sf.net/\n" );
+  printf( "For help, try `rpilot -?'\n\n" );
+}
+  
diff --git a/Applications/rpilot-1.4.2/main.h b/Applications/rpilot-1.4.2/main.h
new file mode 100644 (file)
index 0000000..0efe59a
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * main.h - prototypes for main.c
+ */
+
+#ifndef _main_h_
+#define _main_h_
+
+void help();
+void banner();
+
+#endif
diff --git a/Applications/rpilot-1.4.2/math.c b/Applications/rpilot-1.4.2/math.c
new file mode 100644 (file)
index 0000000..3d807e0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * math.c - mathematical functions for RPilot
+ * 
+ * major update - aug.11.2000
+ *  - remove all garbage, express() remains only as a wrapper to calc()
+ */
+
+#include "rpilot.h"
+#include "calc.h"
+
+#include <string.h>
+
+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 (file)
index 0000000..adf3685
--- /dev/null
@@ -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 (file)
index 0000000..00e6335
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+
+#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 (file)
index 0000000..a06ecf3
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+
+#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 (file)
index 0000000..c934fb9
--- /dev/null
@@ -0,0 +1,25 @@
+#include "rpinfo.h"
+#include <stdio.h>
+#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 (file)
index 0000000..d898904
--- /dev/null
@@ -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 (file)
index 0000000..f6f680d
--- /dev/null
@@ -0,0 +1,439 @@
+/*
+ * rstring.c - generic string-handling functions
+ * as of version 1.49, this contains the contents of the `parse' library
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#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(s); i++ ) {
+    s[i] = toupper(s[i]);
+  }
+  
+  return s;
+}
+
+/*
+ * Name    : strset
+ * Descrip : Sets all characters in s to ch
+ * Input   : s = pointer to a string to set
+ *           ch = character to set all positions in s to 
+ * Output  : returns a pointer to s
+ * Notes   : None
+ * Example : char cstring[10];
+             strset( cstring, 'C' ) - returns "CCCCCCCCC"
+ */
+
+char *strset( char *s, int ch )
+{
+  unsigned char c;
+  
+  for(c=0; s[c] != 0; c++)
+    s[c] = ch;
+  
+  return s;
+}
+
+// make a copy of a string
+char *new_string( char *src ) 
+{
+  char *str;
+
+  str = (char *)malloc( strlen(src)+1 );
+  strncpy( str, src, strlen(src) );
+
+  // prevent junk from being tacked on the end
+  if( strlen(str) > 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<strlen(d); k++) {
+    if( d[k] != e )
+      return k;
+  }
+  return -1;
+}
+
+/*
+ * Name: neither -  Finds the first character after the two specified
+ * Input: d - Pointer to the string to search through
+ *        e - The first char to search against
+ *        f - The second char to search against
+ *        first - The location in d to start searching at
+ * Output: Returns the location of the first char which is not e or f.
+ *         Returns -1 on errors
+ * Notes: This is just like firstnot() except it takes to chars as args.
+ * Example: neither( "ggggXgggXzgg", 'g', 'X', 0 ) returns 9.
+ */
+
+int neither( const char *d, const char e, const char f, char first )
+{
+  char k;
+  
+  for(k=first; k<strlen(d); k++) {
+    if( (d[k] != e) && (d[k] != f) )
+      return k;
+  }
+  return -1;
+}
+
+/*
+ * Name: find - Search for any chars in the string e in string d
+ * Input: d - pointer to a string to search through
+ *        e - pointer to a list of chars to search for
+ *        first - location in d to start search at
+ * Output: Returns the location of the first occurence of a char in e in d.
+ *         Returns -1 on errors
+ * Example: find( "xrcedfg", "dg", 0 ) returns 4.
+ */
+
+int find( const char *d, const char *e, int first )
+{
+  int k, k2;
+  
+  for(k=first; k<strlen(d); k++) {
+    for(k2=0; k2<strlen(e); k2++) {
+      if( d[k] == e[k2] )
+       return k;
+    }
+  }
+  return -1;
+}
+
+/*
+ * Name    : scopy
+ * Descrip : Like the Pascal Copy function, scopy copies a portion of a
+ *           string from src to dest, starting at index, and going for
+ *           count characters.
+ * Input   : dest - pointer to a string to recieve the copied portion
+ *           src - pointer to a string to use as input
+ *           index - character to start copying at
+ *           count - number of characters to copy
+ * Output  : dest contains the slice of src[index..index+count]
+ * Notes   : None
+ * Example : scopy( last, "Charlie Brown", 8, 5 ) - puts "Brown" in last.
+ * History : the parse() function was originally coded in Pascal. To support
+ *           the translation, this function was implemented, but now its proved
+ *           useful on its own.
+ */
+
+char *scopy( char *dest, char *src, int index, int count )
+{
+  int k;
+  
+  for(k=0;k<=count;k++) {
+    dest[k] = src[k+index];
+  }
+  dest[k] = '\0';
+  return dest;
+}
+
+/*
+ * Name: numstr - Returns number of substrings in a string
+ * Input : d - a pointer to the string to search through
+ * Output: returns number of substrings in string d
+ * Example: numstr( "bob and    Figment  are THE  Bombz  " ) returns 6
+ */
+int numstr( const char *d )
+{
+
+  int k2, k3;
+  int cnt = 0;
+
+  k3 = -1;
+
+  /* new version */  
+  do {
+    k2 = wspace( d, k3+1 ); /* find start of substring */
+    if( k2 == -1 ) /* if there is no start, we return */
+      return cnt;
+    k3 = find( d, " \t", k2 ); /* find end of substring */
+    if( k3 == -1 )
+      return ++cnt;
+    ++cnt;   /* increase counter if there is a start & a finish */
+  } while( k3 != -1 );
+  return -1;
+}
+
+/*
+ * Name: parse - Returns specified substrings seperated by whitespace
+ * Input: d - a pointer to the string to parse
+ *               i - the number of the substring you want
+ *               c - a pointer to the string where we place the substring
+ * Output: Returns nonzero on errors and zero when there are no errors
+ * Example: parse( " bob ate  cheese", 3, buffer ) places "cheese" in buffer
+ */
+
+char *parse( const char *src, int num )
+{
+  char *srccopy;
+  char *ret = NULL;
+  int currws, nextws;
+  int i;
+  
+  srccopy = (char *)malloc(strlen(src)+1);
+  strcpy( srccopy, src );
+  
+  total_trim( srccopy );
+  
+  if( !strcmp(srccopy, "") ) {
+    return NULL;
+  }
+  
+  currws = find( srccopy, " \t", 1 );
+
+  if( currws == -1 ) { // no spaces found, so only one string available
+    return srccopy;
+  } 
+
+  if( num == 1 ) {
+    ret = new_string_from( srccopy, 0, currws );
+    free( srccopy );
+    return ret;
+  }
+  
+  /*
+    01234567890123456789
+    "hello said the fig"
+  */          
+  
+  for( i=1; i<num; i++ ) {
+    nextws = find( srccopy, " \t", currws+1 );
+    if( i+1 != num ) {
+      currws = nextws;
+    }
+  }
+
+  if( nextws == -1 ) {  // last bit in src, no whitespace after
+    ret = new_string_from( srccopy, currws+1, strlen(srccopy)-currws-1 );
+  } else {
+    ret = new_string_from( srccopy, currws+1, nextws-currws-1 );
+  }
+
+  free( srccopy );
+  return ret;
+}
+
+/*
+ * Name    : rtrim
+ * Descrip : Removes all trailing whitespace from a string
+ * Input   : str = pointer to a string to strip
+ * Output  : Returns a pointer to str
+ * Notes   : None.
+ * Example : rtrim( "Bob was busy   " ) - returns "Bob was busy"
+ */
+
+char *rtrim( char *str )
+{
+
+  int i = strlen( str ) - 1;
+  
+  while( (isspace(str[i])) && (i>=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<strlen(str); i++ ) {
+    str[i] = str[i+spc];
+  }
+  str[i] = 0;
+  
+  return str;
+}
+
+/*
+ * Name    : rws
+ * Descrip : Reverse WhiteSpace: Finds the last charater in a string which
+ *           is not a space or a tab
+ * Input   : str = pointer to a string to search through
+ * Output  : Returns the position of the last non-whitespace character
+ * Notes   : Just like, ws(), but backwards
+ * Example : rws( "Hey, you!  " ) - returns 8
+ */
+
+int rws( const char *str)
+{
+  int k;
+  
+  for(k=strlen(str);k>-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<strlen(str);k++) {
+    if( (str[k] != ' ') && (str[k] != '\t') )
+      return k;
+  }
+  return -1;
+}
+
+
+int wspace( const char *str, int first )
+{
+  return neither( str, ' ', '\t', first );
+}
+
+
+char *trim( char *str ) 
+{
+  if( !strcmp(str, "") ) {
+    return "";
+  }
+
+  ltrim( str );
+  rtrim( str );
+  
+  return str;
+}
+
+
+
+int findchar( const char *str, char c )
+{
+  int i;
+  for(i=0; i<strlen(str); i++) {
+    if( str[i] == c )
+      return i;
+  }
+  return -1;
+}
+
+
+
+/*
+**  total_trim() - Remove leading, trailing, & excess embedded spaces
+**  from the Snippets collection (TRIM.C)
+**  public domain by Bob Stout & Michael Dehlwes 
+*/
+char *total_trim( char *str )
+{
+  char *ibuf, *obuf;
+  if( !strcmp(str, "") ) {
+    return str;
+  }
+
+  if( str ) {
+    for( ibuf = obuf = str; *ibuf; ){
+      while (*ibuf && (isspace (*ibuf))) {
+       ibuf++;
+      }
+      if (*ibuf && (obuf != str)) {
+       *(obuf++) = ' ';
+      }
+      while (*ibuf && (!isspace (*ibuf))) {
+       *(obuf++) = *(ibuf++);
+      }
+    }
+    *obuf = 0;
+  }
+  return str;
+}
+
+
+#ifdef STANDALONE
+
+int main( int argc, char *argv[] )
+{
+  char *tmp;
+  const char *text = "  hello, said the       happy       figment!     ";
+  int i;
+  int num = numstr( text );
+  
+  printf( "%d bits in `text'\n", num );
+  
+  for( i=1; i<=num; i++ ) {
+    tmp = parse( text, i );
+    puts( tmp );
+    free( tmp );
+  }
+
+  return 0;
+}
+
+#endif
diff --git a/Applications/rpilot-1.4.2/rstring.h b/Applications/rpilot-1.4.2/rstring.h
new file mode 100644 (file)
index 0000000..8eca018
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef _RSTRING_H_
+#define _RSTRING_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+char *strupr( char *s );
+char *strset( char *s, int ch );
+char *new_string( char *src );
+char *new_string_from( char *src, int index, int count );
+
+extern int firstnot( const char *d, const char e, int first );
+extern int neither( const char *d, const char e, const char f, char first );
+extern int find( const char *d, const char *e, int first );
+extern char *parse( const char *src, int num );
+extern int numstr( const char *d );
+extern char *rtrim( char *str );
+extern int rws( const char *str);
+extern char *scopy( char *dest, char *src, int index, int count );
+extern int ws( const char *str );
+extern char *ltrim( char *str );
+char *trim( char *str );
+int wspace( const char *str, int first );
+int findchar( const char *str, char c );
+char *total_trim( char *str );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ifndef _RSTRING_H_ */
diff --git a/Applications/rpilot-1.4.2/stack.c b/Applications/rpilot-1.4.2/stack.c
new file mode 100644 (file)
index 0000000..a1def48
--- /dev/null
@@ -0,0 +1,59 @@
+
+/* #include "stack.h" */
+/* #include "line.h" */
+#include "rpilot.h"
+
+#include <stdlib.h>
+
+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 (file)
index 0000000..aada045
--- /dev/null
@@ -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 (file)
index 0000000..4a7e21e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+  var.c - RPilot variable support
+*/
+
+#include <string.h>
+#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 (file)
index 0000000..fa5305b
--- /dev/null
@@ -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