2214 lines · 65.0 KB · Text
RawDownload
 $ sysprog, ucsd, heap_dispose, partial_eval $ {$ debug$}  program basic(input, output);  const    checking = true;    varnamelen = 20;   maxdims = 4;   type    varnamestring = string[varnamelen];    string255 = string[255];   string255ptr = ^string255;    tokenkinds = (tokvar, toknum, tokstr, toksnerr,                  tokplus, tokminus, toktimes, tokdiv, tokup, toklp, tokrp,                  tokcomma, toksemi, tokcolon, tokeq, toklt, tokgt,                 tokle, tokge, tokne,                  tokand, tokor, tokxor, tokmod, toknot, toksqr, toksqrt, toksin,                 tokcos, toktan, tokarctan, toklog, tokexp, tokabs, toksgn,                 tokstr_, tokval, tokchr_, tokasc, toklen, tokmid_, tokpeek,                  tokrem, toklet, tokprint, tokinput, tokgoto, tokif, tokend,                  tokstop, tokfor, toknext, tokwhile, tokwend, tokgosub,                 tokreturn, tokread, tokdata, tokrestore, tokgotoxy, tokon,                 tokdim, tokpoke,                  toklist, tokrun, toknew, tokload, tokmerge, toksave, tokbye,                 tokdel, tokrenum,                  tokthen, tokelse, tokto, tokstep);    realptr = ^real;   basicstring = string255ptr;   stringptr = ^basicstring;   numarray = array[0..maxint] of real;   arrayptr = ^numarray;   strarray = array[0..maxint] of basicstring;   strarrayptr = ^strarray;    tokenptr = ^tokenrec;   lineptr = ^linerec;   varptr = ^varrec;   loopptr = ^looprec;    tokenrec =      record         next : tokenptr;         case kind : tokenkinds of            tokvar : (vp : varptr);            toknum : (num : real);            tokstr, tokrem : (sp : string255ptr);            toksnerr : (snch : char);      end;    linerec =      record         num, num2 : integer;         txt : tokenptr;         next : lineptr;      end;    varrec =      record         name : varnamestring;         next : varptr;         dims : array [1..maxdims] of integer;         numdims : 0..maxdims;         case stringvar : boolean of            false : (arr : arrayptr;  val : realptr;  rv : real);            true : (sarr : strarrayptr;  sval : stringptr;  sv : basicstring);      end;    valrec =      record         case stringval : boolean of            false : (val : real);            true : (sval : basicstring);      end;    loopkind = (forloop, whileloop, gosubloop);   looprec =      record         next : loopptr;         homeline : lineptr;         hometok : tokenptr;         case kind : loopkind of            forloop :               ( vp : varptr;                 max, step : real );      end;   var    inbuf : string255ptr;    linebase : lineptr;   varbase : varptr;   loopbase : loopptr;    curline : integer;   stmtline, dataline : lineptr;   stmttok, datatok, buf : tokenptr;    exitflag : boolean;    excp_line ['EXCP_LINE'] : integer;   $if not checking$   $range off$$end$   procedure misc_getioerrmsg(var s : string; io : integer);   external; procedure misc_printerror(er, io : integer);   external; function asm_iand(a, b : integer) : integer;   external; function asm_ior(a, b : integer) : integer;   external; procedure hpm_new(var p : anyptr; size : integer);   external; procedure hpm_dispose(var p : anyptr; size : integer);   external;   procedure restoredata;   begin      dataline := nil;      datatok := nil;   end;   procedure clearloops;   var      l : loopptr;   begin      while loopbase <> nil do         begin            l := loopbase^.next;            dispose(loopbase);            loopbase := l;         end;   end;   function arraysize(v : varptr) : integer;   var      i, j : integer;   begin      with v^ do         begin            if stringvar then               j := 4            else               j := 8;            for i := 1 to numdims do               j := j * dims[i];         end;      arraysize := j;   end;  procedure clearvar(v : varptr);   begin      with v^ do         begin            if numdims <> 0 then               hpm_dispose(arr, arraysize(v))            else if stringvar and (sv <> nil) then               dispose(sv);            numdims := 0;            if stringvar then               begin                  sv := nil;                  sval := addr(sv);               end            else               begin                  rv := 0;                  val := addr(rv);               end;         end;   end;  procedure clearvars;   var      v : varptr;   begin      v := varbase;      while v <> nil do         begin            clearvar(v);            v := v^.next;         end;   end;   function numtostr(n : real) : string255;   var      s : string255;      i : integer;   begin      setstrlen(s, 255);      if (n <> 0) and (abs(n) < 1e-2) or (abs(n) >= 1e12) then         begin            strwrite(s, 1, i, n);            setstrlen(s, i-1);            numtostr := s;         end      else         begin            strwrite(s, 1, i, n:30:10);            repeat               i := i - 1;            until s[i] <> '0';            if s[i] = '.' then               i := i - 1;            setstrlen(s, i);            numtostr := strltrim(s);         end;   end;   procedure parse(inbuf : string255ptr; var buf : tokenptr);    const      toklength = 20;    type      chset = set of char;    const      idchars = chset ['A'..'Z','a'..'z','0'..'9','_','$'];    var      i, j, k : integer;      token : string[toklength];      t, tptr : tokenptr;      v : varptr;      ch : char;      n, d, d1 : real;    begin      tptr := nil;      buf := nil;      i := 1;      repeat         ch := ' ';         while (i <= strlen(inbuf^)) and (ch = ' ') do            begin               ch := inbuf^[i];               i := i + 1;            end;         if ch <> ' ' then            begin               new(t);               if tptr = nil then                  buf := t               else                  tptr^.next := t;               tptr := t;               t^.next := nil;               case ch of                  'A'..'Z', 'a'..'z' :                     begin                        i := i - 1;                        j := 0;                        setstrlen(token, strmax(token));                        while (i <= strlen(inbuf^)) and (inbuf^[i] in idchars) do                           begin                              if j < toklength then                                 begin                                    j := j + 1;                                    token[j] := inbuf^[i];                                 end;                              i := i + 1;                           end;                        setstrlen(token, j);                        if (token = 'and')     or (token = 'AND')     then t^.kind := tokand                        else if (token = 'or')      or (token = 'OR')      then t^.kind := tokor                         else if (token = 'xor')     or (token = 'XOR')     then t^.kind := tokxor                        else if (token = 'not')     or (token = 'NOT')     then t^.kind := toknot                        else if (token = 'mod')     or (token = 'MOD')     then t^.kind := tokmod                        else if (token = 'sqr')     or (token = 'SQR')     then t^.kind := toksqr                        else if (token = 'sqrt')    or (token = 'SQRT')    then t^.kind := toksqrt                       else if (token = 'sin')     or (token = 'SIN')     then t^.kind := toksin                        else if (token = 'cos')     or (token = 'COS')     then t^.kind := tokcos                        else if (token = 'tan')     or (token = 'TAN')     then t^.kind := toktan                        else if (token = 'arctan')  or (token = 'ARCTAN')  then t^.kind := tokarctan                     else if (token = 'log')     or (token = 'LOG')     then t^.kind := toklog                        else if (token = 'exp')     or (token = 'EXP')     then t^.kind := tokexp                        else if (token = 'abs')     or (token = 'ABS')     then t^.kind := tokabs                        else if (token = 'sgn')     or (token = 'SGN')     then t^.kind := toksgn                        else if (token = 'str$')    or (token = 'STR$')    then t^.kind := tokstr_                       else if (token = 'val')     or (token = 'VAL')     then t^.kind := tokval                        else if (token = 'chr$')    or (token = 'CHR$')    then t^.kind := tokchr_                       else if (token = 'asc')     or (token = 'ASC')     then t^.kind := tokasc                        else if (token = 'len')     or (token = 'LEN')     then t^.kind := toklen                        else if (token = 'mid$')    or (token = 'MID$')    then t^.kind := tokmid_                       else if (token = 'peek')    or (token = 'PEEK')    then t^.kind := tokpeek                       else if (token = 'let')     or (token = 'LET')     then t^.kind := toklet                        else if (token = 'print')   or (token = 'PRINT')   then t^.kind := tokprint                      else if (token = 'input')   or (token = 'INPUT')   then t^.kind := tokinput                      else if (token = 'goto')    or (token = 'GOTO')    then t^.kind := tokgoto                       else if (token = 'go to')   or (token = 'GO TO')   then t^.kind := tokgoto                       else if (token = 'if')      or (token = 'IF')      then t^.kind := tokif                         else if (token = 'end')     or (token = 'END')     then t^.kind := tokend                        else if (token = 'stop')    or (token = 'STOP')    then t^.kind := tokstop                       else if (token = 'for')     or (token = 'FOR')     then t^.kind := tokfor                        else if (token = 'next')    or (token = 'NEXT')    then t^.kind := toknext                       else if (token = 'while')   or (token = 'WHILE')   then t^.kind := tokwhile                      else if (token = 'wend')    or (token = 'WEND')    then t^.kind := tokwend                       else if (token = 'gosub')   or (token = 'GOSUB')   then t^.kind := tokgosub                      else if (token = 'return')  or (token = 'RETURN')  then t^.kind := tokreturn                     else if (token = 'read')    or (token = 'READ')    then t^.kind := tokread                       else if (token = 'data')    or (token = 'DATA')    then t^.kind := tokdata                       else if (token = 'restore') or (token = 'RESTORE') then t^.kind := tokrestore                    else if (token = 'gotoxy')  or (token = 'GOTOXY')  then t^.kind := tokgotoxy                     else if (token = 'on')      or (token = 'ON')      then t^.kind := tokon                         else if (token = 'dim')     or (token = 'DIM')     then t^.kind := tokdim                        else if (token = 'poke')    or (token = 'POKE')    then t^.kind := tokpoke                       else if (token = 'list')    or (token = 'LIST')    then t^.kind := toklist                       else if (token = 'run')     or (token = 'RUN')     then t^.kind := tokrun                        else if (token = 'new')     or (token = 'NEW')     then t^.kind := toknew                        else if (token = 'load')    or (token = 'LOAD')    then t^.kind := tokload                       else if (token = 'merge')   or (token = 'MERGE')   then t^.kind := tokmerge                      else if (token = 'save')    or (token = 'SAVE')    then t^.kind := toksave                       else if (token = 'bye')     or (token = 'BYE')     then t^.kind := tokbye                        else if (token = 'quit')    or (token = 'QUIT')    then t^.kind := tokbye                        else if (token = 'del')     or (token = 'DEL')     then t^.kind := tokdel                        else if (token = 'renum')   or (token = 'RENUM')   then t^.kind := tokrenum                      else if (token = 'then')    or (token = 'THEN')    then t^.kind := tokthen                       else if (token = 'else')    or (token = 'ELSE')    then t^.kind := tokelse                       else if (token = 'to')      or (token = 'TO')      then t^.kind := tokto                         else if (token = 'step')    or (token = 'STEP')    then t^.kind := tokstep                       else if (token = 'rem')     or (token = 'REM')     then                           begin                              t^.kind := tokrem;                              new(t^.sp);                              t^.sp^ := str(inbuf^, i, strlen(inbuf^)-i+1);                              i := strlen(inbuf^)+1;                           end                        else                           begin                              t^.kind := tokvar;                              v := varbase;                              while (v <> nil) and (v^.name <> token) do                                 v := v^.next;                              if v = nil then                                 begin                                    new(v);                                    v^.next := varbase;                                    varbase := v;                                    v^.name := token;                                    v^.numdims := 0;                                    if token[strlen(token)] = '$' then                                       begin                                          v^.stringvar := true;                                          v^.sv := nil;                                          v^.sval := addr(v^.sv);                                       end                                    else                                       begin                                          v^.stringvar := false;                                          v^.rv := 0;                                          v^.val := addr(v^.rv);                                       end;                                 end;                              t^.vp := v;                           end;                     end;                  '"', '''' :                     begin                        t^.kind := tokstr;                        new(t^.sp);                        setstrlen(t^.sp^, 255);                        j := 0;                        while (i <= strlen(inbuf^)) and (inbuf^[i] <> ch) do                           begin                              j := j + 1;                              t^.sp^[j] := inbuf^[i];                              i := i + 1;                           end;                        setstrlen(t^.sp^, j);                        i := i + 1;                     end;                  '0'..'9', '.' :                     begin                        t^.kind := toknum;                        n := 0;                        d := 1;                        d1 := 1;                        i := i - 1;                        while (i <= strlen(inbuf^)) and ((inbuf^[i] in ['0'..'9'])                                    or ((inbuf^[i] = '.') and (d1 = 1))) do                           begin                              if inbuf^[i] = '.' then                                 d1 := 10                              else                                 begin                                    n := n * 10 + ord(inbuf^[i]) - 48;                                    d := d * d1;                                 end;                              i := i + 1;                           end;                        n := n / d;                        if (i <= strlen(inbuf^)) and (inbuf^[i] in ['e','E']) then                           begin                              i := i + 1;                              d1 := 10;                              if (i <= strlen(inbuf^)) and (inbuf^[i] in ['+','-']) then                                 begin                                    if inbuf^[i] = '-' then                                       d1 := 0.1;                                    i := i + 1;                                 end;                              j := 0;                              while (i <= strlen(inbuf^)) and (inbuf^[i] in ['0'..'9']) do                                 begin                                    j := j * 10 + ord(inbuf^[i]) - 48;                                    i := i + 1;                                 end;                              for k := 1 to j do                                 n := n * d1;                           end;                        t^.num := n;                     end;                  '+' : t^.kind := tokplus;                  '-' : t^.kind := tokminus;                  '*' : t^.kind := toktimes;                  '/' : t^.kind := tokdiv;                  '^' : t^.kind := tokup;                  '(', '[' : t^.kind := toklp;                  ')', ']' : t^.kind := tokrp;                  ',' : t^.kind := tokcomma;                  ';' : t^.kind := toksemi;                  ':' : t^.kind := tokcolon;                  '?' : t^.kind := tokprint;                  '=' : t^.kind := tokeq;                  '<' :                      begin                        if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then                           begin                              t^.kind := tokle;                              i := i + 1;                           end                        else if (i <= strlen(inbuf^)) and (inbuf^[i] = '>') then                           begin                              t^.kind := tokne;                              i := i + 1;                           end                        else                           t^.kind := toklt;                     end;                  '>' :                     begin                        if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then                           begin                              t^.kind := tokge;                              i := i + 1;                           end                        else                           t^.kind := tokgt;                     end;                  otherwise                     begin                        t^.kind := toksnerr;                        t^.snch := ch;                     end;

Lines 1–500 of 2214.