(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: Main.m3 *) (* Last modified on Wed Apr 15 09:55:58 PDT 1992 by kalsow *) (* modified on Sun Jan 21 06:56:46 1990 by muller *) MODULE Main; IMPORT Wr, Fmt, Thread; IMPORT String, Token, Error, Scanner, Value, Scope; IMPORT Module, Type, BuiltinTypes, Emit, Host; IMPORT BuiltinOps, WordModule, M3, ETimer, Coverage, Marker; IMPORT Ident, ReelExpr, TextExpr, Temp, Constant, Procedure; IMPORT ESet, Fault; PROCEDURE Initialize () = BEGIN (* this list is ordered! *) Host.Initialize (); IF (Host.emitBuiltins) THEN Module.depth := 1 END; String.Initialize (); Token.Initialize (); Scanner.Initialize (); Scope.Initialize (); Type.Initialize (); Value.Initialize (); BuiltinTypes.Initialize (); BuiltinOps.Initialize (); WordModule.Initialize (); Module.Initialize (); END Initialize; PROCEDURE Reset (): BOOLEAN = BEGIN (* this list is ordered! *) IF NOT Host.Reset () THEN RETURN FALSE END; (* ETimer.ResetAll(); *) String.Reset (); Scanner.Reset (); Emit.Reset (); Fault.Reset (); Scope.Reset (); Coverage.Reset (); Error.Reset (); Marker.Reset (); ESet.Reset (); Type.Reset (); Value.Reset (); Module.Reset (); Ident.Reset (); ReelExpr.Reset (); TextExpr.Reset (); Temp.Reset (); Constant.Reset (); Procedure.Reset (); RETURN TRUE; END Reset; PROCEDURE Compile () = VAR m: Module.T; cs := M3.OuterCheckState; BEGIN Scanner.Push (Host.filename, Host.source); StartPhase ("initializing builtins"); Scope.TypeCheck (Scope.Initial, cs); Value.TypeCheck (WordModule.M, cs); StartPhase ("parsing"); m := Module.Parse (); IF Failed () THEN RETURN END; StartPhase ("type checking"); Module.TypeCheck (m, TRUE, cs); IF Failed () THEN RETURN END; StartPhase ("emitting code"); IF (Host.emitBuiltins) THEN Scope.Enter (Scope.Initial); Module.Compile (WordModule.M); ELSE Module.Compile (m); END; IF Failed () THEN RETURN END; END Compile; PROCEDURE StartPhase (tag: TEXT) = <*FATAL Wr.Failure, Thread.Alerted*> BEGIN IF (Host.verbose) THEN Wr.PutText (Host.errors, tag); Wr.PutText (Host.errors, "...\n"); END; END StartPhase; PROCEDURE Failed (): BOOLEAN = VAR errs, warns: INTEGER; BEGIN Error.Count (errs, warns); RETURN (errs > 0); END Failed; PROCEDURE Finalize () = <*FATAL Wr.Failure, Thread.Alerted*> VAR errs, warns: INTEGER; speed: LONGREAL; BEGIN Scanner.Pop (); Emit.Finalize (); Error.Count (errs, warns); IF (Host.do_timing) THEN ETimer.Dump (Host.errors); speed := FLOAT (Scanner.nLines, LONGREAL) / ETimer.TotalElapsed (); Wr.PutText (Host.errors, Fmt.Int (Scanner.nLines)); Wr.PutText (Host.errors, " lines ("); Wr.PutText (Host.errors, Fmt.Int (Scanner.nPushed)); Wr.PutText (Host.errors, " files) scanned, "); Wr.PutText (Host.errors, Fmt.LongReal (speed, 1, Fmt.Style.Flo)); Wr.PutText (Host.errors, " lines / second.\n\n"); END; IF (errs > 0) THEN Wr.PutText (Host.errors, Fmt.Int (errs)); Wr.PutText (Host.errors, " error"); IF (errs > 1) THEN Wr.PutText (Host.errors, "s") END; END; IF (warns > 0) THEN IF (errs > 0) THEN Wr.PutText (Host.errors, " and ") END; Wr.PutText (Host.errors, Fmt.Int (warns)); Wr.PutText (Host.errors, " warning"); IF (warns > 1) THEN Wr.PutText (Host.errors, "s") END; END; IF (errs + warns > 0) THEN Wr.PutText (Host.errors, " encountered\n") END; END Finalize; BEGIN TRY Initialize (); WHILE Reset () DO Compile (); Finalize (); END; FINALLY Host.Halt (0); END; END Main.