Date: Fri, 02 Nov 90 11:03:50 PST From: Eric Muller Subject: CALL FOR VOTES: comp.lang.modula3 The discussion period for the creation of comp.lang.modula3 is now over. It seems that there is enough support to go ahead with the call for votes, so here it is. NAME: comp.lang.modula3 STATUS: unmoderated CHARTER: Modula-3 is a new programming language (see below for a short description). This newsgroup would serve to discuss all aspects of the language, such as use of language, good style, availability of implementations, implementation techniques. WHY A GROUP ? There are currently two freely available implementations of the language. Other people are also working on implementations. There are also two mailing lists related to Modula-3: one as been setup to discuss the use of one of the implementations; the other deals more with implementation issues. It seems that the level of interest in Modula-3 and the traffic on theses lists is now large enough to justify the creation of a newsgroup. SCHEDULE: 1. Voting: The vote will run for 21 days starting today (11/2/90). Votes should be received before or on 11/23/90 to be valid. Votes should be sent to muller@src.dec.com, and have "comp.lang.modula3" in the subject line. If you want to vote for the creation of comp.lang.modula3, include the word "yes" in the subject line. If you want to vote against the creation of the group include the word "no" in the subject line. I will post a second Call For Votes, and possibly a list of unreachable return addresses, on 11/16/90. When the vote is over, I will post the final results. 2. Waiting Period: I will observe the normal waiting period of five days from the time that the final results appear in news.announce.newgroups. During this time, people may report lost votes. 3. Consummation: After the waiting period, I will issue the appropriate control message to create comp.lang.modula3. About one week later, I will re-issue the creation control message. SHORT DESCRIPTION OF MODULA-3: Modula-3 is a new programming language. The goals of its design are best encapsulated in the preface to the "The Modula-3 Report (Revised)", (L. Cardelli, J. Dohnaue, L. Glassman, M. Jordan, B. Kalsow, G. Nelson, DEC Systems Research Center, Palo Alto, CA and Olivetti Research Center, Menlo Park, CA, Nov 89.): The goal of Modula-3 is to be as simple and safe as it can be while meeting the needs of modern systems programmers. Instead of exploring new features, we studied the features of the Modula family of languages that have proven themselves in practice and tried to simplify them into a harmonious language. We found that most of the successful features were aimed at one of two main goals: greater robustness, and a simpler, more systematic type system. Modula-3 descends from Mesa, Modula-2, Cedar, and Modula-2+. It also resembles its cousins Object Pascal, Oberon, and Euclid. Modula-3 retains one of Modula-2's most successful features, the provision for explicit interfaces between modules. It adds objects and classes, exception handling, garbage collection, lightweight processes (or threads), and the isolation of unsafe features. ------------------------------------------------------------------------------ Date: Mon, 5 Nov 90 18:53:09 EST From: sdl@mbunix.mitre.org (Litvintchouk) Subject: BYTE Modula-3 article > Date: Fri, 2 Nov 90 13:10:29 EST > From: harbison@tartan.com > > My article on Modula-3 is in the current (November) of BYTE, p. 385. If you > would like a photocopy, call or send me your name/address and I'll send you a > copy. > > Sam Harbison > Pine Creek Software > 305 S. Craig St., Suite 300 > Pittsburgh, PA 15213 > 412-681-9811 I would very much like a copy of your paper. Also, do you know if anyone is developing or porting public domain or commercial Modula-3 compilers for: Macintosh (Finder, not A/UX) Commodore Amiga Both these machines could really use an object-oriented system programming language like Modula-3 (I don't care much for C++, and Objective-C is not available). Steven Litvintchouk MITRE Corporation Burlington Road Bedford, MA 01730 (617)271-7753 ARPA: sdl@mbunix.mitre.org UUCP: ...{att,decvax,genrad,ll-xn,philabs,utzoo}!linus!sdl "Where does he get those wonderful toys?" ------------------------------------------------------------------------------ Date: Tue, 06 Nov 90 12:38:24 PST From: Eric Muller Subject: October m3 mailing list archive available The mail archive for the messages sent to the m3 mailing list during the month of October is available via anonymous ftp from gatekeeper.dec.com, in pub/DEC/Modula-3/m3-mail.10-90.Z. Previous months can be found in the same directory. Eric Muller. ------------------------------------------------------------------------------ System Research Center - 130 Lytton Av. - Palo Alto, CA 94301 - (415) 853 2193 ------------------------------------------------------------------------------ Date: Wed, 7 Nov 90 10:40:57 EST From: harbison@tartan.com Subject: SIO input/output interface Attached is a proposed general-purpose I/O interface for Modula-3. If after looking at the interface you want to know more, send me a note and I'll send you the written documentation. (Sorry, it's not emailable.) Comments are welcome. Due to circumstances partially under my control, I did NOT run this interface through the SRC Modula-3 compiler, so please excuse careless syntax problems. INTERFACE SIO; (* v1.0 11/7/90 *) (***** SIO Input/Output Interface for Modula-3 programs. Copyright 1990 Samuel P. Harbison. 305 S. Craig St., Suite 300, Pittsburgh, PA 15213. (412) 681-9811. email: Harbison@Tartan.COM This interface presents a number of input/output facilities that are useful for general programming and student projects in Modula-3. SIO gathers together a number of operations and interfaces for SRC Modula-3's readers and writers, adds others, and smooths them all into a consistent style. Readers and writers are generically referred to as "streams" in this interface. The documentation in this interface is minimal. A detailed (20 pp.) manual for SIO is available by writing or e-mailing to the above address. (The documentation is currently available only in written form, since it is formatted in Microsoft Word on a Macintosh.) Comments are solicited. This interface (as modified) will be used in a forthcoming Modula-3 textbook, and an implementation for SRC Modula-3 will be created and made available. *******) IMPORT Rd, Wr; TYPE RdT = Rd.T; (* So you don't have to import Rd and Wr *) WrT = Wr.T; (* Exception SIO.Error, and the input and output style types are defined after the input/output procedures in this interface. *) PROCEDURE OpenInput (FileName : TEXT ) : Rd.T RAISES {Error}; PROCEDURE OpenOutput (FileName : TEXT; append := FALSE) : Wr.T RAISES {Error}; PROCEDURE Exists(FileName: TEXT) : BOOLEAN RAISES {}; PROCEDURE Writable(FileName: TEXT) : BOOLEAN RAISES {}; PROCEDURE Delete(FileName: TEXT) RAISES {Error}; PROCEDURE Rename(OldName, NewName : TEXT) RAISES {Error}; PROCEDURE TemporaryName(brand : TEXT:=NIL) : TEXT RAISES {}; (* Returns a unique, system-generated name for a temporary file. The name is then used in a call to OpenOutput. *) (* The "current" input and output streams are used when no explicit stream argument is specified in an input or output procedure call (i.e., when that argument is nil). The current streams are initially set to the "standard" input and output of UNIX. *) PROCEDURE CurrentInput () : Rd.T RAISES {}; (* Fetch current streams *) PROCEDURE CurrentOutput () : Wr.T RAISES {}; PROCEDURE SetInput (f: Rd.T := NIL) RAISES {}; (* Change current streams *) PROCEDURE SetOutput (f: Wr.T := NIL) RAISES {}; PROCEDURE StandardError() : Wr.T RAISES {}; (* UNIX stderr *) (* Streams are closed on program termination, but can also be closed explicitly. *) PROCEDURE CloseOutput (f: Wr.T := NIL) RAISES {}; PROCEDURE CloseInput (f: Rd.T := NIL) RAISES {} (* Determine some characteristics of an input stream: *) PROCEDURE Intermittent(f: Rd.T := NIL) : BOOLEAN RAISES {Error}; PROCEDURE InputLength(f: Rd.T := NIL) : CARDINAL RAISES {Error}; PROCEDURE EOF(f: Rd.T := NIL) : BOOLEAN RAISES {Error}; (* end-of-stream? *) PROCEDURE EOL(f: Rd.T := NIL) : BOOLEAN RAISES {Error}; (* end-of-line? *) (* Output operations *) PROCEDURE PutChar(item : CHAR; f: Wr.T := NIL; s:= DefaultOutputStyle) RAISES {Error}; (* Writes single character, no translation *) PROCEDURE PutCharLiteral(item : CHAR; f: Wr.T := NIL; s:= DefaultOutputStyle) RAISES {Error}; (* Writes quoted, escaped literal, e.g., '\n' *) PROCEDURE PutText(item: TEXT; f: Wr.T := NIL; s:= DefaultOutputStyle) RAISES {Error}; (* Writes TEXT with no translation *) PROCEDURE PutTextLiteral(item: TEXT; f: Wr.T := NIL; s:= DefaultOutputStyle) RAISES {Error}; (* Writes quoted, escaped string, e.g., "Hi!\n" *) PROCEDURE PutBool(item: BOOLEAN; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; (* Writes TRUE or FALSE *) PROCEDURE PutInt(item INTEGER; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; PROCEDURE PutWord(item: Word.T; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; (* Like PutInt except for parameter type *) PROCEDURE PutReal(item: REAL; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; PROCEDURE PutLongReal(item: LONGREAL; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; PROCEDURE PutExtended(item: EXTENDED; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; PROCEDURE PutRef(item: REFANY; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; (* Like PutInt except for parameter type *) PROCEDURE PutAddress(item: ADDRESS; f: Wr.T := NIL; s := DefaultOutputStyle) RAISES {Error}; (* Like PutInt except for parameter type *) PROCEDURE PutLine(item : TEXT := NIL; f: Wr.T := NIL; s:= DefaultOutputStyle) RAISES {Error}; (* Like PutText folloed by PutChar('\n') *) (* Input operations. Except for GetChar and GetAll, the procedures expect their input to be on the current line. Leading whitespace is skipped. This can be changed by the input style. *) RROCEDURE GetChar(f: Rd.T := NIL; s:= DefaultInputStyle) : CHAR RAISES {Error}; PROCEDURE GetCharLiteral(f Rd.T := NIL; s:= DefaultInputStyle) : CHAR RAISES {Error}; (* Read and translate a char literal, e.g., '\n' *) PROCEDURE UngetChar(c: CHAR; f: Rd.T := NIL) RAISES {Error}; PROCEDURE GetText(f: Rd.T := NIL; s:= DefaultInputStyle) : TEXT RAISES {Error}; (* Reads whitespace-terminated string *) PROCEDURE GetTextLiteral(f: Rd.T := NIL; s:= DefaultInputStyle) : TEXT RAISES {Error}; (* Reads TEXT literal, e.g., "Hi!\n" *) PROCEDURE GetLine(f: Rd.T := NIL; s:= DefaultInputStyle) : TEXT RAISES {Error}; (* Read rest of line and discard newline *) PROCEDURE GetInt(f : Rd.T := NIL; s:= DefaultInputStyle) : INTEGER RAISES {Error}; PROCEDURE GetWord(f : Rd.T := NIL; s:= DefaultInputStyle) : Word.T RAISES {Error}; PROCEDURE GetReal(f : Rd.T := NIL; s:= DefaultInputStyle) : REAL RAISES {Error}; PROCEDURE GetLongReal(f : Rd.T := NIL; s:= DefaultInputStyle) : LONGREAL RAISES {Error}; PROCEDURE GetExtended(f : Rd.T := NIL; s:= DefaultInputStyle) : EXTENDED RAISES {Error}; PROCEDURE GetBool(f : Rd.T := NIL; s:= DefaultInputStyle) : BOOLEAN RAISES {Error}; PROCEDURE GetAll(f: Rd.T := NIL; s:= DefaultInputStyle) : TEXT RAISES {FileError}; (* Read to end-of-stream *) PROCEDURE SkipLine(f : Rd.T := NIL; s := DefaultInputStyle); (* Discard rest of this line, advance to next. *) (* Errors: All errors map to the single exception SIO.Error, whose parameter will supply additional information about the cause. *) EXCEPTION Error(REF ErrorDetail); TYPE ErrorDetail =RECORD Kind := ErrorKind.Unkknown; File : TEXT := NIL; Direction := ErrorDirection.Unknown; LineNumber : CARDINAL := 0; CharNumber : CARDINAL := 0; END; ErrorKind = {Unknown, Name, NotFound, Closed, Access, SpaceExhausted, System, Format, Numeric, EndOfLine, EndOfStream}; ErrorDirection = {Unknown, Input, Output}; PROCEDURE ErrorText( e: ErrorDetail ) : TEXT; (* Turns a parameter from the Error exception to a human-readable message. *) (* Output styles: All output operations take a style parameter that provides a way to customize the output and yet keep the argument list short. The parameter is normally defaulted. *) CONST DefaultOutputStyle = OutputStyle{}; TYPE OutputStyle = RECORD NumberBase : [2..16]:= 10; Signed := TRUE; FStyle := FloatingType.Mix; Precision: CARDINAL := 6; Width: CARDINAL := 0; Alignment := AlignType.General; TrueOutput : TEXT := NIL; FalseOutput : TEXT := NIL; PaddingChar := ' '; TypeStyle := SET OF TypeAttribute{}; TypeSize: CARDINAL := 0; (*points; 0 means default size *) TypeFont: TEXT := NIL; (* NIL means default font *) x, y: INTEGER := 0; END; FloatingType = {Flo, AltFlo, Sci, AltSci, Mix }; AlignType = {General,Left,Center,Right}; TypeAttribute = {Bold,Italic,Underline,Shadow,Blink}; (* Input styles: All input operations take an input style parameter that can be used to customize the way input is performed. The parameter is normally defaulted. *) CONST DefaultInputStyle = InputStyle {}; TYPE InputStyle = RECORD Width : CARDINAL := 0; Signed := TRUE; Whitespace := SET OF CHAR {' ','\t'}; TrueInput, FalseInput: TEXT := NIL; (* If NIL, use built-in defaults *) END; END SIO. ------------------------------------------------------------------------------ Date: Tue, 13 Nov 90 15:13:57 EST From: Norman Ramsey Subject: prettyprinting in m3 I am having a lot of trouble getting the prettyprinter (`Formatter') to do what I want it to do. For example, I can't seem to get it to restore the previous left margin after Formatter.End, so I have had to resort to `Formatter.Newline(wr,offset := -4)' to get the effect I am looking for. Is there anyone out there who understands `Formatter' or who has used it successfully? I think I would be happier with a simpler prettyprinter that I had a better chance of understanding. Does anyone know of one? Norman ------------------------------------------------------------------------------ Date: Mon, 12 Nov 90 20:38:13 +0100 From: tubsibr!buschman@relay.EU.net (Andreas Buschmann) Subject: Modula3 wish list Hello, Some time ago someone asked for a Modula3 wish list. Here is a personal one. o In addition to the type REFANY let's have a type ANY. To a variable or parameter of type ANY a value of every available type should be assignable. It would be very usefull for e.g. an I/O package, you could have something like printf in C, but with full typechecking. An example: TYPE P = ARRAY OF ANY; PROCEDURE writef (READONLY format: TEXT; READONLY params: ARRAY OF ANY := P{}; READONLY outfile: File := stdout) = ... BEGIN ... TYPECASE params[i] OF INTEGER (i) => ... CHAR (c) => ... TEXT (t) => ... ... END; ... END printf; ... writef ("Hello world, this is my %d%s try\n", P{ 1, "st" }); writef ("Hello underground, this is my %d%s try\n", P{ 2, "nd" }, stderr ); ANY should be supertype to every other type. o Make the `Type' optional in the `Constructor' production: Constructor = [ Type ] "{" [ SetCons | RecordCons | ArrayCons ] "}" instead of: Constructor = Type "{" [ SetCons | RecordCons | ArrayCons ] "}" if type is omitted, the type of this expression should be `ARRAY n OF ANY' which should be assignable to sets, records and arrays, but only if the corresponding elementtypes are assignable. What do you think about it? Is this reasonable? Why?, Why not? Tschuess Andreas ------------------------------------------------------------------------------ Date: Wed, 14 Nov 90 08:42:10 EST From: moss%ibis@cs.umass.edu (Eliot Moss) Subject: Buschman's ANY proposal I sent a number of proposals prior to a language designer / revision meeting last May, though near as I can tell they were nmot received by most people, and certainly were not discussed or acted upon. One of my proposal was for an ANY type, but it was a bit different from what Andreas proposed. Andreas's proposal is not workable, for a simple reason: one cannot determine the size of an ANY and hence cannot allocate storage for it. If we are to have a type such as ANY, then we need to restrict where and how it can be used, and the rules are similar to those for open arrays. My original proposal suggested that ANY be allowed as a type for a parameter, but not for an ordinary variable. I then suggested an extension whereby variable length argument lists (sort of like C varargs, but nicer) would turn into an implicit ARRAY OF ANY. But note that this is all implementable, since the caller of such a routine would pass a type descriptor (type code) and the location of the actual (or of a caller allocated and initialized copy of the actual in the case of VALUE parameters) -- the parameters themselves are thus of fixed size. My ANY proposal may need a little more work, but I think it adds something useful to the language, and it can work nicely with the proposal for variable length argument lists. (Personally I have never really bought the argument that string catenation allows you to do things almost as nicely as C, LISP, etc., format strings; for one thing, when you don't have format strings, you can't make input/output format a simply rearranged option -- each I/O site would have to be changed to change overall I/O appearance.) As for omitting the type on constructors, I am not sure what that buys us. If the goal is to save some typing by having the compiler infer types, I have never subscribed to that attitude -- redundant information helps uncover errors, plain and simple. If there is some other benefit, perhaps it could be made more clear. Maybe I'll try to revive some of my earlier proposals ..... Eliot J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206; Moss@cs.umass.edu ------------------------------------------------------------------------------ Date: Wed, 14 Nov 90 10:27:43 EST From: saber.com!wyant@saber.com Subject: Re: Modula3 wish list Some time ago someone asked for a Modula3 wish list. Here is a personal one. o In addition to the type REFANY let's have a type ANY. To a variable or parameter of type ANY a value of every available type should be assignable. It would be very usefull for e.g. an I/O package, you could have something like printf in C, but with full typechecking. ----------------------------------------------------------------------------- A type of ANY doesn't really work in a world that is not completely referenced based. For instance, how big should the elements of an array of type ANY be ? How does a called procedure know the size of an ANY parameter ? How does it find the parameters after an ANY parameter ? Languages like CLU get away with it because they use reference paramaters and values uniformly. This would be a radical change to Modula-3. I'm sure it would give the typechecking people fits anyway. -- Geoff wyant@saber.com ------------------------------------------------------------------------------ Date: Wed, 14 Nov 90 15:07:42 EST From: Norman Ramsey Subject: Re: Modula3 wish list If we're wishing, I wish I could declare a variable in an interface that could be read by anyone importing the interface, but written only by the module exporting that interface. Perhaps the syntax READONLY instead of VAR would be appropriate. For example, the variables in M3toC might properly be declared READONLY. Norman ------------------------------------------------------------------------------ Date: Wed, 14 Nov 90 17:06:02 EST From: Norman Ramsey Subject: dependency analysis Does anybody have a tool to print out the names of all the interfaces in a program in depth-first order? I have thought about playing copycat with m3imc.c but I looked at the source and was more mystified than enlightened. Norman ------------------------------------------------------------------------------ Date: Mon, 12 Nov 90 14:10:12 EST From: saber.com!wyant@saber.com Subject: Olivetti M3 Just out of curiousity, what ever became of the M3 implementation that Mick Jordan, et. al., were doing at Olivetti ? Does anyone know how far they got ? Seems like they had some interesting ideas, building the tools around the AST of the units being compiled. Any plans to incorporate some these ideas into SRC Modula-3 ? Thanks, Geoff Wyant wynat@saber.com ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 13:43:54 EST From: Norman Ramsey Subject: inlining It seems to me unlikely that an implementation of Modula-3 will ever inline procedures across interface boundaries (how would it know which module exports the interface in which an inlined procedure appears). But I am interested in what other people think. How would you implement inlining across interface boundaries? Norman ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 14:06:03 EST From: emery@d74sun.mitre.org (David Emery) Subject: Re: inlining Ada supports this now. It's a pragma, and not all compilers do it in all circumstances, but it essentially works like macro expansion. The library system maintains the fact that the using routine has a dependency on the body of the inlined procedure. Depending on the compiler, most (if not all) compilers ignore the inline if the body of the inlined procedure hasn't been compiled yet. A really friendly compiler can wait until the body is compiled, and then go back and 'expand' the body at each point of use. The best Ada compilers do exactly this with generics that have been separately compiled. The recompilation tool should make use of the additional dependency to insure that the body of the inlined procedure is compiled before the using procedure. This can lead to potential circular orders of compilation, which is why the compiler has to be able to ignore it (hopefully with a warning) sometimes. dave emery emery@aries.mitre.org ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 14:30:28 EST From: Norman Ramsey Subject: Re: inlining > Ada supports this now. It's a pragma, and not all compilers do it in > all circumstances, but it essentially works like macro expansion. The > library system maintains the fact that the using routine has a > dependency on the body of the inlined procedure. Depending > on the compiler, most (if not all) compilers ignore the inline if the > body of the inlined procedure hasn't been compiled yet. How does the Ada compiler know where to find the body of the inlined procedure? Modula-3 guarantees that the body can be found in whatever module exports the appropriate interface, but the identity of that module isn't known until link time. Or is it? Norman ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 11:43:13 PST From: Eric Muller Subject: Re: inlining This is personnal opinion and does not reflect what may happen in SRC Modula-3. On DECstations, there is a global optimizer. The C compiler generates U-code (a variant of P-code), the linker can take U-code to produce U-code, the global optimizer transforms this linked U-code and sends it to the final code generator. Today, this global optimizer does global register allocation. It also does code reorganization based on profiling information. I think the global optimizer is actually the best place to do it, as the U-code contains enough information and the problem you mention is solved. Given the availability of profiling information in that stage, I don't see any reason why the decision about which procedures to inline should not be left to the optimizer. In the case of SRC Modula-3, this technique is simple to implement; there is nothing to do for us! The same is true for a native compiler that generates U-code. Eric Muller. ------------------------------------------------------------------------------ System Research Center - 130 Lytton Av. - Palo Alto, CA 94301 - (415) 853 2193 ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 14:31:58 EST From: emery@d74sun.mitre.org (David Emery) Subject: Re: inlining The Ada program library has two functions: For the compiler, it finds and resolves references to other specs. Specifically, when I say "with foo;", it locates and loads the interface information for package foo. For the linker, it marries up specs with bodies and provides the linker with information on elaboration ordering requirements (elaborate foo before bar, because bar depends on foo.) Modula-3 also needs support for these two functions, but much of the program library information is implicit (in things like directory structure, file names, and paths) rather than explicit, as in Ada. dave ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 20:44:24 EST From: emery@d74sun.mitre.org (David Emery) Subject: Re: Inlining Well, I understand the problem better now, but this brings me back to an old opinion I've occasionally expressed about Ada: Code generation at compile-time seems stupid. Inlining is only one of many cross-compilation unit optimizations that make sense in separately-compiled languages such as Ada and Mod-3. Furthermore, postphoning code generation supports the observation that one compiles a unit many, many times more often than one links a program, so shortening compile times should be more 'user-friendly'. It's worth noting that the Meridian PC Ada compiler postphones code optimizations until link-time, but I think that their optimizer more closely resembles a peep-hole optimizer rather than a full code-generator. Comments from you compiler implementors out there? dave emery ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 17:35:42 EST From: saber.com!wyant@saber.com Subject: Re: inlining It seems to me unlikely that an implementation of Modula-3 will ever inline procedures across interface boundaries (how would it know which module exports the interface in which an inlined procedure appears). But I am interested in what other people think. How would you implement inlining across interface boundaries? Norman In theory, one could build an environment where part of the compilation process would stored analyzed representations of a program in program database. When encountering a declaration with the <*inline*> pragma, the definition could be retrieved from the database. However, I don't know of any environments that support this yet. Perhaps some of the ADA environments ? -- geoff wyant@saber.com ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 17:40:10 EST From: saber.com!wyant@saber.com Subject: Re: Modula3 wish list If we're wishing, I wish I could declare a variable in an interface that could be read by anyone importing the interface, but written only by the module exporting that interface. Perhaps the syntax READONLY instead of VAR would be appropriate. For example, the variables in M3toC might properly be declared READONLY. Norman This seems like a fairly reasonable suggestion, though I might prefer 'CONST' to 'READONLY'. One of the things I like about C++ is the addition of 'const' and 'protected', 'private', and 'public' in class declartions. ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 17:00:38 EST From: moss%ibis@cs.umass.edu (Eliot Moss) Subject: Inlining First, an explanation to David Emery of the nature of the problem Norman posed ... In Ada, the interfaces and bodies are one-to-one, so if something appears in interface FOO, then the body will be in body FOO. In Modula-3 any module may implement (EXPORT) any interface; the relationship is many-to-many. In particular, several modules may implement a single interface, each implementing only part of the interface, and a module may implement (all or parts of) many modules. Thus, it is not at all obvious how to find the body of something from the interface, and it is program dependent, since different programs might be composed of different collections of modules all implementing the same interface (presumably in usefully different ways). Separate compilation and compile-time inlining are essentially antithetical: one separates modules, the other glues them together. A later optimization phase, such as the MIPS U-code discussed by Eric (note, it is not DEC systems i n general but only the MIPS based DEC products that have this, and only for the MIPS cc compiler, not gcc, etc.) is a reasonable solution. This is probably all as it should be, but the tools have not entirely caught up with the approaches yet ..... Eliot J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206; Moss@cs.umass.edu ------------------------------------------------------------------------------ Date: Thu, 15 Nov 90 18:58:18 EST From: Norman Ramsey Subject: Re: Modula3 wish list > > [I propose READONLY variables in interfaces] > > This seems like a fairly reasonable suggestion, though I might prefer > 'CONST' to 'READONLY'. CONST is already used in interfaces to denote true compile-time constants. What syntax did you have in mind? Norman ------------------------------------------------------------------------------ Date: Fri, 16 Nov 1990 06:28:47 PST From: James_E._Heliotis.ROCH803@xerox.com Subject: Re: Inlining ----------------------------------------------------- Furthermore, postphoning code generation supports the observation that one compiles a unit many, many times more often than one links a program, so shortening compile times should be more 'user-friendly'. ----------------------------------------------------- I am not sure I agree with that -- I think this is best explained by example: # compile module1 -- errors result -- only early passes of compiler are invoked anyway, so time is short # -- fix errors # compile module1 : : # compile module1 -- successful! Compiler runs through all its passes # compile module2 -- errors; here we go again : : # compile moduleN -- successful! Compiler run in its entirety N times # link module1 module2 ... moduleN # -- run program -- errors found; fix one module # -- fix errors # compile modulei # link module1 module2 ... moduleN -- repeat last 4 steps until program works OK, the points are that 1) Compiling a module that contains compiler-detectable errors is quick -- the code generation pass almost never runs. 2) Once a program is linked for the first time, revisions change very few modules, so at this point, modules get sent to the linker much more often than they are sent to the compiler. Therefore, I believe that putting off code generation until link time slows down the process of generating correct code. Jim ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 09:36:07 EST From: emery@d74sun.mitre.org (David Emery) Subject: Re: Inlining You make a good point about the debug cycle, as opposed to the compile cycle. Here's where a really smart linker could do "delta code generation" on the changes to the module in question. The alternative is to have a non-optimizing code generation mode to support this kind of turnaround, and then send it to the "grand optimizer" for final testing, etc. dave ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 10:08:49 EST From: saber.com!wyant@saber.com Subject: Re: Inlining --- excerpted from James Heliotis' message --- OK, the points are that 1) Compiling a module that contains compiler-detectable errors is quick -- the code generation pass almost never runs. 2) Once a program is linked for the first time, revisions change very f ew modules, so at this point, modules get sent to the linker much mor e often than they are sent to the compiler. Therefore, I believe that putting off code generation until link time s lows down the process of generating correct code. Jim ------------------------------ Not necessarily, if one is willing to abandon the traditional tool view of a compiler. For instance, if the compiler and other "tools" stored derived softwa re objects in a database. For instance, the result of compiling a module is a 'u-c ode' object. The result of linking could store a an 'object file' object in the data base. If the module contained no inlines, then the object file could be used directly and the 'u-code -> object' translation step skipped. I think this points out though that languages such as Modula-3 can benefit from new paradigms for dependency analysis, configuration management, and tool integrati on. Anyone want to start such a discussion. Any views or opinions above are strictly my own, and have no relationship with my employer. -- Geoff Wyant wyant@saber.com ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 08:29:40 PST From: patl@Eng.Sun.COM (Pat Lashley [MtV NeWStech Eng.]) Subject: Re: Modula3 wish list |> If we're wishing, I wish I could declare a variable in an |> interface that could be read by anyone importing the interface, |> but written only by the module exporting that interface. |> Perhaps the syntax READONLY instead of VAR would be |> appropriate. For example, the variables in M3toC might |> properly be declared READONLY. |> |> Norman |> |> This seems like a fairly reasonable suggestion, though I might prefer |> 'CONST' to 'READONLY'. One of the things I like about C++ is the |> addition of 'const' and 'protected', 'private', and 'public' in class |> declartions. CONST and READONLY imply different semantics. CONST implies that the value never changes, so the optimizer need not worry about re-loading the value after calls to external functions. READONLY implies that the value may only be changed by the owning module. READONLY is effectivly an inlined accessor function with variable/constant syntax instead of function syntax. -Pat ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 11:43:56 EST From: saber.com!wyant@saber.com Subject: Re: Modula3 wish list (CONST vs. READONLY) The way I view CONST is that it indicates permissible usage of this item to the clients of this item. Thus an item may be CONST (i.e. unassignable) to the clients of an interface, but non-CONST to the implementation of the interface. C++ has much the same notion when it comes to parameter passing: a parameter may be declared as 'const' to indicate that the called routine is not allowed to assign to the parameter. However the item in the calling routine may indeed may be non-'const'. Of course, I'll accept arguments that this overloads the CONST keyword too much, and hence is poor language design. 'nuff said. -- Geoff wyant@saber.com ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 17:20:20 EST From: harbison@tartan.com Subject: Re: inlining Ada has somewhat the same characteristics as M3 here. Ada implementations DO inline-expand procedures declared in an interface and supplied in a body (ah, er, module). There is a "soft" compilation dependency from users of the interface to the module implementing the inlined procedure. (The module must be compiled before the interface's clients are in order to get the inlining.) I think its a good feature, although it requires some implementing. Oh, of course, with Ada's "library" mechanism, the module implementing the inlined procedure can be discovered and recorded. I think a good M3 implementation would also have a library facility. I think a good implementation should have a library facility. Sam ------------------------------------------------------------------------------ Date: Fri, 16 Nov 90 17:38:57 EST From: harbison@tartan.com Subject: SRC Modula-3 on floppies Well, I hate to even mention this, but... Would anyone out there be interested in getting the SRC Modula-3 1.5 release on floppy disks? I *might* be able to supply the release on one or more of the following media: - Macintosh-formatted SyQuest 44-meg removable disk (1 of them) - Macintosh-formatted 800K floppies (compressed with Stuffit) (20 of them?) - PC-formatted 3-1/2" HD disks, compressed with (?) (15 of them?) You'd probably have to send me the blank media, or pay a corresponding amount. As long as we're at it, you might as well tell me what other media you'd like. (Sun 150-meg tape?). I realize that most of the readers of this BBoard do OK with net access of M3, but I'm interested in the response. Sam ------------------------------------------------------------------------------ From: jay@hermix.UUCP (Jay Skeer) Subject: Modula3 wish list Date: Fri, 16 Nov 90 16:15:23 PST >From: patl@eng.sun.com (Pat Lashley [MtV NeWStech Eng.]) > CONST and READONLY imply different semantics. CONST implies that the > value never changes, so the optimizer need not worry about re-loading > the value after calls to external functions. READONLY implies that > the value may only be changed by the owning module. READONLY is effectivly > an inlined accessor function with variable/constant syntax instead of > function syntax. In many C compilers there is the storage class VOLITILE. Volitile means that the compiler can not assume that the value remains unchanged over time. This is typicaly used for memory maped input devices. Can Modula-3 do that? Ought it? j' ------------------------------------------------------------------------------ Date: 16 Nov 1990 1716-PST (Friday) From: Subject: Re: Olivetti M3 This is a reposting of an article that didnt make it to the external list. SRCers can ignore it. In article <9011121910.AA13608@riposte>, saber.com!wyant@saber.com writes: > Just out of curiousity, what ever became of the M3 implementation > that Mick Jordan, et. al., were doing at Olivetti ? Does anyone > know how far they got ? Seems like they had some interesting ideas, > building the tools around the AST of the units being compiled. Any plans > to incorporate some these ideas into SRC Modula-3 ? > Those people who managed to ftp the system before Olivetti closed ORC down have a valid licence to use it, re-export it etc, as provided by the terms of that licence. As you can see I joined the competition and to this date still use the Olivetti system for my M3 work (DEC has a licence). In July of 1990 Olivetti provided me with a copyright notice which permits the software to be distributed without a licence. However, I have no plans to make the original distribution available, since the code-generator, which was written in C and suffered badly in our bootstrap from an IDL-based AST to one in terms of Modula-3 objects, is unmaintainable except by the author (who is now at Sun). And it doesnt make a lot of sense for SRC to be shipping two, incompatible, run-time environments! Since arriving at SRC, I have been adapting the implementation independent parts of the Olivetti toolkit to conform to the SRC conventions (e.g. different file extensions), and experimenting with some more integrated and ambitious tools. The reason that I am still using the Olivetti code generator is that to date the SRC compiler hasnt been able to compile the toolkit correctly. However, this is getting fixed and I plan to ship the toolkit with the SRC distribution sometime in early 91. The most interesting tool that I have built to date contains a compiler front end, a pre-linker, simple code browser, and Makefile generator. It first compiles an entire "world" of interfaces and modules, and then will scan the file system for changes, pre-link (i.e. check for program completeness), generate a Makefile to build the system off-line (using the SRC compiler/linker) etc., under interactive control. By "compile" I really mean syntax/semantic check, although invoking the SRC compiler as a code generator would be straightforward. The turnround for a compilation is very fast because of the cache of pre-compiled ASTs. Of course you need a decent amount of memory to make this work. The tool really needs a window-based user interface. I did some experiments with X a couple of years ago and, based on that experience, would prefer to wait until the TreXle toolkit is released. TreXle is an alternative to Xt, which uses Modula-3 objects, rather like Interviews for C++. It will be added to the SRC distribution sometime in 91. Another tool I am experimenting with is a "demodulariser". This builds on the above tool to extract the set of modules that make up a program (discovered by the pre-linker) and "optimises" them into a single module, potentially doing all sorts of interesting language-dependent optimisations along the way. Right now it merely removes unused procedures and variables, but I plan to do inlining and TYPECASE->CASE optimisations, because they will make the toolkit itself go much faster. The toolkit was designed to be extensible so that it is easy for others to build tools of the above nature. One of my tasks before shipping the system is to provide adequate documentation on how to do this. I am giving a paper on the system at the upcoming SIGSOFT SDE Conference so you will be able to read about it soon. Mick Jordan ------------------------------------------------------------------------------ Date: Tue, 20 Nov 90 19:35:16 -0500 From: William E Williams Subject: Modula-3_Compiler Dear SRC; I am a junior in the computer science program at The University of Pittsburgh. Over the past three years I have been exposed to many diverse computer languages at Pitt. My personal favorite of these languages was Pascal until I was exposed Modula-2. Modula-2 seemed to solve many of my problems with Pascal. This is the same situation I now find myself in with Modula-2 and Modula-3. The more I read about Modula-3, the more I realize that it takes care of my problems with Modula-2. I recently read an article in "BYTE" magazine that mentioned your research into Modula-3. With this information and you network address, I obtained a copies of the Modula-3 report and the compiler document via anonymous FTP. This is all I could obtain, although I have an student account on a VAX 8800 running ULTRIX, I have only a small fraction of the resources necessary to install the compiler, or even to get the compressed tar file. This is my reason for witting. Does a version of the Modula-3 compiler exist for the IBM AT using MS-DOS v3.3? If there is, could I obtain a copy of it? I would be happy for any help you can give me. Sincerely, William E. Williams wewst1@unix.cis.pitt.edu ------------------------------------------------------------------------------ Date: Wed, 21 Nov 90 23:51:49 CDT From: rachel!johnh@gargoyle.uchicago.edu (John (Doc) Hayward) Subject: Rd.GetLine problem in 1.2 This may have been fixed in later releases of modula-3 so these comments may be out of date, however they are correct for version 1.2 and I don't remember this being discussed. If you try to do something like: ... Wr.PutText(Stdio.stdout,"Enter a line\n"); Line := Rd.GetLine(Stdio.stdin); Wr.PutText(Stdio.stdout,Line & " was entered\n") END Main. If you run this program you will have to enter new-line (return) twice. The problem is that GetLine in lib/rd/RdMove.m3 has a code fragment ... WHILE NOT EOF(rd) AND Ch # '\n' DO ... END If there are no more characters in the input buffer the EOF routine will cause another line to be read in. Changing the code to: WHILE Ch # '\n' AND NOT EOF(Rd) DO ... END Causes the code to see the new line before the call to eof and due to the short circuit AND does not call EOF (and does not cause a second new-line to be required). Other routines in RdMove.m3 have similar coding. Does anyone know if there was a reason it was coded this way? A second question is why does Ultrix.UltrixFileStream.m3 in lib/files initialize terminal readers to seekable and not intermittent? (It seems from other comments that terminals would not be seekable and would be intermittent). johnh... -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- = UUCP: johnh@wheaton.uucp telephone: (708) 260-3871 (office) Mail: John Hayward Math/Computer Science Dept. Wheaton College Wheaton Il 60187 Act justly, love mercy and walk humbly with your God. Micah 6:8b -- ------------------------------------------------------------------------------ Date: Mon, 26 Nov 90 11:00:05 MET From: Thomas Roemke Subject: variable access bug ? I got a message sh: Memory fault - core dumped while compiling the program below (SRC M3 1.5 SPARC). Simply tell me why. MODULE blockinfor EXPORTS Main; BEGIN FOR x := 1 TO 10 DO PROCEDURE aaa() = BEGIN EVAL x; END aaa; BEGIN END END END blockinfor. Thomas P.S.: If there isn't any access to x within aaa, your compiler works well. -- (* Thomas Roemke, University of Paderborn, Germany modula-3@uni-paderborn.de ..!uunet!mcsun!unido!pbinfo!modula-3 *) ------------------------------------------------------------------------------ Date: Mon, 26 Nov 1990 17:31:05 PST From: Brian_Masao_Oki.PARC@xerox.com Subject: code for parsing Time.T to Text.T Hi, I'm looking for some code that parses quantities of type Time.T to a nice, textual representation. I want to call Time.Now(), parse the result, and print out the time. Anybody out there have some code he/she is willing to share? --Brian Oki ------------------------------------------------------------------------------ Date: Mon, 26 Nov 1990 17:34:01 PST From: Brian_Masao_Oki.PARC@xerox.com Subject: Clarification Clarification. What I really want is to print out the date and time in a nice format, given a quantity of type Time.T. --Brian ------------------------------------------------------------------------------ Date: Mon, 26 Nov 90 17:13:29 EST From: Norman Ramsey Subject: Debugging Modula-3 Suppose I want a debugger to run in the same address space as a Modula-3 program. For the time being let's assume that I'm interested only in the DS3100 implementation. Here are two questions: Is there a way for me to stop all threads other than the debugger thread(s)? When I'm walking a stack created by Thread.Fork, how do I tell when I've reached the bottom? Norman ------------------------------------------------------------------------------ Date: Tue, 27 Nov 90 12:16:19 PST From: Eric Muller Subject: Re: Debugging Modula-3 > Suppose I want a debugger to run in the same address space as a Modula-3 > program. For the time being let's assume that I'm interested only in the > DS3100 implementation. Here are two questions: > Is there a way for me to stop all threads other than the > debugger thread(s)? No. The 1.5 implementation of Thread (as well as the 1.6) does not provide any support for debugging. However, this should not be very difficult to add, especially in 1.6 where 95% of the code is in Modula-3. I remember once calling Thread.Yield from the debugger to change the active thread. > When I'm walking a stack created by Thread.Fork, how do I tell > when I've reached the bottom? In 1.6, ThreadF.ProcessStacks should be good enough for what you want: you pass a procedure that will be called once for each stack, with the limits as its arguments. I don't remember if it existed in 1.5. Eric Muller. ------------------------------------------------------------------------------ System Research Center - 130 Lytton Av. - Palo Alto, CA 94301 - (415) 853 2193 ------------------------------------------------------------------------------ Date: Tue, 27 Nov 90 16:08:20 PST From: Eric Muller Subject: Re: variable access bug ? > I got a message > sh: Memory fault - core dumped > while compiling the program below (SRC M3 1.5 SPARC). > > Simply tell me why. > > > MODULE blockinfor > EXPORTS Main; > > BEGIN > FOR x := 1 TO 10 DO > PROCEDURE aaa() = > BEGIN > EVAL x; > END aaa; > BEGIN > END > END > END blockinfor. Because there is a bug ? Fixed for 1.6. Thanks for the report. Until the release, you can write: FOR x := 1 TO 10 DO VAR y := x; PROCEDURE aaa () = BEGIN EVAL y; END aaa; BEGIN END; END; Eric Muller. ------------------------------------------------------------------------------ System Research Center - 130 Lytton Av. - Palo Alto, CA 94301 - (415) 853 2193 ------------------------------------------------------------------------------ Date: Tue, 27 Nov 1990 13:50:37 -0600 (CST) From: Dick Orgass Subject: Re: code for parsing Time.T to Text.T I think the attached interface and implementation does much of what Brian asked about. There are a few limitations: (1) In TimeConvert.ToText I used the AIX 3.1 C library function NLstrtime to do the conversion; it's quite easy to replace this with Modula-3 code. (2) Both TimeConvert.ToText ignores microseconds and TimeConvert.FromText assumes that there are no microseconds. (3) Only the four US time zones (Eastern, Central, Moutain, Pacific) are dealt with. (4) As usual, no warantees of any sort. Fixing these problems is on my list of things to do but I'm not likely to get to it soon as the present version meets my needs. If it were a bit more finished, I'd offer it as a contribution to the SRC Modula-3 library. Hope it's useful to someone. Dick ------------------- TimeConvert.i3 ---------------------- (* File TimeConvert.i3, created by Orgass on 10-Sep-90. *) (* Last edited by Orgass on 13-Sep-90. *) (* Copyright (C) by IBM Corporation, 1990. *) INTERFACE TimeConvert; IMPORT Time; <* UNUSED *> CONST TimeConvertCopyright = "Copyright (C) by IBM Corporation, 1990."; TimeConvertRCSHeader = "$Header$"; TimeConvertRevision = "$Revision$"; TimeConvertDate = "$Date$"; TYPE Code = {DashesMissing, ColonsMissing, InvalidTimeZone, InvalidDay, InvalidMonth, InvalidYear, InvalidHour, InvalidMinute, InvalidSecond, StringTooShort}; EXCEPTION Error(Code); (* The actual parameter can be used together with GetErrorMessage, below, to write an error message.. Here is an example: TRY t := TimeConvert.FromText(t) EXCEPT Error(c) => Wr.PutText(Stdio.stderr, "\'" & t & "\' " & GetErrorMessage(c) & "\n") END *) PROCEDURE ToText(t: Time.T): TEXT RAISES {}; (* Converts a Time.T to text of the form dd-mmm-yy hh:mm:ss zzz where: dd is the day of the month, mmm is one of Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov or Dec, yy is the last two digits of the year number (If yy < 70 then 19yy else 20yy.), hh is the (24 hour) hours mm is the number of minutes past the hour ss is the number of seconds past the minute zzz is one of {E,C,M,P}{S,D}T or GMT *) PROCEDURE FromText(t: TEXT): Time.T RAISES {Error}; (* Converts a text of the form dd-mmm-yy[ hh:mm:ss[ zzz]] to a Time.T. If hh:mm:ss is omitted, 00:00:00 is assumed and if zzz is omitted the appropriate local time zone is assumed.*) PROCEDURE GetErrorMessage(c: Code): TEXT RAISES {}; (* Returns an error message string that explains the error c. See the example after the declaration of Error, above. *) END TimeConvert. (* $Log$ *) ------------------------ TimeConvert.m3 ------------- (* File TimeConvert.m3, created by Orgass on 10-Sep-90. *) (* Last edited by Orgass on 13-Sep-90. *) (* Copyright (C) by IBM Corporation, 1990. *) MODULE TimeConvert; IMPORT Convert, Ctypes, M3toC, Text, Time, Utime; <* UNUSED *> CONST TimeConvertImplCopyright = "Copyright (C) by IBM Corporation, 1990."; TimeConvertImplRCSHeader = "$Header$"; TimeConvertImplRevision = "$Revision$"; TimeConvertImplDate = "$Date$"; <* EXTERNAL *> PROCEDURE NLstrtime(string: Ctypes.String64; length: INTEGER; format: Ctypes.char_star; tm: Utime.struct_tm_star); CONST NLtimeFormat = "%2d-%3b-%2y %8T %3Z"; PROCEDURE ToText(t: Time.T): TEXT RAISES {} = (* Converts a Time.T to text of the form dd-mmm-yy hh:mm:ss zzz. *) VAR string := NEW(Ctypes.String64); tloc := NEW(Ctypes.long_star); BEGIN tloc^ := t.seconds; NLstrtime(string, 64, M3toC.TtoS(NLtimeFormat), Utime.localtime(tloc)); RETURN M3toC.StoT(string) END ToText; CONST DaysInMonth = ARRAY [0..11] OF INTEGER{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; LeapYearDaysInMonth = ARRAY [0..11] OF INTEGER{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; EasternOffset = 5*60*60; (* Units are seconds. *) CentralOffset = 6*60*60; MountainOffset = 7*60*60; PacificOffset = 8*60*60; DaylightTimeOffset = -60*60; SecondsPerDay = 24*60*60; SecondsPerHour = 60*60; SecondsPerMinute = 60; PROCEDURE FromText(t: TEXT): Time.T RAISES {Error} = (* Converts a text of the form dd-mmm-yy hh:mm:ss zzz to a Time.T. *) VAR length := Text.Length(t); tm: Utime.struct_tm; offset: INTEGER; isLeapYear := FALSE; answer := Time.T{0,0}; <* INLINE *> PROCEDURE DayOfYear(): INTEGER RAISES {} = VAR answer: INTEGER := 0; BEGIN IF isLeapYear THEN FOR i := 0 TO tm.tm_mon-1 DO INC(answer, LeapYearDaysInMonth[i]) END ELSE FOR i := 0 TO tm.tm_mon-1 DO INC(answer, DaysInMonth[i]) END END; INC(answer, tm.tm_mday-1); RETURN answer END DayOfYear; BEGIN IF length < 22 THEN RAISE Error(Code.StringTooShort); END; IF Text.GetChar(t, 2) # '-' OR Text.GetChar(t, 6) # '-' THEN RAISE Error(Code.DashesMissing); END; IF Text.GetChar(t, 12) # ':' OR Text.GetChar(t, 15) # ':' THEN RAISE Error(Code.ColonsMissing) END; IF Text.GetChar(t, 21) # 'T' THEN RAISE Error(Code.InvalidTimeZone) END; CASE Text.GetChar(t, 20) OF | 'S' => tm.tm_isdst := 0 | 'D' => tm.tm_isdst := 1 | 'M' => IF Text.GetChar(t, 19) = 'G' THEN tm.tm_isdst := 0; offset := 0 ELSE RAISE Error(Code.InvalidTimeZone) END ELSE RAISE Error(Code.InvalidTimeZone) END; CASE Text.GetChar(t, 19) OF | 'E' => offset := EasternOffset | 'C' => offset := CentralOffset | 'M' => offset := MountainOffset | 'P' => offset := PacificOffset | 'G' => ELSE RAISE Error(Code.InvalidTimeZone) END; tm.tm_year := ToInt(Text.Sub(t, 7, 2)); IF tm.tm_year < 0 OR tm.tm_year > 99 THEN RAISE Error(Code.InvalidYear) END; IF tm.tm_year < 70 THEN INC(tm.tm_year, 100) END; isLeapYear := IsLeapYear(1900+tm.tm_year); tm.tm_mon := GetMonth(Text.Sub(t, 3, 3), t); tm.tm_mday := ToInt(Text.Sub(t, 0, 2)); IF isLeapYear THEN IF tm.tm_mday < 1 OR tm.tm_mday > LeapYearDaysInMonth[tm.tm_mon] THEN RAISE Error(Code.InvalidDay) END ELSE IF tm.tm_mday < 1 OR tm.tm_mday > DaysInMonth[tm.tm_mon] THEN RAISE Error(Code.InvalidDay) END END; (* Time zone and date have been translated and the value of offset and tm.tm_isdst have been computed. *) tm.tm_hour := ToInt(Text.Sub(t, 10, 2)); IF tm.tm_hour >= 24 THEN RAISE Error(Code.InvalidHour) END; tm.tm_min := ToInt(Text.Sub(t, 13, 2)); IF tm.tm_min >= 60 THEN RAISE Error(Code.InvalidMinute); END; tm.tm_sec := ToInt(Text.Sub(t, 16, 2)); IF tm.tm_sec >= 60 THEN RAISE Error(Code.InvalidSecond); END; tm.tm_yday := DayOfYear(); (* Have filled in all of tm except tm_wday. *) answer.seconds := DaysBeforeThisYear(tm)*SecondsPerDay; INC(answer.seconds, tm.tm_yday*SecondsPerDay); INC(answer.seconds, tm.tm_hour*SecondsPerHour); INC(answer.seconds, tm.tm_min*SecondsPerMinute); INC(answer.seconds, tm.tm_sec); INC(answer.seconds, offset); IF tm.tm_isdst # 0 THEN INC(answer.seconds, DaylightTimeOffset) END; RETURN answer END FromText; <* INLINE *> PROCEDURE ToInt(t: TEXT): Ctypes.int RAISES {} = VAR tmp: ARRAY [0..1] OF CHAR; used: INTEGER; BEGIN tmp[0] := Text.GetChar(t,0); tmp[1] := Text.GetChar(t, 1); RETURN Convert.ToInt(tmp, used) END ToInt; <* INLINE *> PROCEDURE GetMonth(t, t2: TEXT): INTEGER RAISES {Error} = (* If the subtext of length 3 of t beginning at position pos is a valid month name then the index of the month is returned. Otherwise, the exception Error with a message appropriate for printing is raised. *) VAR first := Text.GetChar(t, 0); second := Text.GetChar(t, 1); third := Text.GetChar(t, 2); BEGIN CASE first OF | 'J' => IF second = 'a' AND third = 'n' THEN RETURN 0 END; IF second = 'u' THEN IF third = 'n' THEN RETURN 5 END; IF third = 'l' THEN RETURN 6 END; END | 'M' => IF second = 'a' THEN IF third = 'r' THEN RETURN 2 END; IF third = 'y' THEN RETURN 4 END; END | 'A' => IF second = 'p' AND third = 'r' THEN RETURN 3 END; IF second = 'u' AND third = 'g' THEN RETURN 7 END; | 'F' => IF second = 'e' AND third = 'b' THEN RETURN 1 END; | 'S' => IF second = 'e' AND third = 'p' THEN RETURN 8 END; | 'O' => IF second = 'c' AND third = 't' THEN RETURN 9 END; | 'N' => IF second = 'o' AND third = 'v' THEN RETURN 10 END; | 'D' => IF second = 'e' AND third = 'c' THEN RETURN 11 END; ELSE END; RAISE Error(Code.InvalidMonth); END GetMonth; <* INLINE *> PROCEDURE IsLeapYear(year: INTEGER): BOOLEAN RAISES {} = BEGIN RETURN (((year MOD 4) = 0) AND ((year MOD 400) # 0)) OR ((year MOD 2000) = 0) END IsLeapYear; <* INLINE *> PROCEDURE DaysBeforeThisYear(tm: Utime.struct_tm): INTEGER RAISES {} = VAR answer: INTEGER := 0; BEGIN FOR i := 1970 TO tm.tm_year+1899 DO IF IsLeapYear(i) THEN INC(answer, 366) ELSE INC(answer, 365) END END; RETURN answer END DaysBeforeThisYear; CONST ErrorMessages = ARRAY Code OF TEXT{ "the character \'-\' is not in the required places.", "the character \':\' is not in the required places.", "the time zone is incorrect.", "the day of the month is invalid.", "the month name is invalid.", "the year number is invalid.", "the hour is incorrect.", "the minutes are incorrect.", "the seconds are incorrect.", "the string is too short to contain a valid time."}; PROCEDURE GetErrorMessage(c: Code): TEXT RAISES {} = (* Returns an error message string that explains the error c. The message should be prefixed with the offending string as well as other information useful to the user. The message text just explains what is wrong with the string that is supposed to contain a time. *) BEGIN RETURN ErrorMessages[c] END GetErrorMessage; (* PROCEDURE Struct_tmToText(tm: Utime.struct_tm): TEXT = BEGIN RETURN " = [\n\ttm_sec: " & Fmt.Int(tm.tm_sec) & ",\n\ttm_min: " & Fmt.Int(tm.tm_min) & ",\n\ttm_hour: " & Fmt.Int(tm.tm_hour) & ",\n\ttm_mday: " & Fmt.Int(tm.tm_mday) & ",\n\ttm_mon: " & Fmt.Int(tm.tm_mon) & ",\n\ttm_year: " & Fmt.Int(tm.tm_year) & ",\n\ttm_wday: " & Fmt.Int(tm.tm_wday) & ",\n\ttm_yday: " & Fmt.Int(tm.tm_yday) & ",\n\ttm_isdst: " & Fmt.Int(tm.tm_isdst) & "]\n" END Struct_tmToText; *) BEGIN END TimeConvert. (* $Log$ *) ------------------------- End --------------------------- ------------------------------------------------------------------------------ Date: 28 Nov 90 13:48 +0100 From: "Ron D. Appel" Subject: Report.ps and Release-1.5.ps I cannot print the postscript files Report.ps and Release-1.5.ps on my postscript printer. Could anybody tell me why, or send me a copy via postmail? Thanks #################################################################### Ron D. Appel appel@medsun.unige.ch Unite d'Imagerie Numerique appel@cgehcu61.bitnet Centre d'Informatique Hospitaliere Hopital Cantonal Universitaire de Geneve 24, rue Micheli-du-Crest ### CH-1211 Geneve 4 ######## Switzerland ############### tel.: 41-22-229254 ################### fax : 41-22-227073 ########################## #################################################################### ------------------------------------------------------------------------------ Date: Wed, 28 Nov 90 08:55:51 EST From: moss%ibis@cs.umass.edu (Eliot Moss) Subject: Report.ps and Release-1.5.ps Mr. Appel -- First, I would usually complain about something like this being posted to the whole mailing list. Sending to m3-request@src.dec.com would get to the mailing list maintainers, who are closest to the problem. In this case, others might be able to offer additional insight. Second, let me guess: you've got an Apple Laserwriter. My gues is based on the fact that the most common reason a perfectly good PS file won't print is that you run out of memory, and Laserwriters are notorious about not having much. The fix is to get the DEC folks to run their file through dvips with a lower setting of the "printer memory" switch. (I also wish they would not put up PostScript files with the last page printing first, but that's a different issue.) Maybe we could also suggest consideration of posting .dvi files (I *think* these documents are done with LaTeX, but I could be wrong) and then people could produce their own PS file locally. Anyway, those are my guesses and my proposed solutions. J. Eliot B. Moss, Assistant Professor Department of Computer and Information Science Lederle Graduate Research Center University of Massachusetts Amherst, MA 01003 (413) 545-4206; Moss@cs.umass.edu ------------------------------------------------------------------------------ Date: Wed, 28 Nov 90 11:51:59 EST From: Norman Ramsey Subject: m3 functionality It would be nice if m3 included a -S option to produce assembly code instead of an object file. Norman ------------------------------------------------------------------------------ Date: 29 Nov 90 16:26 +0100 From: "Ron D. Appel" Subject: OSF/Motif Did anybody do anything with OSF/Motif? Ron D. Appel Geneva University Hospital ------------------------------------------------------------------------------