|
|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 13056 (0x3300)
Types: TextFile
Names: »esw«
└─⟦621cfb9a2⟧ Bits:30002817 RC8000 Dump tape fra HCØ. Detaljer om "HC8000" projekt.
└─⟦0364f57e3⟧
└─⟦this⟧ »esw«
program forth(input,output);
const
maxcol = 79;
maxstack = 999;
type
pparam = ^param;
param = record
content : integer;
next : pparam;
end;
pentry = ^entry;
entry = record
leng : integer;
name : alfa;
link : pentry;
code : integer;
next : pparam;
end;
pinteger = ^integer;
string = packed arrayÆ0..maxcolÅ of char;
var
ipc : pparam;
curpfa : pinteger;
sizein : integer;
sentry : pentry;
H0 : pentry;
H : pentry;
pfa : pinteger;
base : integer;
token : alfa;
finish : boolean;
stack : arrayÆ0..maxstackÅ of integer;
sidx : integer;
xstack : arrayÆ0..maxstackÅ of integer;
xsidx : integer;
line : string;
tidx : integer;
compilemode : boolean;
contab : arrayÆ0..63Å of char;
galias : record case integer of
1 : ( int : integer);
2 : ( pnt : pinteger);
3 : ( pp : pparam);
4 : ( pe : pentry);
end;
procedure execute;
forward;
function intable:integer;
forward;
procedure writetoken;
var
i : integer;
begin
for i:=1 to 12 do
write(tokenÆiÅ);
end;
\f
procedure readstring;
var
ch : char;
idx : integer;
begin
idx:=0;readln;
while not eoln(input) do
begin
if idx<=maxcol then
begin
read(input,ch);
if ch<>chr(0) then
lineÆidxÅ:=ch;
end;
idx:=idx+1;
end;
end;
procedure writestring(s:string);
var
idx : integer;
begin
for idx:=0 to maxcol do
if sÆidxÅ>chr(0) then write(sÆidxÅ);
writeln;
end;
procedure blankfill(var s:string);
var
idx : integer;
begin
for idx:=0 to maxcol do
sÆidxÅ:=chr(0);
end;
procedure error(no:integer);
var
i : integer;
begin
if no=2 then
for i:=1 to 12 do
write(tokenÆiÅ);
case no of
1 : writeln(" Stack underflow");
2 : writeln(' Undefined');
3 : writeln(' Address error ');
4 : writeln(' File');
5 : writeln(' Unexpected nil');
end;
end;
procedure clearline;
var
i : integer;
begin
for i:=0 to maxcol do
lineÆiÅ:=' ';
end;
procedure skipblanks;
begin
while (lineÆtidxÅ=' ') and (tidx<maxcol) do
tidx:=tidx+1;
end;
procedure getnext;
var
idx : integer;
i : integer;
begin
for i:=1 to 12 do
tokenÆiÅ:=' ';
idx:=1;sizein:=0;
while (tidx<maxcol) and (lineÆtidxÅ<>' ') and (lineÆtidxÅ<>chr(0)) do
begin
if idx<13 then
begin
tokenÆidxÅ:=lineÆtidxÅ;
idx:=idx+1;
end;
tidx:=tidx+1;
sizein:=sizein+1;
end;
end;
procedure entstdnames(std:boolean;n:alfa;c:integer);
var
e : pentry;
i,count : integer;
begin
if std then
begin
count:=0;
for i:=1 to 12 do
if nÆiÅ<>' ' then count:=count+1;
end
else
count:=sizein;
new(e);
if c=0 then sentry:=e; (* mark first entry *)
with e^ do
begin
leng:=count;
name:=n;
link:=H0;
code:=c;
next :=nil;
end;
H0:=e;
end;
procedure builddir;
begin
entstdnames(true,' ',0);
entstdnames(true,'2swap ',1);
entstdnames(true,'2drop ',2);
entstdnames(true,'2rot ',3);
entstdnames(true,'2dup ',4);
entstdnames(true,'2over ',5);
entstdnames(true,'swap ',6);
entstdnames(true,'drop ',7);
entstdnames(true,'rot ',8);
entstdnames(true,'dup ',9);
entstdnames(true,'over ',10);
entstdnames(true,'. ',11);
entstdnames(true,'+ ',12);
entstdnames(true,'- ',13);
entstdnames(true,'< ',14);
entstdnames(true,'> ',15);
entstdnames(true,'= ',16);
entstdnames(true,'^ ',17);
entstdnames(true,'base ',18);
entstdnames(true,': ',19);
entstdnames(true,'interpret ',20);
entstdnames(true,'; ',21);
entstdnames(true,''' ',22);
entstdnames(true,'! ',23);
entstdnames(true,'@ ',24);
entstdnames(true,'variable ',25);
entstdnames(true,'execute ',27);
entstdnames(true,'emit ',28);
entstdnames(true,'* ',29);
entstdnames(true,'exit ',30);
entstdnames(true,'/ ',31);
entstdnames(true,'constant ',32);
entstdnames(true,'forget ',34);
entstdnames(true,'literal ',35);
entstdnames(true,'p! ',36);
entstdnames(true,'p@ ',37);
entstdnames(true,'." ',38);
entstdnames(true,'" ',39);
entstdnames(true,'sliteral ',40);
end;
procedure push(item:integer);
begin
sidx:=sidx+1;
stackÆsidxÅ:=item;
end;
procedure pop(var item:integer);
begin
item:=0;
if sidx<0 then
begin
error(1);
sidx:=0;
end
else
begin
item:=stackÆsidxÅ;
sidx:=sidx-1;
end;
end;
procedure xpush(item:integer);
begin
xsidx:=xsidx+1;
xstackÆxsidxÅ:=item;
end;
procedure xpop(var item:integer);
begin
item:=xstackÆxsidxÅ;
xsidx:=xsidx-1;
end;
procedure load;
var
alias : record case boolean of
true : (int : integer);
false : (pnt : pinteger);
end;
a : integer;
begin
pop(alias.int);
push(alias.pnt^);
end;
procedure pload;
var
alias : record case boolean of
true : ( int : integer);
false : ( pnt : pinteger);
end;
a : integer;
begin
end;
procedure store;
var
alias : record case boolean of
true : (int : integer);
false : (pnt : pinteger);
end;
a : integer;
begin
pop(alias.int);
pop(a);
alias.pnt^:=a;
end;
procedure pstore;
begin
end;
procedure cvariable;
begin
galias.pnt:=curpfa;
push(ord(galias.pe^.next));
end;
procedure cconstant;
var p : pparam;
begin
galias.pnt:=curpfa;
p:=galias.pe^.next;
push(p^.content);
end;
procedure cnumber;
var
a : record case boolean of
true : (int : integer);
false : (pnt : pinteger);
end;
begin
push(ipc^.content);
ipc:=ipc^.next;
end;
procedure cstring;
var
a : record case boolean of
true : (int : integer);
false : (pnt : pinteger);
end;
l : integer;
i : integer;
begin
xpop(a.int);
l:=a.pnt^;
for i:=1 to l do
begin
a.int:=a.int+2;
write(chr(a.pnt^));
end;
xpush(a.int+2);
end;
procedure add;
var
a,b : integer;
begin
pop(a);
pop(b);
a:=a+b;
push(a);
end;
procedure subtract;
var
a,b : integer;
begin
pop(a);
pop(b);
b:=b-a;
push(b);
end;
procedure multiply;
var
a,b : integer;
begin
pop(a);
pop(b);
b:=b*a;
push(b);
end;
procedure divide;
var
a,b : integer;
begin
pop(a);
pop(b);
b:=b div a;
push(b);
end;
procedure less;
var
a,b : integer;
begin
pop(b);
pop(a);
if a<b then
a:=1
else
a:=0;
push(a);
end;
procedure gtr;
var
a,b : integer;
begin
pop(b);
pop(a);
if a>b then
a:=1
else
a:=0;
push(a);
end;
procedure eql;
var
a,b : integer;
begin
pop(a);
pop(b);
if a=b then
push(1)
else
push(0);
end;
(* relations *)
(* tos operations *)
procedure swap;
var
a,b : integer;
begin
pop(a);
pop(b);
push(a);
push(b);
end;
procedure drop;
var
a : integer;
begin
pop(a);
end;
procedure rotate;
var
a,i : integer;
begin
a:=stackÆ1Å;
for i:=2 to sidx do
stackÆi-1Å:=stackÆiÅ;
stackÆsidxÅ:=a;
end;
procedure dup;
var
a : integer;
begin
pop(a);
push(a);
push(a);
end;
procedure over;
var
a,b : integer;
begin
pop(a);
pop(b);
push(b);
push(a);
push(b);
end;
procedure swap2;
begin
end;
procedure drop2;
begin
end;
procedure rotate2;
begin
end;
procedure dup2;
begin
end;
procedure over2;
begin
end;
procedure dot;
var
a : integer;
begin
pop(a);
writeln(a:6);
end;
procedure emit;
var
a : integer;
begin
pop(a);
writeln(chr(a));
end;
procedure dotq;
var
pi : pinteger;
l : pinteger;
i,idx : integer;
begin
if compilemode then
begin
token:='sliteral ';
sizein:=8;
idx:=intable;
end
else
while lineÆtidxÅ<>'"' do
begin
write(lineÆtidxÅ);
tidx:=tidx+1;
end;
writeln;
end;
procedure shiftbase;
var
a : integer;
begin
pop(a);
base:=a;
end;
function intable;
var
found: boolean;
sizeofentry : integer;
p : pentry;
alias: record case integer of
0 : (int : integer);
1 : (pnt : pinteger);
2 : (pp : pentry);
end;
begin
p := h0;
intable := 0;found:=false;
sentry^.leng := sizein;
sentry^.name := token;
while not found do
begin
with p^ do
if leng = sizein then
begin
if name = token then
begin
found := true;
alias.pp := p;
pfa := alias.pnt;
if p^.code= 0 then
intable := 0
else
intable := alias.int;
end
else
p := link;
end
else
p := link;
end;
end;
procedure tick;
var
idx : integer;
begin
skipblanks;
getnext;
idx:=intable;
if idx>0 then
push(idx);
end;
procedure place(i:integer);
var
pe : pparam;
p : pparam;
begin
writeln(' placing ');
new(pe);
pe^.next:=nil;
if H0^.next=nil then
begin
H0^.next:=pe;
end
else
begin
p:=H0^.next;
while p^.next<>nil do
p:=p^.next;
p^.next:=pe;
end;
pe^.content:=i;
end;
procedure variable;
begin
skipblanks;
getnext;
entstdnames(false,token,26);
place(0);
end;
procedure constant;
var
a : integer;
i : pinteger;
begin
skipblanks;
getnext;
entstdnames(false,token,33);
pop(a);
new(i);
i^:=a;
end;
procedure forget;
begin
end;
procedure runcolon;
var
al : record case integer of
0: (int : integer);
1: ( pnt: pinteger);
2: (pa : pparam);
3: (pe : pentry);
end;
begin
xpush(ord(ipc));
al.pnt:=curpfa;
ipc:=al.pe^.next;
repeat
push(ipc^.content);
ipc:=ipc^.next;
execute;
until xstackÆxsidxÅ=1;
xpop(al.int);
xpop(al.int);
ipc:=al.pa;
end; (* end of runcolon *)
procedure interpret;
var
op : integer;
begin
runcolon;
end; (* end of runcolon *)
procedure codeexit;
var
iipc :integer;
begin
xpush(1);
end; (* end of codeexit *)
procedure compile;
var
idx : integer;
ie : pinteger;
begin
compilemode := true;
skipblanks;
getnext;
entstdnames(false,token,20);
end; (* end of compile *)
procedure execute;
var
alias : record case integer of
0 : (int : integer);
1 : (pnt : pinteger);
2 : (pp : pentry);
end;
begin
pop(alias.int);
curpfa:=alias.pnt;
if compilemode then
begin
place(ord(curpfa));
if alias.pp^.code=21 then
compilemode := false;
end
else
begin
(*
writeln(' exe ',alias.pp^.code:4);
*)
case alias.pp^.code of
1: swap2;
2: drop2;
3: rotate2;
4 : dup2;
5 : over2;
6 : swap;
7 : drop;
8 : rotate;
9 : dup;
10: over;
11: dot;
12: add;
13: subtract;
14: less;
15: gtr;
16: eql;
17: finish := true;
18: shiftbase;
19: compile;
20: interpret;
21: codeexit;
22: tick;
23: store;
24: load;
25: variable;
26: cvariable;
27: execute;
28: emit;
29: multiply;
30: codeexit;
31: divide;
32: constant;
33: cconstant;
34: forget;
35: cnumber;
36: pstore;
37: pload;
38: dotq;
39: ;
40: cstring;
end;
end;
end;
procedure scan;
var
i : integer;
idx : integer;
procedure gettoken;
var
top : integer;
function incontab(ch:char):integer;
var
i : integer;
begin
incontab:=-1;
for i:=0 to base-1 do
if ch=contabÆiÅ then
incontab:=i;
end;
function number:boolean;
var
nidx : integer;
inumber : integer;
pi : pinteger;
begin
number:=true;
nidx :=1;
if incontab(tokenÆnidxÅ)>-1 then
begin
inumber :=0;
while (incontab(tokenÆnidxÅ)>-1) and (nidx<13) do
begin
inumber:=inumber*base+incontab(tokenÆnidxÅ);
nidx:=nidx+1;
end;
if tokenÆnidxÅ<>' ' then
begin
number:=false;
end;
if compilemode then
begin
token:='literal ';
sizein:=7;
idx :=intable;
writeln(' Literal idx ',idx:5);
if idx>0 then
begin
place(idx);
place(inumber);
end;
end
else
push(inumber);
end
else
number:=false;
end;
begin
tidx:=0;
repeat
skipblanks;
if tidx<maxcol then
begin
getnext;
idx:=intable;
if idx>0 then
begin
push(idx);
execute;
end
else
if not number then
error(2);
end;
until (tidx>=maxcol) or (lineÆtidxÅ=chr(0));
end;
begin
for i:=1 to 12 do
tokenÆiÅ:=' ';
gettoken;
end;
procedure init;
var
i : integer;
begin
sidx:=0;
stackÆsidxÅ:=0;
xsidx:=0;
xstackÆxsidxÅ:=0;
H0:=nil;
H :=nil;
builddir;
base:=10;
compilemode:=false;
for i:=0 to 9 do
contabÆiÅ:=chr(48+i);
for i:=10 to 63 do
contabÆiÅ:=chr(55+i);
end;
begin (* main program *)
init;
repeat
finish:=false;
writeln;
writeln(' ready ');
blankfill(line);
readstring;
scan;
until finish;
end.
▶EOF◀