======================================================================= 1 === Date: 1 Oct 92 10:47:28 GMT From: pdt@unix.brighton.ac.uk (taylor) Subject: Oberon on a Sparc Has anyone used Oberon (from ETH) on a Sparcstation? I have downloaded it but when I try to run it it can't seem to load the shared object libraries. (libpixrect.so). The necessary libraries seem to be in /usr/lib as needed so I don't know what is wrong. Can anyone help? ======================================================================= 2 === Date: Thu, 1 Oct 92 19:16:51 GMT From: muller@src.dec.com (Eric Muller) Subject: Modula-3 Frequently Asked Questions (FAQ) Archive-name: Modula-3-faq Last-modified: Aug 5 1992 Modula-3 Frequently Asked Questions =================================== What is Modula-3 ? 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. Is Modula-3 a superset of Modula-2 ? No; valid Modula-2 programs are not valid Modula-3 programs. Where can I get a description of Modula-3 ? The definition of Modula-3 is contained in: System Programming with Modula-3 Edited by Greg Nelson Prentice Hall Series in Innovative Technology ISBN 0-13-590464-1 L.C. QA76.66.S87 1991 also known as SPwM3. Here is the table of contents: 1. Introduction 2. Language Definition 3. Standard Interfaces 4. An Introduction to Programming with Threads 5. Thread Synchronization: A Formal Specification 6. I/O Streams: Abstract Types, Real Programs 7. Trestle Window System Tutorial 8. How the Language Got its Spots Chapters 2 and 3 have been reprinted in Sigplan Notices, Volume 27, Number 8, August 1992, pp 15-42. Sam Harbison has written a book about Modula3: Modula-3 Samuel P. Harbison Prentice Hall, 1992 ISBN 0-13-596396-6 as well as an overview article, "Modula-3", in Byte, Vol. 15, Number 12, October 1990, p 385. Where can I get information on Modula-3 ? There is a Usenet newsgroup, comp.lang.modula3. The archives of that group are available via anonymous ftp from gatekeeper.dec.com in pub/DEC/Modula-3/comp.lang.modula3. If you do not have access to Usenet, there is a relay mailing list; send a message to m3-request@src.dec.com to be added to it. Where can I get an implementation ? There is only one implementation available today. It has been built by SRC and is available via anonymous ftp from gatekeeper.dec.com in pub/DEC/Modula-3/release. Contributed software can be found in pub/DEC/Modula-3/contrib. The current version, 2.07, implements the language defined in SPwM3. There are versions for the following machines: AIX386 IBM PC running AIX/PS2, AP3000 Apollo DN4500 running Domain/OS ARM Acorn R260 running RISC iX 1.21 DS3100 DECstation 3100 and 5000 running Ultrix 4.0 and 4.2 HP300 HP 9000/300 running HP-UX 8.0 IBMR2 IBM R6000 running AIX 3.1, IBMRT IBM RT running IBM/4.3, NEXT NeXT running ? SPARC SPARCstation running SunOS 4.1.x SUN3 SUN3 running SunOS UMAX Encore Multimax running UMAX 4.3 (R4.1.1) VAX VAX running Ultrix 3.1 SRC Modula-3 includes a user manual, compiler, runtime library, some libraries and a few other goodies (see below). The compiler generates C as an intermediate language and should be fairly easy to port. Except for the very lowest levels of the thread implementation, the entire system is written in Modula-3. What if I don't have ftp access ? Unfortunately, we cannot deliver Modula-3 other than by anonymous ftp. Your best bet is to post a message to comp.lang.modula3, in the hope that somebody with ftp access can make a tape or floppy for you. Can I contribute Modula-3 software ? Certainly. Send us what you are willing to share, be it programs, libraries or other things. We'll put them in the distribution. -- Eric. ======================================================================= 3 === Date: 2 Oct 92 10:26:32 GMT From: marc@ecrc.de (Marc Bourgois) Subject: comparing object-oriented platforms I think it is important to direct the attention of this newsgroup to the discus sion about "comparing object-oriented platforms" which is going on in comp.object. The main point is that though modula3 gets mentioned, and occasionally defended , it is wiped away by the zealous interventions of Eiffel and C/C++ people. The main problem seems to be the "limited interest" in modula3; maybe we should start the "modula3 1000" list of applications/users as the prolog people are doing to make the system more widespread, to demostrate its momentum... Anyway here is a resume of the relevant interventions, I myself posted a pointe r to this group, and especially to the "Modula-3 Frequently Asked Questions (FAQ)" m essage. Moreover I emphasized modula3's rich library structure (trestle), the provision s for concurrency (threads, reentrant libs; appears toi be a weak issue in Eiffel) an d the expected gnu implementation. Original query: In article 29066@news.service.uci.edu, mwu@orion.oac.uci.edu (Matt Wu) writes: > >I'm currently evaluating several object-oriented development platforms >and I was wondering if any of you would like to share your opinions on >platforms that you prefer or know about. It'd be especially useful to hear >comparisons between different platforms (for instance, Eiffel v. Smalltalk). > A response that triggered most of the remaining discussion: In article nagle@netcom.com, nagle@netcom.com (John Nagle) writes: > The language situation is roughly as follows: > > Ada Big, no inheritance, some tools expensive but do > exist. Many books on language available. Many > free libraries available. DoD standard. > C++ Big, multiple versions of language, unsafe. > Tools widely available. Many books available. > Most popular choice. > Modula-2 No classes or inheritance. Many books. > Many implementations. Solid, but limited. > Modula-3 Limited interest - one free compiler, one book. > Adds classes to Modula-2. Less used than > Modula-2. > Eiffel Limited interest - one or two compilers, one book. > Less used than Smalltalk, C++, Ada, or Modula-2. > Smalltalk Slow execution, good tools. Multiple books > available. Clean language. Good for experimental > work. Avoid pure-interpreted versions if speed > at all important. Then most centered on the "enormous benefits" of using Eiffel, and some discuss ion on the C++ approach. Luckily we got the following intervention (the author is rather active in this group too): In article 92Sep28090446@pollux.vlsi.polymtl.ca, dagenais@vlsi.polymtl.ca (Mich el Dagenais) writes: >I dont want to start a language war here (it already started, a dozen >replies already came out on John Nagle's post), but the extensive libraries >available ( X graphical user interface, read/write for objects) for free >with DEC SRC Modula 3 should be mentioned. Moreover it has garbage >collection AND preemptive multi-threading (all the libraries are thread >safe), which none of the others mentioned (C++, Eiffel, SmallTalk...) have. >Threads are quite useful for user interaction and client-server >applications. Then part of the discussion centered on garbage collection, its performance (fo r real-time systems,...) no modula3 info was given here, and I don't feel confide nt to do so ... Finally someone got interested in modula3: In article <1992Sep29.043418.16848@actrix.gen.nz> Des.Kenny@bbs.actrix.gen.nz w rites: >Does Modula-3 have inheritance/multiple inheritance? and got a reply: In article 48043@neat.cs.toronto.edu, tlai@cs.toronto.edu (Tony Wen Hsun Lai) w rites: >Um, I think Modula-3 has (single) inheritance, polymorphism, and dynamic >binding. Traced types are automatically garbage collected, and untraced >types must be allocated and deallocated by the programmer. --- Marc Bourgois European Computer-Industry Research Centre Tel. + (49) 89-92699-179 Arabellastr 17, 8000 Muenchen 81. Germany. Internet: marc@ecrc.de UUCP: ..unido!ecrc!marc ======================================================================= 4 === Date: 2 Oct 92 18:41:14 GMT From: barnesdo@CS.ColoState.EDU (douglas barnes) Subject: Sys V ports What work, if any, is being done to port m3 to either the various flavors of AT&T Sys V rel 3.x (eg Interactive)? doug -- ----------- ----------- douglas barnes Calgon can't take me away... barnesdo@CS.ColoState.EDU From the things I did today -L7 ======================================================================= 5 === Date: 1 Oct 92 15:53:02 GMT From: rlp@drutx.ATT.COM (Bob Prehn (@ The Right Choice)) Subject: can't install compiler on SPARC I just obtained Modula-3 2.07 from gatekeeper.dec.com and tried to install the compiler via "m3make -f m3makefile.boot all install" It lists all the .io files and preceeds the Ustat_i.o file with a "\ ". The loader fails with "ld: Ustat_i.o: No such file or directory". Ive tried this under ksh,/bin/sh & csh with the same results. ============================================================================ "They that can give up an essential liberty to obtain a little temporary safety deserve neither liberty nor safety". - Benjamin Franklin (1759) Robert Prehn +-------------------------------------------------------+ AT&T Bell Labs | ____ _______ _____ _______ | Room 1F50 | / __ \ |__ __| / _ \ |__ __| | 11900 North Pecos | | <__> | | | \ \ \_\ | | | Denver, Co 80234 | | __ | | | / \ __ | | THE CHOICE| | | | | | | | | (\ / / | | | drutx!rlp | |_| |_| |_| \_____/ |_| | (303) 538-4554 | | +-------------------------------------------------------+ ======================================================================= 6 === Date: 4 Oct 92 12:39:53 From: vixie@pa.dec.com (Paul A Vixie) Subject: Re: How to use threads in Modula-3? A sample request. UNSAFE MODULE Main; IMPORT Datagram, Netdb, Net, MyTime; (* local hacks *) IMPORT Stdio, Wr, Fmt, Thread, Time, Text; (* standard *) IMPORT Word, Ctypes; (* nonportable *) TYPE T = Ctypes.long; (* 64-bit machines will be trouble here *) VAR Done := FALSE; Rcvd := 0; Waits := 0; NetTime: T; CONST TimeDifferential = -2085978496; (* inetd(8)'s offset *) PROCEDURE ProtocolF(self: Thread.Closure): REFANY RAISES {} = VAR port := Datagram.NewClient(NIL, mayBroadcast := TRUE); server := Netdb.NewRemotePort("255.255.255.255", "time", "udp"); timeval := NEW(REF T); BEGIN port.send(NIL, 0, server); (* 0-length datagram is a "request" *) LOOP EVAL port.recv(timeval, BYTESIZE(timeval^), server); timeval^ := Word.Minus(Net.ntohl(timeval^), TimeDifferential); Wr.PutText(Stdio.stdout, "["& Netdb.INaddrToText(server.host.addrList[0]) &"]" & " -> " & MyTime.TimeToText(timeval^) & "\n"); Wr.Flush(Stdio.stdout); IF Rcvd = 0 THEN NetTime := timeval^; ELSE NetTime := Word.Divide(Word.Plus(NetTime, timeval^), 2); END; INC(Rcvd); Done := FALSE; END; END ProtocolF; BEGIN EVAL Thread.Fork(NEW(Thread.Closure, apply := ProtocolF)); REPEAT Done := TRUE; Time.LongPause(1); INC(Waits); UNTIL Done; IF Rcvd = 0 THEN Wr.PutText(Stdio.stdout, "No Replies.\n"); ELSE NetTime := Word.Minus(NetTime, Waits); Wr.PutText(Stdio.stdout, "Network time: " & MyTime.TimeToText(NetTime) & " (" & Fmt.Int(Rcvd) & " replies)\n"); END; END Main. -- Paul Vixie, DEC Network Systems Lab Palo Alto, California, USA "Don't be a rebel, or a conformist; decwrl!vixie they're the same thing, anyway. Find vixie!paul your own path, and stay on it." -me ======================================================================= 7 === Date: Sun, 4 Oct 92 18:59:35 GMT From: karmat@polaris.utu.fi (Kari Mattsson) Subject: How to use threads in Modula-3? A sample request. Hi! I'm just starting to seriously program in Modula-3. It is installed on our (Univ. of Turku) Sun SPARCserver. It appears that the administrators have not installed any contributing or sample programs. I have experience with Pascal and Modula-2, and find the Modula-3 language itself rather easy. I'm not very familiar programming Unix, and that's where my problem lies. I'm trying to implement (a rather theoretical, I know) parallel merge sort routine using the thread feature of M3. I have the routines implemented, but how to do thread programming, so, *** COULD SOMEONE, PLEASE E-MAIL/POST SOME WORKING SAMPLE *** CODE USING THE THREADS IN MODULA-3??? Anything is appreciated..., a lot. Thank You. Kari Mattsson YO-kyl 12 B 9, SF-20540 Turku, Finland Kari.Mattsson@utu.fi -or- karmat@utu.fi Voice and Fax: +358-21-542354 Sent from TAHKO III, an OS/2 2.0 personal computer... settling for no less! ======================================================================= 8 === Date: Mon, 05 Oct 92 16:42:28 CDT From: Ryan Stansifer Subject: Syntax of Modula-3 After programming some in Modula-3 I have come to think that the WITH and TRY statements are wordy, especially in conjunction with other blocks. In thinking about the language syntax it occurred to me that some simplification may be possible. So, for the sake of argument I offer the following 2 suggestions for expanding the block statement to encompass both the WITH and the TRY statements. Instead of WITH x = e DO S END add a new kind declaration, say, WITH. Now we write: WITH x = e BEGIN S END Now we can mix VAR, CONST, WITH declarations and use only one BEGIN/END block. I think the WITH declarations should be separated (and/or terminated) by semicolons like other declarations. (There is another, perhaps more important, issue. WITH declarations seem to be used in two distinct ways. One, as READONLY constant r-values. Two, as aliases. Adding READONLY constants is unproblematic, but I would hate to add a new "alias" declaration when they are really READONLY constants of type reference, reference in the C++ sense.) Instead of TRY S EXCEPT Handler END we could follow the example of Ada and tack on an exception part to the block. Now we write BEGIN S EXCEPT Handler END This permits declarations can be added to the block without extra BEGIN/END pairs. I do not wish to touch off another language-changing war. I'm just curious about the advantages and disadvantages of different approaches. Ryan Stansifer ryan@cs.unt.edu ======================================================================= 9 === Date: Tue, 6 Oct 1992 06:44:57 GMT From: cavers@menudo.uh.edu (Chris M. Cavers) Subject: docs for m3 Can someone email me info on how to correctly assemble the docs for modula 3. I have the doc-2.07.tar.Z file. I uncompressed/untared it and could never find anything to make the complete documentaion... the makefile has a message like 'doc has to be built by hand' ======================================================================= 10 === Date: Tue, 6 Oct 1992 00:15:20 GMT From: stanjm02@cc.curtin.edu.au Subject: Difference btwn Modula-2 & Modula-3 I have just started learning and using Modula-2 and I must admit I like the language. However, I am a little confused about the difference between Modula-2 and Modula-3. I would appreciate it very much if someone could highlight the differences. I presume from the description that 3 is 'better' than 2. Thanks.. Email STANJM02@CC.CURTIN.EDU.AU ======================================================================= 11 === Date: Mon, 5 Oct 1992 22:37:40 GMT From: nr@cs.Princeton.EDU () Subject: Suggestion for ETimer interface It might not be a bad idea if ETimer.Pop verified the timer on top of the stack, e.g. PROCEDURE Pop(top : T := NIL) = BEGIN IF top = NIL OR top = <> THEN <> ELSE <> END; END Pop; Existing clients of ETimer.Pop would continue to work, and new clients -- Norman Ramsey nr@princeton.edu ======================================================================= 12 === Date: 6 Oct 92 14:44:58 GMT From: moss@cs.umass.edu (Eliot Moss) Subject: Re: Difference btwn Modula-2 & Modula-3 There is a regular posting (FAQ = Frequently Asked Questions) that mentions a few differences. I'm not an expert on M2, but here are what I understand to be the highlights: Features Modula-3 adds to Modula-2: - Object types and subtyping - Exceptions and exception handling - Garbage collection (and types for non-gc areas too) - Threads (lightweight processes in the same address space) and related support (such as mutual exclusion locks and conditions) Features "removed" from Modula-2: - Variant records (since object types largely overlap in functionality) - Nesting of modules Other differences: - The module/interface system is somewhat different in that a module can implement parts of more than one interface and an interface can be implemented by more than one module (though any given item in the interface should be implemented no more than once in a particular program). In short, the module/interface relationship is many to many. - Modula-3 supports generic interfaces and modules via what I characterize as "syntactic macro expansion" (i.e., parameter substitution). - The scheme for opaque types is rather different in that, via subtyping, types can be partially revealed in some contexts. - The required interfaces ("built-in" stuff) are more extensive and detailed, I believe. Note also that there are enough differences that Modula-2 programs are generally not legal Modula-3, and even automated tools cannot handle every difference. In my opinion Modula-3 is better in that it provides more of the features one frequently wants for building substantial systems. There are philosophical disagreements on this kind of point, of course, which are exemplified by the fact that Wirth's own successor for Modula-2, called Oberon, is actually smaller than Modula-2, whereas Modula-3 can be considered bigger. -- J. Eliot B. Moss, Associate Professor Visiting Associate Professor Department of Computer Science School of Computer Science Lederle Graduate Research Center Carnegie Mellon University University of Massachusetts 5000 Forbes Avenue Amherst, MA 01003 Pittsburgh, PA 15213-3891 (413) 545-4206, 545-1249 (fax) (412) 268-6767, 681-5739 (fax) Moss@cs.umass.edu Moss@cs.cmu.edu ======================================================================= 13 === Date: Wed, 7 Oct 1992 14:02:20 GMT From: collberg@dna.lth.se (Christian S. Collberg) Subject: Reference missing. Can someone help me to fill in the missing pieces of information for this bibliographic entry? Thanks! @CONFERENCE{Cardelli89b, AUTHOR = "Luca Cardelli and James Donahue and Mick Jordan and Bill Kalsow and Greg Nelson", TITLE = "The {Modula-3} Type System", BOOKTITLE = "XXX", PAGES = {202--212}, ADDRESS = "", MONTH = "", YEAR = 1989 } -- Christian.Collberg@dna.lth.se Department of Computer Science, Lund University, BOX 118, S-221 00 LUND, Sweden ======================================================================= 14 === Date: Wed, 7 Oct 1992 09:15:43 GMT From: laverman@cs.rug.nl (Bert Laverman) Subject: Re: Syntax of Modula-3 Ryan Stansifer writes: > [ Some text deleted ] > (There is another, perhaps more important, issue. WITH declarations > seem to be used in two distinct ways. One, as READONLY constant > r-values. Two, as aliases. Adding READONLY constants is > unproblematic, but I would hate to add a new "alias" declaration when > they are really READONLY constants of type reference, reference in the > C++ sense.) WITH _is_ an aliasing construct _ONLY_. A constant (which btw implies readonlyness) _is_ nothing more than an alias for a value. I do not see how replacing aliases for designators (aka C rvalues) with constant pointers (which they are not, but anyway) reduces complexity. I consider WITH as a textual help only, which btw can help the compiler in finding common subexpressions, but nothing more. Greetings, Bert -- #include Bert Laverman, Dept. of Computing Science, Groningen University Friendly mail to: laverman@cs.rug.nl The rest to: /dev/null ======================================================================= 15 === Date: Wed, 7 Oct 92 19:23:52 GMT From: Eric Muller Subject: Re: can't install compiler on SPARC In article <21018@drutx.ATT.COM>, rlp@drutx.ATT.COM (Bob Prehn (@ The Right Cho ice)) writes: |> I just obtained Modula-3 2.07 from gatekeeper.dec.com and tried to |> install the compiler via "m3make -f m3makefile.boot all install" |> It lists all the .io files and preceeds the Ustat_i.o file with a "\ ". |> The loader fails with "ld: Ustat_i.o: No such file or directory". |> Ive tried this under ksh,/bin/sh & csh with the same results. It seems that make on SPARC has a limitation on the size of the value of symbols. Try to change {compiler,driver}/boot-SPARC; right now it looks like: OBJS = \ @@\ M3Runtime.o \ @@\ Uexec_i.o \ @@\ Usignal_i.o \ @@\ Cstdlib_i.o \ @@\ Cstring_i.o \ @@\ Cstdarg_i.o \ @@\ RTArgs_i.o \ @@\ ... Uprocess_i.o \ @@\ Upwd_i.o \ @@\ Uresource_i.o \ @@\ Usem_i.o \ @@\ Ushm_i.o \ @@\ Uuio_i.o \ @@\ ... Usignal_m.o \ @@\ Uin_m.o \ @@\ _m3main.o Split this list in two: OBJS1 = \ @@\ M3Runtime.o \ @@\ Uexec_i.o \ @@\ Usignal_i.o \ @@\ Cstdlib_i.o \ @@\ Cstring_i.o \ @@\ Cstdarg_i.o \ @@\ RTArgs_i.o \ @@\ ... Uprocess_i.o \ @@\ Upwd_i.o \ @@\ Uresource_i.o \ @@\ Usem_i.o OBJS2 = \ @@\ Ushm_i.o \ @@\ Uuio_i.o \ @@\ ... Usignal_m.o \ @@\ Uin_m.o \ @@\ _m3main.o OBJS = $(OBJS1) $(OBJS2) Please let us (m3-request@src.dec.com) know if that works so that we can modify the release. -- Eric. ======================================================================= 16 === Date: Wed, 7 Oct 92 19:17:07 GMT From: Eric Muller Subject: Re: docs for m3 In article <1992Oct6.064457.10120@menudo.uh.edu>, cavers@menudo.uh.edu (Chris M . Cavers) writes: |> Can someone email me info on how to correctly assemble the docs for |> modula 3. I have the doc-2.07.tar.Z file. I uncompressed/untared it |> and could never find anything to make the complete documentaion... |> the makefile has a message like 'doc has to be built by hand' First, you may want to change the words for the chapter that describe the local installation: - cd doc - create localinst.tex, which should start with the following lines: \chapter{Local Guide} \label{local} Then: (cd doc; m3make) If you don't want to change the words in the local chapter, you can also use directly doc/doc.ps. -- Eric. ======================================================================= 17 === Date: Wed, 7 Oct 92 18:26:47 EDT From: Benoit.Desrosiers hi, I don't know if you received my last message because my system has crasched just at the moment that I was pushing the deliver button. So I sending you anot her copy of it. Ok, I now have a Modula-3 compiler on my system. I've tried to compile the tetr is program and I got the following result: =============================================================================== m3make /jupiter/home/spec/modula/bin/m3 -w1 -make -why -g -o tetris ./Main.m3 -lm3X1 1R4 -LPENWINHOME/lib -lXaw -lXmu -lXext -lXt -lX11 new source -> compile ./Main.m3 program missing -> link tetris ld: Undefined symbol _get_wmShellWidgetClass _get_applicationShellWidgetClass =============================================================================== (N.B it is possible that the result is a little bit different than the one in t he first mail because I had to recompile everything) Tetris is working, (it is such a great game....) I don't know how and why? Than I tried to compile solitaire (another great game...) but this time the res ult is much more complex: =============================================================================== metis% m3make /jupiter/home/spec/modula/bin/m3 -w1 -make -why -g -o solitaire ./Solve.i3 . /Solve.m3 ./Tree.i3 ./Tree.m3 ./TreeQueue.i3 ./TreeQueue.m3 ./TreeQueueADT .i3 ./TreeQueueADT.m3 ./Solitaire.m3 -lm3bicycle -lm3ui -lm3X11R4 -lX11 new source -> compile ./TreeQueue.i3 "./TreeQueue.i3", line 4: missing file no "Queue.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueue.i3", line 3: number of actuals doesn't match number of generic for mals "./TreeQueueADT.i3", line 4: missing file no "QueueADT.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.i3", line 3: number of actuals doesn't match number of generic formals 4 errors encountered new source -> compile ./TreeQueueADT.i3 "./TreeQueueADT.i3", line 4: missing file no "QueueADT.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.i3", line 3: number of actuals doesn't match number of generic formals 2 errors encountered new source -> compile ./Solve.m3 "./TreeQueue.i3", line 4: missing file no "Queue.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueue.i3", line 3: number of actuals doesn't match number of generic for mals "./TreeQueueADT.i3", line 4: missing file no "QueueADT.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.i3", line 3: number of actuals doesn't match number of generic formals 4 errors encountered new source -> compile ./TreeQueue.m3 "./TreeQueue.i3", line 4: missing file no "Queue.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueue.i3", line 3: number of actuals doesn't match number of generic for mals "./TreeQueueADT.i3", line 4: missing file no "QueueADT.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.i3", line 3: number of actuals doesn't match number of generic formals "./TreeQueue.m3", line 4: missing file no "Queue.mg" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueue.m3", line 3: number of actuals doesn't match number of generic for mals 6 errors encountered new source -> compile ./TreeQueueADT.m3 "./TreeQueueADT.i3", line 4: missing file no "QueueADT.ig" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.i3", line 3: number of actuals doesn't match number of generic formals "./TreeQueueADT.m3", line 4: missing file no "QueueADT.mg" on path ".:.:/jupiter/home/spec/modula/include/m3" "./TreeQueueADT.m3", line 3: number of actuals doesn't match number of generic formals 4 errors encountered new source -> compile ./Solitaire.m3 "./Solitaire.m3", line 12: missing file no "Card.i3" on path ".:.:/jupiter/home/spec/modula/include/m3" "./Solitaire.m3", line 18: symbol not exported (Card.Width) "./Solitaire.m3", line 18: symbol not exported (Card.Height) "./Solitaire.m3", line 18: symbol not exported (Card.Overlap) "./Solitaire.m3", line 18: symbol not exported (Card.Value) "./Solitaire.m3", line 18: symbol not exported (Card.Suit) "./Solitaire.m3", line 18: symbol not exported (Card.Real) "./Solitaire.m3", line 18: symbol not exported (Card.Family) 8 errors encountered compilation failed => not building program "solitaire" *** Error code 255 make: Fatal error: Command failed for target `solitaire' metis% ============================================================================= could you tell me what goes wrong??? thank you. benoit ======================================================================= 18 === Date: Wed, 7 Oct 92 19:32:55 GMT From: Eric Muller Subject: Re: Modula-3 for OS/2 ?? In article <1992Sep28.190918.13401@beaver.cs.washington.edu>, andrewb@lynx.cs.w ashington.edu (Andrew Berg) writes: |> Addmittedly, I may be a bit green on these things, but what would it take to |> port the Modula-3 to OS/2? I know that the source is available, but the one s |> I saw at the FTP site seemed to all be targeted for a system much more |> expensive than mine. Is it possible to get a fairly generic version of the |> source that I could hack into an OS/2 version? Right now the only compilers |> I have for OS/2 are GCC and a _really_ old Modula-2. |> |> Does anybody have suggestions or advice? I am not familiar with OS/2, so I am not sure about the problems you will find. The sources that are on gatekeeper are all the sources. They are as generic as you can find. The system assumes a C compiler and a flavor of Unix. To port to a new operating system, you need to find how to implement all the Unix functions that used in the system and to provide implementations for your target system. Unfortunately, the list is not described anywhere. Paul McJones (mcjones@src.dec.com) is working on a set of OS-independent interfaces that would allow to build the rest of the system without any dependency on the OS. Of course, the implementation of those interfaces will be system specific. This should give a clear description of what needs to be implemented. Also, we use a number of Unix tools to put the system together: cc, ld, ar, install, make, sed, cpp, and so on. Again, this list is not described anywhere. The last chapter of the documentation (doc/doc.ps, after you unpack m3doc-2.07.tar.Z) describes the steps for a new port. -- Eric. ======================================================================= 19 === Date: Thu, 8 Oct 92 00:23:06 GMT From: Eric Muller Subject: Re: In article <9210072226.AA05731@Amnesix.UQSS.UQuebec.CA>, Benoit.Desrosiers writes: |> hi, I don't know if you received my last message because my system has crasc hed |> just at the moment that I was pushing the deliver button. So I sending you a nother |> copy of it. |> |> |> Ok, I now have a Modula-3 compiler on my system. I've tried to compile the t etris program and I got the following result: |> |> ============================================================================ === |> |> m3make |> /jupiter/home/spec/modula/bin/m3 -w1 -make -why -g -o tetris ./Main.m3 -lm 3X11R4 -LPENWINHOME/lib -lXaw -lXmu -lXext -lXt -lX11 |> new source -> compile ./Main.m3 |> program missing -> link tetris |> ld: Undefined symbol |> _get_wmShellWidgetClass |> _get_applicationShellWidgetClass |> Do you have a PENWHINHOME/lib subdirectory ? I bet that you have in your config file: XLIBPATH = $OPENWINHOME or something like that. This line of config is interpreted by make, which needs () around variable names, and these have to be make variables anyway, not shell variables. Try to put the expansion of OPENWINHOME for XLIBPATH instead. |> Than I tried to compile solitaire (another great game...) but this time |> the result is much more complex: It looks like you don't have installed the data archive, which is needed by solitaire. I have added some code in the m3makefiles to handle that. -- Eric. ======================================================================= 20 === Date: 8 Oct 92 13:54:15 GMT From: reid@ss6.cps.msu.edu (Dr Richard J. Reid) Subject: Modula Usage in CS1? Among the 253 schools that have responded to our survey, the following have indicated they are using Modula2 in their CS1 course. Do you know of any additions or corrections? Thanks, Dick *************************** Modula2 ******************************** Augustana University College Australian National University Bethune-Cookman College Bismarck State College, North Dakota (Modula-2) Bond University, Australia Clemson University ETH, Zurich (Also reported using Oberon in CS1) Johannes Kepler University, Austria Laurentian University, Sudbury, Ontario New Mexico State University North Dakota State University, Fargo Odense University, Denmark Ohio State Oldenburg University, Germany Queensland University of Technology, Australia Rhodes University, South Africa Rochester Institute of Technology San Francisco State University Seattle University State University of New York at Buffalo State University of New York at Oswego State University of New York at Plattsburgh TU Braunschweig, Germany Trinity College, Dublin Trinity Western University, BC, Canada University of Bern University of Cambridge (Modula-3) University of Canterbury, New Zealand (Modula-2) University of Central Florida, Orlando University of Limerick, Ireland University of Montana, Missoula University of Stuttgart University of the Witwatersrand, Johannesburg Vrije Universiteit Amsterdam, the Netherlands Western Washington University ======================================================================= 21 === Date: 8 Oct 92 12:03:57 From: vixie@pa.dec.com (Paul A Vixie) Subject: another thread example Someone pointed out in private mail that my previous Thread example wouldn't compile without some libraries that I refuse to publish due to extreme embarrassment. At the risk of publishing code that does nothing useful, here is a shorter Thread example that has no non- published dependencies. MODULE Main; IMPORT Stdio, Wr, Fmt, Thread, Text, Time; TYPE LockedIndex = MUTEX OBJECT index := 0; END; VAR Inner := NEW(LockedIndex); Outer := 0; PROCEDURE InnerF(self: Thread.Closure): REFANY RAISES {} = BEGIN LOOP LOCK Inner DO INC(Inner.index); END; END; END InnerF; BEGIN EVAL Thread.Fork(NEW(Thread.Closure, apply := InnerF)); LOOP Time.LongPause(1); LOCK Inner DO Wr.PutText(Stdio.stdout, "Inner=" & Fmt.Int(Inner.index) & "; " & "Outer=" & Fmt.Int(Outer) & "\n"); Wr.Flush(Stdio.stdout); INC(Outer); Inner.index := 0; END; END; END Main. -- Paul Vixie, DEC Network Systems Lab Palo Alto, California, USA "Don't be a rebel, or a conformist; decwrl!vixie they're the same thing, anyway. Find vixie!paul your own path, and stay on it." -me ======================================================================= 22 === Date: 8 Oct 92 21:41:06 GMT From: tlai@cs.toronto.edu (Tony Wen Hsun Lai) Subject: Extending Modula-3 with MI? There was an article by Bracha and Lindstrom in the 1992 International Conference on Computer Languages called "Modularity meets Inheritance". The article briefly mentioned work on an upwardly compatible extension of Modula-3 that would have multiple inheritance and mixins. Does anyone know much about this? ======================================================================= 23 === Date: Thu, 08 Oct 92 17:48:50 EDT From: Roger Hoover Subject: m3 changes for IBMR2/SPARC I've been hacking on the m3 2.08 test release on gatekeeper. I have the IBMR2 version so it will compile out of the box, and have added shared library code for both IBMR2 and SPARC. Below is a textual description of the changes. Complete context diffs follow that. The IBMR2 version still has bugs---I think they are color related. roger hoover rhoover@watson.ibm.com ./m3make/src/Makefile Added confige file #define: IMAKEFLAGS to allow args such as -DREDUCED_TO_ASCII_SPACE to be defined while compiling imake. ./m3make/src/mklist.awk Minor changes to avoid redirection to string expression. Caused AIX 3.2 awk to barf. ./m3make/src/toplevel.tmpl Shared library support. Added second arg to Library() function, the second arg specifies which other libraries are referenced by the library being built. Two config file #defines are used: SHLIBARGS is included with the m3 command to build the lib MKSHLIB(l,d) builds a shared library l (with dependent libs d) from m3 output The install part of library is hacked to install a SunOS .so.1.1 shared lib. ./m3make/model-configs/SPARC ./m3make/model-configs/IBMR2 defined SHLIBARGS, MKSHLIB, IMAKEFLAGS. These should be added with blank defs to all of the other model-configs. I also fixed a couple of bugs in IBMR2. ./m3make/src/Makefile Added confige file #define: IMAKEFLAGS to allow args such as -DREDUCED_TO_ASCII_SPACE to be defined while compiling imake. ./m3make/src/mklist.awk Minor changes to avoid redirection to string expression. Caused AIX 3.2 awk to barf. ./m3make/src/toplevel.tmpl Shared library support. Added second arg to Library() function, the second arg specifies which other libraries are referenced by the library being built. Two config file #defines are used: SHLIBARGS is included with the m3 command to build the lib MKSHLIB(l,d) builds a shared library l (with dependent libs d) from m3 output The install part of library is hacked to install a SunOS .so.1.1 shared lib. ./m3make/model-configs/SPARC ./m3make/model-configs/IBMR2 defined SHLIBARGS, MKSHLIB, IMAKEFLAGS. These should be added with blank defs to all of the other model-configs. I also fixed a couple of bugs in IBMR2. ./driver/src/Main.m3 The driver assumes that the pass 3 command takes a "cru" or "cruv" option. This does not work for SunOS shared libraries, where you need to do a load. I hacked the driver to put in the "cru" or "cruv" option only if the last two letters of pass_3 are "ar". Not pretty, but any other reasonable way would have axed the automatic "v" archive option. ./compiler/src/exprs/ArrayExpr.m3 ./compiler/src/exprs/ReelExpr.m3 ./compiler/src/exprs/TextExpr.m3 ./compiler/src/misc/Coverage.m3 ./compiler/src/misc/ESet.m3 ./compiler/src/misc/Fault.m3 ./compiler/src/stmts/TryFinStmt.m3 ./compiler/src/stmts/TryStmt.m3 ./compiler/src/types/ObjectType.m3 ./compiler/src/types/OpaqueType.m3 ./compiler/src/types/RefType.m3 ./compiler/src/types/Type.m3 ./compiler/src/values/Constant.m3 ./compiler/src/values/Module.m3 ./compiler/src/values/Procedure.m3 ./compiler/src/values/Revelation.m3 ./compiler/src/values/Value.i3 ./compiler/src/values/Value.m3 ./compiler/src/values/Variable.m3 The IBMR2 M3Machine.h config file had volatile in the definitions of _PRIVATE, _IMPORT, and _EXPORT. It isn't that easy. The RS6000 xlc compiler is rigerous at inforcing the ansi c standard with respect to volatile. The compiler now generates _VOLATILE at the appropriate places. _VOLATILE should be defined to be "volatile" if the compiler supports it, or "" if not. Note that xlc compilers before Version 01.02.0000.0009 has bugs with volatile type defs. ./libm3/Csupport/src/IBMR2/M3Machine.h ./libm3/Csupport/src/SPARC/M3Machine.h _VOLATILE is now defined. This needs to be done for the other machines. ./libm3/src/m3makefile ./X11R4/src/m3makefile ./trestle/src/m3makefile Library() now has a second arg. ./trestle/src/xvbtm3/XClient.m3 M3 compilation error. Fixed in the obvious way. -----Context Diffs follow ----- *** m3-2.08/./m3make/src/Makefile Thu Aug 6 01:27:07 1992 --- improved/./m3make/src/Makefile Thu Oct 8 13:41:47 1992 *************** *** 9,16 **** imake: ../src/imake.c config n=`sed -n -e 's/^CPP[ \t]*=[ \t]*//p' -e 'd' < config`; \ m=`sed -n -e 's/^CC[ \t]*=[ \t]*//p' -e 'd' < config`; \ sed -e 's+M3_CPP+'$$n'+' ../src/imake.c > imake.c; \ ! $$m -o imake imake.c all install scratch:: @t=`sed -n -e 's/^TEMPLATE[ \t]*=[ \t*]//p' -e 'd' < config`; \ --- 9,17 ---- imake: ../src/imake.c config n=`sed -n -e 's/^CPP[ \t]*=[ \t]*//p' -e 'd' < config`; \ m=`sed -n -e 's/^CC[ \t]*=[ \t]*//p' -e 'd' < config`; \ + z=`sed -n -e 's/^IMAKEFLAGS[ \t]*=[ \t]*//p' -e 'd' < config`; \ sed -e 's+M3_CPP+'$$n'+' ../src/imake.c > imake.c; \ ! $$m $$z -o imake imake.c all install scratch:: @t=`sed -n -e 's/^TEMPLATE[ \t]*=[ \t*]//p' -e 'd' < config`; \ *** m3-2.08/./m3make/src/mklist.awk Fri Mar 20 21:46:40 1992 --- improved/./m3make/src/mklist.awk Mon Sep 28 15:42:19 1992 *************** *** 40,46 **** print " ", file_data[name "," (n-1)] } else { print name, "= -F." name ! for (i = 0; i < n; i++) { print file_data[name "," i] > "." name } } } } --- 40,46 ---- print " ", file_data[name "," (n-1)] } else { print name, "= -F." name ! for (i = 0; i < n; i++) {filename = "." name; print file_data[name "," i] > filename } } } } *************** *** 47,53 **** if (any_always != 0) { for (name in always_count) { n = always_count[name]; ! for (i = 0; i < n; i++) { print always_data[name "," i] > "." name } } } } --- 47,53 ---- if (any_always != 0) { for (name in always_count) { n = always_count[name]; ! for (i = 0; i < n; i++) {filename = "." name; print always_data[name "," i] > filename } } } } *** m3-2.08/./m3make/src/toplevel.tmpl Thu Sep 3 04:05:38 1992 --- improved/./m3make/src/toplevel.tmpl Wed Oct 7 18:24:02 1992 *************** *** 160,176 **** /*------------------------------------------------------ library building --- */ ! #define library(name) @ @\ all:: lib##name.a @ @\ clean:: ; rm -f lib##name.a lib##name.ax @ @\ ! lib##name.a: FRC; $(DO_M3) -a lib##name.a $(PGM_SOURCES) $(IMPORT_LIBS) ! #define Library(name) @ @\ install:: @ @\ ! INSTALL (lib##name.a, $(LIB_INSTALL), 644) @@\ INSTALL (lib##name.ax, $(LIB_INSTALL), 644) @@\ ! ranlib $(LIB_INSTALL)/lib##name.a @@\ ! library(name) #define LibExport(name) @ @\ install:: @ @\ --- 160,185 ---- /*------------------------------------------------------ library building --- */ ! #define library(name, deplibs) @ @\ all:: lib##name.a @ @\ clean:: ; rm -f lib##name.a lib##name.ax @ @\ ! lib##name.a: FRC; @ @\ ! $(DO_M3) -a lib##name.a SHLIBARGS $(PGM_SOURCES) $(IMPORT_LIBS) @@\ ! MKSHLIB (lib##name, deplibs) ! #define Library(name, deplibs) @ @\ install:: @ @\ ! if [ -f lib##name.a ]; then \ @@\ ! INSTALL (lib##name.a, $(LIB_INSTALL), 644);\ @@\ ! fi @@\ ! if [ -f lib##name.so.1.1 ]; then \ @@\ ! INSTALL (lib##name.so.1.1, $(LIB_INSTALL), 644);\ @@\ ! fi @@\ INSTALL (lib##name.ax, $(LIB_INSTALL), 644) @@\ ! if [ -f $(LIB_INSTALL)/lib##name.a ]; then \ @@\ ! ranlib $(LIB_INSTALL)/lib##name.a;\ @@\ ! fi @@\ ! library(name, deplibs) #define LibExport(name) @ @\ install:: @ @\ *** m3-2.08/./m3make/model-configs/SPARC Mon May 4 16:52:02 1992 --- improved/./m3make/model-configs/SPARC Thu Oct 8 13:56:55 1992 *************** *** 109,115 **** /* When m3(1) receives the -O option, it really does this */ CC_O = @-O@ ! /* Give the value 0 if you want the m3 driver to pass -L/-l arguments to LD for libraries; otherwise (value = 1), the m3 driver will pass the full path name of the librairies it located */ --- 109,118 ---- /* When m3(1) receives the -O option, it really does this */ CC_O = @-O@ ! ! #define SHLIBARGS -X1@-PIC@ -Y3@$/bin/ld@-assert@pure-text@-o@ -Y4@/bin/true@ ! #define MKSHLIB(libname,deplibs) mv libname.a libname.so.1.1 ! /* Give the value 0 if you want the m3 driver to pass -L/-l arguments to LD for libraries; otherwise (value = 1), the m3 driver will pass the full path name of the librairies it located */ *************** *** 132,137 **** --- 135,143 ---- Note: the value of this symbol must not use the values of other symbols. * / CPP = /lib/cpp + + /* Flags needed to make imake */ + IMAKEFLAGS = /* What about MAKE ? *** m3-2.08/./m3make/model-configs/IBMR2 Mon May 4 16:52:04 1992 --- improved/./m3make/model-configs/IBMR2 Thu Oct 8 13:49:57 1992 *************** *** 1,4 **** ! /* Copyright (C) 1989, 1992 Digital Equipment Corporation */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ --- 1,4 ---- ! /* Copyright (C) 1989, 1992 Digital Equipment Corporation */ /* All rights reserved. */ /* See the file COPYRIGHT for a full description. */ *************** *** 149,158 **** /* When m3(1) receives the -O option, it really does this */ CC_O = @-O@ /* Give the value 0 if you want the m3 driver to pass -L/-l arguments to LD for libraries; otherwise (value = 1), the m3 driver will pass the full path name of the librairies it located */ ! KEEP_LIBRARIES_RESOLVED = 1 /* We don't want to use the predefined CFLAGS */ CFLAGS = --- 149,161 ---- /* When m3(1) receives the -O option, it really does this */ CC_O = @-O@ + #define SHLIBARGS + #define MKSHLIB(libname,deplibs) /bin/dump -g libname.a | sed -n -e 's/^[ ]*[0-9][0-9]*[ ]*\([^ .][^ ]*\)$$/\1/p' > _expnames; /bin/bsdcc -bE:_expnames -bM:SRE -o _shar.o libname.a -L$(LIB_USE) deplibs -e _nostart; rm libname.a; /bin/ar cru libname.a _shar.o; /bin/rm -f _expnames _shar.o + /* Give the value 0 if you want the m3 driver to pass -L/-l arguments to LD for libraries; otherwise (value = 1), the m3 driver will pass the full path name of the librairies it located */ ! KEEP_LIBRARIES_RESOLVED = 0 /* we need -L/-l for shared libraries */ /* We don't want to use the predefined CFLAGS */ CFLAGS = *************** *** 170,181 **** /* What about CPP ? Note: the value of this symbol must not use the values of other symbols. * / ! CPP = /usr/local/lib/cpp /* What about MAKE ? Note: the value of this symbol must not use the values of other symbols. * / ! MAKE = make /* And install */ #define INSTALL(f,d,p) install -c -m p f d --- 173,187 ---- /* What about CPP ? Note: the value of this symbol must not use the values of other symbols. * / ! CPP = /usr/lpp/X11/Xamples/util/cpp/cpp ! ! /* Flags needed to make imake */ ! IMAKEFLAGS = -DREDUCED_TO_ASCII_SPACE /* What about MAKE ? Note: the value of this symbol must not use the values of other symbols. * / ! MAKE = /usr/bin/make /* And install */ #define INSTALL(f,d,p) install -c -m p f d *************** *** 211,216 **** --- 217,223 ---- OVERLAY_0 = @-g@ OVERLAY_1 = @-lc@ BASE_ARGS = @-N@ + PASS1_LIBRARY = /* The maximum size (in megabytes) that Pass0 is allowed to reach as a persistent server before the driver kills it. Setting SERVER_LIMIT *************** *** 237,244 **** LINKBFILES = @-lm@ LINKFILES = @-lm3@-lm@ ! /* These files are linked with Modula-3 programs when -Z is specified. *. ! LINKCOVER = $(LIB_USE)/report_coverage.o /* The C code generated by the Modula-3 to C translator #include's some basic files, to be found in this directory. */ --- 244,251 ---- LINKBFILES = @-lm@ LINKFILES = @-lm3@-lm@ ! /* These files are linked with Modula-3 programs when -Z is specified. */ ! LINKCOVER = $(LIB_USE)/report_coverage.o /* The C code generated by the Modula-3 to C translator #include's some basic files, to be found in this directory. */ *** m3-2.08/./driver/src/Main.m3 Mon Aug 10 11:02:08 1992 --- improved/./driver/src/Main.m3 Wed Oct 7 16:09:37 1992 *************** *** 1746,1752 **** ETimer.Push (pass3_timer); Append (args, pass_3); AppendL (args, pass_3_args); ! Append (args, ArOptions [msg_level >= MsgLevel.Debug]); Append (args, lib); Append (args, Main_O); a := objects.head; --- 1746,1754 ---- ETimer.Push (pass3_timer); Append (args, pass_3); AppendL (args, pass_3_args); ! IF Text.Equal(Text.Sub(pass_3, Text.Length(pass_3)-2, 2), "ar") THEN ! Append (args, ArOptions [msg_level >= MsgLevel.Debug]); ! END; Append (args, lib); Append (args, Main_O); a := objects.head; *** m3-2.08/./compiler/src/exprs/ArrayExpr.m3 Tue Jun 30 11:25:14 1992 --- improved/./compiler/src/exprs/ArrayExpr.m3 Mon Oct 5 14:25:46 1992 *************** *** 379,385 **** TYPECASE array OF | NULL => RETURN; | P(p) => IF (p.uid # 0) AND NUMBER (p.args^) # 0 THEN ! Emit.OpF ("_PRIVATE @ ", OpenArrayType.OpenType (p.tipe)); Emit.OpI ("_openConst@ [] = {", p.uid); GenOpenLiteral (p); Emit.Op ("};\n"); --- 379,385 ---- TYPECASE array OF | NULL => RETURN; | P(p) => IF (p.uid # 0) AND NUMBER (p.args^) # 0 THEN ! Emit.OpF ("_PRIVATE _VOLATILE @ ", OpenArrayType.OpenType (p.tipe)); Emit.OpI ("_openConst@ [] = {", p.uid); GenOpenLiteral (p); Emit.Op ("};\n"); *** m3-2.08/./compiler/src/exprs/ReelExpr.m3 Tue Jun 30 11:25:23 1992 --- improved/./compiler/src/exprs/ReelExpr.m3 Mon Oct 5 14:26:25 1992 *************** *** 128,134 **** (* make sure the literal pool is started *) IF (newUID = 0) THEN Emit.RegisterShutDown (LitStream[p.pre], FinishLiteralPool); ! Emit.Op ("_PRIVATE "); Emit.Op (PoolType[p.pre]); Emit.Op (Tag[p.pre]); Emit.Op ("[] = {\n"); --- 128,134 ---- (* make sure the literal pool is started *) IF (newUID = 0) THEN Emit.RegisterShutDown (LitStream[p.pre], FinishLiteralPool); ! Emit.Op ("_PRIVATE _VOLATILE "); Emit.Op (PoolType[p.pre]); Emit.Op (Tag[p.pre]); Emit.Op ("[] = {\n"); *** m3-2.08/./compiler/src/exprs/TextExpr.m3 Tue Jun 30 11:25:24 1992 --- improved/./compiler/src/exprs/TextExpr.m3 Mon Oct 5 14:27:12 1992 *************** *** 66,72 **** save := Emit.Switch (Emit.Stream.TextLiterals); uid := nextID; INC (nextID); String.SetUID (p.value, uid); ! Emit.OpI ("_PRIVATE _TXT _txt@ = ", uid); EmitRep (p.value); Emit.Op (";\n"); EVAL Emit.Switch (save); --- 66,72 ---- save := Emit.Switch (Emit.Stream.TextLiterals); uid := nextID; INC (nextID); String.SetUID (p.value, uid); ! Emit.OpI ("_PRIVATE _VOLATILE _TXT _txt@ = ", uid); EmitRep (p.value); Emit.Op (";\n"); EVAL Emit.Switch (save); *** m3-2.08/./compiler/src/misc/Coverage.m3 Mon Apr 27 19:57:04 1992 --- improved/./compiler/src/misc/Coverage.m3 Mon Oct 5 14:28:30 1992 *************** *** 82,88 **** fname := String.FileTail (Host.filename); (* generate the coverage tables *) ! Emit.Op ("_PRIVATE struct {\001\n"); Emit.OpI ("char header [@];\n", SLen (header)); Emit.Op ("int timestamp;\n"); Emit.Op ("int fileLen;\n"); --- 82,88 ---- fname := String.FileTail (Host.filename); (* generate the coverage tables *) ! Emit.Op ("_PRIVATE _VOLATILE struct {\001\n"); Emit.OpI ("char header [@];\n", SLen (header)); Emit.Op ("int timestamp;\n"); Emit.Op ("int fileLen;\n"); *** m3-2.08/./compiler/src/misc/ESet.m3 Wed May 6 11:13:49 1992 --- improved/./compiler/src/misc/ESet.m3 Mon Oct 5 14:28:57 1992 *************** *** 152,158 **** IF (t.age >= thisAge) THEN RETURN END; e := t.elts; WHILE (e # NIL) DO Value.Declare0 (e.except); e := e.next; END; ! Emit.OpI ("_PRIVATE _EXCEPTION _raises_@ [] = {\n\001", t.uid); e := t.elts; WHILE (e # NIL) DO IF (e.except # NIL) THEN Emit.OpN ("& @, ", e.except) END; --- 152,158 ---- IF (t.age >= thisAge) THEN RETURN END; e := t.elts; WHILE (e # NIL) DO Value.Declare0 (e.except); e := e.next; END; ! Emit.OpI ("_PRIVATE _VOLATILE _EXCEPTION _raises_@ [] = {\n\001", t.uid); e := t.elts; WHILE (e # NIL) DO IF (e.except # NIL) THEN Emit.OpN ("& @, ", e.except) END; *** m3-2.08/./compiler/src/misc/Fault.m3 Thu Feb 27 19:46:21 1992 --- improved/./compiler/src/misc/Fault.m3 Mon Oct 5 14:29:34 1992 *************** *** 22,28 **** IF (NOT file_declared) THEN file_declared := TRUE; save := Emit.Switch (Emit.Stream.TextLiterals); ! Emit.Op ("_PRIVATE _TXT __file = "); TextExpr.EmitRep (file); Emit.Op (";\n"); EVAL Emit.Switch (save); --- 22,28 ---- IF (NOT file_declared) THEN file_declared := TRUE; save := Emit.Switch (Emit.Stream.TextLiterals); ! Emit.Op ("_PRIVATE _VOLATILE _TXT __file = "); TextExpr.EmitRep (file); Emit.Op (";\n"); EVAL Emit.Switch (save); *** m3-2.08/./compiler/src/stmts/TryStmt.m3 Wed Jul 22 12:10:23 1992 --- improved/./compiler/src/stmts/TryStmt.m3 Mon Oct 5 14:30:38 1992 *************** *** 283,289 **** VAR h: Handler; e: Except; save: Emit.Stream; BEGIN save := Emit.Switch (Emit.Stream.Constants); ! Emit.OpI ("_PRIVATE _EXCEPTION _try_labels_@ [] = {\n\001", label); h := p.handles; WHILE (h # NIL) DO e := h.tags; --- 283,289 ---- VAR h: Handler; e: Except; save: Emit.Stream; BEGIN save := Emit.Switch (Emit.Stream.Constants); ! Emit.OpI ("_PRIVATE _VOLATILE _EXCEPTION _try_labels_@ [] = {\n\001", lab el); h := p.handles; WHILE (h # NIL) DO e := h.tags; *** m3-2.08/./compiler/src/types/ObjectType.m3 Mon Jun 8 11:30:12 1992 --- improved/./compiler/src/types/ObjectType.m3 Mon Oct 5 14:40:11 1992 *************** *** 450,456 **** GenFields (p, fields, nFields); (* import my type cell *) ! Emit.OpF ("_IMPORT _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; --- 450,456 ---- GenFields (p, fields, nFields); (* import my type cell *) ! Emit.OpF ("_IMPORT _VOLATILE _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; *************** *** 491,497 **** GenMapProc (p, fields, nFields); (* generate my Type cell info *) ! Emit.OpF ("_PRIVATE _TYPE @_tc = {\n", p); Emit.Op (" 0, 0,\n"); (* typecode, lastSubTypeTC *) Emit.OpH (" 0x@,\n", (* selfID *) Type.Name (p)); --- 491,497 ---- GenMapProc (p, fields, nFields); (* generate my Type cell info *) ! Emit.OpF ("_PRIVATE _VOLATILE _TYPE @_tc = {\n", p); Emit.Op (" 0, 0,\n"); (* typecode, lastSubTypeTC *) Emit.OpH (" 0x@,\n", (* selfID *) Type.Name (p)); *** m3-2.08/./compiler/src/types/OpaqueType.m3 Mon Mar 2 14:18:10 1992 --- improved/./compiler/src/types/OpaqueType.m3 Mon Oct 5 14:40:34 1992 *************** *** 103,109 **** Emit.OpF ("typedef _ADDRESS @;\n", p); (* import my type cell *) ! Emit.OpF ("_IMPORT _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; Emit.OpF ("S@\n", p.super); --- 103,109 ---- Emit.OpF ("typedef _ADDRESS @;\n", p); (* import my type cell *) ! Emit.OpF ("_IMPORT _VOLATILE _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; Emit.OpF ("S@\n", p.super); *** m3-2.08/./compiler/src/types/RefType.m3 Mon Mar 2 14:20:14 1992 --- improved/./compiler/src/types/RefType.m3 Mon Oct 5 14:40:53 1992 *************** *** 237,243 **** Type.Compile (p.target); (* import my type cell *) ! Emit.OpF ("_IMPORT _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; Emit.OpF ("d@\n", p.target); --- 237,243 ---- Type.Compile (p.target); (* import my type cell *) ! Emit.OpF ("_IMPORT _VOLATILE _TYPE* @_TC;\n", p); IF TypeRep.StartLinkInfo (p) THEN RETURN END; Emit.OpF ("d@\n", p.target); *************** *** 296,302 **** END; (* generate my Type cell info *) ! Emit.OpF ("\n_PRIVATE _TYPE @_tc = {\n", p); Emit.Op (" 0, 0,\n"); (* typecode, lastSubTypeTC *) Emit.OpH (" 0x@,\n", (* selfID *) Type.Name (p)); --- 296,302 ---- END; (* generate my Type cell info *) ! Emit.OpF ("\n_PRIVATE _VOLATILE _TYPE @_tc = {\n", p); Emit.Op (" 0, 0,\n"); (* typecode, lastSubTypeTC *) Emit.OpH (" 0x@,\n", (* selfID *) Type.Name (p)); *** m3-2.08/./compiler/src/types/Type.m3 Thu Jul 2 14:24:46 1992 --- improved/./compiler/src/types/Type.m3 Mon Oct 5 14:32:21 1992 *************** *** 504,510 **** IF NOT OpaqueType.Is (t) THEN EVAL Emit.Switch (Emit.Stream.TypeFPs); IF (next_fp_data = 0) THEN ! Emit.Op ("_PRIVATE int _fp_data[] = {\n"); END; wr := MBuf.New (); map := NEW (FPMap, deep := FALSE, cnt := 0, list := NEW (TypeVec, 20) ); --- 504,510 ---- IF NOT OpaqueType.Is (t) THEN EVAL Emit.Switch (Emit.Stream.TypeFPs); IF (next_fp_data = 0) THEN ! Emit.Op ("_PRIVATE _VOLATILE int _fp_data[] = {\n"); END; wr := MBuf.New (); map := NEW (FPMap, deep := FALSE, cnt := 0, list := NEW (TypeVec, 20) ); *************** *** 552,558 **** IF (first_header = NIL) THEN Emit.Op ("\003#define _type_info 0\n"); ELSE ! Emit.Op ("_PRIVATE _TYPE_INFO _type_info [] = {\n"); x := first_header; WHILE (x # NIL) DO t := x.type; --- 552,558 ---- IF (first_header = NIL) THEN Emit.Op ("\003#define _type_info 0\n"); ELSE ! Emit.Op ("_PRIVATE _VOLATILE _TYPE_INFO _type_info [] = {\n"); x := first_header; WHILE (x # NIL) DO t := x.type; *************** *** 576,582 **** t := x.type; c := t.class (); IF (c = Class.Ref) OR (c = Class.Object) THEN ! IF (n = 0) THEN Emit.Op ("_PRIVATE _TYPE* _type_cells [] = {\n") END; Emit.OpF (" &@_tc,", t); EndLine (t); INC (n); --- 576,582 ---- t := x.type; c := t.class (); IF (c = Class.Ref) OR (c = Class.Object) THEN ! IF (n = 0) THEN Emit.Op ("_PRIVATE _VOLATILE _TYPE* _type_cells [] = {\n") END; Emit.OpF (" &@_tc,", t); EndLine (t); INC (n); *** m3-2.08/./compiler/src/values/Constant.m3 Wed Apr 15 12:56:29 1992 --- improved/./compiler/src/values/Constant.m3 Mon Oct 5 14:44:39 1992 *************** *** 164,170 **** Type.Compile (t.tipe); IF (t.exported) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_EXPORT @ ", t.tipe); Emit.OpN ("@ = ", t); Expr.GenLiteral (t.value); Emit.Op (";\n"); --- 164,170 ---- Type.Compile (t.tipe); IF (t.exported) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_EXPORT _VOLATILE @ ", t.tipe); Emit.OpN ("@ = ", t); Expr.GenLiteral (t.value); Emit.Op (";\n"); *************** *** 171,182 **** t.written := TRUE; ELSIF (t.imported) AND (t.loaded) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_IMPORT @ ", t.tipe); Emit.OpN ("@;\n", t); t.written := TRUE; ELSIF (t.loaded) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_PRIVATE @ ", t.tipe); Emit.OpN ("@ = ", t); Expr.GenLiteral (t.value); Emit.Op (";\n"); --- 171,182 ---- t.written := TRUE; ELSIF (t.imported) AND (t.loaded) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_IMPORT _VOLATILE @ ", t.tipe); Emit.OpN ("@;\n", t); t.written := TRUE; ELSIF (t.loaded) THEN ArrayExpr.PreGenLiteral (t.value); ! Emit.OpF ("_PRIVATE _VOLATILE @ ", t.tipe); Emit.OpN ("@ = ", t); Expr.GenLiteral (t.value); Emit.Op (";\n"); *** m3-2.08/./compiler/src/values/Module.m3 Mon Jun 29 14:56:38 1992 --- improved/./compiler/src/values/Module.m3 Mon Oct 5 14:45:32 1992 *************** *** 764,770 **** save := Emit.Switch (Emit.Stream.LinkTables); Scanner.offset := t.origin; Scanner.Here (file, line); ! Emit.OpX ("_EXPORT _LINK_INFO @", tag [t.interface]); Emit.OpS ("@ = {\n", t.name); Emit.OpS (" \"@\",\n", file); Emit.Op (" _type_info,\n"); --- 764,770 ---- save := Emit.Switch (Emit.Stream.LinkTables); Scanner.offset := t.origin; Scanner.Here (file, line); ! Emit.OpX ("_EXPORT _VOLATILE _LINK_INFO @", tag [t.interface]); Emit.OpS ("@ = {\n", t.name); Emit.OpS (" \"@\",\n", file); Emit.Op (" _type_info,\n"); *** m3-2.08/./compiler/src/values/Procedure.m3 Tue Jun 30 13:56:49 1992 --- improved/./compiler/src/values/Procedure.m3 Tue Oct 6 11:35:44 1992 *************** *** 323,329 **** (* try to compile the imported type first... *) save := Emit.Switch (Emit.Stream.ProcHeads); ! Value.GenStorageClass (p); Emit.OpF ("@ ", ProcType.CResult (p.signature)); WriteName (p); Emit.Op (" ();\n"); --- 323,329 ---- (* try to compile the imported type first... *) save := Emit.Switch (Emit.Stream.ProcHeads); ! Value.GenNovolStorageClass (p); Emit.OpF ("@ ", ProcType.CResult (p.signature)); WriteName (p); Emit.Op (" ();\n"); *************** *** 380,386 **** WHILE (p # NIL) DO IF (p.hasBody) AND (NOT p.builtin) AND (NOT IsNested (p)) THEN IF (n = 0) THEN ! Emit.Op ("\n_PRIVATE _PROC_INFO _proc_info [] = {\n"); END; GenRegistration (p); INC (n); --- 380,386 ---- WHILE (p # NIL) DO IF (p.hasBody) AND (NOT p.builtin) AND (NOT IsNested (p)) THEN IF (n = 0) THEN ! Emit.Op ("\n_PRIVATE _VOLATILE _PROC_INFO _proc_info [] = {\n"); END; GenRegistration (p); INC (n); *************** *** 456,462 **** Frame.Push (frame, 0, TRUE); ! Value.GenStorageClass (p); IF ProcType.LargeResult (tresult) THEN Emit.Op ("_VOID "); ELSE Emit.OpF ("@ ", tresult); --- 456,462 ---- Frame.Push (frame, 0, TRUE); ! Value.GenNovolStorageClass (p); IF ProcType.LargeResult (tresult) THEN Emit.Op ("_VOID "); ELSE Emit.OpF ("@ ", tresult); *** m3-2.08/./compiler/src/values/Revelation.m3 Wed Jul 22 11:34:12 1992 --- improved/./compiler/src/values/Revelation.m3 Mon Oct 5 14:33:28 199 2 *************** *** 576,582 **** t := l.ident; IF (l.local= local) AND (t.equal = full) AND (local OR l.used) TH EN IF (cnt = 0) THEN ! Emit.OpX("_PRIVATE _TYPE_PAIR @[] = {\n",name); END; Emit.OpFF (" { &@_TC, &@_TC, ", t.lhs, t.rhs); Emit.OpHH ("0x@, 0x@ },\n", Type.Name (t.lhs), Type.Name(t.rhs) ); --- 576,582 ---- t := l.ident; IF (l.local= local) AND (t.equal = full) AND (local OR l.used) TH EN IF (cnt = 0) THEN ! Emit.OpX("_PRIVATE _VOLATILE _TYPE_PAIR @[] = {\n",name); END; Emit.OpFF (" { &@_TC, &@_TC, ", t.lhs, t.rhs); Emit.OpHH ("0x@, 0x@ },\n", Type.Name (t.lhs), Type.Name(t.rhs) ); *** m3-2.08/./compiler/src/values/Value.i3 Mon Feb 10 18:10:29 1992 --- improved/./compiler/src/values/Value.i3 Tue Oct 6 11:36:02 1992 *************** *** 36,41 **** --- 36,42 ---- PROCEDURE ClassOf (t: T): Class; PROCEDURE Fingerprint (t: T; map: Type.FPMap; wr: MBuf.T); PROCEDURE GenStorageClass (t: T); + PROCEDURE GenNovolStorageClass (t: T); PROCEDURE IsExternal (t: T): BOOLEAN; PROCEDURE IsImported (t: T): BOOLEAN; PROCEDURE IsWritable (t: T): BOOLEAN; *** m3-2.08/./compiler/src/values/Value.m3 Wed Jul 22 12:44:20 1992 --- improved/./compiler/src/values/Value.m3 Tue Oct 6 11:36:32 1992 *************** *** 126,131 **** --- 126,146 ---- PROCEDURE GenStorageClass (t: T) = BEGIN IF t.external THEN + Emit.Op ("_IMPORT _VOLATILE "); + ELSE + CASE StorageClass (t) OF + | SC.Exported => Emit.Op ("_EXPORT _VOLATILE "); + | SC.Imported => Emit.Op ("_IMPORT _VOLATILE "); + | SC.Global => Emit.Op ("_PRIVATE _VOLATILE "); + | SC.LocalProc => Emit.Op ("_LOCAL_PROC "); + | SC.Local => Emit.Op ("_LOCAL "); + END; + END; + END GenStorageClass; + + PROCEDURE GenNovolStorageClass (t: T) = + BEGIN + IF t.external THEN Emit.Op ("_IMPORT "); ELSE CASE StorageClass (t) OF *************** *** 136,142 **** | SC.Local => Emit.Op ("_LOCAL "); END; END; ! END GenStorageClass; PROCEDURE GenVSClass (t: T; sc: SC) = BEGIN --- 151,157 ---- | SC.Local => Emit.Op ("_LOCAL "); END; END; ! END GenNovolStorageClass; PROCEDURE GenVSClass (t: T; sc: SC) = BEGIN *** m3-2.08/./compiler/src/values/Variable.m3 Thu Jul 2 10:43:40 1992 --- improved/./compiler/src/values/Variable.m3 Tue Oct 6 11:30:04 1992 *************** *** 313,325 **** Frame.NoteDeclaration (t.tipe); IF t.initID # -1 THEN ! Emit.OpF ("_PRIVATE @ ", t.tipe); Emit.OpI ("_init@ = ", t.initID); Expr.GenLiteral (Expr.ConstValue (t.init)); Emit.Op (";\n"); END; ! Value.GenStorageClass (t); DeclareType (t); Emit.OpN ("@", t); IF (t.init = NIL) OR (t.imported) OR (NOT Scope.OuterMost (t.scope)) THEN --- 313,325 ---- Frame.NoteDeclaration (t.tipe); IF t.initID # -1 THEN ! Emit.OpF ("_PRIVATE _VOLATILE @ ", t.tipe); Emit.OpI ("_init@ = ", t.initID); Expr.GenLiteral (Expr.ConstValue (t.init)); Emit.Op (";\n"); END; ! Value.GenNovolStorageClass (t); DeclareType (t); Emit.OpN ("@", t); IF (t.init = NIL) OR (t.imported) OR (NOT Scope.OuterMost (t.scope)) THEN *** m3-2.08/./libm3/Csupport/src/IBMR2/M3Machine.h Fri Feb 28 14:15:12 199 2 --- improved/./libm3/Csupport/src/IBMR2/M3Machine.h Tue Oct 6 11:46:44 199 2 *************** *** 14,23 **** #pragma alloca /* These are the storage classes and type qualifiers */ ! #define _PRIVATE static volatile ! #define _IMPORT extern volatile ! #define _EXPORT volatile #define _LOCAL_PROC static #define _LOCAL auto --- 14,24 ---- #pragma alloca /* These are the storage classes and type qualifiers */ + #define _VOLATILE volatile ! #define _PRIVATE static ! #define _IMPORT extern ! #define _EXPORT #define _LOCAL_PROC static #define _LOCAL auto *************** *** 65,71 **** /* NILCHECKB must evaluate its argument 'e' (a char*) and generate a trap if it is NIL (0). */ ! extern volatile char _M3__nil_check_char; #define _NILCHECKB(e) _M3__nil_check_char = ((char*)(e))[-1]; --- 66,72 ---- /* NILCHECKB must evaluate its argument 'e' (a char*) and generate a trap if it is NIL (0). */ ! extern _VOLATILE char _M3__nil_check_char; #define _NILCHECKB(e) _M3__nil_check_char = ((char*)(e))[-1]; *************** *** 75,79 **** typedef signed int signed_int; /* builtin types */ ! #define _ADDRESS volatile char* --- 76,80 ---- typedef signed int signed_int; /* builtin types */ ! #define _ADDRESS _VOLATILE char* *** m3-2.08/./libm3/Csupport/src/SPARC/M3Machine.h Fri Feb 28 14:23:56 199 2 --- improved/./libm3/Csupport/src/SPARC/M3Machine.h Tue Oct 6 11:44:35 199 2 *************** *** 9,14 **** --- 9,16 ---- /* These are the storage classes and type qualifiers */ + #define _VOLATILE + #define _PRIVATE static #define _IMPORT extern #define _EXPORT *** m3-2.08/./libm3/src/m3makefile Thu Sep 3 04:32:16 1992 --- improved/./libm3/src/m3makefile Tue Oct 6 14:14:03 1992 *************** *** 180,183 **** M3FLAGS = -w1 -make -why -nostd -times ! Library (m3) --- 180,183 ---- M3FLAGS = -w1 -make -why -nostd -times ! Library (m3,-lm) *** m3-2.08/./X11R4/src/m3makefile Thu Sep 3 04:35:54 1992 --- improved/./X11R4/src/m3makefile Mon Oct 5 11:43:08 1992 *************** *** 9,12 **** source_dir (../src/Xt) source_dir (../src/Xaw) ! Library (m3X11R4) --- 9,12 ---- source_dir (../src/Xt) source_dir (../src/Xaw) ! Library (m3X11R4,-lm3) *** m3-2.08/./trestle/src/m3makefile Thu Sep 3 04:36:30 1992 --- improved/./trestle/src/m3makefile Mon Oct 5 13:02:54 1992 *************** *** 12,15 **** import_lib (m3X11R4) ! Library (m3ui) --- 12,15 ---- import_lib (m3X11R4) ! Library (m3ui,-lm3 -lm3X11R4 -lX11) *** m3-2.08/./trestle/src/xvbtm3/XClient.m3 Wed Sep 2 20:33:00 1992 --- improved/./trestle/src/xvbtm3/XClient.m3 Mon Oct 5 12:55:58 1992 *************** *** 4295,4301 **** VAR ehandler := X.XSetErrorHandler(Error); iohandler := X.XSetIOErrorHandler(LOOPHOLE(IOError, X.XIOErrorHandler)); ! vec := Usignal.struct_sigvec{Usignal.SIG_IGN, Usignal.empty_sigset_t, 0}; ovec: Usignal.struct_sigvec; BEGIN --- 4295,4301 ---- VAR ehandler := X.XSetErrorHandler(Error); iohandler := X.XSetIOErrorHandler(LOOPHOLE(IOError, X.XIOErrorHandler)); ! vec := Usignal.struct_sigvec{Usignal.SIG_IGN, Usignal.empty_sv_mask, 0}; ovec: Usignal.struct_sigvec; BEGIN ======================================================================= 24 === Date: 10 Oct 92 22:37:32 GMT From: sorensen@bcsaic.boeing.com (Paul Sorensen) Subject: Philosophy, audience of Oberon and Modula3 ? Recently, I've found some time so look around at less mainstream programming languages -- and having heard good and interesting tidbits about Oberon and Modula3 -- I'd like to ask for a summary of the philosphy, and audience for Oberon and Modula3. Also a brief comparison (if that's a reasonable thing to ask for) of the two would be quite helpful. Thanks, sorensen@atc.boeing.com ======================================================================= 25 === Date: Tue, 13 Oct 1992 02:27:24 GMT From: nr@cs.Princeton.EDU () Subject: Extracting the subtype relation I want to extract the (transitive reduction of) the subtype relation from a Modula-3 program. Can anybody suggest a way to do it, either using the information in the .ix and .mx files, or by writing runtime code to grovel in _types? -- Norman Ramsey nr@princeton.edu ======================================================================= 26 === Date: Tue, 13 Oct 92 12:55:40 EDT From: Geoff.Wyant@East.Sun.COM (Geoffrey Wyant - Sun BOS SunLabs) Subject: Extracting the subtype relation > I want to extract the (transitive reduction of) the subtype relation > from a Modula-3 program. Can anybody suggest a way to do it, either > using the information in the .ix and .mx files, or by writing runtime > code to grovel in _types? > > Norman Ramsey > nr@princeton.edu Why not use M3TK, the Modula-3 AST toolkit. This is one of the things it was designed to help build. There is a modest learning curve, but its pretty straightforward and there is probably already code that does what you want. --geoff ======================================================================= 27 === Date: Tue, 13 Oct 92 17:55:50 GMT From: mjordan@src.dec.com (Mick Jordan) Subject: Re: Extracting the subtype relation In article <9210131655.AA21177@gidney.East.Sun.COM>, Geoff.Wyant@East.Sun.COM ( Geoffrey Wyant - Sun BOS SunLabs) writes: |> Why not use M3TK, the Modula-3 AST toolkit. This is one of the |> things it was designed to help build. There is a modest learning |> curve, but its pretty straightforward and there is probably already |> code that does what you want. |> Since Norman already knows about M3TK, I imagine he has considered that option and rejected it. Although it is certainly possible to use M3TK to do this, the problem is that one needs the entire set of ASTs that make up the program to do the analysis. First, there is the problem of locating the sources of the modules (to generates the ASTs); these are not stored in a single place unlike the interfaces and libraries. Second, the VM requirements for a non-trivial program can be substantial. However, assuming that you can locate all the sources for the program, and thus generate an appropriate search path to feed the "m3check" tool, you can discover the subtype relationship for a given type "I.T" using the command "TypeHierarchy I.T". This form of the command provides a client's view of the type hierarchy, i.e. for opaque types it doesnt show the part of the hierarchy that corresponds to the concrete revelation. The comand "ConcreteTypeHierarchy I.T" shows the complete hierarchy. In a legal program, the first command shows a strict subset of the output from the second command. I am not sure what Norman means by "transitive reduction", perhaps he could elaborate. Despite the plug for M3TK, it is a pretty simple task to garner the information from the run-time _types table. The disadvantage is that the code probably wouldnt be portable between implementations of Modula-3, whereas the AST specification is, by definition, implementation independent. Mick Jordan ======================================================================= 28 === Date: Wed, 14 Oct 1992 01:07:06 GMT From: nr@dynastar (Norman Ramsey) Subject: Re: Extracting the subtype relation Here's a quick and dirty solution to the problem of finding the subtype relation, using _types, also known as RT0u.types. As Mick points out, it's completely non-portable. It's also ugly because it has to be compiled into the program of interest. But it did what I wanted with a minimum of effort. UNSAFE MODULE Subtypes; IMPORT Fmt, M3toC, RT0u, Wr; PROCEDURE Write(wr: Wr.T) = BEGIN FOR i := 0 TO RT0u.nTypes-1 DO WITH p = RT0u.types[i] DO IF p # NIL AND p.name # NIL AND p.parent # NIL AND p.parent.name # NIL THEN Wr.PutText(wr, Fmt.F("%s -> %s;\n", M3toC.StoT(p.name), M3toC.StoT(p.parent.name))); END; END; END; END Write; BEGIN END Subtypes. ======================================================================= 29 === Date: 14 Oct 92 13:31:23 GMT From: fn00@gte.com (Farshad Nayeri) Subject: Re: Porting Modula-3 to a PC: Linux or 386BSD In article fn00@gte.com (Farshad Nayeri) wri tes: [On a separate topic, I have not seen a new message in a long time on this newsgroup. Is anyone out there these days? ] Sorry, apparently there was something wrong with my newsreader. I just figured that there are 50 messages on this newsgroup that I haven't read. That's great! --farshad -- Farshad Nayeri Intelligent Database Systems fn00@gte.com Computer and Intelligent Systems Laboratory (617)466-2473 GTE Laboratories, Waltham, MA "Our research shows that even double-clicking can be hard concept for some new users to grasp." -- John Cook, Apple consumer product manager ======================================================================= 30 === Date: 14 Oct 92 12:27:08 GMT From: steven.haden@gsi.fr (Steven Haden) Subject: test Please do not consider this article... ======================================================================= 31 === Date: 14 Oct 92 21:05:45 GMT From: BERRYMAN@orca.drep.dnd.ca (DON BERRYMAN) Subject: Porting modula3 to HPUX for HP730 Has any body ported Modula3 to HPUX on a HP730??? Don Berryman Defence Research Establishment Pacific Canadian Forces Base Esquimalt Victoria, BC, CANADA, V0S-1B0 604-363-2731 604-363-2856fax berryman@orca.drep.dnd.ca ======================================================================= 32 === Date: Fri, 16 Oct 92 04:29:47 GMT From: pwilliam@nyx.cs.du.edu (PJ Williams) Subject: Re: Modula Usage in CS1? reid@ss6.cps.msu.edu (Dr Richard J. Reid) writes: >Among the 253 schools that have responded to our survey, the >following have indicated they are using >Modula2 >in their CS1 course. >Do you know of any additions or corrections? >Thanks, >Dick University of Wollongong, Australia (Modula-2 for both first year courses) Peter Williams (pwilliam@nyx.cs.du.edu) Computer Engineering undergraduate - University of Wollongong ( Standard disclaimer - "This is MINE, ALL MINE !!" [ get the idea ?] ) >Laurentian University, Sudbury, Ontario ======================================================================= 33 === Date: 16 Oct 1992 07:20:40 GMT From: at243@cleveland.Freenet.Edu (Wallace Lee) Subject: Inheritance I'm just starting to program in Modula-3. And I have some problem... Is Modula-3 a single or multiple inheritance language? What kind of overriding is possible when one type inherits from another? Can a thread in one module access a private variable of another module? I preferred reply this by email, or whatever. Thanx for help Wally :-) -- \/\/\/\/\/<^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^>\/\/\/\/\/ |||||||||< e-mail: at243@po.cwru.edu, user0035@student.anu.edu.au >||||||||| /\/\/\/\/\<_._._._._._._._._._._._._._._._._._._._._._._._._._._.>/\/\/\/\/\ ======================================================================= 34 === Date: Fri, 16 Oct 1992 18:24:25 GMT From: pyeatt@Texaco.com (Larry D. Pyeatt) Subject: Where O' where could my pswrap be? I am trying to build dpskit, and it keeps choking. Here is a transcript: > [aisun2]ak45ldp$ m3make -f m3makefile.dpskit > ============================= Building in SPARC > \ > pswrap -o wraps.c -h wraps.h ../src/wraps.psw > sh: pswrap: not found > *** Error code 1 > make: Fatal error: Command failed for target `wraps.h' > Current working directory /public/M3src/dpskit/SPARC > [aisun2]ak45ldp$ What is a pswrap, and why can't I find it? Thanks in advance. -- Larry D. Pyeatt The views expressed here are not Internet : pyeatt@texaco.com those of my employer or of anyone Voice : (713) 975-4056 that I know of with the possible exception of myself. ======================================================================= 35 === Date: Sun, 18 Oct 1992 20:35:13 GMT From: ddean@sapphire.risc.uni-linz.ac.at (Drew Dean) Subject: Speaking of m3tk (was: Re: Extracting the subtype relation) In article <1992Oct13.175550.12129@src.dec.com> mjordan@src.dec.com (Mick Jordan) writes: > In article <9210131655.AA21177@gidney.East.Sun.COM>, Geoff.Wyant@East.Sun.COM (Geoffrey Wyant - Sun BOS SunLabs) writes: > > |> Why not use M3TK, the Modula-3 AST toolkit. This is one of the > |> things it was designed to help build. There is a modest learning > |> curve, but its pretty straightforward and there is probably already > |> code that does what you want. Apologies to the bored, but .... After 3+ years, I finally got hold of a computer that will run Modula-3 (a DECsystem 5000/240). The machine has 2.8 GB of disk, but I can't build m3tk because I run out of space in /tmp (on the root partition, as per DEC factory installed Ultrix 4.2A). I tried setting TMPDIR; I tried making /tmp a symlink to /usr/tmp (/usr has a few hundred MB free), but I can't get ar to use any other partition for its temp file. Help ! Thanks, Drew Dean ddean@risc.uni-linz.ac.at Not speaking for RISC, of course. ======================================================================= 36 === Date: 20 Oct 92 14:34:45 GMT From: dagenais@vlsi.polymtl.ca (Michel Dagenais) Subject: Shared libraries on sun A simple script was posted here about 2 weeks ago to convert normal libraries into shared libraries on sun. Below is a revised version that relies on sh instead of zsh that the original author was using. Some performance statistics are provided too. The compile/link/edit cycle is not improved, only the disk usage appears to benefit significantly. Perhaps if all the library modules were compiled with the -pic option, the linker would have less work to do and the start-up time of the dynamically linked application would diminish; i am not familiar enough with sun shared libraries to guess how the performance would be affected. revised script: #! /bin/csh /bin/ld -o $1:r.so.$2 `/bin/nm -pg $1 | awk '/^[0-9a-f]* D/{printf " -u " $3 }' ` $1 # first argument is the library name e.g. libm3.a and the second argument # is the revision number e.g. 2.07 -time to compile with static libraries (sparc1 8MB: pollux> time m3 -o DrawRect DrawRect.m3 -lm3ui -lm3X11R4 -lX11 186.8 real 63.8 user 18.4 sys -executable size: 3872 -rwxrwxr-x 1 dagenais 3956736 Oct 8 17:00 DrawRect* -execution time: pollux> time ./DrawRect 9.5 real 0.4 user 0.8 sys -time to compile with dynamic libraries pollux> time m3 -o DrawRect DrawRect.m3 -lm3ui -lm3X11R4 -lX11 113.2 real 44.4 user 8.8 sys -executable size: 80 -rwxrwxr-x 1 dagenais 81920 Oct 8 17:20 DrawRect* -execution time: pollux> time ./DrawRect 56.8 real 20.9 user 2.9 sys Same information but on a Sparc 2 with 32MB froh> time m3 -o DrawRect DrawRect.m3 -lm3ui -lm3X11R4 -lX11 30.75user 9.46system 1:30.90elapsed 44%CPU (0text+4633data 5784max)k 964inputs+516outputs (1363major+4699minor)pagefaults 0swaps froh> ls -als DrawRect 3872 -rwxrwxr-x 1 dagenais analyste 3956736 Oct 15 17:18 DrawRect* froh> time ./DrawRect 0.30user 0.42system 0:02.24elapsed 32%CPU (0text+2623data 2420max)k 0inputs+0outputs (0major+515minor)pagefaults 0swaps froh> time m3 -o DrawRect DrawRect.m3 -lm3ui -lm3X11R4 -lX11 26.9user 8.39system 2:00.06elapsed 28%CPU (0text+5405data 5320max)k 428inputs+79outputs (716major+3095minor)pagefaults 0swaps froh> ls -als DrawRect 80 -rwxrwxr-x 1 dagenais analyste 81920 Oct 15 17:27 DrawRect* froh> time ./DrawRect 12.53user 3.12system 0:38.76elapsed 40%CPU (0text+4268data 4568max)k 54inputs+7outputs (302major+1169minor)pagefaults 0swaps -- --------------------------------------------------------------------- Prof. Michel Dagenais dagenais@vlsi.polymtl.ca Dept of Electrical and Computer Eng. Ecole Polytechnique de Montreal tel: (514) 340-4029 --------------------------------------------------------------------- ======================================================================= 37 === Date: Tue, 20 Oct 1992 16:14:07 PDT From: David Nichols Subject: Tables, tables, tables! If I want a table to map TEXTs to REFANYs, I seem to have at least three choices: STextTable, TextToRefanyTable, and TxtRefTbl. The last two seem to be identical (see attached diff). I see that STextTable uses a 2-3-4 tree and the others use hash tables, but is there any particular advice on which I should use? Will one of the latter two (which are both parts of a series) be decommissioned by the library police? David ================================================================ osprey> diff TxtRefTbl.i3 TextToRefanyTable.i3 7c7 < (* Last modified on Sat Jun 27 15:45:59 PDT 1992 by muller *) --- > (* Last modified on Tue Feb 11 17:08:29 PST 1992 by muller *) 10c10 < INTERFACE TxtRefTbl; --- > INTERFACE TextToRefanyTable; 11a12,16 > (********************************************************************) > (* WARNING: DO NOT EDIT THIS FILE, IT WAS GENERATED MECHANICALLY. *) > (* See the Makefile for more details. *) > (********************************************************************) > 146c151 < END TxtRefTbl. --- > END TextToRefanyTable. osprey> ======================================================================= 38 === Date: Tue, 20 Oct 92 19:41:38 GMT From: mjordan@src.dec.com (Mick Jordan) Subject: Re: Speaking of m3tk (was: Re: Extracting the subtype relation) In article <1992Oct18.203513.11615@alijku05.edvz.uni-linz.ac.at>, ddean@sapphir e.risc.uni-linz.ac.at (Drew Dean) writes: |> Apologies to the bored, but .... |> After 3+ years, I finally got hold of a computer that will run |> Modula-3 (a DECsystem 5000/240). The machine has 2.8 GB of disk, but I |> can't build m3tk because I run out of space in /tmp (on the root |> partition, as per DEC factory installed Ultrix 4.2A). I tried setting |> TMPDIR; I tried making /tmp a symlink to /usr/tmp (/usr has a few hundred |> MB free), but I can't get ar to use any other partition for its temp file. |> Help ! |> Hmm. Both of your solutions should have worked. Here is another, to use the "l" flag of "ar" directly, although it is tricky to do this because of ar's weird argument syntax. First create yourself a shell script as follows: #! /bin/csh shift ar crul $* Put this somewhere on your PATH, in a file caled, say "arl". Then edit the m3makefile for the m3tk library and add the line: M3FLAGS = "-g -make -why -Y3/arl/" This will run "arl" instead of "ar", which will discard the "cru" option and substitute "crul", which should use the current working directory for the temporary file. Mick Jordan ======================================================================= 39 === Date: Tue, 20 Oct 92 16:49:53 -0700 From: Subject: Re: Tables, tables, tables! David, The interface police will be replacing the current galaxy of *Tbl and *Table interfaces with the following family: Table: a generic interface implementing a partial map from Key.T to Value.T, where Key and Value are formal imports SortedTable: a generic interface implementing a subtype of Table for the case that a total ordering on Key.T exists; a sorted table supports iterating over its (key, value) pairs in key order various standard instances of Table and SortedTable, say with Key in {Text, Integer, Atom} and Value = {Text, Integer, Refany}. Our Table.ig is very similar to the one in Greg's book--the main differences are to replace the map method with a "pull" iterator and to add optional per-table hash and equal functions. We also supply a generic Table module that uses chained hashing and a generic SortedTable module that uses randomized heap-ordered binary trees or "treaps" (following Aragon and Seidel, FOCS 1989). So TxtRefTbl/TextToRefanyTable (the only difference was to shorten the name) will be going away. In case you're interested, I've attached the draft sources of Table.ig and Table.mg to this message. I'd be interested in your comments. Paul McJones ------ (* Copyright 1992 Digital Equipment Corporation. *) (* Distributed only by permission. *) (* See the file COPYRIGHT for a full description. *) (* Last modified on Tue Oct 20 16:49:45 PDT 1992 by mcjones *) (* modified on Sun Jan 19 18:07:07 PST 1992 by gnelson *) (* "Table" is a generic interface defining partial maps. *) GENERIC INTERFACE Table(Key, Value); IMPORT Word; (* Where "Key.T" and "Value.T" are types and "Key.Hash(READONLY k: Key.T): Word.T" and "Key.Equal(READONLY k1, k2: Key.T): BOOLEAN" are procedures. *) TYPE T <: Public; Public = OBJECT METHODS init(keyOps: KeyOps := NIL; n: CARDINAL := 0): T; get(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; put(READONLY key: Key.T; READONLY val: Value.T): BOOLEAN; delete(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; size(): CARDINAL; iterate(): Iterator; END; (* A "Table(Key, Value).T", or table, is a partial map from "Key.T"s to "Value.T"s. That is, if "tbl" is a table, then for each "k" in the set "domain(map(tbl))", "k" is a "Key.T" and "map(tbl)(k)" is a "Value.T". The methods have the following specifications: The call "tbl.init(keyOps, n)" initializes "tbl" to an empty table, and returns "tbl". If "keyOps" is not "NIL", then its "hash" and "equal" methods are used for this table. Otherwise, "Key.Hash" and "Key.Equal" are used. The parameter "n" can be used to specify a lower bound on the size of the table (see the discussion of the generic module "Table", below, for more detail). The call "tbl.get(key, val)" sets "val" to "tbl(key)" and returns "TRUE" if "key" is in "domain(tbl)", otherwise it returns "FALSE" without changing "val". The call "tbl.put(key, val)" sets "tbl(key)" to "val". It returns "TRUE" if "key" was already in "domain(tbl)", "FALSE" if it was not. The result of calling "put" concurrently with a call of another method of the same table is undefined. The call "tbl.delete(key, val)" sets "val" to "tbl(key)", removes "(key, val)" from "tbl", and returns "TRUE" if "key" is in "domain(tbl)". Otherwise it returns "FALSE" without changing "val". The result of calling "delete" concurrently with a call of another method of the same table is undefined. The call "tbl.size()" returns the number of key-value pairs in "tbl". The call "tbl.iterate()" returns an iterator, which is an object that can be used to iterate over the key-value pairs in "tbl". (See the definition of the type "Iterator" below.) [Move the discussion of concurrency to one place?] *) TYPE Iterator <: PublicIterator; PublicIterator = OBJECT METHODS next(VAR (*OUT*) key: Key.T; VAR (*OUT*) val: Value.T): BOOLEAN END; (* If "it" is the result of the call "tbl.iterate()", then the call "it.next(key, val)" selects an entry from "tbl" that has not already been returned by "it", sets "key" and "val" to its key and value, and returns "TRUE". If no entries remain, the call returns "FALSE" without setting "key" or "val". It is a checked runtime error to call "next" after it has returned "FALSE". The result of calling a table's "put" or "delete" method while an iteration is in progress is undefined. *) TYPE KeyOps = OBJECT METHODS hash(READONLY k: Key.T): Word.T; equal(READONLY k1, k2: Key.T): BOOLEAN; END; END Table. (* There is a corresponding generic module with parameters "Key" and "Value". This generic module imposes the additional constraint that the "Key" interface must supply procedures for hashing and comparing keys: | GENERIC MODULE Table(Key, Value); | IMPORT Word; | (* where Key.Hash(READONLY k: Key.T): Word.T, | and Key.Equal(READONLY k1, k2: Key.T): BOOLEAN. *) | ... | END Table. We omit the body of the generic module, which is a straightforward table implementation using chained hashing. The implementation normally maintains the density of in-use entries between .2 and .75. If you know a lower bound on the number of entries that will be in a table, you can pass it as the value of the "n" parameter in the call to the "init" method to avoid intermediate reallocations of the table. [Add "TableEq.mg" that uses "=" instead of "Key.Equal"?] *) ------ (* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* Created by Paul McJones on 28 May 92, based on LTbl.mg of 5 May 92 *) (* by Jorge Stolfi, based on Set.mg of 11 Feb 92 by Eric Muller; *) (* This version is very similar to Table.mod of 16 Jan 90 by John Ellis. *) (* modified on Mon May 18 21:01:59 PDT 1992 by stolfi *) (* modified on Tue Feb 11 20:48:05 PST 1992 by muller *) GENERIC MODULE Table(Key, Value); (* where Key.Hash(k: Key.T): Word.T, | and Key.Equal(k1, k2: Key.T): BOOLEAN. *) IMPORT Word; REVEAL T = Public BRANDED OBJECT keyOps : KeyOps; minLogBuckets: CARDINAL; (* minimum value for Log_2(initial size) *) buckets: REF ARRAY OF EntryList; logBuckets: CARDINAL; (* CEILING(Log2(NUMBER(buckets^))) *) numEntries: CARDINAL; (* current num of entries in table *) maxEntries: CARDINAL; (* maximum number of entries *) minEntries: CARDINAL (* minimum number of entries *) OVERRIDES init := Init; get := Get; put := Put; delete := Delete; size := Size; iterate := Iterate END; TYPE EntryList = REF RECORD key: Key.T; value: Value.T; tail: EntryList END; CONST Multiplier = -1640531527; (* good only for 32-bit words *) CONST MaxLogBuckets = BITSIZE(Word.T) - 2; MaxBuckets = Word.Shift(1, MaxLogBuckets); MinLogBuckets = 4; MinBuckets = Word.Shift(1, MinLogBuckets); CONST (* Thresholds for rehashing the table: *) (* to avoid crazy oscillations, we must have MaxDensity > 2*MinDensity; *) (* to avoid excessive probes, we must try to keep MaxDensity low. *) MaxDensity = 0.75; (* max numEntries/NUMBER(buckets) *) MinDensity = 0.20; (* min numEntries/NUMBER(buckets) *) IdealDensity = 0.50; REVEAL Iterator = PublicIterator BRANDED OBJECT tbl: T; this: EntryList; (* next entry to visit if non-NIL *) bucket: CARDINAL; (* next bucket if < NUMBER(tbl.buckets^) *) done: BOOLEAN; (* TRUE if next() has returned FALSE *) OVERRIDES next := Next END; TYPE DefaultKeyOps = KeyOps BRANDED OBJECT OVERRIDES hash := Hash; equal := Equal; END; VAR defaultKeyOps := NEW(DefaultKeyOps); (*************) (* T methods *) (*************) PROCEDURE Init(tbl: T; keyOps: KeyOps := NIL; n: CARDINAL := 0): T = BEGIN <* ASSERT tbl.buckets = NIL *> WITH idealBuckets = CEILING(MIN(FLOAT(n) / IdealDensity, FLOAT(MaxBuckets))), minBuckets = MAX(MinBuckets, idealBuckets) DO tbl.minLogBuckets := Log_2(minBuckets) END; IF keyOps # NIL THEN tbl.keyOps := keyOps ELSE tbl.keyOps := defaultKeyOps END; NewBuckets(tbl, tbl.minLogBuckets); tbl.numEntries := 0; RETURN tbl END Init; PROCEDURE Get(tbl: T; READONLY key: Key.T; VAR val: Value.T): BOOLEAN = VAR this: EntryList; BEGIN this := tbl.buckets[ Word.RightShift(Word.Times(tbl.keyOps.hash(key), Multiplier), Word.Size - tbl.logBuckets)]; WHILE this # NIL AND NOT tbl.keyOps.equal(key, this.key) DO this := this.tail END; IF this # NIL THEN val := this.value; RETURN TRUE ELSE RETURN FALSE END END Get; PROCEDURE Put(tbl: T; READONLY key: Key.T; READONLY val: Value.T): BOOLEAN = VAR this: EntryList; BEGIN WITH first = tbl.buckets[Word.RightShift( Word.Times(tbl.keyOps.hash(key), Multiplier), Word.Size - tbl.logBuckets)] DO this := first; WHILE this # NIL AND NOT tbl.keyOps.equal(key, this.key) DO this := this.tail END; IF this # NIL THEN this.value := val; RETURN TRUE ELSE first := NEW(EntryList, key := key, value := val, tail := first); INC(tbl.numEntries); IF tbl.logBuckets < MaxLogBuckets AND tbl.numEntries > tbl.maxEntries THEN Rehash(tbl, tbl.logBuckets + 1) (* too crowded *) END; RETURN FALSE END END END Put; PROCEDURE Delete(tbl: T; READONLY key: Key.T; VAR val: Value.T): BOOLEAN = VAR this, prev: EntryList; BEGIN WITH first = tbl.buckets[Word.RightShift( Word.Times(tbl.keyOps.hash(key), Multiplier), Word.Size - tbl.logBuckets)] DO this := first; prev := NIL; WHILE this # NIL AND NOT tbl.keyOps.equal(key, this.key) DO prev := this; this := this.tail END; IF this # NIL THEN val := this.value; IF prev = NIL THEN first := this.tail ELSE prev.tail := this.tail END; DEC(tbl.numEntries); IF tbl.logBuckets > tbl.minLogBuckets AND tbl.numEntries < tbl.minEntries THEN Rehash(tbl, tbl.logBuckets - 1) (* too sparse *) END; RETURN TRUE ELSE RETURN FALSE END END END Delete; PROCEDURE Size(tbl: T): CARDINAL = BEGIN RETURN tbl.numEntries END Size; PROCEDURE Iterate(tbl: T): Iterator = BEGIN RETURN NEW(Iterator, tbl := tbl, this := NIL, bucket := 0, done := FALSE) END Iterate; (***********************) (* Internal procedures *) (***********************) PROCEDURE Log_2(x: CARDINAL): CARDINAL = (* Return CEILING(LOG_2(x)) *) VAR log: CARDINAL := 0; n : CARDINAL := 1; BEGIN <* ASSERT x # 0 *> WHILE (log < MaxLogBuckets) AND (x > n) DO INC(log); n := n + n END; RETURN log END Log_2; PROCEDURE NewBuckets(tbl: T; logBuckets: CARDINAL) = (* Allocate "2^logBuckets" buckets. *) BEGIN WITH numBuckets = Word.LeftShift(1, logBuckets) DO tbl.buckets := NEW(REF ARRAY OF EntryList, numBuckets); WITH b = tbl.buckets^ DO FOR i := FIRST(b) TO LAST(b) DO b[i] := NIL END END; tbl.logBuckets := logBuckets; tbl.maxEntries := ROUND(MaxDensity * FLOAT(numBuckets)); tbl.minEntries := ROUND(MinDensity * FLOAT(numBuckets)) END END NewBuckets; PROCEDURE Rehash(tbl: T; logBuckets: CARDINAL) = (* Reallocate "2^logBuckets" buckets, and rehash the entries into the new table. *) BEGIN <* ASSERT logBuckets <= MaxLogBuckets *> <* ASSERT logBuckets >= tbl.minLogBuckets *> WITH ob = tbl.buckets^ DO NewBuckets(tbl, logBuckets); WITH nb = tbl.buckets^ DO FOR i := FIRST(ob) TO LAST(ob) DO WITH obi = ob[i] DO VAR this: EntryList := obi; tail: EntryList; BEGIN obi := NIL; (* ease collector's life *) WHILE this # NIL DO WITH nbh = nb[Word.RightShift( Word.Times( tbl.keyOps.hash(this.key), Multiplier), Word.Size - logBuckets)] DO tail := this.tail; this.tail := nbh; nbh := this; this := tail END END END END END END END END Rehash; (********************) (* Iterator methods *) (********************) PROCEDURE Next(i: Iterator; VAR key: Key.T; VAR val: Value.T): BOOLEAN = BEGIN BEGIN WHILE i.this = NIL AND i.bucket < NUMBER(i.tbl.buckets^) DO i.this := i.tbl.buckets^[i.bucket]; INC(i.bucket) END; IF i.this # NIL THEN key := i.this.key; val := i.this.value; i.this := i.this.tail; RETURN TRUE ELSE <* ASSERT NOT i.done *> i.done := TRUE; RETURN FALSE END END END Next; (*************************) (* DefaultKeyOps methods *) (*************************) PROCEDURE Hash(<*UNUSED*> keyOps: DefaultKeyOps; READONLY k: Key.T): Word.T = BEGIN RETURN Key.Hash(k) END Hash; PROCEDURE Equal(<*UNUSED*> keyOps: DefaultKeyOps; READONLY k1, k2: Key.T): BOOLEAN = BEGIN RETURN Key.Equal(k1, k2) END Equal; BEGIN END Table. ======================================================================= 40 === Date: Tue, 20 Oct 1992 21:56:06 GMT From: cavers@menudo.uh.edu (Chris M. Cavers) Subject: docs Can someone email me the full docs (hopefully a ps file) for m3. I tried to build the docs as described, but was unable to get them to work out. ======================================================================= 41 === Date: 20 Oct 92 20:43:56 GMT From: goldberg@acf5.NYU.EDU (Benjamin Goldberg) Subject: CALL FOR PAPERS: SIGPLAN'93 PLDI ====================================================================== CALL FOR PAPERS ACM SIGPLAN '93 Conference on Programming Language Design and Implementation Albuquerque, New Mexico, USA, June 23-25, 1993 ====================================================================== SIGPLAN '93 continues the series of broad-based language and compiler design conferences. The conference will provide a forum for researchers and developers to learn about current practical and experimental work across the breadth of the field. The conference will emphasize experimental results and experience with the languages and techniques described. The conference seeks original papers relevant to practical issues concerning the design, development, implementation, and use of programming languages (in contrast to the annual SIGACT/SIGPLAN POPL Conference, which is oriented more toward foundations). The conference favors no particular programming paradigm or support architecture. Conference topics include: * compiler construction * translation by program transformation * interpretation * benchmarking and assessment * preprocessing * translator validation * design and use of languages * programming environments * special-purpose languages * internal representations * optimization for scalar and parallel architectures * implementation for non-traditional languages and/or architectures * incremental and interactive methods Authors should submit twelve copies (preferably double-sided) of a technical summary of a prospective paper to the program chair; persons without access to a photocopier may submit a single copy. The first sheet of the summary (not the cover letter) must include the phone number and street and Internet addresses for the corresponding author. Summaries must not exceed 5000 words (approximately 10 pages typeset 10-point on 16-point spacing, or 15 pages if typewritten double-spaced). Excessively long summaries will be rejected immediately by the program chair. Papers awaiting acceptance by any other conference are ineligible for SIGPLAN '93; if a closely related paper has been submitted to a journal, the authors must notify the program chair. The summary must be organized so that it easily understood. Clearly identify what has been accomplished, why it is significant, and how it compares with prior work. Summaries will be judged on clarity, significance, relevance, correctness, and originality. Authors should make their papers understandable to a broad audience. Submissions must be received by **November 11, 1992**. Authors will be notified of acceptance or rejection by **January 20, 1993**. Full versions of the accepted papers must be formatted according to ACM conventions, and camera-ready copy must be received by the program chair by **April 2, 1993**. Authors of accepted papers must sign an ACM copyright release form. Proceedings will be distributed at the conference and as a special issue of SIGPLAN Notices. All papers published in the proceedings are eligible for publication in refereed ACM journals at the discretion of the editor. Program Committee: Timothy A. Budd Oregon State University Robert Cartwright Rice University Jack W. Davidson University of Virginia Susan J. Eggers University of Washington Benjamin Goldberg New York University Ralph E. Griswold The University of Arizona James Larus University of Wisconsin Mark Linton Silicon Graphics Steven S. Muchnick Sun Microsystems Vivek Sarkar IBM Corporation Walter Tichy University of Karlsruhe David W. Wall Digital Western Research Lab Tutorials will precede the conference on June 21-22. The conference advance program will announce the tutorial topics. Conference Chair: Program Chair: Local Arrangements Chair: Robert Cartwright David W. Wall Rebecca Parsons Rice University Digital Equipment Los Alamos National Labs Computer Science Dept. Western Research Lab C-3 MS B265 P. O. Box 1892 250 University Ave. Los Alamos, NM 87545 Houston, TX 77251-1892 Palo Alto, CA 94301 (505) 667-2655 (713) 527-6042 (415) 617-3309 rebecca@lanl.gov cork@cs.rice.edu wall@decwrl.dec.com ======================================================================= 42 === Date: Wed, 21 Oct 1992 08:00:17 PDT From: Mike_Spreitzer.PARC@xerox.com Subject: Re: Tables, tables, tables! There are mappings that vary, and there are mappings that don't. Some procedures want as an argument a mapping that's guaranteed to be constant. Wouldn't it be nice if we could use the static typing of Modula-3 to check at compile time constraints about whether a mapping is allowed to vary? Imagine that there's a base type for mappings with the init, get, size, and iterate methods. Such a mapping may or may not vary (you'd probably want to modify the init method to take some kind of specification of the initial contents, so that mappings could be created "whole"). Imagine further making two subtypes: one adds a guarantee that the mapping does not change (after it's been "init"ted), the other adds the ability to modify the mapping by introducing the put and delete methods. The interface might like this: (* Copyright 1992 Digital Equipment Corporation. *) (* Distributed only by permission. *) (* See the file COPYRIGHT for a full description. *) (* Last modified on Tue Oct 20 16:49:45 PDT 1992 by mcjones *) (* modified on Sun Jan 19 18:07:07 PST 1992 by gnelson *) (* modified on Wed Oct 21 07:57:00 PDT 1992 by Mike Spreitzer *) (* "Table" is a generic interface defining partial maps. *) GENERIC INTERFACE Table(Key, Value); IMPORT Word; (* Where "Key.T" and "Value.T" are types and "Key.Hash(READONLY k: Key.T): Word.T" and "Key.Equal(READONLY k1, k2: Key.T): BOOLEAN" are procedures. *) TYPE T <: Public; Public = OBJECT METHODS init (keyOps : KeyOps := NIL; n : CARDINAL := 0; contents: ContentsSpec := NIL): T; get (READONLY key: Key.T; VAR val: Value.T): BOOLEAN; size (): CARDINAL; iterate (): Iterator; END; ContentsSpec = PROCEDURE (put: PROCEDURE (READONLY key: Key.T; READONLY val: Value.T)); (* A "Table(Key, Value).T", or table, is a partial map from "Key.T"s to "Value.T"s. That is, if "tbl" is a table, then for each "k" in the set "domain(map(tbl))", "k" is a "Key.T" and "map(tbl)(k)" is a "Value.T". The methods have the following specifications: The call "tbl.init(keyOps, n, C)" initializes "tbl" to the mapping specified by "C", and returns "tbl". If "keyOps" is not "NIL", then its "hash" and "equal" methods are used for this table. Otherwise, "Key.Hash" and "Key.Equal" are used. The parameter "n" can be used to specify a lower bound on the size of the table (see the discussion of the generic module "Table", below, for more detail). A mapping is specified by a procedure (a "ContentsSpec") that calls a callback argument ("put") once for every pair in the mapping. The null ContentsSpec specifies the empty mapping. The call "tbl.get(key, val)" sets "val" to "tbl(key)" and returns "TRUE" if "key" is in "domain(tbl)", otherwise it returns "FALSE" without changing "val". The call "tbl.size()" returns the number of key-value pairs in "tbl". The call "tbl.iterate()" returns an iterator, which is an object that can be used to iterate over the key-value pairs in "tbl". (See the definition of the type "Iterator" below.) The contents of a table may or may not change after its "init" method has been called. [Move the discussion of concurrency to one place?] *) TYPE Constant = T BRANDED OBJECT END; (* A "Table(Key, Value).Constant" is a constant partial map; its contents do not change after the "init" method has been called. *) TYPE Variable <: VariablePublic; VariablePublic = T BRANDED OBJECT METHODS put (READONLY key: Key.T; READONLY val: Value.T): BOOLEAN; delete (READONLY key: Key.T; VAR val: Value.T): BOOLEAN; END; (* A "Table(Key, Value).Variable" is a variable partial map; its contents can change through time. Two new methods are introduced, which provide means to change the map. The call "tbl.put(key, val)" sets "tbl(key)" to "val". It returns "TRUE" if "key" was already in "domain(tbl)", "FALSE" if it was not. The result of calling "put" concurrently with a call of another method of the same table is undefined. The call "tbl.delete(key, val)" sets "val" to "tbl(key)", removes "(key, val)" from "tbl", and returns "TRUE" if "key" is in "domain(tbl)". Otherwise it returns "FALSE" without changing "val". The result of calling "delete" concurrently with a call of another method of the same table is undefined. *) TYPE Iterator <: PublicIterator; PublicIterator = OBJECT METHODS next (VAR (*OUT*) key: Key.T; VAR (*OUT*) val: Value.T): BOOLEAN END; (* If "it" is the result of the call "tbl.iterate()", then the call "it.next(key, val)" selects an entry from "tbl" that has not already been returned by "it", sets "key" and "val" to its key and value, and returns "TRUE". If no entries remain, the call returns "FALSE" without setting "key" or "val". It is a checked runtime error to call "next" after it has returned "FALSE". The result of calling a table's "put" or "delete" method while an iteration is in progress is undefined. *) TYPE KeyOps = OBJECT METHODS hash (READONLY k: Key.T): Word.T; equal (READONLY k1, k2: Key.T): BOOLEAN; END; END Table. (* There is a corresponding generic module with parameters "Key" and "Value". This generic module imposes the additional constraint that the "Key" interface must supply procedures for hashing and comparing keys: | GENERIC MODULE Table(Key, Value); | IMPORT Word; | (* where Key.Hash(READONLY k: Key.T): Word.T, | and Key.Equal(READONLY k1, k2: Key.T): BOOLEAN. *) | ... | END Table. We omit the body of the generic module, which is a straightforward table implementation using chained hashing. The implementation normally maintains the density of in-use entries between .2 and .75. If you know a lower bound on the number of entries that will be in a table, you can pass it as the value of the "n" parameter in the call to the "init" method to avoid intermediate reallocations of the table. [Add "TableEq.mg" that uses "=" instead of "Key.Equal"?] *) Unfortunately, if you did this you would have a problem defining orthogonal subtypes, such as one for sorted tables. You'd want sorted subtypes of "Table(Key, Value).T", "Table(Key, Value).Constant", and "Table(Key, Value).Variable". I think this is a good example of why multiple inheritance is needed, and of how it can make sense. Mike ======================================================================= 43 === Date: Wed, 21 Oct 1992 11:17:48 PDT From: David Nichols Subject: Re: Tables, tables, tables! Thanks. I have a couple of comments. 1) As you mentioned, this interface switched from the callback style of interation to an interator object. Will this be the standard for all interfaces that support iteration? I'm not sure which style I prefer, but I'd like to have only one. 2) This is not really about Table.ig, but about callback procedures. The example in Greg's book went like this (I've paraphrased a bit): PROCEDURE Map(cl: Closure) RAISES ANY; TYPE Closure = OBJECT METHODS apply(key: Key.T; value: Value.T): BOOLEAN RAISES ANY; END; Since the closure is guaranteed not to be saved after map returns, why not use a procedure instead: PROCEDURE Map(p: MapProc) RAISES ANY; TYPE MapProc(key: Key.T; value: Value.T): BOOLEAN RAISES ANY; Since local procedures can be used here, any data that the MapProc needs can be in the static environment of the procedure being passed in: PROCEDURE P() = VAR n: INTEGER; PROCEDURE MP(key: Key.T; value: Value.T) = BEGIN ... use n ... END MP; BEGIN ... Map(MP); ... END P; I propose the following rule for passing procedures as parameters: - If the procedure parameter will not be assigned by the callee (i.e. it will only be used during the call to the callee), then only a procedure is passed as an argument. No closures, no REFANY rocks (private data). - If the procedure will be assigned by the callee, then an object is always used. The caller's private data is kept in that object using subtyping in the usual way. David ======================================================================= 44 === Date: Wed, 21 Oct 1992 21:34:51 PDT From: jacobi.PARC@xerox.com Subject: Re: Tables, tables, tables! >> I'm not sure which style I prefer, but I'd like to have only one I have some sympathy, but I can not believe that you can prevail. E.g. I think the style with the iteratior object to be more powerful. It also could lead to designs which have less register window overflows. But it is certainly more work to implement and therefore will sometimes not be used. >> No closures I never liked closures for callbacks. Using a closure saves one narrow operation, at the cost of a memory allocation. It also made the code slightly harder to read, but that may be because I'm not used to it, I'm not sure. >> no REFANY rocks I disagree. Always a REFANY. Using a REFANY leads to more efficiant code: The REFANY lands somewhere in a register window. Using an intermediate level procedure may be ok sometimes, but not always. The intermediate level procedure forces variables to moved from registers into memory on certain architectures. Christian ======================================================================= 45 === Date: 21 Oct 92 09:39:25 CDT From: dafnioti@cae.wisc.edu (Petros Dafniotis) Subject: Modula-3 for VAX/VMS Hello all, as subject says I am looking for a MODULA3 port of the SRC-Modula3 to the VAX/VMS; I have read the FAQ and I saw that there is a port for VAX running ULTRIX but not VMS. I cannot understand how DEC did this to us! Any help is greatly appreciated! Thank you, Petros Dafniotis Chem Engr Dept, UW-Madison e-mail: dafnioti@cae.wisc.edu ======================================================================= 46 === Date: Thu, 22 Oct 1992 09:52:31 PDT From: Mike_Spreitzer.PARC@xerox.com Subject: Re: Tables, tables, tables! 1) Why only one style? Why not have implementors implement both styles? There are trade-offs between use of the two styles. The callback style is more efficient; for basic data structures, this can really be significant. The iterator style lets the consumer use any desired control structure. The only problem with implementing both styles is that both implementations have to be written. For a basic library that will be written once and distributed for wide use, it's worth paying this implementation-writing cost to maximize the use that can be gotten from the library. ======================================================================= 47 === Date: Thu, 22 Oct 1992 10:59:37 PDT From: Mike_Spreitzer.PARC@xerox.com Subject: Re: Tables, tables, tables! 2) Under the conditions that Dave suggests should lead to use of callback procedures, it is not only *always possible* to use callback procedures, but also *sometimes significantly more efficient* (and somewhat more pleasing to the eye) to use callback procedures than to pass consumer objects. For basic data structures, it's worth paying some attention to efficiency. When the consumer needs to access state that is in local (to a procedure) variables, a callback procedure can be a local procedure that just accesses the state directly; if a consumer object is to be passed, a heap object must be allocated and the state must be copied to it (and maybe back again). Even when the state that must be accessed is already entirely distributed among heap-allocated objects, it's rarely already collected together under one object type that is (or can be made) a subtype of the consumer object type. Thus, the callback style often saves the cost of a heap object allocation and some copying. This is a cost of run time and code complexity. [Christian Jacobi favors a callback that takes a REFANY rock, on the grounds that in some architectures it's faster to access a parameter than an up-level variable. I'm not convinced, because using that REFANY rock also often involves the same allocation and copying disparaged above. Also, what will the callback procedure do with that REFANY? Probably NARROW it to some RECORD or OBJECT type (another cost in itself) and then access fields. Those field accesses correspond to the up-level variable accesses he fears, and I wouldn't expect the field accesses to be more efficient. Also, it's tough to write code that does or does not use the REFANY depending on the machine architecture. However, the change from the callback style to the callback-with-rock style does not require any significant change in client code --- only the addition of a NIL actual value in the unlikely case that the rock parameter does not default to NIL. The additional cost to the server code --- passing the rock around with the callback --- is small too. So I don't have any real objection to using the callback-with-rock style.] Part of my efficiency objection to the consumer-object style comes from the assumptions that the consumer object will be heap-allocated and that such allocation is expensive. We had a raging discussion last February (started by a message of Thu, 20 Feb 1992 13:38:41 PST from swart@src.dec.com (Garret Swart) on the subject "Safe cheap objects for Modula 3") on falsifying those assumptions. That discussion faded with a lack of data on the actual costs of things in the current SRC implementation and untested speculations about how things could be done better. Has anybody done anything to get more concrete answers since? Another problem with the callback style is that Modula-3's rules for what you can do with a local procedure value are *VERY* conservative. For example, MODULE Test2 EXPORTS Main ; TYPE R = RECORD p: PROCEDURE() END; PROCEDURE P2() = PROCEDURE P2A() = BEGIN INC(i) END P2A; BEGIN R{P2A}.p(); END P2; VAR i: INTEGER; BEGIN END Test2. augustus % m3 Test2.m3 "Test2.m3", line 8: cannot assign nested procedures (P2A) 1 error encountered augustus % The kinds of proposals floated in the "Safe cheap objects for Modula 3" discussion would also liberalize the rules for local procedure values. Finally, if the callback style is used, it would be nice if the language let me pass a lambda expression as the callback value. A call on an iterator with a lambda expression parameter looks very similar to a loop, which is better than moving the callback body way up earlier to some less relevent context. Mike ======================================================================= 48 === Date: Thu, 22 Oct 92 16:48:21 -0700 From: Subject: Call backs (was Re: Tables, tables, tables!) We are now discussing good style for call backs, not iterators vs. call backs in tables, so I thought I would change the subject title. The rules I follow for call backs are simple: 1. In cases where the semantics dictate that the call back is executed only while the procedure accepting the call back is active, I use simple PROCEDUREs and rely on stack based closures. Note that in this case it is generally okay to use RAISES ANY on the call back procedure signature. 2. In all other cases I use object types with a call back method that are subtyped by the client. This does not normally cause extra allocations because in the case where I am going to hold on to the call back and call it after the procedure accepting it has returned, I usually need to put the call back on a list somewhere. I can then play a trick and give the object type the client subtypes an opaque super type and store the list fields there. Note that in this case it is generally not okay to use RAISES ANY on the call back method signature. The problems I have noticed with these rules are: 1. If one wants to implement a parallel version of a procedure that accepts the call back, the threads it forks cannot get access to the call back. I proposed a solution to this problem some time ago, a "Thread.ParDo" procedure that accepts a, possibly, internal, procedure as an argument, calls it in several threads, and waits for all threads to terminate. Though the interface is safe, nothing came of the proposal, perhaps because, in addition to being a language change, it precludes the use of certain types of concurrent garbage collectors. [The concurrent collector that John DeTreville is working on for Modula 3 assumes that the only way a REF can pass from on thread to another is through a heap assignment. This is violated by Thread.ParDo as any uplevel REF on the stack can be accessed by any of the threads created by Thread.ParDo. The current M3 collector has no problems with Thread.ParDo.] 2. (a) In the case where the closure data needed by the call back consists of a single REF there is additional syntactic overhead for the client over the PROCEDURE + REFANY convention. The advantage to the clients of the object call back technique is that they get static checking of the closure arguments. Note that if the call back needs no closure data then there is no syntactic overhead for using object call backs, as the override of the call back method can be done in the NEW. (b) Our proposed network object implementation doesn't allow one to have fields in the supertypes of object types passed by reference over the network, so a remote interface with a call back object can't take advantage of the trick to put its own data in the client's call back object. But it really doesn't matter as in this case the cost of the local NEW is dwarfed by the cost of creating and passing the remote object in the first place. Garret ======================================================================= 49 === Date: Thu, 22 Oct 1992 12:39:36 PDT From: Mike_Spreitzer.PARC@xerox.com Subject: Re: Tables, tables, tables! I notice a debateable design decision. It is the use of what might be termed an "implementation-centric", rather than an "abstraction-centric", type hierarchy. Consider this alternative ("abstraction-centric") approach: GENERIC INTERFACE Map(Key, Value); (* Where "Key.T" and "Value.T" are types. *) TYPE T = OBJECT METHODS get(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; put(READONLY key: Key.T; READONLY val: Value.T): BOOLEAN; delete(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; size(): CARDINAL; iterate(): Iterator; END; Interator ... END Map. GENERIC INTERFACE HashTable(Key, Value, MapADT); IMPORT Word; (* Where "Key.T" and "Value.T" are types; "Key.Hash(READONLY k: Key.T): Word.T" and "Key.Equal(READONLY k1, k2: Key.T): BOOLEAN" are procedures; and "MapADT = Map(Key, Value)". *) TYPE KeyOps = OBJECT METHODS hash(READONLY k: Key.T): Word.T; equal(READONLY k1, k2: Key.T): BOOLEAN; END; PROCEDURE Create_Chained(keyOps: KeyOps := NIL; n: CARDINAL := 0): MapADT.T; PROCEDURE Create_Non_Chained(keyOps: KeyOps := NIL; n: CARDINAL := 0): MapADT.T; END HashTable. In the abstraction-centric approach, we declare one type for all mappings from Key.T to Value.T. Many different implementations can have that same type. Thus, if I write a large body of code that manipulates mappings from Key.T to Value.T, for some fixed Key and Value, that body of code does not need to be generic, and can be compiled and type-checked once, even when I want to pass it mappings that use different implementations. On the other hand, if I write some generic code that manipulates mappings from Key.T to Value.T for any Key and Value, the abstraction-centric approach requires only one instantiation of that generic code per (Key, Value) pair. In the implementation-centric approach, one could still write such generic code; it would take one of the many implementation-specific Map interfaces, rather than the only abstraction-centric Map interface, as an argument. There would thus be one instantiation per (Key, Value, ImplMap) triple. Mappings are a very fundamental abstraction, and in any large program there will be a great number of uses for mappings, between various types and of various implementations. This makes for more instantiations, and greater code size. I'm not saying these are bad --- just something that ought to be considered. Another difference between these styles is that in the implementation-centric approach it is statically apparent (by the time instantiation and linking is done) which implementation is behind every map-valued variable, whereas in the abstraction-centric approach it is impossible to compute (after instantiation and linking) which implementation is behind every map-valued variable in every legal program. This makes some computations easier to express in the abstraction-centric approach, and some (maybe all) programs easier to optimize in the implementation-centric approach. I'm not sure how to value these two differences. My gut reaction is to favor the implementation-centric approach because of the optimization opportunities. ======================================================================= 50 === Date: 22 Oct 1992 18:17:52 GMT From: chased@rbbb.Eng.Sun.COM (David Chase) Subject: Re: Tables, tables, tables! In article <92Oct21.213527pdt.12930@alpha.xerox.com> jacobi.PARC@xerox.com writ es: >>> No closures >I never liked closures for callbacks. Using a closure saves one narrow >operation, at the cost of a memory allocation. It also made the code slightly >harder to read, but that may be because I'm not used to it, I'm not sure. Memory allocation may be about as cheap as NARROW. Except in cases of gross performance differences, I'd generally advocate choices that are concise and easy to read. David Chase Sun ======================================================================= 51 === Date: Fri, 23 Oct 1992 07:21:48 PDT From: Mike_Spreitzer.PARC@xerox.com Subject: Local procedures in UNSAFE MODULEs Why isn't the prohibition against assigning local procedures lifted in UNSAFE modules? Modula-3's restrictions on local procedures are *so* conservative that there are plenty of things currently forbidden that I would expect to work just fine if only the picky rules were relaxed. For example, UNSAFE MODULE Test2 EXPORTS Main ; TYPE R = RECORD p: PROCEDURE() END; PROCEDURE P2() = PROCEDURE P2A() = BEGIN INC(i) END P2A; BEGIN R{P2A}.p(); END P2; VAR i: INTEGER; BEGIN END Test2. augustus% m3 Test2.m3 "Test2.m3", line 8: cannot assign nested procedures (P2A) 1 error encountered augustus% Why should this *UNSAFE* module be illegal? ======================================================================= 52 === Date: Fri, 23 Oct 1992 11:15:23 PDT From: jacobi.PARC@xerox.com Subject: Re: Tables, tables, tables! >>>>> No closures >>>I never liked closures for callbacks. Using a closure saves one narrow >>>operation, at the cost of a memory allocation. It also made the code slightly >>>harder to read, but that may be because I'm not used to it, I'm not sure. >Memory allocation may be about as cheap as NARROW. Except in cases of >gross performance differences, I'd generally advocate choices that are >concise and easy to read. Baffling... I just said "closures made the code harder to read" and you are arguing you advocate choices that are concise and easy to read. What memory allocator are you proposing?. Narrow is in the order of two memory references. Even if your memory allocator only pumps a pointer it has to take a monitor lock to do so. My memory allocators usually also have a collection phase, whose cost I also have to pay. I can not imagine how you can implement this with less then 4 memory references... Christian ======================================================================= 53 === Date: Fri, 23 Oct 92 11:53:26 PDT From: David.Chase@Eng.Sun.COM (David Chase) Subject: Re: Tables, tables, tables! Well, some people think closures make code easier to read. Even if not, you should keep minor cost considerations off the list, because people might think that was actually a valid justification. As to memory allocator performance, I'm assuming that you do a little bit of per-thread pooling. Last time I checked, the best way to do NARROW requires 4 memory references, as in pre(Type) <= pre(Object) and post(Type) >= Post(Object). (Hmm -- there's that other way to do it that uses more space. That might be cheaper.) The type pre and post order numbers may be constant, but they aren't known until at least link time, if not run-time. I count 4 memory references, and a couple of branches. Allocation of a closure could be as fast as t = load freeptr (remember, you know the size) if not zero (common case) n = load next(freeptr) store n in freeptr That's two loads, one store. Not exactly equivalent, but not enough to justify changing an interface over. Consider also that the costs change if you are generating position indepedent code -- each new symbol referenced (e.g., type constants) corresponds to a load (on a SPARC). David Chase Sun ======================================================================= 54 === Date: 23 Oct 92 20:53:16 GMT From: K1XE@UNB.CA (TOM ZINCK) Subject: Random.Integer in SRC M3 on Sun. Hello, I need some information on how to generate a random integer, say between 1 and 10, in Modula3. I know of the procedure Random.Integer but cannpt seem to get it to work properly. What are the types of the arguements and does anyone have some examples? E-mail or post to net. Will summarize to net. Thanx, Tom -------------------------------------------------------- Thomas R. A. Zinck Faculty of Computer Science "Beer does the body good" University of New Brunswick Fredericton , N.B. , CANADA K1XE@UNB.CA -------------------------------------------------------- ======================================================================= 55 === Date: Fri, 23 Oct 1992 12:48:13 PDT From: jacobi.PARC@xerox.com Subject: Re: Tables, tables, tables! > you should keep minor cost considerations off the list, because people might think that was actually a valid justification. 1) Are you proposing censorship? 2) Since when is a factor of 3 considered minor? 3) I do think this is a valid justification > t = load freeptr (remember, you know the size) > if not zero (common case) > n = load next(freeptr) > store n in freeptr Misses the monitor lock. Misses the collection phase. Christian ======================================================================= 56 === Date: Fri, 23 Oct 92 13:12:04 PDT From: David.Chase@Eng.Sun.COM (David Chase) Subject: Re: Tables, tables, tables! > > you should keep minor cost considerations off the list, because people migh t > > think that was actually a valid justification. > 1) Are you proposing censorship? Of course not (who would do the censoring?). In general, minor cost considerations shouldn't drive interface design. Maybe the costs aren't minor, and it would be good to look at it. > 2) Since when is a factor of 3 considered minor? I didn't see a factor of three. 4 loads, 2 branches, versus 2 loads, 1 store, 1 branch, didn't seem too bad to me. Maybe I wasn't looking closely enough. (PIC would be 6ld/2br vs 3ld/1st/1br). At any rate, be sure that your factor of three is not some weird artifact of a particular implementation. Also be sure that this factor of three is likely to be noticed -- if we turn 1% into 3% (i.e., 100 seconds into 102, overall) this is not worth worrying about. If it is 50 seconds (out of 100) turned into 150, then I'd pay more attention. > > t = load freeptr (remember, you know the size) > > if not zero (common case) > > n = load next(freeptr) > > store n in freeptr > Misses the monitor lock. Cache your free lists, per-thread. Amortize that monitor lock over a larger number of accesses. > Misses the collection phase. True. Depends a lot on the collector. Depends a lot on the optimizer, if only we had one. Depends on the compilation model (PIC/pic/not-pic). Depends upon the particular implementation of SPARC that you are using -- the relative speeds of loads, stores, and branches does vary. David Chase Sun ======================================================================= 57 === Date: Fri, 23 Oct 92 17:47:41 -0700 From: Subject: Call backs (was Re: Tables, tables, tables!) Someone asked me privately: "There are plenty of cases where I have a procedure that accepts a call back that is called much later, but the call back is not a part of a list or any other structure that can use the supertype." I respond: Yes, but in that case the call back might as well be a method of the object it is stored in. If the object is a type that the client is expected to NEW, just have the client override the method their rather than hand in a separate object. E.g. in Table.ig as sent out by Paul McJones can be modified as follows: TYPE T <: Public; Public = OBJECT METHODS init(n: CARDINAL := 0): T; get(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; put(READONLY key: Key.T; READONLY val: Value.T): BOOLEAN; delete(READONLY key: Key.T; VAR val: Value.T): BOOLEAN; size(): CARDINAL; iterate(): Iterator; (* May be overriden by the client. If not overriden Key.Hash and Key.Equal are used. *) hash(READONLY k: Key.T): Word.T := NIL; equal(READONLY k1, k2: Key.T): BOOLEAN := NIL; END; If you'd rather hide away the hash and equal methods, you can always put them in a more obscure supertype of Table.T and hide it away, either in the same interface or in a different interface. Garret ======================================================================= 58 === Date: Mon, 26 Oct 1992 15:51:09 GMT From: moss@cs.umass.edu (Eliot Moss) Subject: Allocation and locks (was Re: Tables, tables, tables!) >>>>> On 23 Oct 92 18:15:23 GMT, jacobi.PARC@xerox.com said: >Memory allocation may be about as cheap as NARROW. Except in cases of >gross performance differences, I'd generally advocate choices that are >concise and easy to read. Jacobi> What memory allocator are you proposing?. Narrow is in the order of Jacobi> two memory references. Even if your memory allocator only pumps a Jacobi> pointer it has to take a monitor lock to do so. My memory allocators Jacobi> usually also have a collection phase, whose cost I also have to pay. Jacobi> I can not imagine how you can implement this with less then 4 memory Jacobi> references... First, it is not at all clear that allocation needs to acquire and release a lock. There are lots of other ways to do it, cheaper in the normal case. Second, if the stuff is garbage, a copying collector won't touch it, so there are less than 4 memory references to reclaim the item. (Granted, this works best when most things are garbage.) I think you were assuming particular strategies, which need not be used. -- J. Eliot B. Moss, Associate Professor Visiting Associate Professor Department of Computer Science School of Computer Science Lederle Graduate Research Center Carnegie Mellon University University of Massachusetts 5000 Forbes Avenue Amherst, MA 01003 Pittsburgh, PA 15213-3891 (413) 545-4206, 545-1249 (fax) (412) 268-6767, 681-5739 (fax) Moss@cs.umass.edu Moss@cs.cmu.edu ======================================================================= 59 === Date: 26 Oct 92 16:46:21 GMT From: psu@cs.duke.edu (Peter Su) Subject: M3 Threads under Multithreaded OS's? So, I've been poking around with m3, after having built it on my Sparc 2. I was trying to dig into the low levels of the threads implementation, but the discussion of this in the docs on internals seems to be out of data. ./libm3/threads/src has no machine dependent files, and no file called 'WildJmp.i3' as mentioned in the notes on internals. No amount of blind digging around on my part turned up anything that looked like what I wanted. So, my question is: (1) where does the threads impl. live? (2) How hard would it be to port it in such a way that it used native OS-level threads? My specific interest is in using the threads library that comes with the KSR-1 computer...though Mach threads on a Multimax, or something similar would make me happy too. Thanks, Pete -- Department of Computer Science, Duke University, Durham, NC 27706 Internet: psu@cs.duke.edu UUCP: mcnc!duke!psu ======================================================================= 60 === Date: 26 Oct 92 19:29:43 GMT From: obry@flash.bellcore.com (Pascal Obry) Subject: M3 docs Hi there, I would like to know where can I find a description of the modula-3 language ? A kind of LRM, in ASCII or better in PS format will be good. Thanks, Pascal. -- ------------------------------------------------------------------------------- -- Pascal OBRY -- -- Room 2D-337 e_mail : obry@bellcore.com -- -- Bellcore -- -- 445 South Street voice : 1 - 201 829 4039 -- -- Post Office Box 1910 -- -- Morristown, New Jersey 07962-1910 -- ------------------------------------------------------------------------------- `` inheritance is surely a good answer, but who knows the question ? '' ======================================================================= 61 === Date: 27 Oct 92 00:40:46 GMT From: moss@cs.umass.edu (Eliot Moss) Subject: M3 language definition Is there any good reason why the language definition part(s) of the Nelson book have not been made available online? It's great to have people buy the book and have all the neat extra material, but for immediate popularization, as well as for personal handiness (though I have bought more than one copy of the book), having the definition online would be nice (of course with instruction on how to get the book and what neat stuff is in it). -- J. Eliot B. Moss, Associate Professor Visiting Associate Professor Department of Computer Science School of Computer Science Lederle Graduate Research Center Carnegie Mellon University University of Massachusetts 5000 Forbes Avenue Amherst, MA 01003 Pittsburgh, PA 15213-3891 (413) 545-4206, 545-1249 (fax) (412) 268-6767, 681-5739 (fax) Moss@cs.umass.edu Moss@cs.cmu.edu ======================================================================= 62 === Date: 27 Oct 92 11:53:59 GMT From: mlo@dcs.qmw.ac.uk (Mike Osborne) Subject: M3 Threads - another question I would like to know how the size of the jmp_buf is arrived at in Csetjmp.i3 as it appears (on Sun3 and Sparc at least) not to match the size of the jmp_buf in setjmp.h. The documentation says "Be careful to get the size of the jmp_buf right" but does not say how. I have got a flaky port running (AUX3.0 gcc2.2) but the exception handling and threads don't work which at the moment I am assuming is related to the jmp_buf size. Any additional info would be appreciated. Mike -- Michael Osborne Internet: mlo@dcs.qmw.ac.uk Computer Science Department JANET: mlo@uk.ac.qmw.dcs Queen Mary & Westfield College Mile End Road Telephone: +44 71-975 5244/5/9 LONDON, E1 4NS, UK Fax: +44 81-980 6533 ======================================================================= 63 === Date: Tue, 27 Oct 92 16:30:44 GMT From: kalsow@src.dec.com (Bill Kalsow) Subject: Re: M3 Threads - another question We get the size of jmp_buf (and all other machine dependent values!) from the people doing ports. The size of Csetjmp.jmp_buf should be at least as big as what's in setjmp.h. What does the following program produce on your system? #include #include main () { printf ("sizeof (jmp_buf) = %d\n", sizeof (jmp_buf)); } If you find a bug, please send a message to m3-request@src.dec.com describing what you found. We'll try to fix it for the next release. > I have got a flaky port running (AUX3.0 gcc2.2) but the exception handling > and threads don't work which at the moment I am assuming is related to the > jmp_buf size. That sounds very likely. - Bill Kalsow ======================================================================= 64 === Date: Tue, 27 Oct 92 16:40:30 GMT From: kalsow@src.dec.com (Bill Kalsow) Subject: Re: Modula-3 for VAX/VMS In article <1992Oct21.093925.18668@doug.cae.wisc.edu>, dafnioti@cae.wisc.edu (P etros Dafniotis) writes: > as subject says I am looking for a MODULA3 port of the SRC-Modula3 > to the VAX/VMS; I have read the FAQ and I saw that there is a port for > VAX running ULTRIX but not VMS. I cannot understand how DEC did this > to us! I wouldn't say that "DEC did this to us". There's a very small group of us here at SRC who are working on the compiler and runtime system. VMS has been on my to-do list for a long time, but I haven't gotten there yet. The only ports done at SRC were VAX and DECstation Ultrix. Every other version of the system was provided by outside friends. If you port the system to VMS, let us know. We'd be happy to have it. - Bill Kalsow ======================================================================= 65 === Date: 27 Oct 1992 13:23:22 GMT From: mead@bucknell.edu (Jerry Mead) Subject: Modula3 examples? Is there an FTP site with modula3 example programs or interfaces. I am trying to convert a modula2 program to modula3. The non-IO code is easy to deal with, its the conversion of InOut procedures which is a problem. Any help? Thanks - jerry --------------------- Jerry Mead Dept of Computer Science Bucknell University Lewisburg, PA 17837 mead@bucknell.edu ======================================================================= 66 === Date: Tue, 27 Oct 1992 13:58:29 GMT From: emery@Dr_No.mitre.org (David Emery) Subject: Re: M3 language definition Eliot makes a good point. The Ada community has gotten a lot of mileage from having the ASCII source text for the Ada RM publically available. dave ======================================================================= 67 === Date: Tue, 27 Oct 92 16:20:51 GMT From: kalsow@src.dec.com (Bill Kalsow) Subject: Re: M3 Threads under Multithreaded OS's? The thread implementation is hiding in the following places: ./libm3/thread/src/Thread - machine independent code ./libm3/runtime/src//RTStack - stack allocator/deallocator ./libm3/runtime/src//RTThread - low-level muck You'll find what used to be in "WildJmp" in "RTThread". Porting the system to OS-level threads shouldn't be too bad. The key step will be to replace "RT0u.inCritical" and its uses (Thread & RTHeap) with an OS-level lock. As always, the pain will be in the details. - Bill Kalsow ======================================================================= 68 === Date: Tue, 27 Oct 92 21:18:58 GMT From: Eric Muller Subject: Re: Modula3 examples? |> Is there an FTP site with modula3 example programs or interfaces. gatekeeper.dec.com:pub/DEC/Modula-3 -- Eric. ======================================================================= 69 === Date: Tue, 27 Oct 92 21:17:40 GMT From: Eric Muller Subject: Re: Random.Integer in SRC M3 on Sun. |> I know of the procedure Random.Integer but |> cannpt seem to get it to work properly. Can we have some evidence ? |> and does anyone have some examples? > cat Main.m3 MODULE Main; IMPORT Stdio, Wr, Fmt, Random; BEGIN FOR i := 1 TO 10 DO Wr.PutText (Stdio.stdout, Fmt.Int (Random.Subrange (Random.Default, 1, 10)) & " "); END; Wr.PutText (Stdio.stdout, "\n"); END Main. > m3 -o main Main.m3 > ./main 7 3 8 2 5 2 10 3 4 5 -- Eric. ======================================================================= 70 === Date: Tue, 27 Oct 92 20:55:51 GMT From: Eric Muller Subject: Re: Where O' where could my pswrap be? |> What is a pswrap, and why can't I find it? dps stands for Display PostScript. pswrap is a program that takes a pseudo-PostScript input and generates C code to download this PostScript in a server, together with functions to call this PostScript code from a (C) client. -- Eric. ======================================================================= 71 === Date: Wed, 28 Oct 92 13:47:03 GMT From: pk@rwthi3.informatik.rwth-aachen.de (Peter Klein) Subject: Re: Modula3 examples? In article 1cjfsaINNs04@coral.bucknell.edu, mead@bucknell.edu (Jerry Mead) writ es: >Is there an FTP site with modula3 example programs or interfaces. >I am trying to convert a modula2 program to modula3. The non-IO >code is easy to deal with, its the conversion of InOut procedures >which is a problem. Any help? > I converted a rather large subsystem (~ 50000 LOC) from Modula-2 to -3. For this reason, I wrote a little program (in Sun Modula-2) which performs the most conversions automatically (except WITH, variant RECORDS and enumertion type constants - it's actually based on a Modula-2 pretty printer). Also, I wrote a Modula-3 module which emulates the Sun Modula-2 DEFINITION MODULE InOut (and so me others, like File, Dirs etc.) If there's any interest, contact me by e-mail. Peter --- Peter Klein E-Mail: pk@rwthi3.informatik.rwth-aachen.de Lehrstuhl fuer Informatik III Tel.: +49/241/80-21320 Ahornstrasse 55 Fax.: +49/241/80-21329 RWTH Aachen D-5100 Aachen Germany ======================================================================= 72 === Date: Wed, 28 Oct 92 21:23:05 GMT From: mjordan@src.dec.com (Mick Jordan) Subject: Re: Cyclic Inheritance A plug for m3check and the M3 AST toolkit (m3tk) One advantage of compiling several modules in a single session is that some "link-time" problems can be detected, vis. gentilly 11> m3check -ic s -pu m3check> s m3cfe: compiling interface 'Another' from Another.i3 m3cfe: compiling module 'Main' from Main.m3 m3cfe: compiling interface 'Main' from /proj/m3/pub.mips/Main.i3 m3cfe: compiling module 'Another' from Another.m3 "Another.m3", line 3,21: illegal recursive revelation m3check> Mick Jordan ======================================================================= 73 === Date: 28 Oct 92 19:31:31 GMT From: adiwan@quick.fox.cs.cmu.edu (Amer Diwan) Subject: Cyclic Inheritance This is to report a problem in the SRC compiler and point out a possible grey area in the Modula-3 report. The problem happens when an object type A inherits from B and B inherits from A. The compiler gives a reasonable error message in the simple cases when both A and B are in the same module. For example: TYPE A = A OBJECT i: INTEGER END; If however they are in different modules, the linker goes into an infinite loop (well, I killed it when it did not terminate after 30 minutes). For example: File Main.m3 ------------ MODULE Main; FROM Another IMPORT T, U; REVEAL T = U BRANDED OBJECT i: INTEGER; END; BEGIN END Main. File Another.m3 --------------- MODULE Another; REVEAL U = T BRANDED OBJECT j: INTEGER; END; BEGIN END Another. File Another.i3 --------------- INTERFACE Another; TYPE U <: ROOT; TYPE T <: ROOT; END Another. I compiled the three files separately using m3 -c and then linked them together. I am using version 2.06 of the Modula-3 compiler on a DS3100. I cannot find anything in the Modula-3 report that addresses circular inheritance. It seems that in the general case, the work of detecting circularity will have to be deferred to link time. Amer -- --------------------------------------------------------------------------- Amer Diwan School of Computer Science Fox Project Carnegie Mellon University adiwan@cs.cmu.edu Pittsburgh, PA 15213 (412) 268-3066 ======================================================================= 74 === Date: 28 Oct 92 08:56:25 GMT From: C.R.Snow@newcastle.ac.uk Subject: Detached threads I would be interested to know why the Modula-3 Threads interface does not allow for a thread to be detached, either at the time of creation, or subsequently. I observe that Encore Parallel Threads (based on the Brown University Threads package created by Thomas W. Doeppner Jr.) allows a thread to be created either ATTACHED or DETACHED, and both the C threads package (Cooper and Draves, Carnegie Mellon University), and the Mesa Process interface allowed threads to be detached after creation. The SunOS4.0 lightweight process package also has a similar facility, although using a slightly different approach, but Modula-3 has no such operation, and hence a thread must continue to exist, even though terminated, until either its parent joins with it, or else the parent also terminates. A fairly standard way of writing server programs is for the server to create a new thread to deal with a specific request when it arrives, leaving the main server program to listen out for further requests. This would seem to me to be an ideal application for detached threads, and I am surprised to find this facility missing from the Modula-3 interface. ... Dick Snow. -------------------------------------- Department of Computing Science University of Newcastle upon Tyne, UK. Tel: +44 91 222 8064 Fax: +44 91 222 8232 E-mail: C.R.Snow@newcastle.ac.uk ======================================================================= 75 === Date: Thu, 29 Oct 92 15:55:38 GMT From: kalsow@src.dec.com (Bill Kalsow) Subject: Re: Detached threads Unlike C or Mesa (or I suspect whatever Encore Parallel Threads is written in), Modula-3 has garbage collection. If you want a "detached" thread, fork it and drop the returned handle. When the thread finishes the collector will reclaim its storage. If you want an "attached" thread, fork it and call Thread.Join with the returned handle. - Bill Kalsow ======================================================================= 76 === Date: Fri, 30 Oct 1992 10:27:09 GMT From: gram@aim1.aztec.co.za (Graham Wheeler) Subject: m3 for DOS/Windows? Hi all Does anyone know of any company/group/individual developing an m3 compiler for DOS, Windows 3.1 or Windows NT? If so, when will it be released? Regards Graham -- Graham Wheeler | "That which is weak conquers the strong, Network Systems Programmer | that which is soft conquers the hard." Aztec Information Management | Lao Tzu - Tao Te Ching Ch. 78 gram@aim1.aztec.co.za | There's no justice, there's just us ======================================================================= 77 === Date: 27 Oct 92 09:26:30 GMT From: C.R.Snow@newcastle.ac.uk (unregistered@newcastle.ac.uk Snow) Subject: Detached threads I would be interested to know why the Modula-3 Threads interface does not allow for a thread to be detached, either at the time of creation, or subsequently. I observe that Encore Parallel Threads (based on the Brown University Threads package created by Thomas W. Doeppner Jr.) allows a thread to be created either ATTACHED or DETACHED, and both the C threads package (Cooper and Draves, Carnegie Mellon University), and the Mesa Process interface allowed threads to be detached after creation. The SunOS4.0 lightweight process package also has a similar facility, although using a slightly different approach, but Modula-3 has no such operation, and hence a thread must continue to exist, even though terminated, until either its parent joins with it, or else the parent also terminates. A fairly standard way of writing server programs is for the server to create a new thread to deal with a specific request when it arrives, leaving the main server program to listen out for further requests. This would seem to me to be an ideal application for detached threads, and I am surprised to find this facility missing from the Modula-3 interface. ... Dick Snow. -------------------------------------- Department of Computing Science University of Newcastle upon Tyne, UK. Tel: +44 91 222 8064 Fax: +44 91 222 8232 E-mail: C.R.Snow@newcastle.ac.uk ======================================================================= 78 === Date: 28 Oct 92 08:59:34 GMT From: C.R.Snow@newcastle.ac.uk Subject: Re: M3 Threads under Multithreaded OS's? In article psu@cs.duke.edu (Peter Su) writes: .... > >So, my question is: (1) where does the threads impl. live? (2) How >hard would it be to port it in such a way that it used native OS-level >threads? My specific interest is in using the threads library that >comes with the KSR-1 computer...though Mach threads on a Multimax, or >something similar would make me happy too. > >Thanks, >Pete > > > >-- >Department of Computer Science, Duke University, Durham, NC 27706 >Internet: psu@cs.duke.edu >UUCP: mcnc!duke!psu > I cannot answer question (1), but I have been playing around with a threads implementation which sits on top of Encore Parallel Threads (EPT) on the Multimax. Unfortunately, Modula-3 threads cohabit rather uneasily with EPT, due to slight, but significant differences for example in the semantics of Join and Wait/Signal/Broadcast. With regard to the use of native OS-level threads in general, I suspect that Modula-3 threads would fit better with Mach's C-threads or with SunOS's Lightweight Processes than with EPT, but I am not in a position to try these out. Regards, ... Dick Snow. -------------------------------------- Department of Computing Science, University of Newcastle upon Tyne, UK. Tel: +44 91 222 8064 Fax: +44 91 222 8232 E-mail: C.R.Snow@newcastle.ac.uk