{-------------------------------------------------------------} { routines for phase 1 -- input } {-------------------------------------------------------------} procedure indent; { indent the cursor for the current nesting level } var i : 0..9; begin for i := 1 to indlevel do write('. . ') end; function readnc : nchar; { get one byte from the keyboard, bypassing the usual pascal procedures and going straight to CP/M } var c : integer; begin repeat c := bdos(6,-1) until c<>0; if c>31 then write(chr(c)); readnc := c; end; procedure getterm(tree: pnode; var a:str; var cont: boolean); { get a term from the user, with control keys used thus: cr : end the term. lf : end the term, begin a subterm of it. esc: try to complete the term with the next (first) matching term from the present tree-context. del: cancel esc-completion, return to original entry. } var c : nchar; j, oj : strindex; k : strlength; x,ua : str; quit : boolean; tw : treewalk; p : pnode; procedure backup; { backup the screen and the "a" string to the original term that was entered. } var qj : strindex; begin for qj := j downto (oj+1) do write(chr(asciibs),chr(asciiblank),chr(asciibs)); j := oj; a.val[j] := nullch end; procedure startscan; { set up for an alphabetical scan over all terms that are an initial match to user entry thus far. Setscan does most of the work. } begin stucase(a,ua); { for stepscan's benefit } p := setscan(tree,tw,a); if p<>nil then { phony node only if a.len=0 } if p^.skip then p := treestep(tw); if p<>nil then begin { this node has to be equal } stget(p^.iref,x); k := x.len+1 end else k := 0 end; procedure stepscan; { find the next match to the original string, leaving its value in x, or k=0 if there is none. } begin k := 0; p := treestep(tw); if p<>nil then if p^.skip then p := treestep(tw); if p<>nil then if equal=sxcomp(ua,p^.uref) then begin stget(p^.iref,x); k := x.len+1 end end; begin { the main Get Term procedure } indent; write('term: '); j := 1; oj := j; { no data in the a-string } k := 0; { no esc-scan working } quit := false; { not finished yet (hardly!) } repeat a.val[j] := nullch; { keep "a" a finished string } a.len := j-1; { ..at all times } c := readnc; case c of asciibs : { destructive backspace } if j>1 then begin write(chr(asciibs),chr(asciiblank),chr(asciibs)); j := j-1; oj := j; { the current scan is accepted } k := 0; { ..and no scan is underway } end; asciicr : { normal completion } begin writeln; quit := true end; asciilf : { complete, move on to subterm } begin writeln; quit := true end; asciiesc : { automatic scan for match } begin backup; { wipe rejected match if any } if k=0 then startscan else stepscan; if k=0 then { no (further) match found } write(chr(asciibel)) else { next (first?) match found } while j it } begin if pg>p1^.num then makepage(p1^.next,pg); goto 103 end; 102: {p1^.num <= pg p1^.num then begin makepage(p3,pg); p3^.next := p2; p1^.next := p3 end end; 103: ; end end; procedure load(var atree:pnode); { input control: load terms into a tree from the keyboard. the code is recursive; if the user wants to do a subterm this routine calls itself to load the sub-tree of the superior term's node. A page number of zero is a disaster when we reload the saved tree, so one is converted to -1.} var aterm : str; anode : pnode; apage : integer; cont : boolean; begin repeat getterm(atree,aterm,cont); if aterm.len>0 then begin anode := insert(atree,aterm); if not cont then begin getpage(apage); if apage=0 then apage := 32767; addpage(anode,apage) end else begin { user hit lf, wants to recurse } if anode^.subt=nil then startree(anode^.subt); indlevel := indlevel+1; load(anode^.subt); indlevel := indlevel-1 end end; until (aterm.len=0) or (indlevel>0) end;  indl