home *** CD-ROM | disk | FTP | other *** search
- {UnPars.inc}
- (********* Source code Copyright 1986, by L. David Baldwin *********)
-
- Type
- Symb = (Nul,Ident4,Ident2,Identunk,Bytesy,Wordsy,Lparn,Rparn);
- Var
- Sy : Symb;
-
- {-------------DefaultExtension}
- PROCEDURE DefaultExtension(Extension:Filestring;Var Infile,Name :Filestring);
- {Given a filename, infile, add a default extension if none exists. Return
- also the name without any extension.}
- Var
- I,J : Integer;
- Temp : Filestring;
- begin
- I:=Pos('..',Infile);
- if I=0 then
- Temp:=Infile
- else
- begin {a pathname starting with ..}
- Temp:=Copy(Infile,I+2,64);
- I:=I+1;
- end;
- J:=Pos('.',Temp);
- if J=0 then
- begin
- Name := Infile;
- Infile:=Infile+'.'+Extension;
- end
- else Name:=Copy(Infile,1,I+J-1);
- end;
-
- {-------------GetCh}
- PROCEDURE GetCh;
- {Return next char in Uch and lch with Uch in upper case. Ignore comments}
- Var Comment : Boolean;
- PROCEDURE GetchBasic; {read a character and a character pair}
- begin
- if Chi<=Ord(St[0]) then
- begin {NOTE: pair has the same address as lch}
- Move(St[Chi], Pair, 2);
- if LCh=Chr(Tab) then LCh:=' ';
- UCh := UpCase(LCh);
- Chi := Chi+1;
- end
- else
- if not EOF(Inf) then
- begin
- ReadLn(Inf,St);
- St:=St+' '; {EOL is equivalent to space}
- Chi:=1;
- GetCh;
- end
- else
- begin
- EofInf:=True;
- if Comment then
- begin
- WriteLn('Open Comment at End of Input File');
- Halt(1);
- end;
- end;
- end;
-
- begin {Getch}
- if UCh<>' ' then
- Symname:=Symname+UCh; {build up a phrase with old character}
- repeat
- if EofInf then
- begin WriteLn('Unexpected End of Input File'); Halt(1) end;
- Comment:=False;
- GetchBasic;
- if (UCh='{') or (Pair='(*') then
- begin
- Comment:=True;
- if UCh='{' then repeat GetchBasic; until UCh='}'
- else
- begin
- repeat GetchBasic; until Pair='*)';
- GetchBasic; {pass by the '*'}
- end;
- end;
- until not Comment;
- end;
-
- {-------------SkipSpaces}
- PROCEDURE SkipSpaces;
- begin
- while (UCh=' ') or (UCh=Chr(Tab)) do
- GetCh;
- end;
-
- {-------------GetDec}
- FUNCTION GetDec(Var V :Integer): Boolean ;
- Const
- Ssize = 8;
- Var
- S : String[Ssize];
- Getd : Boolean;
- Code : Integer;
- begin
- Getd := False;
- S := '';
- while (UCh>='0') and (UCh<='9') do
- begin
- Getd := True;
- if Ord(S[0])<Ssize
- then S := S+UCh;
- GetCh;
- end;
- if Getd then
- begin
- Val(S,V,Code);
- if Code<>0
- then Error(Chi,'Bad Number Format');
- end;
- GetDec := Getd;
- end;
-
- {-------------GetHex}
- FUNCTION GetHex(Var H :Integer): Boolean;
- Var
- Digit : Integer; {check for '$' before the call}
- begin
- H := 0;
- GetHex := False;
- while (UCh in ['A'..'F','0'..'9']) do
- begin
- GetHex := True;
- if (UCh>='A')
- then Digit := Ord(UCh)-Ord('A')+10
- else Digit := Ord(UCh)-Ord('0');
- if H>=$1000
- then Error(Chi,'Overflow');
- H := (H Shl 4)+Digit;
- GetCh;
- end;
- end;
-
- {-------------GetNumber}
- FUNCTION GetNumber(Var N :Integer): Boolean;
- {get a number and return it in n}
- begin
- SkipSpaces;
- N := 0;
- if UCh='$'
- then
- begin {a hex number}
- GetCh;
- if not GetHex(N)
- then Error(Chi, 'Hex Number Exp');
- GetNumber := True;
- end
- else
- begin {maybe a decimal number}
- GetNumber := GetDec(N);
- end;
- end;
-
- {-------------GetExpr}
- FUNCTION GetExpr(Var Rslt :Integer): Boolean;
- Var
- Rs1,Rs2 : Integer;
- Pos,Neg,GE : Boolean;
- begin
- GE := False;
- SkipSpaces;
- Neg := UCh='-';
- Pos := UCh='+';
- if Pos or Neg
- then GetCh;
- if GetNumber(Rs1)
- then
- begin
- GE := True;
- if Neg
- then Rs1 := -Rs1;
- SkipSpaces;
- if (UCh='+') or (UCh='-') then
- if GetExpr(Rs2) then
- Rs1 := Rs1+Rs2 {GetExpr will take care of sign}
- else GE:=False;
- Rslt := Rs1;
- end;
- SkipSpaces;
- GetExpr:=GE and ((UCh='/') or (UCh=')')); {must terminate in '/' or ')'}
- end;
-
- {-------------GetToken}
- PROCEDURE GetToken;
- Const
- Tokenchars : set of Char = ['A'..'Z','0'..'9','_'];
- Startchars : set of Char = ['A'..'Z','_'];
- begin
- while not (UCh in Startchars) and not EofInf do GetCh;
- Token[0] := #0;
- if not EofInf then
- while UCh in Tokenchars do
- begin
- if Ord(Token[0])<Tokenleng
- then Token := Token+UCh;
- GetCh;
- end;
- end;
-
- {-------------Next}
- PROCEDURE Next;
- Var C : Char;
-
- FUNCTION GetExprX(Var N : Word; Var C : Char): Boolean;
- begin
- C:=UCh;
- if (UCh='>') or (UCh='<') then GetCh;
- GetExprX:=GetExpr(Integer(N));
- end;
-
- begin
- Sy := Nul;
- repeat
- SkipSpaces;
- Symname[0]:=#0; {build up a phrase which may be needed later}
- if BytePending then
- begin
- NValue:=PendingByte;
- BytePending:=False;
- Sy:=Bytesy;
- end
- else if UCh='(' then begin Sy:=Lparn; GetCh; end
- else if UCh=')' then begin Sy:=Rparn; GetCh; end
- else if UCh='/' then Error(Chi+2, 'Syntax')
- else if GetExprX(NValue,C) then
- begin
- if C='<' then Sy:=Bytesy
- else if C='>' then Sy:=Wordsy
- else if NValue and $FF00 = 0 then Sy := Bytesy
- else Sy:=Wordsy;
- if UCh='/' then GetCh;
- end
- else
- begin {it's a symbolic phrase}
- while (UCh<>'/') and (UCh<>')') do GetCh; {finish reading the phrase}
- if UCh='/' then
- begin
- GetCh; {pass the '/' by}
- Symname[0]:=Pred(Symname[0]); {but remove it from phrase}
- end;
- if (Pos('>',Symname)>0) or (Pos('*',Symname)>0) then
- Sy:=Ident4
- else if Pos('<',Symname)>0 then Sy:=Ident2
- else Sy:=Identunk; {unknown size}
- end;
- if Sy=Nul then GetCh;
- until Sy<>Nul;
- end;
-
- {-------------GetByte}
- FUNCTION GetByte(Var P :Packet; PhraseOk : Boolean): Boolean;
- Var Result : Boolean;
- begin
- Result:=True;
- with P do
- begin
- Dispsize:=Bytesize; Phrase:=False;
- if (Sy=Ident2) or (Sy=Identunk) then
- begin
- if not PhraseOk then Result:=False
- else
- begin
- Phrase:=True;
- if Sy=Identunk then Insert('<',Symname,1);
- S:=Symname; {the phrase}
- end;
- end
- else if Sy=Bytesy then Value:=Lo(NValue)
- else if Sy=Wordsy then
- begin
- Value:=Lo(NValue);
- BytePending:=True;
- PendingByte:=Hi(NValue);
- end
- else Result:=False;
- if Result then
- begin
- PC:=PC+1;
- Next;
- end;
- GetByte:=Result;
- end;
- end;
-
- {-------------GetWord}
- PROCEDURE GetWord(Var P :Packet);
- Var H,L : Packet;
- PROCEDURE WordErr;
- begin Error(Chi,'Word or two bytes exp'); PC:=PC+2; Next; end;
- begin
- with P do
- begin
- Dispsize:=Wordsize; Phrase:=False;
- if (Sy=Ident4) or (Sy=Identunk) then
- begin
- if Sy=Identunk then Insert('>',Symname,1);
- Phrase:=True; S:=Symname;
- PC:=PC+2; Next;
- end
- else if Sy=Ident2 then WordErr
- else if Sy=Wordsy then
- begin Value:=NValue; PC:=PC+2; Next; end
- else if GetByte(L,not PhraseOk) then
- begin
- if not GetByte(H, not PhraseOk) then NumbyteErr;
- Value:=H.Value Shl 8 +L.Value;
- end
- else WordErr;
- end;
- end;