home *** CD-ROM | disk | FTP | other *** search
- Subject: v21i064: Pascal to C translator, Part19/32
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: da6cea1c d014eb81 886e97ce e7773e24
-
- Submitted-by: Dave Gillespie <daveg@csvax.caltech.edu>
- Posting-number: Volume 21, Issue 64
- Archive-name: p2c/part19
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 19 (of 32)."
- # Contents: examples/basic.p.1
- # Wrapped by rsalz@litchi.bbn.com on Mon Mar 26 14:29:42 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'examples/basic.p.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'examples/basic.p.1'\"
- else
- echo shar: Extracting \"'examples/basic.p.1'\" \(48192 characters\)
- sed "s/^X//" >'examples/basic.p.1' <<'END_OF_FILE'
- X
- X$ sysprog, ucsd, heap_dispose, partial_eval $
- X
- X{$ debug$}
- X
- X
- Xprogram basic(input, output);
- X
- X
- Xconst
- X
- X checking = true;
- X
- X varnamelen = 20;
- X maxdims = 4;
- X
- X
- X
- Xtype
- X
- X varnamestring = string[varnamelen];
- X
- X string255 = string[255];
- X string255ptr = ^string255;
- X
- X tokenkinds = (tokvar, toknum, tokstr, toksnerr,
- X
- X tokplus, tokminus, toktimes, tokdiv, tokup, toklp, tokrp,
- X tokcomma, toksemi, tokcolon, tokeq, toklt, tokgt,
- X tokle, tokge, tokne,
- X
- X tokand, tokor, tokxor, tokmod, toknot, toksqr, toksqrt, toksin,
- X tokcos, toktan, tokarctan, toklog, tokexp, tokabs, toksgn,
- X tokstr_, tokval, tokchr_, tokasc, toklen, tokmid_, tokpeek,
- X
- X tokrem, toklet, tokprint, tokinput, tokgoto, tokif, tokend,
- X tokstop, tokfor, toknext, tokwhile, tokwend, tokgosub,
- X tokreturn, tokread, tokdata, tokrestore, tokgotoxy, tokon,
- X tokdim, tokpoke,
- X
- X toklist, tokrun, toknew, tokload, tokmerge, toksave, tokbye,
- X tokdel, tokrenum,
- X
- X tokthen, tokelse, tokto, tokstep);
- X
- X realptr = ^real;
- X basicstring = string255ptr;
- X stringptr = ^basicstring;
- X numarray = array[0..maxint] of real;
- X arrayptr = ^numarray;
- X strarray = array[0..maxint] of basicstring;
- X strarrayptr = ^strarray;
- X
- X tokenptr = ^tokenrec;
- X lineptr = ^linerec;
- X varptr = ^varrec;
- X loopptr = ^looprec;
- X
- X tokenrec =
- X record
- X next : tokenptr;
- X case kind : tokenkinds of
- X tokvar : (vp : varptr);
- X toknum : (num : real);
- X tokstr, tokrem : (sp : string255ptr);
- X toksnerr : (snch : char);
- X end;
- X
- X linerec =
- X record
- X num, num2 : integer;
- X txt : tokenptr;
- X next : lineptr;
- X end;
- X
- X varrec =
- X record
- X name : varnamestring;
- X next : varptr;
- X dims : array [1..maxdims] of integer;
- X numdims : 0..maxdims;
- X case stringvar : boolean of
- X false : (arr : arrayptr; val : realptr; rv : real);
- X true : (sarr : strarrayptr; sval : stringptr; sv : basicstring);
- X end;
- X
- X valrec =
- X record
- X case stringval : boolean of
- X false : (val : real);
- X true : (sval : basicstring);
- X end;
- X
- X loopkind = (forloop, whileloop, gosubloop);
- X looprec =
- X record
- X next : loopptr;
- X homeline : lineptr;
- X hometok : tokenptr;
- X case kind : loopkind of
- X forloop :
- X ( vp : varptr;
- X max, step : real );
- X end;
- X
- X
- X
- Xvar
- X
- X inbuf : string255ptr;
- X
- X linebase : lineptr;
- X varbase : varptr;
- X loopbase : loopptr;
- X
- X curline : integer;
- X stmtline, dataline : lineptr;
- X stmttok, datatok, buf : tokenptr;
- X
- X exitflag : boolean;
- X
- X excp_line ['EXCP_LINE'] : integer;
- X
- X
- X
- X$if not checking$
- X $range off$
- X$end$
- X
- X
- X
- Xprocedure misc_getioerrmsg(var s : string; io : integer);
- X external;
- X
- Xprocedure misc_printerror(er, io : integer);
- X external;
- X
- Xfunction asm_iand(a, b : integer) : integer;
- X external;
- X
- Xfunction asm_ior(a, b : integer) : integer;
- X external;
- X
- Xprocedure hpm_new(var p : anyptr; size : integer);
- X external;
- X
- Xprocedure hpm_dispose(var p : anyptr; size : integer);
- X external;
- X
- X
- X
- Xprocedure restoredata;
- X begin
- X dataline := nil;
- X datatok := nil;
- X end;
- X
- X
- X
- Xprocedure clearloops;
- X var
- X l : loopptr;
- X begin
- X while loopbase <> nil do
- X begin
- X l := loopbase^.next;
- X dispose(loopbase);
- X loopbase := l;
- X end;
- X end;
- X
- X
- X
- Xfunction arraysize(v : varptr) : integer;
- X var
- X i, j : integer;
- X begin
- X with v^ do
- X begin
- X if stringvar then
- X j := 4
- X else
- X j := 8;
- X for i := 1 to numdims do
- X j := j * dims[i];
- X end;
- X arraysize := j;
- X end;
- X
- X
- Xprocedure clearvar(v : varptr);
- X begin
- X with v^ do
- X begin
- X if numdims <> 0 then
- X hpm_dispose(arr, arraysize(v))
- X else if stringvar and (sv <> nil) then
- X dispose(sv);
- X numdims := 0;
- X if stringvar then
- X begin
- X sv := nil;
- X sval := addr(sv);
- X end
- X else
- X begin
- X rv := 0;
- X val := addr(rv);
- X end;
- X end;
- X end;
- X
- X
- Xprocedure clearvars;
- X var
- X v : varptr;
- X begin
- X v := varbase;
- X while v <> nil do
- X begin
- X clearvar(v);
- X v := v^.next;
- X end;
- X end;
- X
- X
- X
- Xfunction numtostr(n : real) : string255;
- X var
- X s : string255;
- X i : integer;
- X begin
- X setstrlen(s, 255);
- X if (n <> 0) and (abs(n) < 1e-2) or (abs(n) >= 1e12) then
- X begin
- X strwrite(s, 1, i, n);
- X setstrlen(s, i-1);
- X numtostr := s;
- X end
- X else
- X begin
- X strwrite(s, 1, i, n:30:10);
- X repeat
- X i := i - 1;
- X until s[i] <> '0';
- X if s[i] = '.' then
- X i := i - 1;
- X setstrlen(s, i);
- X numtostr := strltrim(s);
- X end;
- X end;
- X
- X
- X
- Xprocedure parse(inbuf : string255ptr; var buf : tokenptr);
- X
- X const
- X toklength = 20;
- X
- X type
- X chset = set of char;
- X
- X const
- X idchars = chset ['A'..'Z','a'..'z','0'..'9','_','$'];
- X
- X var
- X i, j, k : integer;
- X token : string[toklength];
- X t, tptr : tokenptr;
- X v : varptr;
- X ch : char;
- X n, d, d1 : real;
- X
- X begin
- X tptr := nil;
- X buf := nil;
- X i := 1;
- X repeat
- X ch := ' ';
- X while (i <= strlen(inbuf^)) and (ch = ' ') do
- X begin
- X ch := inbuf^[i];
- X i := i + 1;
- X end;
- X if ch <> ' ' then
- X begin
- X new(t);
- X if tptr = nil then
- X buf := t
- X else
- X tptr^.next := t;
- X tptr := t;
- X t^.next := nil;
- X case ch of
- X 'A'..'Z', 'a'..'z' :
- X begin
- X i := i - 1;
- X j := 0;
- X setstrlen(token, strmax(token));
- X while (i <= strlen(inbuf^)) and (inbuf^[i] in idchars) do
- X begin
- X if j < toklength then
- X begin
- X j := j + 1;
- X token[j] := inbuf^[i];
- X end;
- X i := i + 1;
- X end;
- X setstrlen(token, j);
- X if (token = 'and') or (token = 'AND') then t^.kind := tokand
- X else if (token = 'or') or (token = 'OR') then t^.kind := tokor
- X else if (token = 'xor') or (token = 'XOR') then t^.kind := tokxor
- X else if (token = 'not') or (token = 'NOT') then t^.kind := toknot
- X else if (token = 'mod') or (token = 'MOD') then t^.kind := tokmod
- X else if (token = 'sqr') or (token = 'SQR') then t^.kind := toksqr
- X else if (token = 'sqrt') or (token = 'SQRT') then t^.kind := toksqrt
- X else if (token = 'sin') or (token = 'SIN') then t^.kind := toksin
- X else if (token = 'cos') or (token = 'COS') then t^.kind := tokcos
- X else if (token = 'tan') or (token = 'TAN') then t^.kind := toktan
- X else if (token = 'arctan') or (token = 'ARCTAN') then t^.kind := tokarctan
- X else if (token = 'log') or (token = 'LOG') then t^.kind := toklog
- X else if (token = 'exp') or (token = 'EXP') then t^.kind := tokexp
- X else if (token = 'abs') or (token = 'ABS') then t^.kind := tokabs
- X else if (token = 'sgn') or (token = 'SGN') then t^.kind := toksgn
- X else if (token = 'str$') or (token = 'STR$') then t^.kind := tokstr_
- X else if (token = 'val') or (token = 'VAL') then t^.kind := tokval
- X else if (token = 'chr$') or (token = 'CHR$') then t^.kind := tokchr_
- X else if (token = 'asc') or (token = 'ASC') then t^.kind := tokasc
- X else if (token = 'len') or (token = 'LEN') then t^.kind := toklen
- X else if (token = 'mid$') or (token = 'MID$') then t^.kind := tokmid_
- X else if (token = 'peek') or (token = 'PEEK') then t^.kind := tokpeek
- X else if (token = 'let') or (token = 'LET') then t^.kind := toklet
- X else if (token = 'print') or (token = 'PRINT') then t^.kind := tokprint
- X else if (token = 'input') or (token = 'INPUT') then t^.kind := tokinput
- X else if (token = 'goto') or (token = 'GOTO') then t^.kind := tokgoto
- X else if (token = 'go to') or (token = 'GO TO') then t^.kind := tokgoto
- X else if (token = 'if') or (token = 'IF') then t^.kind := tokif
- X else if (token = 'end') or (token = 'END') then t^.kind := tokend
- X else if (token = 'stop') or (token = 'STOP') then t^.kind := tokstop
- X else if (token = 'for') or (token = 'FOR') then t^.kind := tokfor
- X else if (token = 'next') or (token = 'NEXT') then t^.kind := toknext
- X else if (token = 'while') or (token = 'WHILE') then t^.kind := tokwhile
- X else if (token = 'wend') or (token = 'WEND') then t^.kind := tokwend
- X else if (token = 'gosub') or (token = 'GOSUB') then t^.kind := tokgosub
- X else if (token = 'return') or (token = 'RETURN') then t^.kind := tokreturn
- X else if (token = 'read') or (token = 'READ') then t^.kind := tokread
- X else if (token = 'data') or (token = 'DATA') then t^.kind := tokdata
- X else if (token = 'restore') or (token = 'RESTORE') then t^.kind := tokrestore
- X else if (token = 'gotoxy') or (token = 'GOTOXY') then t^.kind := tokgotoxy
- X else if (token = 'on') or (token = 'ON') then t^.kind := tokon
- X else if (token = 'dim') or (token = 'DIM') then t^.kind := tokdim
- X else if (token = 'poke') or (token = 'POKE') then t^.kind := tokpoke
- X else if (token = 'list') or (token = 'LIST') then t^.kind := toklist
- X else if (token = 'run') or (token = 'RUN') then t^.kind := tokrun
- X else if (token = 'new') or (token = 'NEW') then t^.kind := toknew
- X else if (token = 'load') or (token = 'LOAD') then t^.kind := tokload
- X else if (token = 'merge') or (token = 'MERGE') then t^.kind := tokmerge
- X else if (token = 'save') or (token = 'SAVE') then t^.kind := toksave
- X else if (token = 'bye') or (token = 'BYE') then t^.kind := tokbye
- X else if (token = 'quit') or (token = 'QUIT') then t^.kind := tokbye
- X else if (token = 'del') or (token = 'DEL') then t^.kind := tokdel
- X else if (token = 'renum') or (token = 'RENUM') then t^.kind := tokrenum
- X else if (token = 'then') or (token = 'THEN') then t^.kind := tokthen
- X else if (token = 'else') or (token = 'ELSE') then t^.kind := tokelse
- X else if (token = 'to') or (token = 'TO') then t^.kind := tokto
- X else if (token = 'step') or (token = 'STEP') then t^.kind := tokstep
- X else if (token = 'rem') or (token = 'REM') then
- X begin
- X t^.kind := tokrem;
- X new(t^.sp);
- X t^.sp^ := str(inbuf^, i, strlen(inbuf^)-i+1);
- X i := strlen(inbuf^)+1;
- X end
- X else
- X begin
- X t^.kind := tokvar;
- X v := varbase;
- X while (v <> nil) and (v^.name <> token) do
- X v := v^.next;
- X if v = nil then
- X begin
- X new(v);
- X v^.next := varbase;
- X varbase := v;
- X v^.name := token;
- X v^.numdims := 0;
- X if token[strlen(token)] = '$' then
- X begin
- X v^.stringvar := true;
- X v^.sv := nil;
- X v^.sval := addr(v^.sv);
- X end
- X else
- X begin
- X v^.stringvar := false;
- X v^.rv := 0;
- X v^.val := addr(v^.rv);
- X end;
- X end;
- X t^.vp := v;
- X end;
- X end;
- X '"', '''' :
- X begin
- X t^.kind := tokstr;
- X new(t^.sp);
- X setstrlen(t^.sp^, 255);
- X j := 0;
- X while (i <= strlen(inbuf^)) and (inbuf^[i] <> ch) do
- X begin
- X j := j + 1;
- X t^.sp^[j] := inbuf^[i];
- X i := i + 1;
- X end;
- X setstrlen(t^.sp^, j);
- X i := i + 1;
- X end;
- X '0'..'9', '.' :
- X begin
- X t^.kind := toknum;
- X n := 0;
- X d := 1;
- X d1 := 1;
- X i := i - 1;
- X while (i <= strlen(inbuf^)) and ((inbuf^[i] in ['0'..'9'])
- X or ((inbuf^[i] = '.') and (d1 = 1))) do
- X begin
- X if inbuf^[i] = '.' then
- X d1 := 10
- X else
- X begin
- X n := n * 10 + ord(inbuf^[i]) - 48;
- X d := d * d1;
- X end;
- X i := i + 1;
- X end;
- X n := n / d;
- X if (i <= strlen(inbuf^)) and (inbuf^[i] in ['e','E']) then
- X begin
- X i := i + 1;
- X d1 := 10;
- X if (i <= strlen(inbuf^)) and (inbuf^[i] in ['+','-']) then
- X begin
- X if inbuf^[i] = '-' then
- X d1 := 0.1;
- X i := i + 1;
- X end;
- X j := 0;
- X while (i <= strlen(inbuf^)) and (inbuf^[i] in ['0'..'9']) do
- X begin
- X j := j * 10 + ord(inbuf^[i]) - 48;
- X i := i + 1;
- X end;
- X for k := 1 to j do
- X n := n * d1;
- X end;
- X t^.num := n;
- X end;
- X '+' : t^.kind := tokplus;
- X '-' : t^.kind := tokminus;
- X '*' : t^.kind := toktimes;
- X '/' : t^.kind := tokdiv;
- X '^' : t^.kind := tokup;
- X '(', '[' : t^.kind := toklp;
- X ')', ']' : t^.kind := tokrp;
- X ',' : t^.kind := tokcomma;
- X ';' : t^.kind := toksemi;
- X ':' : t^.kind := tokcolon;
- X '?' : t^.kind := tokprint;
- X '=' : t^.kind := tokeq;
- X '<' :
- X begin
- X if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then
- X begin
- X t^.kind := tokle;
- X i := i + 1;
- X end
- X else if (i <= strlen(inbuf^)) and (inbuf^[i] = '>') then
- X begin
- X t^.kind := tokne;
- X i := i + 1;
- X end
- X else
- X t^.kind := toklt;
- X end;
- X '>' :
- X begin
- X if (i <= strlen(inbuf^)) and (inbuf^[i] = '=') then
- X begin
- X t^.kind := tokge;
- X i := i + 1;
- X end
- X else
- X t^.kind := tokgt;
- X end;
- X otherwise
- X begin
- X t^.kind := toksnerr;
- X t^.snch := ch;
- X end;
- X end;
- X end;
- X until i > strlen(inbuf^);
- X end;
- X
- X
- X
- Xprocedure listtokens(var f : text; buf : tokenptr);
- X var
- X ltr, ltr0 : boolean;
- X begin
- X ltr := false;
- X while buf <> nil do
- X begin
- X if buf^.kind in [tokvar, toknum, toknot..tokrenum] then
- X begin
- X if ltr then write(f, ' ');
- X ltr := (buf^.kind <> toknot);
- X end
- X else
- X ltr := false;
- X case buf^.kind of
- X tokvar : write(f, buf^.vp^.name);
- X toknum : write(f, numtostr(buf^.num));
- X tokstr : write(f, '"', buf^.sp^, '"');
- X toksnerr : write(f, '{', buf^.snch, '}');
- X tokplus : write(f, '+');
- X tokminus : write(f, '-');
- X toktimes : write(f, '*');
- X tokdiv : write(f, '/');
- X tokup : write(f, '^');
- X toklp : write(f, '(');
- X tokrp : write(f, ')');
- X tokcomma : write(f, ',');
- X toksemi : write(f, ';');
- X tokcolon : write(f, ' : ');
- X tokeq : write(f, ' = ');
- X toklt : write(f, ' < ');
- X tokgt : write(f, ' > ');
- X tokle : write(f, ' <= ');
- X tokge : write(f, ' >= ');
- X tokne : write(f, ' <> ');
- X tokand : write(f, ' AND ');
- X tokor : write(f, ' OR ');
- X tokxor : write(f, ' XOR ');
- X tokmod : write(f, ' MOD ');
- X toknot : write(f, 'NOT ');
- X toksqr : write(f, 'SQR');
- X toksqrt : write(f, 'SQRT');
- X toksin : write(f, 'SIN');
- X tokcos : write(f, 'COS');
- X toktan : write(f, 'TAN');
- X tokarctan : write(f, 'ARCTAN');
- X toklog : write(f, 'LOG');
- X tokexp : write(f, 'EXP');
- X tokabs : write(f, 'ABS');
- X toksgn : write(f, 'SGN');
- X tokstr_ : write(f, 'STR$');
- X tokval : write(f, 'VAL');
- X tokchr_ : write(f, 'CHR$');
- X tokasc : write(f, 'ASC');
- X toklen : write(f, 'LEN');
- X tokmid_ : write(f, 'MID$');
- X tokpeek : write(f, 'PEEK');
- X toklet : write(f, 'LET');
- X tokprint : write(f, 'PRINT');
- X tokinput : write(f, 'INPUT');
- X tokgoto : write(f, 'GOTO');
- X tokif : write(f, 'IF');
- X tokend : write(f, 'END');
- X tokstop : write(f, 'STOP');
- X tokfor : write(f, 'FOR');
- X toknext : write(f, 'NEXT');
- X tokwhile : write(f, 'WHILE');
- X tokwend : write(f, 'WEND');
- X tokgosub : write(f, 'GOSUB');
- X tokreturn : write(f, 'RETURN');
- X tokread : write(f, 'READ');
- X tokdata : write(f, 'DATA');
- X tokrestore : write(f, 'RESTORE');
- X tokgotoxy : write(f, 'GOTOXY');
- X tokon : write(f, 'ON');
- X tokdim : write(f, 'DIM');
- X tokpoke : write(f, 'POKE');
- X toklist : write(f, 'LIST');
- X tokrun : write(f, 'RUN');
- X toknew : write(f, 'NEW');
- X tokload : write(f, 'LOAD');
- X tokmerge : write(f, 'MERGE');
- X toksave : write(f, 'SAVE');
- X tokdel : write(f, 'DEL');
- X tokbye : write(f, 'BYE');
- X tokrenum : write(f, 'RENUM');
- X tokthen : write(f, ' THEN ');
- X tokelse : write(f, ' ELSE ');
- X tokto : write(f, ' TO ');
- X tokstep : write(f, ' STEP ');
- X tokrem : write(f, 'REM', buf^.sp^);
- X end;
- X buf := buf^.next;
- X end;
- X end;
- X
- X
- X
- Xprocedure disposetokens(var tok : tokenptr);
- X var
- X tok1 : tokenptr;
- X begin
- X while tok <> nil do
- X begin
- X tok1 := tok^.next;
- X if tok^.kind in [tokstr, tokrem] then
- X dispose(tok^.sp);
- X dispose(tok);
- X tok := tok1;
- X end;
- X end;
- X
- X
- X
- Xprocedure parseinput(var buf : tokenptr);
- X var
- X l, l0, l1 : lineptr;
- X begin
- X inbuf^ := strltrim(inbuf^);
- X curline := 0;
- X while (strlen(inbuf^) <> 0) and (inbuf^[1] in ['0'..'9']) do
- X begin
- X curline := curline * 10 + ord(inbuf^[1]) - 48;
- X strdelete(inbuf^, 1, 1);
- X end;
- X parse(inbuf, buf);
- X if curline <> 0 then
- X begin
- X l := linebase;
- X l0 := nil;
- X while (l <> nil) and (l^.num < curline) do
- X begin
- X l0 := l;
- X l := l^.next;
- X end;
- X if (l <> nil) and (l^.num = curline) then
- X begin
- X l1 := l;
- X l := l^.next;
- X if l0 = nil then
- X linebase := l
- X else
- X l0^.next := l;
- X disposetokens(l1^.txt);
- X dispose(l1);
- X end;
- X if buf <> nil then
- X begin
- X new(l1);
- X l1^.next := l;
- X if l0 = nil then
- X linebase := l1
- X else
- X l0^.next := l1;
- X l1^.num := curline;
- X l1^.txt := buf;
- X end;
- X clearloops;
- X restoredata;
- X end;
- X end;
- X
- X
- X
- X
- X
- Xprocedure errormsg(s : string255);
- X begin
- X write(#7, s);
- X escape(42);
- X end;
- X
- X
- Xprocedure snerr;
- X begin
- X errormsg('Syntax error');
- X end;
- X
- Xprocedure tmerr;
- X begin
- X errormsg('Type mismatch error');
- X end;
- X
- Xprocedure badsubscr;
- X begin
- X errormsg('Bad subscript');
- X end;
- X
- X
- X
- X
- X
- X
- Xprocedure exec;
- X
- X var
- X gotoflag, elseflag : boolean;
- X t : tokenptr;
- X ioerrmsg : string255ptr;
- X
- X
- X function factor : valrec;
- X forward;
- X
- X function expr : valrec;
- X forward;
- X
- X function realfactor : real;
- X var
- X n : valrec;
- X begin
- X n := factor;
- X if n.stringval then tmerr;
- X realfactor := n.val;
- X end;
- X
- X function strfactor : basicstring;
- X var
- X n : valrec;
- X begin
- X n := factor;
- X if not n.stringval then tmerr;
- X strfactor := n.sval;
- X end;
- X
- X function stringfactor : string255;
- X var
- X n : valrec;
- X begin
- X n := factor;
- X if not n.stringval then tmerr;
- X stringfactor := n.sval^;
- X dispose(n.sval);
- X end;
- X
- X function intfactor : integer;
- X begin
- X intfactor := round(realfactor);
- X end;
- X
- X function realexpr : real;
- X var
- X n : valrec;
- X begin
- X n := expr;
- X if n.stringval then tmerr;
- X realexpr := n.val;
- X end;
- X
- X function strexpr : basicstring;
- X var
- X n : valrec;
- X begin
- X n := expr;
- X if not n.stringval then tmerr;
- X strexpr := n.sval;
- X end;
- X
- X function stringexpr : string255;
- X var
- X n : valrec;
- X begin
- X n := expr;
- X if not n.stringval then tmerr;
- X stringexpr := n.sval^;
- X dispose(n.sval);
- X end;
- X
- X function intexpr : integer;
- X begin
- X intexpr := round(realexpr);
- X end;
- X
- X
- X procedure require(k : tokenkinds);
- X begin
- X if (t = nil) or (t^.kind <> k) then
- X snerr;
- X t := t^.next;
- X end;
- X
- X
- X procedure skipparen;
- X label 1;
- X begin
- X repeat
- X if t = nil then snerr;
- X if (t^.kind = tokrp) or (t^.kind = tokcomma) then
- X goto 1;
- X if t^.kind = toklp then
- X begin
- X t := t^.next;
- X skipparen;
- X end;
- X t := t^.next;
- X until false;
- X 1 :
- X end;
- X
- X
- X function findvar : varptr;
- X var
- X v : varptr;
- X i, j, k : integer;
- X tok : tokenptr;
- X begin
- X if (t = nil) or (t^.kind <> tokvar) then snerr;
- X v := t^.vp;
- X t := t^.next;
- X if (t <> nil) and (t^.kind = toklp) then
- X with v^ do
- X begin
- X if numdims = 0 then
- X begin
- X tok := t;
- X i := 0;
- X j := 1;
- X repeat
- X if i >= maxdims then badsubscr;
- X t := t^.next;
- X skipparen;
- X j := j * 11;
- X i := i + 1;
- X dims[i] := 11;
- X until t^.kind = tokrp;
- X numdims := i;
- X if stringvar then
- X begin
- X hpm_new(sarr, j*4);
- X for k := 0 to j-1 do
- X sarr^[k] := nil;
- X end
- X else
- X begin
- X hpm_new(arr, j*8);
- X for k := 0 to j-1 do
- X arr^[k] := 0;
- X end;
- X t := tok;
- X end;
- X k := 0;
- X t := t^.next;
- X for i := 1 to numdims do
- X begin
- X j := intexpr;
- X if (j < 0) or (j >= dims[i]) then
- X badsubscr;
- X k := k * dims[i] + j;
- X if i < numdims then
- X require(tokcomma);
- X end;
- X require(tokrp);
- X if stringvar then
- X sval := addr(sarr^[k])
- X else
- X val := addr(arr^[k]);
- X end
- X else
- X begin
- X if v^.numdims <> 0 then
- X badsubscr;
- X end;
- X findvar := v;
- X end;
- X
- X
- X function inot(i : integer) : integer;
- X begin
- X inot := -1 - i;
- X end;
- X
- X function ixor(a, b : integer) : integer;
- X begin
- X ixor := asm_ior(asm_iand(a, inot(b)), asm_iand(inot(a), b));
- X end;
- X
- X
- X function factor : valrec;
- X var
- X v : varptr;
- X facttok : tokenptr;
- X n : valrec;
- X i, j : integer;
- X tok, tok1 : tokenptr;
- X s : basicstring;
- X trick :
- X record
- X case boolean of
- X true : (i : integer);
- X false : (c : ^char);
- X end;
- X begin
- X if t = nil then snerr;
- X facttok := t;
- X t := t^.next;
- X n.stringval := false;
- X case facttok^.kind of
- X toknum :
- X n.val := facttok^.num;
- X tokstr :
- X begin
- X n.stringval := true;
- X new(n.sval);
- X n.sval^ := facttok^.sp^;
- X end;
- X tokvar :
- X begin
- X t := facttok;
- X v := findvar;
- X n.stringval := v^.stringvar;
- X if n.stringval then
- X begin
- X new(n.sval);
- X n.sval^ := v^.sval^^;
- X end
- X else
- X n.val := v^.val^;
- X end;
- X toklp :
- X begin
- X n := expr;
- X require(tokrp);
- X end;
- X tokminus :
- X n.val := - realfactor;
- X tokplus :
- X n.val := realfactor;
- X toknot :
- X n.val := inot(intfactor);
- X toksqr :
- X n.val := sqr(realfactor);
- X toksqrt :
- X n.val := sqrt(realfactor);
- X toksin :
- X n.val := sin(realfactor);
- X tokcos :
- X n.val := cos(realfactor);
- X toktan :
- X begin
- X n.val := realfactor;
- X n.val := sin(n.val) / cos(n.val);
- X end;
- X tokarctan :
- X n.val := arctan(realfactor);
- X toklog:
- X n.val := ln(realfactor);
- X tokexp :
- X n.val := exp(realfactor);
- X tokabs :
- X n.val := abs(realfactor);
- X toksgn :
- X begin
- X n.val := realfactor;
- X n.val := ord(n.val > 0) - ord(n.val < 0);
- X end;
- X tokstr_ :
- X begin
- X n.stringval := true;
- X new(n.sval);
- X n.sval^ := numtostr(realfactor);
- X end;
- X tokval :
- X begin
- X s := strfactor;
- X tok1 := t;
- X parse(s, t);
- X tok := t;
- X if tok = nil then
- X n.val := 0
- X else
- X n := expr;
- X disposetokens(tok);
- X t := tok1;
- X dispose(s);
- X end;
- X tokchr_ :
- X begin
- X n.stringval := true;
- X new(n.sval);
- X n.sval^ := ' ';
- X n.sval^[1] := chr(intfactor);
- X end;
- X tokasc :
- X begin
- X s := strfactor;
- X if strlen(s^) = 0 then
- X n.val := 0
- X else
- X n.val := ord(s^[1]);
- X dispose(s);
- X end;
- X tokmid_ :
- X begin
- X n.stringval := true;
- X require(toklp);
- X n.sval := strexpr;
- X require(tokcomma);
- X i := intexpr;
- X if i < 1 then i := 1;
- X j := 255;
- X if (t <> nil) and (t^.kind = tokcomma) then
- X begin
- X t := t^.next;
- X j := intexpr;
- X end;
- X if j > strlen(n.sval^)-i+1 then
- X j := strlen(n.sval^)-i+1;
- X if i > strlen(n.sval^) then
- X n.sval^ := ''
- X else
- X n.sval^ := str(n.sval^, i, j);
- X require(tokrp);
- X end;
- X toklen :
- X begin
- X s := strfactor;
- X n.val := strlen(s^);
- X dispose(s);
- X end;
- X tokpeek :
- X begin
- X $range off$
- X trick.i := intfactor;
- X n.val := ord(trick.c^);
- X $if checking$ $range on$ $end$
- X end;
- X otherwise
- X snerr;
- X end;
- X factor := n;
- X end;
- X
- X function upexpr : valrec;
- X var
- X n, n2 : valrec;
- X begin
- X n := factor;
- X while (t <> nil) and (t^.kind = tokup) do
- X begin
- X if n.stringval then tmerr;
- X t := t^.next;
- X n2 := upexpr;
- X if n2.stringval then tmerr;
- X if n.val < 0 then
- X begin
- X if n2.val <> trunc(n2.val) then n.val := ln(n.val);
- X n.val := exp(n2.val * ln(-n.val));
- X if odd(trunc(n2.val)) then
- X n.val := - n.val;
- X end
- X else
- X n.val := exp(n2.val * ln(n.val));
- X end;
- X upexpr := n;
- X end;
- X
- X function term : valrec;
- X var
- X n, n2 : valrec;
- X k : tokenkinds;
- X begin
- X n := upexpr;
- X while (t <> nil) and (t^.kind in [toktimes, tokdiv, tokmod]) do
- X begin
- X k := t^.kind;
- X t := t^.next;
- X n2 := upexpr;
- X if n.stringval or n2.stringval then tmerr;
- X if k = tokmod then
- X n.val := round(n.val) mod round(n2.val)
- X else if k = toktimes then
- X n.val := n.val * n2.val
- X else
- X n.val := n.val / n2.val;
- X end;
- X term := n;
- X end;
- X
- X function sexpr : valrec;
- X var
- X n, n2 : valrec;
- X k : tokenkinds;
- X begin
- X n := term;
- X while (t <> nil) and (t^.kind in [tokplus, tokminus]) do
- X begin
- X k := t^.kind;
- X t := t^.next;
- X n2 := term;
- X if n.stringval <> n2.stringval then tmerr;
- X if k = tokplus then
- X if n.stringval then
- X begin
- X n.sval^ := n.sval^ + n2.sval^;
- X dispose(n2.sval);
- X end
- X else
- X n.val := n.val + n2.val
- X else
- X if n.stringval then
- X tmerr
- X else
- X n.val := n.val - n2.val;
- X end;
- X sexpr := n;
- X end;
- X
- X function relexpr : valrec;
- X var
- X n, n2 : valrec;
- X f : boolean;
- X k : tokenkinds;
- X begin
- X n := sexpr;
- X while (t <> nil) and (t^.kind in [tokeq..tokne]) do
- X begin
- X k := t^.kind;
- X t := t^.next;
- X n2 := sexpr;
- X if n.stringval <> n2.stringval then tmerr;
- X if n.stringval then
- X begin
- X f := ((n.sval^ = n2.sval^) and (k in [tokeq, tokge, tokle]) or
- X (n.sval^ < n2.sval^) and (k in [toklt, tokle, tokne]) or
- X (n.sval^ > n2.sval^) and (k in [tokgt, tokge, tokne]));
- X dispose(n.sval);
- X dispose(n2.sval);
- X end
- X else
- X f := ((n.val = n2.val) and (k in [tokeq, tokge, tokle]) or
- X (n.val < n2.val) and (k in [toklt, tokle, tokne]) or
- X (n.val > n2.val) and (k in [tokgt, tokge, tokne]));
- X n.stringval := false;
- X n.val := ord(f);
- X end;
- X relexpr := n;
- X end;
- X
- X function andexpr : valrec;
- X var
- X n, n2 : valrec;
- X begin
- X n := relexpr;
- X while (t <> nil) and (t^.kind = tokand) do
- X begin
- X t := t^.next;
- X n2 := relexpr;
- X if n.stringval or n2.stringval then tmerr;
- X n.val := asm_iand(trunc(n.val), trunc(n2.val));
- X end;
- X andexpr := n;
- X end;
- X
- X function expr : valrec;
- X var
- X n, n2 : valrec;
- X k : tokenkinds;
- X begin
- X n := andexpr;
- X while (t <> nil) and (t^.kind in [tokor, tokxor]) do
- X begin
- X k := t^.kind;
- X t := t^.next;
- X n2 := andexpr;
- X if n.stringval or n2.stringval then tmerr;
- X if k = tokor then
- X n.val := asm_ior(trunc(n.val), trunc(n2.val))
- X else
- X n.val := ixor(trunc(n.val), trunc(n2.val));
- X end;
- X expr := n;
- X end;
- X
- X
- X procedure checkextra;
- X begin
- X if t <> nil then
- X errormsg('Extra information on line');
- X end;
- X
- X
- X function iseos : boolean;
- X begin
- X iseos := (t = nil) or (t^.kind in [tokcolon, tokelse]);
- X end;
- X
- X
- X procedure skiptoeos;
- X begin
- X while not iseos do
- X t := t^.next;
- X end;
- X
- X
- X function findline(n : integer) : lineptr;
- X var
- X l : lineptr;
- X begin
- X l := linebase;
- X while (l <> nil) and (l^.num <> n) do
- X l := l^.next;
- X findline := l;
- X end;
- X
- X
- X function mustfindline(n : integer) : lineptr;
- X var
- X l : lineptr;
- X begin
- X l := findline(n);
- X if l = nil then
- X errormsg('Undefined line');
- X mustfindline := l;
- X end;
- X
- X
- X procedure cmdend;
- X begin
- X stmtline := nil;
- X t := nil;
- X end;
- X
- X
- X procedure cmdnew;
- X var
- X p : anyptr;
- X begin
- X cmdend;
- X clearloops;
- X restoredata;
- X while linebase <> nil do
- X begin
- X p := linebase^.next;
- X disposetokens(linebase^.txt);
- X dispose(linebase);
- X linebase := p;
- X end;
- X while varbase <> nil do
- X begin
- X p := varbase^.next;
- X if varbase^.stringvar then
- X if varbase^.sval^ <> nil then
- X dispose(varbase^.sval^);
- X dispose(varbase);
- X varbase := p;
- X end;
- X end;
- X
- X
- X procedure cmdlist;
- X var
- X l : lineptr;
- X n1, n2 : integer;
- X begin
- X repeat
- X n1 := 0;
- X n2 := maxint;
- X if (t <> nil) and (t^.kind = toknum) then
- X begin
- X n1 := trunc(t^.num);
- X t := t^.next;
- X if (t = nil) or (t^.kind <> tokminus) then
- X n2 := n1;
- X end;
- X if (t <> nil) and (t^.kind = tokminus) then
- X begin
- X t := t^.next;
- X if (t <> nil) and (t^.kind = toknum) then
- X begin
- X n2 := trunc(t^.num);
- X t := t^.next;
- X end
- X else
- X n2 := maxint;
- X end;
- X l := linebase;
- X while (l <> nil) and (l^.num <= n2) do
- X begin
- X if (l^.num >= n1) then
- X begin
- X write(l^.num:1, ' ');
- X listtokens(output, l^.txt);
- X writeln;
- X end;
- X l := l^.next;
- X end;
- X if not iseos then
- X require(tokcomma);
- X until iseos;
- X end;
- X
- X
- X procedure cmdload(merging : boolean; name : string255);
- X var
- X f : text;
- X buf : tokenptr;
- X begin
- X if not merging then
- X cmdnew;
- X reset(f, name + '.TEXT', 'shared');
- X while not eof(f) do
- X begin
- X readln(f, inbuf^);
- X parseinput(buf);
- X if curline = 0 then
- X begin
- X writeln('Bad line in file');
- X disposetokens(buf);
- X end;
- X end;
- X close(f);
- X end;
- X
- X
- X procedure cmdrun;
- X var
- X l : lineptr;
- X i : integer;
- X s : string255;
- X begin
- X l := linebase;
- X if not iseos then
- X begin
- X if t^.kind = toknum then
- X l := mustfindline(intexpr)
- X else
- X begin
- X s := stringexpr;
- X i := 0;
- X if not iseos then
- X begin
- X require(tokcomma);
- X i := intexpr;
- X end;
- X checkextra;
- X cmdload(false, s);
- X if i = 0 then
- X l := linebase
- X else
- X l := mustfindline(i)
- X end
- X end;
- X stmtline := l;
- X gotoflag := true;
- X clearvars;
- X clearloops;
- X restoredata;
- X end;
- X
- X
- X procedure cmdsave;
- X var
- X f : text;
- X l : lineptr;
- X begin
- X rewrite(f, stringexpr + '.TEXT');
- X l := linebase;
- X while l <> nil do
- X begin
- X write(f, l^.num:1, ' ');
- X listtokens(f, l^.txt);
- X writeln(f);
- X l := l^.next;
- X end;
- X close(f, 'save');
- X end;
- X
- X
- X procedure cmdbye;
- X begin
- X exitflag := true;
- X end;
- X
- X
- X procedure cmddel;
- X var
- X l, l0, l1 : lineptr;
- X n1, n2 : integer;
- X begin
- X repeat
- X if iseos then snerr;
- X n1 := 0;
- X n2 := maxint;
- X if (t <> nil) and (t^.kind = toknum) then
- X begin
- X n1 := trunc(t^.num);
- X t := t^.next;
- X if (t = nil) or (t^.kind <> tokminus) then
- X n2 := n1;
- X end;
- X if (t <> nil) and (t^.kind = tokminus) then
- X begin
- X t := t^.next;
- X if (t <> nil) and (t^.kind = toknum) then
- X begin
- X n2 := trunc(t^.num);
- X t := t^.next;
- X end
- X else
- X n2 := maxint;
- X end;
- X l := linebase;
- X l0 := nil;
- X while (l <> nil) and (l^.num <= n2) do
- X begin
- X l1 := l^.next;
- X if (l^.num >= n1) then
- X begin
- X if l = stmtline then
- X begin
- X cmdend;
- X clearloops;
- X restoredata;
- X end;
- X if l0 = nil then
- X linebase := l^.next
- X else
- X l0^.next := l^.next;
- X disposetokens(l^.txt);
- X dispose(l);
- X end
- X else
- X l0 := l;
- X l := l1;
- X end;
- X if not iseos then
- X require(tokcomma);
- X until iseos;
- X end;
- X
- X
- X procedure cmdrenum;
- X var
- X l, l1 : lineptr;
- X tok : tokenptr;
- X lnum, step : integer;
- X begin
- X lnum := 10;
- X step := 10;
- X if not iseos then
- X begin
- X lnum := intexpr;
- X if not iseos then
- X begin
- X require(tokcomma);
- X step := intexpr;
- X end;
- X end;
- X l := linebase;
- X if l <> nil then
- X begin
- X while l <> nil do
- X begin
- X l^.num2 := lnum;
- X lnum := lnum + step;
- X l := l^.next;
- X end;
- X l := linebase;
- X repeat
- X tok := l^.txt;
- X repeat
- X if tok^.kind in [tokgoto, tokgosub, tokthen, tokelse,
- X tokrun, toklist, tokrestore, tokdel] then
- X while (tok^.next <> nil) and (tok^.next^.kind = toknum) do
- X begin
- X tok := tok^.next;
- X lnum := round(tok^.num);
- X l1 := linebase;
- X while (l1 <> nil) and (l1^.num <> lnum) do
- X l1 := l1^.next;
- X if l1 = nil then
- X writeln('Undefined line ', lnum:1, ' in line ', l^.num2:1)
- X else
- X tok^.num := l1^.num2;
- X if (tok^.next <> nil) and (tok^.next^.kind = tokcomma) then
- X tok := tok^.next;
- X end;
- X tok := tok^.next;
- X until tok = nil;
- X l := l^.next;
- X until l = nil;
- X l := linebase;
- X while l <> nil do
- X begin
- X l^.num := l^.num2;
- X l := l^.next;
- X end;
- X end;
- X end;
- X
- X
- X procedure cmdprint;
- X var
- X semiflag : boolean;
- X n : valrec;
- X begin
- X semiflag := false;
- X while not iseos do
- X begin
- X semiflag := false;
- X if t^.kind in [toksemi, tokcomma] then
- X begin
- X semiflag := true;
- X t := t^.next;
- X end
- X else
- X begin
- X n := expr;
- X if n.stringval then
- X begin
- X write(n.sval^);
- X dispose(n.sval);
- X end
- X else
- X write(numtostr(n.val), ' ');
- X end;
- X end;
- X if not semiflag then
- X writeln;
- X end;
- X
- X
- X procedure cmdinput;
- X var
- X v : varptr;
- X s : string255;
- X tok, tok0, tok1 : tokenptr;
- X strflag : boolean;
- X begin
- X if (t <> nil) and (t^.kind = tokstr) then
- X begin
- X write(t^.sp^);
- X t := t^.next;
- X require(toksemi);
- X end
- X else
- X begin
- X write('? ');
- X end;
- X tok := t;
- X if (t = nil) or (t^.kind <> tokvar) then snerr;
- X strflag := t^.vp^.stringvar;
- X repeat
- X if (t <> nil) and (t^.kind = tokvar) then
- X if t^.vp^.stringvar <> strflag then snerr;
- X t := t^.next;
- X until iseos;
- X t := tok;
- X if strflag then
- X begin
- X repeat
- X readln(s);
- X v := findvar;
- END_OF_FILE
- if test 48192 -ne `wc -c <'examples/basic.p.1'`; then
- echo shar: \"'examples/basic.p.1'\" unpacked with wrong size!
- fi
- # end of 'examples/basic.p.1'
- fi
- echo shar: End of archive 19 \(of 32\).
- cp /dev/null ark19isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 32 archives.
- echo "Now see PACKNOTES and the README"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-