perm filename EPAR3D.2[EAL,HE]1 blob
sn#676487 filedate 1982-09-27 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00005 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 {$NOMAIN Editor: Reparsing routine & Stmnt delete routine }
C00006 00003 (* aux routine: addNewDeclarations *)
C00010 00004 (* aux routine: reParse *)
C00023 00005 (* delStmnt *)
C00036 ENDMK
C⊗;
{$NOMAIN Editor: Reparsing routine & Stmnt delete routine }
%include eparse.hdr;
{ Externally defined routines from elsewhere: }
(* From ALLOC *)
procedure relNode(n: nodep); external;
function newStatement: statementp; external;
(* From FREE *)
procedure freeNode(n: nodep); external;
procedure freeStatement(s: statementp); external;
(* From EROOT: Inter-overlay calls *)
function e3dExprParse: nodep; external;
(* From PAUX1 *)
function getDtype(n: nodep): datatypes; external;
function checkArg(n: nodep; d: datatypes): nodep; external;
(* From PAUX2 *)
function getdim(n: nodep; var d: nodep): nodep; external;
function evalOrder(what,last: nodep; pcons: boolean): nodep; external;
procedure relExpr(n: nodep); external;
(* From EAUX1A *)
procedure clearLine(i: integer); external;
procedure pushStmnt(s: statementp; indent: integer); external;
procedure pushNode(n: nodep); external;
procedure borderLines; external;
(* From EPUT *)
procedure putLine; external;
procedure putexpr(n: nodep; opp: integer); external;
(* From EAUX2A *)
procedure eMakeNewVar(newvar: varidefp); external;
procedure flushVar(oldvar: varidefp); external;
(* From EAUX2C *)
procedure displayLines(var pfrom: integer); external;
procedure insertLines(start,number,coff: integer); external;
procedure deleteLines(start,number,coff: integer); external;
(* From EPUTST *)
procedure putstmnt(s: statementp; indent, plevel: integer); external;
(* From EMOVEO *)
procedure moveOrder(st: statementp); external;
(* From ETOKEN *)
procedure eDimCheck(n,d: nodep); external;
(* From PP *)
procedure relLine(l: linerecp); external;
procedure ppLine; external;
procedure ppOutNow; external;
procedure ppChar(ch: ascii); external;
procedure pp5(ch: c5str; length: integer); external;
procedure pp10(ch: cstring; length: integer); external;
procedure pp10L(ch: cstring; length: integer); external;
procedure pp20(ch: c20str; length: integer); external;
procedure pp20L(ch: c20str; length: integer); external;
procedure ppInt(i: integer); external;
procedure ppReal(r: real); external;
procedure ppStrng(length: integer; s: strngp); external;
procedure ppDtype(d: datatypes); external;
procedure ppDelChar; external;
(* From DISP *)
procedure showCursor(line,col: integer); external;
procedure ePar3dGet; external;
procedure ePar3dGet; begin end;
(* aux routine: addNewDeclarations *)
function addNewDeclarations: integer; external;
function addNewDeclarations;
var s,sp: statementp; i,j,l: integer;
begin
l := 0;
if newDeclarations <> nil then
begin (* deal with any new declarations *)
s := newDeclarations;
while s↑.stype <> blocktype do (* find block they're in *)
begin sp := s; s := s↑.last; l := l + 1 end;
with s↑ do
begin
bcode↑.last := newDeclarations;
bcode := sp; (* splice us into block *)
end;
j := cursor;
i := 1;
while (j > i) do
with cursorStack[j] do
if stmntp and (st = s) then i := j
else begin cline := cline + l; j := j - 1; end;
with cursorStack[i] do
begin
if cline < lineNum then lineNum := lineNum + l;
if cline < topDline then
begin
topDline := topDline + l;
botDline := botDline + l;
for j := 1 to i do
with cursorStack[j] do (* update line counts *)
if stmntp then st↑.nlines := st↑.nlines + l;
end
else if cline < botDline then
begin
insertLines(cline+1,l,cursor-i);
curLine := cline; (* set up for putStmnt *)
firstLine := curLine + 1;
lastLine := curline + l;
s := s↑.bcode;
for j := 1 to l do
begin
if s↑.variables↑.vtype = undeftype then
begin
(* *** probably should ask the luser to define it, but... *** *)
s↑.variables↑.vtype := svaltype;
end;
(* *** especially need to ask for array bounds *** *)
(* *** & if procedure do something to set up a reasonable definition *** *)
putStmnt(s,ind,99); (* write out the declaration *)
eMakeNewVar(s↑.variables); (* if active block make env entry for var *)
s := s↑.next;
end;
putLine; (* force last line to be written out *)
end;
end;
cursorLine := cursorLine + l;
if ocur > 0 then ocur := ocur + l;
borderLines;
newDeclarations := nil;
end;
showCursor(cursorLine-topDline-firstDline+2,1);
addNewDeclarations := l;
end;
(* aux routine: reParse *)
procedure reParse(st: statementp); external;
procedure reParse;
var i: integer; v: varidefp; lexp: nodep;
procedure reParseAux(st: statementp);
var s: statementp; n,np: nodep; d: datatypes;
function reExpr(n,dim: nodep; d: datatypes): nodep;
var i: integer;
begin (* reExpr *)
if n <> nil then
begin
if (n↑.ntype = exprnode) or
((n↑.ntype = leafnode) and (n↑.ltype = varitype)) then
begin
lbufp := 0;
putExpr(n,0); (* write expression into lbuf *)
relExpr(n); (* flush old expression *)
for i := 1 to lbufp do (* copy expression for getToken *)
listing[i] := lbuf[i];
listing[lbufp+1] := ' ';
curChar := 1;
maxChar := lbufp + 1;
endOfLine := false;
eBackup := false;
expandMacros := true;
n := e3dExprParse; (* parse new expression *)
if n <> nil then
with n↑ do
if ntype = exprnode then elength := lbufp
else if (ntype = leafnode) and (ltype = svaltype) then wid := lbufp;
if d <> nulltype then n := checkArg(n,d); (* datatype still ok? *)
if dim <> nil then eDimCheck(n,dim); (* do dimensions still match? *)
end;
end;
reExpr := n;
end (* reExpr *);
procedure reCmon(st: statementp); forward;
procedure reClause(n: nodep);
var d: datatypes;
begin (* reClause *)
with n↑ do
case ntype of
deprnode,
apprnode,
destnode: begin
if ntype <> destnode then d := nulltype
else if st↑.stype = movetype then d := transtype
else d := svaltype;
loc := reExpr(loc,distancedim↑.dim,d);
reParseAux(code);
end;
viaptnode: begin
via := reExpr(via,distancedim↑.dim,transtype);
duration := reExpr(duration,timedim↑.dim,svaltype);
velocity := reExpr(velocity,veldim↑.dim,vectype);
reParseAux(code);
end;
durnode: begin
durval := reExpr(durval,timedim↑.dim,svaltype);
end;
sfacnode,
wobblenode,
swtnode: begin
clval := reExpr(clval,nil,svaltype);
end;
ffnode: begin
ff := reExpr(ff,nil,transtype);
end;
forcenode: begin
fval := reExpr(fval,nil,svaltype);
fvec := reExpr(fvec,nil,vectype);
if fframe <> nil then reClause(fframe);
end;
stiffnode: begin
fv := reExpr(fv,nil,vectype);
mv := reExpr(mv,nil,vectype);
coc := reExpr(coc,nil,transtype);
end;
cmonnode: begin
reCmon(cmon);
end;
otherwise {do nothing};
end;
end (* reClause *);
procedure reCmon (* st: statementp *);
begin (* reCmon *)
with st↑, oncond↑ do
begin
if (ntype = durnode) or (ntype = forcenode) then reClause(oncond)
else if (ntype = exprnode) or (ntype = leafnode) then
begin
oncond := reExpr(oncond,nil,nulltype);
exprCm := getDtype(oncond) <> eventtype;
end;
if exprCm or (ntype = durnode) or (ntype = forcenode) then
exprs := evalOrder(oncond,nil,true)
else if ntype = exprnode then (* subscripted event *)
exprs := evalOrder(arg2,nil,true)
else exprs := nil;
reParseAux(conclusion);
end;
end (* reCmon *);
begin (* reParseAux *)
if st <> nil then
with st↑ do
case stype of
blocktype: begin
pushStmnt(st,0); (* for var lookup *)
s := bcode;
while s <> nil do begin reParseAux(s); s := s↑.next end;
cursor := cursor - 1;
end;
declaretype: begin
with variables↑ do
if tbits = 2 then (* check for procedure *)
begin
pushNode(p); (* for var lookup *)
reParseAux(p↑.body);
cursor := cursor - 1;
end;
end;
coblocktype: begin
n := threads;
while n <> nil do begin reParseAux(n↑.cstmnt); n := n↑.next end;
end;
fortype: begin
forvar := reExpr(forvar,nil,svaltype);
n := nil;
n := getdim(forvar,n);
initial := reExpr(initial,n,svaltype);
step := reExpr(step,n,svaltype);
final := reExpr(final,n,svaltype);
relNode(n);
reParseAux(fbody);
with forvar↑ do
if ntype = leafnode then n := nil
else n := evalOrder(arg2,nil,true); (* push array subscripts *)
n := evalOrder(initial,n,true);
n := evalOrder(step,n,true);
exprs := evalOrder(final,n,true);
end;
whiletype,
untiltype: begin
cond := reExpr(cond,nil,svaltype);
exprs := evalOrder(cond,nil,true);
reParseAux(body);
end;
casetype: begin
index := reExpr(index,nil,svaltype);
exprs := evalOrder(index,nil,true);
n := caselist;
s := nil;
while n <> nil do
begin
if n↑.stmnt <> s then reParseAux(n↑.stmnt);
s := n↑.stmnt;
n := n↑.next;
end;
end;
iftype: begin
icond := reExpr(icond,nil,svaltype);
exprs := evalOrder(icond,nil,true);
reParseAux(thn);
reParseAux(els);
end;
pausetype: begin
ptime := reExpr(ptime,timedim↑.dim,svaltype);
exprs := evalOrder(ptime,nil,true);
end;
prompttype,
printtype,
aborttype: begin
n := plist;
while n <> nil do
begin
n↑.lval := reExpr(n↑.lval,nil,nulltype);
n := n↑.next;
end;
exprs := evalOrder(plist,nil,false);
end;
returntype: begin (*** * should check what procedure wants *** *)
retval := reExpr(retval,nil,nulltype);
exprs := evalOrder(retval,nil,true);
end;
calltype: begin
what := reExpr(what,nil,nulltype);
exprs := evalOrder(what,nil,true);
end;
assigntype: begin
what := reExpr(what,nil,nulltype);
n := nil;
n := getDim(what,n);
d := getDtype(what);
if d = frametype then d := transtype;
aval := reExpr(aval,n,d);
relNode(n);
with what↑ do
if ntype = leafnode then n := nil
else if op = arefop then n := arg2
else if arg1↑.ntype = leafnode then n := nil
else n := arg1↑.arg2;
if n <> nil then
n := evalorder(n,nil,true); (* deal with subscripts *)
exprs := evalorder(aval,n,true);
end;
affixtype,
unfixtype: begin
frame1 := reExpr(frame1,nil,frametype);
frame2 := reExpr(frame2,nil,frametype);
byvar := reExpr(byvar,distancedim↑.dim,transtype);
atexp := reExpr(atexp,distancedim↑.dim,transtype);
with frame1↑ do
if ntype = leafnode then n := nil
else n := evalOrder(arg2,nil,true); (* push array subscripts *)
with frame2↑ do
if ntype <> leafnode then n := evalOrder(arg2,n,true);
if byvar <> nil then
with byvar↑ do
if ntype <> leafnode then n := evalOrder(arg2,n,true);
if atexp <> nil then exprs := evalOrder(atexp,n,true)
else exprs := n;
end;
signaltype,
waittype: begin
event := reExpr(event,nil,eventtype);
if event↑.ntype <> leafnode then exprs := nil
else exprs := evalOrder(event↑.arg2,nil,true);
end;
movetype,
operatetype,
opentype,
closetype,
centertype,
stoptype: begin
pushStmnt(st,0); (* so grinch can be parsed *)
cf := reExpr(cf,nil,nulltype);
n := clauses;
while n <> nil do
begin reClause(n); n := n↑.next end;
moveOrder(st);
cursor := cursor - 1;
end;
cmtype: begin
reCmon(st);
end;
wristtype: begin
fvec := reExpr(fvec,forcedim↑.dim,vectype);
tvec := reExpr(tvec,torquedim↑.dim,vectype);
n := nil;
with fvec↑ do
if (ntype = exprnode) and (op = arefop) then
n := evalorder(arg2,n,true); (* deal with subscripts *)
with tvec↑ do
if (ntype = exprnode) and (op = arefop) then
n := evalorder(arg2,n,true); (* deal with subscripts *)
exprs := n;
end;
otherwise {do nothing};
end;
end (* reParseAux *);
begin (* reParse *)
pp20L('Need to reparse... ',18); ppLine;
if st↑.stype = blocktype then
begin
v := st↑.variables; (* need to push any array bounds info *)
lexp := nil;
while v <> nil do
begin
if v↑.tbits = 1 then lexp := evalOrder(v↑.a↑.bounds,lexp,false);
v := v↑.next;
end;
st↑.exprs := lexp;
end;
reParseAux(st);
lbufp := 0;
i := addNewDeclarations;
topDline := 0; (* flush old display *)
botDline := 0;
displayLines(lineNum); (* & redraw it *)
end (* reParse *);
(* delStmnt *)
procedure delStmnt(arg: integer); external;
procedure delStmnt;
var s,sp,so: statementp; n,np,no: nodep; v,vp: varidefp;
ocur,i,j,dlines: integer; b,bv,reparsep: boolean;
procedure resetPC(i,f:integer; st: statementp);
var j: integer; p: pdbp;
begin
for j := 0 to debugLevel do
begin (* make sure no process is about to execute stmnt we're deleting *)
if j = 0 then p := allPdbs else p := debugPdbs[j];
while p <> nil do (* run through all the active processes *)
with p↑ do
begin
if (i <= linenum) and (linenum <= f) then
begin
(* *** check if we need to remove any fornodes from process stack *** *)
spc := st;
linenum := i;
end;
p := next;
end;
end;
end;
function newEmptyStmnt: statementp;
var st: statementp; l: integer;
begin
st := newStatement;
dlines := sp↑.nlines - 1;
with st↑ do
begin
stype := emptytype;
last := cursorStack[cursor-1].st;
next := sp↑.next;
end;
if sp↑.stlab <> nil then sp↑.stlab↑.s := nil; (* label points nowhere now *)
resetPC(cursorLine,cursorLine + sp↑.nlines,st);
freeStatement(sp); (* delete old body *)
ocur := cursorLine; (* so we print out empty stmnt *)
l := cursorLine - topDline + 1;
relLine(lines[l]); (* free up old line *)
lines[l] := nil;
cursorLine := cursorLine + 1;
newEmptyStmnt := st;
end;
begin
dlines := 0;
ocur := 0;
with cursorStack[cursor] do (* don't care if it's a proc def *)
if (not stmntp) and (nd↑.ntype = procdefnode) then cursor := cursor - 1
else if stmntp and (st↑.stype = cmtype) then
with cursorStack[cursor-1] do
if (not stmntp) and (nd↑.ntype = cmonnode) then cursor := cursor - 1;
with cursorStack[cursor] do
begin (* see what we're deleting *)
if not stmntp then
begin (* case labels or motion clauses *)
if nd↑.ntype = clistnode then
begin (* case labels *)
(* *** later *** *)
end
else
begin (* motion clauses *)
np := nd;
sp := cursorStack[cursor-1].st;
n := sp↑.clauses; (* find clause in list *)
b := n = np; (* deleting first clause? *)
if (not b) and (n <> nil) then (* find clause *)
while (n↑.next <> nil) and (n↑.next <> np) do n := n↑.next;
j := 1;
while (j <= arg) and (np <> nil) do
begin (* delete them *)
if np↑.ntype = viaptnode then
begin (* check if via list *)
bv := np↑.next <> nil;
while bv do
with np↑.next↑ do
if (ntype = viaptnode) and vlist then
begin
no := np↑.next;
bv := next <> nil;
np↑.next := nil;
freeNode(np); (* flush front part of via list *)
np := no;
end
else bv := false;
end;
with np↑ do
begin
if (ntype = viaptnode) and (vcode <> nil) then
if vcode↑.stype = signaltype then i := 1
else
begin
i := vcode↑.conclusion↑.nlines;
flushVar(vcode↑.cdef); (* flush the cmon variable *)
end
else if ((ntype = deprnode) or (ntype = apprnode)) and (code <> nil) then
if code↑.stype = signaltype then i := 1
else
begin
i := code↑.conclusion↑.nlines;
flushVar(code↑.cdef); (* flush the cmon variable *)
end
else if ntype = cmonnode then
begin
i := cmon↑.nlines;
flushVar(cmon↑.cdef); (* flush the cmon variable *)
end
else i := 0;
dlines := dlines + i + 1; (* how many lines are we deleting *)
no := next;
next := nil; (* so freeNode doesn't clobber remaining clauses *)
end;
freeNode(np);
np := no;
j := j + 1;
end;
if b then sp↑.clauses := np (* splice in last clauses *)
else if n <> nil then n↑.next := np;
moveOrder(sp);
end
end
else
begin
sp := st;
if (sp↑.stype = iftype) and (fieldNum = 2) then
begin (* flush ELSE *)
dlines := sp↑.els↑.nlines + 1;
resetPC(cursorLine+1,cursorLine + sp↑.els↑.nlines,sp↑.next);
freeStatement(sp↑.els);
sp↑.els := nil;
sp↑.nlines := sp↑.nlines - dlines;
end
else if (sp↑.stype = affixtype) and (fieldNum = 5) then
begin (* flush atexp *)
sp↑.atexp := nil;
sp↑.nlines := sp↑.nlines - 1;
dlines := 1;
end
else if ((prompttype <= sp↑.stype) and (sp↑.stype <= aborttype)) and
(fieldNum > 1) then
begin (* part of plist *)
(* *** yech!!! *** *)
end
else if (sp↑.stype = endtype) or (sp↑.stype = coendtype) then
begin (* no good *)
pp20L('Can''t delete END or ',20); pp5('COEND',5); ppLine;
end
else
with cursorStack[cursor-1] do
if stmntp then
case st↑.stype of
blocktype: begin
reparsep := false;
j := 1;
b := st↑.bcode = sp; (* first stmnt in block? *)
while (j <= arg) and (sp↑.stype <> endtype) do
begin
dlines := dlines + sp↑.nlines;
if sp↑.stype = declaretype then
begin (* flush the variables *)
reparsep := true;
v := sp↑.variables;
while v <> nil do
begin
vp := v↑.dnext;
flushVar(v);
v := vp;
end;
end
else if sp↑.stype = cmtype then
begin (* flush the cmon variable *)
flushVar(sp↑.cdef);
end
else if sp↑.stype = dimdeftype then
begin (* flush the dimension variable *)
flushVar(sp↑.dimname);
end
else if sp↑.stype = definetype then
begin (* flush the macro variable *)
flushVar(sp↑.macname);
end;
so := sp↑.next;
so↑.last := sp↑.last; (* splice block out of list *)
if b then st↑.bcode := so else sp↑.last↑.next := so;
if sp↑.stlab <> nil then sp↑.stlab↑.s := nil; (* update label *)
resetPC(cursorLine,cursorLine + sp↑.nlines,sp↑.next);
freeStatement(sp); (* delete it *)
sp := so;
j := j + 1;
end;
if reparsep then
begin (* need to reparse block *)
for i := 1 to cursor - 1 do (* update cursor stack *)
with cursorStack[i] do
if stmntp then st↑.nlines := st↑.nlines - dlines;
reParse(curBlock);
if dprog↑.nlines < dispHeight then
for i := dprog↑.nlines + 1 to dprog↑.nlines + dlines do
if i <= dispHeight then clearLine(i+1);
dlines := 0; (* reParse will fix up the screen *)
end;
end;
coblocktype: begin (* *** if active then kill sprouted processes *** *)
end;
iftype: if st↑.thn = sp then st↑.thn := newEmptyStmnt
else st↑.els := newEmptyStmnt;
fortype: st↑.fbody := newEmptyStmnt;
whiletype,
untiltype: st↑.body := newEmptyStmnt;
cmtype: st↑.conclusion := newEmptyStmnt;
otherwise {do nothing};
end
else if nd↑.ntype = colistnode then
begin (* coblock *)
so := sp↑.last;
if so↑.nthreads = 1 then (* only statement in coblock? *)
nd↑.cstmnt := newEmptyStmnt (* yes - replace with an empty stmnt *)
else
begin (* delete statement from coblock *)
dlines := dlines + sp↑.nlines;
if sp↑.stlab <> nil then sp↑.stlab↑.s := nil; (* update label *)
(* *** If active then kill process *** *)
resetPC(cursorLine,cursorLine + sp↑.nlines,sp↑.next);
freeStatement(sp); (* delete it *)
if nd↑.next <> nil then nd↑.next↑.prev := nd↑.prev;
if nd↑.prev <> nil then nd↑.prev↑.next := nd↑.next
else so↑.threads := nd↑.next;
so↑.nthreads := so↑.nthreads - 1;
end
end
else
begin (* case list *)
(* *** later *** *)
end
end
end;
if dlines > 0 then deleteLines(cursorLine,dlines,1); (* fix up display *)
firstLine := ocur;
if ocur > 0 then lastLine := ocur else lastLine := -1;
setCursor := true;
curLine := 0;
putStmnt(dProg,0,99); (* reset cursor & possibly redraw a line *)
setCursor := false;
showCursor(cursorLine-topDline-firstDline+2,1);
borderLines;
end;