{ MODULE FOR LIST AND TREE OPERATIONS ARGUMENTS } { RANDALL VENHOLA JULY 8, 1987 } [INHERIT('SCREENHANDLERS','UTILITYOPS'), environment('argops')] MODULE ARGOPS; CONST maxchars = 31; {# of chars in arg literal } maxargsinarray = 30; {for conversion to an array of args} indexofunknowntexcommand = 0; TYPE pckstr = VARYING [ maxchars ] of char; comparisons = (notvalid, lessthan, equal, greaterthan); setofcomparisons = set of comparisons; argtype = ( dsrverb, int, signedint, stylespecifier, textpckstr, character, quotedpckstr, nulltype); setofargtype = set of argtype; argument = record source : pckstr; isgeneralization : boolean; texindex : integer; class : setofargtype end; argarray = array[1..maxargsinarray] of argument; [GLOBAL] FUNCTION argliteral( arg : argument; smooth : boolean ) : pckstr; var s : pckstr; i,j, firstchar, lastchar : integer; ch : char; procedure findfirstchar( s : pckstr; var firstchar : integer); begin firstchar := 1; while (firstchar < s.length) and (s.body[firstchar] <= blank) do firstchar := firstchar + 1 end; procedure findlastchar( s : pckstr; var lastchar : integer ); begin lastchar := s.length; while (lastchar > 1) and (s.body[lastchar] <= blank) do lastchar := lastchar - 1 end; begin if smooth then begin findfirstchar( arg.source, firstchar); findlastchar( arg.source, lastchar); j := 0; for i := firstchar to lastchar do begin ch := arg.source.body[i]; if ch < blank then ch := blank; if ch in ['a'..'z'] then ch := chr(ord(ch) - ord(blank)); j := j + 1; s.body[j] := ch end; if (j = 1) and (s.body[1] = blank) then s.length := 0 else s.length := j end else s := arg.source; argliteral := s end; [GLOBAL] FUNCTION pckstrisgeneralization( s : pckstr ) : boolean; label routineexit; var flag : boolean; begin flag := false; if s = '[N]' then begin flag := true; goto routineexit end; if s = '[C]' then begin flag := true; goto routineexit end; if s = '[Y]' then begin flag := true; goto routineexit end; if s = '[T]' then begin flag := true; goto routineexit end; if s = '[Q]' then begin flag := true; goto routineexit end; routineexit : pckstrisgeneralization := flag end; [GLOBAL] FUNCTION argisgeneralization( arg : argument ) : boolean; begin argisgeneralization := arg.isgeneralization end; [GLOBAL] FUNCTION textualmatch( arg1, arg2 : argument) : boolean; begin textualmatch := false; if (arg1.source = '[T]') and (textpckstr in arg2.class) then textualmatch := true else if (arg2.source = '[T]') and (textpckstr in arg1.class) then textualmatch := true end; [GLOBAL] FUNCTION compareargs( leftarg, rightarg : argument ) : comparisons; label routineexit; var lefts, rights : pckstr; equalpckstrs : boolean; comp : comparisons; procedure greaterorlessthancompare; begin if lefts < rights then comp := lessthan else comp := greaterthan end; procedure checktexindex; begin if (leftarg.texindex = indexofunknowntexcommand) or (rightarg.texindex = indexofunknowntexcommand) then comp := equal else if leftarg.texindex = rightarg.texindex then comp := equal else greaterorlessthancompare end; begin if textualmatch( leftarg, rightarg) then begin comp := equal; goto routineexit end; if (leftarg.class = [nulltype]) or (rightarg.class = [nulltype]) then begin comp := equal; goto routineexit end; lefts := argliteral(leftarg, TRUE); rights := argliteral(rightarg, TRUE); equalpckstrs := (lefts = rights); comp := notvalid; if leftarg.class * rightarg.class <> [] then begin if equalpckstrs then comp := equal else if (leftarg.isgeneralization) or (rightarg.isgeneralization) then checktexindex else greaterorlessthancompare end else greaterorlessthancompare; routineexit : compareargs := comp end; [GLOBAL] FUNCTION argtexindex( arg : argument ) : integer; begin argtexindex := arg.texindex end; [GLOBAL] FUNCTION argclass( arg : argument ) : setofargtype; begin argclass := arg.class end; [GLOBAL] PROCEDURE initarg( var arg : argument; classification : setofargtype; lit : pckstr; index : integer; general : boolean ); begin arg.source := lit; arg.class := classification; arg.texindex := index; arg.isgeneralization := general end; [GLOBAL] PROCEDURE reassignargclass( var arg : argument; newclass : setofargtype); begin arg.class := newclass end; [GLOBAL] PROCEDURE reassignargtexindex( var arg : argument; newindex:integer); begin arg.texindex := newindex end; [GLOBAL] PROCEDURE reassignarggeneralization( var arg : argument;general:boolean); begin arg.isgeneralization := general end; [GLOBAL] PROCEDURE appendchartoarg( ch : char; var arg : argument ); begin if arg.source.length = maxchars then warningmessage('appendchartoarg','argument too long') else begin arg.source.length := arg.source.length + 1; arg.source.body[arg.source.length] := ch end end; [GLOBAL] PROCEDURE extractintegerfromargument( arg : argument; var successful : boolean; var int : integer; var signed : boolean ); var s : pckstr; begin s := argliteral( arg, TRUE); readv( s, int, error := continue ); if statusv <> 0 then successful := false else begin successful := true; signed := (s.body[1] = '+') or (s.body[1] = '-') end end; END.