home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 February
/
Chip_2000-02_cd.bin
/
zkuste
/
Delphi
/
navody
/
tt
/
pasint.txt
< prev
next >
Wrap
Text File
|
1999-11-22
|
27KB
|
914 lines
(*Assembler and interpreter of Pascal code*)
(*K. Jensen, N. Wirth, Ch. Jacobi, ETH May 76*)
program pcode(input,output,prd,prr);
(* Note for the implementation.
===========================
This interpreter is written for the case where all the fundamental types
take one storage unit.
In an actual implementation, the handling of the sp pointer has to take
into account the fact that the types may have lengths different from one:
in push and pop operations the sp has to be increased and decreased not
by 1, but by a number depending on the type concerned.
However, where the number of units of storage has been computed by the
compiler, the value must not be corrected, since the lengths of the types
involved have already been taken into account.
*)
label 1;
const codemax = 8650;
pcmax = 17500;
maxstk = 13650; (* size of variable store *)
overi = 13655; (* size of integer constant table = 5 *)
overr = 13660; (* size of real constant table = 5 *)
overs = 13730; (* size of set constant table = 70 *)
overb = 13820;
overm = 18000;
maxstr = 18001;
largeint = 26144;
begincode = 3;
inputadr = 5;
outputadr = 6;
prdadr = 7;
prradr = 8;
duminst = 62;
type bit4
= 0..15;
bit6
= 0..127;
bit20 = -26143..26143;
datatype = (undef,int,reel,bool,sett,adr,mark,car);
address = -1..maxstr;
beta
= packed array[1..25] of char; (*error message*)
settype = set of 0..58;
alfa = packed array[1..10] of char;
var code
: array[0..codemax] of (* the program *)
packed record op1 :bit6;
p1 :bit4;
q1 :bit20;
op2 :bit6;
p2 :bit4;
q2 :bit20
end;
pc
: 0..pcmax;
(*program address register*)
op : bit6; p : bit4; q : bit20; (*instruction register*)
store
: array [0..overm] of
record case datatype of
int
:(vi :integer);
reel :(vr :real);
bool :(vb :boolean);
sett :(vs :settype);
car
:(vc :char);
adr
:(va :address);
(*address in store*)
mark :(vm :integer)
end;
mp,sp,np,ep : address; (* address registers *)
(*mp points to beginning of a data segment
sp points to top of the stack
ep points to the maximum extent of the stack
np points to top of the dynamically allocated area*)
interpreting: boolean;
prd,prr : text;(*prd for read only, prr for write only *)
instr : array[bit6] of alfa; (* mnemonic instruction codes *)
cop
: array[bit6] of integer;
sptable : array[0..20] of alfa; (*standard functions and procedures*)
(*locally used for interpreting one instruction*)
ad,ad1 : address;
b
: boolean;
i,j,i1,i2 : integer;
c
: char;
(*--------------------------------------------------------------------*)
procedure load;
const maxlabel = 1850;
type labelst = (entered,defined); (*label situation*)
labelrg = 0..maxlabel; (*label range*)
labelrec = record
val: address;
st: labelst
end;
var icp,rcp,scp,bcp,mcp : address; (*pointers to next free position*)
word : array[1..10] of char; i : integer; ch : char;
labeltab: array[labelrg] of labelrec;
labelvalue: address;
procedure init;
var i: integer;
begin instr[ 0]:='lod '; instr[ 1]:='ldo ';
instr[ 2]:='str '; instr[ 3]:='sro ';
instr[ 4]:='lda '; instr[ 5]:='lao ';
instr[ 6]:='sto '; instr[ 7]:='ldc ';
instr[ 8]:='... '; instr[ 9]:='ind ';
instr[10]:='inc '; instr[11]:='mst ';
instr[12]:='cup '; instr[13]:='ent ';
instr[14]:='ret '; instr[15]:='csp ';
instr[16]:='ixa '; instr[17]:='equ ';
instr[18]:='neq '; instr[19]:='geq ';
instr[20]:='grt '; instr[21]:='leq ';
instr[22]:='les '; instr[23]:='ujp ';
instr[24]:='fjp '; instr[25]:='xjp ';
instr[26]:='chk '; instr[27]:='eof ';
instr[28]:='adi '; instr[29]:='adr ';
instr[30]:='sbi '; instr[31]:='sbr ';
instr[32]:='sgs '; instr[33]:='flt ';
instr[34]:='flo '; instr[35]:='trc ';
instr[36]:='ngi '; instr[37]:='ngr ';
instr[38]:='sqi '; instr[39]:='sqr ';
instr[40]:='abi '; instr[41]:='abr ';
instr[42]:='not '; instr[43]:='and ';
instr[44]:='ior '; instr[45]:='dif ';
instr[46]:='int '; instr[47]:='uni ';
instr[48]:='inn '; instr[49]:='mod ';
instr[50]:='odd '; instr[51]:='mpi ';
instr[52]:='mpr '; instr[53]:='dvi ';
instr[54]:='dvr '; instr[55]:='mov ';
instr[56]:='lca '; instr[57]:='dec ';
instr[58]:='stp '; instr[59]:='ord ';
instr[60]:='chr '; instr[61]:='ujc ';
sptable[ 0]:='get '; sptable[ 1]:='put ';
sptable[ 2]:='rst '; sptable[ 3]:='rln ';
sptable[ 4]:='new '; sptable[ 5]:='wln ';
sptable[ 6]:='wrs '; sptable[ 7]:='eln ';
sptable[ 8]:='wri '; sptable[ 9]:='wrr ';
sptable[10]:='wrc '; sptable[11]:='rdi ';
sptable[12]:='rdr '; sptable[13]:='rdc ';
sptable[14]:='sin '; sptable[15]:='cos ';
sptable[16]:='exp '; sptable[17]:='log ';
sptable[18]:='sqt '; sptable[19]:='atn ';
sptable[20]:='sav ';
cop[ 0] := 105; cop[ 1] := 65;
cop[ 2] := 70; cop[ 3] := 75;
cop[ 6] := 80; cop[ 9] := 85;
cop[10] := 90; cop[26] := 95;
cop[57] := 100;
pc := begincode;
icp := maxstk + 1;
rcp := overi + 1;
scp := overr + 1;
bcp := overs + 2;
mcp := overb + 1;
for i:= 1 to 10 do word[i]:= ' ';
for i:= 0 to maxlabel do
with labeltab[i] do begin val:=-1; st:= entered end;
reset(prd);
end;(*init*)
procedure errorl(string: beta); (*error in loading*)
begin writeln;
write(string);
halt
end; (*errorl*)
procedure update(x: labelrg); (*when a label definition lx is found*)
var curr,succ: -1..pcmax; (*resp. current element and successor element
of a list of future references*)
endlist: boolean;
begin
if labeltab[x].st=defined then errorl(' duplicated label
')
else begin
if labeltab[x].val<>-1 then (*forward reference(s)*)
begin curr:= labeltab[x].val; endlist:= false;
while not endlist do
with code[curr div 2] do
begin
if odd(curr) then begin succ:= q2;
q2:= labelvalue
end
else begin succ:= q1;
q1:= labelvalue
end;
if succ=-1 then endlist:= true
else curr:= succ
end;
end;
labeltab[x].st := defined;
labeltab[x].val:= labelvalue;
end
end;(*update*)
procedure assemble; forward;
procedure generate;(*generate segment of code*)
var x: integer; (* label number *)
again: boolean;
begin
again := true;
while again do
begin read(prd,ch);(* first character of line*)
case ch of
'i': readln(prd);
'l': begin read(prd,x);
if not eoln(prd) then read(prd,ch);
if ch='=' then read(prd,labelvalue)
else labelvalue:= pc;
update(x); readln(prd);
end;
'q': begin again := false; readln(prd) end;
' ': begin read(prd,ch); assemble end
end;
end
end; (*generate*)
procedure assemble; (*translate symbolic code into machine code and store*)
label 1;
(*goto 1 for instructions without code generation*)
var name :alfa; b :boolean; r :real; s :settype;
c1 :char; i,s1,lb,ub :integer;
procedure lookup(x: labelrg); (* search in label table*)
begin case labeltab[x].st of
entered: begin q := labeltab[x].val;
labeltab[x].val := pc
end;
defined: q:= labeltab[x].val
end(*case label..*)
end;(*lookup*)
procedure labelsearch;
var x: labelrg;
begin while (ch<>'l') and not eoln(prd) do read(prd,ch);
read(prd,x); lookup(x)
end;(*labelsearch*)
procedure getname;
begin word[1] := ch;
read(prd,word[2],word[3]);
if not eoln(prd) then read(prd,ch) (*next character*);
pack(word,1,name)
end; (*getname*)
procedure typesymbol;
var i: integer;
begin
if ch <> 'i' then
begin
case ch of
'a': i := 0;
'r': i := 1;
's': i := 2;
'b': i := 3;
'c': i := 4;
end;
op := cop[op]+i;
end;
end (*typesymbol*) ;
begin p := 0; q := 0; op := 0;
getname;
instr[duminst] := name;
while instr[op]<>name do op := op+1;
if op = duminst then errorl(' illegal instruction ');
case op of (* get parameters p,q *)
(*equ,neq,geq,grt,leq,les*)
17,18,19,
20,21,22: begin case ch of
'a': ; (*p = 0*)
'i': p := 1;
'r': p := 2;
'b': p := 3;
's': p := 4;
'c': p := 6;
'm': begin p := 5;
read(prd,q)
end
end
end;
(*lod,str*)
0,2: begin typesymbol; read(prd,p,q)
end;
4 (*lda*): read(prd,p,q);
12 (*cup*): begin read(prd,p); labelsearch end;
11 (*mst*): read(prd,p);
14 (*ret*): case ch of
'p': p:=0;
'i': p:=1;
'r': p:=2;
'c': p:=3;
'b': p:=4;
'a': p:=5
end;
(*lao,ixa,mov*)
5,16,55: read(prd,q);
(*ldo,sro,ind,inc,dec*)
1,3,9,10,57: begin typesymbol; read(prd,q)
end;
(*ujp,fjp,xjp*)
23,24,25: labelsearch;
13 (*ent*): begin read(prd,p); labelsearch end;
15 (*csp*): begin for i:=1 to 9 do read(prd,ch); getname;
while name<>sptable[q] do q := q+1
end;
7 (*ldc*): begin case ch of (*get q*)
'i': begin p := 1; read(prd,i);
if abs(i)>=largeint then
begin op := 8;
store[icp].vi := i; q := maxstk;
repeat q := q+1 until store[q].vi=i;
if q=icp then
begin icp := icp+1;
if icp=overi then
errorl(' integer table overflow ');
end
end else q := i
end;
'r': begin op := 8; p := 2;
read(prd,r);
store[rcp].vr := r; q := overi;
repeat q := q+1 until store[q].vr=r;
if q=rcp then
begin rcp := rcp+1;
if rcp = overr then
errorl(' real table overflow ');
end
end;
'n': ; (*p,q = 0*)
'b': begin p := 3; read(prd,q) end;
'c': begin p := 6;
repeat read(prd,ch); until ch <> ' ';
if ch <> '''' then
errorl(' illegal character ');
read(prd,ch); q := ord(ch);
read(prd,ch);
if ch <> '''' then
errorl(' illegal character ');
end;
'(': begin op := 8; p := 4;
s := [ ]; read(prd,ch);
while ch<>')' do
begin read(prd,s1,ch); s := s + [s1]
end;
store[scp].vs := s; q := overr;
repeat q := q+1 until store[q].vs=s;
if q=scp then
begin scp := scp+1;
if scp=overs then
errorl(' set table overflow ');
end
end
end (*case*)
end;
26 (*chk*): begin typesymbol;
read(prd,lb,ub);
if op = 95 then q := lb
else
begin
store[bcp-1].vi := lb; store[bcp].vi := ub;
q := overs;
repeat q := q+2
until (store[q-1].vi=lb)and (store[q].vi=ub);
if q=bcp then
begin bcp := bcp+2;
if bcp=overb then
errorl(' boundary table overflow ');
end
end
end;
56 (*lca*): begin
if mcp + 16 >= overm then
errorl(' multiple table overflow ');
mcp := mcp+16;
q := mcp;
for i := 0 to 15 (*stringlgth*) do
begin read(prd,ch);
store[q+i].vc := ch
end;
end;
6 (*sto*): typesymbol;
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,58: ;
(*ord,chr*)
59,60: goto 1;
61 (*ujc*): ; (*must have same length as ujp*)
end; (*case*)
(* store instruction *)
with code[pc div 2] do
if odd(pc) then
begin op2 := op; p2 := p; q2 := q
end else
begin op1 := op; p1 := p; q1 := q
end;
pc := pc+1;
1: readln(prd);
end; (*assemble*)
begin (*load*)
init;
generate;
pc := 0;
generate;
end; (*load*)
(*------------------------------------------------------------------------*)
procedure pmd;
var s :integer; i: integer;
procedure pt;
begin write(s:6);
if abs(store[s].vi) < maxint then write(store[s].vi)
else write('too big ');
s := s - 1;
i := i + 1;
if i = 4 then
begin writeln(output); i := 0 end;
end; (*pt*)
begin
write(' pc =',pc-1:5,' op =',op:3,' sp =',sp:5,' mp =',mp:5,
' np =',np:5);
writeln; writeln('--------------------------------------');
s := sp; i := 0;
while s>=0 do pt;
s := maxstk;
while s>=np do pt;
end; (*pmd*)
procedure errori(string: beta);
begin writeln; writeln(string);
pmd; goto 1
end;(*errori*)
function base(ld :integer):address;
var ad :address;
begin ad := mp;
while ld>0 do
begin ad := store[ad+1].vm; ld := ld-1
end;
base := ad
end; (*base*)
procedure compare;
(*comparing is only correct if result by comparing integers will be*)
begin
i1 := store[sp].va;
i2 := store[sp+1].va;
i := 0; b := true;
while b and (i<>q) do
if store[i1+i].vi = store[i2+i].vi then i := i+1
else b := false
end; (*compare*)
procedure callsp;
var line: boolean; adptr,adelnt: address;
i: integer;
procedure readi(var f:text);
var ad: address;
begin ad:= store[sp-1].va;
read(f,store[ad].vi);
store[store[sp].va].vc := f^;
sp:= sp-2
end;(*readi*)
procedure readr(var f: text);
var ad: address;
begin ad:= store[sp-1].va;
read(f,store[ad].vr);
store[store[sp].va].vc := f^;
sp:= sp-2
end;(*readr*)
procedure readc(var f: text);
var c: char; ad: address;
begin read(f,c);
ad:= store[sp-1].va;
store[ad].vc := c;
store[store[sp].va].vc := f^;
store[store[sp].va].vi := ord(f^);
sp:= sp-2
end;(*readc*)
procedure writestr(var f: text);
var i,j,k: integer;
ad: address;
begin ad:= store[sp-3].va;
k := store[sp-2].vi; j := store[sp-1].vi;
(* j and k are numbers of characters *)
if k>j then for i:=1 to k-j do write(f,' ')
else j:= k;
for i := 0 to j-1 do write(f,store[ad+i].vc);
sp:= sp-4
end;(*writestr*)
procedure getfile(var f: text);
var ad: address;
begin ad:=store[sp].va;
get(f); store[ad].vc := f^;
sp:=sp-1
end;(*getfile*)
procedure putfile(var f: text);
var ad: address;
begin ad:= store[sp].va;
f^:= store[ad].vc; put(f);
sp:= sp-1;
end;(*putfile*)
begin (*callsp*)
case q of
0 (*get*): case store[sp].va of
5: getfile(input);
6: errori(' get on output file ');
7: getfile(prd);
8: errori(' get on prr file
')
end;
1 (*put*): case store[sp].va of
5: errori(' put on read file
');
6: putfile(output);
7: errori(' put on prd file
');
8: putfile(prr)
end;
2 (*rst*): begin
(*for testphase*)
np := store[sp].va; sp := sp-1
end;
3 (*rln*): begin case store[sp].va of
5: begin readln(input);
store[inputadr].vc := input^
end;
6: errori(' readln on output file ');
7: begin readln(input);
store[inputadr].vc := input^
end;
8: errori(' readln on prr file ')
end;
sp:= sp-1
end;
4 (*new*): begin ad:= np-store[sp].va;
(*top of stack gives the length in units of storage *)
if ad <= ep then
errori(' store overflow
');
np:= ad; ad:= store[sp-1].va;
store[ad].va := np;
sp:=sp-2
end;
5 (*wln*): begin case store[sp].va of
5: errori(' writeln on input file ');
6: writeln(output);
7: errori(' writeln on prd file ');
8: writeln(prr)
end;
sp:= sp-1
end;
6 (*wrs*): case store[sp].va of
5: errori(' write on input file ');
6: writestr(output);
7: errori(' write on prd file ');
8: writestr(prr)
end;
7 (*eln*): begin case store[sp].va of
5: line:= eoln(input);
6: errori(' eoln output file
');
7: line:=eoln(prd);
8: errori(' eoln on prr file
')
end;
store[sp].vb := line
end;
8 (*wri*): begin case store[sp].va of
5: errori(' write on input file ');
6: write(output,
store[sp-2].vi: store[sp-1].vi);
7: errori(' write on prd file ');
8: write(prr,
store[sp-2].vi: store[sp-1].vi)
end;
sp:=sp-3
end;
9 (*wrr*): begin case store[sp].va of
5: errori(' write on input file ');
6: write(output,
store[sp-2].vr: store[sp-1].vi);
7: errori(' write on prd file ');
8: write(prr,
store[sp-2].vr: store[sp-1].vi)
end;
sp:=sp-3
end;
10(*wrc*): begin case store[sp].va of
5: errori(' write on input file ');
6: write(output,store[sp-2].vc:
store[sp-1].vi);
7: errori(' write on prd file ');
8: write(prr,chr(store[sp-2].vi):
store[sp-1].vi);
end;
sp:=sp-3
end;
11(*rdi*): case store[sp].va of
5: readi(input);
6: errori(' read on output file ');
7: readi(prd);
8: errori(' read on prr file
')
end;
12(*rdr*): case store[sp].va of
5: readr(input);
6: errori(' read on output file ');
7: readr(prd);
8: errori(' read on prr file
')
end;
13(*rdc*): case store[sp].va of
5: readc(input);
6: errori(' read on output file ');
7: readc(prd);
8: errori(' read on prr file
')
end;
14(*sin*): store[sp].vr:= sin(store[sp].vr);
15(*cos*): store[sp].vr:= cos(store[sp].vr);
16(*exp*): store[sp].vr:= exp(store[sp].vr);
17(*log*): store[sp].vr:= ln(store[sp].vr);
18(*sqt*): store[sp].vr:= sqrt(store[sp].vr);
19(*atn*): store[sp].vr:= arctan(store[sp].vr);
20(*sav*): begin ad:=store[sp].va;
store[ad].va := np;
sp:= sp-1
end;
end;(*case q*)
end;(*callsp*)
begin (* main *)
rewrite(prr);
load; (* assembles and stores code *)
(* writeln(output); for testing *)
pc := 0; sp := -1; mp := 0; np := maxstk+1; ep := 5;
store[inputadr].vc := input^;
store[prdadr].vc := prd^;
interpreting := true;
while interpreting do
begin
(*fetch*)
with code[pc div 2] do
if odd(pc) then
begin op := op2; p := p2; q := q2
end else
begin op := op1; p := p1; q := q1
end;
pc := pc+1;
(*execute*)
case op of
105,106,107,108,109,
0 (*lod*): begin ad := base(p) + q;
sp := sp+1;
store[sp] := store[ad]
end;
65,66,67,68,69,
1 (*ldo*): begin
sp := sp+1;
store[sp] := store[q]
end;
70,71,72,73,74,
2 (*str*): begin store[base(p)+q] := store[sp];
sp := sp-1
end;
75,76,77,78,79,
3 (*sro*): begin store[q] := store[sp];
sp := sp-1
end;
4 (*lda*): begin sp := sp+1;
store[sp].va := base(p) + q
end;
5 (*lao*): begin sp := sp+1;
store[sp].va := q
end;
80,81,82,83,84,
6 (*sto*): begin
store[store[sp-1].va] := store[sp];
sp := sp-2;
end;
7 (*ldc*): begin sp := sp+1;
if p=1 then
begin store[sp].vi := q;
end else
if p = 6 then store[sp].vc := chr(q)
else
if p = 3 then store[sp].vb := q = 1
else (* load nil *) store[sp].va := maxstr
end;
8 (*lci*): begin sp := sp+1;
store[sp] := store[q]
end;
85,86,87,88,89,
9 (*ind*): begin ad := store[sp].va + q;
(* q is a number of storage units *)
store[sp] := store[ad]
end;
90,91,92,93,94,
10 (*inc*): store[sp].vi := store[sp].vi+q;
11 (*mst*): begin (*p=level of calling procedure minus level of called
procedure + 1; set dl and sl, increment sp*)
(* then length of this element is
max(intsize,realsize,boolsize,charsize,ptrsize *)
store[sp+2].vm := base(p);
(* the length of this element is ptrsize *)
store[sp+3].vm := mp;
(* idem *)
store[sp+4].vm := ep;
(* idem *)
sp := sp+5
end;
12 (*cup*): begin (*p=no of locations for parameters, q=entry point*)
mp := sp-(p+4);
store[mp+4].vm := pc;
pc := q
end;
13 (*ent*): if p = 1 then
begin sp := mp + q; (*q = length of dataseg*)
if sp > np then errori(' store overflow
');
end
else
begin ep := sp+q;
if ep > np then errori(' store overflow
');
end;
(*q = max space required on stack*)
14 (*ret*): begin case p of
0: sp:= mp-1;
1,2,3,4,5: sp:= mp
end;
pc := store[mp+4].vm;
ep := store[mp+3].vm;
mp:= store[mp+2].vm;
end;
15 (*csp*): callsp;
16 (*ixa*): begin
i := store[sp].vi;
sp := sp-1;
store[sp].va := q*i+store[sp].va;
end;
17 (*equ*): begin sp := sp-1;
case p of
1: store[sp].vb := store[sp].vi = store[sp+1].vi;
0: store[sp].vb := store[sp].va = store[sp+1].va;
6: store[sp].vb := store[sp].vc = store[sp+1].vc;
2: store[sp].vb := store[sp].vr = store[sp+1].vr;
3: store[sp].vb := store[sp].vb = store[sp+1].vb;
4: store[sp].vb := store[sp].vs = store[sp+1].vs;
5: begin compare;
store[sp].vb := b;
end;
end; (*case p*)
end;
18 (*neq*): begin sp := sp-1;
case p of
0: store[sp].vb := store[sp].va <> store[sp+1].va;
1: store[sp].vb := store[sp].vi <> store[sp+1].vi;
6: store[sp].vb := store[sp].vc <> store[sp+1].vc;
2: store[sp].vb := store[sp].vr <> store[sp+1].vr;
3: store[sp].vb := store[sp].vb <> store[sp+1].vb;
4: store[sp].vb := store[sp].vs <> store[sp+1].vs;
5: begin compare;
store[sp].vb := not b;
end
end; (*case p*)
end;
19 (*geq*): begin sp := sp-1;
case p of
0: errori(' <,<=,>,>= for address ');
1: store[sp].vb := store[sp].vi >= store[sp+1].vi;
6: store[sp].vb := store[sp].vc >= store[sp+1].vc;
2: store[sp].vb := store[sp].vr >= store[sp+1].vr;
3: store[sp].vb := store[sp].vb >= store[sp+1].vb;
4: store[sp].vb := store[sp].vs >= store[sp+1].vs;
5: begin compare;
store[sp].vb := b or
(store[i1+i].vi >= store[i2+i].vi)
end
end; (*case p*)
end;
20 (*grt*): begin sp := sp-1;
case p of
0: errori(' <,<=,>,>= for address ');
1: store[sp].vb := store[sp].vi > store[sp+1].vi;
6: store[sp].vb := store[sp].vc > store[sp+1].vc;
2: store[sp].vb := store[sp].vr > store[sp+1].vr;
3: store[sp].vb := store[sp].vb > store[sp+1].vb;
4: errori(' set inclusion
');
5: begin compare;
store[sp].vb := not b and
(store[i1+i].vi > store[i2+i].vi)
end
end; (*case p*)
end;
21 (*leq*): begin sp := sp-1;
case p of
0: errori(' <,<=,>,>= for address ');
1: store[sp].vb := store[sp].vi <= store[sp+1].vi;
6: store[sp].vb := store[sp].vc <= store[sp+1].vc;
2: store[sp].vb := store[sp].vr <= store[sp+1].vr;
3: store[sp].vb := store[sp].vb <= store[sp+1].vb;
4: store[sp].vb := store[sp].vs <= store[sp+1].vs;
5: begin compare;
store[sp].vb := b or
(store[i1+i].vi <= store[i2+i].vi)
end;
end; (*case p*)
end;
22 (*les*): begin sp := sp-1;
case p of
0: errori(' <,<=,>,>= for address ');
1: store[sp].vb := store[sp].vi < store[sp+1].vi;
6: store[sp].vb := store[sp].vc < store[sp+1].vc;
2: store[sp].vb := store[sp].vr < store[sp+1].vr;
3: store[sp].vb := store[sp].vb < store[sp+1].vb;
5: begin compare;
store[sp].vb := not b and
(store[i1+i].vi < store[i2+i].vi)
end
end; (*case p*)
end;
23 (*ujp*): pc := q;
24 (*fjp*): begin if not store[sp].vb then pc := q;
sp := sp-1
end;
25 (*xjp*): begin
pc := store[sp].vi + q;
sp := sp-1
end;
95 (*chka*): if (store[sp].va < np) or
(store[sp].va > (maxstr-q)) then
errori(' bad pointer value ');
96,97,98,99,
26 (*chk*): if (store[sp].vi < store[q-1].vi) or
(store[sp].vi > store[q].vi) then
errori(' value out of range ');
27 (*eof*): begin i := store[sp].vi;
if i=inputadr then
begin store[sp].vb := eof(input);
end else errori(' code in error
')
end;
28 (*adi*): begin sp := sp-1;
store[sp].vi := store[sp].vi + store[sp+1].vi
end;
29 (*adr*): begin sp := sp-1;
store[sp].vr := store[sp].vr + store[sp+1].vr
end;
30 (*sbi*): begin sp := sp-1;
store[sp].vi := store[sp].vi - store[sp+1].vi
end;
31 (*sbr*): begin sp := sp-1;
store[sp].vr := store[sp].vr - store[sp+1].vr
end;
32 (*sgs*): store[sp].vs := [store[sp].vi];
33 (*flt*): store[sp].vr := store[sp].vi;
34 (*flo*): store[sp-1].vr := store[sp-1].vi;
35 (*trc*): store[sp].vi := trunc(store[sp].vr);
36 (*ngi*): store[sp].vi := -store[sp].vi;
37 (*ngr*): store[sp].vr := -store[sp].vr;
38 (*sqi*): store[sp].vi := sqr(store[sp].vi);
39 (*sqr*): store[sp].vr := sqr(store[sp].vr);
40 (*abi*): store[sp].vi := abs(store[sp].vi);
41 (*abr*): store[sp].vr := abs(store[sp].vr);
42 (*not*): store[sp].vb := not store[sp].vb;
43 (*and*): begin sp := sp-1;
store[sp].vb := store[sp].vb and store[sp+1].vb
end;
44 (*ior*): begin sp := sp-1;
store[sp].vb := store[sp].vb or store[sp+1].vb
end;
45 (*dif*): begin sp := sp-1;
store[sp].vs := store[sp].vs - store[sp+1].vs
end;
46 (*int*): begin sp := sp-1;
store[sp].vs := store[sp].vs * store[sp+1].vs
end;
47 (*uni*): begin sp := sp-1;
store[sp].vs := store[sp].vs + store[sp+1].vs
end;
48 (*inn*): begin
sp := sp - 1; i := store[sp].vi;
store[sp].vb := i in store[sp+1].vs;
end;
49 (*mod*): begin sp := sp-1;
store[sp].vi := store[sp].vi mod store[sp+1].vi
end;
50 (*odd*): store[sp].vb := odd(store[sp].vi);
51 (*mpi*): begin sp := sp-1;
store[sp].vi := store[sp].vi * store[sp+1].vi
end;
52 (*mpr*): begin sp := sp-1;
store[sp].vr := store[sp].vr * store[sp+1].vr
end;
53 (*dvi*): begin sp := sp-1;
store[sp].vi := store[sp].vi div store[sp+1].vi
end;
54 (*dvr*): begin sp := sp-1;
store[sp].vr := store[sp].vr / store[sp+1].vr
end;
55 (*mov*): begin i1 := store[sp-1].va;
i2 := store[sp].va; sp := sp-2;
for i := 0 to q-1 do store[i1+i] := store[i2+i]
(* q is a number of storage units *)
end;
56 (*lca*): begin sp := sp+1;
store[sp].va := q;
end;
100,101,102,103,104,
57 (*dec*): store[sp].vi := store[sp].vi-q;
58 (*stp*): interpreting := false;
59 (*ord*): (*only used to change the tagfield*)
begin
end;
60 (*chr*): begin
end;
61 (*ujc*): errori(' case - error
');
end
end; (*while interpreting*)
1 :
end.