home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
dev
/
obero
/
oberon-a
/
source
/
oc
/
oc.mod
< prev
next >
Wrap
Text File
|
1994-08-20
|
9KB
|
323 lines
(***************************************************************************
$RCSfile: OC.mod $
Description: Main entry point for Oberon-A compiler.
Created by: fjc (Frank Copeland)
$Revision: 4.9 $
$Author: fjc $
$Date: 1994/08/14 10:36:42 $
Copyright © 1993-1994, Frank Copeland
This module forms part of the OC program
See OC.doc for conditions of use and distribution
Log entries are at the end of the file.
***************************************************************************)
MODULE OC;
(*
** $C= CaseChk $I= IndexChk $L= LongAdr $N= NilChk
** $P- PortableCode $R= RangeChk $S= StackChk $T= TypeChk
** $V= OvflChk $Z= ZeroVars
*)
IMPORT
OCRev, Errors, E := Exec, Ti := Timer, TU := TimerUtil, U := Utility,
Dos, DU := DosUtil, Args, IU := IntuiUtil, Files, IO := StdIO,
Str := Strings, OCG, OCS, OCT, OCC, OCE, Compiler, SYS := SYSTEM;
CONST
CopyrightStr = "Copyright © 1993-94 Frank Copeland\n";
UsageStr = "See OC.doc for conditions of use\n";
VAR
file, batchFile : Files.File;
r : Files.Rider;
TimerBase : Ti.TimerBasePtr;
tr : Ti.TimeRequestPtr;
returnError : BOOLEAN;
(*------------------------------------*)
PROCEDURE* Cleanup ();
BEGIN (* Cleanup *)
IF file # NIL THEN Files.Close (file); file := NIL END;
IF batchFile # NIL THEN Files.Close (batchFile); batchFile := NIL END;
IF TimerBase # NIL THEN E.base.CloseDevice (tr); TimerBase := NIL END;
END Cleanup;
(*------------------------------------*)
PROCEDURE Init ();
BEGIN (* Init *)
file := NIL; TimerBase := NIL; returnError := FALSE; NEW (tr);
Errors.Assert
( E.base.OpenDevice (Ti.name, Ti.unitVBlank, tr, {}) = 0,
"OC -- failed to open timer.device" );
TimerBase := SYS.VAL (Ti.TimerBasePtr, tr.device);
SYS.SETCLEANUP (Cleanup);
END Init;
(*------------------------------------*)
PROCEDURE Main ();
VAR newsymfile : BOOLEAN;
(*------------------------------------*)
PROCEDURE ReportTime (VAR t1, t2 : Ti.TimeVal);
BEGIN (* ReportTime *)
TimerBase.SubTime (t2, t1);
IO.WriteF3
( " Elapsed time = %02.ld:%02.ld.%ld\n\n",
t2.secs DIV 60, t2.secs MOD 60,
(t2.micro + 50000) DIV 100000 )
END ReportTime;
(*------------------------------------*)
(*$D-*)
PROCEDURE DoCompile (source : ARRAY OF CHAR);
VAR
t1, t2 : Ti.TimeVal;
BEGIN (* DoCompile *)
TU.GetSysTime (tr, t1);
file := Files.Old (source);
IF file = NIL THEN
IO.WriteF1 ("Failed to open : %s\n\n", SYS.ADR (source));
ELSE
IO.WriteF1 ("Compiling %s...\n\n", SYS.ADR (source));
Compiler.newSF := newsymfile;
Compiler.CompilationUnit (file);
IF OCS.scanerr THEN returnError := TRUE END;
Files.Close (file); file := NIL
END;
TU.GetSysTime (tr, t2);
ReportTime (t1, t2);
END DoCompile;
(*------------------------------------*)
PROCEDURE DoCleanup ();
VAR
t1, t2 : Ti.TimeVal;
BEGIN (* DoCleanup *)
IO.WriteStr ("Garbage collecting...\n");
TU.GetSysTime (tr, t1);
OCC.Close (); OCT.Close ();
SYS.GC;
TU.GetSysTime (tr, t2);
ReportTime (t1, t2)
END DoCleanup;
(*------------------------------------*)
PROCEDURE DoInteractive ();
CONST prompt = "Source file ? : ";
VAR nameBuffer : ARRAY 256 OF CHAR;
BEGIN (* DoInteractive *)
IO.WriteStr (prompt); IO.ReadStr (nameBuffer);
IF nameBuffer [0] # 0X THEN
DoCompile (nameBuffer);
LOOP
IO.WriteStr (prompt); IO.ReadStr (nameBuffer);
IF nameBuffer [0] = 0X THEN EXIT END;
DoCleanup ();
DoCompile (nameBuffer)
END
END
END DoInteractive;
(*------------------------------------*)
(*$D-*)
PROCEDURE DoBatch (batchName : ARRAY OF CHAR);
VAR
sourceName : ARRAY 256 OF CHAR;
i : INTEGER;
ch : CHAR;
t1, t2 : Ti.TimeVal;
BEGIN (* DoBatch *)
batchFile := Files.Old (batchName);
IF batchFile # NIL THEN
TU.GetSysTime (tr, t1);
Files.Set (r, batchFile, 0);
LOOP
Files.Read (r, ch);
IF r.eof THEN EXIT END;
WHILE ch <= " " DO (* Skip whitespace *)
Files.Read (r, ch); IF r.eof THEN EXIT END;
END;
i := 0;
REPEAT
sourceName [i] := ch; INC (i); Files.Read (r, ch)
UNTIL r.eof OR (ch = "\n");
sourceName [i] := 0X;
DoCompile (sourceName);
IF r.eof THEN EXIT END;
DoCleanup ()
END;
Files.Close (batchFile); batchFile := NIL;
TU.GetSysTime (tr, t2);
IO.WriteStr ("Finished batch compile\n");
ReportTime (t1, t2)
ELSE
IO.WriteF1 (" !! Could not open %s\n", SYS.ADR (batchName))
END;
END DoBatch;
(*------------------------------------*)
PROCEDURE WbMain ();
BEGIN (* WbMain *)
IU.SimpleNotice
(NIL, SYS.ADR ("Sorry, no support for Workbench yet :-("));
HALT (Dos.returnWarn)
END WbMain;
(*------------------------------------*)
PROCEDURE CliMain ();
VAR
argStr : ARRAY 256 OF CHAR;
arg : INTEGER;
batch : BOOLEAN;
ch : CHAR;
(*------------------------------------*)
PROCEDURE Usage ();
BEGIN (* Usage *)
IO.WriteStr ("Usage : OC {option} {<filename>}\n");
IO.WriteStr ("Options : NS | NEWSYMFILE, DEBUG, VERBOSE, BATCH\n");
IO.WriteStr (" SYM | SYMBOLS <directory>\n");
IO.WriteStr (" DST | DESTINATION <directory>\n");
IO.WriteStr ("\nSee OC.doc for details\n\n");
END Usage;
BEGIN (* CliMain *)
OCT.DestPath := ""; arg := 1; batch := FALSE; newsymfile := FALSE;
LOOP
IF arg >= Args.argc THEN EXIT END;
COPY (Args.argv [arg]^, argStr); Str.ToUpper (argStr);
IF (argStr = "SYM") OR (argStr = "SYMBOLS") THEN
INC (arg);
IF arg >= Args.argc THEN Usage (); HALT (Dos.returnWarn) END;
IF DU.DirExists (Args.argv [arg]^) THEN
OCT.AddPath (Args.argv [arg])
ELSE
IO.WriteF1
(" !! SYM directory %s doesn't exist\n", Args.argv [arg]);
HALT (Dos.returnWarn)
END
ELSIF (argStr = "DST") OR (argStr = "DESTINATION") THEN
IF OCT.DestPath # "" THEN Usage (); HALT (Dos.returnWarn) END;
INC (arg);
IF arg >= Args.argc THEN Usage (); HALT (Dos.returnWarn) END;
IF DU.DirExists (Args.argv [arg]^) THEN
COPY (Args.argv [arg]^, OCT.DestPath);
IF OCT.DestPath # "" THEN
ch := OCT.DestPath [Str.Length (OCT.DestPath) - 1];
IF (ch # ":") & (ch # "/") THEN Str.Append (OCT.DestPath, "/")
END
END
ELSE
IO.WriteF1
(" !! DST directory %s doesn't exist\n", Args.argv [arg]);
HALT (Dos.returnWarn)
END
ELSIF (argStr = "NS") OR (argStr = "NEWSYMFILE") THEN
newsymfile := TRUE
ELSIF argStr = "FORCE" THEN
Compiler.forceCode := TRUE
ELSIF argStr = "VERBOSE" THEN
OCG.Verbose := TRUE;
ELSIF argStr = "DEBUG" THEN
OCC.Debug := TRUE
ELSIF argStr = "TRACE" THEN
OCG.StartTrace ()
ELSIF argStr = "BATCH" THEN
batch := TRUE
ELSIF argStr = "TEXTERR" THEN
OCS.binErrFile := FALSE
ELSE
EXIT
END;
INC (arg);
END; (* LOOP *)
OCT.AddPath (SYS.ADR ("OLIB:"));
IF arg < Args.argc THEN
WHILE arg < Args.argc DO
COPY (Args.argv [arg]^, argStr); INC (arg);
IF batch THEN DoBatch (argStr)
ELSE DoCompile (argStr)
END
END
ELSIF Dos.base.IsInteractive (Dos.base.Input ()) THEN
DoInteractive ()
END;
OCG.EndTrace ()
END CliMain;
BEGIN (* Main *)
Compiler.newSF := FALSE; Compiler.forceCode := FALSE;
OCG.Verbose := FALSE; OCS.binErrFile := TRUE;
IF Args.IsCLI THEN
CliMain ()
ELSE
WbMain ()
END
END Main;
BEGIN (* OC *)
IO.WriteStr (OCRev.vString);
IO.WriteStr (CopyrightStr);
IO.WriteStr (UsageStr);
IO.WriteLn ();
IF E.base.version >= 37 THEN
Init();
Main();
IF returnError THEN HALT (Dos.returnError) END;
ELSE
IO.WriteStr (" !! OC requires AmigaOS 2.04+\n");
HALT (Dos.returnWarn)
END
END OC.
(***************************************************************************
$Log: OC.mod $
Revision 4.9 1994/08/14 10:36:42 fjc
- Argument parsing code now checks that SYM and DST
directories actually exist.
Revision 4.8 1994/08/03 11:51:34 fjc
- Added TEXTERR option.
Revision 4.5 1994/07/10 13:37:06 fjc
- Changed to use new SETCLEANUP format.
Revision 4.2 1994/06/05 22:35:47 fjc
- Changed to use new Amiga interface.
- Added FORCE argument.
Revision 4.1 1994/06/01 09:33:44 fjc
- Bumped version number
***************************************************************************)