| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829 |
- (* Release 3.10 *)
- (*-------------------------------------------------------------------------*
- * *
- * SCRIPTCO.MOD - COMMS Toolkit Script compiler *
- * *
- * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
- * All Rights Reserved *
- * *
- *--------------------------------------------------------------------------*)
- IMPLEMENTATION MODULE ScriptCompiler; (* Compile a Procomm type Script *)
- IMPORT CommUtil,FIO,IO,Lib,Scanner,Storage,Str;
- FROM Scanner IMPORT Symbols;
- CONST
- MaxStringLnth = 80;
- MaxLabels = 20;
- TYPE
- SymSet = SET OF Scanner.Symbols;
- LabelDef = RECORD
- Label : Scanner.Alpha;
- Defined : BOOLEAN;
- Addr : CARDINAL;
- END;
- VAR
- StatBegSyms : SymSet;
- LblCnt : CARDINAL;
- Labels : ARRAY[0..MaxLabels-1] OF LabelDef;
- (*..............................................*)
- PROCEDURE FindLabel(VAR Lbl:Scanner.Alpha; PC:CARDINAL):CARDINAL;
- VAR
- Found : BOOLEAN;
- i,a : CARDINAL;
- BEGIN
- i:=0;
- Found:=FALSE;
- WHILE (NOT Found) AND (i<LblCnt) DO
- IF Scanner.StrCompare(Lbl,Labels[i].Label)=0 THEN
- Found:=TRUE;
- ELSE
- INC(i);
- END;
- END;
- WITH Labels[i] DO
- IF Found THEN
- IF Defined THEN
- RETURN Addr;
- ELSE
- a := Addr;
- Addr := PC;
- RETURN a;
- END
- ELSE
- Label := Lbl;
- Defined:=FALSE;
- Addr:=PC;
- INC(LblCnt);
- RETURN 0FFFFH;
- END;
- END;
- END FindLabel;
- (************************************************)
- PROCEDURE Statement(TermSyms:SymSet);
- (*..............................................*)
- PROCEDURE Value(VAR s:ARRAY OF CHAR):CARDINAL;
- VAR
- i,x : CARDINAL;
- c : CHAR;
- BEGIN
- x := 0;
- FOR i:=0 TO HIGH(s) DO
- c := s[i];
- IF c=0C THEN
- RETURN x
- ELSIF (c>='0') AND (c<='9') THEN
- x := x*10+ORD(c)-48;
- END;
- END;
- RETURN x;
- END Value;
- (*..............................................*)
- PROCEDURE Gen(op:SHORTCARD);
- BEGIN
- CodeBuff^[PC] := op;
- INC(PC);
- END Gen;
- (*..............................................*)
- PROCEDURE GenW(op:CARDINAL);
- BEGIN
- Gen(SHORTCARD(op MOD 100H));
- Gen(SHORTCARD(op DIV 100H));
- END GenW;
- (*..............................................*)
- PROCEDURE PatchW(Addr,op:CARDINAL);
- VAR
- Temp : CARDINAL;
- BEGIN
- Temp:=PC;
- PC:=Addr;
- GenW(op);
- PC:=Temp;
- END PatchW;
- (*..............................................*)
- PROCEDURE GenS(VAR op:ARRAY OF CHAR);
- VAR
- Lnth : CARDINAL;
- BEGIN
- Lnth := Str.Length(op)+1;
- Gen(255);
- Lib.Move(ADR(op),ADR(CodeBuff^[PC]),Lnth);
- INC(PC,Lnth);
- END GenS;
- (*..............................................*)
- PROCEDURE StringVar(VAR StringNo:SHORTCARD):BOOLEAN;
- VAR
- c : CHAR;
- BEGIN
- IF (Scanner.Sy=Ident) AND (Str.Length(Scanner.Id)=2) AND (CAP(Scanner.Id[0])='S') THEN
- c := Scanner.Id[1];
- IF (c>='0') AND (c<='9') THEN
- StringNo:=SHORTCARD(ORD(c)-48);
- RETURN TRUE
- END;
- END;
- RETURN FALSE;
- END StringVar;
- (*..............................................*)
- PROCEDURE String;
- VAR
- Sno : SHORTCARD;
- BEGIN
- IF StringVar(Sno) THEN
- Gen(Sno)
- ELSIF Scanner.Sy=StringConst THEN
- GenS(Scanner.LastStringConst)
- ELSE
- Scanner.Error(6);
- END;
- Scanner.GetSym;
- END String;
- (*..............................................*)
- PROCEDURE DefineLabel(VAR Lbl:Scanner.Alpha; PC:CARDINAL);
- VAR
- Found : BOOLEAN;
- i,nextp,p : CARDINAL;
- BEGIN
- i:=0;
- Found:=FALSE;
- WHILE (NOT Found) AND (i<LblCnt) DO
- IF Scanner.StrCompare(Lbl,Labels[i].Label)=0 THEN
- Found:=TRUE;
- ELSE
- INC(i);
- END;
- END;
- WITH Labels[i] DO
- IF Found THEN
- IF Defined THEN
- Scanner.Error(11);
- ELSE
- (* Chain through patch list, fixing addresses *)
- nextp := Addr;
- WHILE nextp<>0FFFFH DO
- p:=nextp;
- nextp := CARDINAL(CodeBuff^[p])+CARDINAL(CodeBuff^[p+1])*100H;
- PatchW(p,PC);
- END;
- END
- ELSE
- Label:=Lbl;
- INC(LblCnt);
- END;
- Defined:=TRUE;
- Addr:=PC;
- END;
- END DefineLabel;
- (*..............................................*)
- PROCEDURE Label;
- BEGIN
- IF Scanner.Sy=Colon THEN
- DefineLabel(Scanner.Id,PC);
- Scanner.GetSym;
- ELSE
- Scanner.Error(12);
- END;
- END Label;
- (*..............................................*)
- PROCEDURE SimpleCommand(Op,Default:SHORTCARD);
- VAR
- x : CARDINAL;
- BEGIN
- Gen(Op);
- IF Scanner.Sy=IntConst THEN
- x := Value(Scanner.LastNumConst);
- IF x<=255 THEN
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(4);
- END;
- Scanner.GetSym;
- ELSE
- Gen(Default); (* default to three second alarm *)
- END;
- END SimpleCommand;
- (*..............................................*)
- PROCEDURE Assign;
- VAR
- SNo : SHORTCARD;
- BEGIN
- IF StringVar(SNo) THEN
- Gen(1);
- Gen(SNo);
- Scanner.GetSym;
- String;
- ELSE
- Scanner.Error(5);
- END;
- END Assign;
- (*..............................................*)
- PROCEDURE Clear;
- VAR
- Bg,Fg : CARDINAL;
- BEGIN
- IF Scanner.Sy=IntConst THEN
- Bg := Value(Scanner.LastNumConst);
- IF Bg<=7 THEN
- Scanner.GetSym;
- IF Scanner.Sy=IntConst THEN
- Fg:=Value(Scanner.LastNumConst);
- IF Fg<=15 THEN
- Gen(7);
- Gen(SHORTCARD(Bg*16+Fg));
- ELSE
- Scanner.Error(7);
- END;
- ELSE
- Scanner.Error(8);
- END;
- ELSE
- Scanner.Error(7);
- END;
- Scanner.GetSym;
- ELSE
- Gen(6);
- END;
- END Clear;
- (*..............................................*)
- PROCEDURE Locate;
- VAR
- y,x : CARDINAL;
- BEGIN
- IF Scanner.Sy=IntConst THEN
- y := Value(Scanner.LastNumConst);
- IF y<=23 THEN
- Scanner.GetSym;
- IF Scanner.Sy=IntConst THEN
- x:=Value(Scanner.LastNumConst);
- IF x<=79 THEN
- Gen(35);
- Gen(SHORTCARD(y));
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(7);
- END;
- ELSE
- Scanner.Error(8);
- END;
- ELSE
- Scanner.Error(7);
- END;
- Scanner.GetSym;
- ELSE
- Scanner.Error(8);
- END;
- END Locate;
- (*..............................................*)
- PROCEDURE DosOrRun(op:SHORTCARD);
- VAR
- SNo : SHORTCARD;
- BEGIN
- Gen(op);
- IF NOT StringVar(SNo) THEN
- SNo:=255;
- END;
- Scanner.GetSym;
- IF Scanner.Sy=WaitSy THEN
- Gen(1);
- ELSE
- Gen(0);
- END;
- IF SNo=255 THEN
- GenS(Scanner.LastStringConst);
- ELSE
- Gen(SNo);
- END;
- IF Scanner.Sy=WaitSy THEN
- Scanner.GetSym;
- END;
- END DosOrRun;
- (*..............................................*)
- PROCEDURE WaitFor;
- VAR
- SNo : SHORTCARD;
- x : CARDINAL;
- BEGIN
- Gen(11);
- IF NOT StringVar(SNo) THEN
- SNo:=255;
- END;
- Scanner.GetSym;
- IF Scanner.Sy=IntConst THEN
- x := Value(Scanner.LastNumConst);
- IF x<=255 THEN
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(4);
- END;
- ELSE
- Gen(30);
- END;
- IF SNo=255 THEN
- GenS(Scanner.LastStringConst);
- ELSE
- Gen(SNo);
- END;
- IF Scanner.Sy=IntConst THEN
- Scanner.GetSym;
- END;
- END WaitFor;
- (*..............................................*)
- PROCEDURE If;
- VAR
- ElseAllowed : BOOLEAN;
- JumpOp : SHORTCARD;
- StartPC,JumpPC : CARDINAL;
- BEGIN
- StartPC := PC;
- IF Scanner.Sy=NotSy THEN
- JumpOp:=18;
- Scanner.GetSym;
- ELSE
- JumpOp:=19;
- END;
- CASE Scanner.Sy OF
- LinkedSy : Gen(12); |
- SuccessSy : Gen(13); |
- FailureSy : Gen(14); |
- FoundSy : Gen(15); |
- ConnectSy : Gen(16); |
- WaitForSy : Gen(17); |
- ELSE
- Scanner.Error(3);
- END;
- Scanner.GetSym;
- ElseAllowed := (Scanner.Sy<>ElseSy);
- IF Scanner.Sy=ElseSy THEN (* Empty if, but we have an else clause *)
- IF JumpOp=18 THEN
- JumpOp:=19;
- ELSE
- JumpOp:=18;
- END;
- Scanner.GetSym;
- END;
- IF Scanner.Sy=EndifSy THEN
- PC := StartPC; (* completely empty if statement - optimise out *)
- ELSE
- Gen(JumpOp);
- JumpPC:=PC;
- GenW(0);
- Statement(SymSet{ElseSy,EndifSy});
- IF Scanner.GotError THEN
- RETURN;
- END;
- IF (ElseAllowed) AND (Scanner.Sy=ElseSy) THEN
- Scanner.GetSym;
- IF Scanner.Sy<>EndifSy THEN
- PatchW(JumpPC,PC+3);
- Gen(3);
- JumpPC:=PC;
- GenW(0);
- Statement(SymSet{ElseSy,EndifSy});
- IF Scanner.GotError THEN
- RETURN;
- END;
- PatchW(JumpPC,PC);
- END
- ELSE
- PatchW(JumpPC,PC);
- END;
- END;
- IF Scanner.Sy=EndifSy THEN
- Scanner.GetSym;
- ELSE
- Scanner.Error(3);
- END;
- END If;
- (*..............................................*)
- PROCEDURE Emulate;
- BEGIN
- Gen(22);
- IF Scanner.Sy=Ident THEN
- GenS(Scanner.Id);
- Scanner.GetSym;
- ELSE
- String;
- END;
- END Emulate;
- (*..............................................*)
- PROCEDURE Find;
- VAR
- sno : SHORTCARD;
- BEGIN
- Gen(24);
- IF StringVar(sno) THEN
- Gen(sno);
- Scanner.GetSym;
- String;
- ELSE
- Scanner.Error(5);
- END;
- END Find;
- (*..............................................*)
- PROCEDURE Get(op:SHORTCARD);
- VAR
- sno : SHORTCARD;
- x : CARDINAL;
- BEGIN
- Gen(op);
- IF StringVar(sno) THEN
- Gen(sno);
- Scanner.GetSym;
- IF Scanner.Sy=IntConst THEN
- x := Value(Scanner.LastNumConst);
- IF x<256 THEN
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(4);
- END;
- Scanner.GetSym;
- ELSE
- Gen(80);
- END;
- ELSE
- Scanner.Error(5);
- END;
- END Get;
- (*..............................................*)
- PROCEDURE RGet;
- VAR
- x : CARDINAL;
- BEGIN
- Get(47);
- IF Scanner.Sy=IntConst THEN
- x:=Value(Scanner.LastNumConst);
- Scanner.GetSym;
- IF x<256 THEN
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(4);
- END;
- ELSE
- Gen(30);
- END;
- END RGet;
- (*..............................................*)
- PROCEDURE FileTransfer(op:SHORTCARD; FileRequired:BOOLEAN);
- VAR
- sno : SHORTCARD;
- Dummy : ARRAY[0..1] OF CHAR;
- BEGIN
- Gen(op);
- IF (Scanner.Sy>=FTAscii) AND (Scanner.Sy<=FTBYmodem) THEN
- Gen(SHORTCARD(ORD(Scanner.Sy)-ORD(FTAscii)));
- Scanner.GetSym;
- IF StringVar(sno) OR (Scanner.Sy=StringConst) THEN
- String
- ELSIF FileRequired THEN
- Scanner.Error(6);
- ELSE
- Dummy[0]:=0C;
- GenS(Dummy);
- (**** Scanner.GetSym; shouldn't advance here ****)
- END;
- ELSE
- Scanner.Error(10);
- END;
- END FileTransfer;
- (*..............................................*)
- PROCEDURE ReferenceLabel(op:SHORTCARD);
- BEGIN
- Gen(op);
- IF Scanner.Sy=Ident THEN
- GenW(FindLabel(Scanner.Id,PC));
- Scanner.GetSym;
- ELSE
- Scanner.Error(13);
- END;
- END ReferenceLabel;
- (*..............................................*)
- PROCEDURE Log;
- VAR
- sno : SHORTCARD;
- Dummy : ARRAY[0..1] OF CHAR;
- BEGIN
- Dummy[0] := 0C;
- CASE Scanner.Sy OF
- OpenSy : Gen(36);
- Scanner.GetSym;
- IF StringVar(sno) OR (Scanner.Sy=StringConst) THEN
- String
- ELSE
- GenS(Dummy);
- END; |
- CloseSy : Gen(37);
- Scanner.GetSym; |
- SuspendSy : Gen(38);
- Scanner.GetSym; |
- ResumeSy : Gen(39);
- Scanner.GetSym; |
- ELSE
- Scanner.Error(3);
- END;
- END Log;
- (*..............................................*)
- PROCEDURE Macro;
- VAR
- x : CARDINAL;
- BEGIN
- IF Scanner.Sy=IntConst THEN
- Gen(40);
- x:=Value(Scanner.LastNumConst);
- IF x<10 THEN
- Gen(SHORTCARD(x));
- ELSE
- Scanner.Error(7);
- END;
- Scanner.GetSym;
- ELSE
- Gen(41);
- String;
- END;
- END Macro;
- (*..............................................*)
- PROCEDURE OnOff(opOn,opOff:SHORTCARD);
- BEGIN
- IF Scanner.Sy=OnSy THEN
- Gen(opOn);
- ELSIF Scanner.Sy=OffSy THEN
- Gen(opOff);
- ELSE
- Scanner.Error(3);
- END;
- Scanner.GetSym;
- END OnOff;
- (*..............................................*)
- PROCEDURE Switch;
- VAR
- sno : SHORTCARD;
- GotDefault : BOOLEAN;
- (*. . . . . . . . . . . . . . . . . . . . . . . *)
- PROCEDURE CaseSelection;
- VAR
- PatchLoc : CARDINAL;
- BEGIN
- IF (NOT GotDefault) AND (Scanner.Sy=CaseSy) THEN
- Scanner.GetSym;
- Gen(52);
- Gen(sno);
- String;
- IF NOT Scanner.GotError THEN
- Gen(19);
- PatchLoc:=PC;
- GenW(0);
- Statement(SymSet{EndCaseSy});
- IF Scanner.Sy=EndCaseSy THEN
- Scanner.GetSym;
- ELSE
- Scanner.Error(3);
- END;
- PatchW(PatchLoc,PC+3);
- Gen(3);
- PatchLoc:=PC;
- GenW(0);
- CaseSelection;
- PatchW(PatchLoc,PC);
- END
- ELSIF Scanner.Sy=DefaultSy THEN
- IF GotDefault THEN
- Scanner.Error(14);
- RETURN;
- END;
- GotDefault := TRUE;
- Scanner.GetSym;
- Statement(SymSet{EndCaseSy});
- IF Scanner.Sy=EndCaseSy THEN
- Scanner.GetSym;
- ELSE
- Scanner.Error(3);
- END;
- END;
- END CaseSelection;
- (*. . . . . . . . . . . . . . . . . . . . . . . *)
- BEGIN (* Switch *)
- GotDefault := FALSE;
- IF StringVar(sno) THEN
- Scanner.GetSym;
- CaseSelection;
- IF Scanner.Sy=EndSwitchSy THEN
- Scanner.GetSym;
- ELSE
- Scanner.Error(3);
- END;
- ELSE
- Scanner.Error(5);
- END;
- END Switch;
- (*..............................................*)
- VAR
- Sym : Scanner.Symbols;
- BEGIN (* Statement *)
- WHILE (NOT Scanner.GotError) AND (Scanner.Sy IN StatBegSyms) DO
- Sym:=Scanner.Sy;
- Scanner.GetSym;
- CASE Sym OF
- Ident : Label; |
- AlarmSy : SimpleCommand(0,3); |
- AssignSy : Assign; |
- BreakSy : SimpleCommand(4,1); |
- ChDirSy : Gen(5);
- String; |
- ClearSy : Clear; |
- CWhenSy : Gen(54); |
- DialSy : Scanner.Error(9); |
- DosSy : DosOrRun(8); |
- EmulateSy : Emulate; |
- ExecuteSy : Gen(23);
- String; |
- ExitSy : Gen(20); |
- FindSy : Find; |
- GetSy : Get(25); |
- MGetSy : Get(26); |
- GetFileSy : FileTransfer(27,FALSE); |
- GosubSy : ReferenceLabel(29); |
- GotoSy : ReferenceLabel(30); |
- HangupSy : Gen(31); |
- IfSy : If; |
- IsFileSy : Gen(33);
- String; |
- KermServSy : |
- KFlushSy : Gen(34); |
- LocateSy : Locate; |
- LogSy : Log; |
- MacroSy : Macro; |
- MessageSy : Gen(9);
- String; |
- MLoadSy : Gen(42);
- String; |
- PauseSy : SimpleCommand(21,1); |
- PrinterSy : OnOff(43,44); |
- QuitSy : Gen(45); |
- ReturnSy : Gen(32); |
- RFlushSy : Gen(46); |
- RGetSy : RGet; |
- RunSy : DosOrRun(48); |
- SendFileSy : FileTransfer(28,TRUE); |
- SetSy : |
- SnapshotSy : Gen(49); |
- SwitchSy : Switch; |
- TraceSy : OnOff(50,51); |
- TransmitSy : Gen(10);
- String; |
- WaitForSy : WaitFor; |
- WhenSy : Gen(53);
- String;
- String; |
- END;
- END;
- IF NOT (Scanner.Sy IN TermSyms) THEN
- Scanner.Error(3);
- END;
- END Statement;
- (************************************************)
- PROCEDURE Initialise;
- BEGIN
- PC := 0;
- Scanner.InitScanner;
- Scanner.GetSym;
- LblCnt := 0;
- StatBegSyms := SymSet{Ident,AlarmSy,AssignSy,BreakSy,ChDirSy,ClearSy,CWhenSy,DialSy,
- DosSy,EmulateSy,ExecuteSy,ExitSy,FindSy,GetSy,MGetSy,GetFileSy,
- GosubSy,GotoSy,HangupSy,IfSy,IsFileSy,KermServSy,KFlushSy,LocateSy,
- LogSy,MacroSy,MessageSy,MLoadSy,PauseSy,PrinterSy,QuitSy,ReturnSy,
- RFlushSy,RGetSy,RunSy,SendFileSy,SetSy,SnapshotSy,SwitchSy,TraceSy,
- TransmitSy,WaitForSy,WhenSy};
- END Initialise;
- (*..............................................*)
- PROCEDURE CheckLabels;
- VAR
- i : CARDINAL;
- BEGIN
- i:=0;
- WHILE i<LblCnt DO
- WITH Labels[i] DO
- IF NOT Defined THEN
- IO.WrStr('Label "');
- IO.WrStr(Label);
- IO.WrStr('" is not defined');
- IO.WrLn;
- Scanner.GotError := TRUE;
- END;
- INC(i);
- END;
- END;
- END CheckLabels;
- (*..............................................*)
- PROCEDURE Compile(VAR Filename:ARRAY OF CHAR):BOOLEAN;
- BEGIN
- FIO.IOcheck := FALSE;
- Scanner.infile := FIO.Open(Filename);
- IF FIO.IOresult()=0 THEN
- FIO.EOF := FALSE;
- IF CodeBuff=NIL THEN
- IF NOT Storage.Available(MaxCodeBytes) THEN
- FIO.Close(Scanner.infile);
- CommUtil.ErrorMessage('Not enough memory to compile script!!');
- RETURN(FALSE)
- END;
- Storage.ALLOCATE(CodeBuff,MaxCodeBytes);
- END;
- Initialise;
- IF Scanner.Sy<>EndOfFile THEN
- Statement(SymSet{EndOfFile})
- ELSE
- Scanner.Error(3);
- END;
- CodeBuff^[PC]:=20;
- INC(PC); (* insert an EXIT command *)
- FIO.Close(Scanner.infile);
- IF NOT Scanner.GotError THEN
- CheckLabels;
- END;
- IF Scanner.GotError THEN
- Storage.DEALLOCATE(CodeBuff,MaxCodeBytes);
- CodeBuff := NIL;
- END;
- RETURN (NOT Scanner.GotError);
- ELSE
- CommUtil.ErrorMessage('Script File not found!');
- RETURN FALSE;
- END;
- END Compile;
- (*..............................................*)
- BEGIN
- CodeBuff := NIL;
- END ScriptCompiler.
|