Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /archive/0.93/doc/bugs/masterbugs
ViewVC logotype

View of /archive/0.93/doc/bugs/masterbugs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4958 - (download) (annotate)
Wed Apr 10 01:33:29 2019 UTC (3 months, 1 week ago) by dbm
File size: 1065565 byte(s)
adding 0.93 src and doc to archive
Master Bug List, Standard ML of New Jersey as of June 26, 1991.
Most of these bugs have been fixed; these are all bugs ever reported.

-------------------------------------------------------------------------------
1. Identifier as functor body (dbm)
Problem: 
  Using a parameter structure variable as the body of a functor yields an
  error message.
Code:
   functor F(structure A: sig end) = A
Messages:
   Error: unbound structure id: A
Comment:
Status: fixed in 0.20, along with some related bugs involving lack of
  visibility of parameters on the rhs of functor declarations.
-------------------------------------------------------------------------------
2. Mispelled nonnullary constructors in patterns
Problem: 
  Mispelling a constructor with arguments in a pattern leads to misleading
  error messages.
Version: 0.18
Code:  (in typing/typecheck.sml)
      ...
	       app genType rvbs
	   end
       | EXCEPTIONdec(ebs) =>
	   let fun checkWeak(VARty(ref(UNBOUND id))) = 
		     if tyvarWeakness id > abs
		     then condemn "type variable in exception type too strong"
      ...
Status: Fixed in 0.50
-------------------------------------------------------------------------------
3. Redefining an open structure at top level
Problem:
  It appears that redeclaration of an opened structure S releases the
  runtime binding of S, even though we can still refer to its component
  x.  We get the effect of a kind of dangling reference.  Need to avoid
  reclaiming S if S is open at the point where it is redeclared.
Version: 0.18
Code:
    - structure S = struct datatype t = A val x = A end;
    structure S : <sig>
    - S.x;
    val it = A : S.t
    - open S;
    open S
    - x;
    val it = A : t
    - type t = bool;
    type t = bool
    - x;
    val it = A : S.t
    - structure S = struct end;
    structure S : <sig>
    - x;
    uncaught exception Intmap
    - 
Comment:
  Need to detect the fact that a structure has been opened at the top level
  and if so it's lvar binding should not be deleted from the top-level environment.
Status: fixed in 0.20.  top level opens copy bindings into top level environment.
--------------------------------------------------------------------------------
4. duplicate specifications not checked
Problem:
  No checking for duplicated specifications in signatures.
Version: 0.18
Comment:
  This should be done when building the signature symbol table.
  See bug 81.  (elg)
Status: fixed in 0.73
--------------------------------------------------------------------------------
5. exportML environment
Problem:
  Subtle bug in exportML: it exports the environment of the person who
  originally booted the system, and this environment is restored when
  the image is started up.  This effects system, execute, and
  subsequent exportML's.  On startup, exportFN destroys the environment
  and command-line args, and this too could have adverse effects on
  those functions.
Version: 0.18
Status: fixed in version 0.31
--------------------------------------------------------------------------------
6. open file descriptors
Problem:
  File descriptors open in the ML system remain open on a call of system.
Version: 0.18
Comment:
  I haven't decided what I want to do about this yet.  We
  might like only stdin, stdout, and stderr to remain open.
  Note that if the parent closes one of them, it will be closed in the
  child as well (it inherits them rather than getting new ones).
  Note that
	  ioctl(fd,FIOCLEX,(void *)0)
  will cause a file descriptor to be closed on an exec.  This could be
  called after each open (but shouldn't be called on pipes).
  Another possibility is just to leave them all open.
Status: not a bug, reflects Unix semantics
--------------------------------------------------------------------------------
7. constructor representation
Problem:
  There is a bug involving constructor representation.  The compiler
  examines the structure of a datatype and tries to determine an efficient
  runtime representation for it.  For example, for the list datatype, nil
  can be represented as an integer, and :: can just be a pointer to its
  tuple argument (integers and tuples are distinct).  This fails in our system
  at the structure level.  For example:
Version: 0.18
Code:
    signature S = sig
	type 'a t
	datatype 'a list = nil | :: of 'a t
    end
    structure A : S = struct
	datatype 'a list = nil | :: of 'a * 'a list
	withtype 'a t = 'a * 'a list
    end
Comment:
  Here the compiler can deduce the efficient representation for the
  (local) list datatype in structure A; but this cannot be deduced in
  the signature S (an object of type 'a t might not be a pointer).
Status: An error message is now generated (0.54) when this occurs.
--------------------------------------------------------------------------------
8. interactive error recovery
Problem:
  In the interactive mode, parser error recovery should be suppressed
  (but isn't); the parser may continue to look for input after an error,
  when the user would expect to be back at top level.
Version: 0.18
Status: Fixed in 0.52
--------------------------------------------------------------------------------
9. behavior at limits (e.g. stack overflow)
Problem:
  The behavior of the system when it reaches limits is sometimes bizarre.
  For instance, on a Sun, if the system runs out of stack space it
  will die with "Illegal instruction".  This is because the signal can't
  be handled since the stack is full.  A possible fix would be to use a
  separate stack to handle signals, but the handler would have to be
  smart, since SIGSEGV would be raised.  Note that the stack limit can
  be changed with the limit command; and hopefully this particular bug will
  disappear with the next version of the code generator.
Version: 0.18
Status: fixed in version 0.31
--------------------------------------------------------------------------------
10. exhaustiveness messages at top-level
Problem: Top level bindings should not report on exhaustiveness, but they do.
Version: 0.18
Status: Not important.
--------------------------------------------------------------------------------
11. poor error messages [parser]
Problem: Poor error message (parens are needed around the hd::tl pattern):
Version: 0.18
Code:
   -  fun f hd::tl = 4;
Messages:
    Error: expected EQUAL, found ID (::)
    Error: expected nonfix-identifier, found ID ::
    Error: unbound variable bogus
    Error: type error: operator and operand don't agree
    operator : ((wrong*wrong list) -> wrong list)
    operand : (wrong*('aA list -> 'aA list))
    expression:
      bogus :: tl
    - 
Comment:
  The "unbound variable bogus" in particular is confusing.
Status: Fixed in 0.52.
-----------------------------------------------------------------------------
12. loss of information in value printing
Problem:
  When printing values formed using constructors created by functor application,
  the argument type of the constructor can sometimes be lost, resulting in
  inability to print the value accurately.
Version: 0.18
Code:
	- functor F(type t) =
	= struct
	=   datatype r = C of t
	= end;

	- structure S = F(type t = int);

	- S.C 3;
  [1]   val it = C - : S.r

  But
  	- signature SS = sig type t datatype r = C of t end;

        - structure S = struct type t = int  datatype r = C of t end;

	- S.C;
	val it = fn : ?.t -> S.r

	- S.C 3;
	val it = C 3 : S.r

  and
	- structure S': SS = struct type t = int  datatype r = C of t end;
	- S'.C;
	val it = fn : ?.t -> S'.r
	- S'.C 3;
	val it = C 3 : S'.r

Comments:
  Printing the argument type of C at [1] yields "IND/1/", indicating that
  the type of C contains an indirection that is not interpreted in context.
  It does not seem possible to recover the context from the structure S, because
  there is no simple way to get back from the type S.r or the DATACON C to the 
  structure environment.  This may be a reason for having type constructors
  contain a pointer to their home structure rather than just the symbolic
  path.  Another alternative would be to follow the path in S.r to find the
  structure S so that we can use it as context for the type of C.
Status: fixed in 0.58
-----------------------------------------------------------------------------
13. printing of types from abstraction structure
Problem:
  Printing of types from an abstraction is not quite right.
Code: (test/sigs/test7)
    signature FOO = 
    sig
       type T1 and T2
       val x1: T1 and x2: T2
       sharing type T1 = T2
    end

    abstraction Foo: FOO =
    struct
       datatype T1 = CON
       type T2 = T1
       val x1 = CON and x2 = CON
    end

    [Foo.x1,Foo.x2];
Messages:
    [-,-] : ?.T1   (* should be Foo.T1 *)
Status: Fixed in 0.56
--------------------------------------------------------------------------------
14. Bad printing of list values
Problem: list values printed with :: instead of [...]
Version:
Code:
    datatype Foo = FOO of int list
    val it = FOO [1, 2, 3]
Messages:
    FOO (1 :: 2 :: 3 :: nil): Foo
Comments:
Status: Fixed in version 0.25.
--------------------------------------------------------------------------------
15. Error message
Problem: Unfortunate error message (I left out `type'):
Version: ?
Code: 
	- signature STWO = sig structure X:SIG and Y:SIG sharing X.t=Y.t end;
Messages:
	Error: bad path is sharing specification
Comments:
   (It's also misspelled.)
Status: fixed in 0.56
--------------------------------------------------------------------------------
16. "use" errors
Problem:
  Untidy interface to "use". "use" on a nonexistent file still prints the
  "[opening ...]" message and then raises Io_failure - shouldn't it just
  say "[cannot open ...]" or something?
Status: fixed
--------------------------------------------------------------------------------
17. Inaccurate line numbers
Problem:
	Misleading line numbers for some things (eg. type errors in multi-line
	datatype declarations). Could the system print something like
	"Line 33ff", or a line range a la LaTeX, for these?
Status: fixed in 0.53
--------------------------------------------------------------------------------
18. Bad error messages for illegal record expression
Version: [< 0.16]
Problem:
	interesting diagnostic in the (meaningless) expression
Code:
	- {3};
Messages:
	Error: expected RBRACE, found INT
	Error: type error: operator and operand don't agree
	operator : unit
	operand : int
	expression:
	  () 3

	Error: declaration or expression expected, found RBRACE
Comment:
	What's the "() 3"?
Status: fixed in 0.53
--------------------------------------------------------------------------------
19. Exception declaration with ":"
Problem: This gives a type error rather than a syntax error: odd:
Version: ?
Code:
		- signature FOO = sig exception Foo of string end;

		- structure Foo: FOO = struct exception Foo: string end;
		                                       =-> ^ <-=
Messages:
		Error: Type in structure doesn't match signature
		name = Foo
		spec = (string -> exn)
		actual = exn
Comments:
  Without signature constraint ":FOO" in declaration of Foo you get a syntax
  error: "expected END, found COLON".  With the signature, you get the above
  type error but no complaint about the ":".
Status: fixed in 0.53
--------------------------------------------------------------------------------
20. "print" seems overloaded rather than polymorphic:
Problem: print is overloaded rather than being polymorphic
Version: -
Code:
	- datatype Foo = FOO1 | FOO2;
	- print FOO1;
Messages:
	Error: type error: no match for overloaded variable:
	print
Comments:
	according to the original SML report, both "print" and "makestring"
	should be polymorphic identity functions. In our compiler, "print"
	is correctly polymorphic. "makestring" is (incorrectly) overloaded,
	disallowing "makestring FOO1". Needless to say, I want to be able
	to do "makestring" on datatypes.
Status: not a bug
--------------------------------------------------------------------------------
21. Bad error recovery in the typechecker:
Problem:
Version: 0.15a
Code:
	- signature SIG = sig
	     exception Foo of int
	     val A: int
	     val B: int
	     val C: int
	  end;

	- structure S: SIG =
	     struct
		exception Foo: int
			     ^
		val A = 1
		val B = 2
		val C = 3
	     end
Messages:
	Error: Type in structure doesn't match signature
	name = Foo
	spec = (int -> exn)
	actual = exn
	Error: unmatched val spec: A
	Error: unmatched val spec: B
	Error: unmatched val spec: C
	^ there can be a lot of these!
Comments:
	Sometimes the exception error doesn't appear, just giving the unmatched
	spec errors, rather misleadingly.
Status: fixed in 0.53
--------------------------------------------------------------------------------
22. inherited environment of subprocesses
Problem:
  (one you know about) - subprocesses created via "execute" inherit
  the environment present when the ML system was built! Also: broken
  pipe errors should be caught and raise Io_failure?
Status: fixed in 0.31
--------------------------------------------------------------------------------
23. circularity in substructure relationship
Problem:
  No checking for circular sharing constraints.  Circular constraints cause
  unhandled Notfound_Table exception.
Code:
	- signature Sig =
	    sig
		structure D: sig
				structure E: sig end
			     end

		sharing D = D.E
	     end;
Messages:
	uncaught exception Notfound_Table
Comments:
  By the way - why is "sharing structure D = D.E" illegal above? (it
  dislikes the word "structure".)
  See bug 33. (elg)
Status:
  Not considered a bug (signature can't be matched, -- this property could
  be statically detected in the compiler, but isn't).
--------------------------------------------------------------------------------
24. incomplete write
Submitter: Nick
Comments:
	I'm trying to put in some bullet-proof error recovery into my
	subprocess software, so that "^C" at ML top-level doesn't
	confuse the daemon. What happens if an "output" operation is
	active when ^C is hit - does it do a partial write? I seem to be
	getting some buffer corruption somewhere, as a partial write is
	immediately followed by another complete write. It might make
	my life easier if "output" could be guaranteed atomic under "^C"
	(i.e. any single output operation will complete before Interrupt
	gets raised).
	   Just a thought. I'll perhaps put timers into the daemon and ML code
	so that they flush and restart properly - this may solve the problem.
Status: New signal-handling stuff in 0.56 makes this less important.
--------------------------------------------------------------------------------
25. parser vs grammar (?)
Problem: Parser doesn't accept "vb ::= rec rec vb".
Status: language problem
--------------------------------------------------------------------------------
26. export ML within a use
Problem:
	Awkward behaviour when exportML is called while a file is being
	"use"'d - the saved state falls over with Io_failure. Shouldn't
	restarting clear the use stack?Version:
Status:
  Modified in version 18 so the image doesn't die.  It still raises
  Io_failure, though. (tyj)
  Fixed in 0.56
--------------------------------------------------------------------------------
27. different numbers of arguments in curried clauses cause bogus type error
Version: 0.15
Code:
    fun compose [] = (fn x => x) |
	compose (f::fl) x = compose fl (f x);
Messages:
    Error: type error: rules don't agree
     expected: ('a list -> ('b -> 'b))
     found:
      (f :: fl,x) => compose fl (f x)
      : ((('c -> 'd) list*'c) -> 'e)
Status: fixed in 0.19.
--------------------------------------------------------------------------------
28. tyvars in top-level type constraint
Submitter: Carl Gunter, gunter@linc.cis.upenn.edu (also Reppy, 4/20/88)
Date: 3/27/88
Version: 0.18
Problem: tyvars not accepted in top-level type constraint
Code:
    - length : 'a list -> int;
Messages: (compiler messages associated with bug)
    Error: lookTyvar -- unbound tyvar in closed scope
    Error: Impossible error: generalizeTy -- bad arg
    undef list -> int
Status: fixed in 0.20  (put protectTyvars around top level expression parse).
--------------------------------------------------------------------------------
29. use_string in structure definition
Submitter: Nick
Date: 3/24/88
Version: 0.18
Problem: use_string can cause uncaught Intmap exception
Code:
    - structure Foo =
       struct
	  val x = use_stream(open_string "val _ = Foo.x;")
       end;
Messages: 
    [opening <instream>]
    [closing <instream>]
    uncaught exception Intmap
Comments: This code shouldn't work, but the Intmap exception should be caught.
Status: Fixed in 0.54
--------------------------------------------------------------------------------
30. weakness 0 in constraint
Date: 4/5/88
Version: 0.18
Problem:
Code:
       - fn (x: '0a) => x;
Messages:
       Error: lookTyvar -- inbound tyvar in closed scope
       Error: Impossible error: generalizeTy -- bad arg
       undef -> undef
Comments: 
    Weak-tyvars of level 0 should raise an error when they occur in
    constraints.
Status: 
    fixed (indirectly) in 0.20.  causes error
      Error: can't generalize weak type variable
      '0a -> '0a
--------------------------------------------------------------------------------
31. redefining an open structure orphans r/t bindings
Submitter: John Reppy, jhr@svax.cs.cornell.edu
Date: 4/4/88
Version: 0.18
Problem:
    Redefining a structure after opening it makes its components inaccessible
    at runtime even though they are still visible, because the structure
    binding is removed from the r/t intmap environment.
Code:
    val it = () : unit
    - structure S = struct type t = int; val x = 1 end;
    structure S : <sig>
    - open S;
    open S
    - structure S = struct type t = bool; val x = true end;
    structure S : <sig>
    - x;
Messages:
    uncaught exception Intmap
Comments: can't eliminate a structure from r/t env if it has been opened
	  See bug 1. (elg)
Status: fixed
--------------------------------------------------------------------------------
32. printing loops
Submitter: Andrew
Date: 4/6/88
Version: 0.18
Problem: printing a cyclic data structure involving a ref loops
Code:
    datatype A = B | C of A ref
    val x = C(ref B);
    val C y = x;
    y := x;
    x;
Messages:
    prints endlessly
Comments: 
    probably not handling ref constructors properly in tracking depth
Status: fixed in 0.20.  missing base (depth = 0) in printDcon in printval.sml.
--------------------------------------------------------------------------------
33. cyclical sharing not checked, parsing problem
Submitter: Mads
Date: 4/12/88
Version: 0.18
Problem: cyclical sharing not detected, but leads to parsing bug
Code:
    (1)

    signature Sig =
      sig structure a:
	    sig structure b: sig end
	    end
	  structure a': sig end sharing a = a'
	  structure b': sig end sharing b' = a.b
	  sharing a' = b'
      end

    This example should be rejected because it would lead to a cycle in 
    the signature for 'a' (the semantics Section 5.4). If one deletes the
    last sharing obtaining

    (2)

    signature Sig =
      sig structure a:
	    sig structure b: sig end
	    end
	  structure a': sig end sharing a = a'
	  structure b': sig end sharing b' = a.b
      end

    one get a legal program. However these examples do not survive
    parsing. (I get an "uncaught exception Notfound_Table"). Ignoring
    this, will your sharing algorithm cope with this subtlety?
Messages:
    uncaught exception Notfound_Table  (now fixed)
Comments:
    We may not try to find cycles, since they would in any case prevent
    the signature from matching any structure.  [dbm]
Status: partially fixed in 0.20.  cycle not detected, but exception is handled.
--------------------------------------------------------------------------------
34. uncaught Instantiate in type checking
Submitter: Trevor
Date: 4/14/88
Version: 0.18
Problem: uncaught Instantiate exception during type checking
Code:
    structure foo =
    struct

    local
      exception Sort
    in
    fun sort (op > : ('x * 'x -> bool))
       = let fun select(min, best, hd::tl) = select(min,
					      if best > min
					       then if best > hd andalso hd > min
						     then hd else best
					       else hd,
					      tl)
	       | select(min, best, nil) = best;
	     fun lowest(best, hd::tl) = lowest( (if hd>best then best else hd), tl)
	       | lowest(best, nil) = best;
	     fun s (l as (hd::tl), min) = min
	       | s _ = raise Sort
	  in fn (l as (hd::tl)) => let val v = lowest(hd,tl) in v :: s(l, v) end
	      | nil => nil
	 end
    end (* local *)

    end
Messages:
    uncaught exception Instantiate
Comments:
Status: fixed in 0.20.
--------------------------------------------------------------------------------
35. Compiler bug: abstractType
Submitter: Andrew
Date: 4/6/88
Version: 0.18
Problem: type error in functor definition causes Compiler bug error
Code:
    signature FORMULA =
     sig
	 type formula
	 val NUM : formula
     end

    functor Parse(F : FORMULA) = 
    struct

       fun parse() : F.formula = (0, F.NUM)
    (*  val parse : unit -> F.formula = (fn () => (0, F.NUM))  -or-
    (*  val parse : F.formula = (0, F.NUM) -- don't cause abstractType error *)

    end
Messages:
Error: expression and constraint don't agree (tycon mismatch)
  expression: int * ?.formula
  constraint: ?.formula
  in expression:
    (0,NUM)
Error: Compiler bug: abstractType
Status: fixed
--------------------------------------------------------------------------------
36. overloading resolution and order of recursive definitions
Submitter: Dave
Date: 5/2/88
Version: 0.18
Problem: 
    overloading resolution can depend on the order in which mutually
    recursive definitions occur
Code:
    fun f x = x + x
    and g() = f 1
      (* + is not resolved *)
    fun g() = f 1
    and f x = x + x
      (* + is resolved *)    
Status: fixed in 0.52, approximately.
--------------------------------------------------------------------------------
37. type printing
Submitter: Nick
Date: 5/3/88
Version: 0.18
Problem: valid path is not printed for a type
Code:
	- signature SIG = sig type t val x: t end
	  structure S: SIG = struct type t = int val x = 3 end;
Messages:
	signature SIG
	structure S : <sig>
	- S.x;
	val it = 3 : ?.t
		     ^ ???
Comments:
Status: fixed in 0.20. (not sure how! as side-effect of another fix?)
--------------------------------------------------------------------------------
38. incompatible sharing raises Notfound_Table
Submitter: Nick
Date: 5/3/88
Version: 0.18
Problem:
    sharing specification between two incompatible structures causes an
    uncaught Notfound_Table exception.
Code:
	- signature FOO1 =
	     sig
	        structure S: sig type S end
	        structure T: sig type T end
	        sharing S = T
	     end;
Messages:
	uncaught exception Notfound_Table
Status: fixed in 0.20.  Added handlers for Notfound_Table in function
    sMerge in typing/sharing.sml.
--------------------------------------------------------------------------------
39. type abbrev not recognized as function type
Submitter: dbm
Date: 5/12/88
Version: 0.19
Problem:
    type abbreviation expands to function type, but not recognized as 
    a functional type by the type checker
Code:
    type 'a church = ('a -> 'a) -> ('a -> 'a);
    val zero = fn f => fn x => x
    val succ = fn n => fn f => fn x => f (n f x)
    val pred = fn n : 'a church =>
		 ((fn (_,b)=>b) (n (fn (a,b) => (succ a, a)) (zero,zero)))
Messages:
    Error: operator is not a function
    operator: 'a church
    in expression:
      n (fn (a,b) => (succ <exp>,a))
Comments:
Status: fixed in 0.20.  reduced the ratorTy in APPexp case of expType in
    typecheck.sml.
--------------------------------------------------------------------------------
40. Exception aliasing (match compiler)
Submitter: Dave
Date: 5/12/88
Version: 0.19
Problem:
   Match compiler doesn't cope with exception aliasing (through functor
   parameters, for instance).
Status: fixed in 0.54
--------------------------------------------------------------------------------
41. missing substructure
Submitter: Dave
Date: 5/18/88
Version: 0.19
Problem:
    substructure required by signature is not declared but appears anyway.
Code:
    signature AS = sig val x: int end

    structure A : AS = struct val x = 3 end

    signature BS =
    sig
      structure A : AS
    end

    structure B : BS =
    struct
      open A
    end
Messages:
   should complain, but doesn't
Comments:
Status: fixed in 0.20.
--------------------------------------------------------------------------------
42. Two signature matching problems.
Submitter: Bob Harper
Date: 5/20/88
Version: 0.18
Problem:
   (1) missing substructures found in environment,
   (2) bind exception processing sig specs after missing substructure
Code:
    signature SIG = sig type t val x:t end;

    signature SIG' = sig structure S:SIG val y:S.t end;

    structure T : SIG = struct type t=int val x = 3 end;

    structure T' : SIG' = struct structure S=T val y=S.x end;

    (* This yields a sensible error message, then an uncaught exception Bind. *)
    structure T'' : SIG' = struct val y=T.x end;

    signature SIG'' = sig structure T:SIG val y:T.t end;

    (* This should not succeed, but it does!  The unbound structure appears
       in the global environment, so it doesn't notice that the substructure T
       is missing.
    *)
    structure U : SIG'' = struct val y = T.x end;
Messages:
Comments:
    (1) missing substructure was found because lookSTR was being used to
        look for structure components in SigMatch.realize.  Fixed by introducing
	lookSTRlocal that does not search through STRlayer.
    (2) TypesUtil.lookTycPath was causing bind exception because the missing
	substructure defaulted to the unexpected form INDstr(~1).  Caused
	lookTycPath to raise an exception that was caught by typeInContext,
	which then returns ERRORty.  SigMatch.compareTypes ignores the ERRORty.
Status: fixed in 0.20
--------------------------------------------------------------------------------
43. incorrect error message for sharing constraints
Submitter: Bob Harper
Date: 5/21/88
Version: 0.18
Problem:
    "unbound structure id in sharing spec" error message was reporting the
    wrong structure id.
Code:
    signature SIG = sig end;

    signature SIG' = sig
      structure S:SIG
    end;

    (* Here it complains that S' is unbound in the sharing specification, but
    actually it's S'.T that is unbound! *)

    signature SIG'' = sig
      structure S':SIG'
      structure T:SIG
      sharing S'.T = T
    end;
Messages:
    Error: unbound structure id in sharing specification: S'
Comments:
    Moved one of the handlers for Notfound_Table from findStr to getStr
    in sharing.sml.
  
    0.65 now gives output

     std_in:19.3-21.19 Error: unbound structure id in sharing specification: T

    it would be better to say that S'.T is unbound.
Status: fixed in 0.20
--------------------------------------------------------------------------------
44. subscript exception during parsing
Submitter: Dave, Bob Harper
Date: 3/20/88
Version: 0.18
Problem:
   Subscript exception raised during parsing
Code:
   /usr/nml/bugs/bob.4, /usr/nml/examples/micro-ml/make
Messages:
   uncaught exception Subscript
Comments:
   path created by function search in EnvAccess.iterFct was in reversed order.
   added rev.
Status: fixed in 0.20
--------------------------------------------------------------------------------
45. equality on simple recursive datatype causes compiler to loop
Submitter: Dave
Date: 5/27/88
Version: 0.19
Problem:
  Compiling equality for a trivial recursive datatype causes the compiler
  to loop in Equal.equal.(test).
Code:
  datatype t = A of t
  fun f(x:t) = (x=x)
Comments:
  Of course this is a useless datatype, but someone could define it by mistake
  and cause the compiler to loop.  The problem is the treatment of datatypes
  with a single transparent constructor in the function test in equal.  It
  recursively calls test on the argument type of the constructor, which in this
  case is justs t again.  A datatype like

     datatype t = A of t * int

  does not cause the loop.
Status: fixed in 0.20
--------------------------------------------------------------------------------
46. equality type checking and flexrecords
Submitter: Dave
Date: 6/3/88
Version: 0.20
Problem:
    when flexrecords are used a nonequality type may be accepted in a context
    where an equality record type is required
Code:
    fun f(r as {a,...},true) = (r = r)  (* checks only that a admits equality *)
      | f({b,...},false) = b 3 (* oops, the b field is a function! *)
Messages:
    val f = fn : {a:''a,b:int -> bool} * bool -> bool
    (* argument type is not an equality type *)
Comments:
    A fix probably requires a change in the way flexrecords are represented.
Status: fixed in 0.54.  [actually only correctly fixed in 0.85]
--------------------------------------------------------------------------------
47. scope of user bound type variable
Submitter: Mads Tofte (Edinburgh)
Date: 3/8/88
Version: 0.18
Problem:
  some uses of user-bound type variables have strange effects
Code:
  fun f(x) = let val y : 'a = x in y y end;
  val f = fn : 'a -> 'a
  - f 3;
Messages:
  Error: operator and operand don't agree (bound type var)
  operator domain: 'a
  operand:         int
  in expression:
    f 3
Comments:
  y gets the type !'a.'a, which allows the expression "y y" to type check
  x gets the user bound type variable 'a as its type and it is not generalized
   either when y's type is generalized or when f's type is generalized
  the result type 'a refers to a generically bound type variable which
   coincidentally is printed as 'a
Status: fixed in 0.20
  generates an error message indicating that the user-bound type variable was
  propagated out of its scope.  This is a rather obscure error message, but it
  is not easy to do better.  This seems much better that allowing the propagation
  of the user bound type variable out of its natural syntactic scope, since it
  would be necessary to do arbitrary amounts of type checking to simply determine
  whether two explicit type variables are the same.
--------------------------------------------------------------------------------
48. printing of identity withtype declarations
Submitter: Dave
Date: 6/9/88
Version: 0.20
Problem:
  A simple identity declaration in the withtype clause of a datatype declaration
  will not be printed properly.
Code:
  datatype foo = A
  withtype t = int;
Messages:
  datatype  foo
  con A : foo
  type  t = t
Comments:
  This happens because the backpatching of the type constructor puts the new
  name in the defining type as well as in the defined type binding.
Status: fixed by 0.54
--------------------------------------------------------------------------------
49. equality status of type constructors after functor application
Submitter: Dave
Date: 6/10/88
Version: 0.20
Problem:
  type constructors defined in a functor should sometimes become
  equality type constructors when the functor is applied, but they don't.
Status: fixed in 0.20 (* unfixed in 0.56, refixed in 0.57? *)
        Given up on for the time being (since it's not required by the
	standard). (elg) 
--------------------------------------------------------------------------------
50. free refs to sibling structures within a signature
Submitter: Dave
Date: 6/13/88
Version: 0.20
Problem:
  Free references to a sibling structure in a signature are not allowed
Code:
  signature SS =
  sig
    structure A : sig type t end
    structure B : sig  val x : A.t end
  end
Messages:
  Error: free ref to sibling struct in sig not implemented
Comments:
  Outer signature env has default info, giving rise to Subscript exception when
  attempting to interpret A.
Status: fixed in 0.31
--------------------------------------------------------------------------------
51. free refs to param struct in functor result signature
Submitter: Dave
Date: 6/13/88
Version: 0.20
Problem:
  Free references to the functor parameter are not allowed in the result
  signature.
Code:
  functor F(S: sig type t val x: t end) : sig val y : S.t end =
  struct
    val y = S.x
  end
Messages:
  Error: unbound head structure: S
    in path: S.t
Comments:
Status: fixed in 0.39
-------------------------------------------
52. input of large strings
Submitter: Appel&Duba
Date: 9/9/88
Version: 0.20
System: any
Problem: (input f k) was unreliable for k>1024
Status: fixed in 0.22
-------------------------------------------
53. exportFn broken
Submitter: Appel&Duba
Date: 9/9/88
Version: 0.20
System: any
Problem: exportFn produced an executable that dumped core
Status: fixed in 0.22
-------------------------------------------
54. problems in Sun Unix version 4.0
Submitter: Appel&Duba
Date: 9/9/88
Version: 0.20
System: Sun 3/SunOS 4.0
Problem: doesn't work; can't boot sml
Status: fixed in 0.22
------------------------------------------ 
55. type constraint on field abbreviation
Submitter: Duba
Date: 11/2/88
Version: 0.22
System: any
Problem: won't except type constraint in abbreviated records
Code: fun f{x : int} = 1;
Message: Error: expected EQUAL after label, found COLON
Status: fixed
------------------------------------------ 
56. big integer constants
Submitter: Duba
Date: 11/8/88
Version: 0.22
System: cps
Problem: interger constants must be less than 31 bits
Code: 1000000000
Message: Error: Compiler bug: Overflow in cps/generic.sml
Status: fixed in 0.24
---------------------------------------------------------------------------
57. open_out causes SystemCall exception
Submitter: dbm
Date: 11/10/88
Version: 0.23
System: --
Problem: opening nonwriteable file causes uncaught exception SystemCall
Code: 
    LexGen.lexGen "ml.lex";
    uncaught exception SystemCall
    - system "ls -l";
    total 38
    -r--r--r--  2 dbm           993 Nov  9 12:03 ascii.sml
    -r--r--r--  2 dbm          3207 Nov  9 12:03 hookup.sml
    -r--r--r--  2 dbm          2813 Nov  9 12:03 ml.lex
    -r--r--r--  2 dbm         23900 Nov  9 12:03 ml.lex.sml
    -r--r--r--  2 dbm          2698 Nov  9 12:03 symbols.sml
    -r--r--r--  2 dbm          2599 Nov  9 12:03 timelex.sml
    val it = () : unit
Messages:
Comments:  Attempting to open an unreadable file for input raises Io_failure,
	   but attempting to open an unwriteable file for output raises
	   SystemCall.
Status: fixed.
---------------------------------------------------------------------------
58. incorrect string value in Io_failure exception
Submitter: dbm
Date: 11/10/88
Version: 0.23
System: vax/v9
Problem: string returned by Io_failure invoked by open_in is bogus
Code:
  [assume "all" is the name of an unreadable file]
    (open_in "all"; "abc") handle Io_failure s => s;
Messages:
    val it = "open_in: open" : string  
Comments: should be "open_in: all"
Status: fixed in 0.49.
---------------------------------------------------------------------------
59. memory fault on sun
Submitter: Benjamin Pierce, CMU (Benjamin.Pierce@prood.ergo.cs.cmu.edu)
Date: 10/18/88
Version: 0.22
System: Sun 3 / SunOS 4.0 (3.x?)
Problem: memory fault
Code: see shamash:/usr/sml/bugs/benli/test1.sml
Messages: see shamash:/usr/sml/bugs/benli/log1
Comments: Test program works on Vax
Status: fixed in 0.24 [bug in polymorphic equality for constructions]
---------------------------------------------------------------------------
60. floating point coprocessor problem on Sun 3
Submitter: M. C. Atkins, University of York, UK., ...!ukc!minster!martin
Date: 10th Nov 1988
Version: 0.22, 10 October 1988
System: Sun3/SunOS 3.5
Problem: sml core dumps with illegal instruction (COPROCESSOR PROTOCOL ERROR)
Code: (This is what I was given!)
	val start_seed1 = 0.71573298;
	val start_seed2 = 0.31872973;
	val start_seed3 = 0.45832123;
	
	val mul1 = 147.0;
	val mul2 = 375.0;
	val mul3 = 13.0;
	
	
	fun random seed mul = let val x = seed*mul*3.0
	                       in x - real(floor x)
	                      end;
	
	fun randlist seed1 seed2 seed3 0 = [] |
	    randlist seed1 seed2 seed3 n = let val s1 = random seed1 mul1
	                                       val s2 = random seed2 mul2
	                                       val s3 = random seed3 mul3
	                                       val rn = (floor ((random (s1*s2*s3) 743.0)*37.0) )
	                                    in rn::(randlist s1 s2 s3 (n-1))
	                                   end;
	
	
	fun rlist n = randlist start_seed1 start_seed2 start_seed3 n;

Messages: No compiler messages. At runtime the following is written to the console:
	sml: USER COPROCESSOR PROTOCOL ERROR
	trap address 0x34, pid 147, pc = ea92a, sr = 4, stkfmt 9, context 3
	D0-D7  3 3 196838 f 0 0 1966b0 efffc50
	A0-A7  efff274 1affec 0 efffd98 efffda4 0 1b0004 efff264

Comments:
	To duplicate `use' the given code, and then evaluate `rlist
300' two or three times. Typically the first evaluation succeeds, but
subsequent evaluations fail, giving a core dump (Illegal Instruction)
and the above error on the console.

	I have duplicated the behaviour on both a Sun 3/50, and a Sun
3/280 - both equipped with MC68881 floating point coprocessors.
/usr/etc/mc68881version gives the following output:
on 3/50:
	MC68881 available; mask set appears to be A93N. 
	Approximate MC68881 frequency 16.5 MHz.
on 3/280:
	MC68881 available; mask set appears to be A93N. 
	Approximate MC68881 frequency 20.3 MHz. 
Status: fixed in 0.31
---------------------------------------------------------------------------
61. lexer bug
Submitter: Trevor
Date: 11/6/88
Version: 0.22
System: any?
Problem: illegal character causes loss of next line of input
Code:
    - 234;^?                (* That's a true delete (or ^A or whatever) that accidentally *)
    val it = 234 : int      (* got stuck in there. *)
    Error: illegal character
    - "hello";              (* This line gets discarded *)
    - 3;
    val it = 3 : int
    - 
Comments:
Status: fixed in 0.24
---------------------------------------------------------------------------
62. share runtime on SunOS 3.n
Submitter: Nick
Date: 10/28/88
Version: 0.22
System: Sun 3, SunOS 3.n
Problem: runtime built with share parameter doesn't work on SunOS 3.n
Comment: SunOS 3.n object format is not supported
Status: no action
---------------------------------------------------------------------------
63. curried, clausal def of infix function
Submitter: Paulson
Version: Version 0.20, 13 June 1988
System: Sun3/SunOS
Problem: parsing of infixes 
Code: (minimal code fragment that causes bug)
    - infix orelf;
    - fun (f orelf g) x = 0;
    Error: expected EQUAL, found RPAREN
    Error: atomic expression expected
    Error: declaration or expression expected, found RPAREN

    - fun f orelf g = fn x => 0;
    val orelf = fn : 'a * 'b -> 'c -> int
Comments: 
  This use of an infix in a pattern seems legal and is accepted by Poly/ML.
Status: fixed in 0.54
---------------------------------------------------------------------------
64. unclosed comment is not reported
Submitter: Duba
Date: 12/2/88
Version: 0.22 and later
System: Any
Problem: unclosed comment is not reported
Code: (* ...
Status: fixed in 0.54.
---------------------------------------------------------------------------
65. arrayoflist should have weak type.
Submitter: Nick
Date: 11/24/88
Version: 0.24
Status: fixed in 0.33
---------------------------------------------------------------------------
66. floor(~3.9) gives ~5.
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Status: fixed in 0.33
---------------------------------------------------------------------------
67. won't parse "fn {x: ty} => x".
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Status: fixed in 0.33
---------------------------------------------------------------------------
68. spurious error message -- doesn't match sig spec
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
	- structure S: sig val x: int end = struct val x = hd "s" end;
	Error: operator and operand don't agree (tycon mismatch)
	  operator domain: 'S list
	  operand:         string
	  in expression:
	    hd "s"
	Error: value type in structure doesn't match signature spec
	  name: x
	  spec:   int
	  actual: error
Status: fixed in 0.54
---------------------------------------------------------------------------
69. printing of exn spec in inferred signature
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
	- structure Blah = struct exception BLAH end;
	structure Blah :
	  sig
	    exception BLAH of exn  (* "of exn" should not appear *)
	  end
Status: fixed in 0.54
---------------------------------------------------------------------------
70. constructor shouldn't appear in printed structure signature
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
	signature SIG =
	    sig
		type t
	    end

	structure S:SIG =
	    struct
		datatype t = foo of int
		val x = 3
	    end
Messages:
	structure S :
	    sig
		datatype t
		  con foo : int -> t  (* shouldn't be printed *)
	    end
Comment: constructor foo is not accessible as component of S
    Also, from Dave Berry (2/2/89):
    NJ ML prints the constructors of a datatype when that datatype is
    matched against a "type" in a signature, even if the signature
    doesn't include the constructors.

    This seems a trivial point (except that it's confusing for the novices on
    the course we teach).  However, with some complicated programs the compiler
    bombs out, raising the subscript exception.  You are left in the ML system,
    but it won't compile your code.

    I don't have a small example of this.  It first hit me preparing
    examples for the aforementioned course, and it's just hit me again.
Status: fixed in 0.56
---------------------------------------------------------------------------
71. Failure to restore enviroment after exception in "use"
Submitter: Nick
Date: 11/24/88
Version: 0.24
System: Sun 3
Code:
      For a file "y.sml" containing "val y = 4";

	- val x = (use "y.sml";
		   let exception X in raise X end
		  );
	[opening y.sml]
	val y = 4 : int
	[closing y.sml]
	uncaught exception X
	- (* so far so good... *)
	- x;
	uncaught exception Runbind
Comment: needs to be a protect around use to trap exceptions and restore env
Status: fixed in 0.54
---------------------------------------------------------------------------
72. equality types with abstype declarations
Submitter: kevin
Date: 11/30/88
Version: 0.24?
System: Sun 3
Code:
    (* The following definition is accepted by the compiler, resulting in
       the declaration test: ''a foo -> bool *)

    abstype 'a foo = Foo of 'a list
    with fun test(Foo x) = (x = []) end;

    (* The next declaration fails with the error
      Error: operator and operand don't agree (equality type required)
      operator domain: ''S * ''S
      operand:         'T foo * 'U foo
      in expression:
	x = Foo nil  *)

    abstype 'a foo = Foo of 'a list
    with fun test(x as Foo _) = (x = Foo []) end;

    (* I'm not sure why one should be allowed and not the other - the old
       Edinburgh compiler accepted both.  *)
Status: fixed in 0.54
---------------------------------------------------------------------------
73. strange function definition
Submitter: Trevor
Date: 12/10/88
Version: 0.24?
System: vax
Problem:
Code:
    - fun add-a x = x+1;
    val a = fn : int -> int
    - a 3;
    val it = 4 : int
Comments:
    The intent was to have a hyphen in a function name
    (something like "fun add_a ...".
Status: fixed in 0.54
---------------------------------------------------------------------------
74. withtype with identity type definition (printing only?)
Submitter: Nick
Date: 12/15/88
Version: 0.22
Code:
        - datatype Foo = FOO of Forest
        =    withtype Forest = Tree list
        =         and Tree = Foo;
        datatype  Foo
        con FOO : Forest -> Foo
        type  Forest = Tree list
        type  Tree = Tree               <-= Huh?
Comments: probably an artifact of printing from symbol table, not abstract syntax
Status: fixed in 0.54
---------------------------------------------------------------------------
75. improper type variable causes Substring exception
Submitter: John Reppy
Date: 12/17/89
Version: 0.24
System: Sun 3
Code:
    - (nil : ' list);
    uncaught exception Substring
Status: fixed in 0.56
---------------------------------------------------------------------------
76. parenthesized infix expression in fun lhs
Submitter: Dave Berry
Date: 12/22/88
Version: 0.24?
Code: 
    infix o;
    fun (f o g) x = f (g x);
Comments: This is correct according to the Definition (according to Berry)
Status: fixed in 0.54
---------------------------------------------------------------------------
77. unparenthesized infix expressions in fun lhs
Submitter: Dave Berry
Date: 12/22/88
Version: 0.24?
Code: 
    infix 4 %;
    infix 3 %%;

    datatype foo = op % of int * int;
    fun a % b %% c % d = 0;

    NJ ML accepts this, as does Edinburgh ML.  It is incorrect; brackets
    are required as follows:

    fun (a % b) %% (c % d) = 0;

    This is defined on page 68 of the definition.  The lhs and rhs of the
    infixed operator being defined are required to be atomic patterns.
Status: fixed in 0.54
---------------------------------------------------------------------------
78. bad signature allowed
Submitter: Nick
Date: 1/20/89
Version: 0.24
Code:
    signature FRED =
       sig
	  type Fred
	  val x: 'a Fred
       end
Comments: This should be caught as an ill-formed signature
Status: fixed in 0.39
---------------------------------------------------------------------------
79. withtype
Submitter: Simon (from abstract hardware) via Mike Fourman
Date: 1/31/88
Version: 0.24
Problem:
    "Did you know that the following is not valid ML?

	datatype type1 = T of type2 * type3
	withtype type2 = int (* this could be a large expression *)
	and      type3 = type2 * string;

    The reason is that the "datatype datbind withtype typbind" construct is
    expanded out into "datatype datbind'; type typbind" where "datbind'" is
    the the result of using "typbind" to expand "datbind". Note that this
    construct does *not* expand "typbind" itself, so "type2" is out of scope
    in its occurrence in "type3". This simultaneous definition property of
    "withtype" is quite annoying, especially as there is no way to get the
    effect of sequential definition (other than manually expanding out the
    body of "type3" - but that is precisely the problem that "withtype" is
    supposed to solve)."

Code:
    - 
	datatype type1 = T of type2 * type3
	withtype type2 = int (* this could be a large expression *)
	and      type3 = type2 * string;


    - = = Error: Compiler bug: defineEqTycon/eqtyc 1
    - 
	datatype type1 = T of type2 * type3
	withtype type3 = type2 * string
	withtype type2 = int (* this could be a large expression *);


    - = = Error: unbound type constructor (in datatype): type2
    Error: unbound type constructor (in datatype): type2
    Error: Compiler bug: defineEqTycon/eqtyc 1
    - 
Comment: withtype should have sequential bindings, not simultaneous
Status: fixed in 0.54
---------------------------------------------------------------------------
80. simultaneous type declarations
Submitter: Dave Berry
Date: 2/1/89
Version: 0.24
Code:
    - type type2 = int
    = and  type3 = type2 * string;
    type  type2 = int
    type  type3 = type2 * string
Comments:
    This is wrong: type2 shouldn't be bound before the declaration of type3.
Status: fixed in 0.54
---------------------------------------------------------------------------
81. repeated specs in signatures
Submitter: John Reppy
Date: 2/12/89
Version: 0.24
Problem:
    I noticed that a signature of the form

	    sig
		    val x : int
		    val x : string
	    end

    is acceptable.  Although this is in keeping with redeclaration in other
    scopes, it isn't very useful, and lets detectable errors get by.  I would
    suggest that redeclaration of identifiers in signatures ought to at least
    generate a warning message (if not an error).
Status: same as #4
---------------------------------------------------------------------------
82. compiler bug caused by type in datatype declaration
Submitter: Andrew
Date: 2/20/89
Version: 0.28?
Code:
    datatype a = A of int;
    datatype b = B of A;                    (* typo for B of a *)
Messages:
    Error: unbound type constructor (in datatype): A
    Error: Compiler bug: defineEqTycon/eqtyc 1.
Status: fixed in 0.39
---------------------------------------------------------------------------
83. unexpected parsing of erroneous datatype declaration
Submitter: Carl Gunter
Date: 2/24/88
Version: 0.20
Code:
    - datatype complex = Complex (real,real);
    datatype  complex
    con Complex : complex
    val it = (fn,fn) : (int -> real) * (int -> real)
Comments:
    implicit "val it = " inserted after constructor Complex breaks the
    declaration into a valid datatype declaration and a top-level value
    expression (implicit value declaration).  This could probably be 
    detected and suppressed.
Status: fixed in 0.54
---------------------------------------------------------------------------
84. definition of open_out and open_append
Submitter: Nick
Date: 2/28/89
Version: 0.29
Problem:
    the following code from perv.sml is faulty:

      val open_out = open_o WRITE
			    handle Assembly.SystemCall s =>
				    raise Io("open_out: " ^ s)
      val open_append = open_o APPEND
			    handle Assembly.SystemCall s =>
				    raise Io("open_append: " ^ s)

    Another lambda-abstraction is needed to catch errors on the application
    of open_o, rather than these bindings.
Status: fixed in 0.33
---------------------------------------------------------------------------
85. bad error message for failed signature match
Submitter: John Reppy
Date: 3/6/89
Version: 0.28
Code:
   structure Foo : sig
     type foo
     val f : foo -> int
   end = struct
     type Foo = int
     fun f x = x
   end;
Messages:
    Error: unmatched type spec: foo
    tycStamp: INDtyc []
    Error: Compiler bug: tycStamp
Status: fixed in 0.54
---------------------------------------------------------------------------
86. incorrectly allows redefining of "="
Submitter: Dave Berry
Date: 3/15/89
Version: 0.29
Problem:
    NJML handles the = symbol incorrectly in some cases.

    - val op = = op = ;
    - nonfix =;
    - = (true, true);
    Error: declaration or expression expected, found EQUAL
Comment:
    The = symbol may not be redefined (Definition, page 4).  The top definition
    does seem to redefine =, despite the lack of response from the system.
    I can't see anything in the Definition that forbids making = nonfix,
    so I suppose it should be possible to use it in a nonfix way.
Status: fixed by 0.69 (rebinding = gives a warning message; parses better)
---------------------------------------------------------------------------
87. execute subprocess dies on interrupt on blocked input
Submitter: dbm
Date: 3/19/89
Version: 0.31
System: Sun3/100, SunOS 4.0.1; VAX8550, V9
Problem: interrupting blocked call of input from execute subprocess
	 kills subprocesss
Code:
	val (ins,outs) = execute "cat"
	input ins 5;
	^Cuncaught exception Interrupt
Messages:
   After interrupt, System.system("ps x"), indicates that "cat"
   subprocess has disappeared, and subsequent attempt to flush output
   to outs raises exeption Io("output: write failed").
Comments:
   end_of_stream also blocks, and interrupting a call of end_of_stream
   seems to have the same effect.

   jhr:  This isn't a bug, but rather a "feature."  The sub-process inherits
    the control terminal (/dev/tty) from its parent.  This means that the
    SIGINT generated by ^C is passed to both processes.  I assume that
    there is a work-around, but the semantics are correct for Unix.
Status: not a bug
---------------------------------------------------------------------------
88. subscript exception while printing type
Submitter:
    Thorsten Altenkirch
    Technische Universitaet Berlin
    alti%theo@tub.BITNET
Date: Fri Mar 31 18:42:20 MET DST 1989
Version: 0.24
System: SunOS Release 4.0_Export
Problem: "uncaught exception Subscript" while printing type.
Code:
    signature A = sig type t end;
    functor F1(a:A) = struct
      datatype t2 = f of a.t
      end;
    functor F2(a:A) = struct
      structure S = F1(a);
      open S
      end;
    structure SA = struct type t = int end;
    structure F2SA = F2(SA);
Messages:
    ..
    structure F2SA :
      sig
	structure S : sig...end
	datatype t2
	  con f : [closing /tmp/sml.tmp.l10641]
    uncaught exception Subscript
Comments:
   The error may be caused by the handling of indirect types
   in src/basics/printtype.sml (printPath).
Status: fixed in 0.39
---------------------------------------------------------------------------
89. continuation line string escape at beginning of string
Submitter: dbm
Date: 4/3/89
Version: 0.33
System: Sun 3, SunOS 4.0.1
Code:
    - "\			(* CR after \ at beginning of string *)
    - akdk";
    Error: unclosed string
    =		    		(* second CR typed *)
    Error: unclosed string
    Error: unbound variable kdk
    = ;
    Error: operator is not a function
      operator: string
      in expression:
	"" kdk
Status: fixed in 0.49.
---------------------------------------------------------------------------
90. secondary prompt is not set in multi-line strings and comments.
Submitter: dbm and duba
Date: 4/3/89
Version: 0.33
System: All
Status: fixed in 0.49
---------------------------------------------------------------------------
91. misparsing of fun lhs
Submitter: dbm and duba
Date: 4/3/89
Version: 0.33
System: All
Code:
    - fun a+b (x) = a;
    Error: Compiler bug: generalizeTy -- bad arg
      b : 'S -> undef
Status: fixed in 0.54
---------------------------------------------------------------------------
92. uncaught Nth exception after type constructor arity mismatch in sigmatch
Submitter: David Tarditi, Princeton University, drt@notecnirp.princeton.edu
Date: 6/23/89
Version: 0.33
System: Vax/4.3 BSD
Problem: Mismatching arities on types causes uncaught exception Nth
	 later in signature checking.

Example:

functor OrdSet(B : sig
			type elem
			val gt : elem * elem -> bool
			val eq : elem * elem -> bool
		   end) =
struct
end

structure Bad =
    struct
	type 'a elem = int * 'a
	val gt = fn ((a:int,_),(b,_)) => a > b
	val eq = fn ((a:int,_),(b,_)) => a = b
    end

structure  X = OrdSet(Bad)

Result:

Standard ML of New Jersey, Version 0.33, 1 April 1989
val it = () : unit
std_in, line 18: Error: mismatching tycon arities: elem
uncaught exception Nth

Comments:

The uncaught exception Nth appears to occur while matching the actual types
of eq and gt against the types in the signature of the formal
structure parameter.

Status: fixed in 0.56
---------------------------------------------------------------------------
93. type propagation failure with functor application
Submitter: David Tarditi, Princeton University, drt@notecnirp
Date: 7/25/89
Version: 0.33
System: Vax/4.3 BSD
Problem:  Type in a structure passed to a functor remains an opaque
	  type outside the functor.

Example code:

signature T =
sig type 'pos token
end

signature L =
sig structure T : T
end

functor P(structure L : L) =
struct
	open L
end

structure L =
   struct
	structure T = struct
			type 'a token = int * 'a * 'a
		      end
   end

structure B = P(structure L = L)

val x = (5,"","")
val _ = x : string L.T.token  (* this works *)
val _ = x : string B.T.token  (* this causes a type error - why ? *)

Comments:

I thought that the type token should be an abstract (opaque) type only
inside the functor P.  It should be non-opaque in the structure created by
applying the functor P.

Status: fixed in 0.37
---------------------------------------------------------------------------
94. uncaught Bind exception parsing functor body
Submitter: David Tarditi, Princeton University, drt@notecnirp
Date: 7/25/89
Version: 0.33
System: Vax/4.3 BSD
Problem:  The compiler failed by raising a Bind exception
	  which was not caught.

Example code:

functor mkDummy () : sig end  = 
    struct
    end

functor mkLalr () =
    struct
	datatype lcore = LCORE of int
    end

functor mkTable () =
   struct
	structure Dummy = mkDummy()
	structure Lalr = mkLalr()
	val x = fn (Lalr.LCORE l) => l
    end

Comment:
It seems that the compiler fails while compiling an access to a data
constructor inside a functor.  The data constructor must have the
special characteristic that it is created by applying another functor
inside the functor being compiled:

Status: fixed in 0.37 (0 should have been 1 in envaccess.sml *)
---------------------------------------------------------------------------
95. infix declaration interferes with type parsing
Submitter: David Tarditi, Princeton University, drt@notecnirp
Date: 4/30/89
Version: 0.33
System: Vax/4.3 BSD
Problem: Spurious declaration of infix for an identifier causes problems
	 when it is used as a type constructor later.

Sample Run:

    Standard ML of New Jersey, Version 0.33, 1 April 1989
    val it = () : unit
    - type ('a,'b) --> = 'a -> 'b;
    type ('a,'b)  --> = 'a -> 'b

    - val a = fn _ => 5;
    val a = fn : 'a -> int

    - a : ('a,int) -->;
    val it = fn : 'a -> int

    - infix -->;

    - a : ('a,int) -->;
    Error: (user) bound type variable propagated out of scope
      it : 'aU -> int

Comments:
	The declaration of an identifier to be infix should not
affect type constructors.  Infix declarations apply only to data
constructors and value identifiers.  The declaration of '-->' to
be infix should not affect the use of '-->' as a type constructor,
even though the declaration is spurious.

P.S.
	Maybe there should be a way to declare type identifiers to be
infix.  I was trying to declare '-->' to be infix because I was creating
different kinds of arrows for my effects inference.  --> could denote
a function that is pure, while -*-> could denote a function with an
effect.  I need to do this to bootstrap the pervasive environment
without assuming that all built-in functions have side-effects.

Status: fixed in 0.54
---------------------------------------------------------------------------
96. uncaught exception Unbound parsing signature
Submitter: Martin Wirsing
Date: 7/18/89
Version: 0.33
System: VAX/V9
Description: uncaught exception Unbound while parsing a signature
Code
 signature Sigtest =
        sig
        structure S:
                sig
                type t1
                val x:t1->t1
                end
        structure R:
                sig
                type t2
                val x:t2->t2
                end
        type t
        val f:t1->R.t2
        end
= = = = = = = = = = = = = uncaught exception Unbound
- Error: declaration or expression expected, found END

Status: fixed in 0.39
---------------------------------------------------------------------------
97. Type checking
Submitter: Mads Tofte
Date: 6/30/89
Version: 0.33
Description:
Here is a program which, although type correct, does not type check
on the NJ compiler --- one gets a type error in the last line.  
It does type check on Poly ML. 
The problem disappears is one erases the explicit result signature
on SymTblFct and it seems that the problem is that sharing is
not propagated correctly in functor application when the signature
has an explicit result signature.
When the internal type stamps are printed, one sees that
the types of the second and the third arguments are ``abstract''
and not instantiated to the stamps for string and real, respectively.

Code: 
signature IntMapSig=
sig
  type 'a map
  exception NotFound
  val apply: 'a map * int -> 'a
  val update: 'a map * int * 'a -> 'a map
  val emptyMap: 'a map
end;

signature ValSig =
sig
  type value
end;

signature SymSig=
sig
  eqtype sym
  val hash: sym -> int
end;


functor SymTblFct(
  structure IntMap: IntMapSig
  structure Val: ValSig
  structure Sym: SymSig):

    sig
      type table
      exception Lookup
      val emptyTable: table
      val update: table * Sym.sym * Val.value -> table
    end=

struct
  datatype table = TBL of
   (Sym.sym * Val.value)list IntMap.map
  val emptyTable = TBL IntMap.emptyMap;

  exception Lookup
  
  fun update(TBL map,s,v)=
   let val n = Sym.hash(s)
       val l = IntMap.apply(map,n) handle IntMap.NotFound => []
       val newmap= IntMap.update(map,n,(s,v)::l)
    in TBL newmap
   end 

end;

functor FastIntMap(): IntMapSig=
struct  (* dummy implementation of int maps *)
  datatype 'a map = N of int * 'a * 'a map * 'a map  
                  | EMPTY
  val emptyMap = EMPTY
  exception NotFound
  fun apply _ = raise NotFound;
  fun update _ = raise NotFound;
end;

functor ValFct(): ValSig=
struct 
  type value = real
end;

functor SymFct(): SymSig=
struct
  type sym = string
  fun hash(s:sym)= ord s
end;

structure MyTbl=
SymTblFct(structure IntMap = FastIntMap()
          structure Val = ValFct()
          structure Sym = SymFct()
         );
              
open MyTbl;
  
update(emptyTable,"ape",10.0);

Comment: parameters Val and Sym appear in result signature of SymTblFct.
This has not been supported previously.

Status: fixed in 0.37
---------------------------------------------------------------------------
98. eqtype determination
Submitter: Carl Gunter (gunter@linc.cis.upenn.edu) [Jakov Kucan]
Date: 7/18/89
Version: 0.33
Problem: compiler bug: defineEqTycon/eqtyc 1
Code:

datatype constant_type = CONSTANT;

datatype composed_type = Constructor of int * CONSTANT;

Messages:

Standard ML of New Jersey, Version 0.20, 13 June 1988
val it = () : unit
- use "bug.ml";
[opening bug.ml]
datatype  constant_type
con CONSTANT : constant_type
bug.ml, line 7: Error: unbound type constructor (in datatype): CONSTANT
bug.ml, line 7: Error: Compiler bug: defineEqTycon/eqtyc 1

Status: fixed in 0.37 
---------------------------------------------------------------------------
99. include bug
Submitter: Nick Rothwell
Date: 7/19/89
Version: 0.33
Problem: include doesn't work
Code:
	signature A = sig end
	signature B = sig include A end;
Messages:
	Error: Compiler bug: SigMatch.setParent
Status: fixed in 0.39
---------------------------------------------------------------------------
100. constructor not printed after open declaration
Submitter: Nick Rothwell
Date: 7/18/89
Version: 0.33
Problem:
  In this case, a datatype is being printed as a type: the constructor isn't
  shown (although it's still bound):
Code:

    - signature X = sig datatype T = T end;
    signature X =
      sig
	datatype T
	  con T : T
      end

    - structure X: X = struct datatype T = T end;
    structure X :
      sig
	datatype T
	  con T : T
      end

    - open X;
    type  T = T

Status: fixed in 0.49
---------------------------------------------------------------------------
101. Duplicate labels (in either types or values) are not detected
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    - {x=1,x=true} : {x:int,x:bool};
    val it = {x=1,x=true} : {x:int,x:bool}
Status: fixed in 0.54
---------------------------------------------------------------------------
102. One-tuples are not printed sensibly.
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    - (* a one-tuple *) {1 = 999};
    val it = (999) : int
    - it = 999;
Messages:
 Error: operator and operand don't agree (tycon mismatch)
   operator domain: (int) * (int)
   operand:         (int) * int
   in expression:
     it = 999
Status: fixed in 0.54
---------------------------------------------------------------------------
103. Space missing in an error message (which might be more informative).
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
   - {999};
Messages:
   Error: numeric label abbreviation999
Status: fixed in 0.54
---------------------------------------------------------------------------
104. Labels with leading zeroes should not be accepted (this is made
     explicit on page 5 of version 3 of the Standard).
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    - {0000002 = 999};
    val it = {2=999} : {2:int}
Status: fixed in 0.54
---------------------------------------------------------------------------
105. Large numeric labels are disallowed.    
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    -  {9999999999999999999999 = 999};
Messages:
    Error: integer too large
    Error: nonpositive integer label, found 0
Status: not important
---------------------------------------------------------------------------
106. Something strange is happening with "it".
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    Standard ML of New Jersey, Version 0.33, 1 April 1989
    val it = () : unit
    - raise it;
    Error: argument of raise is not an exception
      raised: unit
      in expression:
	raise it
    - raise it;
    Error: argument of raise is not an exception
      raised: unit
      in expression:
	raise it
    - raise it;
    uncaught exception Runbind
    - raise it;
    uncaught exception Runbind
    - 
Comment:
    The problem of an exception leaving the system in an uncertain 
    state seems to occur in other contexts too.
Status: fixed in 0.54
---------------------------------------------------------------------------
107. NJML disappears into an infinite loop when trying to parse large real numbers;
     presumably some error recovery code is flakey.
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    - 1.0E308;
    val it = 1.0E308 : real
    - 1.0E309;
    Error: Real constant  out of range
    - 2.0E308; (* wait a long time ... *)
    val it = uncaught exception Interrupt
    - 
Comment:
Furthermore, a failing program elaboration or evaluation (such as the above)
should not rebind the variable "it" (ML Standard v3, rules 194 and 195).
NJML sometimes does (as above).

Furthermore, trying to print "it" when it has been bound to such an
exception sometimes seems to crash the system (it refuses to respond to
further input); at other times the exception Runbind is raised.

Does anyone know why the largest integer NJML will parse is 1073741775 ?
This is 2^30 - 49, which seems a funny number to choose. (Mike Crawley
suggests the fact that 49 is the ASCII code for "1" may be significant.)

Status: fixed in 0.56
---------------------------------------------------------------------------
108. More faulty error recovery?
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    - 
    (* calculates ~ 2^30 *) ~1073741775 - 49;

    [Increasing heap to 4096k]

    [Major collection... 99% used (973164/976372), 8020 msec]

    [Increasing heap to 7568k]
    val it = uncaught exception Interrupt
    - 
Status: fixed in 0.56
---------------------------------------------------------------------------
109. sharing of datatypes not handled properly
Submitter: Simon Finn (simon%abstract-hardware-ltd.co.uk@nsfnet-relay.ac.uk)
Date: 7/28
Version: 0.33
Code:
    signature EQSIG =
    sig
      type r
      datatype s = S of r
	   and t = T of s
      sharing type r = t
    end;

    functor F(X : EQSIG) =
    struct
      fun test(x : X.t) = (x = x);
    end;
Messages:

    signature EQSIG =
      sig
	type r
	datatype s
	  con S : r -> s
	datatype t
	  con T : s -> t
      end
    Error: operator and operand don't agree (equality type required)
      operator domain: ''S * ''S
      operand:         ?.t * ?.t
      in expression:
	x = x
    Error: Compiler bug: abstractType

Comment:
    Both are wrong, as the signature EQSIG elaborates to the same semantic object
    as the following (which both treat correctly):

    signature EQSIG =
    sig
      type r
      datatype s = S of t
	   and t = T of s
      sharing type r = t
    end;

Status: fixed in 0.54
---------------------------------------------------------------------------
110. val rec
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: val rec form of definition rejected
Code:

- val x = 1 and rec y = fn z => z; (* should compile *)
Error: expected an atomic pattern, found REC
Error: expected EQUAL, found REC
Error: atomic expression expected, found REC
Error: declaration or expression expected, found REC

Comment: the compiler should accept the above declaration.
Status: not a bug; the Definition is silly
---------------------------------------------------------------------------
111. local polymorphic definitions
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: local polymorphic definitions rejected
Code:

- val q = let exception x of '_a in 1 handle x _ => 2 end;
Error: type variable in exception type not weak enough

- local exception x of '_a in val q = 1 handle x _ => 2 end;
Error: type variable in exception type not weak enough


Comment: the compiler should accept both the above definitions,
         which are valid, since the imperative type variable '_a
         is *not* free in the top level declaration.
Comment: (dbm)  Consider the following, which leads to insecurity:
     local exception X of '_a in val exn0 = X(3) fun h(X(b:bool)) = b end;
     raise exn0 handle e => h(e);
Status: not a bug
---------------------------------------------------------------------------
112. equality
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: equality misbehaving
Code:

(0.0 = ~0.0, 0.0 = ~ 0.0, ~0.0 = ~ 0.0);    (* (true,true,true) *)

infix eq; fun x eq y = x = y;
(0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,false,false) *)

infix eq; fun (x:real) eq y = x = y;
(0.0 eq ~0.0, 0.0 eq ~ 0.0, ~0.0 eq ~ 0.0); (* (true,true,true) *)

Comment: the polymorphic equality function should give
         consistent results, even when the type of its
         argument is known to be real.
Status: fixed in 0.49
---------------------------------------------------------------------------
113. empty declarations
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Parsing empty declarations
Code:

    let val x = 1; (* empty declaration *) ; val y = 2 in x + y end;
    Error: expected IN, found SEMICOLON
    Error: atomic expression expected, found SEMICOLON
    Error: atomic expression expected, found VAL
    Error: expected END, found VAL
    Error: declaration or expression expected, found IN

Comment: the above program is syntactically correct.
Status: fixed in 0.49
---------------------------------------------------------------------------
114. include broken (same as bug 99)
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: include in signatures
Code:

    - signature old = sig type t end;
    signature old =
      sig
	type t
      end

    - signature new = sig include old end;
    Error: Compiler bug: SigMatch.setParent

Status: fixed in 0.39
---------------------------------------------------------------------------
115. cyclic signatures
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: cyclic signatures
Code:

    (* shouldn't be allowed, since object (signature) is not cycle-free *)
    signature bad =
    sig
      structure A :
      sig
	structure B : sig end;
      end;
      sharing A = A.B;
    end;

Comment: NJML accepts the above signature declaration, which should be
         rejected because it elaborates to a cyclic semantic object;
         cyclic objects are not semantically admissible.

Status: not a bug?  (signature will never match a structure)
---------------------------------------------------------------------------
116. pattern declares no variables warning (?)
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Missing warning message
Code:

let val _ = 1 in 2 end;
local val _ = 1 in val it = 2 end;


Comment: Each of the above should produce a "Pattern declares
         no variables" warning message, but neither does.

Status: not a bug 
---------------------------------------------------------------------------
117. sharing and equality attributes
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: problems with equality attribute
Code:

(***************************************************************************)
(* This is illegal in version 3 of the ML standard                         *)
(* s may only be elaborated to a non-equality type (+ extra bits)          *)
(* t may only be elaborated to an equality type (for consistency with its  *)
(* constructor environment)                                                *)
(* Hence s and t can't share                                               *)
(***************************************************************************)

signature BADSIG =
sig
  datatype s = Dummy of bool -> bool
  datatype t = Dummy of int
  sharing type s = t;
end;

Comment: NJML accepts this signature but shouldn't. Getting the
         equality attribute right in the presence of sharing
         constraints seems to be quite a tricky problem.

Status: fixed in 0.56
---------------------------------------------------------------------------
118. deviation from Definition, div and mod
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: div / mod give non-standard results
Code:

fun divmod (m,n) = (m div n,m mod n);
(* should give (1,2)   *) divmod(5,3);   (* gives (1,2)   *)
(* should give (~2,1)  *) divmod(~5,3);  (* gives (~1,~2) *)
(* should give (~2,~1) *) divmod(5,~3);  (* gives (~1,2)  *)
(* should give (1,~2)  *) divmod(~5,~3); (* gives (1,~2)  *)

Comments: I'd like the initial dynamic basis to conform to the Standard.
          (More efficient, non-standard versions should be hidden away.)
Status: fixed in 0.56
---------------------------------------------------------------------------
119. deviation from Definition
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: I/O functions are curried, Standard has them uncurried
Code:

    - input;
    val it = fn : instream -> int -> string

Comments: I'd like the initial dynamic basis to conform to the Standard.
          (More efficient, non-standard versions should be hidden away.)
Status: fixed in 0.56
---------------------------------------------------------------------------
120. deviation from Definition
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: Prelude functions raise the wrong exceptions
Code:

    0.0 / 0.0; (* raises Overflow *)
    1.0 / 0.0; (* raises Real *)

Comments: I'd like the initial dynamic basis to conform to the Standard.
          (More efficient, non-standard versions should be hidden away.)
This one is even trickier; Poly/ML doesn't raise any exception at all
for these (it prints NaN.0 and Infinity.0 respectively).
Status: fixed in 0.56, mostly
---------------------------------------------------------------------------
121. Unimplemented parts of Standard
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: open in signatures apparently unsupported
Code:

    - structure old = struct type t = int end;
    structure old :
      sig
	eqtype t
      end
    - signature new = sig open old end;
    Error: expected END, found OPEN
    Error: declaration or expression expected, found END
    - 
Status:  This is a language design problem; see doc/localspec
---------------------------------------------------------------------------
122. Unimplemented parts of Standard
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: let and local for structures apparently unsupported
Code:

    - structure Y = struct local val x=1 in structure X = struct val y = 1 end end end;
    Error: expected END, found STRUCTURE
    Error: declaration or expression expected, found END

    - structure Y = let val x=1 in struct structure X = struct val y = 1 end end end;
    Error: expected a structure-expression, found LET
    - 
Status: fixed in 0.54
---------------------------------------------------------------------------
122. Unimplemented parts of Standard
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 7/18/89
Version: 0.33
System: Sun3/SunOS 4.0
Problem: local in signature apparently unsupported
Code:

    - signature SIG =
    sig
      structure S : sig type t end;
      local open S; in val x : t; end;
    end;
    = = = Error: expected END, found LOCAL
    Error: unbound structure name: S
    Error: unbound type constructor: t
    Error: expected EQUAL, found SEMICOLON
    Error: atomic expression expected, found SEMICOLON
    - 
Status: language problem: see doc/localspec
---------------------------------------------------------------------------
123. error recovery
Submitter: Simon Finn, Abstract Hardware Ltd, simon@uk.co.ahl
Date: 18 July 1989
Version: 0.33
System: Sun3/SunOS 4.0
Problem: NJML error recovery is flakey
Code: 
    val it = () : unit
    - infix xxx;
    - fun (a xxx b) = 3;
    Error: expected EQUAL, found RPAREN
    Error: atomic expression expected, found RPAREN
    Error: declaration or expression expected, found RPAREN
    - fun output (s,w) = output s w;
    Error: pattern and expression in val rec dec don't agree (circularity)
      pattern:    'S -> 'T -> 'U
      expression: 'S * 'T -> 'U
      in declaration:
	output = (fn arg => (case arg
		  of <pat> => <exp>))
    - output;
    uncaught exception Runbind

Comments: The declaration of "xxx" should be accepted - this is a minor
          known (?) parsing bug. The redeclaration of "output" is a user
          error. The two in succession seem to severely confuse the
          compiler; either independently seems to be OK.
Status: fixed
---------------------------------------------------------------------------
124. compiler bug after incomplete qualified identifier
Submitter: David Tarditi, Princeton University, drt@notecnirp
Date: 4/21/89
Version: 0.33
System: Vax/4.3 BSD
Problem: compiler error results when incomplete qualified identifier is used.
Sample Run:

    Standard ML of New Jersey, Version 0.33, 1 April 1989
    val it = () : unit
    -Integer.;
    Error: incomplete qualified identifier
    Error: Compiler bug: EnvAccess.lookPathinStr.getStr
    -

Comments:
Caused by using an incomplete qualified identifier.

Status: fixed in 0.56, sort of.
---------------------------------------------------------------------------
125. constructor exported from abstype declaration
Submitter: Carl Gunter <gunter@CENTRAL.CIS.UPENN.EDU>
Date: 6/25/89
Version: 0.33
Problem: constructor for abstract type visible outside abstype decl
Code:
    abstype
      intset = Set of int list
    with
      val empty_set = Set [];
    end

    - Set;
    val it = fn : int list -> intset

Status: fixed in 0.39
---------------------------------------------------------------------------
126.  scope of explicit type variables
Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK>
Date: 7/11/89
Version: 0.33
Problem:
New Jersey ML (Version 33) does not accept the following declarations.
It complains that a user bound type variable escapes out of scope in `insert'.
But the scope of ''a and 'b is the whole of the fun declaration.  The problem
seems to be associated with mutual recursion.

  type (''a, 'b)map = (''a *  'b) list

  fun plus(l:(''a,'b)map ,[]: (''a, 'b)map ): (''a, 'b)map = l
    | plus(l,hd::tl) = plus(insert(l,hd), tl)
  and insert([], p) = [p]
    | insert((x,y)::rest, (x',y')) = 
        if x=x' then (x',y')::rest
        else (x,y) :: insert(rest,(x',y'));

Status: fixed in 0.54
---------------------------------------------------------------------------
127. sharing and equality types
Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK>
Date: 7/11/89
Version: 0.33
Problem: 
New Jersey ML does not accept the following functor declaration (it
complains that S.x is not of equality type).  According to the
Definition, two types share only if they have the same name (stamp).
In particular, since equality is an attribute of type names (Version
3, page 16), one admits equality iff the other does (one cannot have
different ``views'' of equality).  

Presumably the problem is a bug in the unification of type names.

Code:
    functor f(structure S : sig type t val x: t end
	      structure T : sig eqtype t end
	      sharing S = T
	     )=
    struct val b:bool = S.x = S.x
    end;
      
Status: fixed in 0.54
---------------------------------------------------------------------------
128. question mark as reserved word
Submitter: Mads Tofte <mads%lfcs.edinburgh.ac.uk@NSFNET-RELAY.AC.UK>
Date: 7/11/89
Version: 0.33
Problem: 
New Jersey ML treats ? as a reserved word (it once was).

Status: fixed in 0.54
---------------------------------------------------------------------------
129. Bind exception parsing functor  (same as 94)
Submitter:
  Hans Bruun
  Department of Computer Science, Technical University of Denmark
  hb@iddth.dk
Date: 9-June-1989
Version: 0.33
System: Vax/Ultrix
Problem: parsing functor raises Bind
Code:
  signature S_sig=
  sig 
  type 'a T
  val fs: 'a T -> 'a T
  end;

  functor S() =
  struct
  datatype 'a T =  C
  fun fs  (x: 'a T )=  C: 'a T
  end ;

  functor F (type t)=
  struct
  structure S1: S_sig= S();
  open S1
  type  FT = t T
  fun ff (x : FT)=  fs x
  end;

Messages: uncaught exception Bind
Comments: 
  Without  ': FT'   or   ': S_sig'   the code is accepted by the compiler.

Status: Fixed in 0.37
---------------------------------------------------------------------------
130. compiler bug on functor application
Submitter:
  Hans Bruun
  Department of Computer Science, Technical University of Denmark
  hb@iddth.dk
Date: 24-May-1989
Version: 0.33
System: Vax/Ultrix
Code:

    structure S =
    struct
    datatype 'a T =  C
    fun fs  (x: 'a T)=  x
    end ;

    functor F (type t)=
    struct
    open S
    type  FT = t T
    fun ff (x : FT)=  fs x
    end;

    structure SF= F(type t=int);

Messages: 
    structure S :
      sig
	datatype 'a  T
	  con C : 'a T
	val fs : 'a T -> 'a T
      end
    functor F : <sig>
    bug.sml, line 15: Error: Compiler bug: SigMatch.applyFunctor/insttyc

Status: fixed in 0.39
---------------------------------------------------------------------------
131. dying on files of certain lengths
Submitter: Jussi Rintanen, Helsinki University of Technology, jur@hutcs.hut.fi
Date: 15 June 1989
Version: 0.33 1 April 1989
System: Vax 4.3 BSD, Sun-4 SunOS Release4-3.2 (?)
Problem: Neither the batch compiler not the interactive system accept
	 source files of size 2049, 4097, ...(???).
Code: Tested with 2 signatures, I inserted white space, works properly
      if the file size is a byte lower or higher.
Messages: Sun-4 dumps core, uVax raises Io

Status: fixed in 0.37
---------------------------------------------------------------------------
132. rebinding of "=" allowed
Submitter: Mike Fourman (mikef%lfcs.ed.ac.uk)
Date: 6/8/89
Version: 0.33
Problem: NJML allows = to be rebound (contrary to page 4 of the definition)
Code:
    - val op = = op < : int * int -> bool;
    val = = fn : int * int -> bool
    - 
Status: not important
---------------------------------------------------------------------------
133. overloading resolution is weaker than Edinburgh SML or Poly ML
Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk)
Date: 5/8/89
Version: 0.33
Problem:
Code:
    datatype 'a tree = Stree of 'a list * (string * 'a tree) list
    fun insert ((key::keys, x), Stree(xs,alist)) =
	  let fun inslist((keyi,tri)::alist) =
		    if key<keyi then alist else (keyi,tri) :: inslist alist
	  in  Stree(xs, inslist alist)  end;
Messages:
    Error: overloaded variable "<" cannot be resolved
Status: fixed in 0.54
---------------------------------------------------------------------------
134. type checking
Submitter: 
  Erik Tarnvik 
  Department of Computing Science
  University of Umea
  SWEDEN
  erikt@cs.umu.se
Date: 5/12/89
Version: 0.33
System: Sun3
Problem:
The compiler reports a type clash were it shouldn't.

Code:
    type 'a ft = (int * 'a) list;

    fun f ([]:'a ft) x = []:'a ft
      | f (((y,fy)::l):'a ft) x = 
	  if x = y
	  then l:'a ft
	  else (y,fy)::(f l x):'a ft

    and g (l:'a ft) (x,fx) = (x,fx) :: (f l x):'a ft;

Messages:
    type 'a  ft = (int * 'a) list
    line 10: Error: operator and operand don't agree (bound type var)
      operator domain: (int * 'aU) list
      operand:         'aU ft
      in expression:
	f l
Comments:
The Edinburgh SML (ver 3.3) does not report an error on this code.
If the 'and' in the last line is changed to 'fun', no error is reported.
I hope I haven't missunderstood something about SML. This is a bug, isn't it?

Status: fixed in 0.49
---------------------------------------------------------------------------
135. eqtype vs abstype
Submitted: Bernard Sufrin (sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK)
Date: 7/26/89
Version: 0.33
Problem: interaction of abstype and eqtype

I ran into this problem whilst writing you a long note concerning
abstraction bindings structure bindings and their respect for type and
eqtype specifications. Here's a miniature version of the larger
problem.

We want a pair of types Open and Shut, and transfer functions between
them. The two signatures below are candidates for describing such a
structure: the latter leaves visible the equality on Open, the former
should not.

    signature T =
    sig
      type Shut
      type Open
      val Shut:Open->Shut
      and Open: Shut->Open
    end

    signature U =
    sig
      type Shut
      eqtype Open
      val Shut:Open->Shut
      and Open: Shut->Open
    end

Now we design a functor which simply wraps something up in order to shut it.

    functor absT(type Open)  =
    struct
      type Open = Open
      abstype Shut = SHUT of Open  with
	val Shut  = SHUT
	fun Open(SHUT x) = x
      end
    end

Now we instantiate it:

    structure b:T = absT(type Open=int)

Compiler yields:

    structure b :
    sig
      eqtype Shut         <----- can't be right, surely
      eqtype Open
      val Open : Shut -> Open
      val Shut : Open -> Shut
    end

The equality on Shut has leaked, despite the fact that the actual
representation of Shut is an abstype. (The same happens if absT is
itself constrained to yield a T)

    - b.Shut 3=b.Shut 4;
    val it = false : bool

On the other hand using an abstraction binding

    abstraction ab:T = absT(type Open=int)

Compiler yields, correctly,

    structure ab :
      sig
	type Shut
	type Open
	val Open : Shut -> Open
	val Shut : Open -> Shut
      end

but I cannot actually apply ab.Shut to an integer (its domain is not
int, but an opaque and different type, namely ab.Open).  Now let's try

    abstraction au:U = absT(type Open=int)

Compiler yields, correctly,

    structure au :
    sig
      type Shut                                    
      eqtype Open
      val Open : Shut -> Open
      val Shut : Open -> Shut
    end

but I still can't apply au.Shut to an integer. Incidentally in my
original note I asked (a) whether I ought to be able to, (b) if so,
whether eqtype was not getting a bit overloaded [equality visible AND
representation visible] (c) if not, how could one do this sort of
thing at all?

Meanwhile

    structure argh:U = absT(type Open=int)

still makes Open and Shut both eqtypes.  More bizarrely, we have

    abstype opaque = opaque of int with
     val hide = opaque
     val show = fn(opaque x)=>x
    end

    structure biz:T = absT(type Open=opaque)

Compiler yields

    structure biz :
      sig
	eqtype Shut                 <--- wow!
	type Open
	val Open : Shut -> Open
	val Shut : Open -> Shut
      end

Shut is now an eqtype despite being an abstype whose representation
includes another abstype!

Status: fixed in 0.54
---------------------------------------------------------------------------
136. linkdata problem
Submitter: John Reppy (ulysses!jhr, jhr@cs.cornell.edu)
Date: 7/12/89
Version: 0.36
System: Sun 3, SunOS 4.0.3
Problem: failure to build
Code:
When I tried to build 0.36 on the sun-3, I got the message

	ld: : Is a directory

on the load of the runtime system.  The problem is with the allmo.o
file.  I am able to build the system using "-noshare".

Status: fixed in 0.49
---------------------------------------------------------------------------
137. profiler failure
Submitter: Ian Dickinson,  HP Labs, Information Systems Centre,    Bristol
	     ijd%otter@hplabs.hp.com
Date: 9/28/89
Version: 0.33
System: HP 9000 HP-UX 6.3
Problem: 
I have a small, compute intensive program (around 2K lines of code including
comments).  With the profiler turned on, njml fails repeatably at the first
major collect:

        - test 30 30;
        Case 30: TOLUENE, A,O-DICHLORO

        [Major collection... 54% used (2332228/4249436), 2483 msec]
        unknown signal: 20

        Process SML exited abnormally with code 148

Priority: A
---------------------------------------------------------------------------
138. numeric labels not equivalent to tuples
Submitter: Russ Green <rjg%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK>
Date: Thu, 23 Nov 89 11:10:18 GMT
Version: 0.43
Problem: numeric labels over 9 not treated properly
Code:

    New Jersey ML seems to get confused with records composed of n numeric
    labels where n > 9.  (Poly ML doesn't)

      - val a = {1=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0};
      val a = (0,0,0,0,0,0,0,0,0) : int * ... * int       (* OK *)

      - val b = {1=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0,10=0};
      val b = {1=0,10=0,2=0,3=0,4=0,5=0,6=0,7=0,8=0,9=0} : 
	       {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int}

    The resulting record type will not unify with the corresponding tuple

      - a = (0,0,0,0,0,0,0,0,0);
      val it = true : bool			(* OK *)

      - b = (0,0,0,0,0,0,0,0,0,0);
     Error: operator and operand don't agree (tycon mismatch)
     operator domain:{1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int}
     * {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int}
     operand:        {1:int,10:int,2:int,3:int,4:int,5:int,6:int,7:int,8:int,9:int}
     * (int * int * int * int * int * int * int * int * int * int)
      in expression:
	b = (0,0,0,0,0,0,0,0,0,0)
Comments:
Presumably something to do with the sorting of the record labels (10 comes
before 2)?
Status: fixed in 0.54
--------------------------------------------------------------------------------
139.  compiling with gcc doesn't work 
Submitter: Brian Boutel, brian@comp.vuw.ac.nz
Date: 9 November 1989
Version: 0.36 & later
System: HP/Sun 3
Problem: compiling with gcc doesn't work 
Description:

    I have been trying again to port sml to H-P 68030 boxes running
    MORE/bsd, using the Gnu C  compiler. 

    We have a mix of Sun3 and H-P machines, and, although I have installed
    sml on the suns, it would be convenient to have it available on the H-Ps as well.

    The H-P port has not worked, and to separate the problems arising from
    the Operating System from those arising from the use of gcc, I have
    tried building sml on the suns with gcc (using the -traditional
    option). The build completes, but the resulting sml dies immediately
    while doing a major garbage collection. It does not get as far as
    announcing itself as Standard ML of .....
    I have tried various options, (optimiser on/off some of the gcc -f
    options) without effect. Have you tried gcc? I am anxious to persue
    this as  I think getting a gcc compiled version to run on the suns is
    the right first step towards porting to the H-Ps. Can you offer any suggestions?

    I am using sml version 0.36.  ( I tried today to ftp to
    research.att.com to check for a later version, but found an empty
    directory when logging on as anonymous, and was refused permission to
    log on as mldist.)


    Changes made to the source are summarised as

    ------
    gnu C compiler requires f68881 to be changed to m68881
    Changed in makeml by introducing $CCOMP, set to GNUCC for machine hp300,
    otherwise "", and testing it in defining CFL for M68

    ----------------
    for H-P, sys/exec.h defines MID_HP300 instead of M_68020
    linkdata.c and export.c have conditional code if HP300 defined
    makeml has to pass HP300 to make for linkdata
    -------------
    for H-P, callgc.c has FPE_TRAPV_TRAP undefined, and
    TRAPV returns FPE_INTOVF_TRAP
    so FPE_TRAPV_TRAP is defined as FPE_INTOVF_TRAP in callgc.c
    ----------
    _minitfp_ and _fp_state_mc68881 not defined anywhere for H-P
    .globl omitted if HP300 in M68.prim.s
    --------------------
    run dies because stack clobbered by apply
    Registers saved ala NeXT/MACH in saveregs/restoreregs in prim.s if GNUCC
Status: fixed in 0.44
--------------------------------------------------------------------------------
140. comment to end of file  (see also bug 64)
Submitter: Conal Elliott, Kestrel Institute, conal@kestrel.edu
Date: Wed Nov  8 11:15:35 1989
Version: 0.39
System: Sparc
Problem: The compiler doesn't give an error message if the file ends in
         the middle of a comment.
Messages: None (that's the problem)
Comments: This has tripped me up a few times, and was quite puzzling.
Status: fixed in 0.54
--------------------------------------------------------------------------------
141. interrupting gc dumps core
Submitter: peter@central.cis.upenn.edu (Peter Buneman)
Date: 18 November 1989
Version: 0.39
System: ??
Problem:
    I've found occasions on which our current version of ML goes a bit
    flakey after being interrupted during garbage collection.  I haven't
    been able to pin it down until now.  The following interactive session
    appears to be repeatable.
Code:
    % sml
    Standard ML of New Jersey, Version 0.39, 8 September 1989
    val it = () : unit
    - fun foo() = 1::foo();
    val foo = fn : unit -> int list
    - foo();

    [Major collection...
    [Increasing heap to 7144k]
     70% used (1752720/2487664), 4810 msec]

    [Increasing heap to 7280k]

    [Major collection... 62% used (2484132/3975316), 7580 msec]
		  *** I typed <cntrl>C during this garbage collection
    [Increasing heap to 11648k]
    uncaught exception Interrupt
    - fun bar() = bar();
    val bar = fn : unit -> 'a
    - bar();      *** I did not type <cntrl>C here !!
    uncaught exception Interrupt
    - bar();      *** nor here!!
    uncaught exception Interrupt
    - 
Comments:
    In 0.43d2 I can't repeat this behavior, but interrupting during gc causes
    a bus error or segmentation fault. [dbm]
Status: fixed in 0.54
--------------------------------------------------------------------------------
142. import incompatible with interpreter only image
Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK>
Date: 27 Sept 1989
Version: 0.39
System: Sun 3 ?
Problem: import into interpreter
Description:
    OK; when making the intepreter-only it seems one must:

	    makeml -noshare -noclean -run
	    makeml -ionly -noshare -norun 

    Then one gets the smaller (by about 200k) file. 

    Problem: it is not possible to import precompiled stuff; the compiler 
    decides that the .bin file is not in the right format; tries to recompile,
    and fails for lack of a code generator.

    Here's an example...

    - import "/prg/pl/sml/lib/lex";
    [reading /prg/pl/sml/lib/lex.bin... ]
    [/prg/pl/sml/lib/lex.bin is the wrong format; recompiling]
    [closing /prg/pl/sml/lib/lex.bin]
    [reading /prg/pl/sml/lib/lex.sml]
      [reading /prg/pl/sml/lib/lib/lib/extend.bin... ]
      [/prg/pl/sml/lib/lib/lib/extend.bin is the wrong format; recompiling]
      [closing /prg/pl/sml/lib/lib/lib/extend.bin]
      [reading /prg/pl/sml/lib/lib/lib/extend.sml]
    /prg/pl/sml/lib/lib/lib/extend.sml, line 52: Error: Compiler bug: no code generator!
      [closing /prg/pl/sml/lib/lib/lib/extend.sml]
    [closing /prg/pl/sml/lib/lex.sml]
    IMPORT failed (compile-time exception: Syntax)

    When trying to reproduce the import bug
    you might try making the dependency graph more than three arcs deep.

Comments:
    Obviously we don't want to have to dispense with import
    when using the intepreter-only (typically it'd be students loading
    precompiled libraries), but I presume we don't want the complication of
    lambda-formatted bin files as well as machine code bin files.  May I
    propose the following:

    import from an ionly system should behave like import in the cg system if
    everything is up-to-date.

    if something is out of date, then import should either abort, or behave
    like use (I prefer the latter, I think, but you might make it
    controllable from a System.Control variable).
Status: not important
--------------------------------------------------------------------------------
143. use failes on certain input files of a certain length
Submitter: Jawahar Malhotra (malhotra%metasoft.uucp@BBN.COM)
Date: 26 October 1989
Version: ??
System: ??
Problem: use dumping core on magic input file length
Description:
    I have a source file which contains a signature definition and a
    functor definition. When I load it using the "use" statement, the
    compiler responds with the signature defn and the functor defn but
    then dumps core just before its prints the [<closing file>] line.
    Strangely, if I add another blank line to the file, everything is 
    OK. If you like, I can mail you the file; please let me know if
    you would like the file.

    Here is a reproduction of the compiler's output:

    - use "oareadattr.sml";
    [opening oareadattr.sml]
    signature OAREADATTR = ...
    ...
    ...
      end
    functor OAReadAttrFun : <sig>
    Segmentation Fault (core dumped)
Comments:
Status: not reproducible; possibly fixed.
--------------------------------------------------------------------------------
144. not waiting for child process
Submitter: Jawahar Malhotra, Meta Software; malhotra%metasoft@bbn.com
Date: 20 Oct 89
Version: 0.33
System: SUN OS 3.5
Problem: 	
	njsml doesn't wait for child process (created by a call to
	execute) to terminate. Suppose I execute the following 
	sml stmt:

	- execute "ls /users/malhotra";

	njsml creates a child process in which it runs ls. When ls 
	is done, it does an exit(0). In order for the exit to
	complete, its parent process (njsml in this case) should
	do a wait(). However, njsml doesn't do this and hence the
	"ls" process blocks on its exit and remains until njsml
	exits. The state of this process (as displayed by "ps") is:

	malhotra  2376  0.0  0.1    0    0 p2 Z     0:00 <exiting>

Comments: 
	One fix would be to prevent the process created by "execute" from
	being njsml's child. In this case, njsml would not have to wait to
	collect the child's termination status. This can be done by
	forking twice. Hence the code for execute might look like:
	(assume njsml is process p1)

	------------------------------------------------------------

	/* in process p1 */

	if (fork() == 0)	{	/* in p2 */
		if (fork() == 0) {	/* in p3 */
			.........			
			execl(......);
			.......
		}
		else {				/* in p2 */
			exit(0);
		}
	}
	
	/* in p1 */

	wait(0);			/* wait for p2 to exit */

	------------------------------------------------------------	

	Another fix (maybe easier to implement) is to install a signal
	handler for SIGCHLD.

	signal(SIGCHLD, ack);

	where ack() is simply:

	ack()
	{
	  wait(0);
	}
Status: not a bug
--------------------------------------------------------------------------------
145. stale top-level continuations cause type bugs
Submitter: Andrzej Filinski, CMU Computer Science (andrzej@cs.cmu.edu)
Date: Oct 11, 1989
Version: 0.39 (8 September 1989)
System: Sun3/4.3BSD
Problem: Capturing top-level continuation messes up the type system
Code:

    val cl = ref([]:int cont list);
    callcc (fn k=>(cl:=[k]; 42));
    val u = throw (hd (!cl)) 65; (* value 65 with universal type! *)
    u+1;     (* u as integer *)
    u^"str"; (* u as string *)
    u:bool;  (* u as boolean (cannot print) *)
    u:real;  (* u as real (core dump) *)

Comments: This may be a tricky problem, i.e. it is not quite clear
what the "right" behavior should be when the top-level continuation
is captured and carried across commands. Please don't take this as a
criticism of callcc/throw in general, though; they're great! Any plans
for integrating them more deeply in the language, like exceptions?
Status: fixed in 0.49
--------------------------------------------------------------------------------
146. inputting 1025 characters fails
Submitter: Jawahar Malhotra, Meta Software, malhotra%metasoft@bbn.com
Date: 9/29/89
Version: 0.33
System: Sun3/SunOS 3.5
Problem: "input" when applied to std_in and an int > 1024 returns "".
Code:
                - input std_in 1025;
                > val it = "" : string
Comments: It obviously works for all other kinds of instreams.
Status: fixed in 0.43
--------------------------------------------------------------------------------
147. compiler blowup
Submitter: Ian Dickinson,  HP Labs, Information Systems Centre,    Bristol
	     ijd%otter@hplabs.hp.com
Date: 27 Sept 1989
Version: 0.33
System: HP 9000 HP-UX 6.3
Problem: compiler out to lunch
Description:
    I have a large-ish list of type:
	    (string * string list) list

    It has 1003 entries, and on average the string list in each pair is around
    3 elements.  Each string is between 5 and 9 characters.

    The list is declared in a file in the form:
	    val graph = [ ("foo", ["bar"]), ... etc ...];
    This is the only declaration in the file. Poly-ml compiles the file
    in about 10 seconds.

    Njml takes around an hour to increase the heap to 30Mbytes, performs several
    major collects, and then bombs with an out-of-memory error.
Status: fixed in 0.43
--------------------------------------------------------------------------------
148. relational operators on empty string
Submitter: jhr@cs.cornell.edu (John Reppy)
	   also Erik Tarnvik, University of Umea, SWEDEN (erikt@cs.umu.se)
Date: 14 Sept 1989
Version: 0.39?
Problem:
    The implementation of "<" on strings doesn't work for ("" < "").
Comments:
    The fix is to replace line 835 of boot/perv.sml, which is

	fun sgtr(_,"") = true

    with the lines

	fun sgtr("","") = false
	  | sgtr(_,"") = true
Status: fixed in 0.43
--------------------------------------------------------------------------------
149. infinite gc loop with insufficient swap space
Submitter:  jhr@cs.cornell.edu (John Reppy)
Date: 18 Sept 89
Version: 0.39
System: Vax
Problem: 
    SML/NJ is being used at Cornell for a course this semester, and we've
    run into a problem with it on multi-user vaxen.  If there isn't sufficient
    swap space for the system to run, it seems to get into an infinite loop
    of garbage collection attempts.  I should fail gracefully in this situation.
Status: this is a long, finite loop; not a bug
--------------------------------------------------------------------------------
150. incomplete sharing spec accepted
Submitter:  Simon Finn <simon%abstract-hardware-ltd.co.uk@NSFnet-Relay.AC.UK>
Date: 13 Sept 89
Version: 0.33
Problem:
    Both NJML (v0.33) and Poly/ML (v1.80x) erroneously parse the following:

    signature SIG =
    sig
      type t
      sharing type t
    end;
Comments:
    The above signature is illegal, since sharing constraints must involve
    at least two types / structures ("n >= 2" in section 3.5, figure 7).

    This bug was found by Mike Crawley.
Status: fixed in 0.54
--------------------------------------------------------------------------------
151. can't limit length of list printed
Submitter:  Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK>
Date: 14 Sept 1989
Version: ??
Problem:
    How do you tell New Jersey ML not to print all the elements of a list?
    System.Control.Print.printDepth seems to consider nesting only.
Code:
    - take(100,ms);
    val it = [1861294,62685628,105212158,14112418,78287461,35512822,180290056,316473
    64,72270388,168319897,212829007,43941079,142303594,174252739,117587239,56623288,
    96050461,46119052,152678905,140061256,13973941,209088847,109015732,167261566,142
    82215,159257329,69147538,162991570,121739197,19339324,52452037,18146911,23268574
    ,183534766,93272557,163056892,193407172,50009149,131379349,28143469,114167002,14
    8862536,85731877,182107423,28619248,67440382,145320439,121674259,172092145,16412
    2099,196052140,141367123,32002813,17851816,198701119,46866244,196351819,12166451
    8,163288573,14499193,10976578,64526104,139008271,417145,67962574,64746709,994460
    5,117181366,115999456,124879621,188830621,158322193,82998094,187333183,178599706
    ,158794345,17054389,62405431,142521907,182072470,22294474,162171034,163367647,12
    3860254,25498117,13136599,105899185,53939356,184226566,191249065,66913411,177659
    797,114495331,28730221,76001191,104114101,180588016,60920215,151887592,208100422
    ] : int list

    - [[[[[[[[[[[4]]]]]]]]]]];
    val it = [[[[[#]]]]] : int list list list list list list list list list list list
    -
Status: fixed in 0.54
--------------------------------------------------------------------------------
152. floating point errors
Submitter: Lawrence C Paulson <lcp%computer-lab.cambridge.ac.uk@NSFnet-Relay.AC.UK>
Date:  Thu, 14 Sep 89
Version: ??
Problem:
    Why cannot New Jersey handle integers that are well within the maximum
    available on the hardware?
Code:
    - exp(31.0 * ln 2.0);
    val it = 2147483648.0 : real

    - floor 2000000000.0;
    uncaught exception Floor
Status: fixed in 0.54; but the maximum integer is 1073741823 in SML-NJ
--------------------------------------------------------------------------------
153. interrupting coroutine loop dumps core
Submitter: Bernard Sufrin <sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK>
Date:  Sep 15 11:14:13 1989
Version: 0.43
System: Sun 3
Problem: producer consumer segementation fault
        interrupt consumer(producer) with a single ^c to cause a segmentation
	fault
Code:
    datatype state = S of state cont;

    fun  resume(S k: state) : state = callcc( fn  k':state cont => throw k (S k'))

    fun  initiate(p:state -> unit) = callcc( fn  k : state cont => (p(S k); S k))

    val  buf = ref 0;

    fun  producer(s:state):unit =
    let  val  n=ref 0
	val ccont : state ref = ref(resume s)
    in
	while true do (inc n; buf := !n; ccont := resume(!ccont))
    end

    fun  consumer(prod: state->unit) : unit =
    let  val pcont = ref(initiate prod) in
	while true do (pcont := resume(!pcont); print (!buf))
    end
Status: fixed in 0.56
--------------------------------------------------------------------------------
154. import smashing memory
Submitter: Benjamin Pierce, CMU (bcp@cs.cmu.edu)
Date: 11/34/89
Version: 0.41
System: Sun3/SunOS 3.5.2
Problem: import seems to be smashing memory
Comments:
    I've included a minimal version of program that exercises this bug on
    my machine.  Slightly different versions give different incorrect
    results, or simply fail with bus errors.  Removing the first line of
    tconst.sml (the import of globals, which is never used here) gives the
    correct answer.
Transcript:
    Standard ML of New Jersey, Version 0.41, 25 October 1989
    val it = () : unit
    - use "main.sml";
    [opening main.sml]
    val it = () : unit
    [reading checker.sml]
      [reading tconst.sml]
	[reading globals.sml]
	[closing globals.sml]
	[writing globals.bin... done]
      [closing tconst.sml]
      [writing tconst.bin... done]
    [closing checker.sml]
    [writing checker.bin... done]
    signature GLOBALS
    signature CHECKER
    signature TCONST
    functor TConstFun : <sig>
    functor GlobalsFun : <sig>
    functor CheckerFun : <sig>
    structure TConst
    val it = "\000\^VG\200" : ?.t		     <--- Should be "int"
    [closing main.sml]
    val it = () : unit
    - 
Code:
    (* ------------------------  globals.sml: ---------------------- *)
    signature GLOBALS =
    sig
      val member: ''a -> ''a list -> bool
    end

    functor GlobalsFun() : GLOBALS =
    struct
      fun member x [] = false
        | member x (y::l) = (x=y) orelse (member x l)
    end

    (* ------------------------  tconst.sml: ---------------------- *)
    import "globals";

    signature TCONST =
    sig
      type t
      val from_string: string -> t
    end

    functor TConstFun((*structure Globals:GLOBALS*)): TCONST =
    struct
	exception IllegalTConst of string
	type t = string
	fun member x [] = false
	  | member x (y::l) = (x=y) orelse (member x l)
	fun from_string s = if not (member s ["int", "real", "bool"])
			   then raise IllegalTConst(s)
			   else s
    end

    (* ------------------------  checker.sml: ---------------------- *)
    import "tconst";
    signature CHECKER = sig end (* CHECKER *)
    functor CheckerFun() : CHECKER = struct end (* CheckerFun *)

    (* ------------------------  main.sml: ---------------------- *)
    System.Control.Print.signatures := false;
    import "checker";
    (* structure Globals:GLOBALS = GlobalsFun(); *)
    structure TConst:TCONST = TConstFun((*structure Globals=Globals*));
    TConst.from_string "int";
Status: fixed in 0.49
--------------------------------------------------------------------------------
155. Compiler bug caused by of missing structure
Submitter: Benjamin Pierce (bcp@cs.cmu.edu)
Date: 11/3/89
Version: 0.52
System: Sun3/SunOS
Problem: Missing structure component shows up later as compiler bug
Transcript:

    - use "bug155.sml";
    bug155.sml:16.1-18.3 Error: unmatched structure spec: A
    Error: Compiler bug: TypesUtil.lookTycPath.2

Code: (bug155.sml)

signature S1 =
sig
  type t
end;

signature S2 =
sig
  structure A : S1
  val x : A.t
end;

structure B : S2 =
struct
  val x = 3
end;

Status: fixed in 0.54
--------------------------------------------------------------------------------
156. confusing parser error message
Submitter: dbm
Date: 4 Nov 1989
Version: 0.43
Problem:
    Misspelled constructor (VALbind instead of VARbind) in line

	  | scan ((VALbind _)::_) = ...

    causes inappropriate message:

    basics/typesutil.sml, line 74: Error: identifiers in clauses don't match
Status: fixed in 0.49
--------------------------------------------------------------------------------
157. nested imports corrupt memory (same as 154?)
Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK
Date: 3 Nov 89
Version: 0.39
System: Sun 3
Problem:
    I have had a good deal of trouble with transitive imports. Symptom is
    segmentation failure on first call of a procedure defined in a functor
    imported transitively.

    parser:
	    defines abstractsyntax, lexer, and parser functors

    codegen:
	    imports parser
	    defines code generator 

    main:
	    imports codegen
	    instantiates abstractsyntax, lexer, parser
	    crashes at first invocation of procedure defined in parser.

    When I remove the "import parser" from codegen, and 
    import it directly from main, then all is well.

    This actually arose in a student's system, and I haven't time to try it in
    smaller contexts.  Does the symptom sound familiar? If not, I can send the
    whole lot to you.
Status: fixed in 0.49
--------------------------------------------------------------------------------
158. sparc code generator problem
Submitter: Dale Miller, UPenn, dale@linc.cis.upenn.edu
Date: 22 Oct 89
Version: 0.39
System: Sun4 (unagi.cis.upenn.edu)
Problem: Error: Compiler bug: [SparcCoder.move]
Code: /pkg/ml.39/lib/lexgen/lexgen.sml
Transcript:
    Standard ML of New Jersey, Version 0.39, 8 September 1989
    val it = () : unit
    - use "/pkg/ml.39/lib/lexgen/lexgen.sml";
    [opening /pkg/ml.39/lib/lexgen/lexgen.sml]
    /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive
	    (nil,nil) => ...
	    (a :: a',b :: b') => ...
    /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive
	    1 => ...
	    2 => ...
	    3 => ...
    /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Warning: match not exhaustive
	    (tl,el) :: r => ...

    [Major collection... 68% used (1443980/2116924), 2760 msec]

    [Increasing heap to 4576k]

    [Major collection... 70% used (1724168/2441672), 3170 msec]

    [Increasing heap to 5520k]

    [Major collection... 88% used (2573912/2923048), 4620 msec]

    [Increasing heap to 8040k]

    [Major collection... 57% used (2395752/4198108), 4320 msec]

    [Major collection... 68% used (2819788/4139960), 5060 msec]

    [Increasing heap to 8368k]

    [Major collection... 78% used (3364372/4305528), 5940 msec]

    [Increasing heap to 10080k]
    /pkg/ml.39/lib/lexgen/lexgen.sml, line 1083: Error: Compiler bug: [SparcCoder.move]
    ?exception Syntax in SparcCM.storeindexl
    [closing /pkg/ml.39/lib/lexgen/lexgen.sml]
    -
Status: fixed in 0.43
--------------------------------------------------------------------------------
159. nested structure reference causes compiler bug
Submitter: Tom Murtagh, Rice University, tpm@rice.edu
Date: 10/20/89
Version: 0.38 and 0.39
System: Sun4/SunOS 4.0.3c and Sun3/SunOS 4.0.?
Problem: Compiler dies on reference to type from a nested structure
Description:
    I ran into another problem with the compiler.  This one does not
    appear to have anything to do with the port to SPARC.  I ran it
    on a Sparcstation using verion 0.38 and on a Sun3 running version
    0.39 (Bruce's copy) and it died on both.  It compiled without
    complaint on a Sun 3 running verions 0.33 (which is installed
    in the public local software directory here).

Code: (smaller.sml = /usr/sml/bugs/code/bug.159)
    signature SYMTAB =
	sig
	    type ident
	end

    signature LEX =
	sig
	    structure Symtab : SYMTAB

	    datatype lexeme =
		ID of Symtab.ident
	      | DELIM
	end

    structure Symtab =
	struct
	    type ident = string
	end

    functor lex( symtab : SYMTAB ) =
	struct
	    structure Symtab : SYMTAB = symtab
	    datatype lexeme =
		ID of Symtab.ident
	      | DELIM
	end

    structure Lex : LEX = lex( Symtab )

Transcript:
    % sml
    Standard ML of New Jersey, Version 0.38, 23 August 1989
    val it = () : unit
    - use "smaller.sml"
    = ;
    [opening smaller.sml]
    signature SYMTAB =
      sig
	type ident
      end
    signature LEX =
      sig
	structure Symtab : sig...end
	datatype lexeme
	  con DELIM : lexeme
	  con ID : Symtab.ident -> lexeme
      end
    structure Symtab :
      sig
	eqtype ident
      end
    functor lex : <sig>
    structure Lex :
      sig
	structure Symtab : sig...end
	datatype lexeme
	  con DELIM : lexeme
	  con ID : smaller.sml, line 31: Error: Compiler bug: TypesUtil.lookTycPath.
    1
    [closing smaller.sml]

Status: fixed in 0.43
--------------------------------------------------------------------------------
160. errorty fails to match sig spec 
Submitter: dbm
Date: 18 Oct 89
Version: 0.43
System: Sun 3
Problem: error type not matched in checking signature spec
Messages:
    typing/functor.sml, line 363: Error: value type in structure doesn't match
     signature spec
      name: abstractBody
      spec: Structure * stampsets -> Structure
      actual: Structure * error -> Structure
Status: fixed in 0.54
--------------------------------------------------------------------------------
161. nested functor calls
Submitter: Don Sannella <dts%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK>
Date: Tue, 17 Oct 89 18:29:27 BST
Version: 0.39
System: Sun 3
Problem: nested functor calls broken
Code:
    signature SIG =
	sig type t
	end;

    functor F(X : SIG) : SIG
	= struct type t = X.t
	  end;

    (* Replacing output signature by its definition: no problem *)
    functor F'(X : SIG) : sig type t end
	= struct type t = X.t
	  end;

    functor G(X : SIG) : SIG
	= struct type t = X.t
	  end;

    functor H(X : SIG) : SIG = G(F(X));

    (* Replacing output signature by its definition: fails with exception Bind *)
    functor H'(X : SIG) : sig type t end = G(F(X));
    signature SIG =
	sig type t
	end;

    functor F(X : SIG) : SIG
	= struct type t = X.t
	  end;

    (* Replacing output signature by its definition: no problem *)
    functor F'(X : SIG) : sig type t end
	= struct type t = X.t
	  end;

    functor G(X : SIG) : SIG
	= struct type t = X.t
	  end;

    functor H(X : SIG) : SIG = G(F(X));

    (* Replacing output signature by its definition: fails with exception Bind *)
    functor H'(X : SIG) : sig type t end = G(F(X));
Status: fixed in 0.43
--------------------------------------------------------------------------------
162. ByteArray subscript exception expected
Submitter: 	Jawahar Malhotra, Meta Software Corp., 
			malhotra%metasoft@bbn.com
Date:		10/17/89
Version: 	0.33
System: 	Sun OS 3.5
Problem: 	ByteArray.extract doesn't raise Subscript exception when I
			think it should.
Code:		
			val ba = ByteArray.array(4,0);
			
			(* I feel that the following SHOULD raise an exception *)
			ByteArray.extract(ba,4,0);	

			(* the following two statements CORRECTLY raise exceptions *)

			ByteArray.extract(ba,5,0);
			ByteArray.sub(ba,4);
Status: not a bug
--------------------------------------------------------------------------------
163. function definition syntax
Submitter: Andy Gordon, Cambridge University, adg@cl.cam.ac.uk
Date: Mon Oct 16 15:26:44 1989
Version: Version 0.33, 1 April 1989
System: Sun
Problem: another strange function definition
Code:
    fun cps-fact n k = cps-fact n k;
Messages:
    Error: Compiler bug: generalizeTy -- bad arg
      fact : 'S -> 'T -> undef
Comments:
Like in bug 73, I was mistakenly trying to define a function whose identifier
contained a hyphen, but this time the compiler complains of a Compiler bug.

Status: fixed in 0.54
--------------------------------------------------------------------------------
164. NS32 in makeml
Submitter: Allan E. Johannesen, wpi, aej@wpi.wpi.edu
Date: 13-Oct-1989
Version: 0.39, maybe.  That was the number in the README
System: Encore
Problem: makeml error
Code: makeml -encore
Messages: makeml: must specify machine type
Comments:

please put NS32 in $MACHINE case of makeml

maybe:

	NS32)
		if test "$OPSYS" != BSD
		then
			echo "makeml: bad os ($OPSYS) for encore"
			exit 1
		fi
		if test -z "$MO"
		then
			MO="../mo.encore"
		fi
		MODULE="$MODULEKIND"Encore
	;;

Status: no support for NS32, unfortunately
--------------------------------------------------------------------------------
165. NS32 problem in export.c
Submitter: Allan E. Johannesen, wpi, aej@wpi.wpi.edu
Date: 13-Oct-1989
Version: 0.39, maybe.  That was the number in the README
System: Encore
Problem: compile error
Code: makeml -encore
Messages: "export.c", line 108: Undefined member:  a_syms
Comments:

please change:

#ifndef NS32
    E.a_syms = 0;
#endif NS32
    E.a_syms = 0;

to:

#ifndef NS32
    E.a_syms = 0;
#endif NS32

Status: no support for NS32, unfortunately
--------------------------------------------------------------------------------
166. sparc code generator
Submitter: Konrad Slind <slind%calgary.cdn@relay.CDNnet.CA>
    (also Soren Christensen, Aarhus, schristensen@daimi.dk)
Date: 13 Oct 89  0:52 -0600
Problem:
  On the Sparcstation 1, under SunOS 4.0.3c, I get the following error:

    $ sml4
    Standard ML of New Jersey, Version 0.39, 8 September 1989
    val it = () : unit
    - val z = ref " ";
    val z = ref " " : string ref
    - z := " ";
    Error: Compiler bug: [SparcCoder.move]
    ?exception Syntax in SparcCM.storeindexl
    - z := "\n";
    Illegal instruction - core dumped
    $ 

  On just a regular old Sun4, under SunOS 4.0.3_Export, the above runs 
  correctly.
Status: fixed in 0.43
--------------------------------------------------------------------------------
167. repeated bound type variables in type declaration
Submitter: Nick Rothwell
Date: 5 Oct 89
Version: 0.39?
System: Sun 3
Problem: multiple binding occurences of type variable accepted
Code:
        - datatype ('a, 'a, 'a) T = A of 'a | B of 'a;
        datatype ('a,'b,'c)  T
        con A : 'a -> ('a,'b,'c) T
        con B : 'a -> ('a,'b,'c) T
Status: fixed in 0.54
--------------------------------------------------------------------------------
168. profiling on sparc
Submitter: Tom Murtagh ( tpm@rice.edu)
Date: Oct 4, 1989
Version: 0.38
System: Sun4/SunOS 4.0.3c
Problem: unhandled exception Match in codegenerator when Profiling enabled

I stumbled across what appears to be another problem in the Sparc code
generator.  It seems to fail when any function is compiled with
profiling enabled.  This time I do have a minimal code fragment:

% sml
Standard ML of New Jersey, Version 0.38, 23 August 1989
val it = () : unit
-  System.Control.Profile.profiling := true;
val it = () : unit
- (fn x => x);
?exception Match in SparcCM.storeindexl
uncaught exception Match

Status: fixed in 0.43 (?)
--------------------------------------------------------------------------------
169. inferring eqtypes in signatures
Submitter: Randy Pollack <rap%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK>
Date: Wed, 27 Sep 89
Problem: NJML (V0.39) is too liberal in inferring eqtypes in signatures
Code:
    - functor F() = struct abstype t = E with val mk_t = E end end;
    functor F : <sig>
    - structure f = F();
    structure f :
      sig
	eqtype t            (*** incorrect ***)
	val mk_t : t
      end

    however:

    - structure f = struct abstype t = E with val mk_t = E end end;
    structure f :
      sig
	type t              (*** correct ***)
	val mk_t : t
      end
Priority: A
Status: fixed in 0.52
--------------------------------------------------------------------------------
170.  error in makeml script 
Submitter: sufrin%prg.oxford.ac.uk@NSFnet-Relay.AC.UK
Date: Wed Sep 27
Transcript:
26 % makeml -sun3 -ionly -o smli -m 3 
(cd runtime; make clean)
rm -f *.o lint.out prim.s linkdata allmo.s
rm -f mo
ln -s ../mo.m68 mo
(cd runtime; rm -f run allmo.o)
(cd runtime; make MACHINE=M68 linkdata)
cc -O  -DM68  -o linkdata linkdata.c
runtime/linkdata [runtime/IntNull.mos] > runtime/allmo.o
(cd runtime; make MACHINE=M68 'DEFS= -DSUN3 -DSUN3 -DBSD' 'CFL=-n -Bstatic -f68881' 'ASMBLR=as')
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  run.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  gc.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  callgc.c
cc: Warning: Obsolete option -B
/lib/cpp -DM68 -DSUN3 -DSUN3 -DBSD M68.prim.s > prim.s
as -o prim.o prim.s
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  prof.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  export.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  objects.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  cstruct.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD  -mc68020 -c  trace.c
cc: Warning: Obsolete option -B
cc -O -n -Bstatic -f68881 -DM68 -DSUN3 -DSUN3 -DBSD -o run run.o gc.o callgc.o prim.o prof.o export.o objects.o cstruct.o trace.o allmo.o
cc: Warning: Obsolete option -B
_Loader: ld: allmo.o: multiply defined
*** Error code 2
make: Fatal error: Command failed for target `run'
echo (System.Control.interp := true; exportML "smli"; output std_out System.version; output std_out "\n"); | runtime/run -m 3 -r 20 -h 2048 IntNull
makeml: runtime/run: cannot execute

Status: fixed (or else, old version of SunOS went away)
--------------------------------------------------------------------------------
171. illegal datatype declaration accepted
Submitter: Russ Green <rjg%lfcs.edinburgh.ac.uk@NSFnet-Relay.AC.UK>
Date: Tue, 26 Sep 89
Problem:
    New Jersey ML (version 0.39) accepts the following (illegal) declaration:

      datatype t = C1 | C1 of int

    (rule (30) of the version 3 language definition prohibits any two
    constructors from having the same identifier)
Priority: A
Status: fixed in 0.52
--------------------------------------------------------------------------------
172. functor subscript error
Submitter: Simon Finn <simon%abstract-hardware-ltd.co.uk@NSFnet-Relay.AC.UK>
Date: Tue, 26 Sep 89
Problem:
The following fragment breaks NJML (v0.39)

    signature SIG1 =
    sig
      type s
    end;

    signature SIG2 =
    sig
      type t
      val x : t

      structure Sub : 
      sig
	val f : t -> t
      end;
    end;

    functor F (structure Struct1 : SIG1
	       structure Struct2 : SIG2) =
    struct
      val fx = Struct2.Sub.f Struct2.x;
    end;

Messages:

    = = = Error: operator and operand don't agree (tycon mismatch)
      operator domain: ?.t
      operand:         ?.t
      in expression:
	f x
    = Error: Compiler bug: abstractType

Comment:
    Almost any perturbation of the above seems to make the bug disappear, e.g.
    (1) removing "structure Struct1 : SIG1"
    (2) or removing "type s" from SIG1
    (3) or taking "f" out of "Sub" and putting it at the top level of "Struct2" 
  [dbm] behavior is different under 43d2.  It produces a lookTycPath subscript
  exception.

Priority: A
Status: fixed in 0.52
--------------------------------------------------------------------------------
173. Runbind
Submitter: Andrew Tolmach (apt@princeton.edu)
Date: 31 Aug 89
Version: ... 0.43
Problem:
    - val s = t;
    Error: unbound variable t
    - val s = t;
    Error: unbound variable t
    - s;
    uncaught exception Runbind
Priority: A
Status: fixed in 0.52
--------------------------------------------------------------------------------
174. import and types
Submitter:      Lars Bo Nielsen, Aalborg University, Strandvejen 19,
		9000 Aalborg, DENMARK.
		Email : lbn@iesd.auc.dk

Date:		Dec. 4 - 1989

Version:        0.43

System:         Sun 3/260 -- SunOs 4.0.1
		Sun Sparc -- SunOs 4.0.3c		

Severity:       I think this is VERY critical.

Problem:        Types of values in Functors is treated differently when
		imported and used. (Sorry hard to explain, see Code and
		Transcript).
		My code that compiled without problem with version 0.42,
		DIDN't compile under 0.43.

Code: Refered to as file: pop.sml
=================================
signature ASig =
    sig
	datatype POP = a | b
    end

signature BSig =
    sig
	structure DT : ASig
	val f : DT.POP -> unit
    end

functor AFun () : ASig =
    struct
	datatype POP = a | b
    end

functor BFun (structure DT : ASig) : BSig =
    struct
	structure DT = DT
	open DT
	val f = fn _ => output std_out "Is Running\n"
    end


Transcript: NOTE "<--" are my notes
===================================

Standard ML of New Jersey, Version 0.43, 27 November 1989
val it = () : unit
- use "pop.sml";
[opening pop.sml]			<-- USE the file
signature ASig =
  sig
    datatype POP
      con a : POP
      con b : POP
  end
signature BSig =
  sig
    structure DT : sig...end
    val f : DT.POP -> unit
  end
functor AFun : <sig>
functor BFun : <sig>
[closing pop.sml]
val it = () : unit
- structure A = AFun();
structure A :
  sig
    datatype POP
      con a : ?.POP
      con b : ?.POP
  end
- structure B = BFun ( structure DT = A);
structure B :
  sig
    structure DT : sig...end
    val f : A.POP -> unit			<--- A.POP -> unit
  end
- open A;
type  POP = POP
- val test = a;
val test = a : POP
- B.f test;
Is Running
val it = () : unit
- 
- 
- 
- import "pop";
[reading pop.bin... done]			<--- IMPORT the file
signature ASig =
  sig
    datatype POP
      con a : POP
      con b : POP
  end
signature BSig =
  sig
    structure DT : sig...end
    val f : DT.POP -> unit
  end
functor AFun : <sig>
functor BFun : <sig>
- structure A = AFun();
structure A :
  sig
    datatype POP
      con a : ?.POP
      con b : ?.POP
  end
- structure B = BFun ( structure DT = A);
structure B :
  sig
    structure DT : sig...end
    val f : ?.POP -> unit			<-- ?.POP -> unit
  end
- open A;
type  POP = POP
- val test = a;
val test = a : POP
- B.f test;
Error: operator and operand don't agree (tycon mismatch)
  operator domain: ?.POP
  operand:         POP
  in expression:
    B.f test
- 
Comments:	I changed yesterday (Dec 3) from 0.42 to 0.43, and I have 
		been trying all day (Dec 4) to solve my problem, until I
		made the little test above. During the solving periode I also
		had a lot of:

		    ../file, line xxx: Error: structure sharing violation

		In that periode I was using "import", not "use". These 
		error messages may show up to be caused by the same bug.

Fix: 		Sorry, I'm not able to fix it. But I hope my example have 
		given you enough input to track down the bug.
Status: fixed in 0.53
------------------------------------------------------------------------------
175. redundant module loading
Submitter:      Tom Gordon, thomas@gmdzi.uucp
Date:           6 Mar 90
Version:        0.44
System:         Sparc, Sun OS
Severity:       minor
Problem:        The module loader reloads functors and signatures
which have already been loaded. This drastically slows down the edit,
test, debug cycle.  Shouldn't only those modules be reloaded which
depend on files which have been, or need to be, recompiled?
Status: a wish, not a bug (desideratum for sourcegroups)
------------------------------------------------------------------------------
176. include and sharing
Submitter: Nick
Date: 2/26/90
Version: 0.44
Problem:
Poly/ML accepts the following, New Jersey ML (44a) rejects it:

        signature INCLUDE_1 = sig  type Ty  val x: Ty  end
        signature INCLUDE_2 = sig  type Ty  val y: Ty  end

        signature BOTH =
          sig
            type T
            include INCLUDE_1 sharing type Ty = T
            include INCLUDE_2 sharing type Ty = T
          end

        functor F(Both: BOTH) =
          struct
            val _ = [Both.x, Both.y]
          end;
Comment: exact semantics of include not yet defined
Status: not a bug
--------------------------------------------------------------------------------
177. clinkdata on sun 3
Submitter: Dave
Date: 3/8/90
Version: 0.52
System: Sun3, SunOS 4.0.1
Problem: clinkdata doesn't work
Transcript:
    nun% makeml -sun3 -sunos -noclean
    rm -f mo
    ln -s ../mo.m68 mo
    (cd runtime; rm -f run allmo.o)
    (cd runtime; make -f Makefile MACHINE=M68 'DEFS= -DSUN3 -DBSD' clinkdata)
    cc -g  -DM68 -DSUN3 -DBSD -o clinkdata clinkdata.c
    runtime/clinkdata [runtime/IntM68.mos]
    as: error (runtime/allmo.s:4): Invalid op-code
    (cd runtime; make -f Makefile MACHINE=M68 'DEFS= -DSUN3 -DBSD' 'CFL=-n -Bstatic
    -f68881' 'ASMBLR=as' 'WARNPRIM=@:')
    cc -g -n -Bstatic -f68881 -DM68 -DSUN3 -DBSD -o run run.o gc.o callgc.o M68.dep.
    o prim.o prof.o export.o objects.o  cstruct.o errstrings.o allmo.o
    ld: allmo.o: bad string table index (pass 1)
    *** Error code 4
    make: Fatal error: Command failed for target `run'
    echo ( exportML "sml"; output std_out System.version; output std_out (chr 10) (*
     newline *)); | runtime/run -m 4096 -r 20 -h 2048 IntM68
    makeml: runtime/run: not found
Status: fixed in 0.56
--------------------------------------------------------------------------------
178. Missing NS32.dep.c, NS32k port not working
--------------------------------------------------------------------------------
179. compiler bug (783 in sigmatch)
Submitter: John Reppy
Date: 2/15/90
Version: 0.51
Transcript:
   - structure A = GG();  (* GG is unbound *)
   std_in:1.16-1.17 Error: unbound functor identifier: GG
   Error: Compiler bug: 783 in sigmatch
Comments: Have to create bogus functor
Status: fixed in 0.56
--------------------------------------------------------------------------------
180. "sharing violation" error messages not informative
Submitter: Nick
Date: 2/15/90
Version: 0.44
Problem:
    ... the diagnostic messages for sharing mismatches are not really
    useable: having a single message "structure sharing violation" for 100
    lines of nested functor applications is no use, and I often have to
    recompile the entire system in Poly/ML just to get more verbose
    diagnostics with the context of the offending functor application and
    the names of the offending structures/types.
Status: fixed before 0.65
--------------------------------------------------------------------------------
181. 8-bit characters not supported in strings
Submitter: Fritz Ruehr (krf@dip.eecs.umich.edu)
Date: 2/8/90
Version: 0.44
Problem:
    I am looking to read in 8 bit characters in SML-NJ.  I can get UNIX
    to pass 8 bits back & forth, and SML-NJ will PRINT strings containing
    escaped "8-bit characters" (i.e., \nnn) as honest 8-bit output, but for
    the life of me I cannot get it to READ 8-bit characters when i put them in
    a string (I get an "Ord exception").  Is this intended behavior?
    Is there any workaround (say, a switch I didn't notice?)?
Status: fixed in 0.54
--------------------------------------------------------------------------------
182. uncaught exception after exportFn
Submitter: Andy Koenig
Date: 1/31/90
Version: 0.49 (still in 0.52)
Problem: 
  Unwanted uncaught exception message printed after exportFn is called.
Messages:
    Standard ML of New Jersey, Version 0.49, 26 January 1990
    val it = () : unit
    - fun hello _ = print "hello world\n";
    val hello = fn : 'a -> unit
    - exportFn ("a.out", hello);

    [Major collection... 98% used (492360/498444), 3900 msec]

    [Major collection... 2% used (13020/494516), 100 msec]

    [Decreasing heap to 254k]
    uncaught exception SystemCall with "closed outstream"
Comments: this can be cosmetically improved, but resumption after
	an exportFn is not expected to be implemented
Status: fixed in 0.59
------------------------------------------------------------------------------
183. "raise" not synchronized with evaluation sequence
Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:           Jan 20, 1990
Version:        0.44, 4 December 1989
System:         VAX, 4.3 BSD (also Sun 3, 4.3 BSD)
Severity:       minor
Problem:        "raise" not properly synchronized to expression row evaluation
Code:           (raise e, s := 2);
Transcript:     - exception e;
                exception e
                - val s = ref 0;
                val s = ref 0 : int ref
                - (s := 1, raise e);
                uncaught exception e
                - s;
                val it = ref 1 : int ref        [OK, did assignment first]
                - (raise e, s := 2);
                uncaught exception e
                - s;
                val it = ref 2 : int ref        [did not raise e immediately]
                -
Comments:       This is pathological code, but the Standard does specify
                left-to-right evaluation of expression row components.
Status: fixed (in 0.50?)
------------------------------------------------------------------------------
184. bindings introduced by open are not printed
Submitter: Andy Koenig
Date: 1/30/90
Version: 0.52
Problem:
  After a top level open, the bindings introduced are not printed
Comment: may provide a separate capability for requesting printing of signatures
   and other static info.
Status: not a bug
--------------------------------------------------------------------------------
185. exportML size
Submitter: Soren Christensen,
           University of Aarhus, Computer Science Dep.,
           Denmark
           schristensen@daimi.dk
Date:      24 jan 90
Version:   0.44
System:    Sun4/280 / SunOS 4.0.1
Severity:  ???
Problem:
Ussualy I have build my application by declaring a number of structures,
this could be done using less than 45Mb of heapspace, even if I set the
the flags like:

 System.Control.CG.reducemore := 0;
 System.Control.CG.rounds := 10;
 System.Control.CG.bodysize := 20;

The system produced from an "exportML" of this takes up app. 3Mb.

>From "doc/optimize" I learned that the code could be optimized by
enclosing it in one structure. I did like:

structure whole :
  sig
   < ... >
  end =
struct
 <The usual stuff ..>
end;
open whole;

It meant that the heapsize had to be increased to 80 Mb and I had to reset
the above flags.

I observed a bug in the reporting of GC:
...
[Major collection... 76% used (18670576/24426980), 34260 msec]

[Increasing heap to 59632k]

[Major collection... -57% used (25033788/31118476), 44190 msec]

[Increasing heap to 68216k]

[Major collection... -35% used (30575468/34993364), 54880 msec]
...

The "-57%" should be "80%" and the "-35%" should be "87%".

But the main problem  is that the CG before the "exportML" only decreases
the heap to 49Mb, and then it stops with the message "export" - due to no
disk space (?)

Comments: (appel)  Setting these flags for optimization may cause the
code generator to generate very large output.  Use at your own risk.

Status: can't reproduce; the negative percent messages are fixed in 0.64
-------------------------------------------------------------------------------
186. type error matching against bogus tycon
Submitter: Dave
Date: 1/12/90
Version: 0.52?
Messages:
    Error: value type in structure doesn't match signature spec
      name: instantiate
      spec: Basics.tyvar * Basics.ty -> unit
      actual: ?.bogus * ?.bogus -> unit
Status: can't reproduce
--------------------------------------------------------------------------------
187. parsing clausal definitions with infix functions
Submitter: Mick Francis
Date: 1/11/90
Version: 0.44(?)
Problem:
    1) Infix function declarations using parentheses do not parse. E.g.
	    infix xxx;
	    fun (a xxx b)   = b; (* Will not compile *)
	    fun (a xxx b) c = c; (* Will not compile *)

    2) When an infix identifier appears as the first of more than 2 formal
       parameters in a function declaration, if the second formal parameter
       is an identifier, an attempt is made to declare a function with this
       name. E.g.
	    infix xxx;
	    fun a xxx b c = c;   (* Compiles function b ??? *)
	    fun a xxx nil c = c; (* Tries to bind nil - error *)

    Gamma% njml
    Standard ML of New Jersey, Version 0.44a, 13 December 1989
    val it = () : unit
    - infix xxx;
    - fun (a xxx b) y = y; (* Should work *)
    Error: expected EQUAL, found RPAREN
    Error: atomic expression expected, found RPAREN
    Error: declaration or expression expected, found RPAREN
    - fun (a xxx b) = b; (* Should work *)
    Error: expected EQUAL, found RPAREN
    Error: atomic expression expected, found RPAREN
    Error: declaration or expression expected, found RPAREN
    - fun a xxx b y = y; (* Shouldn't compile *)
    val b = fn : 'a -> 'a
    - fun a xxx nil d = d;
    Error: improper use of constructor nil in pattern
    Error: Compiler bug: generalizeTy -- bad arg
      xxx : 'S * 'T -> undef

    Incidentally, Poly/ML gets the following wrong :-
	infix xxx;
	fun a xxx b d = d;

    It gives the message :-
	Error- Constructor (b) has not been declared   Found near b(y)

    It appears to be looking for a pat, not an atpat on either side of the xxx.
Status: fixed in 0.52
--------------------------------------------------------------------------------
188. infinite loop parsing simple functor declaration
Submitter: Simon Finn
Version: 0.44
Problem:
  loops trying to compile the following definitions
Code:
    signature TRIVSIG = sig end;
    functor A(X : TRIVSIG) : TRIVSIG = X;
    functor B(X : TRIVSIG) : TRIVSIG = A(X);
Status: fixed in 0.50 or so
------------------------------------------------------------------------------
189. confusing error message for bad clausal syntax
Submitter: Carl Gunter
Date: 1/4/90
Version: 0.44/0.52
Problem:
  Parser error message is not as helpful as it could be.
Transcript
    - fun (f:('a pair -> int)) x = 2;
    std_in:3.5-3.24 Error: illegal function symbol in clause
Status: fixed 
--------------------------------------------------------------------------------
190. unclosed string in interactive system
Submitter:      Trevor
Date:           1/5/90
Version:        0.44
System:         SparcStation, SunOs
Severity:       no prob, bob
Problem:        error recovery on unclosed string in interactive system
Transcript:
- wf "/u/trevor/.login
= ";                    (* Shouldn't have done this *)
Error: unclosed string  (* but this warning came too late *)
= ;
Error: unclosed string
Error: operator is not a function
  operator: unit
  in expression:
    wf "" ""
-
Comments:       Guess I shouldn't have tried to close the string after
		I hit return.  But I should have seen an error message
		so I would know not to do this.  The error message
		came one line too late.
Comment by Appel:  The lexer always wants to see the first character of the
next token before processing the current token; this could be fixed
but it's not worth it.
Status: fixed in 0.52 (new parser)
--------------------------------------------------------------------------------
191. Real operators permuted
Submitter:      Peter Canning <canning@hplabs.hp.com>
Date:           2 January 1990
Version:        0.44
System:         Sun 3 running SUNOS 4.0
Severity:       critical
Problem:        Several functions in structure Real are incorrect
Comments:  order of operations in Real structure was wrong
Status: fixed in 0.47
--------------------------------------------------------------------------------
192. bad parsing
Submitter: John Reppy
Date: 1/6/90
Version: 0.44
Transcript:
  Standard ML of New Jersey, Version 0.44, 4 December 1989
  val it = () : unit
  - map fn c => (c, ord c);
  val it = fn : ('a -> 'b) -> 'a list -> 'b list
  val it = fn : string -> string * int
Status: fixed by new parser
--------------------------------------------------------------------------------
193. import types
Submitter: Nick Rothwell
Date: 1/5/90
Version: 0.44a (0.44 with import fix)
Problem:
   I've enclosed a bug in NJ SML 0.44a, based on a bug report I received
from people at HP. I've managed to narrow it down to a simple example.
It seems to be a strange interaction between the type import code of the
separate compilation mechanism, the functor typechecking, and the checking
of record types (of all things!). Unfortunately, I don't know anything about
how types are imported under separate compilation, so I can't take it much
further.
Transcript:
I enclose two files, A.sml and B.sml. B.sml is a simple script that imports
A. Try the following: use "B.sml" (so that A gets imported and compiled), and
then >exit the system<. Start another session and use "B.sml" again. You
should get the following error:

        B.sml, line 8: Error: operator and operand don't agree (tycon mismatch)
          operator domain: {X:'S}
          operand:         {X:int}
          in expression:
            FOO {X=3}
Code:
    *** A.sml ***
    signature A =
      sig
	datatype 'a Foo = FOO of {X: 'a}
	    (* Must be a record type to reproduce the bug. *)
      end;

    functor A(): A =        (* Must have sig constraint to reproduce the bug *)
      struct
	datatype 'a Foo = FOO of {X: 'a}
      end;

    *** B.sml ***
    import "A";

    structure ??? = A();    (*Needed to reproduce the bug*)

    functor F(structure A: A) =
      struct
	val _ = A.FOO{X=3}
      end;

Status: fixed in 0.54, fixed better in 0.57
--------------------------------------------------------------------------------
194. weak type variable syntax 
Submitter: David Tarditi
Date: 12/17/89
Version: 0.44?
Problem: 
    There seems to be one slight problem in the documentation on support
    for imperative type variables as described in the Standard.  I took
    the documentation to mean that '_a is an abbreviation for '1a.  This
    isn't true.  If you try the code at the bottom, you'll see this.
Code:
    (* Sample code:  The second declaration of y causes a type error *)
    val x = fn (a,b) => (ref a; ref (a b));
    val y = x : ('1a -> '1b) * '1a -> '1b ref;
    val y = x : ('1a -> '1b) * '_a -> '_b ref
Status: fixed in 0.54
--------------------------------------------------------------------------------
195. Compiler bug: abstractType
Submitter: John Reppy
Date: 2/12/89
Version: 0.28
Problem:
I got a compiler bug message when working on my code generator.  Unfortunately
I wasn't able to reproduce it in a small example.  When I fixed the type error,
the bug message went away.  I don't know if this is useful to you, but here it is:
Transcript:
    - use "sparc/sparccoder.sml";
    [opening sparc/sparccoder.sml]
    sparc/sparccoder.sml, line 195: Error: operator and operand don't agree (tyco
n mismatch)
    operator domain: register * reg_or_immed * register
      operand:         register * register * register
      in expression:
            emit_subcc (a,b,g0)
    sparc/sparccoder.sml, line 210: Error: Compiler bug: abstractType
    [closing sparc/sparccoder.sml]
Status: probably fixed in 0.54 (can't reproduce)
--------------------------------------------------------------------------------
196. Compiler bug: generalizeTy -- bad arg
Submitter: Andrew Appel
Date: 12/6/89
Version: 0.44
Problem:
The following program yields  Compiler bug: generalizeTy -- bad arg
in version 0.44.
Code:
signature COMPLEX =
sig
   type elem
   val complex: real*real -> elem
   val + : elem * elem -> elem
   val - : elem * elem -> elem
   val * : elem * elem -> elem
   val / : elem * elem -> elem
   val ~ : elem -> elem   
   val inv: elem -> elem
   val abs : elem -> real
   val conj : elem -> elem
   val cis: real -> elem
end

abstraction Complex : COMPLEX =
struct
  open Real
  type elem = real * real
  fun complex ri = ri
  val op + = fn ((a,b),(c,d)) => (a+c,b+d)
  and op - = fn ((a,b),(c,d)) => (a-c,b-d)
  and op * = fn ((a,b),(c,d)) => (a*c-b*d, a*d+b*c)
  and op / = fn ((a,b),(c,d)) => let val z = c*c+d*d
				  in ((a*c+b*d)/z, (b*c-a*d)/z)
				 end
  and inv = fn (a,b) => let val z = a*a+b*b in (a/z,b/z) end
  and ~ = fn (a,b) => (~a,~b)
  and abs = fn (a,b) => a*a+b*b
  and conj = fn (a,b) => (a,~b)
  and cis = fn t => (cos t, sin t)
end

signature FIELD =
sig
   type elem
   val zero: elem
   val one: elem
   val + : elem * elem -> elem
   val * : elem * elem -> elem
   val inv: elem -> elem
end

signature POLYNOMIAL =
sig
    structure F : FIELD
    type poly
    val x : poly
    val const : F.elem -> poly
    val * : poly * poly -> poly
    val + : poly * poly -> poly
    val ~ : poly -> poly
    val eval: poly -> F.elem -> F.elem
    val deriv: poly -> poly
end

functor Polynomial(F : FIELD) : POLYNOMIAL =
struct
  structure F=F
  type poly = F.elem list
  val x = [F.zero,F.one]
  fun const c = [c]
  fun []+a = a
    | a+[] = a
    | (a::b) + (c::d) = F.+(a,c)::(b+d)
  fun scalarmult(a,[]) = []
    | scalarmult(a,b::c) = a*b::scalarmult(a,c)
  fun []*a = []
    | a*[] = []
    | a::b*c = scalarmult(a,c) + (F.zero::(b*c))
  fun ~ [] = []
    | ~ (a::b) = F.~(a) :: ~(b)
  fun eval p x =
    let fun f([],z,sum) = sum
          | f(a::b,z,sum) = f(b,F.*(x,z),sum+F.*(a,z))
     in f(p,F.one,F.zero)
    end
  fun deriv [] = []
    | deriv a::r =
    let fun f(z,a::b) = F.*(z,a)::f(F.+(z,F.one),b)
     in f(F.one,r)
    end
end

abstraction P = Polynomial(Complex)

Status: fixed in 0.52
--------------------------------------------------------------------------------
197. exportFn size
Submitter:      Lars Bo Nielsen, Aalborg University, Strandvejen 19,
                9000 Aalborg, DENMARK.
                Email : lbn@iesd.auc.dk

Date:           Dec. 6 - 1989
Version:        0.43
System:         Sun 3/60 -- SunOs 4.0.3
Severity:       Depends on the the importness of the the noshare
                version of the compiler and exportFn

Problem:        I make standalone versions of the lex and yacc,
                included in the distribution. I use the following
                code, to make a standalone version of "smlyacc", and
                similar for my "smllex" (feeding it to the noshare
                version of sml):

                | use "load.sml";
                | loadAll();
                | open ParseGen;
                |
                | fun main (argv, env) =
                |     let
                |         val argc = length argv
                |         val prog = hd argv
                |     in
                |         (if (argc <> 2) then
                |             outputc std_out ("Usage: " ^ prog ^ " file\n")
                |          else
                |              let
                |                  val file = hd (tl argv)
                |              in
                |                   parseGen file
                |                   handle Io s =>
                |                       outputc std_out
                |                           (prog ^ ": Couldn't open file: "
                |                            ^ file ^ "\n")
                |              end;
                |              outputc std_out "\n")
                |     end;
                |
                | exportFn ("smlyacc", main);

                The problem then is this: When making "smllex"
                everything works fine, and I get (on Sun 3/60) a
                standalone version of 208K. But the "smlyacc" version,
                though it compiles fine and runs, on more than 2000K.

                I used the same procedure with version 0.39, and the
                standalone version of "smlyacc" then was 368K.

                It seems to me that when exporting "smlyacc", the
                runtime system isn't thrown away, as when "smllex"
                was generated.

Status:  fixed in 0.54
--------------------------------------------------------------------------------
198. printing exception specs in signatures
Submitter: John Reppy
Date: 12/2/89
Version: 0.43
Problem:
   nullary exceptions get printed as "of exn" in signatures
Transcript:
  Standard ML of New Jersey, Version 0.43, 27 November 1989
  val it = () : unit
  - signature S = sig exception Sync end;
  signature S =
    sig
      exception Sync of exn
    end
  - exception Sync;
  exception Sync
Status: fixed in 0.52
--------------------------------------------------------------------------------
199. Compiler bug after unbound signature
Submitter: John Reppy
Date: 12/1/89
Version: 0.43, 0.52
Problem:
   Missing signature causes Compiler bug error after unbound signature error.
Transcript:
    - signature SS = sig structure A : AA end;
    std_in:5.34-5.35 Error: unbound signature: AA
    Error: Compiler bug: ModUtil.shiftStamps.newEnv - bad arg
Status: fixed in 0.56
--------------------------------------------------------------------------------
200. large integer literals
Submitter: Peter Buneman
Date: 12/1/89
Version: 0.39
System: Sun 3? 
Transcript:
    Standard ML of New Jersey, Version 0.39, 8 September 1989
    val it = () : unit
    - val x = 400000000;
    val x = 400000000 : int
    - x + x;
    val it = 800000000 : int
    - val y = 800000000;
    val y = ~273741824 : int  (* problem *)
    - x+x;
    val it = 800000000 : int
    - x*x;
    uncaught exception Overflow
Status: fixed in 0.52 (on Sun 3 at least)
--------------------------------------------------------------------------------
201. funny tycon aliasing behavior
Submitter: John Reppy
Date: 8/18/89
Version: 0.33
Transcript
  Standard ML of New Jersey, Version 0.33, 1 April 1989
  val it = () : unit
  - structure A = struct datatype foo = Bar of int end
  = ;
  structure A :
    sig
      datatype foo
        con Bar : int -> foo
    end
  - structure B : sig datatype foo' = Bar of int end = struct
  = open A
  = type foo' = foo
  = end;
  structure B :
    sig
      datatype foo'
        con Bar : int -> A.foo
    end
Status: fixed in 0.56
--------------------------------------------------------------------------------
202. type error not caught?
Submitter: Norman Ramsey
Date: 8/28/89
Version: ?
Problem:
    I believe that the following file should generate a type error, but
    it doesn't.  In particular, the line val _ = begin_str "replicas"
    ufanout(c,chans) should force chans to be type 'a chan list when c is
    type 'a chan.
Code:
    datatype 'a chan = CHAN of 'a

    signature BADGUYS = sig
	val mkchan : unit -> '1a chan
	val ufanout : '2a chan * '2a chan list -> 'b
	val begin_str :  string -> ('a -> 'b) -> 'a -> unit
    end

    signature WONKY =  sig
	val ureplicas : int -> '2a chan -> '6b chan list
		    (* wrong! should be int -> '2a chan -> '2a chan list *)
      end

    functor buggy(bad:BADGUYS):WONKY = struct

    open bad

    fun ureplicas n c =     (* n unsynchronized copies of channel c *)
	let fun channels(l,0) = l
	      | channels(l,n) = channels(mkchan()::l,n-1)
	    val chans = channels(nil,n)
	    val _ = begin_str "replicas" ufanout(c,chans)
	in  chans
	end

    end
Transcript: (0.52)
  - use "code/bug.202";
  [opening code/bug.202]
  code/bug.202:16.36-28.3 Error: value type in structure doesn't match signature
   spec
    name: ureplicas
    spec:   int -> '2a chan -> '6b chan list
    actual: int -> '1a chan -> '6b chan list
Status: fixed in 0.56
--------------------------------------------------------------------------------
203. printing of infix specs in signatures
Submitter: Trevor Jim
Date: 4/3/89
Version: 0.32, 0.52
Problem:
  infix specs are printed with two precedence numbers
Transcript:
    - signature SS = sig infix 5 bar end;
    signature SS =
      sig
	infix 10 10 bar
      end
Status: fixed in 0.54
--------------------------------------------------------------------------------
204. constructors printed when not accessible
Submitter: Dave Berry
Date: 2/2/89
Version: 0.52
Problem:
  constructors of a datatype in a structure are printed in the structure
  signature even though they are masked out by a signature constraint.
Transcript:
  - signature S1 = sig type d end;
  signature S1 =
    sig
      type d
    end
  - structure A : S1 = struct datatype d = A | B of int end;
  structure A :
    sig
      datatype d
        con A : d
	con B : int -> d
    end
Status: fixed in 0.56
--------------------------------------------------------------------------------
205. performance problem with many opens in a structure
Submitter: Jawahar Malhotra
Problem:
Code:
structure A = struct (* 30 val declarations *) end
structure B,C,D... similar
structure S = struct open A B C D E F G end
Status: fixed in 0.58
------------------------------------------------------------------------------
206. unhelpful parser error message (new parser)
Submitter: Dave
Date: 3/15/90
Version: 0.52
Transcript:
    - structure A =
      struct
        val x = if true then if true then 1 else 2
      end;
    std_in:4.1 Error: syntax error found at END
    -
Comment: what we need is  %prefer ELSE 0, that is, the ability to give
a hint for the insertion of two tokens in a row.  Right now, %prefer can
only hint about single-token insertions.  This fix has to be done
in mlyacc.
Status: open
-------------------------------------------------------------------------------
207. uncaught tycStamp exception
Submitter: Nevin.Heintze@PROOF.ERGO.CS.CMU.EDU
Date: 4/3/90
Version: 0.44 (0.53)
Problem: tycStamp raised during compilation
Code: (file bug207.sml)
    signature SS =
    sig
      datatype t = B of t | A of t list
    end

    functor F(X:SS) =  
    struct
      fun f(X.B(v)) = (v :: nil = v :: nil) | f _ = false
    end
Transcript:
    Standard ML of New Jersey, Version 0.44, 4 December 1989
    val it = () : unit
    - use "bug.sml";
    [opening bug.sml]
    bug.sml, line 11: Error: Compiler bug: tycStamp
    equal: type = ?.ttt list
    [closing bug.sml]
    - 
Comments:
    The problem appears to be the typing of the equality test.
    It is sensitive to the use of lists, both in the datatype
    definition and the equality test.
Status: fixed in 0.56
-------------------------------------------------------------------------------
208. bug in optimizer causing bad free variable
Submitter: Appel & MacQueen
Date: 4/27/90
Version: 0.56
Problem: impossible error in cpsopt phase, on MIPS machine,
	 with default optimization settings
Code: 
     functor MipsCoder(val emit : 'a -> unit)  = struct
       fun needs _ = true
       fun pass now =
       let fun gen inst =
	      if now andalso needs() then ()
	      else if now
		 then let fun gen1() = gen(raise Match)
		       in  case inst of
			     NONE  => gen1()
			   | SOME b =>
			       let fun bc1f offset = ()
				   fun bc1t offset = ()
			       in  if inst=NONE then 
					(emit((if b then bc1t else bc1f)
						     inst); gen1()) 
				   else ()
			       end
		       end
		 else ()
       in  gen
       end
       val assemble  = pass true
     end

Comment: this can be avoided by setting closurestrategy to 2, which we now
         do; Trevor may fix this bug eventually.

Status: avoided in 0.60
-------------------------------------------------------------------------------
209. equality types and functors, again
Submitter: Appel & MacQueen
Date: 4/30/90
Version: 0.56
Problem:
    Problem in eqtypes/defineEqTycon/eqty.  failure when attempting to
    reevaluate equality properties of generative/defined tycons in functor body
    after functor is applied.
Code: 
    signature S1 = sig type t end;
    structure A = struct type t = int end;
    functor F(X : S1)  =  
    struct
      structure B = struct datatype s1 = K of X.t end
      type s = B.s1
    end;
    structure C = F(A);
Comments:  we've put in a warning message, and assumed a non-equality type
	when this happens.  (still causes impossible error in 0.56).
Status:	"fixed" by following the lead of the Definition and not recalculating
	equality properties on functor applications.
--------------------------------------------------------------------------------
210. sharing checking with fixed stamps
Submitter: Appel & MacQueen
Date: 5/3/90
Version: 0.56
Problem:
    Union exception is not caught when sharing specs try to identify two distinct
    types or structures (with differing fixed stamps).
Code:
    structure S = struct end;
    structure T = struct end;
    signature Q = sig sharing S=T end;
Comments:
    Easy to fix.  Just add a handler for the Union exception in Sharing.doSharing
    and produce and appropriate error message.
Status: fixed in 0.57
--------------------------------------------------------------------------------
211. Union exception processing correct sharing in functor body
Submitter: MacQueen
Date: 5/4/90
Version: 0.56
Problem:
    Union exception is raised in doSharing when processing correct sharing
    specs in a functor body.
Code: (* bug211.sml *)
    functor F(type t) =
    struct
      structure K =
      struct 
	type s = t
      end
      structure M : sig structure L : sig type s sharing type s = t end
			sharing L=K
		    end =
      struct
	structure L = K
      end
    end;

Comments:
    The bug occurs because the type definition shortcut (for "type s = t", s
    is made a copy (modulo path) of t) is not done when t has a bound stamp,
    as in the code above.  Here s is a DEFtyc tycon with a different stamp
    from t.
Status: fixed in 0.58
--------------------------------------------------------------------------------
212. polymorphic exception declarations
Submitter:      Dave Berry (for Jo Blishen) (submitted to ml-bugs)
Date:		5/11/90
Version:        0.56
Severity:       major
Problem:        rejects proper weak polymorphic type for locally declared exception
Code:
    fun f (l:'_a) = let exception E of '_a in (raise (E l)) handle E t => t end;
Comments:
    Worked in 0.44a.
Status: fixed in 0.58
    (suspect related bugs because of the way TyvarSet.union_tyvars is defined.)
--------------------------------------------------------------------------------
213. equality on int*int
Submitter: Soren Christensen,
           University of Aarhus, Computer Science Dep.,
           Denmark
           schristensen@daimi.dk
Date:      16 may 90
Version:   0.56
System:    Sun4/280 / SunOS 4.0.1
Severity:  Critical
Problem:   failure compiling equality on type int*int
Code:  (* filename: bug213.sml *)

       (3,3,) = (3,3);

Transcript:
    Standard ML of New Jersey, Version 0.56, 13 April 1990
    Warning: input and output are now uncurried, arithmetic exceptions
    are re-arranged, div and mod are different; see doc/NEWS
    val it = () : unit
    - use "fun";
    [opening fun]
    datatype 'a   $$$
    con $ : 'a -> 'a $$$
    con $$ : 'a $$$
    LOOKUP FAILS in close(FIX 2795 2799 2707 2996
    ) on 2927
    in environment:
    2792 2790 2791
    [closing fun]
    uncaught exception Match
    - val x = 5;
    Illegal instruction
Comments:
    [Christensen] It looks like the compiler is messed up after this error. It
    core-dumps parsing the next declaration.  Version 0.44 has no problem
    handling this declaration.

    [dbm] The code "(3,3) = (3,3);" reproduces the bug.  Haven't been able
    to reproduce the core dump.
Status: fixed in 0.58.  (bug was in codegen)
--------------------------------------------------------------------------------
214. Compiler bug: EnvAccess.lookPath when printing
Submitter: Frank Pfenning (Frank.Pfenning@proof.ergo.cs.cmu.edu
Date: 5/17/90
Version: 0.56
Severity: critical
Problem: Compiler bug: EnvAccess.lookPath occurs when printing a top-level result.
Code:
    signature TERM =
      sig
	datatype term =  Const of string
	     and varbind = Varbind of string * term
      end

    functor Term ( ) : TERM =
      struct
	datatype term = Const of string
	     and varbind = Varbind of string * term
      end

    signature BUG =
      sig
	structure Term : TERM
	type progentry
	val bug : progentry list
      end

    functor Bug ( structure Term : TERM ) : BUG =
      struct
	structure Term = Term
	open Term
	datatype progentry =
	  Progentry of string * Term.term * Term.varbind list * Term.term
	val bug =
	  [Progentry("test",Const "test",
		     [Varbind("v",Const("test"))],Const("test"))]
      end

    structure Term : TERM = Term ();
    structure Bug : BUG = Bug ( structure Term = Term );

    Bug.bug;

Status: fixed in 0.58
--------------------------------------------------------------------------------
215. sin gives incorrect values
Submitter:      Thomas M. Breuel (tmb@ai.mit.edu)
Date:		5/18/90
Version:        0.59
System:         SPARC/SunOS 4.0.3c
Severity:       major
Problem: sin function is incorrect
Transcript:
	(* SparcStation 1, SunOS 4.0 *)
	Standard ML of New Jersey, Version 0.56, 13 April 1990
	Warning: input and output are now uncurried, arithmetic exceptions
	are re-arranged, div and mod are different; see doc/NEWS
	val it = () : unit
	- sin(4.0);
	val it = ~0.756802495307928 : real
	- sin(5.0);
	val it = ~0.958924274663138 : real
	- sin(6.0);
	val it = 0.279415498198926 : real
	- (*     ^^^^^^^^^^^^^^^^^ this should be negative, since it is between pi and 2 pi *)

Comments:
        Probably someone transcribed the sin function from the Berkeley
	math library incorrectly in boot/math.sml.
Status: fixed in 0.58 (Appel)
--------------------------------------------------------------------------------
216. floating point on SPARC
Submitter:      tmb@ai.mit.edu
Date:           Sat May 19 04:52:35 EDT 1990
Version:        0.56
System:         Sun SS1, Sun OS 4.0.3
Severity:       critical
Problem:        floating point broken in Sparc compiler?!
Transcript:

(everything that begins with a TAB comes from an actual transcript)
  
	Standard ML of New Jersey, Version 0.56, 13 April 1990
	Warning: input and output are now uncurried, arithmetic exceptions
	are re-arranged, div and mod are different; see doc/NEWS
	val it = () : unit
	- fun ilist(from:int,to:int,step:int)
	=     f = if (from<to) then (f from)::ilist(from+step,to,step) f else [];
	val ilist = fn : int * int * int -> (int -> 'a) -> 'a list
	- ilist(0,10,1) (fn x => x);
	val it = [0,1,2,3,4,5,6,7,8,9] : int list
	- ilist(0,10,1) print;
	0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list

all is as it should be--so far

	- fun rlist(from:real,to:real,step:real) f =
	=     if (from<to) then (f from)::rlist(from+step,to,step) f else [];
	val rlist = fn : real * real * real -> (real -> 'a) -> 'a list

this is the same definition with different type constraints

	- rlist(0.0,10.0,1.0) (fn x => x);
	val it = [] : real list

???

	- rlist(0.0,10.0,1.0) (fn x => x);
	val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list

same expression, different result???

	- rlist(0.0,10.0,1.0) (fn x => x);
	val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list

now it seems to work...

	- rlist(0.0,10.0,1.0) print;
	0.0val it = [()] : (unit) list

but it still doesn't work with "print"

	- rlist(0.0,10.0,1.0) (fn x => x);
	val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] : real list
	- 

Comments:

These problems don't occur on the m68 version of SML. In fact,
the problem with "sin" that I reported previously also doesn't
occur with the m68 version.

Maybe this is an installation problem, but if it is, then there is
probably something wrong with the makeml script. The Sparc version
was generated with "makeml -sun4 -sunos" if I remember correctly.

Here is the transcript from a Sun-3:

	Standard ML of New Jersey, Version 0.56, 13 April 1990
	Warning: input and output are now uncurried, arithmetic exceptions
	are re-arranged, div and mod are different; see doc/NEWS
	val it = () : unit
	- [opening /tmp_mnt/home/vi/tmb/cad/bad.sml]
	val identity = fn : 'a -> 'a
	val ilist = fn : int * int * int -> (int -> 'a) -> 'a list
	val rlist = fn : real * real * real -> (real -> 'a) -> 'a list
	[closing /tmp_mnt/home/vi/tmb/cad/bad.sml]
	val it = () : unit

these are the same definitions as above

	- ilist(0,10,1) (fn x => x);
	val it = [0,1,2,3,4,5,6,7,8,9] : int list
	- ilist(0,10,1) print;
	0123456789val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list
	- rlist(0.0,10.0,1.0) (fn x => x);
	val it = [0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0] : real list
	- rlist(0.0,10.0,1.0) print;
	0.01.02.03.04.05.06.07.08.09.0val it = [(),(),(),(),(),(),(),(),(),()] : (unit) list
	- sin 6.0;
	val it = ~0.279415498198926 : real
	- sin 5.0;
	val it = ~0.958924274663138 : real
	- 

Status: fixed in 0.58 (Reppy)
--------------------------------------------------------------------------------
217. simultaneous opens
Submitter: Larry Paulson (lcp@lfcs.ed.ac.uk)
Date: 5/25/90
Version: 0.56
Severity: major
Problem: opening several structures simultaneously can result in Runbind
Code: code/bug217.sml
    structure A = struct val x = 3  end;
    structure B = struct structure A = A; end;
    open A B;
    x;
Comments:
   This works if "open A B;" is replaced with "open A; open B;"
Status: fixed in 0.59
--------------------------------------------------------------------------------
218. compiler bug after unbound variable
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: 5/26/90
Version: 0.57
Severity: major
Problem: Compiler bug: generalizeTy -- bad arg occurs after top level unbound var
Transcript:
  - x;
  std_in:2.1 Error: unbound variable x
  Error: Compiler bug: generalizeTy -- bad arg
Status: fixed in 0.59
--------------------------------------------------------------------------------
219. parsing layered patterns
Submitter: Andrew Appel
Date: 5/90
Version: 0.56 and later
Severity: minor
Problem: parsing of layered pattern is too liberal.  An atomic pattern is
  accepted where a variable is required by the Definition syntax.
Code:
  let val (x) as (y :: z) = [1,2] in x end
Comments:
  Seems to require nontrivial change to the mlyacc grammar
Status: open
--------------------------------------------------------------------------------
220. Match exception after error
Submitter: John Reppy
Date: 6/1/90
Version: 0.58
System: Sun 4
Severity: minor
Problem: uncaught exception Match after signature matching error
Code:
  signature S = sig
    type foo
    val f : int -> foo
  end
  
  structure Foo : S = struct
    datatype foo_t = Foo of int
    val f = Foo
  end

Transcript:
  xxx.sml:6.21-9.3 Error: unmatched type spec: foo
  xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec
    name: f
    spec:   int -> [closing xxx.sml]

  uncaught exception Match
  - 
Comment:
Now produces
    std_in:10.21-13.3 Error: unmatched type spec: foo
    std_in:10.21-13.3 Error: value type in structure doesn't match signature spec
      name: f
      spec:   int -> NULLtyc
      actual: int -> foo_t
The NULLtyc is undesirable.

Status: partially fixed (before 0.65)
--------------------------------------------------------------------------------
221. profiling broken
Submitter: Benjamin Pierce (Benjamin.Pierce%proof.ergo.cs.cmu.edu
Date: 5/22/1990
System: 0.56 (and later)
Problem:
  Profiling provides call counts bug not timings.  For separately compiled
  modules, profiling provides neither call counts nor timings.
Transcript:
 (1) for separately compiled code
 %time  cumsecs     #call   ms/call  name
            .00         0            (toplevel)
            .00         0            (gc)
            .00         0            (unprofiled)


 (2) for "used" code
 %time  cumsecs     #call   ms/call  name
            .00      2398     .0000  anon.AType.==.anon
            .00      2398     .0000  anon.AType.==
            .00      2051     .0000  anon.Id.==.anon
            .00      2051     .0000  anon.Id.==
            .00      1890     .0000  anon.AType.apply_rule.anon
	    [etc...]
Fix:
Some of the problems may be caused by handleprof() in runtime/signal.c
being braindamaged.  I changed it to be:

  SIGH_RET_TYPE handleprof ()
  {
    extern ML_val_t current0[];
    ML_val_t cur_barray = current0[1];
    cur_barray[1] = (unsigned int)INT_incr(cur_barray[1],1);
  }

and it seemed to work for simple examples.  However, I'm not too sure
that the times mean anything for larger examples.  Perhaps there's some
bad interaction with GC?
Status: fixed in 0.70
--------------------------------------------------------------------------------
222. equality on ref types
Submitter:      Larry Paulson <lcp@lfcs.edinburgh.ac.uk>
Date:		11/6/90
Version:        0.56, 0.59
Severity:       major
Problem:
    ref type not being recognized as unconditionally an equality type
Transcript:
    - fun silly x = (ref x = ref x);
    val silly = fn : ''1a -> bool
    - silly not;
    std_in:4.1-4.9 Error: operator and operand don't agree (equality type required)
      operator domain: ''0S
      operand:         bool -> bool
      in expression:
	silly not

    And anyway the type checker behaves inconsistently by admitting the
    following:

    - ref not = ref not;
    val it = false : bool
Status: fixed (before 0.65)
--------------------------------------------------------------------------------
223. nontty standard input and uncaught exceptions
Submitter:	KINOSHITA Yoshiki	yoshiki@etl.go.jp
Date:		4, June 1990
Version:	SML of NJ 0.56
System:		Sparc Station 330 (SUN4), SUN-OS 4.0.3 (generic version)
Severity:	major
Problem:	If the standard input is a pipe, the system ends
		abnormally after it sends an error message.
Code:		None.  The problem concerns with the interface to UNIX.
Transcript:
	% cat - | sml  
	Standard ML of New Jersey, Version 0.56, 13 April 1990 
	Warning: input and output are now uncurried, arithmetic exceptions 
	are re-arranged, div and mod are different; see doc/NEWS 
	val it = () : unit 
	- foo; 
	std_in:2.1-2.3 Error: unbound variable foo 
	uncaught exception Stop 
	^Z 
	Stopped  
	% jobs 
	[1]  + Stopped              cat - | 
	       Done                 sml 
	%

Comments:	This problem makes it impossible to use the system with
		its input sent through a UNIX filter.
  from jhr:
    You might call this a feature.  It appears that the person who wrote
    the top-level loop code (interact.sml), decided that exceptions
    should only be caught at the top-level loop when std_in is a tty
    (look at lines 292-309 in interact.sml).  The following work-around
    avoids the problem

      <jhr@rocky:76> cat - | sml
      Standard ML of New Jersey, Version 0.59, 4 June 1990
      Warning: input and output are now uncurried, arithmetic exceptions
      are re-arranged, div and mod are different; see doc/NEWS
      val it = () : unit
      - set_term_in(std_in, true);
      val it = () : unit
      - foo;
      std_in:3.1-3.3 Error: unbound variable foo
      - 1+2;
      val it = 3 : int
      - 

    But, maybe the code should change.  It isn't clear to me what the correct
    semantics are in this case.  This problem came up here at Cornell when
    Bill Aitken was using "rsh" to run sml on a remote machine.
Status: fixed in 0.65
--------------------------------------------------------------------------------
224. weakness 0 type variables in let declaration
Submitter:      Larry Paulson
Date:		6/4/90
Version:        0.56, 0.59
Severity:       major
Problem:
    A weakness 0 type variable should be admitted, but not generalized, in local
    declarations.
Transcript:     <transcript of session illustrating problem>
    - let val f = ref(fn x => x) in f := not; !f true end;
    std_in:1.9-1.26 Error: nongeneric weak type variable
      f : ('0Y -> '0Y) ref
    std_in:1.9-1.26 Error: nongeneric weak type variable
      f : ('0Y -> '0Y) ref
Comments:
    This worked in 0.44.
Status: fixed (before 0.65)
--------------------------------------------------------------------------------
225. import broken in 0.59
Submitter:   Lars Bo Nielsen <lbn@iesd.auc.dk>
Date:        Jun 5, 1990
Version:     Version 0.59
System:      Sparc/sunos
Severity:    critical
Problem:     import broken. A simple 'import "file"' doesn't work, if
             only 'file.sml' is present. If 'file.bin' is present it
             works.
	     I DIDN'T have this problem with version 0.56.
Transcript:  

   The following example shows the problem.

   SHELL% ll
   total 68
      2 calc.dsl             11 calc.grm.sml         31 calc.parser.sml
      3 calc.grm              1 calc.instr            2 calc.sml
      4 calc.grm.desc         2 calc.lex
      1 calc.grm.sig         11 calc.lex.sml
   SHELL% sml
   Standard ML of New Jersey, Version 0.59, 4 June 1990
   Warning: input and output are now uncurried, arithmetic exceptions
   are re-arranged, div and mod are different; see doc/NEWS
   val it = () : unit
   - import "calc.parser";

   uncaught exception SystemCall
   - ^Z
   Stopped
   SHELL% touch calc.parser.bin
   SHELL% fg
   sml
   - import "calc.parser";
   [reading calc.parser.bin... ]
   [calc.parser.bin is the wrong format; recompiling
   [closing calc.parser.bin]
   [reading calc.parser.sml]

   [Major collection... 69% used (1475096/2123360), 1700 msec]

   [Increasing heap to 4451k]

   ..... etc .....

Status: fixed in 0.60 (jhr)
--------------------------------------------------------------------------------
226. uncaught exception Match while printing type  (same as 220)
Submitter:      John Reppy
Date:		6/1/90
Version:        0.56
Severity:       major
Problem:
   Uncaught Match exception occurs when printing out the spec type in an error message.
Code:

  signature S = sig
    type foo
    val f : int -> foo
  end
  
  structure Foo : S = struct
    datatype foo_t = Foo of int
    val f = Foo
  end

Transcript:
  xxx.sml:6.21-9.3 Error: unmatched type spec: foo
  xxx.sml:6.21-9.3 Error: value type in structure doesn't match signature spec
    name: f
    spec:   int -> [closing xxx.sml]

  uncaught exception Match
  - 

Status: partially fixed (before 0.65)
--------------------------------------------------------------------------------
227. equality property of datatypes
Submitter: Brian Boutel (brian@comp.vuw.ac.nz)
Date: May 25 1990
Version: 0.56
System: Sun3/sunos and H-P workstation (More/bsd)
Severity: major
Problem: Equality test for recursive types may fail in various ways
 (similar to bug 45, reported fixed)

Description:
Given
datatype 'a d1 = c11 | c12 of ('a * 'a d1);
datatype 'a d2 = c21 | c22 of ('a d2 * 'a );
datatype    d3 = c31 | c32 of ( d3 * int);

a) c11 = c11 works correctly
b) c12(1,c11) = c12(1,c11) gets uncaught exception Match (* ok in 0.59 *)
c) c21 = c21 loops forever  (* in 0.59 as well *)
d) c22(c21,1) = c22(c21,1) gets uncaught exception Match (* ok in 0.59 *)
e) c31 = c31 works correctly
f) c32(c31,1) = c32(c31,1) gets uncaught exception Match (* ok in 0.59 *)

Transcript: (with System.Control.debugging := true)
b)
-  c12(1,c11) = c12(1,c11);
parse
semantics

BEFORE:
val it = = (c12 (1,c11),c12 (1,c11))

AFTER:
val it = = (c12 (1,c11),c12 (1,c11))

test: int d1
test: int d1
find: int d1
find-notfound
enter: int d1
test: int * int d1
find: int * int d1
find-notfound
enter: int * int d1
test: int
test: int
test: int d1
find: int d1
translate
reorder
convert
cpsopt
closure
LOOKUP FAILS in close(FIX 4146 4150
) on 4161
in environment:
4143 4141 4142
globalfix
spill
codegen
uncaught exception Match
-

c)
- c21 = c21;
parse
semantics

BEFORE:
val it = = (c21,c21)


AFTER:
val it = = (c21,c21)

test: ''S d2
test: ''S d2
find: ''S d2
find-notfound
enter: ''S d2
test: ''S d2 * ''S
find: ''S d2 * ''S
find-notfound
enter: ''S d2 * ''S
test: ''S d2
find: ''S d2
find-notfound
enter: ''S d2
test: ''S d2 * ''S
find: ''S d2 * ''S
find-notfound
enter: ''S d2 * ''S
test: ''S d2
find: ''S d2
find-notfound
.....

Status: fixed in 0.60
--------------------------------------------------------------------------------
228. string to real conversion
Submitter:      jubu@tub.UUCP or jubu@tub.BITNET (Juergen Buntrock TUB)
Date:           Fri Apr 27 14:12:10 MET DST 1990
Version:        0.44
System:         Sun4, SunOS Release 4.0.3c
Severity:       critical
Code:           and Transcript:

Script started on Fri Apr 27 13:49:54 1990
jubu@curry mlj/handel 1) cat bug.sml
exception bad_number;

fun string2real (s : string) = let
    val (fac,li) = case explode s of
        "-" :: li => (~1.0,li) |
        "+" :: li => (1.0,li) |
        li => (1.0,li)
    val (res,_) = (revfold (fn (c,(a,fac1)) => let
        val n = ord c - ord "0"
        in
        output std_out ""; (* comiler bug ! *)
        if fac1 > 0.0
        then
            if n < 0 orelse n > 9
            then raise bad_number
            else (a + fac1 * (real n),fac1/10.0)
        else if c = "."
        then (a,1.0/10.0)
        else
            if n < 0 orelse n > 9
            then raise bad_number
            else (10.0 * a + (real n),0.0)
        end) li (0.0,0.0))
    in
    res * fac
    end

fun string2real_bug (s : string) = let
    val (fac,li) = case explode s of
        "-" :: li => (~1.0,li) |
        "+" :: li => (1.0,li) |
        li => (1.0,li)
    val (res,_) = (revfold (fn (c,(a,fac1)) => let
        val n = ord c - ord "0"
        in
        if fac1 > 0.0
        then
            if n < 0 orelse n > 9
            then raise bad_number
            else (a + fac1 * (real n),fac1/10.0)
        else if c = "."
        then (a,1.0/10.0)
        else
            if n < 0 orelse n > 9
            then raise bad_number
            else (10.0 * a + (real n),0.0)
        end) li (0.0,0.0))
    in
    res * fac
    end


jubu@curry mlj/handel 2) sml
Standard ML of New Jersey, Version 0.44, 4 December 1989
val it = () : unit
- use"bug.sml";
[opening bug.sml]
exception bad_number
val string2real = fn : string -> real
val string2real_bug = fn : string -> real
[closing bug.sml]
val it = () : unit
- string2real "123.456";
val it = 123.456 : real
- string2real_bug "123.456";
val it = 12346.0 : real
- open System.Control.CG;
structure M68 :
  sig
    val trapv : bool ref
  end
val reducemore = ref 15 : int ref
val printit = ref false : bool ref
val knowngen = ref 12 : int ref
val etasplit = ref true : bool ref
val comment = ref false : bool ref
val knowncl = ref 0 : int ref
val scheduling = ref true : bool ref
val printsize = ref false : bool ref
val reduce = ref true : bool ref
val closureprint = ref false : bool ref
val stdgen = ref 64 : int ref
val alphac = ref true : bool ref
val profile = ref false : bool ref
val hoist = ref true : bool ref
val foldconst = ref true : bool ref
val tailrecur = ref true : bool ref
val path = ref false : bool ref
val rounds = ref 1 : int ref
val closureStrategy = ref 1 : int ref
val recordopt = ref true : bool ref
val bodysize = ref 0 : int ref
val tail = ref true : bool ref
-
script done on Fri Apr 27 13:55:57 1990

Comments:
   the Sun3 Compiler is correct
Status: fixed in 0.56
--------------------------------------------------------------------------------
229. uncaught Match after signature spec error
Submitter: Peter Buneman
Date: 4/21/89
Version: 0.59
Severity: major
Problem:
   Following code produces uncaught Match exception
Code:
    signature SS = sig type t1 val t2:t1 end;

    structure ss:SS =
      struct local
	       datatype t = T of int
	     in val t2 = T 3
	     end
      end;
Comment: 
Output in 0.65 is
    std_in:8.1-12.3 Error: unmatched type spec: t1
    std_in:8.1-12.3 Error: value type in structure doesn't match signature spec
      name: t2
      spec:   NULLtyc
      actual: ?.ss.t
NULLtyc for spec is undesirable (similar to 220,226 problem).

Status: partially fixed (before 0.65)
--------------------------------------------------------------------------------
230. printing reals on mips
Submitter:      David MacQueen, Andrew Tolmach
Date:		6/12/90
Version:        0.59
System:         MIPS, RISCos
Severity:       critical
Problem:
    Uncaught exception Overflow when printing real numbers at top level.  Infinite
    loop in other cases (e.g. code/bug230.sml).
Transcript:
    - 1.0;
    val it =
    uncaught exception Overflow
    -
Comment: works ok on Sun3 and Sun4.
	works ok on DECsystem (with MIPS chip) / Ultrix
Status: fixed in 0.64
--------------------------------------------------------------------------------
231. equality property of DEFtyc
Submitter:      Nick Rothwell
Date:		6/21/90
Version:        0.56?
Severity:       major
Problem:
  A type abbreviation for an abstract type admits equality.
Code:
    abstype A = A
    with
      type B = A
    end;

    fn (x: B) => (x=x);

Comments:
   The type name associated with A (and therefore with B) should be
   stripped of its equality attribute outside the "abstype".
Status: fixed in 0.69
--------------------------------------------------------------------------------
232. user bound type variable in exception declaration 
Submitter:      Jo Blishen, Nick Rothwell
Date:		6/20/90
Version:	0.59
Severity:       minor
Problem:
  User-bound tyvar is not generalized at val binding containing it.
Transcript:
  - fun f l = let exception E of '_a in (raise (E l)) handle E t => t end;
  std_in:2.30-2.32 Error: unbound tyvars in exception declaration
Comments:
  According to the Definition '_a should be considered bound at the outermost
  val (fun f l ...) where it is the type of the lambda-bound variable l.
Status: fixed in 0.65
--------------------------------------------------------------------------------
233. opening locally declared structure causes Runbind
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Wed Jun 20 17:21:17 BST 1990
Version:        0.56 (applies to 0.59 as well I believe)
System:         Sun3, SunOS 4.1
Severity:       You decide....
Problem:
  You cannot declare a local structure and open it.
Transcript:
    Standard ML of New Jersey, Version 0.56, 13 April 1990
    val it = () : unit
    - local
    =   structure Bug =
    =     struct
    =       val message = "Try to evaluate me !"
    =     end
    = in
    =   open Bug
    = end ;
    open Bug
    - message;
    uncaught exception Runbind
    - 
Status: fixed in 0.60
--------------------------------------------------------------------------------
234. Compiler Bug: abstractBody.abstractType 1
Submitter: deutsch@poly.polytechnique.fr.
   Alain Deutsch,
   Laboratoire d'Informatique de l'Ecole Polytechnique (LIX)
   91128 Palaiseau Cedex
   France.
Date: Tue Jun 19 11:04:05 MET DST 1990
Version: Standard ML of New Jersey, Version 0.56, 13 April 1990
System: Sun 3/60, SunOS Release 4.0_Export
Severity: major (?)
Problem: Compiler Bug: abstractBody.abstractType 1
Code: Too long, ommited.
Transcript:
   - use "/home/icsla/deutsch/ESTFM/basic_ev.sml";
   [opening /home/icsla/deutsch/ESTFM/basic_ev.sml]
   [reading Powerset.bin... done]
   signature FunctionLattice
   signature ProductLattice
   signature OrderedSet
   signature Lattice
   signature Product
   signature PartialFunction
   signature TotalFunction
   functor Powerset
   [reading HashTable.bin... done]
   signature arrayext
   functor HashTable
   functor arrayext
   [reading lattice.sig.bin... done]
   signature FunctionLattice
   signature ProductLattice
   signature OrderedSet
   signature Lattice
   signature Product
   signature PartialFunction
   signature TotalFunction
   [reading Syntax.sig.bin... done]
   signature Syntax
   [reading StrgHash.sig.bin... done]
   signature StrgHash
   [reading Error.sig.bin... done]
   signature Error
   [reading ListUtilities.sig.bin... 
   [Major collection... 66% used (2325300/3480644), 2680 msec]

   [Increasing heap to 7023k]
   done]
   signature ListUtilities
   [reading Io.sig.bin... done]
   signature Io
   [closing /home/icsla/deutsch/ESTFM/basic_ev.sml]
   /home/icsla/deutsch/ESTFM/basic_ev.sml:20.3 Compiler Bug: abstractBody.abstractType 1
   - 

Comments: the bug is not systematic, and hard to reproduce, this is why the
source code has been ommited, as I have not been able to isolate the faulty part
of the source.

Status: fixed in 0.65 (same as 261)
--------------------------------------------------------------------------------
235. repeated type variables in typdesc and datdesc
Submitter:      Don Sannella <dts@informatik.uni-Bremen.de>
Date:		6/13/90
Version:        0.44?
Severity:       major
Problem:
    The Definition of SML seems to allow repeated type variables in a typdesc and
    datdesc, making the following signatures legal:

    signature SIG1 =
	 sig
	    eqtype ('a,'a) t1
	    type ('a,'a) t2
	 end

    signature SIG2 =
	 sig
	    datatype ('a,'a) t3 = foo of 'a
	 end

    Section 2.9 forbids repeated variables in a typbind and datbind, but I don't
    see anything forbidding it in a typdesc or datdesc.  I assume below that the
    omission of a syntactic restriction here was intentional.

    Repeated type variables in a typdesc seem unproblematic if strange, since the
    semantics only looks at the number of variables.  SML-NJ accepts SIG1 above,
    and treats it the same as a signature without repeated type variables, which is
    correct.

    Repeated type variables in a datdesc are more of a problem, since the
    constructors refer to them.  According to the Definition, foo in SIG2 above
    gets type 'a -> ('a,'a) t3.  Both of the following structures then match SIG2:

    structure A =
	 struct
	    datatype ('a,'b) t3 = foo of 'a
	 end

    structure B =
	 struct
	    datatype ('a,'b) t3 = foo of 'b
	 end

    SML-NJ (version 0.44a) says foo : 'a -> ('a,'b) t3, which is wrong.  The result
    of this is that A matches SIG2 but B does not.  I don't know about Poly-SML,
    since I don't have it here.
Status: fixed in 0.65
--------------------------------------------------------------------------------
236. Mach problems in 0.59
Submitter:      David Tarditi
Date:		6/18/90
Version:        0.59
System:         Mach
Severity:       critical
Comments:
    I have installed version 0.59 on Vaxes, Suns, and Pmaxes running Mach.

    There were two problems:

    VAX.prim.s contained a reference to the variable maskSignals.
    The name should be _maskSignals instead.

    The file export.c should also include the file ml_os.h, which
    contains some definitions needed for Decstations running Mach.
Status: fixed in 0.60

--------------------------------------------------------------------------------
237. Can't parse most-negative integer constant
Submitter:      David Berry
Date:		6/5/90
Version:        0.56
System:         All
Severity:       mild
Comments:

- ~1073741823;
exception Overflow

- ~1073741822;
val it = ~1073741822: int

- it - 1;
val it = ~1073741823: int

Status: fixed in 0.60
--------------------------------------------------------------------------------
238. div is unreliable at extremes
Submitter:      Andrew Appel
Date:		7/5/90
Version:        0.56
System:         All
Severity:       mild
Comments:

- val a = ~1073741822 - 2;
  val a = ~1073741824: int
- a div 2;

uncaught exception Overflow;

Status: fixed in 0.60
--------------------------------------------------------------------------------
239. INCONSISTENT exception raised in sharing analysis
Submitter:      Nick
Date:		13 July
Version:        0.56, 0.59
System:         <irrelevant>
Severity:       Serious
Problem:        Internal exception raised in the typechecker during sharing
		analysis
Code:

	signature A =
	  sig
	    type A
	    datatype Foo = FOO of A
	  end;

	signature B = sig  type B  end;

	signature C = sig  datatype C = C of int -> int  end;

	functor XYZZY(structure A: A
		      structure B: B sharing type A.A = B.B
		      structure C: C sharing type C.C = B.B
		     ) =
	  struct
	  end;

Transcript:

	signature A =
	  sig
	    type A
	    datatype Foo
	      con FOO : A -> Foo
	  end
	signature B =
	  sig
	    type B
	  end
	signature C =
	  sig
	    datatype C
	      con C : (int -> int) -> C
	  end
	[closing Kit/foo.sml]
	uncaught exception INCONSISTENT
Status: fixed in 0.61 (dbm)
--------------------------------------------------------------------------------
240. concrete printing of abstype value
Submitter:      Allen Leung. allen@sbcs.sunysb.edu
Date:           July 12th, 1990
Version:        v59    4 June, 1990
System:         SUN 3 on bsd
Severity:       minor
Problem:        Toplevel printing of abstype is transparent.
Code:           - abstype Foo = Foo of int
                = with fun foo i = Foo i end
                = val bar = foo 0;
                > type Foo
                > val foo = fn : int -> Foo
                > val bar = Foo 0 : Foo    (* instead of - : Foo *)
                -
Transcript:     
Comments:       Is this a new feature of v59+?
                It does help debugging. 
Status: fixed in 0.64
--------------------------------------------------------------------------------
241. sharing constraint error ignored
Submitter:      David Turner
Date:           12 July '90
Version:        0.59
System:         Sun4
Severity:       Slightly irritating
Problem:        Ignores error in sharing constraint even though it
		obviously detects it.

Input:
        - signature S = sig  type t  end;

	- functor F
	    (structure A : S
	     structure B : S
	    	sharing type B.t = A.s) = struct end;

Output:
	Error: unbound type in structure: s
	functor F : <sig>
Comment:
  Nonstandard function used in doSharing to report the bug.
  In 0.65 error message is:
     std_in:9.6-11.23 Error: unbound type in structure: s
  This doesn't provide as much useful information as it should.  Error
  message should read something like "unbound type A.s in sharing spec".

Status: fixed in 0.65
-------------------------------------------------------------------------------
242. incorrect forward referencing allowed
Submitter:      Nick
Date:		12 July '90
Version:        0.56, 0.59
System:         Irrelevant
Severity:       Major (& Embarrassing?)
Problem:        Incorrect forward referencing when analysing SPECs in
		functor arguments.

Input:
	signature SIG = sig  type t  end

	functor F(structure STR1: sig type t end sharing type STR1.t = Foo.t
		    structure Foo: SIG
		   ) = struct end;

Output:
	functor F: <sig>

Status: fixed in 0.73
--------------------------------------------------------------------------------
243. include compiler bug
Submitter: Nick Rothwell <nick@lfcs.edinburgh.ac.uk>
Date: Thu, 5 Jul 90 17:09:30 BST
Version: 0.59
Problem:
  The following file produces the error

	Compiler bug: Parse.includeSig.newTyc.
Code:
(* This "batch" file has been generated from the original
   sources by MAKE. If you want to make alterations, make them
   to the originals, and execute Make.make_task again. *)

(*$DECTREE_DT*)
(* Just the bare datatype for decision trees. *)

signature DECTREE_DT =
  sig
    type lab
    type lvar
    type longvar
    type longcon
    type longexcon
    type scon
    type pat
    type type_info
    eqtype (*pah!*) RuleNum sharing type RuleNum = int
    type Decision
    type (''a, 'b) map

    datatype 'a option = NONE | SOME of 'a

    datatype DecisionTree =
        LAB_DECOMPOSE of {bind: lvar,
			  parent: lvar,
			  lab: lab,
			  child: DecisionTree,
			  info: type_info
			 }
      | CON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree}
      | EXCON_DECOMPOSE of {bind: lvar, parent: lvar, child: DecisionTree}

      | CON_SWITCH of {arg: lvar,
		       selections: (longcon, DecisionTree) map,
		       wildcard: DecisionTree option,
				(* An `option' because we may notice that all
				   the constructors are present. *)
		       info: type_info
		      }
      | SCON_SWITCH of {arg: lvar,
			selections: (scon, DecisionTree) map,
			wildcard: DecisionTree
		       }
      | EXCON_SWITCH of {arg: lvar,
			 selections: (longexcon * DecisionTree) list,
			 wildcard: DecisionTree
			}

      | END of {ruleNum: RuleNum,
		environment: (longvar, lvar) map
	       }

      | FAIL
  end;

(*$MATCH_COMPILER: DECTREE_DT*)

(* The match compiler interface; the actual match compiler is built from
   a number of sub-functors, but this top-level interface is the only one
   which the rest of the compiler cares about. Given a series of patterns,
   it returns a DecisionTree (which is essentially an abstract form of the
   final lambda-code), in which all the lvars for identifiers and temporaries
   have been generated. At each leaf of the decision tree, there's a
   single rule number (the rule reached by this series of decisions), and an
   environment from identifiers to lvars, which is used to compile the
   right-hand-side expression for this rule. Nice, huh? *)

signature MATCH_COMPILER =
  sig
    include DECTREE_DT

    val matchCompiler:
      lvar * pat list * {warnInexhaustive: bool, warnNoBindings: bool}
      -> DecisionTree			(* these flags are set when the
					   warnings are required. *)

    type StringTree
    val layoutDecisionTree: DecisionTree -> StringTree
  end;

Status: fixed in 0.69
-------------------------------------------------------------------------------
244. compiler bug on product of large integer constants on SPARC
Submitter:      Bennet Vance (bennet@cse.ogi.edu)
Date:		Jul  1, 1990
Version:        0.59
System:         Sun 4/60 - SunOS Release 4.0.3c
Severity:       minor
Problem:        compiler bug on large products of integer constants
Transcript:

	val it = () : unit
	- 2*268435455;
	val it = 536870910 : int
	- 2*268435456;
	Error: Compiler bug: [SparcCM.ashr]
Status: fixed in 0.61 (jhr)
--------------------------------------------------------------------------------
245. NeXT installation problem
Submitter:      Lyman Taylor ( respond to lyman@portia.stanford.edu )
Date:		07/12/90
Version:        0.56
System:         NeXT , 8M , hard disk , & OD  ( build done on OD )
Severity:       major
Problem:        install script does not excute
Code:           none
Transcript:    	following ouput of makeml ( machine name helen )

helen> makeml -next
makeml> (cd runtime; make clean)
rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.m68 mo
makeml> (cd runtime; rm -f run allmo.o)
makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT -DRUNTIME=\"runtime\"' linkdata)
cc -O  -DM68 -DBSD -DNeXT -DRUNTIME=\"runtime\" -o linkdata linkdata.c
makeml> runtime/linkdata [runtime/IntM68.mos]
runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
makeml> (cd runtime; make MACHINE=M68 'DEFS= -DBSD -DNeXT' CPP=/lib/cpp 'CFL=' 'AS=as')
cc -O  -DM68 -DBSD -DNeXT -c run.c
ml_os.h:113: can't find include file `sys/syscall.h'
*** Exit 1
Stop.

Comments:	I'm not skilled at development for the NeXT. I was just looking
		to compile the latest version of SMLNJ so I could try it out
		there is an older version ( 0.43 ) on the Sparcs around here
		but the Next allows me to dump all this onto an OD so noone 
		can complain about the space all the source is taking up.
			
Status: fixed in 0.59 (jhr)
--------------------------------------------------------------------------------
246. repeated import consumes too much memory
Submitter:      Peter Canning  <canning@hplabs.hp.com>
Date:		27 June 1990
Version:        0.56
System:         HP900S370 (m68030)  HP-UX 7.0
Severity:       major
Problem:        repeated use of the import facility causes the heap to grow
Comments:
    In particular, if I repeatedly modify a file, import the file, then run the
    program defined in the file (the standard edit/compile/debug loop), my sml
    image seems to grow (and never shink again).  When I was just using "use",
    sml would garbage collect freqently, but the process size would stay between
    4000 and 5000 Kbytes.  Using import (working on the same program), the
    process has grown as large as 11000 Kbytes.  It appears that for some reason
    some data related to importing/compiling files is not being reclaimed by the
    garbage collector.
Status: Fixed (defunct feature)
--------------------------------------------------------------------------------
247. close_out std_out
Submitter: Mark R. Leone  <mleone@cs.cmu.edu>
Date: Fri, 29 Jun 90 16:09:02 EDT
Version: 0.59
Problem:
  If standard output is closed, the top level exits ungracefully:
Transcript:
    [r.ergo]/usr/mleone/sml/hypo-pl> sml
    Standard ML of New Jersey, Version 0.59, 4 June 1990
    Warning: input and output are now uncurried, arithmetic exceptions
    are re-arranged, div and mod are different; see doc/NEWS
    val it = () : unit
    - close_out std_out;
    Uncaught exception Io with "output "<std_out>": closed outstream"
Status: not a bug
--------------------------------------------------------------------------------
248. abstract types are not abstract
Submitter:      Dave MacQueen
Date:		7/16/90
Version:        0.59 (0.57 and later)
Severity:       major
Problem:
   Abstract types defined by abstype declarations are not made abstract
  (i.e. converted from DATAtyc to ABStyc form), and their equality property
  is not reset to NO.  Equality properties of types defined in terms of the
  abstype are not recomputed (see bug 231.)
Comments:
  After the abstype body has been processed, the concrete form of the abstract
  types must be replaced by the abstract form throughout the 'signature' of the
  exported bindings (values, constructors, types).  Also equality properties
  of exported types have to be reevaluated.
  Currently, there is a function that attempts to transform the tycons in the
  type checker, but it affects only the abstract syntax, and not the static
  environment.  The problem results from the removal of the ref around tycons
  in 0.57.
Status: fixed in 0.64.
--------------------------------------------------------------------------------
249. separate compilation printing problems
Submitter:      Nick Rothwell <nick@lfcs.ed.ac.uk> (also Richard O'Neill)
Date:		7/5/90
Version:        0.59
Severity:       minor
Problem:
    0. If only one or other of the files exists (say, Foo.sml without Foo.bin
	or vice versa), the exception SystemCall gets raised.

    1. The error message

		[Foo.bin is in the wrong format; recompiling]

    seems to have lost its closing "]" in 0.59.

    2. The final bindings from a separately compiled module get
    printed on one line, as in:

    signature Asignature Bsignature Csignature D- 

    rather than

    signature A
    signature B
    etc.
Fix:  (Richard O'Neill)
    For some reason the function printBindingTbl in print/printdec.sml was changed
    from its form in release 0.56 to a slightly modified forn in 0.59. The new
    form is functionally equivalent appart from omiting to generate newlines.

    Fix (currently untried):

    Return printBindingTbl to it 0.56 form.
Status: fixed in 0.64(?)
--------------------------------------------------------------------------------
250. interpreter broken
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Tue Jul 17 12:24:19 BST 1990
Version:        0.59
System:         Sun3, SunOS 4.1
Severity:       Major
Problem:

In interpret mode, version 0.59 fails with no explanation when compiling a
grammar from mlyacc (slightly modified to use 'import'), whilst in compile
mode, the grammar is compiled correctly. Version 0.56 does not exhibit the same
problem.

This seems a significant problem since using compile mode takes significant
time and memory. Equally, I cannot use version 0.56 due to some of its bugs
which manifest themselves when compiling other modules.

I have not included the files as they are rather long (being an mlyacc 
generated parser and the relevant support files). I can supply you with a
uuencoded compressed tar archive of them all if you desire.

Transcript:

unix% sml
Standard ML of New Jersey, Version 0.59, 4 June 1990
- System.Control.interp;
val it = ref true : bool ref
- import "clean.grm";
[clean.grm.bin is out of date; recompiling]
[reading clean.grm.sml]
  [reading lib/token.sig.bin... done]
[closing clean.grm.sml]
IMPORT failed (compile-time exception: SystemCall)
- import "clean.grm";
[clean.grm.bin is out of date; recompiling]
[reading clean.grm.sml]
  [reading lib/token.sig.bin... done]
  [reading clean.grm.sig.bin... done]

[Major collection... 60% used (648480/1067380), 1900 msec]

[Major collection... 96% used (1015412/1055228), 3000 msec]

[Increasing heap to 3088k]

[Major collection... 96% used (1526764/1586468), 4740 msec]

[Increasing heap to 4640k]

[Major collection... 96% used (2287536/2378284), 7480 msec]

[Increasing heap to 6952k]

[Major collection...
[Increasing heap to 10528k]
 96% used (3515248/3635044), 11120 msec]

[Increasing heap to 10632k]
[closing clean.grm.sml]
IMPORT failed (compile-time exception: Cascade)
- ^D

unix% old-sml
Standard ML of New Jersey, Version 0.56, 13 April 1990
val it = () : unit
- System.Control.interp;
val it = ref true : bool ref
- import "clean.grm";
[clean.grm.bin is out of date; recompiling]
[reading clean.grm.sml]
  [reading lib/token.sig.bin... ]
  [lib/token.sig.bin is the wrong format; recompiling]
  [closing lib/token.sig.bin]
  [reading lib/token.sig.sml]
    [reading lib/lrtable.sig.bin... ]
    [lib/lrtable.sig.bin is the wrong format; recompiling]
    [closing lib/lrtable.sig.bin]
    [reading lib/lrtable.sig.sml]
    [writing lib/lrtable.sig.bin... done]
    [closing lib/lrtable.sig.sml]
  [writing lib/token.sig.bin... done]
  [closing lib/token.sig.sml]
  [reading clean.grm.sig.bin... ]
  [clean.grm.sig.bin is the wrong format; recompiling]
  [closing clean.grm.sig.bin]
  [reading clean.grm.sig.sml]
    [reading lib/parserdata.sig.bin... ]
    [lib/parserdata.sig.bin is the wrong format; recompiling]
    [closing lib/parserdata.sig.bin]
    [reading lib/parserdata.sig.sml]
      [reading lib/token.sig.bin... ]
      [import(s) of lib/token.sig are out of date; recompiling]
      [closing lib/token.sig.bin]
      [reading lib/token.sig.sml]
        [reading lib/lrtable.sig.bin... done]
      [writing lib/token.sig.bin... done]
      [closing lib/token.sig.sml]
      [reading lib/lrtable.sig.bin... done]
    [writing lib/parserdata.sig.bin... done]
    [closing lib/parserdata.sig.sml]
  [writing clean.grm.sig.bin... done]
  [closing clean.grm.sig.sml]


[Major collection... 66% used (1058292/1581868), 3360 msec]

[Increasing heap to 3249k]

[Major collection... 96% used (1629952/1687576), 5020 msec]

[Increasing heap to 4929k]

[Major collection... 96% used (2478864/2562240), 7800 msec]

[Increasing heap to 7481k]

[Major collection... 30% used (1226344/3978648), 4200 msec]

[Decreasing heap to 4153k]

[Major collection... 92% used (1982616/2147092), 6060 msec]

[Increasing heap to 6081k]

[Major collection... 85% used (2731764/3199400), 8480 msec]

[Increasing heap to 8593k]

[Major collection... 62% used (2809816/4478688), 9180 msec]

[Increasing heap to 8657k]

[Major collection... 60% used (2770384/4573952), 8920 msec]

[Major collection... 62% used (2804296/4452412), 8980 msec]

[Increasing heap to 8721k]

[Major collection... 67% used (3031468/4473120), 8700 msec]

[Increasing heap to 9033k]
[writing clean.grm.bin... done]
[closing clean.grm.sml]
signature Clean_TOKENS
signature TOKEN
signature PARSER_DATA
signature Clean_LRVALS
signature LR_TABLE
functor CleanLrValsFun
- ^D

unix% sml
Standard ML of New Jersey, Version 0.59, 4 June 1990
- System.Control.interp := false;
val it = () : unit
- import "clean.grm";
[reading clean.grm.bin... ]
[clean.grm.bin is the wrong format; recompiling
[closing clean.grm.bin]
[reading clean.grm.sml]
  [reading lib/token.sig.bin... ]
  [lib/token.sig.bin is the wrong format; recompiling
  [closing lib/token.sig.bin]
  [reading lib/token.sig.sml]
    [reading lib/lrtable.sig.bin... ]
    [lib/lrtable.sig.bin is the wrong format; recompiling
    [closing lib/lrtable.sig.bin]
    [reading lib/lrtable.sig.sml]
    [writing lib/lrtable.sig.bin... done]
    [closing lib/lrtable.sig.sml]
  [writing lib/token.sig.bin... done]
  [closing lib/token.sig.sml]
  [reading clean.grm.sig.bin... ]
  [clean.grm.sig.bin is the wrong format; recompiling
  [closing clean.grm.sig.bin]
  [reading clean.grm.sig.sml]
    [reading lib/parserdata.sig.bin... ]
    [lib/parserdata.sig.bin is the wrong format; recompiling
    [closing lib/parserdata.sig.bin]
    [reading lib/parserdata.sig.sml]
      [reading lib/token.sig.bin... done]
      [reading lib/lrtable.sig.bin... done]
    [writing lib/parserdata.sig.bin... done]
    [closing lib/parserdata.sig.sml]
  [writing clean.grm.sig.bin... done]
  [closing clean.grm.sig.sml]

[Major collection... 61% used (679180/1109552), 2060 msec]

[Increasing heap to 2240k]

[Major collection... 80% used (932040/1158752), 2780 msec]

[Increasing heap to 2848k]

[Major collection... 95% used (1403328/1463408), 4240 msec]

[Increasing heap to 4272k]

[Major collection... 96% used (2109420/2194020), 6680 msec]

[Increasing heap to 6408k]

[Major collection...
[Increasing heap to 9656k]
 96% used (3255168/3361612), 10700 msec]

[Increasing heap to 9824k]

[Major collection... 36% used (1914068/5201708), 6400 msec]

[Decreasing heap to 6208k]

[Major collection... 85% used (2811340/3298792), 8620 msec]

[Increasing heap to 8816k]

[Major collection... 61% used (2810740/4607236), 8320 msec]

[Major collection... 63% used (2882812/4569184), 8900 msec]

[Increasing heap to 8928k]

[Major collection... 57% used (2705236/4669212), 8360 msec]

[Major collection... 61% used (2854268/4612180), 8560 msec]
[writing clean.grm.bin... done]
[closing clean.grm.sml]
signature Clean_TOKENSsignature TOKENsignature PARSER_DATAsignature Clean_LRVALSsignature LR_TABLEfunctor CleanLrValsFun-

Comment: import and interpreter mode are currently incompatible

Status: not a bug
-------------------------------------------------------------------------------
251. omits tests for repeated bindings
Submitter:      Dave Berry db@lfcs.ed.ac.uk
Date:		18th July 1990
Version:        0.59
System:         All (I presume; actually tested on a Sun 3 with SunOS 4.0)
Severity:       minor
Problem:        omits tests for repeated bindings
Code:           

type t = int and t = string;

exception E and E;

val rec f = fn x => x + 1
and f = fn n => if n > 0 then 1 else n * f (n - 1);

Transcript:

- type t = int and t = string;
type  t = int
type  t = string

- exception E and E;
exception E
exception E

- val rec f = fn x => x + 1
= and f = fn n => if n > 0 then 1 else n * f (n - 1);
val f = fn : int -> int
val f = fn : int -> int

Comments:

I expect that few people would make these mistakes in "real"
code, but they might be more common when teaching.

The tests are made for repeated constructors in a datatype,
and in some (non-recursive?) value bindings, e.g.

- datatype a = A | A;
std_in:3.14-3.18 Error: duplicate constructor name

- val a = 1 and a = 2;
std_in:2.5-2.19 Error: duplicate variable-name `a' in pattern(s)

Page 9 is the relevant part of the definition.

Status: fixed in 0.65
--------------------------------------------------------------------------------
252. include broken in 0.59
Submitter:      Nick
Date:		17 July '90
Version:        0.59
System:         Irrelevant
Severity:       Major
Problem:        Inclusion of signatures with shared types: >Blam!<.
Code:

		signature SIG1 = sig  type ty sharing type ty = int  end;

		signature SIG2 = sig  include SIG1  end;

Transcript:

		signature SIG1 =
		  sig
		    eqtype ty
		  end
		Error: Compiler bug: Parse.includeSig.newTyc

Comments:	Works in 0.56 (which has different problems - see a previous
		report).
Status: fixed in 0.64
--------------------------------------------------------------------------------
253.  SML Dumping core compiling mlyacc with -pervshare
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Wed Jul 18 16:18:47 BST 1990
Version:        0.59
System:         Sun3/50, SunOS 4.1
Severity:       You decide...
Problem:

Attempting to compile mlyacc (as supplied with version 0.56 of SML of NJ) 
with a '-pervshare' version of SML of NJ 0.59 causes a Segmentation Fault.

This does not seem to happen with the sharable SML compiler.

I have the core dump if that would help...

Status: fixed sometime between 0.59 and 0.74
--------------------------------------------------------------------------------
254. failure to detect type error
Submitter:      Andrew Appel
Date:		7/23/90
Version:        0.60
Severity:       critical
Problem:        type error not detected
Code:
    signature SIG = sig
      type EA
      val fopt : ((EA * EA) -> unit) option
    end

    functor CPSgen(M: SIG) :  sig  end =
    struct
	val g = 
	    case M.fopt
	     of SOME f => let fun h x = f (x,x)
			   in h
			  end
	val x = g 2
    end
Comments:
   Caused by missing case in scan function in the definition of Unify.instantiate.
Status: fixed in 0.61 (dbm)
--------------------------------------------------------------------------------
255. space leak with redeclaration of variables
Submitter: John Reppy
Date:	   7/24/90
Version:   0.60
Severity:  major
Problem:
    I think that there is a space leak in the top-level loop/environment.
    If I keep redefining the same identifiers, the amount of live data
    grows, when it should be fairly constant.  I assume that the problem
    is that the top-level symbol table is holding onto something it shouldn't.
Transcript:
Here is a simple demonstration of the space leak (60 bytes/iteration):

  Standard ML of New Jersey, Version 0.60, 13 July 1990
  val it = () : unit
  - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end;

  [Major collection... 98% used (516680/526692), 610 msec]
  structure S :
    sig
    end
  - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end;

  [Major collection... 98% used (517100/525980), 550 msec]
  structure S :
    sig
    end
  - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end;

  [Major collection... 98% used (517160/526388), 550 msec]
  structure S :
    sig
    end
  - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end;

  [Major collection... 98% used (517220/526448), 550 msec]
  structure S :
    sig
    end
  - structure S = struct val _ = System.Unsafe.CInterface.gc 1 end;

  [Major collection... 98% used (517280/526508), 540 msec]
  structure S :
    sig
    end

Comment: (appel) This is the top-level line-number information, and
	 is a few bytes per line, regardless of size of defined structures.
Status: fixed in 0.65 (actually, it's now a 48-byte leak)
-------------------------------------------------------------------------------
256. mcopt compiler bug with improper function definition
Submitter: John Mitchell (jcm@iswim.stanford.edu)
Date:      7/24/90
Version:   0.60
Severity:  critical
Problem:
    Compiler bug "r_o in mcopt" raised as a result of improper clausal
    function definition.
Transcript:
    - datatype 'a stack = empty | stk of 'a *'a stack;
    datatype 'a   stack
    con empty : 'a stack
    con stk : 'a * 'a stack -> 'a stack
    - fun pop stk(e,s) = s;
    Error: Compiler bug: r_o in mcopt

    adding parens fixes the problem, so not serious as is:

    fun pop (stk (e,s)) = s;
    std_in:2.5-2.23 Warning: match not exhaustive
	    stk (e,s) => ...
    val pop = fn : 'a stack -> 'a stack

Submitter:      Sergio Antoy, antoy@vtodie.cs.vt.edu
Date:		8/9/90
Version:        SML of NJ version number 056
System:         DEC3100 V2.2 (Rev. 15)
Severity:       
Problem:        "using" following file sml generates "Compiler bug" msg
Code:
		datatype 'a Xlist
		  = Xnil
		  | Xcons of 'a * 'a Xlist
		  | Xappend of 'a Xlist * 'a Xlist;

		fun incr Xappend(Xnil,Xnil) = Xnil
		  | incr Xappend(Xnil,Xcons(a,b)) = Xcons(a,b);
Transcript:
		goliat[8]% sml
		Standard ML of New Jersey, Version 0.56, 13 April 1990
		Warning: input and output are now uncurried, arithmetic exceptions
		are re-arranged, div and mod are different; see doc/NEWS
		val it = () : unit
		- use "trans.sml";
		[opening trans.sml]
		datatype 'a   Xlist
		con Xappend : 'a Xlist * 'a Xlist -> 'a Xlist
		con Xcons : 'a * 'a Xlist -> 'a Xlist
		con Xnil : 'a Xlist
		Error: Compiler bug: r_o in mcopt
		[closing trans.sml]
		-
Status: fixed in 0.62?
--------------------------------------------------------------------------------
257. Compiler bug: EnvAccess.lookPath with imported functors (bug 214 again)
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Mon Jul 30 11:52:10 BST 1990
Version:        0,59, 0.60
System:         Sun3/180, SunOS 4.1
Severity:       Major
Problem:

Bug #214 ('Compiler bug: EnvAccess.lookPath occurs when printing a top level
result') has not been laid to rest, it still occurs with imported functors.

Transcript:

unix% cat > one.sml

functor classes () =
    struct
        datatype symbol_class = 
            DataClass of data_class
          | SpecialClass of special_class
            
        and data_class = Int | Real | Bool | String
        and special_class = Any | None
    end
^D
unix% cat > two.sml

signature classes =
    sig
        datatype symbol_class = 
            DataClass of data_class
          | SpecialClass of special_class
            
        and data_class = Int | Real | Bool | String
        and special_class = Any | None
    end

functor nodes ( structure Classes : classes ) =
    struct
        structure Classes = Classes
        local
            open Classes
        in
            datatype node =
              ClassNode of symbol_class
            | ValueNode of data_class
        end
    end
^D
unix% sml
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- import "one" "two";
[reading one.sml]
[writing one.bin... done]
[closing one.sml]
functor classes
[reading two.sml]
[writing two.bin... done]
[closing two.sml]
signature classes
functor nodes
- structure Classes = classes ()
= structure Nodes = nodes ( structure Classes = Classes )
= open Classes Nodes ;
structure Classes :
  sig
    datatype special_class
      con Any : special_class
      con None : special_class
    datatype symbol_class
      con DataClass : data_class -> symbol_class
      con SpecialClass : special_class -> symbol_class
    datatype data_class
      con Bool : data_class
      con Int : data_class
      con Real : data_class
      con String : data_class
  end
structure Nodes :
  sig
    structure Classes : sig...end
    datatype node
      con ClassNode : symbol_class -> node
      con ValueNode : data_class -> node
  end
open Classes Nodes
- ClassNode (DataClass Int);
val it = ClassNode Error: Compiler bug: EnvAccess.lookPath
- ValueNode Int;
val it = ValueNode Int : node
- ^D
unix% sml
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- app use ["one.sml","two.sml"];
[opening one.sml]
functor classes : <sig>
[closing one.sml]
[opening two.sml]
signature classes =
  sig
    datatype special_class
      con Any : special_class
      con None : special_class
    datatype symbol_class
      con DataClass : data_class -> symbol_class
      con SpecialClass : special_class -> symbol_class
    datatype data_class
      con Bool : data_class
      con Int : data_class
      con Real : data_class
      con String : data_class
  end
functor nodes : <sig>
[closing two.sml]
val it = () : unit
- structure Classes = classes ()
= structure Nodes = nodes ( structure Classes = Classes )
= open Classes Nodes ;
structure Classes :
  sig
    datatype special_class
      con Any : special_class
      con None : special_class
    datatype symbol_class
      con DataClass : data_class -> symbol_class
      con SpecialClass : special_class -> symbol_class
    datatype data_class
      con Bool : data_class
      con Int : data_class
      con Real : data_class
      con String : data_class
  end
structure Nodes :
  sig
    structure Classes : sig...end
    datatype node
      con ClassNode : symbol_class -> node
      con ValueNode : data_class -> node
  end
open Classes Nodes
- ClassNode (DataClass Int);
val it = ClassNode (DataClass Int) : node
- ValueNode Int;
val it = ValueNode Int : node
- ^D
--------------------------------------------------------------------------------
258. System.Directory.cd failure
Submitter: Dave MacQueen
Date: 8/15/90
Version: 0.63
Problem:
  System.Directory.cd applied to nonexistent directory name raises uncaught
  exception
Transcript:
    - System.Directory.cd "foo";
    uncaught exception SysError
    -
Status: fixed in 0.65
--------------------------------------------------------------------------------
259. uncaught exception Match compiling normperv.sml
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Tue Aug 14 10:04:21 BST 1990
Version:        0.63 (not in 0.62 or earlier)
System:         Sun3/180, SunOS 4.1
Severity:       Critical
Problem:

Version 0.63 has a new bug whereby it cannot compile dbguser/normperv.sml
This prevents creating the '-debug' version.

Transcript:

unix% sml
Standard ML of New Jersey, Version 0.63, 10 August 1990
val it = () : unit
- use "dbguser/normperv.sml";
[opening dbguser/normperv.sml]
[closing dbguser/normperv.sml]

uncaught exception Match
-

Comments:

Smlc, version 0.62, created the 680X0 '.mo' files from which a -pervshare
runtime system was built using gcc. This runtime system was then used to build
a normal and then a -debug system (which failed).

I've marked the severity as critical because it is a critical problem for this
version. For me however, its not so critical as I seem to be managing OK with
0.62.
Status: apparently fixed as of 0.75
--------------------------------------------------------------------------------
260. failure to raise overflow
Submitter: David.Tarditi@B.GP.CS.CMU.EDU
Date: Mon, 13 Aug 90 15:43:26 EDT
Version: 0.63?
Problem:
The following program should raise an Overflow exception on all
32-bit 2's complement machines but it doesn't:
-------
fun exp 0 = 1 | exp i = 2 * exp (i-1);

val a = exp 29;
val minint = ~a + ~a;

(* should raise overflow *)

val test = minint div ~1;
-------
An overflow exception was not raised in version 0.59 on a Sun 3 running
Mach emluating 4.3 BSD.  It was raised in version 0.59 on a MicroVax 3
running Mach emulating 4.3 BSD.

Comments:

This is the only case where overflow can occur in division.  It occurs
since MININT = -(MAXINT+1) in 2's complement.  Division of MININT by -1 
causes an overflow.

Status: fixed in 0.64
-------------------------------------------------------------------------------
261. Compiler Bug: abstractBody.abstractType 1 (assumed same as 234)
Submitter:	George Beshers, beshers@sun2.brc.uconn.edu
Date:		Aug 9, 1990
Version:	0.56, sparc
Severity:	Significant
Problem:	Compiler generates
	``Regex.sml:21.17 Compiler Bug: abstractBody.abstractType 1''
		Note: this is somewhat delicate to reproduce.  If you
		break the following into files and start a clean sml
		and do "use Regex.sml;" it consistently generates
		the error.  However, if you *repeat* the use Regex.sml
		it compiles (however I have a lingering suspision about
		the correctness of the code produced...).
		On one occasion I tried "using" all the files in
		sequence and that worked OK, at least the working
		parts of the module did.

		Also I have tried to cut parts of the Regex.sml
		file and reproduce the error but without success.
		In particular, the error is dependent on at least
		some of the code appearing later in the file.

Code:

(*---------------------------- Ordinal.sml ---------------------*)


signature ORD_RANGE =
  sig
    type elem
    val ord : elem -> int
    and de_ord : int -> elem
  end

functor NatFn() : ORD_RANGE =
  struct
    type elem = int
    fun ord x = x
    fun de_ord x = x
  end

functor CharFn() : ORD_RANGE =
  struct
    type elem = string
    val ord = String.ord
    val de_ord = chr
  end


(*------------------------ BitSet.sml ---------------------------*)


import "Ordinal";

signature BITSET =
  sig
    structure Elem : ORD_RANGE
    exception NoSuchElement
    type bitset
    val empty: bitset
    and	singleton : Elem.elem -> bitset
    and range : Elem.elem * Elem.elem -> bitset
    and setFromList : Elem.elem list -> bitset

    and	exists : Elem.elem -> bitset -> bool
    and union : bitset * bitset -> bitset
    and intersect : bitset * bitset -> bitset
    and difference : bitset * bitset -> bitset

    val isempty : bitset -> bool
    and eq : bitset * bitset -> bool
    and subset : bitset * bitset -> bool
    and subset': bitset * bitset -> bool

    val select : bitset * (Elem.elem -> bool) -> bitset
    val lowest : bitset -> Elem.elem
    val lowest' : bitset -> Elem.elem -> Elem.elem
    val highest : bitset -> Elem.elem
    val highest' : bitset -> Elem.elem -> Elem.elem
    val totOrder : bitset * bitset -> bool
    val forall : bitset -> Elem.elem list
    val makeString : bitset -> string
  end;

(* trivialized version *)
functor BitSetFn(Elem1 : ORD_RANGE) : BITSET =
  struct
    structure Elem = Elem1
    local
      open Elem Bits
      val bits_per_int = 30;
      val all_bits = 1073741823        (* 077777777777 *)
    in
      datatype bitset = BS of {lo : int, hi : int, setx : int array}
      val empty = BS{lo = 0, hi = ~1, setx = array(0, 0)}

      fun singleton x = empty

      fun range(l, h) = empty

      fun exists x (BS{lo, hi, setx}) = false

      fun union(set1, set2) = empty

      exception NoSuchElement

      fun lowest (BS{lo,...}) = de_ord lo

      fun lowest' (BS{lo,...}) start = de_ord lo

      fun highest (BS{hi,...}) = de_ord hi

      fun highest' (BS{hi,...}) start = de_ord hi

      fun reduce bs = empty

      fun intersect(set1, set2) = empty

      fun difference(set1, set2) = empty

      fun isempty (BS{lo, hi,...}) = hi < lo

      fun eq (set1, set2) = true

      fun op subset(s1, s2) = isempty (reduce (difference (s1, s2)))

      fun op subset'(s1, s2) = isempty (reduce (difference (s1, s2)))
		       andalso (not (isempty (reduce (difference (s2, s1)))))

      fun lowQuery (bs, q) =
        let
	  val BS{lo, hi, setx} = bs
          val i = ref lo
        in
          de_ord (!i)
        end
      fun highQuery (bs, q) =
        let
	  val BS{lo, hi, setx} = bs
          val i = ref hi
        in
          de_ord (!i)
        end

      fun select (bs, q) = bs

      fun totOrder (set1, set2) = true

      fun forall s = nil

      fun makeString s = ""

      fun setFromList (l' : Elem.elem list) = empty
    end
  end


(*------------------------------ RedBlack.sml ------------------*)

signature RED_BLACK =
  sig type tree
      type key
      val empty : tree
      val insert : key * tree -> tree
      val lookup : key * tree -> key
      exception notfound of key
  end

functor RedBlack(B : sig type key
			 val > : key*key->bool
		     end): RED_BLACK =
struct
 open B
 datatype color = RED | BLACK
 datatype tree = empty | tree of key * color * tree * tree
 exception notfound of key

 fun insert (key,t) =
  let fun f empty = tree(key,RED,empty,empty)
        | f (tree(k,BLACK,l,r)) =
	    if key>k
	    then case f r
		 of r as tree(rk,RED, rl as tree(rlk,RED,rll,rlr),rr) =>
			(case l
			 of tree(lk,RED,ll,lr) =>
				tree(k,RED,tree(lk,BLACK,ll,lr),
					   tree(rk,BLACK,rl,rr))
			  | _ => tree(rlk,BLACK,tree(k,RED,l,rll),
						tree(rk,RED,rlr,rr)))
		  | r as tree(rk,RED,rl, rr as tree(rrk,RED,rrl,rrr)) =>
			(case l
			 of tree(lk,RED,ll,lr) =>
				tree(k,RED,tree(lk,BLACK,ll,lr),
					   tree(rk,BLACK,rl,rr))
			  | _ => tree(rk,BLACK,tree(k,RED,l,rl),rr))
	          | r => tree(k,BLACK,l,r)
	    else if k>key
	    then case f l
	         of l as tree(lk,RED,ll, lr as tree(lrk,RED,lrl,lrr)) =>
			(case r
			 of tree(rk,RED,rl,rr) =>
				tree(k,RED,tree(lk,BLACK,ll,lr),
					   tree(rk,BLACK,rl,rr))
			  | _ => tree(lrk,BLACK,tree(lk,RED,ll,lrl),
						tree(k,RED,lrr,r)))
		  | l as tree(lk,RED, ll as tree(llk,RED,lll,llr), lr) =>
			(case r
			 of tree(rk,RED,rl,rr) =>
				tree(k,RED,tree(lk,BLACK,ll,lr),
					   tree(rk,BLACK,rl,rr))
			  | _ => tree(lk,BLACK,ll,tree(k,RED,lr,r)))
	          | l => tree(k,BLACK,l,r)
	    else tree(key,BLACK,l,r)
        | f (tree(k,RED,l,r)) =
	    if key>k then tree(k,RED,l, f r)
	    else if k>key then tree(k,RED, f l, r)
	    else tree(key,RED,l,r)
   in case f t
      of tree(k,RED, l as tree(_,RED,_,_), r) => tree(k,BLACK,l,r)
       | tree(k,RED, l, r as tree(_,RED,_,_)) => tree(k,BLACK,l,r)
       | t => t
  end


 fun lookup (key,t) =
  let fun look empty = raise (notfound key)
	| look (tree(k,_,l,r)) =
		if k>key then look l
		else if key>k then look r
		else k
   in look t
  end

end


(*------------------------ Regex.sml ------------------------*)


import "Ordinal";
import "BitSet";
import "RedBlack";

signature CHAR_REG_EXP =
  sig
    structure Alphabet : ORD_RANGE
    structure AlphaSet : BITSET
    structure range : ORD_RANGE
    structure Set : BITSET
    sharing type Set.Elem.elem = range.elem = int

    type pattern

    datatype Ch_Reg_Exp
      = CONCAT of Ch_Reg_Exp list
      | ALTERNATE of Ch_Reg_Exp list
      | STAR of Ch_Reg_Exp
      | PLUS of Ch_Reg_Exp
      | OPTION of Ch_Reg_Exp
      | LETTER of AlphaSet.bitset
      | AUG   (* For internal use only *)

    type Aug_Reg_Exp

    val re_to_Aug : Ch_Reg_Exp -> {aug_re : Aug_Reg_Exp, count : int,
				leafList : Aug_Reg_Exp list}

    val Aug_to_Follow : {aug_re : Aug_Reg_Exp, count : int,
			 leafList : Aug_Reg_Exp list} -> Set.bitset array

    val Build_FSM :  {aug_re : Aug_Reg_Exp, count : int,
			 leafList : Aug_Reg_Exp list} * Set.bitset array
		     -> pattern

    val Print : Aug_Reg_Exp -> unit
  end

functor Reg_ExpFn() (* : CHAR_REG_EXP *) =
  struct
      structure Alphabet = CharFn()
      structure AlphaSet : BITSET = BitSetFn(Alphabet)
      structure range = NatFn()
      structure Set : BITSET = BitSetFn(range)

      type InfoTy =
	{
	  fp : Set.bitset,
	  lp : Set.bitset,
	  null : bool
	}

      datatype pattern = Pat

      datatype Ch_Reg_Exp
	= CONCAT of Ch_Reg_Exp list
	| ALTERNATE of Ch_Reg_Exp list
	| STAR of Ch_Reg_Exp
	| PLUS of Ch_Reg_Exp
	| OPTION of Ch_Reg_Exp
	| LETTER of AlphaSet.bitset
	| AUG       (* Internal use only *)

      datatype Aug_Reg_Exp
	= AugCONCAT of InfoTy * Aug_Reg_Exp list
	| AugALTERNATE of InfoTy * Aug_Reg_Exp list
	| AugSTAR of InfoTy * Aug_Reg_Exp
	| AugPLUS of InfoTy * Aug_Reg_Exp
	| AugOPTION of InfoTy * Aug_Reg_Exp
	| AugLETTER of InfoTy * AlphaSet.bitset
	| AugAUG of InfoTy

      fun mkInfo () =
	 {
	   Fpos = Set.empty,
	   Lpos = Set.empty,
	   Nullable = false
	 }

      fun info (AugCONCAT(inf, _)) = inf
	| info (AugALTERNATE(inf, _)) = inf
	| info (AugSTAR(inf, _)) = inf
	| info (AugPLUS(inf, _)) = inf
	| info (AugOPTION(inf, _)) = inf
	| info (AugLETTER(inf, _)) = inf
	| info (AugAUG(inf)) = inf

(*      type 'a Aug = {aug_re : Aug_Reg_Exp, count : int,
		 leafList : Aug_Reg_Exp list}
*)
      fun re_to_Aug re =
        let
	  fun app_map cnt nil = (nil : Aug_Reg_Exp list, cnt, nil)
	    | app_map cnt (hd::tl) =
	      let
		val hd' = pass1(cnt, hd)
		val {aug_re=ar, count=c, leafList=le} = hd'
		val (arTl, cntTl, leTl) = app_map c tl
	      in
		(ar::arTl, cntTl, le@leTl)
	      end
	  and pass1 (counter, CONCAT(re_l)) =
		let
		  val (ar', cnt', le') = app_map counter re_l
		  fun foldConcat (a, b) =
		    let
		      val {fp = fpA, lp = lpA, null = nuA} = a
		      val {fp = fpB, lp = lpB, null = nuB} = b
		      val n = nuA andalso nuB
		      val fp' = if nuB then Set.union (fpA, fpB) else fpB
		      val lp' = if nuA then Set.union (lpA, lpB) else lpA
		    in
		      print "foldConcat\n";
			print "    given A ";
			  print "  fpA="; print (Set.makeString fpA);
			  print "  lpA="; print (Set.makeString lpA);
			  print nuA; print "\n";
			print "    given B ";
			  print "  fpB="; print (Set.makeString fpB);
			  print "  lpB="; print (Set.makeString lpB);
			  print nuB; print "\n";
			print "    results ";
			  print "  fp'="; print (Set.makeString fp');
			  print "  lp'="; print (Set.makeString lp');
			  print n; print "\n";
		      {fp = fp', lp = lp', null = n}
		    end
		  val base = {fp = Set.empty, lp = Set.empty, null = true}
		  val _ = (print "    base ";
			  print "  fp'="; print (Set.makeString (#fp base));
			  print "  lp'="; print (Set.makeString (#lp base));
			  print (#null base); print "\n")
		  val info = revfold foldConcat (map info ar') base
		in
		  {aug_re = AugCONCAT(info, ar'), count = cnt',
		      leafList = le'}
		end
	    | pass1 (counter, ALTERNATE(re_l)) =
		  let
		    val (ar', cnt', le') = app_map counter re_l
		    fun foldAlt (a, b) =
		      let
			val {fp = hdA, lp = lpA, null = nuA} = a
			val {fp = hdB, lp = lpB, null = nuB} = b
		      in
			{fp = Set.union (hdA, hdB),
			 lp = Set.union (lpA, lpB),
			 null = nuA orelse nuB}
		      end
		    val base = {fp = Set.empty, lp = Set.empty, null = false}
		    val info = fold foldAlt (map info ar') base
                  in
		    {aug_re = AugALTERNATE(info, ar'), count = cnt',
			leafList = le'}
		  end
	    | pass1 (counter, STAR(re)) =
		  let
		    val {aug_re=ar, count=c, leafList=le} = pass1(counter, re)
		    val {fp = fp', lp = lp', null = nu} = info ar
		    val info = {fp = fp', lp = lp', null = true}
                  in
		    {aug_re = AugSTAR(info, ar), count = c, leafList = le}
		  end
	    | pass1 (counter, PLUS(re)) =
		  let
		    val {aug_re=ar, count=c, leafList=le} = pass1(counter, re)
		    val {fp = fp', lp = lp', null = nu} = info ar
		    val info = {fp = fp', lp = lp', null = nu}
                  in
		    {aug_re = AugPLUS(info, ar), count = c, leafList = le}
		  end
	    | pass1 (counter, OPTION(re)) =
		  let
		    val {aug_re=ar, count=c, leafList=le} = pass1(counter, re)
		    val {fp = fp', lp = lp', null = nu} = info ar
		    val info = {fp = fp', lp = lp', null = true}
                  in
		    {aug_re = AugOPTION(info, ar), count = c, leafList = le}
		  end
	    | pass1 (counter, LETTER(a)) =
		  let
		    val c = Set.singleton counter
		    val info = {fp = c, lp = c, null = false}
		    val aug_r = AugLETTER(info, a)
                  in
		    {aug_re = aug_r, count = counter+1, leafList = [aug_r]}
		  end
	    | pass1 (counter, AUG) =
		  let
		    val c = Set.singleton counter
		    val info = {fp = c, lp = c, null = false}
		    val aug_r = AugAUG(info)
                  in
		    {aug_re = aug_r, count = counter+1, leafList = [aug_r]}
		  end
        in
	  pass1 (0, CONCAT [re, AUG])
        end



      fun prFollow fp =
	let
	  val l = Array.length fp
          fun prx i = (print i; print "  "; print (Set.makeString (fp sub i));
		print "\n")
	  fun p i = if i < l then (prx i; p (i + 1)) else ()
	in
	  p 0
	end

      fun Aug_to_Follow {aug_re, count, leafList} =
	let
	  val followPos = array(count, Set.empty)
	  val count = ref 0
	  fun updSet fp i = update(followPos, i,
		Set.union(followPos sub i, fp))
	  fun pass2 (AugCONCAT(inf, re_l)) =
		let
		  fun foldConcat (x, y) =
		    let
		      val updList = Set.forall y
		      val {fp, lp, ...} = info x
		      val updSet' = updSet fp
		      fun ms nil = ""
		        | ms (x::y) = (makestring x) ^ (ms y)
		    in
		      print ("[" ^ (ms updList) ^ "]" ^ "\n"); 
		      print (Set.makeString lp ^ "\n");
		      app updSet' updList;
		      lp
		    end
		  val c = !count
		in
		  inc count;
		  print "before fold "; print c; print "\n";
		  prFollow followPos; print "\n";
		  revfold foldConcat re_l Set.empty;
		  print "after fold "; print c; print "\n";
		  prFollow followPos; print "\n";
		  app pass2 re_l;
		  print "after app "; print c; print "\n";
		  prFollow followPos; print "\n"
		end
	    | pass2 (AugALTERNATE(inf, re_l)) = app pass2 re_l
	    | pass2 (AugSTAR(inf, re)) =
		let
		  val {fp, lp, ...} = info re
		  val updSet' = updSet fp
		in
		  app updSet' (Set.forall lp);
		  pass2 re
		end
	    | pass2 (AugPLUS(inf, re)) =
		let
		  val {fp, lp, ...} = info re
		  val updSet' = updSet fp
		in
		  app updSet' (Set.forall lp);
		  pass2 re
		end
	    | pass2 (AugOPTION(inf, re)) = pass2 re
	    | pass2 (AugLETTER(inf, _)) = ()
	    | pass2 (AugAUG(inf)) = ()
	in
	  pass2 aug_re;
	  followPos
        end

	datatype transition = TR of AlphaSet.bitset * state
	and state = ST of {posSet : Set.bitset,
			        stId : int,
			        trans : transition list}
	fun le (ST{posSet = pS1,...}, ST{posSet = pS2,...}) =
		Set.totOrder (pS1, pS2)
        fun getPosSet (ST{posSet,...}) = posSet
        structure table = RedBlack(struct type key = state
					  val op > = le end)

	fun Build_FSM ({aug_re, count, leafList}, followPos) =
	  let
	         (* get character set at position i *)
	    fun cSetAt i =
	      case nth (leafList, i) of
                AugLETTER(inf, x) => x
	      | AugAUG(_) => AlphaSet.empty

		 (* test to see if character has transition at position i *)
	    fun atPos c i = AlphaSet.exists c (cSetAt i)

		 (* Is this position a final position *)
	    fun final i =
	      case nth (leafList, i) of
	        AugAUG(_) => true
              | _ => false

		 (* return only those elements which match query *)
	    fun sublist query l =
	      let
		fun ss nil = nil
	          | ss (hd::tl) =
		     let val x = (ss tl)
		     in if query hd then hd::x else x
		     end
	      in
		ss l
              end

	    val cnt = ref 1

	    fun build_auto states unmarked =
	      if unmarked = nil then states else
	      let
	        val T = hd unmarked
		val _ = print ("build_auto " ^ (Set.makeString T) ^ "\n")
		val allchar =
		    let
		      fun f (i, x)  = AlphaSet.union(cSetAt i, x)
		    in
		      fold f (Set.forall T) AlphaSet.empty
		    end
		val _ = print ("    allchar = " ^ (AlphaSet.makeString allchar)
			^ "\n");
		fun eachChar states unmarked trans allchar =
		  if AlphaSet.isempty allchar then
		    (states, unmarked, trans)
		  else
		    let
		      val _ = print "eachChar\n"
		      fun next cSet =
			let
			  val x = AlphaSet.lowest cSet
			  val _ = print ("next cSet=" ^
				  (AlphaSet.makeString cSet) ^ "  ")
			  val _ = print (makestring (AlphaSet.Elem.ord x)
				   ^ "\n")
			  val posSet = Set.select (T, atPos x)
			  val _ = print "Check\n"
			  fun findSet i ch =
			    if i = count then ch
			    else
			      let val y = if Set.exists i posSet then
					    AlphaSet.intersect(ch, cSetAt i)
					  else
					    AlphaSet.difference(ch, cSetAt i)
			      in
				findSet (i + 1) y
			      end
			in
			  (findSet 0 cSet, posSet)
			end (* next *)

		      val (cSet, posSet) = next allchar
		      val _ = print ("     cSet=" ^ (AlphaSet.makeString cSet)
				   ^ ", posSet = " ^ (Set.makeString posSet)
				   ^ "\n")

		      fun makeU s =
			let
			  fun f (i, x) = Set.union (followPos sub i, x)
			in
			  fold f (Set.forall posSet) Set.empty
			end  (* makeU *)

		      val U = makeU posSet
		      val _ = print ("     U=" ^ (Set.makeString U) ^ "\n") 


		      fun FindInsert st u =
			let
			  val dummy = ST{posSet = u, stId = 0, trans = []}
			in
			  (table.lookup(dummy, st), st, unmarked)
			    handle table.notfound _ =>
			      let
				val u' = ST{posSet = u, stId = !cnt, trans=[]}
				val st' = table.insert(u', st)
			      in
				inc cnt;
				(u', st', unmarked@[u])
			      end
			end  (* FindInsert *)
		      val (ToState, states', unmarked') = FindInsert states U
		      val trans' = TR(cSet, ToState)::trans
		    in
		      eachChar states' unmarked' trans'
			 (AlphaSet.difference (allchar, cSet))
		    end  (* eachChar *)

		val (states', unmarked', trans') =
		    eachChar states unmarked [] allchar
		val dummy = ST{posSet = T, stId = 0, trans = []}
		val ST{stId = Tid,...} = table.lookup(dummy, states')
		val s = ST{posSet = T, stId = Tid, trans = trans'}
		val states2 = table.insert(s, states')
	      in
		build_auto states' (tl unmarked')
	      end  (* build_auto *)
	    val {fp = st',...} = info aug_re
	    val startstate = ST{posSet = st', stId = 0, trans = []}
	    val stTable = table.insert (startstate, table.empty)
	    val autoList = build_auto stTable [st']
	  in
	    autoList
	  end

      fun Print re =
        let
          val depth = ref 0
          fun printInfo ({fp, lp, null} : InfoTy) =
	      (
		print "Fpos=";
		print (Set.makeString (fp));
		print "  Lpos=";
		print (Set.makeString (lp));
		if null then
		  print "  nullable\n"
		else
		  print "\n"
	      )
	  fun Pr (AugCONCAT(inf, re_l)) =
	      (
		print "CONCAT  ";
		printInfo inf;
	        app Pr1 re_l
	      )
	    | Pr (AugALTERNATE(inf, re_l)) =
	      (
		print "ALTERN  ";
		printInfo inf;
	        app Pr1 re_l
	      )
	    | Pr (AugSTAR(inf, re)) =
	      (
		print "KLEENE  ";
		printInfo inf;
	        Pr1 re
	      )
	    | Pr (AugPLUS(inf, re)) =
	      (
		print "POSITV  ";
		printInfo inf;
	        Pr1 re
	      )
	    | Pr (AugOPTION(inf, re)) =
	      (
		print "OPTION  ";
		printInfo inf;
	        Pr1 re
	      )
	    | Pr (AugLETTER(inf, _)) =
	      (
		print "LETTER  ";
		printInfo inf
	      )
	    | Pr (AugAUG(inf)) =
	      (
		print "AUGMEN  ";
		printInfo inf
	      )
          and
	      Pr1 x =
	      let
		val i = ref 0;
	      in
		(
		  while (!i) < (!depth) do
		    (print "  "; inc i);
		  inc depth;
		  Pr x;
		  dec depth
	        )
	      end
        in
	   Pr1 re
        end;
  end;


structure RRP_Test = Reg_ExpFn();

open RRP_Test;

val a = LETTER(AlphaSet.singleton "a")
val b = LETTER(AlphaSet.singleton "b")
val c = LETTER(AlphaSet.singleton "c")
val d = LETTER(AlphaSet.singleton "d")

val a_b_c = ALTERNATE([a, b, c]);
val aug = re_to_Aug a_b_c;
Print (#aug_re aug);
val fol = Aug_to_Follow aug;
prFollow fol;
print "Before Build_FSM\n";
val t = Build_FSM(aug, fol);

print "\n\n\n";
val abc = CONCAT([a, b, c]);
val aug' = re_to_Aug abc;
Print (#aug_re aug');
val fol' = Aug_to_Follow aug';
prFollow fol';
val t' = Build_FSM(aug', fol');

Status: fixed in 0.64
-------------------------------------------------------------------------------
262. Using the LIBRARY with v0.62
Submitter: "Soren P. Christensen" <schristensen@daimi.aau.dk>
Date: Wed, 8 Aug 90 14:28:49 +0200
Problem:
I just tried to build the library found in /dist/ml/LIBRARY.tar.Z and
this fails.  We are using a spark version of 0.62.  I am not dependent
on the Library and the reson I report this is only so that you can use
it in your testing.

I had to make small changes like the definition of the quit function by
means of cleanup.

1)
   There seems to be problems with the exceptions.

---------------
Transcript:
Standard ML of New Jersey, Version 0.62, 1 August 1990
val it = () : unit
- fn () => (() handle Interrupt=>());
val it = fn : unit -> unit
- exception xx = Interrupt;
std_in:3.16-3.24 Error: unbound exn: Interrupt
- raise Interrupt;
std_in:1.7-1.15 Error: unbound variable Interrupt
std_in:1.1-1.15 Error: argument of raise is not an exception
  raised: undef
  in expression:
    raise Interrupt

----------------

2)
   later on it terminates with a runbind, I think this is related to the 
exceptions too.
Comments:
  (1) The Interrupt exception constructor has gone away, and Interrupt
  handling should be replaced by handling the interrupt signal.
  (2) The runbind exception seems to be a genuine bug.
Status: fixed in 0.65
-------------------------------------------------------------------------------
263. problem with input via datakit con
Submitter: pjw
Date: 8/8/90
Transcript:
con tempel
connected to tempel.mesgdcon on /net/dk/4
$ cd /usr/dbm/sml/60/src
$ sml
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- -3;
std_in:2.1 Error: nonfix identifier required
std_in:2.1-2.2 Error: operator and operand don't agree (tycon mismatch)
  operator domain: 'Z * 'Z
  operand:         int
  in expression:
    - 3
std_in:2.1 Error: overloaded variable "-" cannot be resolved
uncaught Io exception (Loader): input "<std_in>": negative character count
$ 
Status: fixed in 0.65
--------------------------------------------------------------------------------
264. No type-explicitness check in nj-sml
Submitter: David Turner <dnt@lfcs.edinburgh.ac.uk>
Date: 7/8/90
Version  : SML of NJ 0.56 and 0.59
System   : Sun
Severity : Dunno, but its pretty anti-social

Problem :

   The compiler doesn't seem to check for type explicitness in
   signatures (see section 5.8 and also rule 65 of the ML definition).
   This means many signatures which can never be matched are still
   accepted as valid signatures.

Transcript :

  - signature X = sig type t val x : t type t end;
  signature X =
    sig
      type t
      val x : ?.t
    end

Status: fixed in 0.73
--------------------------------------------------------------------------------
265. strong type variables accepted in exception declarations
Submitter:      Dave Berry, db@lfcs.ed.ac.uk
Date:		Aug  7 1990
Version:        0.56, 0.59
Severity:       Minor (although it presumably means that the type system
		can be broken!)
Problem:        The compiler doesn't reject applicative type variables
		in exception declarations.
Code:           val id: 'a -> 'a =
		  let exception dummy of 'a
		  in fn x => x
		  end;
Transcript:     The above code produces:
		val id = fn : 'a -> 'a

Status: fixed in 0.65
--------------------------------------------------------------------------------
266. uncaught Io exception in use
From: John Reppy
Date: Mon, 6 Aug 90 18:53:48 EDT
System: 0.62
Problem:
I've noticed the following new (I think) bug.  An Io error in use results
in an uncaught exception.

  Standard ML of New Jersey, Version 0.62, 1 August 1990
  val it = () : unit
  - use "foo";
  [cannot open foo]

  uncaught exception Io "open_in "foo": open failed, No such file or directory"

The problem is that in "use_file" in build/interact.sml (line 307), the
exception Io gets re-raised.  Was this changed for the debugger?
[dbm, 8/30/90] Fixed so that exceptions are handled even for nonterminal
input.

Status: fixed in 0.65
-------------------------------------------------------------------------------
267. sharing again
From: Simon Finn <simon@abstract-hardware-ltd.co.uk>
Date: Thu, 2 Aug 90 10:48:47 BST
Version: d64
Problem:
The following program breaks Poly/ML v1.88 and  NJML v0.44a (the most recent version
to which I have access) [breaks d64 as well].
Code:
signature S1 =
sig
  eqtype t
  val x : t
end;

signature S2 =
sig
  structure A : sig end
  structure C : sig structure A : S1 end
  sharing A = C.A
end;

functor F(structure A:S1
          structure B:S2
          sharing A = B.A)  =
struct
  val y = (A.x = B.C.A.x)
end;

Transcript:
Standard ML of New Jersey, Version d64, ? August 1990
val it = () : unit
- signature S1 =
  sig
    eqtype t
    val x : t
  end
signature S2 =
  sig
    structure A : sig...end
    structure C : sig...end
  end
std_in:21.11-21.25 Error: operator and operand don't agree (tycon mismatch)
  operator domain: ?.t * ?.t
  operand:         ?.t * ?.t
  in expression:
    = (A.x,B.C.A.x)

Comment:
This program is valid, since structure A shares with B.A which shares with B.C.A,
hence A.t and B.C.A.t must be the same (equality) type. However:

Status: fixed in 0.73
--------------------------------------------------------------------------------
268. import, equality
Submitter:      Jason Fischl <fischl@cpsc.ucalgary.ca>
Date:		April 9, 1990
Version:        0.44
System:         Sparcstation 1
Severity:       major

Problem:       

The module system has a bug in it with regard to equality types (I think).
The following is a pretty concise description of what will cause the bug to
occur.  


Code:           
(*-----------------FILE:  term.sig.sml----------------------*)

signature termsig =
sig

datatype term =
    Const of string
  | Var of string
  | Func of string * term list

end;

(*--------------FILE:  term.sml-------------------------*)

import "term.sig";

functor termFC ():termsig =

struct

datatype term =
    Const of string
  | Var of string
  | Func of string * term list

end;

(*------------FILE: parse_term.sml---------------------------*)

import "term.sig";

functor parse_termFC (structure TERM:termsig) =
struct

open TERM

fun term_nil x = (x:term list) = []

end;

(*---------------------------------------*)


Transcript:     

- import "parse_term";
[parse_term.bin is out of date; recompiling]
[reading parse_term.sml]
  [reading term.sig.bin... done]
parse_term.sml, line 11: Error: Compiler bug: tycStamp
equal: type = ?.term list
import: code generation failed
[closing parse_term.sml]
IMPORT failed (codegen)
- 

Comments:

I couldn't find any reference to it in the bug reports so I had to assume it
was all new.  It would have been much nicer if the error message had been a bit
more descriptive.  All I knew was that it was a type problem.  There was no
info as to which line the error occurred on or which function or anything
really. 

I would appreciate a reply at some point if you could manage since I am curious
as to the nature of my problem.  Undoubtedly it will get me again!  

Fix:  

In order to fix the problem I had to define the fun term_nil inside the term
functor and then also put it in the termsig signature.  This took me on the
order of 8 hours to figure out!

Status: fixed before 0.65
-------------------------------------------------------------------------------
269. failure in abstractBody with embedded signature
Submitter: Dave MacQueen
Date: 8/29/90
Version: 0.63
Code: 
    functor F() =
    struct
      datatype d = D
      structure A : sig type s val x : s * d end =
	  struct
	    datatype s = MKs
	    val x = (MKs,D)
	  end
    end;

    structure B = F();

    val (_,B.D) = B.A.x;
Transcript:
    - use "bug269.sml";
    [opening bug269.sml]
    functor F : <sig>
    structure B :
      sig
	structure A : sig...end
	datatype d
	  con D : d
      end
    bug269.sml:16.5-16.19 Error: pattern and expression in val dec don't agree (tycon mis
    match)
      pattern:    B.A.s * B.d
      expression: B.A.s * ?.d
      in declaration:
	(_,D) = B.A.x
    [closing bug269.sml]

Status: fixed in 0.65
-------------------------------------------------------------------------------
270. Compiler bug: TypesUtil.lookTycPath: NULLstr 
Submitter: Dave MacQueen
Date: 8/29/90
Version: 0.63
Problem:
   failure to interpret path for X.d in embedded signature
   Formal paramter X was not bound properly.
Code:
    functor F(X: sig datatype d = A end) =
    struct
      structure S : sig val x : X.d end =
	struct val x = X.A end
    end
Status: fixed in 0.65
-------------------------------------------------------------------------------
271. secondary compiler bug
Submitter:      Gary T. Leavens leavens@bambam.cs.iastate.edu
Date:		8/29/90
Version:        0.64
System:         HP 9000/370, HP-UX 7.0
Severity:       minor
Problem:        get compiler bug report
Code:           the following in a file "report"

signature IntMapSig =
    sig
        type 'a map
        val apply: ('a map)*int -> 'a
        exception NotFound
    end;
 
signature ValueSig =
    sig
        type value
    end;
 
signature SymbolSig =
    sig
        type sym
        val hash: sym -> int
    end;
 
functor SymTblFct(structure IntMap: IntMapSig
                  structure Val: ValSig
                  structure Sym: SymSig):
    sig
        type table
        exception Lookup
        val lookup: table * Sym.sym -> Val.value
        val update: table * Sym.sym * Val.value -> table
    end =
    struct
        datatype table = TBL of (Sym.sym * Val.value)list IntMap.map
        exception Lookup

        fun find(sym,[]) = raise Lookup
         |   find(sym,(sym',v)::rest) =
              if sym = sym' then v else find(sym,rest);

        fun lookup(TBL map, s) =
            let val n = Sym.hash(s)
                val l = IntMap.apply(map,n)
            in find(s,l)
            end handle IntMap.NotFound => raise Lookup

    (* ... *)
    end;

Transcript:     a transcript of session illustrating problem follows

Standard ML of New Jersey, Version 0.64, ? August 1990
val it = () : unit
- [opening report]
signature IntMapSig =
  sig
    type 'a map
    exception NotFound
    val apply : 'a map * int -> 'a
  end
signature ValueSig =
  sig
    type value
  end
signature SymbolSig =
  sig
    type sym
    val hash : sym -> int
  end
report:20.20-20.25 Error: unbound signature: ValSig
[closing report]
std_in:1.1 Compiler Bug: ModUtil.shiftStamps.newEnv - bad arg
-

Comments:  obviously the code has bugs, but I thought you'd want to see
	the "compiler bug" anyway, since it may be triggered by the bugs
	in the program.
Status: fixed in 0.65
-------------------------------------------------------------------------------
272. generalizing user bound type variables
Submitter: Elsa
Date: 9/7/90
Version: 0.65
Problem: user bound variables are occurring in the final type of a function.
Code:
   fun f(x) = let val y : 'a -> 'a = x in y y end;
Transcript:     <transcript of session illustrating problem>
   - fun f(x) = let val y : 'a -> 'a = x in y y end;
   val f = fn : ('aU -> 'aU) -> 'a -> 'a   
   - f (fn x: 'a => x);
   std_in:2.1-2.16 Error: operator and operand don't agree (bound type var)
     operator domain: 'aU -> 'aU
     operand:	      'aU -> 'aU
     in expression:
       f ((fn <pat> : 'aU => x))
Comments:
  Error should be detected when function f is defined, rather than when it
  is applied.
Status: fixed in 0.70
-------------------------------------------------------------------------------
273. generalizing weak variables inside fn abstractions
Submitter: Dave MacQueen
Date: 10/3/90
Version: 0.52 and earlier
Problem: 
  let-bound variables were being generalized with too strong a weak type.
Transcript:
   - val x = fn y => let val f = ref in f end;
   val x = fn : 'a -> '3b -> '3b ref
Comments:
   Second bound type variable should be '2b instead of '3b.
Fix: 
   Added abs field to POLYty constructor to remember abstraction level at
   point where type generalization took place.
Status: fixed in 0.53
-------------------------------------------------------------------------------
274. weakness lost with flex record pattern
Submitter: Colin Meldrum <colin@harlqn.co.uk>
Date: 3/19/90
Version: 0.66
Problem: flex record patterns can cause weakness to be dropped, resulting in
  whole in type system.
Code:
    - val a = 
      let val foo = ref nil
      in
	(fn x as {...} => foo:=[x] | (y,z) => ();
	 foo)
      end

    > val a = ref [] : ('a * 'b) list ref
Comment:
    This is very unsafe and can for example allow the definition of a 'cast'
    function...

    fun cast (x) = ((a := (x,0) :: (!a)); #1(hd (!a)));
Status: fixed in 0.74
-------------------------------------------------------------------------------
275. illegal token with structure named ?
Submitter: Nick Rothwell
Date: 3/16/90
Version: ?
Transcript:
    - structure ? = struct val x = 3 end;
    [succeeds]

    - ?.x;
    [fails with "illegal token"]

    - let open ? in x end;
    [succeeds]
Status: fixed by 0.66
-------------------------------------------------------------------------------
276. overriding included value spec
Submitter: Dave Berry (db@lfcs.ed.ac.uk)
Date: 3/22/90
Version: 0.66
Severity: major
Problem:
    If a value spec in an included signature is redefined in the
    including signature, the value identifier keeps the type
    from the included signature, but it is printed as the type
    from the including signature.
Transcript:
      signature Foo1 =
      sig
        val foo: string
      end;

     signature Foo2 =
     sig
       include Foo1
       val foo: bool
     end;

     structure Foo: Foo2 =
     struct
       val foo = true
     end;

    Error: value type in structure doesn't match signature spec
      name: foo
      spec:   string
      actual: bool
Comments:
    Note:  Once I worked out what was going on I was actually grateful,
    because I hadn't realised that the names clashed.  Perhaps it
    would be useful if implementations could warn about such cases?
Status: fixed in 0.73
-------------------------------------------------------------------------------
276. weak polymorphism
Submitter: Dave Berry (db@lfcs.ed.ac.uk)
Date: 3/22/90
Version: 0.44
Severity: major
Problem:
Code:           <example code that reproduces the problem>
    System.Control.weakUnderscore := true;

    structure RV:
      (* The bug doesn't appear if the signature isn't included. *)
      sig
	val create: int -> '_a -> '_a ref list
      end
    =
    struct
      (* The bug doesn't appear if the first arguiment is omitted (the code
	 here doesn't use it, just to keep the example small. *)
      fun create size init = [ref init]
    end;

    (* The bug doesn't appear if this function is curried. *)
    fun extend (newmax, v) =
	  RV.create newmax v;

Transcript: This is the output from the compiler:

    structure RV :
      sig
	val create : int -> '_a -> '_a ref list
      end
    nj-bug, line 17: Error: nongeneric weak type variable
      extend : int * '0S -> '0S ref list
Status: fixed in 0.70
-------------------------------------------------------------------------------
277. incorrect "inconsistent equality property" error
Submitter: dbm
Date: 3/16/90
Version: 0.66
Severity: major
Problem:
Code: bug277.sml
    signature S1 =
    sig
      type d
    end;

    functor F(X: S1) :
    sig
      datatype a = C of X.d
    end =
    struct
      datatype a = C of X.d
      val f = fn (x : a) => x
    end;
Transcript:
   bug277.sml: 11.3-11.24 Error: inconsistent equality properties (2)
Status: fixed in 0.73
-------------------------------------------------------------------------------
278. local structure declaration at top level
Submitter:      R. M. O'Neill (cmp7130@sys.uea.ac.uk)
Date:		3rd April 1990
Version:        0.44a
System:         Sun 3/50 & 3/160S SunOS 3.5
Severity:       Minor (but, should be easy to fix and I would prefer it fixed)

Problem:        

Using 'local ... in ... end' with structures does not work at the top level,
but does work when wrapped in a 'struct ... end' construct

Code:
  local
     structure Internal = struct val x=1 val y=2 end
  in
     structure First  : sig val x : int end = Internal
     structure Second : sig val y : int end = Internal
  end

  [** As a TOP-LEVEL declaration **]

Transcript:

-   local
=      structure Internal = struct val x=1 val y=2 end
Error: expected IN, found STRUCTURE
Error: expected END, found STRUCTURE
=   in
Error: declaration or expression expected, found IN
-      structure First  : sig val x : int end = Internal
=      structure Second : sig val y : int end = Internal
Error: unbound structure name: Internal
Error: unmatched val spec: x
=   end ;
Error: unbound structure name: Internal
Error: unmatched val spec: y
Error: declaration or expression expected, found END
-

Compare-With:

- structure Kludge = struct
=   local
=      structure Internal = struct val x=1 val y=2 end
=   in
=      structure First  : sig val x : int end = Internal
=      structure Second : sig val y : int end = Internal
=   end
= end ;
structure Kludge :
  sig
    structure First : sig...end
    structure Second : sig...end
  end
-

Comments:

Parser problem ? ( Expecting an 'ldec' rather than an 'sdec' ? )
[ I'm no SML internal workings guru !]

Status: fixed by 0.66
-------------------------------------------------------------------------------
279. big integers causing uncaught exception
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: 4/4/90
Version: 0.55
System: ?
Severity: major
Problem:
    There seems to be a problem in the compiler with integers that are larger
    than 2^29-1.
Transcript:
  Standard ML of New Jersey, Version 0.55, 1 April 1990
  val it = () : unit
  - fun f (i : int, two_i : int) = (
  =        print i; print ": "; print two_i; print "\n"; f(i+1, two_i+two_i));
  val f = fn : int * int -> 'a
  - f(0, 1);
  0: 1
  1: 2
  2: 4
  3: 8
   ...
  27: 134217728
  28: 268435456
  29: 536870912
  uncaught exception 
  - 536870912;
  uncaught exception 
  - 536870911;
  val it = 536870911 : int
Status: fixed in 0.66 on mipsb
-------------------------------------------------------------------------------
280. included infix specs not printed
Submitter: John Reppy
Date: 4/17/90
Version: 0.56
Severity: minor
Problem:
    I noticed that if you include a signature that contains an infix
    specification, the infix specification doesn't get printed.
Code:
Transcript:
  - signature S1 = sig infix ## end;
  signature S1 =
    sig
      infix 0 ##
    end
  - signature S2 = sig include S1 end;
  signature S2 =
    sig
    end
Status: fixed in 0.73
-------------------------------------------------------------------------------
281. Import bombs out when it can't find files.
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Tue Jul 17 11:01:09 BST 1990
Version:        0.59
System:         Sun3, SunOS 4.1
Severity:       You decide...
Problem:

Importing new files (ones which do not already have a '.bin' file) fails (with
an uncaught exception) whilst attempting to import files which do not exist
produces the same unfriendly message.

Transcript:

unix% ls
file.sml
unix% sml
Standard ML of New Jersey, Version 0.59, 4 June 1990
- import "file";

uncaught exception SystemCall
- import "nofile";

uncaught exception SystemCall
-

Perceived Reason:

The timeFile function in sepcomp/importer.sml believes that the SysIO.mtime
function will raise an Io exeption if it cannot find the file. In fact this
exception is never returned by any of the routines in the SysIO module. When
they encounter a problem they raise the SystemCall exception.

Fix (currently untried):

Option 1:

Change the code for timeFile to trap the SystemCall exeption instead of the
Io exception.

e.g.

<PATCH BEGIN>
*** sepcomp/importer.sml.orig   Fri Jun  1 14:08:02 1990
--- sepcomp/importer.sml        Tue Jul 17 10:29:22 1990
***************
*** 159,165 ****
        in
          SOME sec
        end
!         handle (Io _) => NONE

    fun createBinary(indent, filename,
                   statModule: statModule,
--- 159,165 ----
        in
          SOME sec
        end
!         handle (SystemCall _) => NONE

    fun createBinary(indent, filename,
                   statModule: statModule,

<PATCH END>

Option 2:

Create a new exception SysIO wich the module SysIO raises on failure and trap
that. ( This is to my mind better since SystemCall is a rather wide exception
to be trapping ).

Status: fixed in 0.73
-------------------------------------------------------------------------------
282. 'sharable' & 'pervshare' compilers produce different .bin
Submitter:      Richard O'Neill (cmp7130%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date: 		Mon Jul 23 10:53:45 BST 1990
Version:        0.60
System:         Sun3/50, SunOS 4.1
Severity:       You decide...
Problem: 
Status: R

The '.bin' files produced by the normal and the '-pervshare' versions of the
compiler are different and each 'version' cannot load the other's '.bin' file
reliably.

Perhaps I have built the two versions differently, but I cannot see how since
they were both built at the same time with the same .mo files (compiled with
the 0.59 batch compiler).

Below is a comprehensive transcript which should help in reproducing the bug,
if it can be reproduced...

Transcript:

unix% cat > bug.sml
functor test () = struct val it = "testing, testing, 1, 2, 3..." end
unix% sml.pervshare
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- import "bug";
[reading bug.sml]
[writing bug.bin... done]
[closing bug.sml]
functor test
- ^D
unix% sml.sharable
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- import "bug";
[reading bug.bin... done]

[Major collection... 99% used (530424/535668), 1500 msec]

[Increasing heap to 6920k]

[Major collection... 100% used (530424/530424), 1400 msec]

[Increasing heap to 11160k]

[Major collection... 100% used (530424/530424), 1400 msec]

[Increasing heap to 17520k]

[Major collection... 100% used (530424/530424), 1400 msec]

[Increasing heap to 22288k]

[Major collection... 100% used (530424/530424), 1400 msec]

[Increasing heap to 22656k]

[Major collection... 100% used (530424/530424), 1420 msec]

[Increasing heap to 22744k]

[Major collection... 100% used (530424/530424), 1400 msec]

[Increasing heap to 22752k]

[Major collection... 100% used (530424/530424), 1400 msec]

Warning: can't increase heap

Ran out of memory
unix% mv bug.bin bug.bin.sharable
unix% sml.sharable
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- import "bug";
[reading bug.sml]
[writing bug.bin... done]
[closing bug.sml]
functor test
- ^D
unix% sml.pervshare
Standard ML of New Jersey, Version 0.60, 13 July 1990
val it = () : unit
- import "bug";
[reading bug.bin... done]
functor test
- structure Test=test ();
insttyc: NULLtyc
Error: Compiler bug: Functor.applyFunctor.insttyc
- ^D
unix% mv bug.bin bug.bin.pervshare
unix% cmp bug.bin.sharable bug.bin.pervshare
bug.bin.sharable bug.bin.pervshare differ: char 62, line 2
unix% ll bug.bin.*
-rw-------  1 cmp7130      1415 Jul 23 10:21 bug.bin.pervshare
-rw-------  1 cmp7130     17331 Jul 23 10:18 bug.bin.sharable

Status: Fixed (defunct feature)
-------------------------------------------------------------------------------
283. openread (run.c) checking
Submitter: Peter Weinberger
Date: 8/17/90
Version: ?
Severity: minor
Problem:
    openread() in run.c does not check to see if it runs off the
    end of its allowed space.
Comments:
    in practice, this shouldn't be a problem, since openread() only reads
    the first two or three mo files, which should be smaller than the
    initial heap size.
Status: fixed in 0.74
-------------------------------------------------------------------------------
284. Poor type specification handling in mutually recursive functions.
Submitter:      Richard O'Neill (rmo%sys.uea.ac.uk@nsfnet-relay.ac.uk)
Date:		Tue Aug 14 10:04:21 BST 1990
Version:        0.64, 0.62, 0.56, ...
System:         Sun3/180, SunOS 4.1
Problem:

When processing mutually recursive functions, Sml of NJ's current type
mechanism prefers its own inferred types of functions to those specifically
declared by the user.

Code:
	type 'a foobar = {foo:'a, bar:'a}

	fun Foo (acc : 'a list foobar)  (nil : 'a list) = acc
	  | Foo {foo, bar} (h :: t) = Bar {foo=(h :: foo), bar=bar} t

	and Bar (acc : 'a list foobar)  (nil : 'a list) = acc
	  | Bar {foo, bar} (h :: t) = Foo {foo=foo, bar=(h :: bar)} t

Transcript:
unix% sml
Standard ML of New Jersey, Version 0.64, 24 August 1990
val it = () : unit
- use "code.sml";
[opening code.sml]
type 'a  foobar = {bar:'a,foo:'a}
val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar
val Bar = fn : {bar:'a list,foo:'a list} -> 'a list -> 'a list foobar
[closing code.sml]
-
- (* One would expect Foo & Bar to have the SAME type *)

Comments:

The type system seems to be deciding on the type of 'Bar' when it encounters
it in the definition of 'Foo', and then sticking to that. Whilst it checks to
see whether the type in the declaration of foo matches the type it has
inferred, it does not change the 'Foo's type to be in line with its 
declaration.

One can work around the problem by making sure that 'Bar' has the desired type
the first time it is encountered. Thus, if Foo is defined as :-

	fun Foo (acc : 'a list foobar)  (nil : 'a list) = acc
	  | Foo {foo,bar} (h :: t) =
		 Bar ({foo=(h :: foo), bar=bar} : 'a list foobar) t

the correct types result :-
	type 'a  foobar = {bar:'a,foo:'a}
	val Foo = fn : 'a list foobar -> 'a list -> 'a list foobar
	val Bar = fn : 'a list foobar -> 'a list -> 'a list foobar

My (ancient) version of Poly/ML also exhibits the same behaviour.

Status: not a bug; type abbreviations are not new types
-------------------------------------------------------------------------------
285. Bus error
Submitter:
 Alain Deutsch, Laboratoire d'Informatique, LIX,
 Ecole Polytechnique, 91128 Palaiseau Cedex, France.

Date: 8-30-1990

Version:
 Standard ML of New Jersey, Version 0.56, 13 April 1990

System:
 ULTRIX V4.0 (Rev. 174) System #1: Sat Feb 10 01:14:11 MET 1990
 UWS V4.0 (Rev. 164)

Severity:
 critical

Problem:
 Bus error.

Code:
 use "bug.sml";
 (see enclosed files below, tarmail format)

Transcript:
 Standard ML of New Jersey, Version 0.56, 13 April 1990
 Warning: input and output are now uncurried, arithmetic exceptions
 are re-arranged, div and mod are different; see doc/NEWS
 val it = () : unit
 - [opening /usr/users/lix/icsla/deutsch/ModeleSemantique/Bug/bug.sml]
 [opening Extensions.sml]
 type 'a   printer = outstream * 'a -> unit
 type 'a   transformer = 'a -> 'a
 [closing Extensions.sml]
 val it = () : unit
 [opening Utilities.sig.sml]
 signature Utilities =
   sig
     val assoc : ''a * (''a * 'b) list -> 'b option
     val butlast : 'a list -> 'a list
     val cartesian_product : 'a list * 'b list -> ('a * 'b) list
     val display_list : string * string * string * 'a printer -> 'a list printer
     val display_pair : string * string * string * 'a printer * 'b printer -> ('a * 'b) printer
     val error : string * string -> 'a
     val is_prefix : ''a list * ''a list -> bool
     val makestring_list : string * string * string * ('a -> string) -> 'a list -> string
     val member : ''a * ''a list -> bool
     val replace_prefix : (''a list * ''a list) * ''a list -> ''a list
     val update_alist : ''a * 'b * (''a * 'b) list -> (''a * 'b) list
   end
 [closing Utilities.sig.sml]
 val it = () : unit
 [opening Strings.sig.sml]
 signature Strings =
   sig
     type T
     val < : T * T -> bool
     val Display : T printer
     val Hash : T -> int
     val MakeString : T -> string
     val New : string -> T
   end
 [closing Strings.sig.sml]
 val it = () : unit
 [opening Aliases.sig.sml]
 signature Aliases =
   sig
     type Aliases
     type Path
     datatype Accessor
       con IntAcc : int -> Accessor
       con NamedAcc : string -> Accessor
     val ++ : Path * Accessor -> Path
     val Add : Path * Path -> Aliases transformer
     val Adds : Path list * Path list -> Aliases transformer
     val Aliased : Path * Path -> Aliases -> bool
     val Aliases : Path * Aliases -> Path list
     val DisplayAccessor : Accessor printer
     val DisplayPath : Path printer
     val MakeStringAcc : Accessor -> string
     val MakeStringPath : Path -> string
     val NewPath : Accessor list -> Path
     val PathDrop : Path * int -> Path
     val PathLength : Path -> int
     val PathNth : Path * int -> Accessor
     val Remove : Path list -> Aliases transformer
     val SetVariable : Path * Path -> Aliases transformer
   end
 [closing Aliases.sig.sml]
 val it = () : unit
 [opening Object.sig.sml]
 signature Object =
   sig
     type T
     val Display : T printer
   end
 [closing Object.sig.sml]
 val it = () : unit
 [opening OrderedSet.sig.sml]
 signature OrderedSet =
   sig
     type T
     val < : T * T -> bool
     val Display : T printer
   end
 [closing OrderedSet.sig.sml]
 val it = () : unit
 [opening Map.sml]
 Map.sml:125.6-127.68 Warning: match not exhaustive
	 tree ((key,_),_,empty,_) => ...
	 tree ((key,_),_,nonempty_subtree,_) => ...
 pid 4566 (sml) was killed on unaligned access, at pc 0x6016e0

 Process SML bus error

Comments:
 The files loaded in "use.sml" are indeed necessary to reproduce the
 bug. Removing any one of them suppresses that particular occurence of
 the bug, bug, but only shifts the problem.

Fix:
 Perhaps the GC, as suggested by the vanishing nature of
 the bug.

Enclosed files: see bug285.tarmail
Status: probably fixed by 0.73
-------------------------------------------------------------------------------
286. Compiler bug: inststr NULLstr
Submitter: Bob Harper (Robert.Harper@cs.cmu.edu)
Date: 9/6/90
Version: ?
Severity: minor
Problem:
  Compiler bug secondary error
Code:
    functor AbsSyn( structure Id : ID and UnOp : UNOP 
                                      and BinOp : BINOP ): ABSSYN =
     struct end;
    structure AbsSyn : ABSSYN = AbsSyn( structure Id = Id );

    (* because I forgot to add in the extra parameters *)

Transcript:
    The result on execution is:

    /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: UnOp
    /tmp/sml.tmp.k01743:2.5-2.10 Error: unmatched structure spec: BinOp
    Error: Compiler bug: inststr NULLstr
Status: fixed in 0.70
-------------------------------------------------------------------------------
287. cosine function incorrectly defined
Submitter:  Valerio Pinci
Date: SEPT 6, 1990
Version: 0.62
System: Sparc Station 1, SUN OS 0.43
Severity: major
Problem: cos function returns wrong values.
Code:
  cos 0.0;
Transcript:
  - cos 0.0;
  val it = 0.0 : real
Fix:
   In boot/math.sml, change "fun cos x = sin(PI-x)" to
   "fun cos x = sin(PIo2-x)".
Status: fixed in 0.66
-------------------------------------------------------------------------------
288.  extraneous "match not exhaustive" warning
Submitter:      John (jhr@cs.cornell.edu)
Date:		9/8/90
Version:        0.64
System:         sun-4
Severity:       minor
Problem:        extraneous "match not exhaustive" warning
Code:
Transcript:     <transcript of session illustrating problem>

  Standard ML of New Jersey, Version 0.64, 24 August 1990
  val it = () : unit
  - fun f 0 = 0 | f i = 1;
  std_in:1.5-1.21 Warning: match not exhaustive
  val f = fn : int -> int
  - fun f 0 = 0 | f _ = 1;
  std_in:3.5-3.21 Warning: match not exhaustive
  val f = fn : int -> int
  - f 5;
  val it = 1 : int

Comments:

[Appel] I tried this on version 0.64 on our dec 5810, and it works fine
(no extraneous "match not exhaustive" messages).  Was yours a profiling
version or something like that?

I tried it on a sun-4 here (version 0.64) and the bug did not show up,
so it's not machine-specific.

Status: fixed in 0.69
-------------------------------------------------------------------------------
289. 0.65 prerelease  core dumps
Submitter: Bob Ballance (ballance@cascade.cs.unm.edu
Date: 9/13/90
Version: 0.65
System: ?
Severity: critical
Problem:  core dump
Code:
>>>>>>>>>> Sample file --- Causes failure of 0.65. Running "agcd" after
failed load causes core dump.<<<<<<<<<
(*
 *	Stephen R. Wheat, 9/6/90
 *	CS550 - HW1
 *)

(*
 * Find the greatest common divisor
 *)
fun gcd(1,b) = 1	(* avoid an endless situation *)
    | gcd(a,1) = 1	(* avoid an endless situation *)
    | gcd(0,b) = b	(* most likely the one evenly divides the other *)
    | gcd(a,0) = a	(* most likely the one evenly divides the other *)
    | gcd(a,b) =
	if (a<b) then
	    gcd(a,b mod a)
	else
	    (* if they are equal, the next recursion will get the answer *)
	    gcd(a mod b,b);

(*
 * My own absolute value function
 *)
fun abs(a) = if (a<0) then ~a else a;

(*
 * Find the gcd, regardless of the signs of the parameters
 *)
fun agcd(a,b) = gcd(abs(a),abs(b));

(*
 * Convert a rational number (represented as a 2-tuple) into its reduced form
 *)
fun reduce(a,b) = 
    let val c = agcd(a,b)
    in
	if (c = 1) then
	    (* this avoids an endless recursion *)
	    (a,b)
	else
	    reduce((a div c),(b div c))
    end;
Status: fixed in 0.69
-------------------------------------------------------------------------------
290. bin files of share/noshare versions are incompatible
Submitter: Eric Cooper (Eric.Cooper@cs.cmu.edu)
Date: 9/18/90
Version: 0.65
System: ?
Severity: minor
Problem:
    The one problem I still have is that sml-noshare gets an illegal
    instruction when it tries to import a .bin file written by the sharable
    sml, and vice versa.  Also, the .bin files produced by sml-noshare are
    much larger than those produced by sml. For example, compiling
    stream.sig.sml produces the following .bin files:

    -rw-r--r--  1 ecc         2664 Sep 18 13:04 obj/stream.sig.bin
    -rw-r--r--  1 ecc        14904 Sep 18 13:17 obj-noshare/stream.sig.bin
Code:
    (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

    (* STREAM: signature for a lazy stream.*)

    signature STREAM =
     sig type 'xa stream
	 val streamify : (unit -> '_a) -> '_a stream
	 val cons : '_a * '_a stream -> '_a stream
	 val get : '_a stream -> '_a * '_a stream
     end
Comments:  same as 282
Status: Fixed (defunct feature)
-------------------------------------------------------------------------------
291. floating point on sparc
Submitter: Bernard Sufrin
Date: 9/18/90
Version: 0.56
System: Sparc
Problem:
The ``bad'' functions seem to compile incorrectly on Sparc machines
but ok on 68020 machines. Looks like >=0.0 is compiled wrongly, but the
circumstances are mystifying.  Why does the presence of the pair parameter seem
to be critical (offset calculation in the machine-specific code-generator?).

Code:

(* try ??bad(0.0, 0.0) (~0.2) *)

    fun  bad (x, y)  l =
       if l >= 0.0 then  x else bad(x+l, y) (~l);
    fun  alsobad (x, y)  l =
       if l>0.0  orelse  l=0.0 then  x else alsobad(x+l, y) (~l);
    fun  good (x, y)  l =
       if 0.0 <= l then  x else good(x+l, y) (~l);
    fun  alsogood x y  l =
       if l >= 0.0 then  x else alsogood(x+l) y (~l);

Status: fixed in 0.65
-------------------------------------------------------------------------------
292. debugger and interpreter incompatible
Submitter:      Todd Knoblock
		Todd@eecs.umich.edu
Date:		24 September 1990

Version:        0.65
System:         Decstation 3100 under bsd AND Sun4/sparc under sunos
Severity:       Very Minor
Problem:        Compilation of sml with interpretor and debug packages fails

Transcript:     command: makeml -decstation bsd -i -debug
		      or makeml -sun4 sunos -i -debug
appears to progress normally until


[closing dbguser/hio.sml]
val it = () : unit
[opening dbguser/hstore.sml]
[opening debug/weak.sml]
Error: Compiler bug: bad primop in interp
[closing debug/weak.sml]
[closing dbguser/hstore.sml]
[closing dbguser/userlevel.sml]


Comments:

Running the compilation without the -i works on both platforms.
If the interpretor and debugger are truly incompatible, then
makeml should flag it.
(apt) They aren't incompatible: the interpreter was broken.

Status: fixed as of 0.88, but interpreter breaks elsewhere on debugger code.
-------------------------------------------------------------------------------
293. debug problems
Submitter:     	Todd Knoblock, todd@eecs.umich.edu
Date: 		26 September 1990
Version:	SML 0.65, emacs 18.55.1
System:		Decstation under ultrix and Sun sparc under sunos
Severity:	error message: minor, no output: critical

Synopsis:

I am having two problems with the emacs debug package.

The first is quite minor: on start-up on a non-x-display (like my
terminal at home), emacs reports the following error when loading
sml-init: file mode specification error:
(void-variable-x-button-m-left).

The second is more serious.  When sending to the sml process, I do not
get output until I move (c-x o/c-x b) into the process buffer.  For example, 
if I have this in a buffer

fun f(0) = 1
  | f(x) = x*(f (x-1));

and type c-c c-c, then if sml has not been run before, emacs
will bring up a window, and start it properly.  However, the
only output is 

Standard ML of New Jersey, Version 0.65, 10 September 1990
val it = () : unit
- emacsInit (); cd "/afs/engin.umich.edu/user/t/o/todd/";
[opening /tmp/sml.tmp.a02351]


Once I move into the buffer, then I get the rest of the output:


val f = fn : int -> int
[closing /tmp/sml.tmp.a02351]

If sml is already running, and the window is not visible, then
sending to the buffer does not cause it to become visible.

Comments:

If I disable the debugging code, by removing the two "hooks"
in sml-init, then the interface works as in the past.  I am
running emacs version 18.55.1, and have tried it on two platforms:
decstation under ultrix, and a sparc under sunos.  Finally, it 
appears that the file outdent.el is redundant now, and could be
removed from the distribution.

Comments: [apt, 2/1/93]
These bugs aren't fixed.
The first is just a trivial error message.
As to the second: we don't really guarantee that c-c c-c and similar
emacs interface tricks will work with the debugger.

You could "not a bug" these if you want, though they should get addressed
eventually -- I deliberately didn't spend time on minor emacs-related
problems last summer.

Status: open
-------------------------------------------------------------------------------
294. weak polymorphic types
Submitter: David Berry
Date: 9/24/90
Version: 0.65
Severity: major
Problem:
  The Memo structure in the Library still doesn't compile under SML-NJ 0.65
  It compiles under Poly/ML, and is based on a version for Edinburgh ML.
Transcript:
- use "memo.sml";
[opening memo.sml]
[opening ../signatures/Memo.sml]
signature Memo =
  sig
    val memo : (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a
-> '_b) * ('a -> '_b)
    val memo2 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_
c) -> 'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c)
    val memo3 : (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> (
('a -> '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_
d) * ('a -> '_b -> '_c -> '_d)
    val version : real
  end
[closing ../signatures/Memo.sml]
val it = () : unit
memo.sml:41.7-53.33 Error: nongeneric weak type variable
  memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU
-> '~3Z) * ('aU -> '~3Z)
memo.sml:41.7-53.33 Error: nongeneric weak type variable
  memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU
-> '~3Z) * ('aU -> '~3Z)
memo.sml:41.7-53.33 Error: nongeneric weak type variable
  memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU
-> '~3Z) * ('aU -> '~3Z)
memo.sml:41.7-53.33 Error: nongeneric weak type variable
  memo : (Nat -> Nat) -> ('aU -> Nat) -> (('aU -> '~3Z) -> 'aU -> '~3Z) -> ('aU
-> '~3Z) * ('aU -> '~3Z)
memo.sml:58.5-58.76 Error: operator and operand don't agree (circularity)
  operator domain: ('Z -> '~3Y) -> 'Z -> '~3Y
  operand:         ('Z -> '~3Y) -> 'Z -> '~3X -> '~3Y
  in expression:
    memo expfn injy ((fn _ => (fn <rule>)))
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:60.5-63.43 Error: nongeneric weak type variable
  memo3 : (Nat -> Nat) -> ('W -> Nat) -> ('Z -> Nat) -> ('~3X -> Nat) -> (('W ->
 '~3V) -> 'W -> 'Z -> '~3X -> '~3V) -> ('W -> '~3V) * ('W -> '~3V)
memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec
  name: memo
  spec:   (Nat -> Nat) -> ('a -> Nat) -> (('a -> '_b) -> 'a -> '_b) -> ('a -> '_
b) * ('a -> '_b)
  actual: (Nat -> Nat) -> ('a -> Nat) -> (('a -> '~3Z) -> 'a -> '~3Z) -> ('a ->
'~3Z) * ('a -> '~3Z)
memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec
  name: memo2
  spec:   (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> (('a -> '_b -> '_c) ->
'a -> '_b -> '_c) -> ('a -> '_b -> '_c) * ('a -> '_b -> '_c)
  actual: (Nat -> Nat) -> ('a -> Nat) -> ('~3Z -> Nat) -> (('a -> '~3Y) -> 'a ->
 '~3Z -> '~3Y) -> error
memo.sml:15.1-65.3 Error: value type in structure doesn't match signature spec
  name: memo3
  spec:   (Nat -> Nat) -> ('a -> Nat) -> ('_b -> Nat) -> ('_c -> Nat) -> (('a ->
 '_b -> '_c -> '_d) -> 'a -> '_b -> '_c -> '_d) -> ('a -> '_b -> '_c -> '_d) * (
'a -> '_b -> '_c -> '_d)
  actual: (Nat -> Nat) -> ('a -> Nat) -> ('b -> Nat) -> ('~3Z -> Nat) -> (('a ->
 '~3Y) -> 'a -> 'b -> '~3Z -> '~3Y) -> ('a -> '~3Y) * ('a -> '~3Y)
[closing memo.sml]
-
Comment: for Memo.sml to compile, the name of structure Array in Bytearray.sml
has to be changed.
Status: fixed in 0.74
-------------------------------------------------------------------------------
295. Compiler bug: r_o in mcopt
Submitter: Kung Chen
Date: 9/30/90
Version: 0.56
System: Sparc, Sun OS
Problem: the optimization phase of pattern-mtaching dies
Code:
(* Categorical Abstract Machine simulator*)
(* D. Rabin, 5-aug-90, translated to SML by K. Chen, 10-sept-90*)

structure Cam = struct

(* CAM instructions*)

datatype 'val CAMinstr  = QuoteInstr  of 'val 
		  | PrimInstr of int * string
		  | AccInstr of int
		  | ConsInstr
		  | CdrInstr
		  | CarInstr
		  | PushInstr
		  | SwapInstr
		  | BranchInstr of 'val CAMinstr list * 'val CAMinstr list
		  | CurInstr of 'val CAMinstr list
		  | AppInstr
		  | ReturnInstr
		  | UpdInstr
		  | IdInstr 

type  'val Code = 'val CAMinstr list

datatype 'const Val  = Simple of 'const
               | Close of 'const Val * 'const Val CAMinstr list
               | Pair of 'const Val * 'const Val 
               | Truth of bool
               | Save of 'const Val CAMinstr list

(* CAM state*)

datatype  'const CAMstate  = 
              CAMst of 'const Val * 'const Val list * (('const Val) CAMinstr) list 
             | Halt 

(* CAM state transition function*)

(* fun step : 'const CAMstate  -> 'const CAMstate *)

fun step CAMst(x, s, []) = Halt
|step CAMst(x, s, IdInstr::is) = CAMst(x, s, is)
|step CAMst(Pair(x, y), s, CarInstr::is) = CAMst(x ,s, is)
|step CAMst(Pair(x, y), s, CdrInstr::is) = CAMst(y, s, is)
|step CAMst(x, s , PushInstr::is) = CAMst(x, (x :: s), is)
|step CAMst(x, (y :: s), SwapInstr::is) = CAMst(y ,(x :: s), is)
|step CAMst(x, (y :: s), ConsInstr::is) = CAMst(Pair(x, y), (x :: s), is)
|step CAMst(x, s, CurInstr(code)::is) = CAMst(Close(x, code), s ,is)
|step CAMst(Pair(Close(x, code), y), s, AppInstr :: is)
  = CAMst(Pair(x, y), Save(is)::s, code)
|step CAMst(x, Save(code)::s, ReturnInstr::is) = CAMst(x, s, code)
|step CAMst(x, s, QuoteInstr(c)::is) = CAMst(c, s, is)
|step CAMst(Pair(x,Truth(true)), s, BranchInstr(ifTrue, ifFalse)::is)
  = CAMst(x, s, ifTrue)
|step CAMst(Pair(x, Truth(false)), s, BranchInstr(ifTrue, ifFalse)::is)  
  = CAMst(x, s, ifFalse)
|step CAMst(x, (y :: s), UpdInstr::is) = CAMst(y, s, is)

end

Transcript:
- use "cam.sml";
[opening cam.sml]
Error: Compiler bug: r_o in mcopt
[closing cam.sml]

Status: fixed in 0.69
-------------------------------------------------------------------------------
296. patch for HP/MORE
Submitter:      Brian Boutel (brian@comp.vuw.ac.nz)
Date:           11 Oct 90
Version:        0.66
System:         m68020 (H-P workstation)  more/bsd
Severity:       
Problem:        source error in src/runtime/ml_os.h. Will not
		compile.
Code:           n/a
Transcript:     n/a
Comments:       I reported this for 0.56, the first version in which
my patches for more/bsd on H-P workstations were included. The line
in the source has been changed, but only to include the same fix for
NeXT machines.

Fix: src/runtime/ml_os.h. Add the underlined code:

/* where to find syscall.h, used for getting the #define SYS_open */
#if defined(VAX) || defined(NeXT) || defined(MORE)
                                  ~~~~~~~~~~~~~~~~
#include <syscall.h>
#else
#include <sys/syscall.h>
#endif

Status: fixed in 0.71
-------------------------------------------------------------------------------
297. Bits.lshift on Sun4
Submitter:      Eric Cooper <ecc@cs.cmu.edu>
Date:		  11 October 1990
Version:        Standard ML of New Jersey, Version 0.66, 15 September
1990
System:         Sun4, both SunOS and Mach
Severity:       minor
Problem:

1. Calls to Bits.lshift with constant arguments that should raise
Overflow cause a compiler error message instead.

2. With non-constant arguments, Bits.lshift expressions that should
raise Overflow don't.

Code:

(1)	Bits.lshift(1,30);

(2)	fun lshift (x, y) = Bits.lshift (x, y);
	lshift (1, 30);
	lshift (1000000, 64);

Transcript:

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- fun lshift (x, y) = Bits.lshift (x, y);
val lshift = fn : int * int -> int
- lshift (1, 30);
val it = ~1073741824 : int	(* should raise Overflow *)
- lshift (1000000, 64);
val it = 1000000 : int	(* shifting by any multiple of 32 appears to be
equivalent to shifting by 0; should raise Overflow *)
- Bits.lshift (1, 30);
Error: Compiler bug: [SparcCM.ashr]
- ();
SIGILL code 0x2

Comments:

[Cooper] The number of bits to shift is evidently being reduced modulo 32.

[jhr] The lshift operation does not raise Overflow (Andrew's
decision).  I'll look at the other problem.

[jhr] When there is a compiler bug (at least in the backend), the
state of the system gets screwed up in such a way that the system core
dumps.  Is it possible to do a better job of cleaning up when a
compiler bug is detected?  An example is (on 0.66/sparc)

  - Bits.lshift (1, 30);
  Error: Compiler bug: [SparcCM.ashr]
  - ();
  SIGILL code 0x2

[appel]  I don't see where the Definition of Standard ML says that lshift
should raise Overflow!

Status: fixed in 0.66?
-------------------------------------------------------------------------------
298. tags inconsistency
Submitter:      Allen Leung   allen@sbcs.sunysb.edu
Date:           12 Oct 1990
Version:        NJSML v0.66
System:         sun4
Severity:       very minor
Problem:        runtime tags of evaled and unevaled suspension has been
                reversed
Comments:
      The runtime tags of evaluated and unevaluated suspension 
in System.Tags are inconsistent with the ones in tags.h

Status: ok in 0.70
-------------------------------------------------------------------------------
299. user-bound tyvars
Submitter: John Reppy
Date: 
Version: 0.66
Severity: major
Problem:
   There are two versions of the first line of the sync function: one
   produces the error, the other works.
Transcript:
  Standard ML of New Jersey, Version 0.66, 15 September 1990
  val it = () : unit
  - use "compbug.sml";
  [opening compbug.sml]
  compbug.sml:8.3-57.5 Error: value type in structure doesn't match signature spec
    name: sync
    spec:   'a event -> 'a
    actual: 'a event -> 'aU
  [closing compbug.sml]

Code: compbug.sml
signature INTERNAL_CML =
  sig
    type 'a event
    val sync : 'a event -> 'a
  end

functor ConcurML () : INTERNAL_CML =
  struct

    exception Never and Escape
    exception Sync (* for signature compatability *)

    datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK

    type 'a base_evt = {
	pollfn : unit -> evt_sts,
	dofn : unit -> 'a,
	blockfn : bool ref -> 'a
      }

    datatype 'a event = EVT of 'a base_evt list

    local
      datatype 'a ready_evts
	= NO_EVTS				(* no ready events *)
	| ANY_EVTS of (int * (unit -> 'a) list)	(* list of ready anyevents *)
	| RDY_EVTS of (int * (unit -> 'a) list)	(* list of ready events *)

      fun extract _ = NO_EVTS

    (* Generate index numbers for "non-deterministic" selection.  We use a
     * round-robin style policy. *)
      val cnt = ref 0
      fun random i = let val j = !cnt in cnt := j+1; (j mod i) end
      fun selectEvt (_, [f]) = f()
	| selectEvt (n, l) = (nth(l, random n)) ()
    in

  (* sync : 'a event -> 'a *)
    fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **)
    (* fun sync ((EVT []) : 'a event) = raise Never *)  (** THIS WORKS **)
      | sync (EVT el) = (
	  case (extract el)
	   of NO_EVTS => callcc (fn sync_k => let
		val evtflg = ref false
		fun log ({blockfn, ...} : 'a base_evt)=
		      (throw sync_k (blockfn evtflg)) handle Escape => ()
		in
		  app log el;
		  (*atomicDispatch()*) raise Sync
		end)
	    | ANY_EVTS anyevts => selectEvt anyevts
	    | RDY_EVTS evts => selectEvt evts)

    end (* local *)
  end (* functor ConcurML *)

Status: not a bug? (check with MacQueen)
-------------------------------------------------------------------------------
300. uncaught exceptin RegBind
Submitter: Soren Christensen,
           University of Aarhus, Computer Science Dep.,
           Denmark
           schristensen@daimi.dk
Date:      17 oct 90
Version:   0.65
System:    Sun4/280 / SunOS 4.0.1
Severity:  Critical
Problem:
Code:

(* filename: nb *)
datatype ''a ms =  !! of ( (int * ''a) * (''a ms) ) | empty;

fun cr (0,_) = empty
  | cr (coef,col) = (!!((coef,col),empty));

fun foo (c:int ms ref) =
 true
andalso (1 =  length [1])
andalso (cr (1,1) = (!c))
andalso (empty =  (!c));

Transcript:

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- use "nb";
[opening nb]
datatype 'a  ms
con !! : (int * 'a) * 'a ms -> 'a ms
con empty : 'a ms
val cr = fn : int * 'a -> 'a ms
[closing nb]

uncaught exception Regbind
- val x = 5;
Illegal instruction

Status: fixed in 0.69
-------------------------------------------------------------------------------
301. Compiler bug: tycPath
Submitter: Andrew Appel
Date: 10/24/90
Version: 0.66
Severity: minor
Problem:
  The following program gets   Error: Compiler bug: tycPath
  after all the syntax errors.  Perhaps it should be a CASCADE.
Code:
    struct VMat :
    sig
	type v4 = real*real*real*real
	type m4 = v4*v4*v4*v4
	val vmul = v4*v4 -> v4
	val vdot = v4*v4 -> real
	val vmmul = v4*m4 -> v4
	val mmul = m4*m4 -> m4
    end =
    struct

    fun vmul((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) =
	(v1x * v2x, v1y * v2y, v1z * v2z, v1w * v2w)

    fun vdot((v1x, v1y, v1z, v1w), (v2x, v2y, v2z, v2w)) =
	v1x * v2x + v1y * v2y + v1z * v2z + v1w * v2w

    fun vmmul(v, (a, b, c, d)) =
	(vdot(v, a), vdot(v, b), vdot(v, c), vdot(v, d))

    fun mmul((a, b, c, d), m) =
	(vmmul(a, m), vmmul(b, m), vmmul(c, m), vmmul(d, m))

    end

Status: fixed in 0.71
-------------------------------------------------------------------------------
302. match not exhaustive warnings from import have wrong location
Submitter:      Peter Canning <canning@hplabs.hp.com>
Date:		24 October 1990
Version:        0.66
System:         68020  HP-UX 7.0
Severity:       major
Problem:        match not exhaustive warnings from import have wrong location
Code:           
functor foo() =
  struct
    datatype T  = I of int
                | B of bool
                | S of string

    fun foo(I i) = i
      | foo(B b) = if b then 1 else 0
  end;
Transcript:     
Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- import "foo";
[reading foo.sml]
foo.sml:0.0-0.0 Warning: match not exhaustive
        I i => ...
        B b => ...
[writing foo.bin... done]
[closing foo.sml]
functor foo
Comments:
The warning message should give line.column different from 0.0-0.0

Status: Fixed (defunct feature)
-------------------------------------------------------------------------------
303. bad error reporting
Submitter:      Nick
Date:		25 Oct 90
Version:        0.66
System:         irrelevant
Severity:       minor
Problem:        junk error reporting

Code:

	foobar + 3;

Transcript:


(OK:)	Comments:std_in:1.1-1.6 Error: unbound variable foobar
(bogus:)std_in:1.1-1.10 Error: operator and operand don't agree (type mismatch)
	  operator domain: undef * undef
	  operand:         undef * int
	  in expression:
	    + (foobar,3)
(bogus:)std_in:1.8 Error: overloaded variable "+" not defined at type:
	   undef

Status: fixed in 0.73
-------------------------------------------------------------------------------
304. SIGEMT on sparc
Submitter: Nick Rothwell
Date: 10/25/90
Version: 0.66
System: sparc
Severity: major
Problem:
  0.66 has a SIGEMT problem on SPARC's, on hitting ^C (sometimes). Will
  try and narrow down if I can.

 Also from Mike Crawley <mjc@abstract-hardware-ltd.co.uk>, in 0.73:
  I have been able to repeat the following
  bug a number of times. Pressing ^C to interrupt
  sml while it is busy can sometimes crash it.
  The saved image I was using was 10MB at the time.

  ^C
  SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0x9dd8)

  Mike Crawley.
  Abstract Hardware Ltd.

Status: fixed in 0.73
-------------------------------------------------------------------------------
305. Strange floating point error
Submitter:       tmb@ai.mit.edu (Thomas M. Breuel)
Date: 11/28/90
Version:         0.66
System:          Sun4/SunOS4.1
Problem:         division by zero causes "strange floating point error" 
Code:            0.0/0.0
Transcript:     

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- 0.0/0.0;
strange floating point error
Process Inferior sml exited abnormally with code 3

Comments:

Other division-by-zero errors for floating point numbers raise Div.

Status: fixed in 0.69
-------------------------------------------------------------------------------
306. list printing, printlength
Submitter:      tmb@ai.mit.edu
Date:		10/28/90
Version:        SML of NJ 0.66
System:         Sun 4/SunOS 4.0
Severity:       minor
Problem:        extraneous "dots" printed
Code:           [1,2,3,4,5,6,7,8,9,10,11,12];
Transcript:

- [1,2,3,4,5,6,7,8,9,10,11,12,13];
val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list
- [1,2,3,4,5,6,7,8,9,10,11,12];
val it = [1,2,3,4,5,6,7,8,9,10,11,12,...] : int list
- 

Comments:

Since there are no unprinted elements in the 12 element
list, there should be no ellipsis either.
 
Status: fixed in 0.74
----------------------------------------------------------------------------
307. signature matching in 0.69
Submitter:      Greg Morrisett  jgmorris@cs.cmu.edu
Date:           April 29, 1991
Version:        0.67 and 0.69
System:         DECstation 3100, Mach and Sun-3 Mach
Severity:       critical?
Problem:        nested structures and signature matching
Code:           

signature SIG1 =
  sig
    structure T :
      sig
          type t
      end
    structure U :
      sig
          structure V :
              sig
                val s : T.t
              end
      end
  end

structure S : SIG1 =
  struct
      structure T =
          struct
              datatype t = FOO
          end
      structure U =
          struct
              structure V =
                  struct
                      val s = T.FOO
                  end
          end
  end

Transcript:

Standard ML of New Jersey, Version 0.69, 3 April 1991
val it = () : unit
- use "bug.sml";
[opening bug.sml]
$$ lookTycPath 1: 0 0
tyconInContext: [0,0]
[closing bug.sml]

uncaught exception Subscript
-

Comments: I reduced this down to as small a problem as I could.  For instance,
removing any of the enclosing structures makes the bug go away.  This works
under version 0.64 and 0.65.  This came up in some "real" code and there is
no easy work-around...

Fix: ???

Status: fixed in 0.73
---------------------------------------------------------------------------
308. Mips RC6280 code generation bug
Submitter:      Toshinori Maeno <tmaeno@cc.titech.ac.jp>
		Computer Center,
		Tokyo Institute of Technology
Date:		1991-06-01
Version:        0.66 <SML of NJ version number>
System:         MIPS RC6280, 128MB; Riscos 4.52
Severity:       critical (at least for us :-)
Problem:        makeml dumps core after successful make of runtime/run
Code:
		makeml -mips riscos
Transcript:     
makeml> (cd runtime; make clean)
	rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.mipsb mo
makeml> (cd runtime; rm -f run allmo.o allmo.s)
makeml> (cd runtime; make MACHINE=MIPS 'CFL= -systype bsd43' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata)
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c
makeml> runtime/linkdata [runtime/IntMipsBig.mos]
runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
makeml> (cd runtime; make MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as')
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c run_ml.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c callgc.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c gc.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c
	/lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s
	as -o prim.o prim.s
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c export.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c timers.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c ml_objects.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cfuns.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c cstruct.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c signal.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c exncode.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -c malloc.c
	cc -g -signed -systype bsd43 -DMIPS -DRISCos -o run run.o run_ml.o callgc.o gc.o MIPS.dep.o prim.o export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o  allmo.o
makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 4096 -r 20 -h 2048 IntMipsBig

[Increasing heap to 2049k]
[Loading mo/CoreFunc.mo]
[Executing mo/CoreFunc.mo]
[Loading mo/Math.mo]
[Executing mo/Math.mo]
[Loading mo/Initial.mo]
[Executing mo/Initial.mo]
makeml: 18680 Illegal instruction - core dumped
         ^
	This number may be different for another run.

Comments:	On MIPS RC3240, makeml successfully made sml.
		runtime/run made on RC6280 works on RC3240 without problem.
		runtime/run made on either system dumps core on RC6280.
		0.68 reproduced the same problem.
		I disabled FlushIcache, but could not get improvement.
		I shall report this to MIPS, too.
[jgm] 
I assume this is the problem of using the branch delay slots for
some non-standard reason?

Status: Fixed in 0.70; other RC6280 problems not quite fixed in 0.71.
---------------------------------------------------------------------------
309: NeXTstation exported image doesn't work
Submitter: oneill@cs.sfu.ca
Date: 28 Mar 91
Version: 0.68
System: NeXTstation
Severity: 
Problem: boots and exports, but exported image bombs with SEGV when invoked
Fix:
Heres the changes I made to get as far as I got, (note, TRAP #2 on a 
NeXT flushes the 68040 code cache, which is necessary after a gc).

	Richard,

	(used to be {cmp7130,rmo}@sys.uea.ac.uk)

my diffs (w.r.t 0.68)...

diff -r -c runtime.orig/callgc.c runtime/callgc.c
*** runtime.orig/callgc.c	Wed Mar  6 11:50:57 1991
--- runtime/callgc.c	Thu Mar 21 15:19:19 1991
***************
*** 86,95 ****
--- 86,103 ----
      int		live_size = old_high - arenabase;
      int		a = 0;
      ML_val_t	x = gcmessages;
+ #ifdef NeXT
+     extern void * get_edata();
+ #else
      extern int	edata;
+ #endif
  
      resettimers();
+ #ifdef NeXT
+     lastbreak = (int)get_edata();
+ #else
      lastbreak = (int)&edata;
+ #endif
      gcmessages = INT_CtoML(0);
      new_size = compute_new_size(live_size);
      do {
***************
*** 330,335 ****
--- 338,346 ----
      arend = arenabase+arenasize;
      arstart = (((arend+old_high)/2)+3)&(~3);
      (*arptr) = arstart;
+ #ifdef NeXT
+     asm("trap #2");
+ #endif
  
  } /* end of callgc */
  
diff -r -c runtime.orig/export.c runtime/export.c
*** runtime.orig/export.c	Wed Nov 21 11:34:06 1990
--- runtime/export.c	Thu Mar 21 15:08:53 1991
***************
*** 87,93 ****
--- 87,97 ----
   *  > set a_entry as address of start procedure
   */
  
+ #ifdef NeXT
+     extern void * get_etext();
+ #else
  extern int etext;   /* &etext is just beyond the end of the text segment */
+ #endif
  extern int old_high;
  
  static int textstart,datastart;
***************
*** 425,432 ****
  int datasize, bsssize;
  
  E.magic = MH_MAGIC;
! E.cputype = CPU_TYPE_MC68030;
! E.cpusubtype = CPU_SUBTYPE_NeXT;
  E.filetype = MH_EXECUTE;
  E.ncmds = 3;
  E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
--- 429,436 ----
  int datasize, bsssize;
  
  E.magic = MH_MAGIC;
! E.cputype = CPU_TYPE_MC680x0;
! E.cpusubtype = CPU_SUBTYPE_MC68040;
  E.filetype = MH_EXECUTE;
  E.ncmds = 3;
  E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
***************
*** 442,448 ****
  tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
  strcpy(tcmd.segname,SEG_TEXT);
  tcmd.vmaddr = textstart;
! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart;
  tcmd.fileoff = 0;
  tcmd.filesize = tcmd.vmsize;
  tcmd.maxprot = VM_PROT_ALL;
--- 446,452 ----
  tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
  strcpy(tcmd.segname,SEG_TEXT);
  tcmd.vmaddr = textstart;
! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart;
  tcmd.fileoff = 0;
  tcmd.filesize = tcmd.vmsize;
  tcmd.maxprot = VM_PROT_ALL;


>From cs.cornell.edu!jhr Fri Mar 29 10:46:22 0500 1991
Received: by coma; Fri Mar 29 10:46:27 EST 1991
Received: by inet.att.com; Fri Mar 29 10:46 EST 1991
Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N)
	id AA21402; Fri, 29 Mar 91 10:46:22 -0500
Date: Fri, 29 Mar 91 10:46:22 -0500
From: jhr@cs.cornell.edu (John Reppy)
Message-Id: <9103291546.AA27105@maui.cs.cornell.edu>
Received: by maui.cs.cornell.edu (5.65/N-0.12)
	id AA27105; Fri, 29 Mar 91 10:46:20 -0500
To: appel@princeton.edu, dbm@research.att.com
Subject: Re:  NeXT 68040 attempt
Status: R

I have integrated Richard O'Neill's changes into my 0.68, in a style that is
more consistant with the runtime system.  Here are the diffs; maybe they can
be included in 0.69.  (BTW, there are probably still some other changes needed
to make this work).
  - John


<jhr@maui:97> diff -c ml_os.h ml_os.h.ORIG
*** ml_os.h     Fri Mar 29 10:40:07 1991
--- ml_os.h.ORIG        Wed Nov 21 14:34:31 1990
***************
*** 111,122 ****
          (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0))
  #  endif
  #else
! #ifdef NeXT
! #  define FlushICache(addr, size)     asm ("trap #2")
! #else
! #  define FlushICache(addr, size)
  #endif
- #endif
  
  #if defined(MACH) && defined(MIPS)
  
--- 111,118 ----
          (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0))
  #  endif
  #else
! #define FlushICache(addr, size)
  #endif
  
  #if defined(MACH) && defined(MIPS)
  
***************
*** 158,163 ****
--- 154,160 ----
  #define READDIR(fd,buf,sz)    getdirentries((fd), (buf), (sz), &dummy)
  #endif
  
+ 
  #if defined(BSD) || defined(RISCos) || defined(HPUX) || defined(SGI)
  #define HAS_WRITEV
  #include <sys/uio.h>
***************
*** 164,175 ****
  #define HAS_NONBLOCKING_IO
  #endif
  
! #ifdef NeXT
! extern void *get_edata();
! # define EDATA                ((int)get_edata())
! #else
! extern int edata;
! # define EDATA                ((int)(&edata))
! #endif
  
  #endif !_ML_OS_
--- 161,167 ----
  #define HAS_NONBLOCKING_IO
  #endif
  
! 
! 
  
  #endif !_ML_OS_



<jhr@maui:98> diff -c callgc.c callgc.c.ORIG
*** callgc.c    Fri Mar 29 10:41:06 1991
--- callgc.c.ORIG       Wed Mar  6 14:50:57 1991
***************
*** 86,94 ****
      int               live_size = old_high - arenabase;
      int               a = 0;
      ML_val_t  x = gcmessages;
  
      resettimers();
!     lastbreak = EDATA;
      gcmessages = INT_CtoML(0);
      new_size = compute_new_size(live_size);
      do {
--- 86,95 ----
      int               live_size = old_high - arenabase;
      int               a = 0;
      ML_val_t  x = gcmessages;
+     extern int        edata;
  
      resettimers();
!     lastbreak = (int)&edata;
      gcmessages = INT_CtoML(0);
      new_size = compute_new_size(live_size);
      do {

>From cs.sfu.ca!oneill Wed Apr 24 18:22:39 EDT 1991
Received: by coma; Wed Apr 24 18:22:39 EDT 1991
Received: by inet.att.com; Wed Apr 24 18:22 EDT 1991
Received: by relay.CDNnet.CA (4.1/1.14)
	id AA23566; Wed, 24 Apr 91 15:20:58 PDT
From: <oneill@cs.sfu.ca>
Date: 24 Apr 91 15:13 -0700
To: dbm@research.att.com
Cc: jhr@cs.cornell.edu
Message-Id: <9104242213.AA15593@phoenix.cs.sfu.ca>
Subject: Re: Getting Sml up and running on a NeXT running OS2.[01]
Status: R

Long long ago, you (dbm) wrote:
> I think we should have SML of NJ running on the 68040 NeXTs soon,
> since John Reppy has just bought one of them (to write his thesis
> on).  He is confident he can get SML running on it quite quickly.
> I'll forward your message to him, since it looks like a useful start
> on the problem.

John Reppy also wrote:
> It may be a while before I can fix this, since I still need to get a decent
> sized disk.

Well, after a month of messing about with other things, I finally got arround
to getting sml working the NeXT (my NeXT arrived and so I could work on it at
home). I'll tell you the problem and give my diffs. 

The problem was that, among the various load commands needed in the
executable's header, one is needed to load the c shared library, and this was
ommited (since previously programs weren't *forced* into using the shared
libraries).  Since the load command is always exactly the same, I did a
ghastly hack and substituted the thing in as a constant (array stuffed with
the right hex numbers). This isn't quite the cleanest thing to do, but I was
only concerned with getting it to work for me. (Yeah, I know, I'm lazy...)

Anyway, diffs follow, and it at least it works now...

	Richard,

---8<--cut-here--(and ruin your monitor)--cut-here--8<---

*** export.c.orig       Wed Nov 21 11:34:06 1990
--- export.c    Wed Apr 10 17:06:57 1991
***************
*** 87,93 ****
--- 87,98 ----
   *  > set a_entry as address of start procedure
   */
  
+ #ifndef NeXT
  extern int etext;   /* &etext is just beyond the end of the text segment */
+ #else
+ extern void *get_etext();
+ #endif
+ 
  extern int old_high;
  
  static int textstart,datastart;
***************
*** 422,436 ****
  static unsigned long thcount;
  static struct NeXT_thread_state_regs ntregs;
  static unsigned int hdrsize;
  int datasize, bsssize;
  
  E.magic = MH_MAGIC;
! E.cputype = CPU_TYPE_MC68030;
! E.cpusubtype = CPU_SUBTYPE_NeXT;
  E.filetype = MH_EXECUTE;
! E.ncmds = 3;
  E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
!       + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn)
        + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
  E.flags = MH_NOUNDEFS;
  
--- 427,445 ----
  static unsigned long thcount;
  static struct NeXT_thread_state_regs ntregs;
  static unsigned int hdrsize;
+ static unsigned int lcmd[] = {0x00000006, 0x00000030, 0x00000014, 0x0000002c,
+                     0x05000000, 0x2f757372, 0x2f73686c, 0x69622f6c,
+                     0x69627379, 0x735f732e, 0x422e7368, 0x6c696200};
+ 
  int datasize, bsssize;
  
  E.magic = MH_MAGIC;
! E.cputype = CPU_TYPE_MC680x0;
! E.cpusubtype = CPU_SUBTYPE_MC68040;
  E.filetype = MH_EXECUTE;
! E.ncmds = 4;
  E.sizeofcmds = sizeof(tcmd) + sizeof(tsectn)
!       + sizeof(dcmd) + sizeof(dsectn) + sizeof(bsectn) + sizeof(lcmd)
        + sizeof(uthr) + sizeof(thflavor) + sizeof(thcount) + sizeof(ntregs);
  E.flags = MH_NOUNDEFS;
  
***************
*** 442,448 ****
  tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
  strcpy(tcmd.segname,SEG_TEXT);
  tcmd.vmaddr = textstart;
! tcmd.vmsize = (int) CEIL(((int)&etext),getpagesize())-textstart;
  tcmd.fileoff = 0;
  tcmd.filesize = tcmd.vmsize;
  tcmd.maxprot = VM_PROT_ALL;
--- 451,457 ----
  tcmd.cmdsize = sizeof(tcmd) + sizeof(tsectn);
  strcpy(tcmd.segname,SEG_TEXT);
  tcmd.vmaddr = textstart;
! tcmd.vmsize = (int) CEIL(((int)get_etext()),getpagesize())-textstart;
  tcmd.fileoff = 0;
  tcmd.filesize = tcmd.vmsize;
  tcmd.maxprot = VM_PROT_ALL;
***************
*** 515,520 ****
--- 524,530 ----
   bulletproofWrite(filid,&dcmd,sizeof(dcmd));
   bulletproofWrite(filid,&dsectn,sizeof(dsectn));
   bulletproofWrite(filid,&bsectn,sizeof(bsectn));
+  bulletproofWrite(filid,&lcmd,sizeof(lcmd));
   bulletproofWrite(filid,&uthr,sizeof(uthr));
   bulletproofWrite(filid,&thflavor,sizeof(thflavor));
   bulletproofWrite(filid,&thcount,sizeof(thcount));

>From cs.cornell.edu!jhr Wed Apr 24 20:41:38 0400 1991
Received: by coma; Wed Apr 24 20:42:39 EDT 1991
Received: by inet.att.com; Wed Apr 24 20:42 EDT 1991
Received: from MAUI.CS.CORNELL.EDU by cloyd.cs.cornell.edu (5.65/I-1.98N)
	id AA00996; Wed, 24 Apr 91 20:41:38 -0400
Date: Wed, 24 Apr 91 20:41:38 -0400
From: jhr@cs.cornell.edu (John Reppy)
Message-Id: <9104250041.AA16310@maui.cs.cornell.edu>
Received: by maui.cs.cornell.edu (5.65/N-0.12)
	id AA16310; Wed, 24 Apr 91 20:41:37 -0400
To: dbm@research.att.com, oneill@cs.sfu.ca
Subject: Re: Getting Sml up and running on a NeXT running OS2.[01]
Cc: appel@cs.cornell.edu, jhr@cs.cornell.edu
Status: R

> From oneill@cs.sfu.ca Wed Apr 24 18:22:04 1991
> 
> Long long ago, you (dbm) wrote:
> > I think we should have SML of NJ running on the 68040 NeXTs soon,
> > since John Reppy has just bought one of them (to write his thesis
> > on).  He is confident he can get SML running on it quite quickly.
> > I'll forward your message to him, since it looks like a useful start
> > on the problem.
> 
> John Reppy also wrote:
> > It may be a while before I can fix this, since I still need to get a decent
> > sized disk.
> 
> Well, after a month of messing about with other things, I finally got arround
> to getting sml working the NeXT (my NeXT arrived and so I could work on it at
> home). I'll tell you the problem and give my diffs. 
> 
> ...

Thanks for the fix.  I'll merge these diffs into 0.69, and it should part
of 0.70 (whenever that is).
  - John

[jgm]
Rumor has it that jhr has 0.69 running on the NeXTstation?

Status: Fixed?

---------------------------------------------------------------------------
310. HP Cache flush problem
Submitter:      Nick Rothwell
Date:		23 May 1991
Version:        0.66
System:         HP9000/380 (a /300 with go-faster 68040 option)
Severity:       Critical for this system; fairly major overall
Problem:        Bombs with random bus errors or other traps on 68040-based
		HP machines. The build sequence runs, but not much else.
		Maybe it's a problem with saved images or something
Code:           <almost anything>
Transcript:

(i)	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- 3;
	EMT instruction (core dumped)

(ii)	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- 3;
	Segmentation fault (core dumped)

(iii)	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- 3;
	val it = 3 : int

(iv)	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- 3;
	exnCode: code was 0
Fix:

From: Andy Norman <ange@hplb.hpl.hp.com>

A solution to your problem is to change the caching to 'writethrough' instead
of 'copyback' on the data region of the dumped sml image. i.e.

  chatr -Cd sml

This is documented in the file /etc/newconfig/ReleaseNotes and on the man page
for chatr.

Hope this helps... a bit...
					-- ange --

					ange@hpl.hp.co.uk

From: Andrew Appel <appel@Princeton.EDU>
Message-Id: <9105240134.AA10277@cs.Princeton.EDU>
To: ange.hpl.hp.co.uk@cs.Princeton.EDU
Cc: dbm@inet.att.com

I'm intrigued by your mail about write-through.  Perhaps we can
still use write-back, if we flush the cache whenever the
garbage collector (etc.) moves code around.  There
is a provision in the runtime system to do this for machines
like the MIPS where the i-cache does not track updates to the
data.  Could this be the problem?  (grep for FLUSH in the runtime)
Status: Fixed?
---------------------------------------------------------------------------
311. abstype bug
Submitter: Russ Green (rjg@lfcs)
Date: 
Version: 
System: 
Severity: minor
Problem: doesn't compile the following abstype definition
Code: 
      abstype t = C1 | C2
      with fun f (x:t,y:t) = x=y
      end
[jgm] This is fixed under 0.69.
Fix: 
Status: Fixed
---------------------------------------------------------------------------
312. non-printable characters cause exception Abort to be raised
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Wed Feb 6 1991
Version: 0.69
Severity: minor
Problem: I've noticed that if you type a non-printable character (such as 
a control character), then you get an uncaught exception Abort.
Code: 
Transcript: 
  - ^W
  std_in:1.1 Error: illegal token
  
  uncaught exception Abort
Comment:  in parse/parse.sml, the first token is extracted from the
input stream in order to initialize the parse.  Unfortunately, this
is outside the scope of the appropriate exception handler.

Status: Fixed in 0.84
---------------------------------------------------------------------------
313. poor error message
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Thu, 20 Jun 91
Version: 0.69
System: 
Severity: minor
Problem: 
I tripped across a poor error message last night.  Assume we have a 7 line
file "xxx.sml" with the following contents:

  (* 1 *)  fun foo () = let
  (* 2 *)        fun bar () = let
  (* 3 *)              val z = 1
  (* 4 *)              in
  (* 5 *)                z
  (* 6 *)              end
  (* 7 *)  val w = 1

The error being that we forgot the body of foo's let.  The error message
that SML/NJ gives is:
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - use "xxx.sml";
  [opening xxx.sml]
  xxx.sml:7.19 Error: syntax error found at EOF
  [closing xxx.sml]
  - 
Comments: 
When foo is in the middle of a 1000 line file, figuring out the source
of the error becomes quite hard.  If the error message had the line range, 
it would be a lot better.
Fix: perhaps allow specification in mlyacc that a three-token
     insertion should be tried; in this case  "in 0 end"
     Same approach could fix bug 206.
Status: open
---------------------------------------------------------------------------
314. unbalanced brackets on error message
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Mar 5 1991
Version: 0.66-0.69
Severity: minor
Problem: 
Minor bug in 0.66: if you use a non-existent file, the
resulting diagnostic has unbalanced brackets:

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- use "nonexistent";
[use failed: open_in "nonexistent": open failed, No such file or directory

Status: fixed in 0.74
---------------------------------------------------------------------------
315. bad weakness degree (too weak)
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/15/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        bad weakness degree (too weak);
Code:           
Transcript:     - fun f g x = g x;
		val f = fn : ('a -> 'b) -> 'a -> 'b
		- f ref;
		std_in:2.1-2.5 Error: nongeneric weak type variable
		  it : '0Z -> '0Z ref
		std_in:2.1-2.5 Error: nongeneric weak type variable
		  it : '0Z -> '0Z ref
		-
Comments:	f ref should have type: '1a -> '1a ref
		(DBM: but can't tell this without examining the definition of f)
Status: not a bug
-------------------------------------------------------------------------
316. stronger than required equality-type inference
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/15/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        stronger than required equality-type inference
Code:           
Transcript:     - datatype 'a new = N of 'a ref;
		datatype 'a  new
		con N : 'a ref -> 'a new
		- fun f (X as ref x) (Y as ref y) = N X = N Y;
		val f = fn : ''a ref -> ''a ref -> bool
		-
Comments:	Not really a bug, but confusing. I may understand the
		reason why, but type of f above is unnecessarily strong;
		type 'a ref -> 'a ref -> bool would be enough as equality
		property for type constructor "new" does not depend upon
		its type argument (due to the ref in "N of 'a ref").
		It is surprising that references to functions would admit
		equality, while	constructions from these by N (as built
		in function f) would not. e.g.

		- let val r = ref (fn x=>x) in r=r end;
		val it = true : bool
		- let val r = ref (fn x=>x) in N r = N r end;
		std_in:3.1-3.47 Error: operator and operand don't agree
							(equality type required)
		  operator domain: ''Z * ''Z
		  operand:         ('0Y -> '0Y) new * ('0Y -> '0Y) new
		  in expression:
		    = (N r,N r)
		- 
                - datatype 'a new0 = N0;
		- fun g x = x=N0;
		val g = fn : ''a new0 -> bool
		-
Comments:	g should have type: 'a new0 -> bool
		(DBM: see TACS paper)
Status: not a bug
-------------------------------------------------------------------------
317. eqtypes and abstype
Submitter: Simon Finn (simon@abstract-hardware-ltd.co.uk)
Date: Sep 20, 1990
Version: 0.69
Severity: 
Problem: shouldn't allow since the datatype constructor "Y" doesn't
respect equality in the final environment (since it maps the non-equality
type "abs" to the equality type "repp").  Poly/ML [and SML/NJ] fail
to detect this.
Code: 
  abstype abs = X of int 
  with
    datatype rep = Y of abs;
    val foo = X 1
  end;
  fun eq x y = Y x = Y y;
  eq foo foo;
Transcript: 
  type abs
  con Y : abs -> rep
  val foo = - : abs
  val eq = fn : abs -> abs -> bool
  val it = true : bool

Status: open
---------------------------------------------------------------------------
318. rebinding of type operator "*"
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/13/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        One is allowed to rebind type operator "*", but the new "*"
		is not properly handled in types, and old product type
		operator still present.
Code:           
Transcript:     - datatype * = P;
		datatype  *
		con P : *
		- P;
		val it = P : *
		- fun f (x : *) = P;
		std_in:5.12 Error: syntax error found at ASTERISK
		- fun f (x : 'a * 'b) = (1,2);
		val f = fn : 'a * 'b -> int * int
Comments:	Is it really safe to allow rebinding of product type ? This
		operator must be parsed as special case anyway, as product type
		operator does not obey the same syntax as user definable type
		operators. Further, function type operator may not be rebound.

[jgm] see Dave Tarditi's comments --  (x: *) is a syntax error since *) is
a close comment delimiter.
Fix:
Status: fixed
------------------------------------------------------------------------------
319. bad weakness degree (not weak enough)
Submitter:      Thierry Le Sergent (lesergen@laas.laas.fr)
Date:		11/13/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       major
Problem:        bad weakness degree (not weak enough);
		may create toplevel polymorphic references;
Code:           
Transcript:     - fun f x = let fun g z = ref x in g 3 end;
		val f = fn : '2a -> '2a ref
		- f [];
		val it = ref [] : '1a list ref
Comments:	f above should have type '1a -> '1a ref;
Fix: propagate weakness for free as well as bound type variables
     (function instantiateType in basics/typesutil.sml).
Status: fixed in 0.72
------------------------------------------------------------------------------
320. bad weakness degree (too weak)
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/13/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        bad weakness degree (too weak);
Code:           
Transcript:     - fun f x = (ref x; fn x=>x) x;
		std_in:1.5-1.28 Error: nongeneric weak type variable
		  f : '0Z -> '0Z
		std_in:1.5-1.28 Error: nongeneric weak type variable
		  f : '0Z -> '0Z
		- fun g x y = (ref x; fn x=>x) x;
		val g = fn : '1a -> 'b -> '1a
Comments:	f above should have type '1a -> '1a
		g above should have type '2a -> 'b -> '2a
		some rator forms confuse the type checker; which
		generate higher weakness degrees than expected.
Fix: added base field to type absp in typing/typecheck.sml (but see bug 539).
Status: fixed in 0.67
------------------------------------------------------------------------------
321. top level polymorphic exceptions allowed
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/13/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        top level polymorphic exceptions allowed
Transcript:     - exception X of '0a;
		exception X
		- fun f x = raise X x;
		val f = fn : '0aU -> 'a
		- fun g h x = h x handle X y => y;
		val g = fn : ('a -> '0aU) -> 'a -> '0aU
Comments:	This would be a bug if I could raise that exception, but
		I could not; so ?
		As a comment, I would prefer the compiler to infer automatically
		weakness degrees for arguments of polymorphic exceptions,
		rather than asking the user to (sometime unconsistently)
		apply a type constraint. Weakness degrees are neglected in
		types appearing in, e.g., datatype declarations; I think this
		is a good practice, that I would generalize to all types
		written by the user.
Status: fixed in 0.74
------------------------------------------------------------------------------
322. unreachable constructors should not be printed
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		11/13/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        unreachable constructors should not be printed
Code:           
Transcript:     - fun f x = let exception X of '1a in raise X x end;
		val f = fn : '1a -> 'b
		- f 5;
		uncaught exception X
		- fun f x = let datatype new = N in N end;
		val f = fn : 'a -> ?.new
		- f 1;
		val it = N : ?.new
Comments:	Not a bug, but confusing, as X and N above are not reachable
		at toplevel; and some reachable values may be printed as these.
Fix:
Status: not a bug, but confusing
------------------------------------------------------------------------------
323. blast_read/write should have types
Submitter: Jawahar (malhotra%metasoft.uucp@BBN.COM)
Date: Wed, 8 May 91
Version: 0.69
Severity: minor
Problem: I'm trying to use blast_read/write to dump some functors into a file
in binary form and then reload them in another image. I tried a small
experiment and found that it causes a segmentation fault. Is there
something I'm doing wrong?

I used:
	- val x = {a=34,b=78};
	- System.Unsafe.blast_write (x, "x.bl");
	
	and
	
	- System.Unsafe.blast_write ("x.bl", x);
both of them failed.
Code: (see above)
Transcript: 
Comments: 
[jgm]
The first argument of blast_write and the argument of blast_read
should be of type outstream and instream respectively.  In system.sig,
they're given types 'outstream * 'a -> unit and 'instream -> 'a making
them polymorphic.  I'm sure there's a reason for this, but I don't
know what it is.

Status: fixed in 0.84
---------------------------------------------------------------------------
324. bulletproofWrite dies in a bad way when out of disk space
Submitter: Larryf Paulson (Larry.Paulson@computer-lab.cambridge.ac.uk)
Date: 27 Nov 90
Version: 
System: 
Severity: minor 
Problem: when out of disk space, an exportML dies in an ugly way.
Code: 
Transcript: 
A New Jersey execution failed giving the following message.  Do you know what
it means?  Out of memory perhaps?				Larry

[Major collection... 99% used (1915968/1921456), 4860 msec]
bulletproofWrite, errno = 28
*** Error code 3
Comments: 

The bulletproofWrite error you got was probably from an exportML, no?
It's not out of memory; you have no space left on your disk.
However, we should provide a better error message, of course.

Status: fixed in 0.71
---------------------------------------------------------------------------
325. import and symlinks
Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Mon Apr  8 15:52:46 MET DST 1991
Version: Standard ML of New Jersey, Version 0.65, 10 September 1990 
System: Sun3-260 / SunOS Release 4.0.3_Export 
	Sun4-370 / SunOS Release 4.1.1
Problem: 
	if the source file is a symbolik link
	import checks the modification time of the link
	but not of the file.
Fix:

*** cfuns.c.new Tue Apr  9 12:11:46 1991
--- cfuns.c.org Wed Aug 22 15:28:17 1990
***************
*** 715,721 ****
      int                   sts;

      if (OBJ_isBOXED(f))
!       sts = stat((char *)PTR_MLtoC(f), buf);
      else
        sts = fstat(INT_MLtoC(f), buf);

--- 715,721 ----
      int                   sts;

      if (OBJ_isBOXED(f))
!       sts = lstat((char *)PTR_MLtoC(f), buf);
      else
        sts = fstat(INT_MLtoC(f), buf);

Comments:
	I use symbolik-links to share the source-code
	but not the bin-files for architectures sun3 and sun4

Status: Fixed (defunct feature)
-------------------------------------------------------------------------
326.  very big arrays

Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Tue Apr  9 12:40:24 MET DST 1991
Version: Standard ML of New Jersey, Version 0.65, 10 September 1990 
System: Sun3-260 / SunOS Release 4.0.3_Export 
	Sun4-370 / SunOS Release 4.1.1
Problem: 
	creating very big arrays leads to the message:
	[Minor collection...bug: insufficient to_space
Comments:
[jgm]
I tried fairly large arrays under 0.69 (10,000,000 integers) and
everything worked fine.  

Fix:	don't know
Status: Fixed
-------------------------------------------------------------------------
327. large constants cause overflow in compilation
	Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Tue Apr 23 13:50:05 MET DST 1991
Version: Standard ML of New Jersey, Version 0.69, 3 April 1991
System: Sun4-370 / SunOS Release 4.1.1
Problem: 
	Big integer constants leads to an uncaught exception Overflow
	in codegen.
Script:

Script started on Tue Apr 23 13:39:20 1991
jubu@flp jubu/ml_bugs 1) smlp69
Standard ML of New Jersey, Version 0.69, 3 April 1991
val it = () : unit
- val x = 1024 * 1024 * 512;
val x = 536870912 : int
- val maxint = x + ( x - 1 );
val maxint = 1073741823 : int
- System.Control.debugging := true;
execution
val it = () : unit
- 1073741823;
parse
semantics
debug instrument
translate
convert
cpsopt
closure
globalfix
spill
codegen

uncaught exception Overflow
- 1;
parse
semantics
debug instrument
translate
convert
cpsopt
closure
globalfix
spill
codegen
done
about to boot
code size =300
codegen

uncaught exception Overflow
- 1;
parse
semantics
debug instrument
translate
convert
cpsopt
closure
globalfix
spill
codegen
done
about to boot
code size =188
codegen
execution
val it = 1 : int
- 
jubu@flp jubu/ml_bugs 2)
script done on Tue Apr 23 13:41:24 1991

Fix:
Status: Fixed as of version 0.69
---------------------------------------------------------------------------
328. callcc not tail recursive
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Jan 14 1991
Version: 
System: 
Severity: minor
Problem: callcc is not tail-recursive
Code: 
Transcript: 
Comments: 
Fix: 
To make callcc tail-recursive, replace the "callcc" conversion
code of cps/convert.sml (starting at line 201) with the following:


     of Lambda.APP(Lambda.PRIM P.callcc, f) => let
	  val h = mkLvar() and k = mkLvar() and x = mkLvar()
	  val k' = mkLvar() and x' = mkLvar()
	  in
	  (* k is the callcc return cont, k' is the argument cont. *)
	    FIX([(k, [x], c (VAR x))],
	      PRIMOP(P.gethdlr, [], [h],
		[FIX(
		  [(k', [x'], PRIMOP(P.sethdlr, [VAR h], [], [APP(VAR k, [VAR x'])]))], 
		  conv (f, fn vf => APP(vf, [VAR k', VAR k])))]))
	  end
Status: Fixed
---------------------------------------------------------------------------
329. checkopen broken
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Dec 6 1990
Version: 0.67
System: 
Severity: major
Problem: Compiling Dave Berry's library produces a compiler bug in 0.67
  Error: Compiler bug: EnvAccess.checkopen.test
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.67, 21 November 1990
  val it = () : unit
  - use "nj-sml.load";
  [opening nj-sml.load]
  ...
  [closing nj-sml.load]
  val it = () : unit
  - use "build.sml";
  [opening build.sml]
  ...
  [closing ../signatures/InStreamType.sml]
  val it = () : unit
  structure Types :
    sig
      eqtype InStream
    end
  open Types
  Error: Compiler bug: EnvAccess.checkopen.test
  structure Types :
    sig
    end
  [opening outStream.sml]
  ...

Comments: 
>From Lal George:
The bug seems simple; checkopen.test was complaining if anything other
than vals, exceptions, or structures were defined within a structure! The
problem was only visible if this other thing (e.g., a type declaration)
came before test had a chance to raise NotStale on something else. A 
revised version of test is as follows:

Fix: 
    let fun test (s:symbol) =
	    case Env.look newenv s
	      of VARbind(VALvar{access=PATH(v'::_),...}) =>
		  if v' = v then raise NotStale else ()
	       | CONbind(DATACON{rep=VARIABLE(PATH(v'::_)),...}) =>
		  if v' = v then raise NotStale else ()
	       | STRbind(STRvar{access=PATH(v'::_),...}) =>
		  if v' = v then raise NotStale else ()
	       | _ => ()
Status: Fixed -- however, the fix in 0.69 adds another arm to the
case after the CONbind:

               | CONbind(DATACON{rep=VARIABLEc(PATH(v'::_)),...}) =>
                  if v' = v then raise NotStale else ()
---------------------------------------------------------------------------
330. comments bug
Submitter: David Tarditi (dtarditi@cs.cmu.edu)
Date: 17 May 1991
Version: 0.69
System: 
Severity: minor
Problem: 
According to Appendix D of the Commentary on Standard ML,
an unmatched right comment bracket should be detected by
the compiler.  Thus the expression (op *) is illegal.

Version 0.69 does not detect unmatched right comment brackets,
and parses (op *).
Code: 
                (op *)(1,2);
Transcript: 
              - (op *)(1,2);
              val it = 2 : int
Comments: 
Fix: add the following line to the lexer:
<INITIAL>"*)"	=> (err(yypos,yypos+1) COMPLAIN "unmatched close comment"; continue());
Status: fixed in 0.71
---------------------------------------------------------------------------
331. type variable generalized wrongly
Submitter: Mike Fourman (mikef@lfcs.edinburgh.ac.uk)
Date: Apr 16 1991
Version: 
System: 
Severity: major? 
Problem: 
The following is not legal ML and is rejected by PolyML,
Poplog ML and the Edinburgh Kit compiler.
NJ-ML and the old Edinburgh ML (wrongly) accept it.

fn x => let val y : 'a -> 'a = fn z => x in y end;

Error message from the Kit compiler (the others are more obscure):

  The following type variables could not be bound,
  even though they are scoped at this declaration.

  'a

Code: 
      fn x => let val y : 'a -> 'a = fn z => x in y end;
Transcript: 
Comments:
Comment from David Turner:

Once the new parser has been properly integrated,
the above error will also show the declaration
where the type variable was scoped (as below).

  fn x => let val y : 'a -> 'a = fn z => x in y end;
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  The following type variables could not be bound,
  even though they are scoped at this declaration.

  'a
 
Fix: 
Status: Fixed as of 0.69
---------------------------------------------------------------------------
332. Allows null datatype constructor to be matched as a unit -> type function.
Submitter: 	stark@cs.sunysb.edu (Gene Stark)
Date: 		1/26/91
Version: 	0.66 and 0.69
System: 		SparcStation SLC, SunOS 4.0.3c
Severity: 	major
Problem: 	Fails to type-check datatype constructors in functor body
		against specifications in signature.  Mismatched types
		result in core dump when constructor is used incorrectly.
Code: 		The compiler allows the following code:

			signature SIG = sig
			    type value;
			    val NIL: unit -> value
			end

			functor Foo(): SIG = struct
			    datatype value = NIL
			end;

		After importing this code, executing the following
		causes a bus error:

			structure Str = Foo();
			open Str;
			NIL();
Status: fixed in 0.73
---------------------------------------------------------------------------
333. code generation bug
Submitter:      David Turner <dnt@uk.ac.ed.lfcs>
Date:           31/10/90
Version:        SML of NJ version 0.66
System:         Mips, Sun3, Sun4, HP9000
Severity:       ?
Problem:        Code generation problem causing ml to crash ?
Code:

  (* This code has been distilled to narrow down the error! *)
  fun sine x = (if 1 mod 4 = 0 then exp(x) else exp(real 1 * x)) / sine x

Transcript:
  uncaught exception Regbind
  (* Doesn't matter too much what you type here, the whole system
  seems to have been corrupted. *)
  - sin; 
  Illegal instruction

Comments:
  This happen on all the machines mentioned above (nearly
  always via an illegal instruction).

This is clearly a problem with the new CPS stuff, but I'd like to
again point out the other problem: code generation bugs, such as
this one or the shift bug on the sparc, cause the system to get into
some kind of corrupted state, which causes a core dump on the next
top-level definition.  I think that there needs to be a catch-all
exception handler wrapped around code generation stuff, which will
restore things to a reasonable state.
  - John

The problem with System.Unsafe.Weak is that John forgot to make it an
abstraction rather than a Structure.  If this is fixed, haven no longer
dumps core; I would hope shamash wouldn't get wedged either, though I don't
intend to try the experiment!

Andrew

Trying to reproduce a bug that occurs on haven in 67, I typed

open System.Unsafe.Weak;
strong 1;

This should give a typechecking error, but on haven, it causes a Bus Error.
It looks like on shamash it wedges the machine!
I'm investigating further on other machines.
Status: Fixed as of 0.69
---------------------------------------------------------------------------
334. adjust_limit in M68.prim.s
Submitter:      Andre Kramer     akramer@ecrc.de 
Date:           May  2 
Version:        0.66
System:         m68 (sun3 sunos)
Severity:       major?
Problem:        
                adjust_limit in M68.prim.s trashes d0 with a 
                comment that ml does not use it. 
                It appears that ML does use d0 (e.g. floating
                point primitives in same file). 
 
Code:           I had an alarm signal handler causing random
                crashes. 
Transcript:     .

Comments:       Sparc is ok. 

Fix:

adjust_limit:
        movw    cc,d5             /* save condition codes */ 
        movl    _saved_pc,sp@-
        movw    d5,sp@-           /* push the saved condition codes */
        clrl    d5                /* generate a trap on the next limit check */
        rtr                       /* return, restoring condition codes */
Status: Fixed in 0.74.
---------------------------------------------------------------------------
335. Dave Berry's library won't compile
Submitter:      Richard O'Neill (oneill@cs.sfu.ca)
Date:		Wed Apr 24 09:57:05 PDT 1991
Version:        0.68-0.69
System:         NeXTstation, OS2.1
Severity:       Major
Problem:        

The current 'working' version cannot compile Dave Berry's library (as in 
dblibrary.tar.Z in dist/ml on research.att.com). It chuggs away for a while 
but finally comes up with a Runbind exception. I can't say if it works for
previous releases as 0.69 is the first version that runs on a NeXT under OS2.1,
and thus the first release I have been able to run in a while.

Transcript:

Standard ML of New Jersey, Version 0.69, 3 April 1991
val it = () : unit
- use "nj-sml.load";
	.
	.
	.
- use "build_all.sml";
[opening build_all.sml]
val loadEntry = fn : string -> unit
val loadSig = fn : string -> unit
val loadLocalSig = fn : string -> unit
val setLoadPrefix = fn : string -> unit
val setLoadSigPrefix = fn : string -> unit
     ...
[opening Int.sml]
[opening ../signatures/INT.sml]
signature INT =
  sig
    eqtype T
    eqtype int
      ...
    val ~ : int -> int
  end
[closing ../signatures/INT.sml]
val it = () : unit

[Major collection... 36% used (948744/2627428), 814 msec]
[closing Int.sml]
[closing build_all.sml]

uncaught exception Runbind
- 
Status: fixed in 0.74
---------------------------------------------------------------------------
336. $$lookTycPath diagnostic message
Submitter: Andre Appel (appel@princeton.edu)
Date: Jun 3 1991
Version: 0.69
System: 
Severity: minor?
Problem: Reminder: for 0.70 SML/NJ remove the $$lookTycPath diagnostic message.
Fix: 
Status: fixed in 0.73
---------------------------------------------------------------------------
337. double error message
Submitter:      John Ophel jlophel@watmsg.waterloo.edu
Date:           4/1/91
Version:        0.66
System:         Vax, Unix
Severity:       very minor
Problem:        repeated error message

Transcript:

-  val g = (fn x => (fn y => (ref x, ref(x,y))));
val g = fn : '2a -> '2b -> '2a ref * ('2a * '2b) ref
- val h = g(nil);
val h = fn : '1a -> '1b list ref * ('1b list * '1a) ref
- h true;
std_in:4.1-4.6 Error: nongeneric weak type variable
  it : '0Z list ref * ('0Z list * bool) ref
std_in:4.1-4.6 Error: nongeneric weak type variable
  it : '0Z list ref * ('0Z list * bool) ref

Comments:

  I tried to generate the double error message with a simpler code
but couldn't.

John
Status: fixed in 0.74
---------------------------------------------------------------------------
338. local datatypes
Submitter: Bruce Duba (duba@rice.edu)
Date: Nov 8 1990
Version:
System: 
Severity: major
Problem: 
Is the following a bug or am I confused? I didn't expect the application of
f1 to a2 to type check. 
Code: 
  fun new() = let datatype A = A
	      in (A,fn A => ())
	      end
  val (a1,f1) = new()
  val (a2,f2) = new()
  val x = f1 a2

Status: not a bug
---------------------------------------------------------------------------
339. type = allowed
Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk)
Date: Nov 8 1990
Version: 
System: 
Severity: minor
Problem: SML/NJ allows the following code
Code: 
   signature S = sig type = end;
Transcript: 
Comments: 
Here, "=" is clearly not standing for the equality predicate (even though
it's not being rebound), so this is illegal.

The status of something like

  signature S =
    sig
      structure T: sig ... end sharing type T.t = T.*
    end;

is less clear. "*" is not allowed as a TyCon, but "T.*" presumably is (even
though no matching signature for "T" would be syntactically possible to
write).

Sender: David.Tarditi@b.gp.cs.cmu.edu
Status: RO

Here are some answers to the questions about parsing in SML/NJ raised
by Nick Rothwell.  First, the processing of infix operators is handled
by an operator precedence parser after parsing is finished.  The ML-Yacc
grammar essentially allows allow any string of legal identifiers in certain
places; the operator precedence parser sorts it out later.  (As a side note,
this make syntactic error correction much harder).  Yes, this means
that we don't have a "pure" LALR grammar, but I don't see any way anyone
could have one with the precedence scheme used in ML.  

The parser deals with "=" and "*" by always regarding them as reserved words.
To put it another way, the lexer always returns separate tokens for these
values.   This reduces our problem to deciding where exactly "=" and "*"
should be permitted to be used in place of identifiers.

The following rules sort this out:

"*" can always be used in place of an identifier, except in the syntactic
    class "TyCon"

"=" can only be used in place of an identifier in an expression.
    Since it cannot be rebound, it cannot be used as an identifier
    in pattern.

As Nick Rothwell has pointed out, there are some mistakes in SML/NJ
where these rules are violated.  To summarize the problems found so
far:

(1) Allows * to be used as TyCon in type specifications.  This is clearly
    illegal SML (see p.  13 of the Definition).

Example:
	sig
	  type *
        end

(2) Allows = to be used as TyCon in type specifications.  Since this
    isn't the equality predicate, this is wrong.

Example:
	sig
	   type =
	end

(3) Doesn't allow "*" to be used as a record label.  This is clearly
    allowed, since "*" is just an identifier.

Example
	{* = 5}

All of these can be fixed by some minor changes to the grammar using by
SML/NJ, without making the grammar ambiguous.

With regard to parsing examples:

(1)  This is complicated, but not ambiguous.  

   val x = {A=B=C=D=E, B=((X=Y), {X=Y}, X=Y), X=Y};

binds  x to a record with fields A,B, and X.  Field A is set to the boolean
value of ((B=C)=D)=E),  Field B is a tuple of type bool * {X:bool} * bool,
and Field X is set to the value of Y.   Thus:

     val B=1 and C=1 and D=true and E=true and X=1 and Y=1
     val x = {A=B=C=D=E,B=((X=Y), {X=Y}, X=Y), X=Y}

gives:

     val x = {A=true,B=(true,{X=1},true),X=1) :
	    {A:bool,B : bool * {X : int} * bool, X : int}
      

(2) This is legal; the Definition says nothing about rebinding the
    precedence of =.  It won't typecheck though, since function types
    are not equality types.

   nonfix =
   val x = = and y = {A= =(=, =), B = =}

(3) This should be illegal, but isn't.  It shows that SML is
    inherently ambiguous for any fixed lookahead k.

   nonfix =
   fun f x = = | f y = case y of 1 => = | 2 => = | f z = =

    The reason is best illustrated with this simpler case

        fun f x = case y of 1 => 1 | f z = 3

    The "| f z = 3" phrase should go with "fun f x", not with
    the case statement clause.  A parser cannot decide this, however,
    until it sees that the "=" is not an "=>".  However, z can be an
    arbitrarily complex pattern, so for fixed lookahead k we can choose
    some pattern that requires lookahead of k+1 tokens.

    There isn't much you can do about this, short of changing the language
    definition.

    The following variant is legal, by the way:

   nonfix =
   fun f x = = |00 stlouis8913372 "" \r\d in:--in: nuucp word: nuucpNUUCP
to the problem of infixes in signatures making
separate parsing and typehcecking passes difficult, it is already
impossible (I think) to separate the parsing and typechecking
completely.  The infix status of an identifier cannot be determined
without the use of static semantics information.

You could separate the passes as:

(1) parsing
(2) typechecking plus parsing of infix identifiers

if you insist on this kind of division.

  Dave
Fix: 
Status: Fixed as of 0.69
---------------------------------------------------------------------------
340. = specification allowed
Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk)
Date: 8 Nov 1990
Severity: minor
Problem: 
The following (legal - I think) signature is accepted by SML/NJ and
rejected by Poly/ML and Poplog/ML:
Code: 
	  signature S = 
	    sig val = : 'a * 'a -> bool
            end

also
          signature S =
            sig val = : int
            end
Transcript: 
Comments: 
Is this legal? "val =" is only allowed if the "=" is standing for the
equality predicate (Defn. p.4). Does its appearance in a spec. count? What
about

  sig
    val = : int
  end

where it can't possibly be the equality predicate.

Status: not much of a bug
---------------------------------------------------------------------------
341. equality 
Submitter: Andrew Tolmach (apt@princeton.edu)
Date: 4/17/91
Version: 0.68
Severity: major
Problem: not consistent about allowing equality
Transcript: 
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - datatype 'a A = A of 'a ref;
  datatype 'a  A
  con A : 'a ref -> 'a A
  - val f = fn () => ();
  val f = fn : unit -> unit
  - val f1 = fn () => ();
  val f1 = fn : unit -> unit
  - f = f1;
  std_in:5.1-5.6 Error: operator and operand don't agree (equality type required)
    operator domain: ''Z * ''Z
    operand:         (unit -> unit) * (unit -> unit)
    in expression:
      Initial.General.Initial.= (f,f1)
  - ref f = ref f1;
  val it = false : bool
  - ref 2 = ref 2;
  val it = false : bool
  - A (ref f) = A (ref f1);
  std_in:3.1-3.22 Error: operator and operand don't agree (equality type required)
    operator domain: ''Z * ''Z
    operand:         (unit -> unit) A * (unit -> unit) A
    in expression:
      Initial.General.Initial.= (A (<exp> <exp>),A (<exp> <exp>))
  - A (ref 2) = A (ref 2);
  val it = false : bool
  -
Comments: 
If I can compare ref f with ref f1, why can't I compare A(ref f) with 
A(ref f1)?  Is this a bug or a feature?
Also, from Chet Murthy:
I want to define a datatype, with constructors/destructors, for which
the system can be forced to not provide an equality.  I do not think
this is possible.  Here is the application:

The Nuprl term-type is one for which constructors/destructors are
crucial.  But the term-type is defined in such a way that alpha-equal
variants are not represented identically.  So lambda(x.x) and
lambda(y.y) are not the same structure.  So structural equality will
fail on them.

So we define alpha-equality, which respects this equivalence.  But the
problem is that we do not want to discard structural equality
completely.  That is, if we were to add a new disjunct to the Nuprl
term-type:

datatype Term = .......... | Bogus of int -> int

then Term would not be an eq-type, and structural equality would be
inadmissible.  But sometimes I DO want structural equality, like in
hash-consing (and I'm not sure where else, but I don't want to rule
that out).  So I don't want to give it up right now.  So it would be
nice to define a structure which exported a datatype for the
term-type, an equality function which happened to be defined as
structural equality, but in which the term-type was NOT an eqtype.  Is
this possible?

Here is my try - and the problem:

signature ASIG = sig
type t
datatype DNE = D of int | Bogus of t
val op == : DNE * DNE -> bool
infix 4 ==
end;

abstraction A:ASIG = struct
type t = int
datatype DNE = D of int | Bogus of t
fun == (a,b) = (a = b)
end;

If I run (A.D 5)=(A.D 6) the system will happily run it.  But I want
the system to complain about DNE not being an eq-type.

This isn't possible, is it?

Status: not a bug (language problem, see Gunter,Gunter,MacQueen)
---------------------------------------------------------------------------
342. execute destroys the unix-environment
Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Fri Dec 21 16:12:49 MET 1990
Version: Standard ML of New Jersey, Version 0.66, 15 September 1990
System: Sun 4/60, 16Mbytes, SunOS Release 4.1
Problem:
The function execute destroys the unix-environment

Transcript:

Script started on Fri Dec 21 16:07:27 1990
jubu@flp ml66/src 1) ./sml
Standard ML of New Jersey, Version 0.66, 15 September 1990
- val (istr,ostr) = execute "/bin/sh";
- outputc ostr "echo '>'$DISPLAY'<'";
val it = () : unit
- close_out ostr;
val it = () : unit
-  inputc istr (can_input istr);
val it = ">flp:0.0\220<\n" : string
                  ^^^^
Comments:
cfuns.c line 1100:

The c-function exec has to add 0-bytes to the ml-strings.

Fix:
A simple fix can be done in perv.sml:

perv.sml line 953:
fun execute cmd = let
	fun add_0byte x = x^"\000\000
	val (fdin, fdout) = exec
		(c_string cmd, [], List.map add_0byte(environ()))

		handle (SysError(_,msg)) => error("execute", cmd, msg)
		.
		.
[jgm]
Trying this on the SGI produces the following:
  Uncaught exception Io with "output "<std_out>": write failed, Broken pipe"
Status: fixed in 0.74 (JHR)
---------------------------------------------------------------------------
343.
Submitter:      Ryan Stansifer ryan@cs.purdue.edu
Date:           May 11, 1991
Version:        0.66
Severity:       minor
Problem:        wrong error message in non-gen exc bindings
Transcript:

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- exception e;
exception e
- val e' = e
- exception e'' = e;
exception e'' = e
- raise e'';

uncaught exception e
- e';
val it = exn : exn
- e'';
val it = exn : exn
- exception f = e';
std_in:3.15-3.16 Error: unbound exn: e'
- exception f = e'';
exception f = e''

Status: not a bug; perhaps the error message could be improved to indicate
that e' is just a value, not a constructor
---------------------------------------------------------------------------
344. explicit type variable problem
Submitter: Dave MacQueen (dbm@research.att.com)
Date: Mar 30 1991
Version: through 0.74
Code: 
structure C : sig val f : 'a -> 'a end =
struct

  exception E
  fun foo(k:'a option -> 'a) : 'a = k(NONE)
  fun bar(x:'a option) (y: 'a) = raise E

  fun f (e) =  (* using (e:'a) as argument works *)
      foo (fn l => let fun g (x : 'a) = bar l x
		    in g e
		   end)

end
Comments: 
The rule for "scoping" explicit type variables like the 'a that
appears in the definition of g is purely syntactic (i.e. doesn't
take type checking, and its associated unifications, into account).
Each explicit type variable is associated with with a particular
val/fun declaration, and it should be generalized at that declaration,
if possible.  In this case 'a is associated with the "fun g" declaration,
and we might annotate the definition of f accordingly:

  fun f (e) =  (* using (e:'a) as argument works *)
      foo (fn l => let fun{'a} g (x : 'a) = bar l x
		    in g e
		   end)

This means that the only legal place to generalize 'a would be at the
definition of g.  However, in this case the expression "bar l x"
forces the type of l to be 'a option, meaning that 'a occurs in
the type of the outer lambda bound variable l.  This prevents the
generalization of 'a at "fun g", so there is a conflict.  Thus the
program is not legal, but there should have been an error message
about not being able to generalize 'a at "fun g", where it is
syntactically scoped.  I'll put in a fix to detect this situation
and generate such an error message.

Status: fixed in 0.85
---------------------------------------------------------------------------
345. export should return a code and have different type
Date: Nov 8, 1990
Severity: minor
Problem: 
How come exportFn is string * (string list * string list -> unit) -> unit
instead of string * (string list * string list -> int) -> 'a   ?

I was actually suggesting two things: the function passed as
argument to exportFn should return an exit status and
exportFn itself should "return" 'a rather than unit
because it doesn't return.

Of course, making exportFn's argument return exit status
might break existing programs that use it; I don't know whether
that's important or not at this stage of the game.

If you want to write unix commands in ML, it's important to
be able to set a return code.

Comments: there is, of course, an "exit" function available for this purpose.

Status: suggestion (not a bug)
---------------------------------------------------------------------------
346. exportFn
Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Mon Apr  8 15:52:46 MET DST 1991
Version: Standard ML of New Jersey, Version 0.66, 15 September 1990 
System: Sun3-260 / SunOS Release 4.0.3_Export 
	Sun4-370 / SunOS Release 4.1.1
Messages:
	Warning: can't increase heap
	Ran out of memory
Comments:
	After an exportFn two pointers in Core.Refs are invalid.
	The addresses of
	(!Core.Refs.getDebugf)
	and (!Core.Refs.debugInterface)
	are bigger then (arenabase+arenasize) !
	After an increase_heapsize the gc will collect
	some random-object.
Bug Fix :
	change the type of
	Core.Refs.getDebugf and Core.Refs.debugInterface
	to (unit->unit) ref. (in file boot/core.sml)
	:= will the do an boxed-update!
Status: fixed in 0.84
---------------------------------------------------------------------------
347. dec function in fastlib wrong
Submitter: Andrew Appel (appel@princeton.edu)
Date: Apr 15 1991
Version: 0.69 (and all previous)
Severity: major
Problem: 
In all versions up to and including 0.69, the "dec" function (decrement)
in boot/fastlib.sml was wrong (it incremented).  This will affect only
those users who followed the hints for faster performance in the
doc/ directory, which explained how to include Fastlib in one's programs.
Unfortunately, I am such a user.  What a waste of time. 
Status: fixed in 0.70
---------------------------------------------------------------------------
348. connect_inet bug 
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Mar 23 1991
Version: 0.68
Severity: minor
Fix: 
If you haven't already built 0.69, then please include the following
bug fix for connect_inet in runtime/cfuns.c:

line 258, which is:

      saddr.sin_port = atoi(port);

should be replaced with

      saddr.sin_port = htons(atoi(port));

and line 266, which is:

        saddr.sin_addr.s_addr = s;

should be replaced with

	saddr.sin_addr.s_addr = htonl(s);
Status: Fixed.
---------------------------------------------------------------------------
349. function names in FUN not checked for uniqueness
Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:		June 5, 1991
Version:        0.67
System:         All
Severity:       Minor
Problem:        Function names in FUN not checked for uniqueness
Code:           fun foo x = 3 and foo x = true
Transcript:     - fun foo x = 3 and foo x = true;
		val foo = fn : 'a -> int
		val foo = fn : 'a -> bool
		-
Comments: The equivalent VAL REC declaration is correctly rejected.
Also, from Olof Johansson (olof@cs.umu.se)
Is this a bug? What is the point of the definition?
Is it allowed to do this according to the definition of SML?

	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- datatype F = C and F = D;
	datatype  F
	con C : F
	datatype  F
	con D : F
	- D;
>	val it = D : F
	- C;
>	val it = D : F

Which one of the following response is the correct one.
Should they not be the same?

	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	- val rec f = fn x => 1 and f = fn y => 2;
	std_in:2.9-2.39 Error: duplicate function name in val rec dec: f
	- fun f x = 1 and f y = 2;
	val f = fn : 'a -> int
	val f = fn : 'a -> int
	- f 0;
	val it = 2 : int

Olof Johansson

Fix:		Add checkUniq of function names to makeFUNdec in 
	   	parse/corelang.sml or to FUNdec in absyn/absyn.sml
Status: fixed in 0.71
---------------------------------------------------------------------------
350. fvalbind rewrite rule
Submitter: Nick Rothwell (nick@lfcs.edinburgh.ac.uk)
Date: 12 Feb 1991
Version: 
System: 
Severity: minor
Problem: 
Referring to the definition of the `fun' derived form (defn. V4 p68):
there's a rewriting rule for fvalbind's looking like

          <op>var atpat.11 ... atpat.1n <: ty> = exp.1
          <op>var atpat.21 ... atpat.2n <: ty> = exp.2

          <op>var atpat.m1 ... atpat.mn <: ty> = exp.m
                <and fvalbind>

This implicitly suggests that all the function result type constraints
(whichever present) have to be the same. But, this is a *syntactic*
constraint (we're dealing with derived forms, not elaboration rules).
Certainly they have to elaborate to the same type, but surely they may be
distinct syntactically? The above rule outlaws the following

        local
          type INT = int
        in
          fun f 0 : int = 0
            | f 1 : INT = 1
        end;
Code: 
Transcript: 
Comments: Appel says: the Def'n should have subscripts on the ty's, and
             that's obviously what is meant here.
Fix: 
Status: not a bug?
---------------------------------------------------------------------------
351. gc messages bug
Submitter: Andrew Tolmach (apt@princeton.edu)
Date: 7 May 1991
Version: 0.69 (and some earlier, 68 based versions)
System: mipsb
Severity: minor
Problem: 
In version 69 (and some earlier, 68 based versions) on mipsb,
the unsafe gc primitive interacts badly with gcmessages.  
Obviously this isn't a serious problem in itself, but maybe bears loking
into...?
Code: 
Transcript: 
- val gc = System.Unsafe.CInterface.gc;
val gc = fn : int -> unit
- (gc 0; gc 0);
val it = () : unit
- System.Control.Runtime.gcmessages := 3;
val it = () : unit
- (gc 0; gc 0);

[Minor collection... 0% used (2224/765756), 10 msec]

[Minor collection...bogus signal in ML: (5, 0x7)
Comments: 
Fix: 
Status: should be fixed in 0.70
---------------------------------------------------------------------------
352. gc statistics bug
Submitter: Greg Morrisett (jgmorris@cs.cmu.edu)
Date: June 25, 1991
Version: 0.69
System: All
Severity: minor
Problem: 
In callgc.c, there's a couple of places where you're trying to
bump an ML_val_t int ref (e.g. majorcollections, collected, etc.)
and using code like this:

           minorcollections += 2;

But since ML_val_t is an unsigned int pointer, this bumps the
value by 4 (i.e. ML 2).  The safe way to add to an ML_val_t is
to use INT_incr.
Code: 
Transcript: 
Comments: 
Fix: 
change line 217 of callgc.c to read
          minorcollections = INT_incr(minorcollections,1);
change lines 292-294 of callgc.c to read
          collected = INT_incr(collected, ((a+512)/1024));
	  collectedfrom = INT_incr(collectedfom, ((b+512)/1024));
          majorcollections = INT_incr(majorcollections,1);
Status: should be fixed in 0.70
---------------------------------------------------------------------------
353. getWD can't get above mount points on NeXT
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Jun 7 1991
Version: 0.69
System: NeXT
Severity: minor
Problem: 
System.Directory.getWD doesn't seem to be able to get above mount
points on the NeXT (works on the sun).  E.g.,
Code: 
Transcript: 
  <jhr@alvis:57> pwd
  /usr/fsys/loki/b/jhr
  <jhr@alvis:58> sml
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - System.Directory.cd ".."; 
  val it = () : unit
  - System.Directory.getWD();
  val it = "/" : string
  - System.Directory.cd ".."; 
  val it = () : unit
  - System.Directory.getWD();
  val it = "/usr/fsys/loki" : string
Comment:
  See also 421.
  To be fixed by calling C version of getWD (after new gc allows malloc).
Status: open
---------------------------------------------------------------------------
354. SIGILL bug on SPARC
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: June 18 1991
Version: 0.69
System: SPARC
Severity: major
Problem: 
One of our alpha testers encountered a strange Overflow exception in
eXene.  Upon closer examination it turns out that the problem really
is an illegal instruction exception (SIGILL), and that modifications
made to support MACH on the SPARC caused SIGILL to be mapped to Overflow.

Further examination demonstrates that the bug is neither an eXene bug
or CML bug, but is a bug in SML/NJ.  After a lot of testing I've managed
to produce a small (<100 lines) example program, which will cause the
bug on both the SPARC and DECstation 3100.  The fact that this program
uses the timer interrupts to do thread switching is key; if you turn
the signals off, then the bug does not appear.  I also note that the bug
does not seem to appear in my version of 0.68 (0.67 + my changes for
the unsafe callcc); thus I suspect that it was introduced by the
changes made for supporting FP registers.  The example program is
included below; to produce the bug, run the function "go."  It usually
takes about 3-5 minutes to fail on a SPARCstation-1.  For example, the
following run took 2.5 min:

  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - use "sml-bug.sml";
  [opening sml-bug.sml]
  val yield = fn : unit -> unit
  val spawn = fn : string * (unit -> unit) -> unit
  val doit = fn : (unit -> unit) -> unit
  val go = fn : unit -> unit
  [closing sml-bug.sml]
  val it = () : unit
  - go();
  initial process
  proc1
  proc2
  proc1: uncaught exception Overflow
  initial process: uncaught exception Overflow
  val it = () : unit
Code: 
  (see John's CML code)
Status: Fixed in 0.70
---------------------------------------------------------------------------
355. incorrect line numbers with import
Submitter: deutsch@poly.polytechnique.fr.
   Alain Deutsch,
   Laboratoire d'Informatique de l'Ecole Polytechnique (LIX)
   91128 Palaiseau Cedex
   France.
Date: Thu Nov 22 14:35:09 MET 1990
Version: Version 0.66
System: SUN3/60
Severity: minor

Problem: Incorrect line/column numbers when compiling a module w. import,
 although the numbers are correct when compiling with use.

Transcript:

 Standard ML of New Jersey, Version 0.66, 15 September 1990
 val it = () : unit

 - use "ExampleFunctor.sml";
 [opening ExampleFunctor.sml]
 ExampleFunctor.sml:3.9-3.18 Warning: match not exhaustive
	 x :: nil => ...
 functor F : <sig>
 [closing ExampleFunctor.sml]
 val it = () : unit

 - import "ExampleFunctor";
 [reading ExampleFunctor.sml]
 ExampleFunctor.sml:0.0-0.0 Warning: match not exhaustive
	 x :: nil => ...
 [writing ExampleFunctor.bin... done]
 [closing ExampleFunctor.sml]
 functor F
 - 
Status: Fixed (Defunct feature)
---------------------------------------------------------------------------
356. size of images generated by import too large
Submitter: Jawahar Malhotra (malhotra%metasoft@bbn.com)
Date: Jan 29, 1991
Version: 
System: 
Severity: 
Problem: 
I recently redesigned a large system so that I could use separate
compilation. I experienced an increase in heap size of
close to 100%. This was a little disturbing and so I investigated
a little. To explain the problem consider the following example:

Say my system consists of 4 modules: A, B, C, D. 
Every functor is in a separate file as is every signature.
To link, I execute 'use "link.sml"'.

++++++++++++++++++++++++++++++
(* link.sml *)

import "a";
import "b";
import "c";
import "d";

structure A = A();
structure B = B(A);
structure C = C(A);
structure D = D(structure X = B
		structure Y = C);
++++++++++++++++++++++++++++++

The files are as follows:

++++++++++++++++++++++++++++++
(* a.sml *)

import "a.sig";

functor A() = 
...
++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++
(* b.sml *)

import "a.sig";
import "b.sig";

functor B (X:ASIG) : BSIG = 
...
++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++
(* c.sml *)

import "a.sig";
import "c.sig";

functor C (X:ASIG) : CSIG = 
...
++++++++++++++++++++++++++++++

...

Building the system as shown above led to LARGE heap sizes (and images
generated by exportML). I suspected that this was due to the
duplicated imports of the same signature file by many sml files.  
For example, "a.sig" is imported by "a.sml", "b.sml", "c.sml". 

To verify this, I wrote a function called "smartImport" which uses
"use" to load files. It maintains an environment of files already
loaded and avoids duplicate loading of files (code appears at end of
message). I then replaced "import" by "smartImport" in all my source
files and rebuilt. I found that the resulting image size was much
smaller. 

The following results were obtained using an actual system with
approx. 40 modules. For both cases, exactly the same source code was
loaded and an image exported using "exportML".

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
						exportML file size
							(bytes)

Without smartImport (regular sep. comp.)	5799968
With smartImport 				3063840
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

This is quite a significant saving. I would eventually like to have an
improved "import" command; one that can avoid duplicated loading of files.
I'm not so sure the technique I have used (i.e. using file names to
determine if a file has already been loaded) is a general error-free
solution.

A combination of file name and file modification time may be better.
So whenever "import" loads a file, it records the file name and the
file modification time. The next time it encounters this file, it
compares the saved modification time with the file's actual
modification time. If the file is newer, it reloads the file else it
skips the file. 

Has anyone else had such experiences with separate compilation? Any
other suggestions for how to keep the heap size down?

Jawahar
Comments: 
[jgm]
Gene Rollin's sourcegroup stuff is being designed to take care of
this problem.
Status: Fixed (defunct feature)
---------------------------------------------------------------------------
357. import broken
Submitter:      Richard O'Neill (rmo@sys.uea.ac.uk)
Date:		Tue Nov 13 10:44:42 GMT 1990
Version:        0.67 (not in 0.66)
System:         Sun4/SunOS 4.1 (probably irrelevant)
Severity:       Major
Problem:        

Version 0.67 of Standard ML of New Jersey breaks 'import'. Import now seems
to compile the file it is given but fails to introduce the declarations
from that file into the environment.

Transcript: 

unix% cat > example.sml
signature Test = sig type foobar end
unix% sml
Standard ML of New Jersey, Version 0.67, 21 November 1990
val it = () : unit
- import "example";
[reading example.sml]
[writing example.bin... done]
[closing example.sml]
signature Test
- signature CopyOfTest = Test;
std_in:3.24-3.27 Error: unbound signature: Test
-

Comments: (guesses)

Looking at differences between 0.66 & 0.67 I see that the way the environment
is handled has changed. I suspect that this has something to do with it.

Other information:

The version I have built was made from the mo.sparc files and src from 
'pub/ml/working' at princeton.
Status: fixed (as of 0.69 anyway)
---------------------------------------------------------------------------
358. import & pervasives
Submitter:      Elsa Gunter elsa@research.att.com
Date:		27 March 1991
Version:        0.68
System:         mips
Problem:        import doesn't always get the pervasive types right
Code:           

(* File: bug.sig.sml *)

signature ASig =
sig
exception FOO of string
end

(* File: bug.sml *)

import "bug.sig";

functor AFunc () =
struct 
exception FOO of string
end


Transcript:

Standard ML of New Jersey, Version 0.68, March 7, 1991
val it = () : unit
- import "bug.sig";
[reading bug.sig.sml]
[writing bug.sig.bin... done]
[closing bug.sig.sml]
signature ASig
- import "bug";
[reading bug.sml]
  [reading bug.sig.bin... done]
bug.sml:5.18-5.23 Error: unbound type constructor: string
import: syntax or semantic error
[closing bug.sml]
IMPORT failed
-  


Standard ML of New Jersey, Version 0.68, March 7, 1991
val it = () : unit
- import "bug";
[reading bug.sml]
  [reading bug.sig.sml]
  [writing bug.sig.bin... done]
  [closing bug.sig.sml]
[writing bug.bin... done]
[closing bug.sml]
signature ASig
functor AFunc
- import "bug";
[reading bug.bin... ]
[import(s) of bug are out of date; recompiling]
[closing bug.bin]
[reading bug.sml]
  [reading bug.sig.bin... done]
bug.sml:5.18-5.23 Error: unbound type constructor: string
import: syntax or semantic error
[closing bug.sml]
IMPORT failed
- 
Status: Fixed (as of 0.69)
---------------------------------------------------------------------------
359. indexing 
Submitter:      Gene Rollins <rollins@cs.cmu.edu>
Date:		Mar 11, 1991
Version:        0.67
Severity:       minor
Problem:        Indexing code doesn't handle all abstract syntax trees
Code:           Anything with an import clause in it.
Transcript:     Error: Compiler bug: Index2
Comments:       Only happens when (!System.Control.indexing) = true
Fix:

In file build/index.sml, add three clauses for printDec, and eliminate
the final wildcard clause.

diff {old,new}/build/index.sml
160a161,162
>       | printDec(FIXdec _) = ()
>       | printDec(OVLDdec _) = ()
161a164
>       | printDec(IMPORTdec _) = ()
163d165
<       | printDec _ = ErrorMsg.impossible "Index2"
Comment:  Import will soon go away.  Then this will be "not a bug".
Status: fixed in 0.71
---------------------------------------------------------------------------
360. bad error message when missing functor argument
Submitter: Robert Harper (rwh@cs.cmu.edu)
Date: Aug 29 1990
Version: 
System: 
Severity: minor
Problem: 
	Here's another bug report, this one relatively minor.  The problem
arises as follows.  I have a build file which imports a bunch of files and
then applies a bunch of functors to build the program.  I changed one of the
functors to take a parameter where it formerly had none.  But I forgot to
change the build file to plug in an argument.  Here's what I get:

/usr/rwh/courses/ic90/build.sml:56.5-56.10 Error: unmatched structure spec:
Type
Error: Compiler bug: inststr NULLstr
[closing /usr/rwh/courses/ic90/build.sml]
- 

It gives a reasonable message, then an unreasonable one.  I've noticed
versions of this where the "compiler bug" is "tyC" (or something close to
that).

My suspicion is that it has to do with the awful declaration-as-argument
syntax for functor applications ....
Code: 
Transcript: 
Comments: 
Fix: 
Status: probably fixed in 0.73, but can't tell (no source provided)
---------------------------------------------------------------------------
361. Error: Compiler bug: Functor.applyFunctor.insttyc
Submitter:      Elsa elsa@research.att.com
Date:		8 March 1991
Version:        0.66 & 0.67
System:         mips mips and Sun3 with SunOS 4.0
Problem:        Error: Compiler bug: Functor.applyFunctor.insttyc
Code:
Status: R

signature AA =
    sig
	datatype s  =  a of s
end  (* signature AA *)

signature BB =
    sig
	structure A : AA
end  (* signature BB *)


signature CC =
    sig
	structure B : BB
	type v
end  (* signature CC *)

functor F (structure B : BB) : CC =
    struct
	structure B = B
	structure A = B.A
	open A
	type u = s
    end (* functor F *)

structure C : CC = F (structure B = B);

Transcript:

- use "bug2.sml";
[opening bug2.sml]
bug2.sml:19.5-24.7 Error: unmatched type spec: v
bug2.sml:26.37 Error: unbound structure name: B
bug2.sml:26.20 Error: unmatched structure spec: A
insttyc: NULLtyc
Error: Compiler bug: Functor.applyFunctor.insttyc
[closing bug2.sml]
- 
Status: fixed in 0.73
---------------------------------------------------------------------------
362. missing primop in interp
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Jan 17 1991
Version: 0.67
System: 
Severity: 
Problem: 
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.67, 21 November 1990
  val it = () : unit
  - System.Control.interp := true;
  val it = () : unit
  - fun f x = Bits.notb x;
  Error: Compiler bug: bad primop in interp
Comments: 
Fix: 
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
363. bug in 0.69 interpreter
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: June 17 1991
Version: 0.69
System: 
Severity: 
Problem: 
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - app (fn x => x) ["abc", "def"];
  val it = () : unit
  - System.Control.interp := true;
  val it = () : unit
  - app (fn x => x) ["abc", "def"];

  uncaught exception Match
  - 
Comments: First fix the saving of lambda in interact.sml.
Fix: 
Status: fixed in 0.70
---------------------------------------------------------------------------
364. bug in lexgen doc
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: June 5 1991
Version: 
System: 
Severity: minor
Problem: 
The example of how to build a lexer is wrong (line 348), because the
input file gets opened multiple times.

        val lexer = Mlex.makeLexer (fn x => input(open_in "f",x))

should be

        val lexer = Mlex.makeLexer (inputc (open_in "f"))

This has confused at least one naive user.
Code: 
Transcript: 
Comments: 
[jgm] according to Dave Tarditi, this has been fixed in the
latest copy of the documentation.
Fix: 
Status: fixed in 0.70
---------------------------------------------------------------------------
365. fixed size of tuples causes bug
Submitter:      Jawahar Malhotra
Date:		29 May 91
Version:        0.62
System:         SUN SPARC, SUN OS 4.1
Severity:       major
Problem:        A labeled record can have no more than 100 fields
Comments:
I was browsing the typechecker code (typing/typecheck.sml) and I
noticed a constant "val maxFieldNum = 100," which I assume limits
the number of slots a tuple is allowed to have.  It would be best
to avoid such hard-coded limits, but, if they must exist, they
probably should be localized into a single structure, to allow
easy modifications.

  - John

Version 0.69 of SML/NJ:

When compiling the following code, an "uncaught exception Subscript"
occurs.  If the number of elements in the tuple is reduced to 100 from
110, the exception no longer occurs.

From: wright@rice.edu (Andrew Wright)
fun g(f) =
( f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f(),
  f(), f(), f(), f(), f(), f(), f(), f(), f(), f() );

Fix:  sort without an array
Status: fixed in 0.71
---------------------------------------------------------------------------
366. lookPath bug in 0.56
Submitter: James Shennan, University of Warwick, Coventry, 
	   CV4 7AL. tel: 0203 523523 
Date: 29th January 1991
Version: 0.56
System: 
Severity: 
Problem: 
The two modules that follow were tested independantly and they both worked.
The problem comes when they try and communicate. I have cut the modules
down as much as possible and hope that the exact problem is clear to you
(as it isn't to me!).

I've been playing around with the two modules and found that they work okay in
conjunction with eachother when the datatype node_seq in the NODE_SEQ
module is not recursive.
Code: 
*****************************************************************************
 This is the Hierarchy structure that uses the sequence structure.
******************************************************************************
import "../sequence/sequence";
signature HIERARCHY =
  sig
	type Sequence
	datatype Hierarchy = EmptyHierarchy | Addlevel of Sequence * Hierarchy
  end

functor Hierarchy(structure Node_Seq : NODE_SEQ) : HIERARCHY =
  struct
	type Sequence = Node_Seq.node_seq
	datatype Hierarchy = EmptyHierarchy | Addlevel of Sequence * Hierarchy
  end
******************************************************************************
And this is the Node_Sequence structure.
******************************************************************************
import "node";
signature NODE_SEQ =
  sig
	eqtype Element
	datatype node_seq = NIL | cons of Element * node_seq
  end

functor Node_Seq(structure Node : NODE) : NODE_SEQ =
  struct
	type Element = Node.tYpe
	datatype node_seq = NIL | cons of Element * node_seq
  end

****************************************************************************
This is the file that I 'use' to save typing. I have tried typing it in
manually as well.
****************************************************************************
import "../hierarchy/hierarchy";
structure n = Node();
structure ns = Node_Seq(structure Node = n);
structure h = Hierarchy( structure Node_Seq = ns);
open h;
val seq = ns.cons("hello",ns.NIL);
val H = Addlevel(ns.NIL,EmptyHierarchy);
val HH = Addlevel(ns.NIL,H);
val HHH = Addlevel(seq,HH);

Transcript:
Script started on Tue Jan 29 16:57:12 1991
warning: could not update utmp entry
njsmlchmod: /dev/ttyp0: Not owner
Variable syntax.
emerald> njsml
Standard ML of New Jersey, Version 0.56, 13 April 1990
Warning: input and output are now uncurried, arithmetic exceptions
are re-arranged, div and mod are different; see doc/NEWS
val it = () : unit
- use "vars";
[opening vars]
[reading ../hierarchy/hierarchy.bin... done]
signature NODE
signature HIERARCHY
signature NODE_SEQ
functor Node
functor Hierarchy
functor Node_Seq
structure n :
  sig
    eqtype tYpe
  end
structure ns :
  sig
    datatype node_seq
      con NIL : node_seq
      con cons : Element * node_seq -> node_seq
    eqtype Element
  end
structure h :
  sig
    eqtype Sequence
    datatype Hierarchy
      con Addlevel : Sequence * Hierarchy -> Hierarchy
      con EmptyHierarchy : Hierarchy
  end
open h
val seq = cons (-,NIL) : ns.node_seq
val H = Addlevel (NIL,EmptyHierarchy) : Hierarchy
val HH = Addlevel (NIL,Addlevel (NIL,EmptyHierarchy)) : Hierarchy
val HHH = Addlevel (Error: Compiler bug: EnvAccess.lookPath
[closing vars]
- ^Demerald> ^Dexit
Comments: 
Fix: Ask the submitter if it still happens in 0.73.
Status: probably fixed
---------------------------------------------------------------------------
366. lookahead
Submitter: Dave Berry <db@lfcs.edinburgh.ac.uk>
Date: Jan 26 1991
Version: ?
Severity: minor
Problem: 
If I type the following simple program to either SML/NJ or Poly/ML, I
get some interesting behaviour:

(lookahead std_in; lookahead std_in);

(I haven't tried this with Poplog ML or Edinburgh ML because they're only
installed on our Suns, which have crashed.)

If I give this program the input

a

it returns the string "a".  This is the behaviour I expect - the first
call looks at the next character but doesn't affect the state of the
stream, so the next call finds the same character.

(If you try this you'll have to type a semi-colon after the program
finishes, because the compiler will read your input.)

However, if I give the following input to the program

<CTRL-D>a

then it still returns "a".  In other words the first call consumes the
end-of-stream marker, changing the state of the stream.  It's not at all
clear to me that this is the desired behaviour.  It's this behaviour
that results in the problem with end_of_stream that I mentioned some weeks
ago, because (end_of_stream i) is defined as (lookahead i = "").

I suggest that lookahead should never change the state of a stream, even
when it finds an end-of-stream marker on an interactive stream.  This
may require some extra state information in the implementation of a 
stream, but that shouldn't be visible to the user.  This would give
more consistent behaviour, and would solve the problem with end_of_stream.
It also means that I could get rid of the InStream and OutStream types
in the Edinburgh library, making it quite a bit simpler to use (and
maintain).

Some interactive programs do have to consume end-of-stream markers on
interactive streams.  This can be done by calling read at the appropriate
place, perhaps using a function like the following:

fun consumeEOS i =
      if InStream.interactive i then
	if end_of_stream i then read i else ""
      else raise NotInteractive i;

The only problem that I can see with this approach is that a program that
tests for end_of_stream won't necessarily consume the end-of-stream marker
with an explicit read, which means that the compiler will read it and exit.
I can think of a couple of ways that an implementation could avoid this.
The first is to consume an end-of-stream marker before reading a new
program, thus requiring the user to type CTRL-D twice to exit (which might
be safer anyway).  The second is to require the user to call a specific
exit function to exit the compiler.  The third is to treat std_in specially,
and to mark when an end-of-stream marker is encountered by a user calling
lookahead as opposed to the compiler calling lookahead.  I don't know
how easy this would be to implement.

To summarise, this gives a consistent behaviour to lookahead, and seems a
far neater way of solving the end_of_stream problem than my previous
suggestion.
Status: fixed in 0.71
---------------------------------------------------------------------------
367. Decstation mach recompolation to m68
Submitter:      Gene Rollins <rollins@cs.cmu.edu>
Date:		Mar 13, 1991
Version:        0.67 Batch Compiler
System:         Decstation mach (cross compiler to m68)
Severity:       major
Problem:        Cross compiler halts with Getscratch
Code:           The 0.67 compiler sources
Transcript 1:   I added vertical ellipses to omit part that worked correctly.
     
Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler)
[setreducemore()]
[reducemore := 0]
[setrounds()]
[rounds := 10]
[setbodysize()]
[bodysize := 20]
[mBoot()]
  .
  .
  .
[Compiling boot/math.sml]
signature MATH
structure Math
boot/math.sml:290.4 Warning: match not exhaustive
        0 => ...
        1 => ...
[closing boot/math.sml]
[Failed on "~mBoot" with Getscratch]

Transcript 2:
Standard ML of New Jersey, Version 0.67, 21 November 1990 (batch compiler)
[globalhandle := false]
[markabsyn := false]
[mBoot()]
  .
  .
  .
[Compiling env/env.sml]
structure Env
[closing env/env.sml]
[Failed on "!env/env.sml" with Getscratch]
uncaught exception (Loader): Getscratch

Comments: The Sun3 Mach batch compiler for m68 works fine.
Status: fixed in 0.69, Appel suspects.
---------------------------------------------------------------------------
368. missing exceptions
Submitter: Larry Paulson (larry.paulson@computer-lab.cambridge.ac.uk)
Date: 16 Nov 90
Version: 0.69
System: 
Severity: minor
Problem: 
You have most, but not all, of those silly arithmetic exceptions.  Larry
Code: 
Transcript: 
- Abs;
std_in:7.1-7.3 Error: unbound variable Abs
- Div;
val it = exn : exn
- Mod;
val it = exn : exn
- Quot;
std_in:3.1-3.4 Error: unbound variable Quot
- Prod;
val it = exn : exn
- Neg;
val it = exn : exn
- Sum;
val it = exn : exn
- Diff;
val it = exn : exn
- Floor;
val it = exn : exn
- Sqrt;
val it = exn : exn
- Exp;
val it = exn : exn
- Ln;
val it = exn : exn
Comments: 
Fix: edit perv.sml and perv.sig
Status: fixed in 0.71
---------------------------------------------------------------------------
369. bug in MLYACC
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: May 29 1991
Version: 0.69
System: 
Severity: major
Problem: 
I was compiling mlyacc with 0.69 and noticed a couple of problems.
In addition to the syntax error in yacc.sml (lines 350-351), there is
also a funny message being generated:

  [opening yacc.sml]
  $$ lookTycPath 1: 2 2
  tyconInContext: [2]
Code: 
Transcript: 
Comments: 
[jgm] See bugs 307 and 336 -- this may not be MLYACC's fault.
Fix: see 336.
Status: fixed in 0.71
---------------------------------------------------------------------------
370. Wrong definition of div & mod in perv.sml
Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:		3/16/91
Version:        0.67
System:         All (verified on PMAX, Mach/4.3 BSD)
Severity:       major
Problem:        Wrong definition of div & mod in perv.sml
Code:           0 div ~2
Transcript:     - 0 div ~2;
		val it = ~1 : int
		- 0 mod ~2;
		val it = ~2 : int
Comments:	Definition (p.79) requires a result of 0 in both cases.
Fix:		
In boot/perv.sml, "structure Integer = ...", replace
<   fun op div(a:int,b:int):int =
<               if a>=0
<                   then if b>=0 then InLine.div(a,b)
<                                else InLine.div(a-1,b)-1
<                   else if b>=0 then InLine.div(a+1,b)-1
<                                else InLine.div(a,b)
with
>    fun op div(a:int,b:int):int =
>		if b>=0
>	 	    then if a>=0 then InLine.div(a,b)
>			         else InLine.div(a+1,b)-1
>		    else if a>0  then InLine.div(a-1,b)-1
>				 else InLine.div(a,b)
Status: fixed in 0.71
---------------------------------------------------------------------------
371. intmap bug
Submitter: Chet Murthy (murthy@cs.cornell.edu)
Date: 13 Jun 91
Version: 
System: 
Severity: 
Problem: I was using intmap to implement a hash table, and I found what appears
to be a bug.  
Code: 
(* requires intmap.sig and intmap.sml to be loaded
   To see the bug, run "try 477 trace;" and "try 476 trace;"
   the variable longtrace is bound to an even longer trace.

   Each will, for each N in the list, add (N,CTR) to the
   intmap, and then increment CTR.

   Then each will dump the intmap with intMapToList, and compare
   the cardinality of the domain (computed by getting the first
   projection of each pair in the graph given by intMapToList and
   and uniquifying it) to the actual length of the list returned
   by intMapToList.

   The function repeated will print out all the pairs (N,V) such
   that N appears more than once in the graph.  Try
   "repeated 476 trace" and observe that the output is empty,
   whereas "repeated 477 trace" produces "[(29,476),(29,316)]"
   meaning that both pairs showed up in the trace.
   *)

(* splits a list into the first N elts and the tail *)
fun chopList(0,l) = (nil,l)
  | chopList(n,h::t) =
    let val (m,l') = chopList(n-1,t) in
        (h::m,l')
    end


fun member x nil = false
|   member x (h::t) = if x = h then true else member x t

fun uniquize nil = nil
|   uniquize (h::t) = if member h t then uniquize t else h::(uniquize t)

  fun collect f l = fold List.@ (map f l) nil

fun runTo n l =
    let val (pref,_) = chopList(n,l)
        val ctr = ref 0
        val imap = Intmap.new(100,General.Match)
        fun go nil = ()
          | go (h::t) = (Intmap.add imap (h,!ctr);inc ctr;go t)
    in
        (go pref;Intmap.intMapToList imap)
end

fun try n trace = uniquize(map #1 (runTo n trace))
    = (map #1 (runTo n trace))

fun repeated n trace =
    let val graph = runTo n trace
        fun aux nil = nil
          | aux (h::t) = 
            (if member h t then [h] else nil)@(aux t)
        fun find x nil = nil
          | find x ((a,b)::t) =
            (if x = a then [(a,b)] else nil)@(find x t)
        val repetitions = aux (map #1 graph)
    in
        collect (fn x => find x graph) repetitions
    end

val trace =
    [26,98,96,64,32,52,62,91,23,53,41,30,58,67,29,16,37,
    68,51,62,89,70,5,10,76,50,90,16,51,47,48,74,32,21,
    68,33,55,58,19,12,19,81,60,31,38,15,45,69,32,19,38,
    44,0,50,97,15,8,79,55,23,3,81,11,3,23,64,26,74,23,
    57,93,69,41,66,19,96,20,63,25,90,8,44,98,98,82,40,
    46,18,81,92,65,35,65,77,98,45,39,87,46,64,2,48,43,
    2,79,83,25,41,42,98,71,39,44,65,40,77,54,32,12,15,
    80,76,55,26,43,20,57,77,15,66,11,92,64,4,8,1,22,5,
    66,39,48,17,72,41,76,28,56,41,6,69,89,31,38,44,51,
    9,64,85,45,37,82,20,97,93,82,61,18,0,27,6,17,65,20,
    23,0,23,39,98,66,75,54,23,19,77,96,57,78,22,50,30,
    13,63,84,88,12,83,84,22,41,68,61,54,60,4,69,84,10,
    21,50,35,28,89,11,62,12,75,69,80,95,6,98,94,2,84,
    60,29,51,72,77,6,20,5,95,29,97,21,49,30,89,3,70,53,
    28,74,37,59,96,22,52,65,6,98,91,22,95,8,7,65,60,61,
    44,47,62,76,30,63,46,32,94,26,30,7,73,79,29,57,12,
    15,14,57,9,25,72,89,36,87,57,66,87,59,26,26,26,16,
    66,68,26,59,59,26,72,22,55,59,73,73,26,64,96,27,73,
    96,96,26,15,43,29,96,48,48,26,71,8,84,48,68,68,26,
    31,50,97,68,88,88,26,91,59,40,88,36,36,26,35,44,31,
    36,16,16,26,39,49,88,16,48,48,26,67,99,21,48,26,27,
    98,98,98,26,48,46,98,26,26,27,77,77,77,26,0,25,77,
    26,27,15,92,92,26,61,71,92,26,27,81,81,81,26,48,19,
    81,26,26,27,15,15,15,26,9,57,15,26,26,27,10,80,80,26,
    25,48,80,26,26,27,24,24,24,26,23,76,24,26,26,27,99,76,
    76,26,43,89,76,26,26,27,34,34,34,26,7,74,34,43,6,27,
    45,26,91,91,26,91,64,91,26,26,27,31,31,31,26,31,54,31,
    26,26,27,36,13,13,26,86,29]
Transcript: 
Comments: Should fix intmap to not allow users to specify initial size.
Fix: Don't use 100 as the initial size.
Status: not a bug
---------------------------------------------------------------------------
372. open in signature causes compiler bug
Submitter:      Gene Rollins <rollins@cs.cmu.edu>
Date:           Mar 11 1991
Version:        0.67
Severity:       major
Problem:        open in signature results in compiler reporting a bug
Code:           
  signature ARITH = sig
     structure Term : TERM
     open Term
  ...
Transcript:     
  - use "src-use/arith.sig.sml";
  [opening src-use/arith.sig.sml]
  Error: Compiler bug: EnvAccess.openStructureVar -- bad access value
  [closing src-use/arith.sig.sml]
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
373. bug in printing fully qualified structure names
Submitter: Andrew Tolmach (apt@princton.edu)
Date: 16 Apr 91
Version: 0.69
System: 
Severity: minor
Problem: prints qualified names in the wrong order on error.  Looks
like someone got the list backwards.
Code: 
Transcript: 
Standard ML of New Jersey, Version 0.69, 3 April 1991
val it = () : unit
- structure Fred = struct structure Bill = struct fun f x = x + 1 end end;
structure Fred :
  sig
    structure Bill : sig...end
  end
- open Fred.Bill;
open Fred.Bill
- f true;
std_in:4.1-4.6 Error: operator and operand don't agree (tycon mismatch)
  operator domain: int
  operand:         bool
  in expression:
    Bill.Fred.f true
Comments: Appel says:  these qualified names shouldn't be there anyway!
The abstract syntax should in this case match the concrete syntax,
so the message should say, "f true" not "Fred.Bill.f true".
Fix: remove "qid@" from varApplied and strApplied in envaccess.sml
Status: fixed in 0.71
---------------------------------------------------------------------------
374. mod overflows on some negative numbers
Submitter: Eric Cooper (ecc@cs.cmu.edu)
Date: 01 May 91
Version: 0.66-0.69
System: Pmax, Vax, Sun4
Severity: major
Problem: 
Code: 
Transcript: 
- val minint = ~1073741824;
val minint = ~1073741824 : int
- minint mod 10;

uncaught exception Overflow
Comments: 
The SML definition of div and mod is different than that typically provided
by hardware, thus mod and div actually defined as

    fun op div(a:int,b:int):int =
                if a>=0
                    then if b>=0 then InLine.div(a,b)
                                 else InLine.div(a-1,b)-1
                    else if b>=0 then InLine.div(a+1,b)-1
                                 else InLine.div(a,b)
    fun op mod(a:int,b:int):int = a-(a div b)*b

(see boot/perv.sml).  The "*" in mod is causing the overflow.  You could
use quot and rem, but they may not give you the answer you want:

    - ~1073741824 rem 10;
    val it = ~4 : int

- John
Fix: First, see the fix for bug 370.  Second, use a separate case 
analysis for "mod", don't just call "div".
Status: fixed in 0.71
---------------------------------------------------------------------------
375. overflow bugs
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: 6 Dec 1990
Version: 0.67
System: 
Severity: major?
Problem: 
Dave Berry's library code trips over the following problem with
large positive integers:
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.67, 21 November 1990
  val it = () : unit
  - ~1073741822;
  val it = ~1073741822 : int
  - it+1;
  val it = ~1073741821 : int
  - ~it;
  val it = 1073741821 : int
  - 1073741821;

  uncaught exception Overflow
Comments: 
dbm@research.att.com writes:
 > (2) I have had a runbind bug report for 0.69, but it may not be the
 > same bug you have seen.  I would appreciate it very much if you could
 > send me formal bug reports on the Runbind and Overflow problems.  We
 > can certainly cope with redundant bug reports!

The easiest way to reproduce the Runbind exception is to try to load
the portable version of the SML library into SML 0.69. I've also had
it occur when I was doing something with returning options, but that
code doesn't exist anymore (I changed the structure of the code and
the problem went away).

As far as the overflow is concerned:

eXene -- version 0.2 (alpha) -- April 1, 1991
Concurrent ML, version 0.9.2, January 15, 1991
val it = () : unit
- 1073741823;

uncaught exception Overflow
- 1024;

uncaught exception Overflow           <------ this shouldn't happen
-

Standard ML of New Jersey, Version 0.68, March 7, 1991
val it = () : unit
- 1073741823;

uncaught exception Overflow
- 1024;

uncaught exception Overflow           <------ this shouldn't happen
-

Fix: 
Status: fixed as of 0.69? ([jgm] works on SGI)
---------------------------------------------------------------------------
376. empty signatures and functors, parsing
Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk)
Date: 21 Nov 1990
Version: 0.66?
Severity: minor
Problem: 
SML/NJ accepts the following (both of which are not legal SML):

   signature S = sig end functor F() = struct end;

   val x = "A" ^ if true then "B" else "C";
Comment: [dbm]
  The first problem is an intensional divergence, the second is
  fixed as of 0.69.
Status: fixed in 0.69
---------------------------------------------------------------------------
377. prop.sml has bug
Submitter: 
Date: Dec 25 1990
Version: 0.66
System: 
Severity: minor
Problem: 
../66/doc/examples/prop.sml doesn't correctly change to conjunctive
normal form.  (* exercise *)
Code: 
Transcript: 
Comments: 
Fix:  Put comment at top of prop.sml saying that it has bugs.
Status: fixed in 0.71 (comment put in!)
---------------------------------------------------------------------------
378. Error: Compiler bug: Functor.applyFunctor.redoTycs 1
Submitter: Elsa Gunter (elsa@research.att.com)
Date: Mar 8 1991
Version: 0.66 & 0.67
System: mips mips and sun3 with SunOS 4.0
Severity: major
Problem: Error: Compiler bug: Functor.applyFunctor.redoTycs 1
Code: 
(* File bug1.sml *)

signature AA =
    sig
	datatype s  =  a of t * s
	and t = b of s
end  (* signature AA *)

signature BB =
    sig
	structure A : AA
end  (* signature BB *)


signature CC =
    sig
	structure B : BB
	type u
end  (* signature CC *)

functor F (structure B : BB) : CC =
    struct
	structure B = B
	structure A = B.A
	open A
	type u = t * s
    end (* functor F *)

structure C : CC = F (structure B = B);
Transcript: 
- use "bug1.sml";
[opening bug1.sml]
bug1.sml:27.37 Error: unbound structure name: B
bug1.sml:27.20 Error: unmatched structure spec: A
Error: Compiler bug: Functor.applyFunctor.redoTycs 1
[closing bug1.sml]
-
Comments: 
Fix: Cascade
Status: fixed in 0.71
---------------------------------------------------------------------------
379. redundant patterns
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Jan 25 1991
Problem: 
I would like to suggest that the compiler reject redundant patterns as
errors (possibly with a flag to generate only warnings to preserve
compatibility with "The Definition").  The reason for this change is
that it will force the user to deal with potential errors (warning
messages usually get buried in the output).  Often, a redundant pattern
is the result of a mis-spelled constructor name, and so is actually an
error (there is an example of this in the 0.67 version of the debugger).
Transcript: 
I noticed the following redundant pattern warnings while compiling
0.67.  The debugger ones are definitely an error.
  - John

translate/translate.sml:227.30 Warning: redundant patterns in match
        VALtrans (PATH p) => ...
        VALtrans (INLINE eql) => ...
        VALtrans (INLINE neq) => ...
        VALtrans (INLINE i) => ...
        THINtrans (PATH p,v,locs) => ...
        CONtrans (d as DATACON {const=true,...}) => ...
        CONtrans (d as DATACON {const=false,...}) => ...
        VALtrans a => ...
        THINtrans (a,_,_) => ...
  -->   _ => ...


build/process.sml:334.32 Warning: redundant patterns in match
        ({access=SLOT s1,name=name},{access=SLOT s2,name=_}) => ...
        ({access=SLOT _,...},_) => ...
        ({access=PATH (:: (<pat>,<pat>)),...},{access=PATH (:: (<pat>,<pat>)),...}) => ...
        ({access=PATH _,...},_) => ...
        ({access=INLINE i1,...},{access=INLINE i2,...}) => ...
        ({access=INLINE _,...},_) => ...
  -->   _ => ...


debug/historystore.sml:371.1 Warning: redundant patterns in match
        (a,weak_desc) => ...
  -->   (_,tag) => ...
debug/historystore.sml:371.1 Warning: redundant patterns in match
        (a,weak_desc) => ...
  -->   (_,tag) => ...
debug/historystore.sml:371.1 Warning: redundant patterns in match
        (a,weak_desc) => ...
  -->   (_,tag) => ...

Status: not a bug (a suggestion)
---------------------------------------------------------------------------
380. regbind compiler bug
Submitter:	Eric Cooper, ecc@cs.cmu.edu
Date:	Dec 5, 1990
Version:	0.66
System:	VAX and SPARC running Mach 2.5
Severity:	major
Problem:	compiler raises Regbind; top-level dumps core
Code:

(*
This example causes the compiler to raise Regbind on
	SML/NJ 0.66 on Sparc
	SML/NJ 0.65 on VAX
After the exception message is printed, typing () to
the top level causes an illegal instruction trap.

It doesn't fail if:
	functor is replaced by a structure
	(name ^ "\n") is replaced by name
	(n mod period = 0) is replaced by (n + period = 0)
	the tail recursive call to proc () is removed
*)

functor Broken (S : sig
			val perform : (unit -> 'a) -> 'a
		    end) =
    struct
	val period = 0
	val name = "foo"
	val n = 0
		
	fun proc () =
	    (if n mod period = 0 then
		 S.perform (fn () => print (name ^ "\n"))
	     else
		 ();
	     proc ())
    end

(* Transcript:

Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- [opening bug.sml]
[closing bug.sml]

uncaught exception Regbind
- ();
SIGILL code 0x2

Process Inferior sml exited abnormally with code 3

*)
Status: fixed? ([jgm] works on SGI)
---------------------------------------------------------------------------
381. saving registers for signal handler continuation
Submitter: Andrew Tolmach (apt@princeton.edu)
Date: 14 may 1991
Version: 0.69
System: 
Severity: major
Problem: 
Andrew Tolmach discovered an interesting bug, which he and I traced
further.  Summary:

At a heap-limit check (typically an add-to-limit-causing-overflow),
there are two kinds of general-purpose registers:

1.  Live Pointers or Tagged Integers.  These get a 1 in the register mask.
2.  Dead Pointers, Live Untagged Integers, or anything else. 
     These get a 0.

Thus, a 0 in the mask does NOT indicate "dead."  Registers with a 1
in the mask should be forwarded (if pointers) by the G.C., and
registers with a 0 should be preserved unchanged.

Unfortunately, the function "make_ml_sigh_arg" was not preserving the 
0-in-the-mask registers, so that the string-creation function create_s
was losing a register if a signal occurred.
Code: 
Transcript: 
Comments: 
From: David.Tarditi@LAMBDA.ERGO.CS.CMU.EDU
Status: R

You write:

> Thus, a 0 in the mask does NOT indicate "dead."  Registers with a 1
> in the mask should be forwarded (if pointers) by the G.C., and
> registers with a 0 should be preserved unchanged.
>
> Unfortunately, the function "make_ml_sigh_arg" was not preserving the 
> 0-in-the-mask registers, so that the string-creation function create_s
> was losing a register if a signal occurred.

Is having ml_sigh_arg preserve all registers the right thing to do ?
Maybe we should enforce the invariant that a 0 in the mask
indicates "dead" ?   The argument for doing this is that it
makes signal handling cheaper in both time and space.  Right now,
make_ml_sigh_arg only has to save the number of used registers.
It scans each bit in the mask to determine which registers to
save until the remainder of the mask is 0, so it takes less time also,
if live registers tend to be the lower numbered registers (as they do
with the current register allocator).

The argument for not doing this is that is allows us to do
"representation analysis", i.e. place untagged integers in
registers across procedure boundaries.  I don't know what
the performance gain from this will be.

   Dave

From: Andrew Appel <appel@Princeton.EDU>
John Reppy has found that signal-handling overhead isn't too bad
(3% for 20-millisecond timer interrupts on a SPARC), and saving
a few extra register shouldn't make a huge difference.
I would certainly hate to rule out passing untagged integers across
procedure boundaries.
Fix: 
Status: not yet a bug
---------------------------------------------------------------------------
382. missing \n on infix echo
Submitter: Eric Cooper (ecc@cs.cmu.edu)
Date: Jun 11 1991
Version: 0.69
System: 
Severity: minor
Problem: 
First, a trivial one: the top-level omits the \n when echoing global infix
declarations:
Code: 
Transcript: 
	Standard ML of New Jersey, Version 0.69, 3 April 1991
	val it = () : unit
	- infix operator;
	infix operator-
(In 0.65, infix declarations weren't being printed at all.)

Comments: 
Fix: insert newline() at end of printFixity function in print/printdec.sml
Status: fixed in 0.71
---------------------------------------------------------------------------
383. open in nested structures fails with "Runbind"
Submitter: Eric Cooper (ecc@cs.cmu.edu)
Date: Jun 11 1991
Version: 0.69
System: 
Severity: major
Problem: 
The "print x" below fails with exception "Runbind".
Code: 
	structure S =
	    struct
		val x = 0
	    end;

	structure SS =
	    struct
		structure S = S
	    end

	open S;

	open SS;

	print x;	(* fails with exception Runbind *)
Transcript: 
Comments: 
This worked OK in 0.65.  Among other things, Paulson's Isabelle examples 
now fail to compile, which is how I tripped over this.
Fix: Appel partially diagnosed this, sent mail to MacQueen
Status: fixed in 0.73
---------------------------------------------------------------------------
384. signal handler never re-installed
Submitter:    Manuel Fahndrich (mf39@andrew.cmu.edu)
Date:         6/4/91
Version:      0.66 0.67
System:       DECstation 3100 (Mach and BSD UNIX 4.3)
Problem:      The signal handlers only get called the first time they are
              installed. Once setHandler(signal, NONE) is executed and then
              setHandler(signal, SOME handler), the signal is ignored.
              Tested on signals (SIGIO, SIGINT, SIGALRM)

Transcript:   fun ioh (_, k) = (print "SIGIO\n"; k);
              System.Signals.setHandler (System.Signals.SIGIO, SOME ioh);
              <ok, this works>
              System.Signals.setHandler (System.Signals.SIGIO, NONE);
              <ok, ignored>
              System.Signals.setHandler (System.Signals.SIGIO, SOME ioh);
              <wrong, still ignored!!!>

Comment:      The inqHandler returns the correct handler function at the end.
[jgm] The following code really exercises the bug:

  open System.Signals;
  setHandler(SIGINT, NONE);
  inqHandler(SIGINT);
  (* core dumps *)

Code for setHandler and inqHandler is simple enough to figure that the
bug is probably in the code generator -- it's broken on Mach and Irix,
so the OS is not to blame.  Also, ripping the signal handling code
in perv.sml out and compiling it on top of the pervasives makes the
bug go away.

(1) Suppose we do :

open System.Signals;
open System.Timer;
val setitimer = System.Unsafe.CInterface.setitimer;
fun setTimer msec =  (setitimer(0,TIME{sec=0,usec=1000*msec}, 
				   TIME{sec=0,usec=1000*msec}));
setHandler(SIGALRM,SOME(fn (_,k) => (print "hi!\n";k)));
setTimer 500;

This will print hi! twice a second (on cs or elan) or (roughly speaking) 
when return is hit (on haven), more or less as expected.

(2) Now suppose we do :

setHandler(SIGALRM,NONE); 
setHandler(SIGALRM,SOME(fn (_,k) => (print "lo!\n";k)));

On all machines, this has no visible effect; that is, lo! is not printed.

(3) But if we then do:

System.Unsafe.CInterface.c_function "enablesig" (3,true);

we do start seeing lo! just as we saw hi! before.


Finally, and most excitingly, if we do (1) followed by:

setHandler(SIGALRM,NONE); 
inqHandler SIGALRM;

we get the following results:

on haven and k2 (both versions):

Bus Error

on elan:

- Fixed up unaligned data access for pid 16679 (sml) at pc 0x417ed0
val it = SOME fn : (int * (unit) cont -> (unit) cont) option


on cs:

val it = SOME fn : (int * (unit) cont -> (unit) cont) option
[jgm]
See bug 397 for the probable cause...
Status: should be fixed in 0.70
---------------------------------------------------------------------------
385. SIGHUP, SIGQUIT, SIGTERM ignored sometimes
Submitter: Mark Foster (mark@central.cis.upenn.edu)
Date: Nov 15 1990
Version: 0.66
System: 
Severity: minor
Problem: 
It appears that some signals get ignored when they shouldn't.
In particular, SIGHUP SIGQUIT and SIGTERM don't get properly delivered
when the parent process of sml exits in certain ways.  As a result,
the sml process remains, sometimes dormant, and sometimes in a spin
loop (continuous select() calls, trying to output a message, but it
can't because it's psuedo tty is "gone").

The easiest way we've found to demonstrate the problem is via telnet

	% telnet me
	Trying 127.0.0.1 ...
	Connected to LOCALHOST.UPENN.EDU.
	Escape character is '^]'.

	(login stuff deleted)
	% sml
	Standard ML of New Jersey, Version 0.66, 15 September 1990
	val it = () : unit
	-

now, escape back to telnet, then close the connection
	^]
	telnet> c

the sml process does not exit.

WORKAROUNDS:

We have two possible workarounds to this problem.  Fundamentally, the
output that's trying to happen probably needs to be fixed.  Either
to detect when it cannot successfully output or to just give up at some
point.  The following two approaches don't do fix the problem, they just 
bandaid around it.  Both methods "cure" the problems we've been 
experiencing.

Method 1:
Change runtime/signal.c to disallow redefining of the signals used to
shutdown a child process

% diff signal.c.orig signal.c
210c210,214
<             case ML_SIG_ENABLED: SETSIG (sig, sig_handler, SIGMASK); break;
---
>             case ML_SIG_ENABLED:  if ((sig != SIGQUIT) &&
>                                       (sig != SIGHUP) && (sig != SIGTERM)) {
>                                     SETSIG (sig, sig_handler, SIGMASK);
>                                   }
>               break;
234c238,241
<           SETSIG (sig, sig_handler, SIGMASK);
---
>         if ((sig != SIGQUIT) &&
>             (sig != SIGHUP) && (sig != SIGTERM)) {
>             SETSIG (sig, sig_handler, SIGMASK);
>           }


Method 2:
Change boot/perv.sml to not attempt to output a message on quit

% diff perv.sml.orig perv.sml
1871,1873c1871
<     fun quit s _ = (
<         output(std_err, s); output(std_err, " (no coredump)\n");
<         System.Unsafe.CleanUp.shutdown())
---
>     fun quit s _ = (System.Unsafe.CleanUp.shutdown())

Date: Sun, 18 Nov 90 09:58:41 -0500
From: jhr@cs.cornell.edu (John Reppy)
Subject: Re:  signal info from Mark Foster at Penn.
Status: R

I've seen this effect, but I never thought about it enough
to realize what was going on.  His first solution is an
awkward way to say the ML can't handle SIGHUP, SIGQUIT
and SIGTERM; I like to avoid that.  His second solution is
better; but there probably should be a warning somewhere
abut the problems with SIGHUP.
  - John

From: jhr@cs.cornell.edu (John Reppy)
Subject: Re:  signal info from Mark Foster at Penn.
Cc: mark@central.cis.upenn.edu
Status: R

I think that this problem is a bug in the way select works.  If you do
a select on a closed file, it fails with EBADF; I think it should do the
same if the ptty has gone away.  But we live in an imperfect world, so
I recommend the following fix:

Replace the function quit (at the end of perv.sml) with the following
code:

    fun quit s _ = let val msg = (s ^ " (no coredump)\n\000")
	  in
	  (* use write, since IO.output will block if we've lost the ptty *)
	    System.Unsafe.SysIO.write(2, System.Unsafe.cast msg, size msg)
	      handle _ => ();
	    System.Unsafe.CleanUp.shutdown()
	  end

Status: fixed (0.69)
---------------------------------------------------------------------------
386. printing bug with abstype
Submitter: *jhr$
Date: Nov 8 1990
Version: 0.69
System: 
Severity: minor
Problem: 
Notice the misplaced white space:

  - abstype 'a foo = Foo of 'a with end;
  type'a  foo
Code: 
Transcript: 
Comments: 
Fix: search for "type" in print/printdec.sml  (also "eqtype")
Status: fixed in 0.71
---------------------------------------------------------------------------
387. arrays on Sparc
Submitter: ark
Date: Feb 12 1991
Version: 0.66
System: Sparcstation
Severity: major
Problem: dumps core when allocating large array
Code: 
array(10000000,0)
Transcript:
Comments:
Fix:
Status: fixed in 0.69
---------------------------------------------------------------------------
388. * as label of record
Submitter: Nick Rothwell (nick@lfcs.ed.ac.uk)
Date: 8 Nov 90
Version: 
System: 
Severity: minor
Problem:
SML/NJ doesn't allow

   { * = "Hello" }

as an expression. It should; after all, "*" is (chortle) just an ordinary
identifier.
Code:
Transcript:
Comments:
Fix:
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
389. stats 
Submitter: Andrew Appel (appel@princeton.edu)
Date: Apr 3 1991
Version: 0.66-0.69
System:
Severity: minor
Problem:
Bug report: versions 0.66-0.69
System.Stats.execution  (as reported in "summary()") starts out negative.
Caused by the following sequence in "interact.sml":
t := current cpu usage; exportML; t' := current cpu usage;
System.Stats.execution := t'-t
But of course, t' is less than t IN THE NEW PROCESS.
Code:
Transcript:
Comments:
Fix: Appel has a fixt for this that will go into 0.70
Status: fixed in 0.70
---------------------------------------------------------------------------
390.
Submitter:      bpwing@phoenix.princeton.edu
Date:		March 19, 1991
Version:        0.65-0.69
System:         SUN 4, v4.1?
Severity:       minor
Problem:        when reporting error positions, tabs are treated as single
		characters instead of being expanded
Comments: [jgm -- this seems correct to me...]
Status: not a bug
---------------------------------------------------------------------------
391. truncate
Submitter: David Taridti (dtarditi@cs.cmu.edu)
Date: Apr 10 1991
Version: 0.69
System:
Severity: major
Problem:
The function truncate does not work properly for large real
numbers.  For example, truncate of 4 billion yields a negative integer
when it should raise the exception Overflow:
Code:
Transcript:
Standard ML of New Jersey, Version 0.69, 3 April 1991
val it = () : unit
- truncate(4000000000.0);
val it = ~294967296 : int
Comments:
Status: fixed in 0.71
---------------------------------------------------------------------------
392. two type constraints
Submitter: Larry Paulson (lcp@computer-lab.cambridge.ac.uk)
Date: 14 Nov 90
Version: 0.66
System:
Severity: minor
Problem:
As I understand the Definition, Poly/ML is correct.  Two type constraints might
be handy if the program involves a lot of type synonyms.  Comments?
Code:
Transcript:
Standard ML of New Jersey, Version 0.66, 15 September 1990
- 0 : int : int;
std_in:2.9 Error: syntax error found at COLON

Poly/ML v1.89 - Definition of SML Version 4
> 0 : int : int;
val it = 0 : int
Comments:
Fix:
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
393. type abbreviations not transparent
Submitter: Chris Okasaki (cokasaki@cs.cmu.edu)
Date: 11/16/90
Version: 0.65
Severity: minor
Problem: type abbreviations not transparent
  In particular, when the type abbreviation takes an argument which
  does not appear on the right hand side of the abbreviation, any type
  which appears in that position should be completely irrelevant.  But
  in the current implementation this is not true.
Code:
	type ('a,'b) bogus = 'a;
	val x = 0 : (int,int) bogus; (* really int *)
	val y = 1 : (int,int list) bogus; (* really int *)
	fun f (x:'a,y:'a) = ();  (* force the types to unify *)
	f (x,y);  (* unify (int,int) bogus and (int,int list) bogus *)
                  (* should be equivalent to unifying int with int  *)
                  (* but it's not                                   *)
Transcript:
	Standard ML of New Jersey, Version 0.65, 10 September 1990
	val it = () : unit
	- type ('a,'b) bogus = 'a;
	type ('a,'b)  bogus = 'a
	- val x = 0 : (int,int) bogus;
	val x = 0 : (int,int) bogus
	- val y = 1 : (int,int list) bogus;
	val y = 1 : (int,int list) bogus
	- fun f (x:'a,y:'a) = ();
	val f = fn : 'a * 'a -> unit
	- f (x,y);
	std_in:3.1-3.7 Error: operator and operand don't agree (tycon mismatch)
	  operator domain: (int,int) bogus * (int,int) bogus
	  operand:         (int,int) bogus * (int,int list) bogus
	  in expression:
	    f (x,y)
	-
Comments:
  Interestingly enough, this doesn't seem to happen when you have a unary
  type abbreviation like
	type 'a bogus = int

  The problem seems to boil down to WHEN you project through abbreviations
  (i.e. when you do the "macro" expansion).  There seems to be at least two
  possibilities, project through before a unification containing this type,
  or attempt to unify with this type and project through only if this fails.
  As long as every argument to the type abbreviation also appears in the
  expanded form, the two are equivalent.  When an argument DOESN'T appear in
  expanded form, the second approach (which is the approach currently
  being used) causes problems.  As is evident in the above example, it
  causes the typechecker to unify things which should not be unified.

  The following code from unify.sml (in unifyTy) is where the problem is:
	   | (CONty(tycon1, args1), CONty(tycon2, args2)) =>
	       if eqTycon(tycon1, tycon2)
----->	       then unifyArgs(args1, args2)
	       else (unifyTy(reduceType ty1, ty2)
		     handle ReduceType =>
		       unifyTy(ty1, reduceType ty2)
		       handle ReduceType => raise Unify("tycon mismatch"))

  The point marked is where the damage is done.  If both types have the same
  abbreviation constructor, unification will blithely go ahead and try to
  unify ALL of the arguments, even though some of them might be irrelevant
  because they are unused.

Fix:
  Three possibilities:
    1. Decide that this is a "feature", that you really don't want
       (int,int) bogus to unify with (int,int list) bogus.  However,
       I would argue that if this is what you want, you should be using
       the datatype facility, not the type facility.
    2. Forbid type abbreviations which do not use all their arguments.
       This is somewhat unsatisfying since, although human programmers
       will probably not produce abbreviations like this, it is easy
       to imagine automatic programming utilities (like Lex or Yacc) that
       MIGHT produce such code.
    3. Perform abbreviation expansion BEFORE unifying an abbreviated
       type with anything except a type variable (you would want to
       unify the type variable with the abbreviated type so that
       it can be printed correctly).  The best way to do this is
       probably to define a new constructor for the type "ty" called
       something like ABBREVty of tycon * tylist * ty where the
         tycon is the abbreviation constructor
         tylist are the constructor's arguments
         and ty is the "macro expanded" type

       Then, in unifyTy, you could have (right after the two VARty clauses)
	  | (ABBREVty(_,_,ty),_) => unifyTy(ty,ty2)
	  | (_,ABBREVty(_,_,ty)) => unifyTy(ty1,ty)
       to project through the abbreviation appropriately.

       The catch to this is that you can then produce circular types
       so you would have to perform an occur check during type printing.
       For instance, consider the following:
		type ('a,'b) bogus;
		fun f (x:'b,y:('a,'b) bogus) = ();
                fun g x = f (x,x);
       What is the type of g?  Really, it's 'a->unit but internally
       it's something like (pardon the abuse of notation):
		ABBREVty(bogus,['a,*],'a) --> unit
       where the * marks a circular reference back to the ABBREVty object.
       Obviously, a naive attempt to print this type will infinite loop--
       hence the requirement for an occur check during type printing.
Status: fixed in 0.74 (dbm)
---------------------------------------------------------------------------
394. strange message in 0.66 typechecker
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: 6 Nov 1990
Version: 0.66
Severity: minor
Code:
Transcript:
  Standard ML of New Jersey, Version 0.66, 15 September 1990
  val it = () : unit
  - signature SAMPLER =
  =   sig
  =     type time sharing type time = System.Timer.time
  =     val init : unit -> unit
  =     val sample : (time * int * int) -> unit
  =   end;
  signature SAMPLER =
    sig
      isEqTycon 1 UNDEF
  type time
      val init : unit -> unit
      val sample : time * int * int -> unit
    end
  - 
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
395. weakness constraint problem
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Mar 18 1991
Problem:
I'm having trouble with a weakness constraint, and I don't understand it.
I have a function at top-level of a module, which the typechecker gives
the type

    val attach : 'aU CML.chan * widget_t * mbutton_t * 'aU menu_t -> widget_t

My memory is that the 'aU is an internal type variable?  Anyway, attach
calls another function taht also has an 'aU in its type; by adding a
type constraint to the other function, then things compile.  Anyway,
this seems like a bug (and I think I've run into it before).
Code:
Transcript:
Comments:
Here is a smaller example that triggers the bug.  The offending line is
marked by "(** THIS DOESN'T WORK **)"


signature INTERNAL_CML =
  sig
    type 'a event
    val sync : 'a event -> 'a
  end

functor ConcurML () : INTERNAL_CML =
  struct

    exception Never and Escape
    exception Sync (* for signature compatability *)

    datatype evt_sts = EVT_ANY | EVT_READY | EVT_BLOCK

    type 'a base_evt = {
        pollfn : unit -> evt_sts,
        dofn : unit -> 'a,
        blockfn : bool ref -> 'a
      }

    datatype 'a event = EVT of 'a base_evt list

    local
      datatype 'a ready_evts
        = NO_EVTS                               (* no ready events *)
        | ANY_EVTS of (int * (unit -> 'a) list) (* list of ready anyevents *)
        | RDY_EVTS of (int * (unit -> 'a) list) (* list of ready events *)

      fun extract _ = NO_EVTS

    (* Generate index numbers for "non-deterministic" selection.  We use a
     * round-robin style policy. *)
      val cnt = ref 0
      fun random i = let val j = !cnt in cnt := j+1; (j mod i) end
      fun selectEvt (_, [f]) = f()
        | selectEvt (n, l) = (nth(l, random n)) ()
    in

  (* sync : 'a event -> 'a *)
    fun sync (EVT []) = raise Never (** THIS DOESN'T WORK **)
    (*fun sync ((EVT []) : 'a event) = raise Never*)  (** THIS WORKS **)
      | sync (EVT el) = (
          case (extract el)
           of NO_EVTS => callcc (fn sync_k => let
                val evtflg = ref false
                fun log ({blockfn, ...} : 'a base_evt)=
                      (throw sync_k (blockfn evtflg)) handle Escape => ()
                in
                  app log el;
                  (*atomicDispatch()*) raise Sync
                end)
            | ANY_EVTS anyevts => selectEvt anyevts
            | RDY_EVTS evts => selectEvt evts)

    end (* local *)

  end (* functor ConcurML *)
Comment:  This is really the way that user-bound type variables are 
          supposed to work!
Status: not a bug
---------------------------------------------------------------------------
396. unbound variables should have type ERRORty
Submitter: Dave MacQueen (dbm@research.att.com)
Date: May 7 1991
Version: 0.66?
Severity: minor
Problem:
An unbound variable should have type ERRORty rather than UNDEFty so that
spurious secondary errors can be avoided.  E.g.

foo 3;
Error: unbound variable foo
Error: operator is not a function
  operator: undef
  in expression
    foo 3

Status: fixed (as of 0.69)
---------------------------------------------------------------------------
397. Unsafe.update with constant
Submitter: Andrew Tolmach (apt@princeton.edu)
Date: Mar 18 1991
Version: 0.69
System: Mips
Severity: critical
Problem:
from Appel:
Andrew Tolmach discovered the following bug, and I've tracked it down.
Unsafe.update is unreliable on the MIPS when the value stored is a constant.
(The same temporary is used twice in mips.sml).  I'll fix this for the
next version; in the meantime, use Array.update.
Code:
Transcript:
Comments:
[jgm]
This is probably causing the bug in the signal handling routines.
See bug 384
Fix: Appel and Tolmach have the fix, will install in 0.70
Status: fixed in 0.70
---------------------------------------------------------------------------
398. use and pathnames
Submitter: ark
Date: May 13 1991
Version: 0.66
Severity: minor
Problem:
A reminder: SML still doesn't interpret pathnames in "use"
calls relative to the correct directory.
Comments:
  Should be taken over by sourcegroup mechanisms.
Fix:  make "use" accumulate filepaths (using filepaths.sig)
Status: open
---------------------------------------------------------------------------
399. Vax dumps core
Submitter: David Tarditi (dtarditi@cs.cmu.edu)
Date: Mar 14 1991
Version: 0.67
System: Vax
Severity: critical
Problem:
The following piece of code causes version 0.67 of the compiler
to dump core on Vaxes running Mach:

- val s = "a";
- s;
Segmentation fault (core dumped)
Code:
Transcript:
Comments:
Fix: 
Status: fixed in 0.69
---------------------------------------------------------------------------
400. problem parsing weak types
Submitter:      John Ophel  jlophel@watmsg.waterloo.edu
Date:           9/11/90
Version:        0.66
System:         Vax, Unix
Severity:       minor
Problem:        weak type variables incorrectly parsed
Transcript:

- fun f (x:'10000000a) = x;
val f = fn : 'a -> 'a

- fun f (x:'10000001a) = x;
std_in:1.5-1.24 Error: pattern and constraint don't agree (weakness violation)
  pattern:    'Z
  constraint: '10000001aU
  in pattern:
    x : '10000001aU
Fix:  In mkUBOUND (basics/typesutil.sml), weakness of more than 900000 
should be illegal.  Also note that the type variable '10000000000000a
will cause an uncaught Overflow, which should be caught in this function.
Status: fixed in 0.71
---------------------------------------------------------------------------
401. Imperative types in SML/NJ 0.66
Submitter: Dave Berry <db@lfcs.edinburgh.ac.uk>
Date: 14 Feb 91 
Version: 0.66
System:
Severity: 
Problem: 
The following program compiles under Poly/ML 1.86, but fails to compile
under SML/NJ 0.66.


fun create (x:int) (y:'_a) :'_a Array.array = Array.array (x, y)

type ('a,'b) table = ('a*int*'b) list Array.array

val defaultSize = 97

fun createDefault (sample'value :'_a) :(string, '_a) table =
  let val mt = [] : (string * int * '_a) list
  in create defaultSize mt
  end


It will compile if Array.array is used directly in place of the curried
version.  It will also compile if createDefault is given an extra parameter,
either before or after the existing one.

This is the simplest example I've run across of SML/NJ failing to type
correct SML use of imperative types. It's fairly simple in this case -
it only took me a day to get the case this simple - but I've come across
at least one other example that I've just given up on.

I remember Dave MacQueen and mads Tofte discussing a bug in the SML/NJ
algorithm at the Edinburgh Workshop.  Is there any chance of a fix?

Dave.


From: jhr@cs.cornell.edu (John Reppy)
This problem was pointed out by Jim O'Toole.  Anyway, it was fixed
in 0.67:

  Standard ML of New Jersey, Version 0.68-JHR, January 25, 1991
  val it = () : unit
  - fun create (x:int) (y:'_a) :'_a Array.array = Array.array (x, y)
  = type ('a,'b) table = ('a*int*'b) list Array.array
  = val defaultSize = 97
  = fun createDefault (sample'value :'_a) :(string, '_a) table =
  = let val mt = [] : (string * int * '_a) list
  = in create defaultSize mt
  = end;
  val create = fn : int -> '1a -> '1a array
  type ('a,'b)  table = ('a * int * 'b) list array
  val defaultSize = 97 : int
  val createDefault = fn : '1a -> (string,'1a) table
  - 
Status: fixed (as of 0.67)
---------------------------------------------------------------------------
402. local non-declarations
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		30/1/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        some declarations not accepted
Code:           local val x = 5 in 20 + x end;
Transcript:     - local val x = 5 in 20 + x end;
		std_in:1.21 Error: syntax error found at INT
Comments:	Not sure this is a bug, but the SML documents are not clear
		about this. According to my interpretation of the standard
		grammar, this declaration should be equivalent to the following:
		- local val x = 5 in val it = 20 + x end;
		val it = 25 : int
Fix:  expressions are considered as declarations ONLY at top level.
Status: not a bug
-------------------------------------------
403. 0.0/0.0 not properly handled
Submitter:      Bernard Berthomieu (bernard@laas.laas.fr)
Date:		30/1/90
Version:        0.66
System:         SUN Sparstation 1+, SunOS 4.0.3c
Severity:       minor
Problem:        0.0/0.0 not properly handled
Code:           0.0/0.0
Transcript:     - 0.0/0.0;
		strange floating point error        (* and sml exits *)
Comments:	0.0/0.0 is generally considered in implementations 
		of reals as an "invalid operation" rather than a "division
		by zero" (exception code FPE_FLTOPERR_TRAP on SUNs OS 4.0).
		I did not checked the effect of 0.0/0.0 on other targets
		than SUN 4s, but it might have strange effects too;
Fix:
Status: fixed (as of 0.69)
---------------------------------------------------------------------------
404. std_out not flushed on read from std_in
Submitter:    Kim Dam Petersen  (kimdam@sun.tfl.dk)
Date:		June 1991
Version:        0.66
System:         all
Severity:       minor
Problem:        std_out not flushed on read from std_in
Comments:
 As printing on the standard output and error streams usually are
 flushed automatically I would suggest that this should be part of the
 standard behaviour of these stream.

 It seems that NJ/ML delays output flushing until the computation of a
 top level expression has completed.  As mentioned above flushing
 should be performed immediately.  A temporary solution in NJ/ML is
 to redefine the `output' function, such that the predefined
 `flush_out' is automatically called:

      val output = fn(s,t) => (output(s,t); flush_out s)

 Future call of `output' will print the text immediately.
Status: fixed in 0.71
---------------------------------------------------------------------------
405. identifiers starting with underscores are incorrectly allowed
Submitter: Mick Francis (Abstract Hardware)
Date:		August 1991
Version:        0.66
System:         all
Severity:       minor
Problem:        identifiers starting with underscores are incorrectly allowed
Status: fixed in 0.73
---------------------------------------------------------------------------
406. funny signatures in 0.71
Submitter: John Reppy
Date:		August 1991
Version:        0.71
System:         all
Severity:       minor
Problem:        Array.tabulate and String.chr have wrong types
		in initial environment
Status: fixed in 0.73
---------------------------------------------------------------------------
407. create_v_v for SPARC
Submitter:      Juergen Buntrock TUB, jubu@cs.tu-berlin.de 
Date: Tue Sep 24 19:23:13 MET DST 1991
Version: 0.73
System:       	sun4c SUNOS 4.1.1 
Severity:       major
Problem:
		The mask is not set in create_v_v (SPARC.prim.s)
		segmentation fault
		in collect_roots in callgc.c
Fix:
diff -c SPARC.prim.s.org SPARC.prim.s

*** SPARC.prim.s.org    Fri Aug 23 20:33:54 1991
--- SPARC.prim.s        Tue Sep 24 19:11:30 1991
***************
*** 476,481 ****
--- 476,483 ----
        nop
  4:
        CONTINUE
+       .word   closmask                /* reg. mask */
+       .word   0

  3:
        add     %g0,0,%g0               /* nop to get PC adjust right */

Status: Fixed in 0.74
---------------------------------------------------------------------------
408. feedback from module system
Submitter:      tmb@ai.mit.edu
Date:           08/03/91
Version:        0.70
System:         Sun4/OS4.1.1
Severity:       cosmetic, but important

I have been playing around with building functors that abstract
various notions of "iteration", "array", "sequence", and "index"
(ultimately, this will hopefully provide a nicer alternative to the
equivalent data structures in the current SML library).

In general, using the ML module and type system for this seems
straightforward and natural, and I'm much more pleased with the way I
can design this code in SML than with similar code that I have written
in Scheme, CommonLisp, and C++.

However, I have also come across some cosmetic but (to me) important
problems with the NJ/SML module system.

Some of the problems are that the system isn't telling me enough about
the identity of objects to allow me to debug the code without having
to guess much; something analogous to the LispMachine inspector and
mouse sensitivity would ultimately be very useful, but for the time
being, just reporting unique tags for objects instead of "?"  would be
sufficient.

Some of this might also be a question of style, but my ignorance is
partially due to the fact that the only uses of the module system that
I have seen have been rather simple and straightforward (even if they
involve lots of code).

I'd appreciate your feedback.

						Thanks, Thomas.

PS: I can send you the complete code if you are interested, but
it is still more of a sketch or prototype.

= 1 ================================================================

I have a functor which generates iteration constructs for some data
type that it is handed (e.g., it generates "fold", "apply", etc. for
lists and arrays). It is very confusing that the types that the system
reports for the functions generated by this functor involve types of
the form "('a,'b) value" and "('a,'b) index". It would be much better
if the types were reported in their true form.

   signature S = sig type ('a,'b) data end;
   functor F(structure X:S) = struct fun f(x:('a,'b) X.data):('a,'b) X.data = x end;
   structure A = struct type ('a,'b) data = 'b list end;
   structure B = F(structure X=A);

   - B.f([1]);
   val it = [1] : ('a,int) A.data
   -

What I would want is:

   - B.f([1]);
   val it = [1] : int list
   -

Obviously, which form one wants depends on the exact use that a
functor is going to be put to. There should be a mechanism for me to
specify in the type binding which form of reporting I prefer.

= 2 ================================================================

Another problem that I have encountered is that it is nearly
impossible to figure out what goes wrong with complicated functor
applications with the current level of reporting: elements of
intermediate structures are now often only reported as
"?.KeyIndexing.foo", and it isn't helpful if the compiler tells you
that "?.KeyIndexing.foo" is a different type from "?.KeyIndexing.foo".

It would be much more convenient if there was an option to the
compiler that would trace and report functor applications, and if the
printer gave unique identities to structures, even temporary ones.

Something like:

   - use "foo";
   [Applying functor F<10> to structure <1001> giving structure <347> bound to structure T]
   [Applying functor G<11> to structure <66> giving structure <67> bound to structure T.M]
   [Applying functor G<11> to structure <33> giving structure <68> bound to structure T.M]
   - T.i;
   val it = SOMETHING : <11>.my_type;
   -

Printing unique ID's for structures (and, for that matter, for other
objects) shouldn't be hard, and it makes debugging so much easier.

= 3 ================================================================

When writing signatures for functors that generate polymorphic
functions, I seem to have to define types that carry around one type
variable for each polymorphic type, e.g.:

signature BASICACCESS =
    sig
	type ('a,'b) point
	type ('a,'b) value
	type ('a,'b) index
	type ('a,'b) range
	val first: ('a,'b) range -> ('a,'b) index
	val succ: ('a,'b) index -> ('a,'b) index
	val done: ('a,'b) index -> bool
	val mkindex: ('a,'b) point * ('a,'b) range -> ('a,'b) index
	val at: ('a,'b) index -> ('a,'b) value
    end;

Most of the polymorphic functions that get generated from BASICACCESS
structures will never need both type variables, while others may need
more than two.

For example,

structure BasicListIndex =
    struct
	type ('a,'b) point = 'a list
	type ('a,'b) value = 'a
	type ('a,'b) index = 'a list
	type ('a,'b) range = 'a list
	fun first x = x
	val succ = tl
	val done = null
	fun mkindex(x,y) = x
	fun at x = System.Unsafe.cast (hd x)  (* bug in NJSML .70 type checker ? *)
    end;

structure BasicArrayIndex =
    struct
	type ('a,'b) point = int
	type ('a,'b) index = int * int
	type ('a,'b) range = int
	fun first(limit:('a,'b) range):('a,'b) index = (0,limit)
	fun succ((x,limit):('a,'b) index):('a,'b) index = (x+1,limit)
	fun done((x,limit):('a,'b) index):bool = x>=limit
	fun at x = x
	fun mkindex(x,r) = (x,r)
	fun index1((x,_):('a,'b) index) = x
    end;

Carrying around the dummy type variables on types like "('a,'b) point"
is a bother. Perhaps a simple solution would be to allow the user to
omit type variables if they are specified as wildcards, e.g., "type
('_,'_) point = int" can be used simply as "val x : point" with the
compiler inserting the missing (wildcard) type variables by
convention.

More generally, it would seem to be nice if type constructors could
take variable numbers of arguments, and if they could pass their
argument lists around as complete entities (analogous to passing
around tuples of arguments in ML).

Another possibility would be to allow "free" type variables:

   type point = '_ list

This would simply be syntactic sugar for

   type 'a point = 'a list

and the compiler would implicitly provide a dummy argument to "point"
wherever it is used. However, this may break other parts of the type
or module system.

    Point 3 is really about a basic problem with the current
    way signatures and functors handle types, not about "'_". 

    Essentially, I want to write functors that generate objects
    that are polymorphic in different ways, e.g., that sometimes
    generate a function "f : 'a -> 'a" and sometimes "f : 'a -> 'b".

    The only way I could find of writing signatures for such functors is to
    make both the LHS and the RHS types (e.g.  type ('a,'b) arg; type
    ('a,'b) result) that depend on two type variables and instantiate them
    in the matching structures to the correct types. This causes a number
    of problems that I mentioned in my previous message.

    Another possibility would be to allow a function of type "'a -> 'a"
    to match a type specification "'a -> 'b", but that does not
    currently work.

    Functors that generate functions that are polymorphic
    in different ways are very important, and, one way or another,
    SML must make this more convenient than it is right now.

				    Thanks, Thomas.
= 4 ================================================================

A related problem is that nongeneric weak type variables
generate an error even if they are never used:

   - val x: '0a t = 3;
   std_in:3.1-3.16 Error: nongeneric weak type variable
     x : '0aU t
   -

I think you can guess from the above structures and functors
how such non-generic weak type variables can pop up unexpectedly
(they are easy to fix for the user, by simply giving a type
to the value, but it seems odd for a user of, say structure
"Array2D" to have to specify some type as "(unit,int) array"
just to create an array of type "int array").

= 5 ================================================================

A minor problem with wildcard type variables:

- type ('_,'_) a;
std_in:7.7-7.11 Error: duplicate type variable: '1
std_in:7.7-7.11 Error: duplicate type variable: '1
std_in:7.7-7.11 Error: duplicate type variable: '1
std_in:7.7-7.11 Error: duplicate type variable: '1
std_in:7.7-7.11 Error: duplicate type variable: '1
- 

I think the "'_" should refer to a new type variable every time it is
used (this is, after all, what "_" does in ML).

Followup discussion:

    Dave MacQueen writes:
     > What you are looking for may be rather difficult to do within the
     > framework of the ML type system.  At first glance it appears to
     > require a serious innovation in the type system to capture an
     > abstraction that could instantiate to both "f : 'a -> 'a" and
     > "f : 'a -> 'b" (note that these two types have different numbers of
     > bound variables).
     > 
     > Do you have any suggestions as to how this could be done?

    I believe it is possible to express type constraints like this
    with SML:

    signature S =
	sig
	    type ('a,'b) from
	    type ('a,'b) to
	    val f : ('a,'b) from -> ('a,'b) to
	end;

    structure X:S =
	struct
	    type ('a,'b) from = 'a
	    type ('a,'b) to = 'a
	    fun f(x) = x
	end;

    structure Y:S =
	struct
	    type ('a,'b) from = 'a * 'b
	    type ('a,'b) to = 'a
	    fun f(x,y) = x
	end;

    (These are actually not accepted by NJ/SML 0.70, even if the types for
    "f" are fully specified in the structure definitions (you get a
    different error message in that case), but I think that's a bug.)

    The main problem is that this use of types in signatures seems to have
    been rather uncommon so far, so, at least NJ/SML has several
    difficulties with it:

     * the type checker/module system (incorrectly?) rejects
       some constructs like this

     * unused type variables need to be instantiated by
       the user when they become weak; instead, the
       language could automatically define such variables to
       be "unit"

     * the type constructors "from" and "to" are really
       auxilliary, and users of S most likely never want
       to see them printed; the current system prints them

     * the writer of the signature "S" has to pick a maximum
       number of auxilliary type variables used as arguments
       to "from" and "to", but I believe that the actual maximum
       number needed depends on the arguments given to the functor,
       not on the functor itself

    I want to state again that I think this feature is important. Without
    the ability to specify signatures that can match structures that are
    polymorphic in different ways, it seems I would have to write
    completely redundant versions of some functors.

    The context in which it came up was writing a functor that generates
    iteration constructs for collections; for some collections, indexes
    and values are different types, for others, they are the same type.

Status: not a bug
---------------------------------------------------------------------------
409. type checking after functor application
Submitter:      tmb@ai.mit.edu
Date:           08/05/91
Version:        0.70
System:         Sun4/OS4.1.1
Severity:       ?
Problem:

Basically, I have something like:

functor F(...) =
    struct
        structure A = G(...);
        ...
        open A
    end;

structure X = F(...);

X.A.f arg;               --> works
X.f arg;                 --> fails with a type error

Comment:

X.A.f and X.f must refer to the same value with the same type: A has
simply been opened at the end of structure X. I don't see how X.f
could ever behave differently from X.A.f.

Sorry about the long code needed to reproduce the bug. I had several
guesses what the problem might be due to, but I have not been able
to reduce the code further than this. In particular, the problem
goes away if the last functor application is removed, i.e.,

   functor GeneralArray(structure Index:BASICACCESS) = struct ... end;
   structure Arrays = GeneralArray(structure Index = BasicArrayIndex);

is replaced with

   structure Arrays =
       struct
           structure Index:BASICACCESS = BasicArrayIndex
           ... body of functor GeneralArray ...
       end

Also, don't try to make sense of the code. To isolate the bug this
far, I collapsed several types.

Code: (file foo.sml)
  signature BASICACCESS =
      sig
	  type ('a,'b) index
	  type ('a,'b) range
	  val first: ('a,'b) range -> ('a,'b) index
	  val succ: ('a,'b) index -> ('a,'b) index
	  val done: ('a,'b) index -> bool
      end;

  functor GeneralIteration(structure Access:BASICACCESS) =
      struct
	  local
	      open Access
	  in
	      fun apply f r =
		  let
		      fun loop(i) = if done(i) then () else (f(i); loop(succ(i)))
		  in
		      loop(first(r))
		  end
	  end
      end;

  functor GeneralArray(structure Index:BASICACCESS) =
      struct
	  type ('a,'b) array = 'b Array.array * ('a,'b) Index.range

	  structure ValueIndex =
	      struct
		  type ('a,'b) range = ('a,'b) array
		  type ('a,'b) index = 'b Array.array * ('a,'b)Index.index
		  fun first((a,r):('a,'b) range) = (a,Index.first(r))
		  fun succ((a,r):('a,'b) index) = (a,Index.succ(r))
		  fun done((a,r):('a,'b) index) = Index.done(r)
	      end

	  structure Value = GeneralIteration(structure Access = ValueIndex)

	  fun array(r:(unit,'1b) Index.range,initial):(unit,'1b) array =
	      (Array.array(100,initial),r)

	  open Value
      end;

  structure BasicArrayIndex =
      struct
	  type ('a,'b) index = int * int
	  type ('a,'b) range = int
	  fun first(limit:('a,'b) range):('a,'b) index = (0,limit)
	  fun succ((x,limit):('a,'b) index):('a,'b) index = (x+1,limit)
	  fun done((x,limit):('a,'b) index):bool = x>=limit
      end;

  structure Arrays = GeneralArray(structure Index = BasicArrayIndex);

Transcript:
volterra$ sml
Standard ML of New Jersey, Version 0.70, 1 July 1991
val it = () : unit
- use "foo.sml";
[opening foo.sml]
signature BASICACCESS =
  sig
    type ('a,'b) index
    type ('a,'b) range
    val done : ('a,'b) index -> bool
    val first : ('a,'b) range -> ('a,'b) index
    val succ : ('a,'b) index -> ('a,'b) index
  end
functor GeneralIteration : <sig>
functor GeneralArray : <sig>
structure BasicArrayIndex :
  sig
    eqtype ('a,'b) index
    eqtype ('a,'b) range
    val done : ('a,'b) index -> bool
    val first : ('a,'b) range -> ('a,'b) index
    val succ : ('a,'b) index -> ('a,'b) index
  end
structure Arrays :
  sig
    structure Value : sig...end
    structure ValueIndex : sig...end
    eqtype ('a,'b) array
    val apply : (('a,'b) ?.ValueIndex.index -> 'c) -> ('a,'b) ?.ValueIndex.range
 -> unit
    val array : (unit,'1a) BasicArrayIndex.range * '1a -> (unit,'1a) array
  end
[closing foo.sml]
val it = () : unit
- val x = Arrays.array(100,0);
val x = (prim?,100) : (unit,int) Arrays.array
- Arrays.Value.Apply (fn a => a) x;
std_in:4.1-4.18 Error: unbound variable or constructor in structure: Apply
- Arrays.Value.apply (fn a => a) x;
val it = () : unit
- Arrays.apply (fn a => a) x;
std_in:2.1-2.26 Error: operator and operand don't agree (tycon mismatch)
  operator domain: ('Z,int) ?.ValueIndex.range
  operand:         (unit,int) Arrays.array
  in expression:
    Arrays.apply ((fn <pat> => <exp>)) x
- volterra$

Status: fixed in 0.73
---------------------------------------------------------------------------
410. inlining property not preserved in simple renaming
Submitter: Andrew Tolmach (apt@cs.princeton.edu)
Date: 8/6/91
Version: 0.73
Severity: minor
Problem: 
  If I use System.Unsafe.getvar directly, it is inlined, as expected.

  If I type

  val g = System.Unsafe.getvar

  then g does not have access INLINE.

  Dbm suggests that this is because g is being eta-expanded; I haven't found
  where this happens in the source.

  In any case, I don't know why the initial definition of


  val getvar = InLine.getvar

  inside the definition of System.Unsafe *does* manage to transfer the inline
  property...  Is it because there's something special about structure InLine?

Fix: look for MARKexps around the rhs VALvar.
  Tolmach: abstract syntax marking.  The MARKexps surrounding the RHS of

    val a = System.Unsafe.getvar

  prevent the INLINE-ness of getvar being recognized by parse/corelang.sml valbind.
  If I turn off marking, it works.
  Tarditi: We should alter parse/corelang.sml valbind so that it recognizes this
  case specially and properly assigns the INLINE property.

Status: fixed in 0.74
---------------------------------------------------------------------------
411. Runbind
Submitter: John Reppy (jhr)
Date: 8/10/91
Version: 0.71
Problem: Runbind exception
Transcript:

  Standard ML of New Jersey, Version 0.71, 23 July 1991
  val it = () : unit
  - structure A = struct val x = 1 end;
  structure A :
    sig
      val x : int
    end
  - structure B = struct structure A = A; val y = 2 end;
  structure B :
    sig
      structure A : sig...end
      val y : int
    end
  - open A;
  open A
  - open B;
  open B
  - x;

  uncaught exception Runbind

Status: fixed in 0.73
---------------------------------------------------------------------------
412. Runbind
Submitter: Dave Tarditi
Date: 8/13/91
Version: 0.71
Problem: 
Code: 
    structure A =
       struct
	 val x = 5
	 structure B = 
	    struct
	       val y = 5
	    end
       end

    open A.B;
    structure A = struct end;
    y;
Comments: (Tarditi)
  There's an incorrect assumption in checkopen, which tests whether
  any value in a structure which has been rebound is still accessible.
  Let the old structure be called S and the new environment be N.  Let
  the symbols bound in the environment of S be T.   The assumption is
  that if any symbol A in T is unbound in N, then all other symbols
  in T are also unbound in N.  This is clearly untrue, as the above
  example shows, where x is unbound in the environment after the redefinition
  of A but y is not.

Status: fixed in 0.73
---------------------------------------------------------------------------
413. System and IO problems
Submitter: Emden Gansner
Date: 8/16/91
Version: 0.71
Problem: 
  The version of system in the System structure should have type string -> int

  The execute function in IO is incorrect as written. It passes the
  the value of environ() to exec, but this is a list of SML strings
  and exec expects a list of C strings. It should pass (map c_string environ())
  instead.

  Finally, the execute function would be a lot more useful if it allowed
  a list of arguments as well as program pathname.
Status: fixed in 0.74 (JHR)
---------------------------------------------------------------------------
414. getWD wrong
Submitter : Ian King <ik@sys.uea.ac.uk>
Date      : 19th August 1991
Version   : SML of New Jersey Version 0.66 , 15 September 1990
System    : Sun 3/160 , Sun OS 4.1
Severity  : Minor
Problem   : The function getWD in structure System.Directory when called 
            with a unit gives an incoorect result.
Code      : fun test path =
                let
                   val cwd = System.Directory.getWD ()
                in
                   { cd_in = fn () => (cd path),
                     cd_out = fn () => (cd cwd) }
                end
Transcipt  : val {cd_in,cd_out} = test "directoryname";
                val cd_in = fn : unit -> unit
                val cd_out = fn : unit -> unit

             cd_in ();
                val it = () : unit;

             cd_out ();
                uncaught exception NotDirectory

Comments   : This code executes correctly on a Sun Sparc machine. It does not 
             execute correctly on our Sun 3/160. Although I have marked the
             bug as minor it is irritating because it crashes code which
             needs to change directories such as loaders.
	     ** This is probably another example of bug #651 (JHR, 10/6/92) **
Status: fixed
---------------------------------------------------------------------------
415. late error detection in parsing
Submitter:      David N. Turner <dnt@dcs.ed.ac.uk>
Date:		17th September 1991
Version:        SML of NJ version 0.73
System:         Sun4
Severity:       minor
Problem:

	The following incorrect text doesn't generate an error,
	the secondary prompt appears and the error is only signalled
 	after more text if typed in. Perhaps this is some kind of
	parser lookahead problem?

	- if true then 365;		(* My input 	*)
	=				(* nj-sml output *)
Status: open
---------------------------------------------------------------------------
416. equality property checking in functor parameter matching
Submitter: Simon Finn <simon@abstract-hardware-ltd.co.uk>
Date: 9/13/91
Version: ?
Severity: minor
Problem: 
Try the following simple (?) exercise in semantics, provided by my
colleague Mike Crawley:
 
	signature PSIG =
	sig
	  eqtype 'a symTab ;
          datatype guide = G1 | G2 of guide symTab
        end;

(Q1) Is guide an eqtype? (in PSIG)
(A1) Yes, since we require the equality-principal signature.

	functor PFUN (structure S : sig type 'a symTab end) =
	struct
	  open S;
	  datatype guide = G1 | G2 of guide symTab;
	end;

(Q2) Is guide an eqtype? (in the output signature of PFUN)
(A2) No, because symTab isn't and our signatures must respect equality


	structure S = struct datatype 'a symTab = Empty end;
	structure P = PFUN(structure S = S);

(Q3) Is guide an eqtype? (in the signature of P)
(A3) No, because it wasn't in the functor.
     Technically, this is because the realisation, \phi, used
     to instantiate the body of the functor doesn't touch
     the bound type names contained in the output signature
     of the functor (except, possibly, for an alpha-conversion).
     
	P.G1 = P.G1;

(Q4) Is this legal?
(A4) No, because P.guide is not an eqtype (see above).

	functor MFUN(structure X : PSIG) =
	struct
	  val z = X.G1 = X.G1;
	end;
	structure M = MFUN(structure X = P);

(Q5) Is this legal?
(A5) No, because MFUN demands that guide be an eqtype (see Q1),
     but P.guide is not an eqtype (see Q3, Q4).


Both SMLNJ 0.66 and Poly/ML 1.88 get Q1 - Q4 right but get Q5 wrong.
Poly/ML 1.98 gets Q1 - Q5 right.

Comment: Conjecture that this is a benign bug.  Have not been able to
  come up with version that is actually wrong.

Fix: Could record equality properties inferred in parameter signature
     instantiation in the signature (memoizing).

Status: open
---------------------------------------------------------------------------
417. cosmetic error message suggestion
Submitter: Andy Koenig
Date: 9/12/91
Version: ?
Problem: 
  Minor suggestion for SML-NJ:  in error messages, how about
  printing infix functions as infix?

Transcript: 
  - 3 + 4.0;
  std_in:1.1-1.7 Error: operator and operand don't agree (tycon mismatch)
    operator domain: int * int
    operand:         int * real
    in expression:
      + (3,4.0)
      ^^^^^^^^^     Why not  3+4.0      ??
		    or at least op+ (3,4.0)

Comment: use original code in error message instead of "pretty-printing"
  abstract syntax
Status: open
---------------------------------------------------------------------------
418. repeated type names in type declarations
Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:		September 11, 1991
Version:        0.72
System:         All
Severity:       minor (but with potentially serious consequences)
Problem:        Repeated type names in DATATYPE ... WITHTYPE ...
		destroy type security.
Transcript:     Standard ML of New Jersey, Version 0.72, 29 August 1991
		val it = () : unit
		- datatype t = T of int withtype t = string;
		datatype  t
		con T : int -> t
		type  t = string
		- T 65:string;
		val it = "A" : string
		-
Comments:	Same problem with ABSTYPE...WITHTYPE. See also bug report 349.

Status: fixed in 0.74
---------------------------------------------------------------------------
419. Runbind
Submitter:      Venkatesh Akella  akella@cs.utah.edu
Date:		8/27/91
Version:        SML of NJ version 0.71
System:         Sparc IPC, SunOS
Severity:       major
Problem:        Raises an uncaught exception Runbind when
		a simple CML program running under SML version 0.71
		(Version of CML being used is 0.95)
		The bug can't be reproduced with CML version 0.90 running
		under SML/NJ 0.66
Code:

fun placeBuffer () =
   let 
	val c = channel () 
	val b = channel () 
	val a = channel ()
	fun input_int (s:string) =
	    fold (fn(a,r) => ord(a) - ord("0") + 10 * r) (tl (rev(explode s))) 0;

	fun P1 x   = (CIO.print( "Waiting for Input on Channel a? \n");
		let
			val y =  input_int(CIO.input_line std_in)
		in
			s__3 x y
		end)
	and 
 	    s__3 x y   = ( ( send (c,y ) ; P1 y  ))

	fun P2 z   = (let val v =  accept  c in s__5 z v  end)
	and 
  	   s__5 z v  =
	( (CIO.print (" Output on Channel b!"^Integer.makestring(v)^"\n");
	P2 v  ))
   in 
	 spawn (fn () => P1 4  );
	 spawn (fn () => P2 5  );
	() 
 	 end;

Transcript:

6 bliss /u/akella/compiler/cml/cml95/cml-0.9.5:: > cml
val it = true : bool
- System.Directory.cd "/u/akella/compiler/hop/example";
val it = () : unit
- use "test_buf.sml";
[opening test_buf.sml]
[closing test_buf.sml]

uncaught exception Runbind
-

Comments:
	The same bug was observed in SML/NJ version 0.66 too but in
	a different context. I had one integrated environment with
	SML 0.66, ML-yacc, ML-lex, CML(version 0.9) and my own code.

Status: fixed in 0.74
---------------------------------------------------------------------------
420. uncaught Nth while compiling
Submitter:	Tsung-Min Kuo	kuo@ecrc.de
Date:		Sep 19, 1991
Version:        Version 0.66, 15 September 1990
System:         SPARCstation 1, SUNOS 4.0
Severity:	sever
Problem:        Compiler-generated exception : uncaught exception Nth
Code:
	signature EXCHANGE_STRUCTURE =
	sig
	   type tree 
	   val new_node : tree -> tree
	end
	
	structure ex : EXCHANGE_STRUCTURE =
	struct
	datatype tree = Subwindow of subwindow
		      | Canvas of canvas
		      | Frame of frame
		      | Baseframe of baseframe
		      | NULL
	withtype subwindow = {t_node: tree}
	and canvas = {subwindow: subwindow}
	and frame = {tree_node: tree}
	and baseframe = {frame: frame,foog:bool} 
	
	exception Tube_Bug
	
	fun position (Canvas c) = position(Subwindow(#subwindow c))
	  | position (Baseframe bf) = position(Frame (#frame bf))
	  | position _ = raise Tube_Bug
	
	fun tn_set_position(t,p) = ()
	fun set_position (Subwindow sb) = tn_set_position(#t_node sb,0)
	  | set_position (Frame f) = tn_set_position(#tree_node f,0)
	  | set_position (Canvas c) = set_position(Subwindow(#subwindow c))
	  | set_position (Baseframe bf) = set_position(Frame(#frame bf))
	  | set_position _ = raise Tube_Bug
	
	fun components(Canvas c) = components(Subwindow (#subwindow c))
	  | components(Baseframe bf) = components(Frame (#frame bf))
	  | components _ = raise Tube_Bug
	
	fun bounding_box(Canvas c) = bounding_box(Subwindow (#subwindow c))
	  | bounding_box(Baseframe bf) = bounding_box(Frame (#frame bf))
	  | bounding_box _ = raise Tube_Bug
	
	fun tn_set_bounding_box(t,r) = ()
	fun set_bounding_box(Subwindow sb) = tn_set_bounding_box(#t_node sb,0)
	  | set_bounding_box(Frame f) = tn_set_bounding_box(#tree_node f,0)
	  | set_bounding_box(Canvas c) = set_bounding_box(Subwindow(#subwindow c))
	  | set_bounding_box(Baseframe bf) = set_bounding_box(Frame(#frame bf))
	  | set_bounding_box _ = raise Tube_Bug
	
	fun new_node tl =
	   let
	      val pos = position(Frame {tree_node = tl})
	   in
	      NULL
	   end
	end

Transcript:
	- use "bug";
	[opening bug]
	[closing bug]

	uncaught exception Nth
	-
Comments: The enclosed code is a trimmed version of a big program, got in an
	  attempt to isolate the error. As you can see, this program virtually
	  does nothing and is full of redundancy. But whatever I did to try to
	  cut it down, results in a good program happily accepted by compiler.
	  Here are some of the things I have tried :
	  * not use the signature constraint on the structure
	  * delete any of the redundant function definitions, e.g."components"
	  * remove the redundant call to function "position" in "new_node"
	  * or, even call "position" with argument NULL
	  * remove a clause from any function definition(I tried many of them)
	  * flat the record, e.g. make type frame = tree
	  * remove the boolean field in type "baseframe"
	  * get rid of second argument of functions "tn_set_position" and
	    "tn_set_bounding_box"
	  * replace equal by equal, e.g. replace calls to "tn_set_position"
	    by ()
	  * replace recursive call by direct call, e.g. in "Canvas" clause of
	    function "set_position"
	Conclusion: These are so diverse that I can not even guess any.

Status: fixed in 0.73
---------------------------------------------------------------------------
421. getWD under SPARC/Mach (same as 353)
Submitter: Fritz Knabe <Frederick_Knabe@ARCTIC.FOX.CS.CMU.edu>
Date: 9/18/91
Version: 0.73
System: SPARC/Mach (CMU)
Severity: minor
Problem: 
  System.Directory.getWD () is still broken for me in version 73
  on a Sparc. It raises a SystemCall exception.
Transcript: (c/o Gene Rollins, 8/21/92)
Standard ML of New Jersey, Version 0.88, August 14, 1992
  with SourceGroup 2.2 built on Mon Aug 17 23:23:16 EDT 1992
- fun pwd() = System.system "pwd";
val pwd = fn : unit -> int
- fun cd x = (System.Directory.cd x; pwd()) handle any => (pwd(); raise any);
val cd = fn : string -> int
- fun ll () = System.system "ls -lL";
val ll = fn : unit -> int
- fun mkdir x = System.system ("mkdir " ^ x);
val mkdir = fn : string -> int
- pwd();
/usr0/rollins
val it = 0 : int
- ll();
total 0
val it = 0 : int
- mkdir "src";
val it = 0 : int
- mkdir "bin";
val it = 0 : int
- ll();
total 2
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
val it = 0 : int
- cd "src";
/usr0/rollins/src
val it = 0 : int
- cd "../bin";
/usr0/rollins/bin
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- cd "bin";
/usr0/rollins/bin
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 2
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
val it = 0 : int
- mkdir "tools";
val it = 0 : int
- cd "src";
/usr0/rollins/src
val it = 0 : int
- cd "../tools";
/usr0/rollins/src

uncaught exception NotDirectory
- cd "../bin";
/usr0/rollins/bin
val it = 0 : int
- cd "../tools";
/usr0/rollins/bin

uncaught exception NotDirectory  (* the rest is more of the same *)
- cd "..";
/usr0/rollins
val it = 0 : int
- cd "tools";
/usr0/rollins/tools
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../tools";
/usr0/rollins/src

uncaught exception NotDirectory
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 3
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
val it = 0 : int
- mkdir "mo.mipsl";
val it = 0 : int
- ll();
total 4
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
val it = 0 : int
- cd "mo.mipsl";
/usr0/rollins

uncaught exception NotDirectory
- cd "src";
/usr0/rollins/src
val it = 0 : int
- cd "../mo.mipsl";
/usr0/rollins/mo.mipsl
val it = 0 : int
- cd "../tools";
/usr0/rollins/mo.mipsl

uncaught exception NotDirectory
- cd "../bin";
/usr0/rollins/bin
val it = 0 : int
- cd "../mo.mipsl";
/usr0/rollins/mo.mipsl
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- cd "mo.mipsl";
/usr0/rollins

uncaught exception NotDirectory
- ll();
total 4
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
val it = 0 : int
- mkdir "zed";
val it = 0 : int
- ll();
total 5
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- cd "zed";
/usr0/rollins/zed
val it = 0 : int
- cd "../tools";
/usr0/rollins/zed

uncaught exception NotDirectory
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../zed";
/usr0/rollins/zed
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- mkdir "moon";
val it = 0 : int
- cd "moon";
/usr0/rollins

uncaught exception NotDirectory
- cd "src";
/usr0/rollins/src
val it = 0 : int
- cd "../moon";
/usr0/rollins/moon
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 6
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- mkdir "tooth";
val it = 0 : int
- ll();
total 7
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- cd "tooth";
/usr0/rollins/tooth
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../tooth";
/usr0/rollins/src

uncaught exception NotDirectory
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 7
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- cd "mzz";
/usr0/rollins

uncaught exception NotDirectory
- mkdir "mzz";
val it = 0 : int
- cd "mzz";
/usr0/rollins/mzz
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../mzz";
/usr0/rollins/mzz
val it = 0 : int
- mkdir "me";
val it = 0 : int
- ll();
total 1
drwxr-xr-x  2 rollins       512 Aug 20 12:26 me
val it = 0 : int
- pwd();
/usr0/rollins/mzz
val it = 0 : int
- cd "..";
/usr0/rollins
val it = 0 : int
- mkdir "me";
val it = 0 : int
- ll();
total 9
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:26 me
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  3 rollins       512 Aug 20 12:26 mzz
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- cd "me";
/usr0/rollins/me
val it = 0 : int
- cd "../tooth";
/usr0/rollins/me

uncaught exception NotDirectory
- cd "..";
/usr0/rollins
val it = 0 : int
- mkdir "teeth";
val it = 0 : int
- cd "teeth";
/usr0/rollins/teeth
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../teeth";
/usr0/rollins/src

uncaught exception NotDirectory
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 10
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:26 me
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  3 rollins       512 Aug 20 12:26 mzz
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:27 teeth
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- mkdir "tzz";
val it = 0 : int
- ll();
total 11
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:26 me
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  3 rollins       512 Aug 20 12:26 mzz
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:27 teeth
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:27 tzz
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- cd "tzz";
/usr0/rollins/tzz
val it = 0 : int
- cd "../src";
/usr0/rollins/src
val it = 0 : int
- cd "../tzz";
/usr0/rollins/tzz
val it = 0 : int
- cd "../teeth";
/usr0/rollins/tzz

uncaught exception NotDirectory
- cd "..";
/usr0/rollins
val it = 0 : int
- ll();
total 11
drwxr-xr-x  2 rollins       512 Aug 20 12:16 bin
drwxr-xr-x  2 rollins       512 Aug 20 12:26 me
drwxr-xr-x  2 rollins       512 Aug 20 12:18 mo.mipsl
drwxr-xr-x  2 rollins       512 Aug 20 12:24 moon
drwxr-xr-x  3 rollins       512 Aug 20 12:26 mzz
drwxr-xr-x  2 rollins       512 Aug 20 12:16 src
drwxr-xr-x  2 rollins       512 Aug 20 12:27 teeth
drwxr-xr-x  2 rollins       512 Aug 20 12:17 tools
drwxr-xr-x  2 rollins       512 Aug 20 12:25 tooth
drwxr-xr-x  2 rollins       512 Aug 20 12:27 tzz
drwxr-xr-x  2 rollins       512 Aug 20 12:23 zed
val it = 0 : int
- 
Comment: (Lal George)
  There is an operating system level 3 call that can be used to
  get the working directory.
  Unfortunately, we cannot use this because it does a malloc.
  So we have to build up the working directory pathname by
  interpreting inodes.
  It is my guess that this is what bombs out in the Andrew file
  system.
  ** This is probably another example of bug #651 (JHR, 10/6/92) **
Status: fixed
---------------------------------------------------------------------------
422. overflow on int to real conversion
Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:		September 20, 1991
Version:        0.73
System:         all
Severity:       major
Problem:        int->real conversion overflows on MININT
Transcript:     Standard ML of New Jersey, Version 0.73, 10 September 1991
		Arrays have changed; see doc/NEWS
		val it = () : unit
		- ~0x40000000;
		val it = ~1073741824 : int
		- real it;	

		uncaught exception Overflow
		-	
Fix:		In boot/perv.sml, move redundant check for MININT
                from Integer.mod to Real.real  :-).

Status: Fixed in 0.74
---------------------------------------------------------------------------
423. printing of structure signatures
Submitter: John Reppy
Date: 10/1/91
Version: 0.73
Severity: minor
Problem: 
  At top level, some structure signatures are printed as identifiers,
  while others are printed in full.
Transcript: 
  Standard ML of New Jersey, Version 0.73, 10 September 1991
  Arrays have changed; see doc/NEWS
  val it = () : unit
  - structure I = IO;
  structure I : IO
  - structure V = Vector;
  structure V : 
    sig
      eqtype 'a vector
      exception Size
      exception Subscript
      val length : 'a vector -> int
      val sub : 'a vector * int -> 'a
      val tabulate : int * (int -> 'a) -> 'a vector
      val vector : 'a list -> 'a vector
      val vector_n : int * 'a list -> 'a vector
    end
  - 
Comments: [Dave Tarditi]
The reported behavior is intentional: the basic idea is that if we know
the name of a structure's signature, we print the name of the signature
instead of the whole signature.

More formally, if S is structure which is bound to structure id SX,
and S was the result of doing a signature match against signature T,
which itself is bound to signature identifier TX, then when we print
the signature for the structure bound to SX, we will print TX, provided
that TX is still bound to the same signature.

Thus we get the following results at the top-level:

- structure S = IO;
structure S : IO
- structure T = S;
structure T : IO

but when we re-bind the signature identifier IO we get:

- signature IO = sig end;
signature IO =
  sig
  end
- structure S = IO
structure S =
  sig 
    type instream
  ...
  end

The problem is that the signature identifier VECTOR is not in 
the top-level environment.  To fix this, change
build/process.sml, lines 202-204 from:

           map Symbol.sigSymbol ["REF","LIST","ARRAY","BYTEARRAY","IO","BOOL",
 				 "ENVIRON", "COMPILE", 
		                 "STRING","INTEGER","REAL","GENERAL"]
to:
           map Symbol.sigSymbol ["REF","LIST","ARRAY","BYTEARRAY","IO","BOOL",
 				 "ENVIRON", "COMPILE"
		                 "STRING","INTEGER","REAL","GENERAL",
	                         "VECTOR"]

Maybe we should add a flag to toggle this behavior, but I was hoping
that we would an environment browsing structure to the compiler
instead.  It's a kludge to have to type "structure S = S" to see the
signature of S.

Status: not a but (but a feature!)
---------------------------------------------------------------------------
424. IO.execute on SPARC
Submitter: Emden Gansner
Date: 10/1/91
Version: 0.73
System: SPARC, SunOS 4.1
Severity: moderate
Problem: 
    "I just noticed that, starting with 0.71, the IO.execute function
    causes problems on the sparc, running SunOS4.1. This problem 
    doesn't occur on 0.73 running on hunny."
Transcript: 
  t) /usr/addon/sml/bin/*69*
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - IO.execute "/bin/date";
  val it = (-,-) : instream * outstream
  - t)
  t) sml
  Standard ML of New Jersey, Version 0.71, 23 July 1991
  val it = () : unit
  - IO.execute "/bin/date";
  /home/erg/bin/sml[7]: 6446 Bus error
  t) sml73
  Standard ML of New Jersey, Version 0.73, 10 September 1991
  val it = () : unit
  - IO.execute "/bin/date";
  Bus error
  t)
Status: fixed in 0.74 (JHR)
---------------------------------------------------------------------------
425. profiler flakiness
Submitter: Frank Pfenning
Date: 10/2/91
Version: 0.73
Problem: 
    I am currently in the process of eliminating obvious inefficiencies in an ML
  implementation of a logic programming language.  While using the profiler, I
  noticed that it seemed to lead to inordinately large core images during the
  development (there is also a small overhead for the mere fact that we are
  profiling, but that is acceptable).  My guess is the profiler keeps a
  (non-weak) pointer to code somehow, which prevents it from being garbage
  collected even if it is no longer accessible from the top-level.  The fact
  that redefined functions show up twice or more often in the profiling
  statistics seem to confirm that, but I may be using it wrong, or there could
  be other reasons.  I would be interested to hear what the
  developer/implementor of the profiler has to say about this.  Thanks,
Comment: (Andrew Appel)
  Yes, I think your analysis is correct.
  There's a profiler function that resets the profiler; perhaps that's
  what you want.  But if you use it, you'd have to reload your entire
  source code.
Status: fixed in 0.86
---------------------------------------------------------------------------
426. type printing
Submitter: Andy Koenig (europa!ark)
Date: 10/4/91
Version: 0.73
Severity: minor
Problem: 
  Spurious parenthesis around unit.
Transcript: 
	- (3,());
	val it = (3,()) : int * (unit)
Status: fixed in 0.74
---------------------------------------------------------------------------
427. Compiler bug: defineEqTycon/eqtyc
Submitter: John Reppy
Date: 10/6/91
Version: 0.73
Severity: ?
Problem: 
  Compiler bug: defineEqTycon/eqtyc -- bad tycon
Transcript: 
  Standard ML of New Jersey, Version 0.73, 10 September 1991
  Arrays have changed; see doc/NEWS
  val it = () : unit
  - 	datatype 'a array = ARRAY of 'a ref VECTOR;
  std_in:2.38-2.43 Error: unbound type constructor VECTOR
  Error: Compiler bug: defineEqTycon/eqtyc -- bad tycon
Comments:
  Obviously this code is incorrect, but I have a bigger example that
  only prints out the "bad tycon" message.
Status: fixed in 0.74
---------------------------------------------------------------------------
428. openStructureVar -- bad access value
Submitter:      Benjamin.Pierce@cs.cmu.edu
Date:		4/3/91
Version:        0.67 (with SourceGroup)
System:         SunOS 4.1
Severity:       Major
Problem:        Compiler bug: EnvAccess.openStructureVar -- bad access value
Code:           see below
Transcript:     

Standard ML of New Jersey, Version 0.67, 21 November 1990
(Built on Sun Mar 17 11:37:30 EST 1991 with GnuTags and SourceGroup)
val it = () : unit
- use "bad.tmp";
[opening bad.tmp]
signature WR =
  sig
    type Wr
    val close : Wr -> unit
    val extract_str : Wr -> string
    val to_file : string -> Wr
    val to_fn : (string -> unit) -> (unit -> unit) -> Wr
    val to_nowhere : unit -> Wr
    val to_stdout : unit -> Wr
    val to_string : unit -> Wr
    val to_wrs : Wr list -> Wr
    val write_wr : Wr -> string -> unit
  end
signature PP =
  sig
    structure Wr : sig...end
    type Pp
    val DEBUG : bool ref
    val break : Pp -> bool -> int -> unit
    val endb : Pp -> unit
    val expbreak : Pp -> bool -> string -> unit
    val pp_from_wr : Wr.Wr -> Pp
    val pwrite : Pp -> string -> unit
    val set_margin : Pp -> int -> unit
    val setb : Pp -> unit
    val wr_from_pp : Pp -> Wr.Wr
  end
signature WRMGT =
  sig
    structure Pp : sig...end
    structure Wr : sig...end
    val get_current_wr : unit -> Wr.Wr
    val set_current_wr : Wr.Wr -> unit
    val stdpp : unit -> Pp.Pp
    val write : string -> unit
  end
signature STRINGUTILS =
  sig
  end
signature REGISTRY =
  sig
    type registeredtype
    val register : string -> (registeredtype -> unit) -> unit
    val registerflag : string -> registeredtype ref -> unit
    val set_all : registeredtype -> unit
    val set_flag : string -> registeredtype -> unit
  end
signature LISTUTILS =
  sig
    val filter : ('a -> bool) -> 'a list -> 'a list
    val forall : ('a -> bool) -> 'a list -> bool
    val forsome : ('a -> bool) -> 'a list -> bool
    val mapappend : ('a -> 'b list) -> 'a list -> 'b list
    val mapfold : ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> 'a list -> 'b
    val mapunit : ('b -> 'a) -> 'b list -> unit
    val mapunit_tuple : ('a -> unit) -> (unit -> unit) -> 'a list -> unit
    val memq : ('a -> 'a -> bool) -> 'a list -> 'a -> bool
  end
signature ID =
  sig
    type T
    val == : T -> T -> bool
    val hashcode : T -> int
    val intern : string -> T
    val new : unit -> T
    val new_from : T -> T
    val tostr : T -> string
  end
signature DEBUGUTILS =
  sig
    val wrap : bool ref -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a
  end
signature GLOBALS =
  sig
    structure Id : sig...end
    structure Pp : sig...end
    structure Pp : sig...end
    structure Wr : sig...end
    structure Wr : sig...end
    structure WrMgt : sig...end
    type registeredtype
    val filter : ('a -> bool) -> 'a list -> 'a list
    val forall : ('a -> bool) -> 'a list -> bool
    val forsome : ('a -> bool) -> 'a list -> bool
    val get_current_wr : unit -> Wr.Wr
    val mapappend : ('a -> 'b list) -> 'a list -> 'b list
    val mapfold : ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> 'a list -> 'b
    val mapunit : ('b -> 'a) -> 'b list -> unit
    val mapunit_tuple : ('a -> unit) -> (unit -> unit) -> 'a list -> unit
    val memq : ('a -> 'a -> bool) -> 'a list -> 'a -> bool
    val register : string -> (registeredtype -> unit) -> unit
    val registerflag : string -> registeredtype ref -> unit
    val set_all : registeredtype -> unit
    val set_current_wr : Wr.Wr -> unit
    val set_flag : string -> registeredtype -> unit
    val stdpp : unit -> Pp.Pp
    val wrap : bool ref -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a
    val write : string -> unit
  end
Error: Compiler bug: EnvAccess.openStructureVar -- bad access value
[closing bad.tmp]
- 


--------------------------------------------------------------------------
(* And here's the offending file ... *)

signature WR = sig

type Wr

val to_stdout: unit -> Wr
val to_file: string -> Wr
val to_nowhere: unit -> Wr
val to_wrs: Wr list -> Wr
val to_fn: (string->unit) -> (unit->unit) -> Wr
val to_string: unit -> Wr
val extract_str: Wr -> string

val close: Wr -> unit

val write_wr: Wr -> string -> unit

end;
signature PP = sig

structure Wr: WR

type Pp

val pp_from_wr: Wr.Wr -> Pp
val wr_from_pp: Pp -> Wr.Wr;

val pwrite : Pp -> string -> unit
val setb: Pp -> unit
val endb: Pp -> unit
val break: Pp -> bool -> int -> unit
val expbreak: Pp -> bool -> string -> unit
val set_margin: Pp -> int -> unit

val DEBUG: bool ref

end;

signature WRMGT = sig

(* Maintains a notion of a current (prettyprinting) writer 
   and its associated prettyprinter *)

structure Wr: WR;
structure Pp: PP;
sharing Pp.Wr = Wr;

val set_current_wr: Wr.Wr -> unit;
val get_current_wr: unit -> Wr.Wr;
val stdpp: unit -> Pp.Pp;

val write: string -> unit;

end;

signature STRINGUTILS = sig

end;

signature REGISTRY = sig

type registeredtype

val register: string -> (registeredtype->unit) -> unit
val registerflag: string -> (registeredtype ref) -> unit

val set_flag: string -> registeredtype -> unit
val set_all: registeredtype -> unit

end;

signature LISTUTILS = sig

val memq: ('a -> 'a -> bool) -> 'a list -> 'a -> bool

val mapappend: ('a -> 'b list) -> ('a list) -> ('b list)
val mapunit: ('a -> 'b) -> ('a list) -> unit
val mapunit_tuple: ('a -> unit) -> (unit -> unit) -> ('a list) -> unit

val mapfold: ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> ('a list) -> 'b
val forall: ('a -> bool) -> ('a list) -> bool
val forsome: ('a -> bool) -> ('a list) -> bool

val filter: ('a -> bool) -> ('a list) -> ('a list)

end;

signature ID = sig

type T 

val intern: string -> T
val tostr: T -> string

val hashcode: T -> int 
val new: unit -> T
val new_from: T -> T

val == : T -> T -> bool

end;


(* May eventually want to support these too:

   val lexlt : T -> T -> bool
*)

signature DEBUGUTILS = sig

val wrap: (bool ref) -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a

end;

signature GLOBALS = sig

structure Wr: WR
structure Pp: PP
structure WrMgt: WRMGT
structure Id: ID

sharing Pp.Wr = Wr
sharing WrMgt.Pp = Pp

include WRMGT

include LISTUTILS
include STRINGUTILS
include DEBUGUTILS
include REGISTRY

sharing type registeredtype = bool

end;

signature TYPPVT = sig

structure Globals: GLOBALS
open Globals

datatype pretyp = 
	    PRETVAR of Id.T
	  | PREARROW of pretyp * pretyp
	  | PREALL of Id.T * pretyp * pretyp
	  | PREMEET of pretyp list

datatype T = 
	    TVAR of unit * int
	  | ARROW of unit * T * T
	  | ALL of {name:Id.T} * T * T
	  | MEET of unit * (T list)
	  
datatype tenvelt = BND of Id.T * T
		 | ABB of Id.T * T
		 | VBND of Id.T * T

datatype tenv = TENV of tenvelt list

val empty_tenv: tenv
val extend_bound: tenv -> Id.T -> T -> tenv
val push_bound: tenv -> Id.T -> T -> tenv
val extend_abbrev: tenv -> Id.T -> T -> tenv
val push_abbrev: tenv -> Id.T -> T -> tenv
val extend_binding: tenv -> Id.T -> T -> tenv
val push_binding: tenv -> Id.T -> T -> tenv
val pop: tenv -> tenv

val index: tenv -> Id.T -> int
val lookup_name: tenv -> int -> Id.T
val lookup_and_relocate_bound: tenv -> int -> T
val lookup_and_relocate_binding: tenv -> int -> T
val lookup_and_relocate: tenv -> int -> tenvelt
val lookup: tenv -> int -> tenvelt
val relocate: int -> T -> T

exception UnknownId of string
exception WrongKindOfId of tenv * int * string
val debruijnify: tenv -> pretyp -> T

val prt: Pp.Pp -> tenv -> T -> unit
val prt_tenv: Pp.Pp -> tenv -> unit

val NS: T

end;
Status: fixed in 0.71
---------------------------------------------------------------------------
429. signature match fails
Submitter: Benjamin Pierce <Benjamin.Pierce@PROOF.ERGO.CS.CMU.EDU>
Date: 4/4/91
Version: 0.69
Problem: signature spec not matched when it should be
Transcript:
  Standard ML of New Jersey, Version 0.69, 3 April 1991
  val it = () : unit
  - use "bug.tmp";
  use "bug.tmp";
  [opening bug.tmp]

  [Major collection...
  [Increasing heap to 10011k]
   96% used (3502604/3627780), 7260 msec]

  [Increasing heap to 10431k]
  bug.tmp:1545.8-1775.3 Error: value type in structure doesn't match signature spec
    name: prt
    spec:   Pp -> tenv -> T -> unit
    actual: ?.Pp -> tenv -> T -> unit
  bug.tmp:1545.8-1775.3 Error: value type in structure doesn't match signature spec
    name: prt_tenv
    spec:   Pp -> tenv -> unit
    actual: ?.Pp -> tenv -> unit
  bug.tmp:1798.7-1802.44 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      Typ.prt pp
  bug.tmp:1798.7-1820.56 Error: rules don't agree (tycon mismatch)
    expected: ?.Pp * 'Z * 'Y list * 'X * rhs_flag -> unit
    found:    ?.Pp * tenv * lhsqueue list * 'W * 'V -> 'U
    rule:
      (pp,te,:: (ARROW_LHS <pat>,nil),t2,flag) => (<exp> <exp> te t1;# # t2 flag)
  bug.tmp:1807.7-1809.38 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      Pp.pwrite pp
  bug.tmp:1798.7-1820.56 Error: rules don't agree (tycon mismatch)
    expected: ?.Pp * 'Z * 'Y list * 'X * rhs_flag -> unit
    found:    ?.Pp * tenv * lhsqueue list * 'W * 'V -> 'U
    rule:
      (pp,te,:: (ARROW_LHS <pat>,X2),t2,flag) => (<exp> <exp> te t1;Pp.pwrite pp ",";# # t2 flag)
  bug.tmp:1811.7-1814.56 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      Typ.prt pp
  bug.tmp:1811.7-1814.56 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      describe_rest pp
  bug.tmp:1816.7-1820.56 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      Typ.prt pp
  bug.tmp:1816.7-1820.56 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      describe_rest pp
  bug.tmp:1797.1-1820.56 Error: pattern and expression in val rec dec don't agree (tycon mismatch)
    pattern:    ?.Pp -> tenv -> lhsqueue list -> 'Z -> 'Y -> 'X
    expression: ?.Pp -> tenv -> lhsqueue list -> 'W -> rhs_flag -> unit
    in declaration:
      describe_rest = (fn arg => (fn <pat> => <exp>))
  bug.tmp:1823.3-1829.14 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      Typ.prt pp
  bug.tmp:1823.3-1829.14 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      describe_rest pp
  bug.tmp:1874.15-1874.54 Error: operator and operand don't agree (tycon mismatch)
    operator domain: ?.Pp
    operand:         ?.Pp
    in expression:
      describe_problem (stdpp ())
  [closing bug.tmp]


  --------------------------------------------------------------------------
  (* and here's the offending file...  Sorry it's a bit long *)

  signature WR = sig

  type Wr

  val to_stdout: unit -> Wr
  val to_file: string -> Wr
  val to_nowhere: unit -> Wr
  val to_wrs: Wr list -> Wr
  val to_fn: (string->unit) -> (unit->unit) -> Wr
  val to_string: unit -> Wr
  val extract_str: Wr -> string

  val close: Wr -> unit

  val write_wr: Wr -> string -> unit

  end
  signature PP = sig

  structure Wr: WR

  type Pp

  val pp_from_wr: Wr.Wr -> Pp
  val wr_from_pp: Pp -> Wr.Wr;

  val pwrite : Pp -> string -> unit
  val setb: Pp -> unit
  val endb: Pp -> unit
  val break: Pp -> bool -> int -> unit
  val expbreak: Pp -> bool -> string -> unit
  val set_margin: Pp -> int -> unit

  val DEBUG: bool ref

  end
  signature WRMGT = sig

  (* Maintains a notion of a current (prettyprinting) writer 
     and its associated prettyprinter *)

  structure Wr: WR;
  structure Pp: PP;
  sharing Pp.Wr = Wr;

  val set_current_wr: Wr.Wr -> unit;
  val get_current_wr: unit -> Wr.Wr;
  val stdpp: unit -> Pp.Pp;

  val write: string -> unit;

  end
  signature STRINGUTILS = sig

  end
  signature REGISTRY = sig

  type registeredtype

  val register: string -> (registeredtype->unit) -> unit
  val registerflag: string -> (registeredtype ref) -> unit

  val set_flag: string -> registeredtype -> unit
  val set_all: registeredtype -> unit

  end
  signature LISTUTILS = sig

  val memq: ('a -> 'a -> bool) -> 'a list -> 'a -> bool

  val mapappend: ('a -> 'b list) -> ('a list) -> ('b list)
  val mapunit: ('a -> 'b) -> ('a list) -> unit
  val mapunit_tuple: ('a -> unit) -> (unit -> unit) -> ('a list) -> unit

  val mapfold: ('a -> 'b) -> ('b -> 'b -> 'b) -> 'b -> ('a list) -> 'b
  val forall: ('a -> bool) -> ('a list) -> bool
  val forsome: ('a -> bool) -> ('a list) -> bool

  val filter: ('a -> bool) -> ('a list) -> ('a list)

  end
  signature ID = sig

  type T 

  val intern: string -> T
  val tostr: T -> string

  val hashcode: T -> int 
  val new: unit -> T
  val new_from: T -> T

  val == : T -> T -> bool

  end

  (* May eventually want to support these too:

     val lexlt : T -> T -> bool
  *)

  signature DEBUGUTILS = sig

  val wrap: (bool ref) -> string -> (unit -> 'a) -> (unit -> unit) -> ('a -> unit) -> 'a

  end
  signature GLOBALS = sig

  structure Wr: WR
  structure Pp: PP
  structure WrMgt: WRMGT
  structure Id: ID

  sharing Pp.Wr = Wr
  sharing WrMgt.Pp = Pp

  include WRMGT

  include LISTUTILS
  include STRINGUTILS
  include DEBUGUTILS
  include REGISTRY

  sharing type registeredtype = bool

  exception CantHappen

  end
  signature TYPPVT = sig

  structure Globals: GLOBALS
  open Globals

  datatype pretyp = 
	      PRETVAR of Id.T
	    | PREARROW of pretyp * pretyp
	    | PREALL of Id.T * pretyp * pretyp
	    | PREMEET of pretyp list

  datatype T = 
	      TVAR of unit * int
	    | ARROW of unit * T * T
	    | ALL of {name:Id.T} * T * T
	    | MEET of unit * (T list)

  datatype tenvelt = BND of Id.T * T
		   | ABB of Id.T * T
		   | VBND of Id.T * T

  datatype tenv = TENV of tenvelt list

  val empty_tenv: tenv
  val push_bound: tenv -> Id.T -> T -> tenv
  val push_abbrev: tenv -> Id.T -> T -> tenv
  val push_binding: tenv -> Id.T -> T -> tenv
  val pop: tenv -> tenv

  val index: tenv -> Id.T -> int
  val lookup_name: tenv -> int -> Id.T
  val lookup_and_relocate_bound: tenv -> int -> T
  val lookup_and_relocate_binding: tenv -> int -> T
  val lookup_and_relocate: tenv -> int -> tenvelt
  val lookup: tenv -> int -> tenvelt
  val relocate: int -> T -> T

  (* Substitute the first arg for instances of var #0 in the second arg *)
  val tsubst_top: T -> T -> T

  exception UnknownId of string
  exception WrongKindOfId of tenv * int * string
  val debruijnify: tenv -> pretyp -> T

  val prt: Pp.Pp -> tenv -> T -> unit
  val prt_tenv: Pp.Pp -> tenv -> unit

  val NS: T

  end

  signature LEQ = sig

  structure Typ: TYPPVT
  structure Globals: GLOBALS
  sharing Globals = Typ.Globals

  val leq: Typ.tenv -> Typ.T -> Typ.T -> bool

  end
  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (* LR_TABLE: signature for an LR Table.

     The list of actions and gotos passed to mkLrTable must be ordered by state
     number. The values for state 0 are the first in the list, the values for
      state 1 are next, etc.
  *)

  signature LR_TABLE =
      sig
	  datatype state = STATE of int
	  datatype term = T of int
	  datatype nonterm = NT of int
	  datatype action = SHIFT of state
			  | REDUCE of int
			  | ACCEPT
			  | ERROR
	  type table

	  val numStates : table -> int
	  val describeActions : table -> state ->
				  ((term * action) list) * action
	  val describeGoto : table -> state -> (nonterm * state) list
	  val action : table -> state * term -> action
	  val goto : table -> state * nonterm -> state
	  val initialState : table -> state
	  exception Goto of state * nonterm

	  val mkLrTable : {actions : (((term * action) list) * action) list,
			   gotos : (nonterm * state) list list,
			   numStates : int,
			   initialState : state} -> table
      end

  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (* import "lr_table.sig"; *)

  (* TOKEN: signature revealing the internal structure of a token. This signature
     TOKEN distinct from the signature {parser name}_TOKENS produced by ML-Yacc.
     The {parser name}_TOKENS structures contain some types and functions to
      construct tokens from values and positions.

     The representation of token was very carefully chosen here to allow the
     polymorphic parser to work without knowing the types of semantic values
     or line numbers.

     This has had an impact on the TOKENS structure produced by SML-Yacc, which
     is a structure parameter to lexer functors.  We would like to have some
     type 'a token which functions to construct tokens would create.  A
     constructor function for a integer token might be

	    INT: int * 'a * 'a -> 'a token.

     This is not possible because we need to have tokens with the representation
     given below for the polymorphic parser.

     Thus our constructur functions for tokens have the form:

	    INT: int * 'a * 'a -> (svalue,'a) token

     This in turn has had an impact on the signature that lexers for SML-Yacc
     must match and the types that a user must declare in the user declarations
     section of lexers.
  *)

  signature TOKEN =
      sig
	  structure LrTable : LR_TABLE
	  datatype ('a,'b) token = TOKEN of LrTable.term * ('a * 'b * 'b)
	  val sameToken : ('a,'b) token * ('a,'b) token -> bool
      end

  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (*
  import "lr_table.sig";
  import "token.sig";
  *)

  (* PARSER_DATA: the signature of ParserData structures in {parser name}LrValsFun
     produced by  SML-Yacc.  All such structures match this signature.  

     The {parser name}LrValsFun produces a structure which contains all the values
     except for the lexer needed to call the polymorphic parser mentioned
     before.

  *)

  signature PARSER_DATA =
     sig
	  (* the type of line numbers *)

	  type pos

	  (* the type of semantic values *)

	  type svalue

	   (* the type of the user-supplied argument to the parser *)
	  type arg

	  (* the intended type of the result of the parser.  This value is
	     produced by applying extract from the structure Actions to the
	     final semantic value resultiing from a parse.
	   *)

	  type result

	  structure LrTable : LR_TABLE
	  structure Token : TOKEN
	  sharing Token.LrTable = LrTable

	  (* structure Actions contains the functions which mantain the
	     semantic values stack in the parser.  Void is used to provide
	     a default value for the semantic stack.
	   *)

	  structure Actions : 
	    sig
		val actions : int * pos *
		     (LrTable.state * (svalue * pos * pos)) list * arg->
			   LrTable.nonterm * (svalue * pos * pos) *
			   ((LrTable.state *(svalue * pos * pos)) list)
		val void : svalue
		val extract : svalue -> result
	    end

	  (* structure EC contains information used to improve error
	     recovery in an error-correcting parser *)

	  structure EC :
	     sig
       val is_keyword : LrTable.term -> bool
	       val noShift : LrTable.term -> bool
	       val preferred_subst : LrTable.term -> LrTable.term list
	       val preferred_insert : LrTable.term -> bool
	       val errtermvalue : LrTable.term -> svalue
	       val showTerminal : LrTable.term -> string
	       val terms: LrTable.term list
	     end

	  (* table is the LR table for the parser *)

	  val table : LrTable.table
      end

  signature FMEET_TOKENS =
  sig
  type ('a,'b) token
  type svalue
  val T_PACK: ('a * 'a) ->(svalue,'a) token
  val T_END: ('a * 'a) ->(svalue,'a) token
  val T_OPEN: ('a * 'a) ->(svalue,'a) token
  val T_SOME: ('a * 'a) ->(svalue,'a) token
  val T_INSTALL: ('a * 'a) ->(svalue,'a) token
  val T_OBSERVE: ('a * 'a) ->(svalue,'a) token
  val T_FOR: ('a * 'a) ->(svalue,'a) token
  val T_OF: ('a * 'a) ->(svalue,'a) token
  val T_CASE: ('a * 'a) ->(svalue,'a) token
  val T_NS: ('a * 'a) ->(svalue,'a) token
  val T_IN: ('a * 'a) ->(svalue,'a) token
  val T_ALL: ('a * 'a) ->(svalue,'a) token
  val T_WITH: ('a * 'a) ->(svalue,'a) token
  val T_CHECK: ('a * 'a) ->(svalue,'a) token
  val T_DEBUG: ('a * 'a) ->(svalue,'a) token
  val T_RESET: ('a * 'a) ->(svalue,'a) token
  val T_SET: ('a * 'a) ->(svalue,'a) token
  val T_TYPE: ('a * 'a) ->(svalue,'a) token
  val T_USE: ('a * 'a) ->(svalue,'a) token
  val T_STR_CONST: ((string) * 'a * 'a) ->(svalue,'a) token
  val T_INT_CONST: ((string) * 'a * 'a) ->(svalue,'a) token
  val T_ID: ((string) * 'a * 'a) ->(svalue,'a) token
  val T_BIGLAMBDA: ('a * 'a) ->(svalue,'a) token
  val T_LAMBDA: ('a * 'a) ->(svalue,'a) token
  val T_INTER: ('a * 'a) ->(svalue,'a) token
  val T_RCURLY: ('a * 'a) ->(svalue,'a) token
  val T_LCURLY: ('a * 'a) ->(svalue,'a) token
  val T_RANGLE: ('a * 'a) ->(svalue,'a) token
  val T_LANGLE: ('a * 'a) ->(svalue,'a) token
  val T_RBRACK: ('a * 'a) ->(svalue,'a) token
  val T_LBRACK: ('a * 'a) ->(svalue,'a) token
  val T_RPAREN: ('a * 'a) ->(svalue,'a) token
  val T_LPAREN: ('a * 'a) ->(svalue,'a) token
  val T_DARROW: ('a * 'a) ->(svalue,'a) token
  val T_ARROW: ('a * 'a) ->(svalue,'a) token
  val T_AT: ('a * 'a) ->(svalue,'a) token
  val T_DOLLAR: ('a * 'a) ->(svalue,'a) token
  val T_DOUBLEEQ: ('a * 'a) ->(svalue,'a) token
  val T_EQ: ('a * 'a) ->(svalue,'a) token
  val T_APOST: ('a * 'a) ->(svalue,'a) token
  val T_COMMA: ('a * 'a) ->(svalue,'a) token
  val T_LEQ: ('a * 'a) ->(svalue,'a) token
  val T_SEMICOLON: ('a * 'a) ->(svalue,'a) token
  val T_COLON: ('a * 'a) ->(svalue,'a) token
  val T_DOT: ('a * 'a) ->(svalue,'a) token
  val T_EOF: ('a * 'a) ->(svalue,'a) token
  end
  signature FMEET_LRVALS =
  sig
  structure Tokens : FMEET_TOKENS
  structure ParserData:PARSER_DATA
  sharing type ParserData.Token.token = Tokens.token
  sharing type ParserData.svalue = Tokens.svalue
  end
  (* Externally visible aspects of the lexer and parser *)

  signature INTERFACE =
  sig

  type pos
  val line : pos ref
  val init_line : unit -> unit
  val next_line : unit -> unit
  val error : string * pos * pos -> unit

  end  (* signature INTERFACE *)

  signature TYP = sig

  structure Globals: GLOBALS
  open Globals

  datatype pretyp = 
	      PRETVAR of Id.T
	    | PREARROW of pretyp * pretyp
	    | PREALL of Id.T * pretyp * pretyp
	    | PREMEET of pretyp list

  type T

  type tenv
  val empty_tenv: tenv
  val push_bound: tenv -> Id.T -> T -> tenv
  val push_abbrev: tenv -> Id.T -> T -> tenv
  val push_binding: tenv -> Id.T -> T -> tenv
  val pop: tenv -> tenv

  exception UnknownId of string
  exception WrongKindOfId of tenv * int * string
  val debruijnify: tenv -> pretyp -> T

  val prt: Pp.Pp -> tenv -> T -> unit
  val prt_tenv: Pp.Pp -> tenv -> unit

  val NS: T

  end

  signature TRM = sig

  structure Globals: GLOBALS
  structure Typ: TYP
  sharing Typ.Globals = Globals
  open Globals

  datatype pretrm = 
	      PREVAR of Id.T
	    | PREABS of Id.T * Typ.pretyp * pretrm
	    | PREAPP of pretrm * pretrm
	    | PRETABS of Id.T * Typ.pretyp * pretrm
	    | PRETAPP of pretrm * Typ.pretyp
	    | PREFOR of Id.T * (Typ.pretyp list) * pretrm

  type T

  exception UnknownId of string
  val debruijnify: Typ.tenv -> pretrm -> T

  val prt: Pp.Pp -> Typ.tenv -> T -> unit

  end

  signature PARSERES = sig

  structure Typ : TYP
  structure Trm : TRM
  structure Globals: GLOBALS
  sharing Typ.Globals = Globals
  sharing Trm.Typ = Typ

  datatype T =
      Leq of Typ.pretyp * Typ.pretyp
    | Type_Assumption of Globals.Id.T * Typ.pretyp
    | Type_Abbrev of Globals.Id.T * Typ.pretyp
    | Term_Def of Globals.Id.T * Trm.pretrm
    | Term_Assumption of Globals.Id.T * Typ.pretyp
    | Use of string
    | Set of string * string
    | Nothing

  end 
  signature PARSE =
  sig

  structure ParseRes : PARSERES

  val file_parse: string -> ParseRes.T;
  val stream_parse: instream -> ParseRes.T;
  val top_parse: unit -> ParseRes.T;

  end  (* signature PARSE *)

  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (* STREAM: signature for a lazy stream.*)

  signature STREAM =
   sig type 'xa stream
       val streamify : (unit -> '_a) -> '_a stream
       val cons : '_a * '_a stream -> '_a stream
       val get : '_a stream -> '_a * '_a stream
   end

  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (*
  import "token.sig";
  import "stream.sig";
  *)

  (* signature PARSER is the signature that most user parsers created by 
     SML-Yacc will match.
  *)

  signature PARSER =
      sig
	  structure Token : TOKEN
	  structure Stream : STREAM
	  exception ParseError

	  (* type pos is the type of line numbers *)

	  type pos

	  (* type result is the type of the result from the parser *)

	  type result

	   (* the type of the user-supplied argument to the parser *)
	  type arg

	  (* type svalue is the type of semantic values for the semantic value
	     stack
	   *)

	  type svalue

	  (* val makeLexer is used to create a stream of tokens for the parser *)

	  val makeLexer : (int -> string) ->
			   (svalue,pos) Token.token Stream.stream

	  (* val parse takes a stream of tokens and a function to prt
	     errors and returns a value of type result and a stream containing
	     the unused tokens
	   *)

	  val parse : int * ((svalue,pos) Token.token Stream.stream) *
		      (string * pos * pos -> unit) * arg ->
				  result * (svalue,pos) Token.token Stream.stream

	  val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token ->
				  bool
       end

  functor Parse (structure Globals : GLOBALS
		 structure ParseRes : PARSERES
		 structure Interface : INTERFACE
		 structure Parser : PARSER
		    sharing type Parser.pos = Interface.pos
		    sharing type Parser.result = ParseRes.T
		    sharing type Parser.arg = unit
		 structure Tokens : FMEET_TOKENS
		    sharing type Tokens.token = Parser.Token.token
		    sharing type Tokens.svalue = Parser.svalue
		 ) : PARSE =
  struct

  structure ParseRes = ParseRes
  open Globals

  val parse = fn (lookahead,reader : int -> string) =>
      let val _ = Interface.init_line()
	  val empty = !Interface.line
	  val dummyEOF = Tokens.T_EOF(empty,empty)
	  fun invoke lexer = 
	     Parser.parse(lookahead,lexer,Interface.error,())
	  fun loop lexer =
	    let val (result,lexer) = invoke lexer
		val (nextToken,lexer) = Parser.Stream.get lexer
	    in if Parser.sameToken(nextToken,dummyEOF) then result
	       else loop lexer
	    end
       in loop (Parser.makeLexer reader)
       end

  fun string_reader s =
   let val next = ref s
   in fn _ => !next before next := ""
   end

  val string_parse = fn s => parse (0, string_reader s)

  val file_parse = fn name =>
    let val dev = open_in name
     in (parse (15,(fn i => input(dev,i)))) before close_in dev
     end

  fun prefix line len = substring(line,0,min(len,size line))    

  fun echo_line line =
      if (line = "\n") orelse (line="")
	 then write line
      else if prefix line 3 = "%% "
	 then write (substring(line,3,size(line)-3))
      else if prefix line 2 = "%%"
	 then write (substring(line,2,size(line)-2))
      else write ("> " ^ line)

  fun convert_tabs s =
      implode (map (fn "\t" => "        " | s => s) (explode s));

  fun stream_parse dev =
     parse (15,(fn i => 
		   let val line = convert_tabs(input_line(dev))
		       val _ = echo_line line
		   in line
		   end))

  val top_parse = fn () => parse (0,
		  let val not_first_flag = ref(false)
		  in fn i => (( if (!not_first_flag)
			       then (write "> "; flush_out std_out)
			       else not_first_flag := true );
			      input_line std_in)
		  end)

  end  (* functor Parse *)

  signature SYNTH = sig

  structure Globals: GLOBALS
  structure Trm: TRM
  structure Typ: TYP
  structure Leq: LEQ
  sharing Trm.Typ = Typ
      and Leq.Typ = Typ
      and Typ.Globals = Globals
  open Globals

  val synth: Typ.tenv -> Trm.T -> Typ.T

  end
  (* Copyright 1989 by AT&T Bell Laboratories *)
  (* util/strghash.sml *)

  (* Functorized by BCP, 1991 *)

  functor StrgHash() =
  struct

    val prime = 8388593 (* largest prime less than 2^23 *)
    val base = 128

  (* the simple version --
      fun hashString(str: string) : int =
	  let fun loop (0,n) = n
		| loop (i,n) = 
		    let val i = i-1
			val n' = (base * n + ordof(str,i)) 
		     in loop (i, (n' - prime * (n' quot prime)))
		    end
	   in loop (size str,0)
	  end
  *)

    fun hashString(str: string) : int =
	let val l = size str
	 in case l
	      of 0 => 0
	       | 1 => ord str
	       | 2 => ordof(str,0) + base * ordof(str,1)
	       | 3 => ordof(str,0) + base * (ordof(str,1) + base * ordof(str,2))
	       | _ =>
		  let fun loop (0,n) = n
			| loop (i,n) = 
			    let val i = i-1
				val n' = (base * n + ordof(str,i)) 
			     in loop (i, (n' - prime * (n' quot prime)))
			    end
		   in loop (l,0)
		  end
	end

  end (* structure StrgHash *)
  functor StringUtils() : STRINGUTILS = struct

  end
  (* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (* LEXER: a signature that most lexers produced for use with SML-Yacc's
     outut will match.  The user is responsible for declaring type token,
     type pos, and type svalue in the UserDeclarations section of a lexer.

     Note that type token is abstract in the lexer.  This allows SML-Yacc to
     create a TOKENS signature for use with lexers produced by ML-Lex that
     treats the type token abstractly.  Lexers that are functors parametrized by
     a Tokens structure matching a TOKENS signature cannot examine the structure
     of tokens.
  *)

  signature LEXER =
     sig
	 structure UserDeclarations :
	     sig
		  type ('a,'b) token
		  type pos
		  type svalue
	     end
	  val makeLexer : (int -> string) -> unit -> 
	   (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token
     end

  functor FMEETLexFun(structure Tokens: FMEET_TOKENS structure Interface: INTERFACE) : LEXER=
     struct
      structure UserDeclarations =
	struct
  structure Tokens = Tokens
  structure Interface = Interface
  open Interface

  type pos = Interface.pos
  type svalue = Tokens.svalue
  type ('a,'b) token = ('a,'b) Tokens.token
  type lexresult= (svalue,pos) token

  val eof = fn () => Tokens.T_EOF(!line,!line)

  val str_begin = ref(!line);
  val str_const = ref([]:string list);

  end (* end of user routines *)
  exception LexError (* raised if illegal leaf action tried *)
  structure Internal =
	  struct

  datatype yyfinstate = N of int
  type statedata = {fin : yyfinstate list, trans: string}
  (* transition & final state table *)
  val tab = let
  val s0 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s1 =
  "\007\007\007\007\007\007\007\007\007\097\099\007\007\007\007\007\
  \\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\007\
  \\097\007\007\007\096\095\007\094\093\092\007\007\091\089\088\086\
  \\084\084\084\084\084\084\084\084\084\084\083\082\080\077\076\007\
  \\075\072\010\010\010\010\010\010\010\010\010\010\010\010\070\010\
  \\010\010\010\066\010\010\010\010\010\010\010\065\063\062\007\007\
  \\061\010\010\053\048\045\042\010\010\040\010\010\010\010\010\035\
  \\031\010\026\023\019\016\010\012\010\010\010\009\007\008\007\007\
  \\007"
  val s3 =
  "\100\100\100\100\100\100\100\100\100\100\101\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\100\
  \\100"
  val s5 =
  "\102\102\102\102\102\102\102\102\102\102\104\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\103\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\102\
  \\102"
  val s10 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s12 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\013\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s13 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\014\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s14 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\015\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s16 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\017\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s17 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\018\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s19 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\020\011\000\000\000\000\000\
  \\000"
  val s20 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\021\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s21 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\022\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s23 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\024\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s24 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\025\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s26 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\027\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s27 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\028\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s28 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\029\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s29 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\030\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s31 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\032\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s32 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\033\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s33 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\034\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s35 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\039\011\011\011\011\011\011\011\011\011\
  \\036\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s36 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\037\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s37 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\038\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s40 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\041\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s42 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\043\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s43 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\044\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s45 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\046\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s46 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\047\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s48 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\049\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s49 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\050\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s50 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\051\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s51 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\052\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s53 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\058\011\011\011\011\011\011\054\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s54 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\055\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s55 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\056\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s56 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\057\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s58 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\059\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s59 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\060\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s63 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\064\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s66 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\067\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s67 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\068\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s68 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\069\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s70 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\071\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s72 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\073\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s73 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\011\000\000\000\000\000\000\000\000\
  \\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\000\
  \\000\011\011\011\011\011\011\011\011\011\011\011\011\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\011\
  \\000\011\011\011\011\011\011\011\011\011\011\011\074\011\011\011\
  \\011\011\011\011\011\011\011\011\011\011\011\000\000\000\000\000\
  \\000"
  val s77 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\079\078\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s80 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\081\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s84 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\085\085\085\085\085\085\085\085\085\085\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s86 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\087\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s89 =
  "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\090\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  val s97 =
  "\000\000\000\000\000\000\000\000\000\098\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\098\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
  \\000"
  in arrayoflist
  [{fin = [], trans = s0},
  {fin = [(N 32)], trans = s1},
  {fin = [(N 32)], trans = s1},
  {fin = [], trans = s3},
  {fin = [], trans = s3},
  {fin = [], trans = s5},
  {fin = [], trans = s5},
  {fin = [(N 144)], trans = s0},
  {fin = [(N 80),(N 144)], trans = s0},
  {fin = [(N 78),(N 144)], trans = s0},
  {fin = [(N 137),(N 144)], trans = s10},
  {fin = [(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s12},
  {fin = [(N 137)], trans = s13},
  {fin = [(N 137)], trans = s14},
  {fin = [(N 91),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s16},
  {fin = [(N 137)], trans = s17},
  {fin = [(N 3),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s19},
  {fin = [(N 137)], trans = s20},
  {fin = [(N 137)], trans = s21},
  {fin = [(N 8),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s23},
  {fin = [(N 137)], trans = s24},
  {fin = [(N 12),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s26},
  {fin = [(N 137)], trans = s27},
  {fin = [(N 137)], trans = s28},
  {fin = [(N 137)], trans = s29},
  {fin = [(N 18),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s31},
  {fin = [(N 137)], trans = s32},
  {fin = [(N 137)], trans = s33},
  {fin = [(N 122),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s35},
  {fin = [(N 137)], trans = s36},
  {fin = [(N 137)], trans = s37},
  {fin = [(N 117),(N 137)], trans = s10},
  {fin = [(N 99),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s40},
  {fin = [(N 129),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s42},
  {fin = [(N 137)], trans = s43},
  {fin = [(N 103),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s45},
  {fin = [(N 137)], trans = s46},
  {fin = [(N 126),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s48},
  {fin = [(N 137)], trans = s49},
  {fin = [(N 137)], trans = s50},
  {fin = [(N 137)], trans = s51},
  {fin = [(N 24),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s53},
  {fin = [(N 137)], trans = s54},
  {fin = [(N 137)], trans = s55},
  {fin = [(N 137)], trans = s56},
  {fin = [(N 30),(N 137)], trans = s10},
  {fin = [(N 137)], trans = s58},
  {fin = [(N 137)], trans = s59},
  {fin = [(N 96),(N 137)], trans = s10},
  {fin = [(N 142),(N 144)], trans = s0},
  {fin = [(N 72),(N 144)], trans = s0},
  {fin = [(N 134),(N 144)], trans = s63},
  {fin = [(N 132)], trans = s0},
  {fin = [(N 70),(N 144)], trans = s0},
  {fin = [(N 137),(N 144)], trans = s66},
  {fin = [(N 137)], trans = s67},
  {fin = [(N 137)], trans = s68},
  {fin = [(N 112),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s70},
  {fin = [(N 86),(N 137)], trans = s10},
  {fin = [(N 137),(N 144)], trans = s72},
  {fin = [(N 137)], trans = s73},
  {fin = [(N 107),(N 137)], trans = s10},
  {fin = [(N 42),(N 144)], trans = s0},
  {fin = [(N 76),(N 144)], trans = s0},
  {fin = [(N 52),(N 144)], trans = s77},
  {fin = [(N 61)], trans = s0},
  {fin = [(N 55)], trans = s0},
  {fin = [(N 74),(N 144)], trans = s80},
  {fin = [(N 58)], trans = s0},
  {fin = [(N 44),(N 144)], trans = s0},
  {fin = [(N 38),(N 144)], trans = s0},
  {fin = [(N 140),(N 144)], trans = s84},
  {fin = [(N 140)], trans = s84},
  {fin = [(N 144)], trans = s86},
  {fin = [(N 64)], trans = s0},
  {fin = [(N 46),(N 144)], trans = s0},
  {fin = [(N 144)], trans = s89},
  {fin = [(N 83)], trans = s0},
  {fin = [(N 48),(N 144)], trans = s0},
  {fin = [(N 68),(N 144)], trans = s0},
  {fin = [(N 66),(N 144)], trans = s0},
  {fin = [(N 50),(N 144)], trans = s0},
  {fin = [(N 36),(N 144)], trans = s0},
  {fin = [(N 40),(N 144)], trans = s0},
  {fin = [(N 32),(N 144)], trans = s97},
  {fin = [(N 32)], trans = s97},
  {fin = [(N 34)], trans = s0},
  {fin = [(N 148)], trans = s0},
  {fin = [(N 146)], trans = s0},
  {fin = [(N 154)], trans = s0},
  {fin = [(N 152),(N 154)], trans = s0},
  {fin = [(N 150)], trans = s0}]
  end
  structure StartStates =
	  struct
	  datatype yystartstate = STARTSTATE of int

  (* start state definitions *)

  val COMMENT = STARTSTATE 3;
  val INITIAL = STARTSTATE 1;
  val STRING = STARTSTATE 5;

  end
  type result = UserDeclarations.lexresult
	  exception LexerError (* raised if illegal leaf action tried *)
  end

  fun makeLexer yyinput = 
  let 
	  val yyb = ref "\n" 		(* buffer *)
	  val yybl = ref 1		(*buffer length *)
	  val yybufpos = ref 1		(* location of next character to use *)
	  val yygone = ref 1		(* position in file of beginning of buffer *)
	  val yydone = ref false		(* eof found yet? *)
	  val yybegin = ref 1		(*Current 'start state' for lexer *)

	  val YYBEGIN = fn (Internal.StartStates.STARTSTATE x) =>
		   yybegin := x

  fun lex () : Internal.result =
  let fun continue() = lex() in
    let fun scan (s,AcceptingLeaves : Internal.yyfinstate list list,l,i0) =
	  let fun action (i,nil) = raise LexError
	  | action (i,nil::l) = action (i-1,l)
	  | action (i,(node::acts)::l) =
		  case node of
		      Internal.N yyk => 
			  (let val yytext = substring(!yyb,i0,i-i0)
			       val yypos = i0+ !yygone
			  open UserDeclarations Internal.StartStates
   in (yybufpos := i; case yyk of 

			  (* Application actions *)

    103 => (Tokens.T_FOR(!line,!line))
  | 107 => (Tokens.T_ALL(!line,!line))
  | 112 => (Tokens.T_SOME(!line,!line))
  | 117 => (Tokens.T_OPEN(!line,!line))
  | 12 => (Tokens.T_SET(!line,!line))
  | 122 => (Tokens.T_PACK(!line,!line))
  | 126 => (Tokens.T_END (!line,!line))
  | 129 => (Tokens.T_IN(!line,!line))
  | 132 => (Tokens.T_BIGLAMBDA(!line,!line))
  | 134 => (Tokens.T_LAMBDA(!line,!line))
  | 137 => (Tokens.T_ID (yytext,!line,!line))
  | 140 => (Tokens.T_INT_CONST (yytext,!line,!line))
  | 142 => (str_begin:=(!line); str_const:=[]; YYBEGIN STRING; lex())
  | 144 => (error ("ignoring illegal character" ^ yytext,
			     !line,!line); lex())
  | 146 => (next_line(); YYBEGIN INITIAL; lex())
  | 148 => (lex())
  | 150 => (next_line(); lex())
  | 152 => (YYBEGIN INITIAL;
		      Tokens.T_STR_CONST(implode(rev(!str_const)),
					 !str_begin,!line))
  | 154 => (str_const:=(yytext::(!str_const)); lex())
  | 18 => (Tokens.T_RESET(!line,!line))
  | 24 => (Tokens.T_DEBUG(!line,!line))
  | 3 => (Tokens.T_USE(!line,!line))
  | 30 => (Tokens.T_CHECK(!line,!line))
  | 32 => (lex())
  | 34 => (next_line(); lex())
  | 36 => (YYBEGIN COMMENT; lex())
  | 38 => (Tokens.T_COLON(!line,!line))
  | 40 => (Tokens.T_DOLLAR(!line,!line))
  | 42 => (Tokens.T_AT(!line,!line))
  | 44 => (Tokens.T_EOF(!line,!line))
  | 46 => (Tokens.T_DOT(!line,!line))
  | 48 => (Tokens.T_COMMA(!line,!line))
  | 50 => (Tokens.T_APOST(!line,!line))
  | 52 => (Tokens.T_EQ(!line,!line))
  | 55 => (Tokens.T_DOUBLEEQ(!line,!line))
  | 58 => (Tokens.T_LEQ(!line,!line))
  | 61 => (Tokens.T_DARROW(!line,!line))
  | 64 => (Tokens.T_INTER(!line,!line))
  | 66 => (Tokens.T_LPAREN(!line,!line))
  | 68 => (Tokens.T_RPAREN(!line,!line))
  | 70 => (Tokens.T_LBRACK(!line,!line))
  | 72 => (Tokens.T_RBRACK(!line,!line))
  | 74 => (Tokens.T_LANGLE(!line,!line))
  | 76 => (Tokens.T_RANGLE(!line,!line))
  | 78 => (Tokens.T_LCURLY(!line,!line))
  | 8 => (Tokens.T_TYPE(!line,!line))
  | 80 => (Tokens.T_RCURLY(!line,!line))
  | 83 => (Tokens.T_ARROW(!line,!line))
  | 86 => (Tokens.T_NS(!line,!line))
  | 91 => (Tokens.T_WITH(!line,!line))
  | 96 => (Tokens.T_CASE(!line,!line))
  | 99 => (Tokens.T_OF(!line,!line))
  | _ => raise Internal.LexerError

		  ) end )

	  val {fin,trans} = Internal.tab sub s
	  val NewAcceptingLeaves = fin::AcceptingLeaves
	  in if l = !yybl then
	       if trans = #trans(Internal.tab sub 0)
		 then action(l,NewAcceptingLeaves) else
	      let val newchars= if !yydone then "" else yyinput 1024
	      in if (size newchars)=0
		    then (yydone := true;
			  if (l=i0) then UserDeclarations.eof ()
				    else action(l,NewAcceptingLeaves))
		    else (if i0=l then yyb := newchars
		       else yyb := substring(!yyb,i0,l-i0)^newchars;
		       yygone := !yygone+i0;
		       yybl := size (!yyb);
		       scan (s,AcceptingLeaves,l-i0,0))
	      end
	    else let val NewChar = ordof(!yyb,l)
		  val NewState = if NewChar<128 then ordof(trans,NewChar) else ordof(trans,128)
		  in if NewState=0 then action(l,NewAcceptingLeaves)
		  else scan(NewState,NewAcceptingLeaves,l+1,i0)
	  end
	  end
  (*
	  val start= if substring(!yyb,!yybufpos-1,1)="\n"
  then !yybegin+1 else !yybegin
  *)
	  in scan(!yybegin (* start *),nil,!yybufpos,!yybufpos)
      end
  end
    in lex
    end
  end
  functor Registry(
	      type registeredtype
	      ): REGISTRY = struct

  type registeredtype = registeredtype

  val registry = ref(nil: (string * (registeredtype->unit)) list)

  fun register name callback = 
    registry := (name,callback)::(!registry)

  fun registerflag name flagref =
    registry := (name,(fn b => flagref := b))::(!registry)

  exception NotRegistered of string

  fun set_flag name v = 
    let fun f [] = raise NotRegistered(name)
	  | f ((n,callback)::tl) = if name=n 
				     then (callback v)
				     else f tl
    in f (!registry)
    end

  fun set_all v =
    let fun f [] = ()
	  | f ((n,callback)::tl) = (callback v; f tl)
    in f (!registry)
    end

  end
  functor Typ(
	      structure Globals: GLOBALS
	      ) : TYPPVT
	      = struct

  structure Globals = Globals
  open Globals
  open Pp

  datatype pretyp = 
	      PRETVAR of Id.T
	    | PREARROW of pretyp * pretyp
	    | PREALL of Id.T * pretyp * pretyp
	    | PREMEET of pretyp list

  datatype T = 
	      TVAR of unit * int
	    | ARROW of unit * T * T
	    | ALL of {name:Id.T} * T * T
	    | MEET of unit * (T list)

  type idindex = int

  val NS = MEET ((),[])

  exception UnknownId of string

  datatype tenvelt = BND of Id.T * T
		   | ABB of Id.T * T
		   | VBND of Id.T * T

  datatype tenv = TENV of tenvelt list

  fun push_bound (TENV(te)) i t = TENV(BND(i,t)::te)

  fun push_abbrev (TENV(te)) i t = TENV(ABB(i,t)::te)

  fun push_binding (TENV(te)) i t = TENV(VBND(i,t)::te)

  val empty_tenv = TENV(nil)

  fun index (TENV(bvs)) i =
    let fun ind [] n =
	      raise UnknownId(Id.tostr i)
	  | ind (BND(i',_)::rest) n =
	      if Id.== i i'
		 then n
		 else ind rest (n+1)
	  | ind (VBND(i',_)::rest) n =
	      if Id.== i i'
		 then n
		 else ind rest (n+1)
	  | ind (ABB(i',_)::rest) n =
	      if Id.== i i'
		 then n
		 else ind rest (n+1)
    in ind bvs 0
    end

  exception TypeVariableOutOfRange of int

  fun old_lookup_name (TENV(te)) i = 
    (case (nth (te,i)) of
      BND(name,_) => name
    | VBND(name,_) => name
    | ABB(name,_) => name)
    handle Nth => Id.intern(("<BAD INDEX: " ^ (makestring i) ^ ">"))

  fun lookup_name (TENV(te)) i = 
    let fun l [] _ _ = Id.intern(("<BAD INDEX: " ^ (makestring i) ^ ">"))
	  | l (hd::tl) rest 0 = 
	      let val name = case hd of BND(n,_) => n | VBND(n,_) => n | ABB(n,_) => n
	      in if memq Id.== rest name 
		   then Id.intern ((Id.tostr name) ^ "^" ^ (makestring i))
		   else name
	      end
	  | l (hd::tl) rest j = 
	      let val name = case hd of BND(n,_) => n | VBND(n,_) => n | ABB(n,_) => n
	      in l tl (name::rest) (j-1)
	      end
    in l te [] i
    end

  exception WrongKindOfId of tenv * int * string

  fun lookup (TENV(te)) i =
    nth (te,i)
    handle Nth => raise TypeVariableOutOfRange(i)

  exception TriedToPopEmptyTEnv
  fun pop (TENV(hd::tl)) = TENV(tl)
    | pop _ = raise TriedToPopEmptyTEnv

  fun inner_relocate offset cutoff t =
    let fun r c (TVAR((),i)) = if i>=c 
				  then TVAR((),i + offset)
				  else TVAR((),i)
	  | r c (ARROW((),t1,t2)) = ARROW((), r c t1, r c t2)
	  | r c (ALL({name=i},t1,t2)) = ALL({name=i}, r c t1, r (c+1) t2)
	  | r c (MEET((),ts)) = MEET((), map (fn t => r c t) ts)
    in r cutoff t
    end

  fun relocate offset t = inner_relocate offset 0 t

  fun lookup_and_relocate (te) i =
    case lookup te i of
      BND(n,b) => BND(n, relocate (i+1) b)
    | VBND(n,b) => VBND(n, relocate (i+1) b)
    | ABB(n,b) => ABB(n, relocate (i+1) b)

  fun lookup_and_relocate_bound te i = 
    case lookup_and_relocate te i of
      BND(_,b) => b
    | VBND(n,_) => raise WrongKindOfId(te,i,"tvar")
    | ABB(n,_) => raise WrongKindOfId(te,i,"tvar")

  fun lookup_and_relocate_binding te i = 
    case lookup_and_relocate te i of
      BND(n,b) => raise WrongKindOfId(te,i,"var")
    | VBND(n,b) => b
    | ABB(n,b) => raise WrongKindOfId(te,i,"var")

  fun lookup_abbrev te i = 
    case lookup_and_relocate te i of
      BND(n,_) => raise WrongKindOfId(te,i,"tabbrev")
    | VBND(n,b) => raise WrongKindOfId(te,i,"tabbrev")
    | ABB(n,b) => b

  fun debruijnify te (PRETVAR i) =
	TVAR((), index te i)
    | debruijnify te (PREARROW (pt1,pt2)) =
	ARROW((), debruijnify te pt1, debruijnify te pt2)
    | debruijnify te (PREALL (i,pt1,pt2)) =
	ALL({name=i}, debruijnify te pt1, debruijnify (push_bound te i NS) pt2)
    | debruijnify te (PREMEET pts) =
	MEET((), map (fn pt => debruijnify te pt) pts)

  fun tsubst_top targ tbody =
    let fun s i (t as TVAR(x,i')) = if i = i' 
				      then relocate i targ
				    else if i < i'
				      then TVAR(x,i'-1)
				    else t
	  | s i (ARROW(x,t1,t2)) = ARROW(x, s i t1, s i t2)
	  | s i (ALL(x,t1,t2)) = ALL(x, s i t1, s (i+1) t2)
	  | s i (MEET(x,ts)) = MEET(x, map (fn t => s i t) ts)
    in s 0 tbody 
    end

  fun prt pp te t =
    let fun p te (TVAR(_,i)) =
		Pp.pwrite pp (Id.tostr (lookup_name te i))
	  | p te (ARROW(_,t1,t2)) =
		(Pp.pwrite pp "(";
		 p te t1;
		 Pp.pwrite pp "->";
		 p te t2;
		 Pp.pwrite pp ")")
	  | p te (ALL({name=i},t1,t2)) =
		(Pp.pwrite pp "(All ";
		 Pp.pwrite pp (Id.tostr i);
		 Pp.pwrite pp "<=";
		 p te t1;
		 Pp.pwrite pp ". ";
		 p (push_bound te i t1) t2;
		 Pp.pwrite pp ")")
	  | p te (MEET(_,[])) =
		 Pp.pwrite pp "NS"
	  | p te (MEET(_,ts)) =
		(Pp.pwrite pp "/\\[";
		 plist te ts;
		 Pp.pwrite pp "]")
	and plist te [] = 
	      ()
	  | plist te [t] = 
	      p te t
	  | plist te (hd::tl) = 
	      (p te hd; pwrite pp ","; plist te tl)
    in p te t
    end

  val short_tenvs = ref(true);
  val _ = registerflag "shorttenvs" short_tenvs;

  fun prt_tenv pp (TENV(te')) =
    let fun p [] = ()
	  | p [(BND(i,t))] = 
	      (Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp "<=";
	       prt pp (TENV([])) t)
	  | p ((BND(i,t))::tl) = 
	      (if (!short_tenvs)
		 then pwrite pp "... "
		 else p tl; 
	       Pp.pwrite pp ", ";
	       Pp.break pp false 0;
	       Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp "<=";
	       prt pp (TENV(tl)) t)
	  | p [(VBND(i,t))] = 
	      (Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp ":";
	       prt pp (TENV([])) t)
	  | p ((VBND(i,t))::tl) = 
	      (if (!short_tenvs)
		 then pwrite pp "... "
		 else p tl; 
	       Pp.pwrite pp ", ";
	       Pp.break pp false 0;
	       Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp ":";
	       prt pp (TENV(tl)) t)
	  | p [(ABB(i,t))] = 
	      (Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp "=";
	       prt pp (TENV([])) t)
	  | p ((ABB(i,t))::tl) = 
	      (if (!short_tenvs)
		 then pwrite pp "... "
		 else p tl; 
	       Pp.pwrite pp ", ";
	       Pp.break pp false 0;
	       Pp.pwrite pp (Id.tostr i);
	       Pp.pwrite pp "=";
	       prt pp (TENV(tl)) t)
    in Pp.pwrite pp "{";
       Pp.setb pp;
       p te';
       Pp.endb pp;
       Pp.pwrite pp "}"
    end

  end
  functor Leq(
	    structure Typ: TYPPVT
	    structure Globals: GLOBALS
	    sharing Typ.Globals = Globals
	    ) : LEQ = struct

  structure Typ = Typ
  structure Globals = Globals
  open Globals
  open Typ

  datatype lhsqueue = 
	      ARROW_LHS of Typ.T
	    | ALL_LHS   of Id.T * Typ.T

  datatype rhs_flag = EXPAND | FIX

  val DEBUG = ref(false)
  val _ = (registerflag "leq" DEBUG;
	   registerflag "Leq" DEBUG)

  fun describe_rest pp te [] t flag = 
	(Pp.pwrite pp "] -> ";
	 Typ.prt pp te t;
	 case flag of
	   EXPAND => Pp.pwrite pp " (EXPAND)?  "
	 | FIX    => Pp.pwrite pp " (FIX)?  ")
    | describe_rest pp te [ARROW_LHS(t1)] t2 flag = 
	(Typ.prt pp te t1;
	 describe_rest pp te [] t2 flag)
    | describe_rest pp te ((ARROW_LHS(t1))::X2) t2 flag = 
	(Typ.prt pp te t1;
	 Pp.pwrite pp ",";
	 describe_rest pp te X2 t2 flag)
    | describe_rest pp te [ALL_LHS(v,t1)] t2 flag = 
	(Pp.pwrite pp (Id.tostr v);
	 Pp.pwrite pp "<=";
	 Typ.prt pp te t1;
	 describe_rest pp (push_bound te v t1) [] t2 flag)
    | describe_rest pp te ((ALL_LHS(v,t1))::X2) t2 flag = 
	(Pp.pwrite pp (Id.tostr v);
	 Pp.pwrite pp "<=";
	 Typ.prt pp te t1;
	 Pp.pwrite pp ",";
	 describe_rest pp (push_bound te v t1) X2 t2 flag)

  fun describe_problem pp te s X t flag =
    (Pp.setb pp;
     Typ.prt pp te s;
     Pp.break pp true ~3;
     Pp.pwrite pp " <= ";
     Pp.pwrite pp "[";
     describe_rest pp te X t flag;
     Pp.endb pp)

  fun bindings_in [] = 0
    | bindings_in (ARROW_LHS(_)::tl) = bindings_in tl
    | bindings_in (ALL_LHS(_)::tl) = 1 + (bindings_in tl)

  fun leqq' te s X (MEET(_,ts)) EXPAND =
	forall (fn t => leqq te s X t EXPAND) ts
    | leqq' te s X (ARROW(_,t1,t2)) EXPAND =
	leqq te s (X@[ARROW_LHS(t1)]) t2 EXPAND
    | leqq' te s X (ALL({name=i},t1,t2)) EXPAND =
	leqq te s (X@[ALL_LHS(i,t1)]) t2 EXPAND
    | leqq' te s X (t as TVAR(_,vt)) EXPAND =
	let val bx = bindings_in X
	in if vt < bx
	   then leqq te s X t FIX
	   else case Typ.lookup te (vt - bx) of 
		 BND(_,_)  => leqq te s X t FIX
	       | VBND(n,_)  => raise Typ.WrongKindOfId(te, vt - bx,"tvar or tabbrev")
	       | ABB(_,ab) => leqq te s X (Typ.relocate (vt + bx) ab) EXPAND
	end
    | leqq' te (MEET(_,ss)) X (t as (TVAR(_,vt))) FIX =
	forsome (fn s => leqq te s X t FIX) ss
    | leqq' te (ARROW(_,s1,s2)) (ARROW_LHS(t1)::X) (t as (TVAR(_,vt))) FIX =
	(leqq te t1 [] s1 EXPAND)
	andalso
	(leqq te s2 X t FIX)
    | leqq' te (ALL(_,s1,s2)) (ALL_LHS(i,t1)::X) (t as (TVAR(_,vt))) FIX =
	(leqq (push_bound te i t1) s2 X t FIX)
	andalso
	(leqq te t1 [] s1 EXPAND)
    | leqq' te (TVAR(_,vs)) X (t as (TVAR(_,vt))) FIX =
	(vs = vt andalso (null X))
	orelse
	(case lookup_and_relocate te vs of
	   BND(_,bnd) => (leqq te bnd X t FIX)
	 | VBND(n,ab)  => raise Typ.WrongKindOfId(te,vs,"tvar or tabbrev")
	 | ABB(_,ab)  => (leqq te ab X t FIX))
    | leqq' te s X t flag =
	false

  and leqq te s X t flag =
    wrap DEBUG "leqq"
      (fn () => 
	leqq' te s X t flag)
      (fn () => describe_problem (stdpp()) te s X t flag)
      (fn b => write (if b then "Yes" else "No"))

  (* and leqq te s X t = leqq' te s X t *)

  fun leq te s t = leqq te s [] t EXPAND

  end
  (* Gene Rollins
     School of Computer Science
     Carnegie-Mellon University
     Pittsburgh, PA 15213
     rollins@cs.cmu.edu *)

  functor HashFun () = struct

  val version = 1.0

  type ('a,'b) table = ('a*'a->bool) * (('a*int*'b) list array) * int

  fun create (sample'key :'1a) (equality :'1a * '1a -> bool)
	     table'size (sample'value :'1b) :('1a,'1b) table =
    let val mt = tl [(sample'key, 0, sample'value)]
    in (equality, array (table'size, mt), table'size)
    end

  val defaultSize = 97 (* a prime; or try primes 37, 997 *)

  fun defaultEqual ((x :string), (y :string)) :bool = (x = y)

  fun createDefault (sample'value :'1b) :(string,'1b) table =
    let val mt = tl [("", 0, sample'value)]
    in (defaultEqual, array (defaultSize, mt), defaultSize)
    end

  fun enter ((equal, table, table'size) :('a,'b) table) key hash value = 
    let val place = hash mod table'size
	val bucket = table sub place
	fun put'in [] = [(key,hash,value)]
	  | put'in ((k,h,v)::tail) =
	      if (h = hash) andalso equal (k, key)
		then (key,hash,value)::tail
		else (k,h,v)::(put'in tail)
    in
      update (table, place, put'in bucket)
    end

  fun remove ((equal, table, table'size) :('a,'b) table) key hash =
    let val place = hash mod table'size
	val bucket = table sub place
	fun take'out [] = []
	  | take'out ((k,h,v)::tail) =
	      if (h = hash) andalso equal (k, key)
		then tail
		else (k,h,v)::(take'out tail)
    in
      update (table, place, take'out bucket)
    end

  fun lookup ((equal, table, table'size) :('a,'b) table) key hash =
    let val place = hash mod table'size
	val bucket = table sub place
	fun get'out [] = NONE
	  | get'out ((k,h,v)::tail) =
	      if (h = hash) andalso equal (k, key)
		then SOME v
		else get'out tail
    in
      get'out bucket
    end

  fun print ((_, table, table'size) :('a,'b) table)
	    (print'key :'a -> unit) (print'value :'b -> unit) =
    let fun pr'bucket [] = ()
	  | pr'bucket ((key,hash,value)::rest) =
	      (print'key key; String.print ": ";
	       Integer.print hash; String.print ": ";
	       print'value value; String.print "\n"; pr'bucket rest)
	fun pr i =
	  if i >= table'size then ()
	    else
	      case (table sub i) of
		 [] => (pr (i+1))
	       | (b as (h::t)) =>
		   (String.print "["; Integer.print i; String.print "]\n";
		    pr'bucket b; pr (i+1))
    in pr 0 end

  fun scan ((_, table, table'size) :('a,'b) table) operation =
    let fun map'bucket [] = ()
	  | map'bucket ((key,hash,value)::rest) =
	      (operation key hash value; map'bucket rest)
	fun iter i =
	  if i >= table'size then ()
	    else (map'bucket (table sub i); iter (i+1))
    in iter 0 end

  fun fold ((_, table, table'size) :('a, 'b) table)
	   (operation :'a -> int -> 'b -> 'g -> 'g) (init :'g) :'g =
    let fun fold'bucket [] acc = acc
	  | fold'bucket ((key,hash,value)::rest) acc =
	       fold'bucket rest (operation key hash value acc)
	fun iter i acc =
	  if i >= table'size then acc
	    else iter (i+1) (fold'bucket (table sub i) acc)
    in iter 0 init end

  fun scanUpdate ((_, table, table'size) :('a,'b) table) operation =
    let fun map'bucket [] = []
	  | map'bucket ((key,hash,value)::rest) =
	      ((key,hash,operation key hash value)::(map'bucket rest))
	fun iter i =
	  if i >= table'size then ()
	    else (update (table, i, map'bucket (table sub i)); iter (i+1))
    in iter 0 end

  fun eliminate ((_, table, table'size) :('a,'b) table) predicate =
    let fun map'bucket [] = []
	  | map'bucket ((key,hash,value)::rest) =
	      if predicate key hash value then map'bucket rest
		else (key,hash,value)::(map'bucket rest)
	fun iter i =
	  if i >= table'size then ()
	    else (update (table, i, map'bucket (table sub i)); iter (i+1))
    in iter 0 end

  fun bucketLengths ((_, table, table'size) :('a,'b) table) (maxlen :int)
      :int array =
    let val count :int array = array (maxlen+1, 0)
	fun inc'sub x = 
	  let val y = min (x, maxlen) in
	    update (count, y, (count sub y) + 1)
	  end
	fun iter i =
	  if i >= table'size then ()
	    else (inc'sub (length (table sub i)); iter (i+1))
    in
      iter 0;
      count
    end

  end
  (* Cribbed from...
     ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  signature ORDSET =
     sig
	type set
	type elem
	exception Select_arb
	val app : (elem -> 'b) -> set -> unit
	    and card: set -> int
	    and closure: set * (elem -> set) -> set
	    and difference: set * set -> set
	    and elem_eq: (elem * elem -> bool)
	    and elem_gt : (elem * elem -> bool)
	    and empty: set
	    and exists: (elem * set) -> bool
	    and find : (elem * set)  ->  elem option
	    and fold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b
	    and insert: (elem * set) -> set
	    and is_empty: set -> bool
	    and make_list: set -> elem list
	    and make_set: (elem list -> set)
	    and partition: (elem -> bool) -> (set -> set * set)
	    and remove: (elem * set) -> set
	    and revfold: ((elem * 'b) -> 'b) -> set -> 'b -> 'b
	    and select_arb: set -> elem
	    and set_eq: (set * set) -> bool
	    and set_gt: (set * set) -> bool
	    and singleton: (elem -> set)
	    and union: set * set -> set
     end

  signature TABLE =
     sig
	  type 'a table
	  type key
	  val size : 'a table -> int
	  val empty: 'a table
	  val exists: (key * 'a table) -> bool
	  val find : (key * 'a table)  ->  'a option
	  val insert: ((key * 'a) * 'a table) -> 'a table
	  val make_table : (key * 'a ) list -> 'a table
	  val make_list : 'a table -> (key * 'a) list
	  val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b
     end

  signature HASH =
    sig
      type table
      type elem

      val size : table -> int
      val add : elem * table -> table
      val find : elem * table -> int option
      val exists : elem * table -> bool
      val empty : table
    end;

  (* Cribbed from...
     ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)

  (*III
  import "tarditi.sig";
  III*)

  (* Implementation of ordered sets using ordered lists and red-black trees.  The
     code for red-black trees was originally written by Norris Boyd, which was
     modified for use here.
  *)   

  (* ordered sets implemented using ordered lists.

     Upper bound running times for functions implemented here:

     app  = O(n)
     card = O(n)
     closure = O(n^2)
     difference = O(n+m), where n,m = the size of the two sets used here.
     empty = O(1)
     exists = O(n)
     find = O(n)
     fold = O(n)
     insert = O(n)
     is_empty = O(1)
     make_list = O(1)
     make_set = O(n^2)
     partition = O(n)
     remove = O(n)
     revfold = O(n)
     select_arb = O(1)
     set_eq = O(n), where n = the cardinality of the smaller set
     set_gt = O(n), ditto
     singleton = O(1)
     union = O(n+m)
  *)

  functor ListOrdSet(B : sig type elem
			  val gt : elem * elem -> bool
			  val eq : elem * elem -> bool
		      end ) : ORDSET =

  struct
   type elem = B.elem
   val elem_gt = B.gt
   val elem_eq = B.eq 

   type set = elem list
   exception Select_arb
   val empty = nil

   val insert = fn (key,s) =>
	  let fun f (l as (h::t)) =
		   if elem_gt(key,h) then h::(f t)
		   else if elem_eq(key,h) then key::t
		   else key::l
		| f nil = [key]
	  in f s
	  end

   val select_arb = fn nil => raise Select_arb
		     | a::b => a

   val exists = fn (key,s) =>
	  let fun f (h::t) = if elem_gt(key,h) then f t
			     else elem_eq(h,key) 
		| f nil = false
	  in f s
	  end

   val find = fn (key,s) =>
	  let fun f (h::t) = if elem_gt(key,h) then f t
			     else if elem_eq(h,key) then SOME h
			     else NONE
		| f nil = NONE
	  in f s
	  end

   val revfold = List.revfold
   val fold = List.fold
   val app = List.app

  fun set_eq(h::t,h'::t') = 
	  (case elem_eq(h,h')
	    of true => set_eq(t,t')
	     | a => a)
    | set_eq(nil,nil) = true
    | set_eq _ = false

  fun set_gt(h::t,h'::t') =
	  (case elem_gt(h,h')
	    of false => (case (elem_eq(h,h'))
			  of true => set_gt(t,t')
			   | a => a)
	     |  a => a)
    | set_gt(_::_,nil) = true
    | set_gt _ = false

  fun union(a as (h::t),b as (h'::t')) =
	    if elem_gt(h',h) then h::union(t,b)
	    else if elem_eq(h,h') then h::union(t,t')
	    else h'::union(a,t')
    | union(nil,s) = s
    | union(s,nil) = s

  val make_list = fn s => s

  val is_empty = fn nil => true | _ => false

  val make_set = fn l => List.fold insert l nil

  val partition = fn f => fn s =>
      fold (fn (e,(yes,no)) =>
	      if (f e) then (e::yes,no) else (e::no,yes)) s (nil,nil)

  val remove = fn (e,s) =>
      let fun f (l as (h::t)) = if elem_gt(h,e) then l
				else if elem_eq(h,e) then t
				else h::(f t)
	    | f nil = nil
      in f s
      end

   (* difference: X-Y *)

   fun difference (nil,_) = nil
     | difference (r,nil) = r
     | difference (a as (h::t),b as (h'::t')) =
	    if elem_gt (h',h) then h::difference(t,b)
	    else if elem_eq(h',h) then difference(t,t')
	    else difference(a,t')

   fun singleton X = [X]

   fun card(S) = fold (fn (a,count) => count+1) S 0

	local
	      fun closure'(from, f, result) =
		if is_empty from then result
		else
		  let val (more,result) =
			  fold (fn (a,(more',result')) =>
				  let val more = f a
				      val new = difference(more,result)
				  in (union(more',new),union(result',new))
				  end) from
				   (empty,result)
		  in closure'(more,f,result)
		  end
	in
	   fun closure(start, f) = closure'(start, f, start)
	end
  end

  (* ordered set implemented using red-black trees:

     Upper bound running time of the functions below:

     app: O(n)
     card: O(n)
     closure: O(n^2 ln n)
     difference: O(n ln n)
     empty: O(1)
     exists: O(ln n)
     find: O(ln n)
     fold: O(n)
     insert: O(ln n)
     is_empty: O(1)
     make_list: O(n)
     make_set: O(n ln n)
     partition: O(n ln n)
     remove: O(n ln n)
     revfold: O(n)
     select_arb: O(1)
     set_eq: O(n)
     set_gt: O(n)
     singleton: O(1)
     union: O(n ln n)
  *)

  functor RbOrdSet (B : sig type elem
			   val eq : (elem*elem) -> bool
			   val gt : (elem*elem) -> bool
		       end
		  ) : ORDSET =
  struct

   type elem = B.elem
   val elem_gt = B.gt
   val elem_eq = B.eq 

   datatype Color = RED | BLACK

   abstype set = EMPTY | TREE of (B.elem * Color * set * set)
   with exception Select_arb
	val empty = EMPTY

   fun insert(key,t) =
    let fun f EMPTY = TREE(key,RED,EMPTY,EMPTY)
	  | f (TREE(k,BLACK,l,r)) =
	      if elem_gt (key,k)
	      then case f r
		   of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) =>
			  (case l
			   of TREE(lk,RED,ll,lr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll),
						  TREE(rk,RED,rlr,rr)))
		    | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) =>
			  (case l
			   of TREE(lk,RED,ll,lr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr))
		    | r => TREE(k,BLACK,l,r)
	      else if elem_gt(k,key)
	      then case f l
		   of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) =>
			  (case r
			   of TREE(rk,RED,rl,rr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl),
						  TREE(k,RED,lrr,r)))
		    | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) =>
			  (case r
			   of TREE(rk,RED,rl,rr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r)))
		    | l => TREE(k,BLACK,l,r)
	      else TREE(key,BLACK,l,r)
	  | f (TREE(k,RED,l,r)) =
	      if elem_gt(key,k) then TREE(k,RED,l, f r)
	      else if elem_gt(k,key) then TREE(k,RED, f l, r)
	      else TREE(key,RED,l,r)
     in case f t
	of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r)
	 | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r)
	 | t => t
    end

   fun select_arb (TREE(k,_,l,r)) = k
     | select_arb EMPTY = raise Select_arb

   fun exists(key,t) =
    let fun look EMPTY = false
	  | look (TREE(k,_,l,r)) =
		  if elem_gt(k,key) then look l
		  else if elem_gt(key,k) then look r
		  else true
     in look t
     end

   fun find(key,t) =
    let fun look EMPTY = NONE
	  | look (TREE(k,_,l,r)) =
		  if elem_gt(k,key) then look l
		  else if elem_gt(key,k) then look r
		  else SOME k
     in look t
    end

    fun revfold f t start =
       let fun scan (EMPTY,value) = value
	     | scan (TREE(k,_,l,r),value) = scan(r,f(k,scan(l,value)))
       in scan(t,start)
       end

     fun fold f t start =
	  let fun scan(EMPTY,value) = value
		| scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value)))
	  in scan(t,start)
	  end

     fun app f t =
	let fun scan EMPTY = ()
	      | scan(TREE(k,_,l,r)) = (scan l; f k; scan r)
	in scan t
	end

  (* equal_tree : test if two trees are equal.  Two trees are equal if
     the set of leaves are equal *)

     fun set_eq (tree1 as (TREE _),tree2 as (TREE _)) =
       let datatype pos = L | R | M
	   exception Done
	   fun getvalue(stack as ((a,position)::b)) =
	      (case a
	       of (TREE(k,_,l,r)) =>
		  (case position
		   of L => getvalue ((l,L)::(a,M)::b)
		    | M => (k,case r of  EMPTY => b | _ => (a,R)::b)
		    | R => getvalue ((r,L)::b)
		   )
		| EMPTY => getvalue b
	       )
	      | getvalue(nil) = raise Done
	    fun f (nil,nil) = true
	      | f (s1 as (_ :: _),s2 as (_ :: _ )) =
			    let val (v1,news1) = getvalue s1
				and (v2,news2) = getvalue s2
			    in (elem_eq(v1,v2)) andalso f(news1,news2)
			    end
	      | f _ = false
	in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
	end
      | set_eq (EMPTY,EMPTY) = true
      | set_eq _ = false

     (* gt_tree : Test if tree1 is greater than tree 2 *)

     fun set_gt (tree1,tree2) =
       let datatype pos = L | R | M
	   exception Done
	   fun getvalue(stack as ((a,position)::b)) =
	      (case a
	       of (TREE(k,_,l,r)) =>
		  (case position
		   of L => getvalue ((l,L)::(a,M)::b)
		    | M => (k,case r of EMPTY => b | _ => (a,R)::b)
		    | R => getvalue ((r,L)::b)
		   )
		| EMPTY => getvalue b
	       )
	      | getvalue(nil) = raise Done
	    fun f (nil,nil) = false
	      | f (s1 as (_ :: _),s2 as (_ :: _ )) =
			    let val (v1,news1) = getvalue s1
				and (v2,news2) = getvalue s2
			    in (elem_gt(v1,v2)) orelse (elem_eq(v1,v2) andalso f(news1,news2))
			    end
	      | f (_,nil) = true
	      | f (nil,_) = false
	in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
	end

	fun is_empty S = (let val _ = select_arb S in false end
			   handle Select_arb => true)

	fun make_list S = fold (op ::) S nil

	fun make_set l = List.fold insert l empty

	fun partition F S = fold (fn (a,(Yes,No)) =>
				  if F(a) then (insert(a,Yes),No)
				  else (Yes,insert(a,No)))
			       S (empty,empty)

	fun remove(X, XSet) =
	       let val (YSet, _) =
			  partition (fn a => not (elem_eq (X, a))) XSet
	       in  YSet
	       end

	fun difference(Xs, Ys) =
	     fold (fn (p as (a,Xs')) =>
			if exists(a,Ys) then Xs' else insert p)
	     Xs empty

	fun singleton X = insert(X,empty)

	fun card(S) = fold (fn (_,count) => count+1) S 0

	fun union(Xs,Ys)= fold insert Ys Xs

	local
	      fun closure'(from, f, result) =
		if is_empty from then result
		else
		  let val (more,result) =
			  fold (fn (a,(more',result')) =>
				  let val more = f a
				      val new = difference(more,result)
				  in (union(more',new),union(result',new))
				  end) from
				   (empty,result)
		  in closure'(more,f,result)
		  end
	in
	   fun closure(start, f) = closure'(start, f, start)
	end
     end
  end

  (*
  signature TABLE =
     sig
	  type 'a table
	  type key
	  val size : 'a table -> int
	  val empty: 'a table
	  val exists: (key * 'a table) -> bool
	  val find : (key * 'a table)  ->  'a option
	  val insert: ((key * 'a) * 'a table) -> 'a table
	  val make_table : (key * 'a ) list -> 'a table
	  val make_list : 'a table -> (key * 'a) list
	  val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b
     end
  *)

  functor Table (B : sig type key
			val gt : (key * key) -> bool
		       end
		  ) : TABLE =
  struct

   datatype Color = RED | BLACK
   type key = B.key

   abstype 'a table = EMPTY
		    | TREE of ((B.key * 'a ) * Color * 'a table * 'a table)
   with

   val empty = EMPTY

   fun insert(elem as (key,data),t) =
    let val key_gt = fn (a,_) => B.gt(key,a)
	val key_lt = fn (a,_) => B.gt(a,key)
	  fun f EMPTY = TREE(elem,RED,EMPTY,EMPTY)
	  | f (TREE(k,BLACK,l,r)) =
	      if key_gt k
	      then case f r
		   of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) =>
			  (case l
			   of TREE(lk,RED,ll,lr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll),
						  TREE(rk,RED,rlr,rr)))
		    | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) =>
			  (case l
			   of TREE(lk,RED,ll,lr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr))
		    | r => TREE(k,BLACK,l,r)
	      else if key_lt k
	      then case f l
		   of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) =>
			  (case r
			   of TREE(rk,RED,rl,rr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl),
						  TREE(k,RED,lrr,r)))
		    | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) =>
			  (case r
			   of TREE(rk,RED,rl,rr) =>
				  TREE(k,RED,TREE(lk,BLACK,ll,lr),
					     TREE(rk,BLACK,rl,rr))
			    | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r)))
		    | l => TREE(k,BLACK,l,r)
	      else TREE(elem,BLACK,l,r)
	  | f (TREE(k,RED,l,r)) =
	      if key_gt k then TREE(k,RED,l, f r)
	      else if key_lt k then TREE(k,RED, f l, r)
	      else TREE(elem,RED,l,r)
     in case f t
	of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r)
	 | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r)
	 | t => t
    end

   fun exists(key,t) =
    let fun look EMPTY = false
	  | look (TREE((k,_),_,l,r)) =
		  if B.gt(k,key) then look l
		  else if B.gt(key,k) then look r
		  else true
     in look t
     end

   fun find(key,t) =
    let fun look EMPTY = NONE
	  | look (TREE((k,data),_,l,r)) =
		  if B.gt(k,key) then look l
		  else if B.gt(key,k) then look r
		  else SOME data
     in look t
    end

    fun fold f t start =
	  let fun scan(EMPTY,value) = value
		| scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value)))
	  in scan(t,start)
	  end

    fun make_table l = List.fold insert l empty

    fun size S = fold (fn (_,count) => count+1) S 0

    fun make_list table = fold (op ::) table nil

    end
  end;

  (* assumes that a functor Table with signature TABLE from table.sml is
     in the environment *)

  (*
  signature HASH =
    sig
      type table
      type elem

      val size : table -> int
      val add : elem * table -> table
      val find : elem * table -> int option
      val exists : elem * table -> bool
      val empty : table
    end
  *)

  (* hash: creates a hash table of size n which assigns each distinct member
     a unique integer between 0 and n-1 *)

  functor Hash(B : sig type elem
		       val gt : elem * elem -> bool
		   end) : HASH =
  struct
      type elem=B.elem
      structure HashTable = Table(type key=B.elem
				  val gt = B.gt)

      type table = {count : int, table : int HashTable.table}

      val empty = {count=0,table=HashTable.empty}
      val size = fn {count,table} => count
      val add = fn (e,{count,table}) =>
		  {count=count+1,table=HashTable.insert((e,count),table)}
      val find = fn (e,{table,count}) => HashTable.find(e,table)
      val exists = fn (e,{table,count}) => HashTable.exists(e,table)
  end;
  (*III
  import "interface.sig";
  III*)

  functor Interface () : INTERFACE =
  struct

  type pos = int
  val line = ref 0
  fun init_line () = (line := 0)
  fun next_line () = (line := !line + 1)
  fun error (errmsg,line:pos,_) =
    output (std_out, ("Line " ^ (makestring line) ^ ": " ^ errmsg ^ "\n"))

  end  (* functor INTERFACE *)
  functor Globals(
	      structure Wr: WR
	      structure Pp: PP
	      structure WrMgt: WRMGT
	      structure ListUtils: LISTUTILS
	      structure StringUtils: STRINGUTILS
	      structure DebugUtils: DEBUGUTILS
	      structure Id: ID
	      structure Registry: REGISTRY
	      sharing Pp.Wr = Wr
		  and WrMgt.Pp = Pp
		  and type Registry.registeredtype = bool
	      ) : GLOBALS 
	      = struct

  structure Wr = Wr;
  open Wr;

  structure Pp = Pp;
  open Pp;

  structure WrMgt = WrMgt;
  open WrMgt;

  structure Id = Id;

  structure Registry = Registry

  open ListUtils
  open StringUtils
  open DebugUtils
  open Registry

  exception CantHappen

  end

  signature TRMPVT = sig

  structure Globals: GLOBALS
  structure Typ: TYPPVT
  sharing Typ.Globals = Globals
  open Globals

  datatype pretrm = 
	      PREVAR of Id.T
	    | PREABS of Id.T * Typ.pretyp * pretrm
	    | PREAPP of pretrm * pretrm
	    | PRETABS of Id.T * Typ.pretyp * pretrm
	    | PRETAPP of pretrm * Typ.pretyp
	    | PREFOR of Id.T * (Typ.pretyp list) * pretrm

  datatype T = 
	      VAR of unit * int
	    | ABS of {name:Id.T} * Typ.T * T
	    | APP of unit * T * T
	    | TABS of {name:Id.T} * Typ.T * T
	    | TAPP of unit * T * Typ.T
	    | FOR of {name:Id.T} * (Typ.T list) * T

  exception UnknownId of string
  val debruijnify: Typ.tenv -> pretrm -> T

  val prt: Pp.Pp -> Typ.tenv -> T -> unit

  end

  functor DebugUtils(
	      structure WrMgt: WRMGT
	      ) : DEBUGUTILS = struct

  open WrMgt
  open Pp;

  val level = ref(0);

  (* $$$ belongs in globals: *)
  fun unwind_protect f cleanup =
    (f())
    handle e => (cleanup(); raise e)

  fun do_wrap pp name f pbefore pafter =
    (pwrite pp "[";
     setb pp;  
     pwrite pp (makestring (!level));
     pwrite pp "] ";
     pwrite pp name;
     pwrite pp "? ";
     pbefore();
     pwrite pp "\n";
     level := (!level) + 1;
     let val result = unwind_protect 
			  f
			  (fn () => level := (!level) - 1)
     in
	level := (!level) - 1;
	break pp true ~3;
	pwrite pp "   [";
	pwrite pp (makestring (!level));
	pwrite pp "] ";
	pwrite pp name;
	pwrite pp ": ";
	pafter(result);
	pwrite pp "\n";
	endb pp;
	result
     end
    )

  fun wrap DEBUG name f pbefore pafter =
    if (not (!DEBUG))
      then f()
      else do_wrap (stdpp()) name f pbefore pafter;

  end
  functor Trm(
	      structure Globals: GLOBALS
	      structure Typ: TYPPVT
	      sharing Typ.Globals = Globals
	      ) : TRMPVT
	      = struct

  structure Globals = Globals
  structure Typ = Typ
  open Globals
  open Typ
  open Pp

  datatype pretrm = 
	      PREVAR of Id.T
	    | PREABS of Id.T * pretyp * pretrm
	    | PREAPP of pretrm * pretrm
	    | PRETABS of Id.T * pretyp * pretrm
	    | PRETAPP of pretrm * pretyp
	    | PREFOR of Id.T * (pretyp list) * pretrm

  datatype T = 
	      VAR of unit * int
	    | ABS of {name:Id.T} * Typ.T * T
	    | APP of unit * T * T
	    | TABS of {name:Id.T} * Typ.T * T
	    | TAPP of unit * T * Typ.T
	    | FOR of {name:Id.T} * (Typ.T list) * T

  fun debruijnify te (PREVAR i) =
	VAR((), index te i)
    | debruijnify te (PREABS(i,ptyp,ptrm)) =
	ABS({name=i}, Typ.debruijnify te ptyp, 
		      debruijnify (push_binding te i NS) ptrm)
    | debruijnify te (PREAPP(ptrm1,ptrm2)) =
	APP((), debruijnify te ptrm1, debruijnify te ptrm2)
    | debruijnify te (PRETABS(i,ptyp,ptrm)) =
	TABS({name=i}, Typ.debruijnify te ptyp, 
		       debruijnify (push_bound te i NS) ptrm)
    | debruijnify te (PRETAPP(ptrm,ptyp)) =
	TAPP((), debruijnify te ptrm, Typ.debruijnify te ptyp)
    | debruijnify te (PREFOR(i,ptyps,ptrm)) =
	FOR({name=i}, map (fn pt => Typ.debruijnify te pt) ptyps, 
		       debruijnify (push_bound te i NS) ptrm)

  fun prt pp te trm =
    let fun p te (VAR(_,i)) =
		Pp.pwrite pp (Id.tostr (lookup_name te i))
	  | p te (ABS({name=i},t,body)) =
		(Pp.pwrite pp "(\\";
		 Pp.pwrite pp (Id.tostr i);
		 Pp.pwrite pp ":";
		 Typ.prt pp te t;
		 Pp.pwrite pp ". ";
		 p (push_binding te i t) body;
		 Pp.pwrite pp ")")
	  | p te (APP(_,trm1,trm2)) =
		(Pp.pwrite pp "(";
		 p te trm1;
		 Pp.pwrite pp " ";
		 p te trm2;
		 Pp.pwrite pp ")")
	  | p te (TABS({name=i},t,body)) =
		(Pp.pwrite pp "(\\\\";
		 Pp.pwrite pp (Id.tostr i);
		 Pp.pwrite pp "<=";
		 Typ.prt pp te t;
		 Pp.pwrite pp ". ";
		 p (push_bound te i t) body;
		 Pp.pwrite pp ")")
	  | p te (TAPP(_,trm1,t)) =
		(Pp.pwrite pp "(";
		 p te trm1;
		 Pp.pwrite pp " [";
		 Typ.prt pp te t;
		 Pp.pwrite pp "])")
	  | p te (FOR({name=i},ts,body)) =
		(Pp.pwrite pp "(for ";
		 Pp.pwrite pp (Id.tostr i);
		 Pp.pwrite pp " in ";
		 mapunit_tuple (fn t => Typ.prt pp te t) (fn () => Pp.pwrite pp ",") ts;
		 Pp.pwrite pp ". ";
		 p (push_abbrev te i NS) body;
		 Pp.pwrite pp ")")
    in p te trm
    end

  end
  functor ListUtils() : LISTUTILS = struct

  fun mapunit f l = 
    let fun mu [] = ()
	  | mu (hd::tl) = (f hd; mu tl)
    in mu l
    end

  fun mapunit_tuple f betw ts =
    let fun mut [] = ()
	  | mut [e] = f e
	  | mut (e::tl) = (f e; betw(); mut tl)
    in mut ts
    end

  fun mapfold fm ff z =
    let fun m []       = z
	  | m (hd::tl) = ff (fm hd) (m tl)
    in m
    end

  fun memq eq l e =
    let fun m [] = false
	  | m (hd::tl) = (eq e hd) orelse (m tl)
    in m l
    end

  fun mapappend f l =
    let fun ma [] = []
	  | ma (hd::tl) = (f hd) @ (ma tl)
    in ma l
    end

  fun filter b l =
    let fun f [] = []
	  | f (hd::tl) = if (b hd) then hd::(f tl) else f tl
    in f l
    end

  fun forall f = mapfold f (fn x => fn y => x andalso y) true

  fun forsome f = mapfold f (fn x => fn y => x orelse y) false

  end
  functor Synth(
	      structure Globals: GLOBALS
	      structure Typ: TYPPVT
	      structure Trm: TRMPVT
	      structure Leq: LEQ
	      sharing Typ.Globals = Globals
		  and Trm.Typ = Typ
		  and Leq.Typ = Typ
	      ) : SYNTH = struct

  structure Globals = Globals
  structure Typ = Typ
  structure Trm = Trm
  structure Leq = Leq
  open Globals
  open Typ
  open Trm

  val DEBUG = ref(false)
  val _ = (registerflag "synth" DEBUG;
	   registerflag "Synth" DEBUG)

  fun arrowbasis te t = 
    let fun ab (TVAR(_,v)) = 
	      (case lookup_and_relocate te v of
		  BND(_,b) => ab b
		| VBND(n,b) => raise Typ.WrongKindOfId(te,v,"tvar or abbrev")
		| ABB(_,b) => ab b)
	  | ab (t as ARROW(_)) =
	      [t]
	  | ab (ALL(_)) =
	      []
	  | ab (MEET(_,ts)) =
	      mapappend ab ts
    in ab t
    end

  fun allbasis te t = 
    let fun ab (TVAR(_,v)) = 
	      (case lookup_and_relocate te v of
		  BND(_,b) => ab b
		| VBND(n,b) => raise Typ.WrongKindOfId(te,v,"tvar or abbrev")
		| ABB(_,b) => ab b)
	  | ab (t as ARROW(_)) =
	      []
	  | ab (t as ALL(_)) =
	      [t]
	  | ab (MEET(_,ts)) =
	      mapappend ab ts
    in ab t
    end

  fun synth' te (VAR(_,v)) = Typ.lookup_and_relocate_binding te v
    | synth' te (ABS({name=i},t,body)) = 
	let val t_body = synth (push_binding te i t) body
	    val t' = relocate ~1 t_body
	in ARROW((),t,t')
	end
    | synth' te (APP(_,trm1,trm2)) = 
	let val t1 = synth te trm1
	    and t2 = synth te trm2
	    val basis = arrowbasis te t1
	    fun collect_apps [] =
		  []
	      | collect_apps ((ARROW(_,tb1,tb2))::tl) = 
		  if Leq.leq te t2 tb1
		     then tb2::(collect_apps tl)
		     else (collect_apps tl)
	      | collect_apps _ = raise CantHappen
	    val ts = collect_apps basis
	in MEET((),ts)
	end
    | synth' te (TABS({name=i},t,body)) = 
	let val t' = synth (push_bound te i t) body
	in ALL({name=i},t,t')
	end
    | synth' te (TAPP(_,body,t)) =
	let val t_body = synth te body
	    val basis = allbasis te t_body
	    fun collect_apps [] =
		  []
	      | collect_apps ((ALL(_,t1,t2))::tl) = 
		  if Leq.leq te t t1
		     then (tsubst_top t t2)::(collect_apps tl)
		     else (collect_apps tl)
	      | collect_apps _ = raise CantHappen
	    val ts = collect_apps basis
	in MEET((),ts)
	end
    | synth' te (FOR({name=i},ts,body)) =
	let fun f t = 
		let val tb = synth (push_abbrev te i t) body
		    val tb' = tsubst_top t tb
		in tb'
		end
	in MEET((), map f ts)
	end

  and synth te e =
    wrap (DEBUG) "synth"
	 (fn () => synth' te e)
	 (fn () => 
	    (Trm.prt (stdpp()) te e;
	     Pp.pwrite (stdpp()) "\n";
	     Typ.prt_tenv (stdpp()) te))
	 (fn t => 
	    (Typ.prt (stdpp()) te t))

  end

  functor FMEETLrValsFun ( structure Token : TOKEN
				  structure Globals : GLOBALS
				  structure ParseRes : PARSERES
				) : FMEET_LRVALS = 
  struct
  structure ParserData=
  struct
  structure Header = 
  struct
  structure ParseRes = ParseRes
  open ParseRes
  open Trm
  open Typ
  open Globals

  end
  structure LrTable = Token.LrTable
  structure Token = Token
  local open LrTable in 
  val table=let val actionT =
  "\
  \\001\000\022\000\014\000\021\000\023\000\020\000\
  \\024\000\019\000\025\000\018\000\026\000\017\000\027\000\016\000\
  \\028\000\015\000\029\000\014\000\030\000\013\000\031\000\012\000\
  \\032\000\011\000\033\000\010\000\040\000\009\000\000\000\001\000\
  \\000\000\141\000\
  \\014\000\025\000\016\000\024\000\025\000\018\000\000\000\140\000\
  \\000\000\116\000\
  \\000\000\147\000\
  \\005\000\028\000\008\000\027\000\009\000\026\000\000\000\137\000\
  \\000\000\118\000\
  \\025\000\018\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\025\000\038\000\000\000\001\000\
  \\025\000\039\000\000\000\001\000\
  \\025\000\040\000\000\000\001\000\
  \\025\000\018\000\000\000\001\000\
  \\025\000\042\000\000\000\001\000\
  \\000\000\139\000\
  \\000\000\138\000\
  \\000\000\136\000\
  \\025\000\018\000\000\000\001\000\
  \\025\000\018\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\000\000\117\000\
  \\000\000\149\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\036\000\053\000\000\000\001\000\
  \\006\000\054\000\000\000\134\000\
  \\005\000\057\000\012\000\056\000\022\000\055\000\000\000\001\000\
  \\000\000\122\000\
  \\025\000\018\000\000\000\001\000\
  \\000\000\126\000\
  \\025\000\018\000\000\000\001\000\
  \\016\000\060\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\000\000\120\000\
  \\000\000\121\000\
  \\000\000\119\000\
  \\005\000\063\000\009\000\062\000\000\000\001\000\
  \\000\000\110\000\
  \\036\000\064\000\000\000\001\000\
  \\002\000\066\000\005\000\065\000\006\000\054\000\000\000\134\000\
  \\003\000\067\000\000\000\001\000\
  \\015\000\068\000\000\000\001\000\
  \\000\000\137\000\
  \\012\000\056\000\017\000\069\000\022\000\055\000\000\000\001\000\
  \\015\000\070\000\000\000\001\000\
  \\012\000\056\000\022\000\055\000\000\000\114\000\
  \\000\000\115\000\
  \\012\000\056\000\022\000\055\000\000\000\112\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\025\000\018\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\002\000\078\000\005\000\077\000\000\000\001\000\
  \\002\000\080\000\005\000\079\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\012\000\056\000\015\000\082\000\022\000\055\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\000\000\148\000\
  \\000\000\151\000\
  \\000\000\150\000\
  \\002\000\089\000\000\000\001\000\
  \\006\000\090\000\012\000\056\000\022\000\055\000\000\000\132\000\
  \\000\000\135\000\
  \\012\000\056\000\022\000\055\000\000\000\124\000\
  \\012\000\056\000\000\000\123\000\
  \\012\000\056\000\022\000\055\000\000\000\109\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\017\000\095\000\000\000\001\000\
  \\000\000\127\000\
  \\012\000\056\000\022\000\055\000\000\000\113\000\
  \\012\000\056\000\022\000\055\000\000\000\111\000\
  \\002\000\096\000\000\000\001\000\
  \\002\000\097\000\012\000\056\000\022\000\055\000\000\000\001\000\
  \\000\000\143\000\
  \\002\000\098\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\002\000\101\000\012\000\056\000\022\000\055\000\000\000\001\000\
  \\012\000\056\000\022\000\055\000\000\000\130\000\
  \\002\000\102\000\012\000\056\000\022\000\055\000\000\000\001\000\
  \\012\000\056\000\022\000\055\000\000\000\128\000\
  \\000\000\125\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\014\000\021\000\023\000\020\000\024\000\019\000\
  \\025\000\018\000\026\000\017\000\027\000\016\000\040\000\009\000\000\000\001\000\
  \\000\000\146\000\
  \\000\000\133\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\014\000\037\000\022\000\036\000\025\000\018\000\
  \\035\000\035\000\037\000\034\000\043\000\033\000\000\000\001\000\
  \\000\000\145\000\
  \\000\000\144\000\
  \\000\000\142\000\
  \\012\000\056\000\022\000\055\000\000\000\131\000\
  \\012\000\056\000\022\000\055\000\000\000\129\000\
  \\001\000\000\000\004\000\000\000\000\000\001\000\
  \"
  val gotoT =
  "\
  \\001\000\106\000\002\000\006\000\003\000\005\000\
  \\005\000\004\000\008\000\003\000\009\000\002\000\010\000\001\000\000\000\000\000\
  \\000\000\000\000\
  \\003\000\021\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\028\000\004\000\027\000\000\000\000\000\
  \\003\000\030\000\006\000\029\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\039\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\042\000\004\000\041\000\000\000\000\000\
  \\003\000\043\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\044\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\046\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\047\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\030\000\006\000\048\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\049\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\030\000\006\000\050\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\056\000\000\000\000\000\
  \\000\000\000\000\
  \\003\000\057\000\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\059\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\070\000\007\000\069\000\000\000\000\000\
  \\003\000\028\000\004\000\071\000\000\000\000\000\
  \\003\000\030\000\006\000\072\000\000\000\000\000\
  \\003\000\030\000\006\000\073\000\000\000\000\000\
  \\003\000\030\000\006\000\074\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\070\000\007\000\079\000\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\081\000\000\000\000\000\
  \\003\000\030\000\006\000\082\000\000\000\000\000\
  \\003\000\030\000\006\000\070\000\007\000\083\000\000\000\000\000\
  \\003\000\030\000\006\000\084\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\085\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\030\000\006\000\070\000\007\000\086\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\089\000\000\000\000\000\
  \\003\000\030\000\006\000\090\000\000\000\000\000\
  \\003\000\030\000\006\000\091\000\000\000\000\000\
  \\003\000\030\000\006\000\092\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\097\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\030\000\006\000\070\000\007\000\098\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\101\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\102\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\003\000\045\000\005\000\004\000\008\000\103\000\
  \\009\000\002\000\010\000\001\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\003\000\030\000\006\000\104\000\000\000\000\000\
  \\003\000\030\000\006\000\105\000\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \\000\000\000\000\
  \"
  val numstates = 107
  val string_to_int = fn(s,index) => (ordof(s,index) + 
			  ordof(s,index+1)*256,index+2)
	  val convert_string_to_row = fn (conv_key,conv_entry) =>
	       fn(s,index) =>
		  let fun f (r,index) =
			  let val (num,index) = string_to_int(s,index)
			      val (i,index) = string_to_int(s,index)
			  in if num=0 then ((rev r,conv_entry i),index)
			     else f((conv_key (num-1),conv_entry i)::r,index)
			  end
		  in f(nil,index)
		  end
	   val convert_string_to_row_list = fn conv_funcs => fn s =>
		      let val convert_row =convert_string_to_row conv_funcs
			  fun f(r,index) =
			    if index < String.length s then
			      let val (newlist,index) = convert_row (s,index)
			      in f(newlist::r,index)
			      end
			    else rev r
		      in f(nil,0)
		      end
	   val entry_to_action = fn j =>
			 if j=0 then ACCEPT
			 else if j=1 then ERROR
			 else if j >= (numstates+2) then REDUCE (j-numstates-2)
			 else SHIFT (STATE (j-2))
	   val make_goto_table = convert_string_to_row_list(NT,STATE)
	   val make_action_table=convert_string_to_row_list(T,entry_to_action)
	   val gotoT = map (fn (a,b) => a) (make_goto_table gotoT)
	   val actionT = make_action_table actionT
       in LrTable.mkLrTable {actions=actionT,gotos=gotoT,
	    numStates=numstates,initialState=STATE 0}
       end
  end
  local open Header in
  type pos = int
  type arg = unit
  structure MlyValue = 
  struct
  datatype svalue = VOID | ntVOID of unit | T_STR_CONST of  (string)
   | T_INT_CONST of  (string) | T_ID of  (string)
   | bnd of  (ParseRes.Trm.pretrm) | appl of  (ParseRes.Trm.pretrm)
   | term of  (ParseRes.Trm.pretrm)
   | tplist of  (ParseRes.Typ.pretyp list)
   | tp of  (ParseRes.Typ.pretyp) | const of  (Id.T)
   | idlist of  (Id.T list) | id of  (Id.T) | setcmd of  (ParseRes.T)
   | start of  (ParseRes.T)
  end
  type svalue = MlyValue.svalue
  type result = ParseRes.T
  end
  structure EC=
  struct
  open LrTable
  val is_keyword =
  fn _ => false
  val preferred_insert =
  fn (T 1) => true | (T 38) => true | _ => false
  val preferred_subst =
  fn  _ => nil
  val noShift = 
  fn (T 3) => true | (T 0) => true | _ => false
  val showTerminal =
  fn (T 0) => "T_EOF"
    | (T 1) => "T_DOT"
    | (T 2) => "T_COLON"
    | (T 3) => "T_SEMICOLON"
    | (T 4) => "T_LEQ"
    | (T 5) => "T_COMMA"
    | (T 6) => "T_APOST"
    | (T 7) => "T_EQ"
    | (T 8) => "T_DOUBLEEQ"
    | (T 9) => "T_DOLLAR"
    | (T 10) => "T_AT"
    | (T 11) => "T_ARROW"
    | (T 12) => "T_DARROW"
    | (T 13) => "T_LPAREN"
    | (T 14) => "T_RPAREN"
    | (T 15) => "T_LBRACK"
    | (T 16) => "T_RBRACK"
    | (T 17) => "T_LANGLE"
    | (T 18) => "T_RANGLE"
    | (T 19) => "T_LCURLY"
    | (T 20) => "T_RCURLY"
    | (T 21) => "T_INTER"
    | (T 22) => "T_LAMBDA"
    | (T 23) => "T_BIGLAMBDA"
    | (T 24) => "T_ID"
    | (T 25) => "T_INT_CONST"
    | (T 26) => "T_STR_CONST"
    | (T 27) => "T_USE"
    | (T 28) => "T_TYPE"
    | (T 29) => "T_SET"
    | (T 30) => "T_RESET"
    | (T 31) => "T_DEBUG"
    | (T 32) => "T_CHECK"
    | (T 33) => "T_WITH"
    | (T 34) => "T_ALL"
    | (T 35) => "T_IN"
    | (T 36) => "T_NS"
    | (T 37) => "T_CASE"
    | (T 38) => "T_OF"
    | (T 39) => "T_FOR"
    | (T 40) => "T_OBSERVE"
    | (T 41) => "T_INSTALL"
    | (T 42) => "T_SOME"
    | (T 43) => "T_OPEN"
    | (T 44) => "T_END"
    | (T 45) => "T_PACK"
    | _ => "bogus-term"
  val errtermvalue=
  let open Header in
  fn _ => MlyValue.VOID
  end
  val terms = (T 0) :: (T 1) :: (T 2) :: (T 3) :: (T 4) :: (T 5) :: (T 6
  ) :: (T 7) :: (T 8) :: (T 9) :: (T 10) :: (T 11) :: (T 12) :: (T 13)
   :: (T 14) :: (T 15) :: (T 16) :: (T 17) :: (T 18) :: (T 19) :: (T 20)
   :: (T 21) :: (T 22) :: (T 23) :: (T 27) :: (T 28) :: (T 29) :: (T 30)
   :: (T 31) :: (T 32) :: (T 33) :: (T 34) :: (T 35) :: (T 36) :: (T 37)
   :: (T 38) :: (T 39) :: (T 40) :: (T 41) :: (T 42) :: (T 43) :: (T 44)
   :: (T 45) :: nil
  end
  structure Actions =
  struct 
  exception mlyAction of int
  val actions = 
  let open Header
  in
  fn (i392,defaultPos,stack,
      (()):arg) =>
  case (i392,stack)
  of (0,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_LEQleft as 
  T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.tp (tp1 as tp),
  tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_CHECKleft as 
  T_CHECK1left,T_CHECKright as T_CHECK1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Leq(tp1,tp2))))
  in (LrTable.NT 0,(result,T_CHECK1left,tp2right),rest671)
  end
  | (1,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left,
  T_IDright as T_ID1right)) :: (_,(_,T_USEleft as T_USE1left,
  T_USEright as T_USE1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Use(T_ID))))
  in (LrTable.NT 0,(result,T_USE1left,T_ID1right),rest671)
  end
  | (2,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right
  )) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: 
  (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right
  )) :: (_,(_,T_TYPEleft as T_TYPE1left,T_TYPEright as T_TYPE1right
  )) :: rest671) =>
  let val result = 
  MlyValue.start (((Type_Assumption(id,tp))))
  in (LrTable.NT 0,(result,T_TYPE1left,tp1right),rest671)
  end
  | (3,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right
  )) :: (_,(_,T_LEQleft as T_LEQ1left,T_LEQright as T_LEQ1right)) :: 
  (_,(MlyValue.id (id1 as id),idleft as id1left,idright as id1right
  )) :: rest671) =>
  let val result = 
  MlyValue.start (((Type_Assumption(id,tp))))
  in (LrTable.NT 0,(result,id1left,tp1right),rest671)
  end
  | (4,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right
  )) :: (_,(_,T_DOUBLEEQleft as T_DOUBLEEQ1left,T_DOUBLEEQright as 
  T_DOUBLEEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,
  idright as id1right)) :: (_,(_,T_TYPEleft as T_TYPE1left,
  T_TYPEright as T_TYPE1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Type_Abbrev(id,tp))))
  in (LrTable.NT 0,(result,T_TYPE1left,tp1right),rest671)
  end
  | (5,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right
  )) :: (_,(_,T_DOUBLEEQleft as T_DOUBLEEQ1left,T_DOUBLEEQright as 
  T_DOUBLEEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,
  idright as id1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Type_Abbrev(id,tp))))
  in (LrTable.NT 0,(result,id1left,tp1right),rest671)
  end
  | (6,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_EQleft as T_EQ1left,T_EQright as 
  T_EQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as id1left,
  idright as id1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Term_Def(id,term))))
  in (LrTable.NT 0,(result,id1left,term1right),rest671)
  end
  | (7,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Term_Def(Id.intern "it",term))))
  in (LrTable.NT 0,(result,term1left,term1right),rest671)
  end
  | (8,(_,(_,T_EOFleft as T_EOF1left,T_EOFright as T_EOF1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((Nothing)))
  in (LrTable.NT 0,(result,T_EOF1left,T_EOF1right),rest671)
  end
  | (9,(_,(MlyValue.setcmd (setcmd1 as setcmd),setcmdleft as setcmd1left
  ,setcmdright as setcmd1right)) :: rest671) =>
  let val result = 
  MlyValue.start (((setcmd)))
  in (LrTable.NT 0,(result,setcmd1left,setcmd1right),rest671)
  end
  | (10,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left,
  T_IDright as T_ID1right)) :: (_,(_,T_SETleft as T_SET1left,
  T_SETright as T_SET1right)) :: rest671) =>
  let val result = 
  MlyValue.setcmd (((Set(T_ID,"true"))))
  in (LrTable.NT 1,(result,T_SET1left,T_ID1right),rest671)
  end
  | (11,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left,
  T_IDright as T_ID1right)) :: (_,(_,T_DEBUGleft as T_DEBUG1left,
  T_DEBUGright as T_DEBUG1right)) :: rest671) =>
  let val result = 
  MlyValue.setcmd (((Set(T_ID,"true"))))
  in (LrTable.NT 1,(result,T_DEBUG1left,T_ID1right),rest671)
  end
  | (12,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left,
  T_IDright as T_ID1right)) :: (_,(_,T_RESETleft as T_RESET1left,
  T_RESETright as T_RESET1right)) :: rest671) =>
  let val result = 
  MlyValue.setcmd (((Set(T_ID,"false"))))
  in (LrTable.NT 1,(result,T_RESET1left,T_ID1right),rest671)
  end
  | (13,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PRETVAR(id))))
  in (LrTable.NT 5,(result,id1left,id1right),rest671)
  end
  | (14,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,
  T_ARROWleft as T_ARROW1left,T_ARROWright as T_ARROW1right)) :: (_,(
  MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREARROW(tp1,tp2))))
  in (LrTable.NT 5,(result,tp1left,tp2right),rest671)
  end
  | (15,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,
  T_INTERleft as T_INTER1left,T_INTERright as T_INTER1right)) :: (_,(
  MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREMEET([tp1,tp2]))))
  in (LrTable.NT 5,(result,tp1left,tp2right),rest671)
  end
  | (16,(_,(_,T_RBRACKleft as T_RBRACK1left,T_RBRACKright as 
  T_RBRACK1right)) :: (_,(MlyValue.tplist (tplist1 as tplist),
  tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_,
  T_LBRACKleft as T_LBRACK1left,T_LBRACKright as T_LBRACK1right)) :: 
  (_,(_,T_INTERleft as T_INTER1left,T_INTERright as T_INTER1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREMEET(tplist))))
  in (LrTable.NT 5,(result,T_INTER1left,T_RBRACK1right),rest671)
  end
  | (17,(_,(_,T_NSleft as T_NS1left,T_NSright as T_NS1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREMEET([]))))
  in (LrTable.NT 5,(result,T_NS1left,T_NS1right),rest671)
  end
  | (18,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as 
  T_RPAREN1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,
  tpright as tp1right)) :: (_,(_,T_LPARENleft as T_LPAREN1left,
  T_LPARENright as T_LPAREN1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((tp)))
  in (LrTable.NT 5,(result,T_LPAREN1left,T_RPAREN1right),rest671)
  end
  | (19,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as 
  tp1right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right
  )) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: (_,(_,T_ALLleft as T_ALL1left,T_ALLright as T_ALL1right
  )) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREALL(id, PREMEET[], tp))))
  in (LrTable.NT 5,(result,T_ALL1left,tp1right),rest671)
  end
  | (20,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_DOTleft as 
  T_DOT1left,T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp),
  tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as 
  T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),
  idleft as id1left,idright as id1right)) :: (_,(_,T_ALLleft as 
  T_ALL1left,T_ALLright as T_ALL1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((PREALL(id, tp1, tp2))))
  in (LrTable.NT 5,(result,T_ALL1left,tp2right),rest671)
  end
  | (21,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as 
  tp1right)) :: (_,(_,T_DOTleft as T_DOT1left,T_DOTright as T_DOT1right
  )) :: (_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: (_,(_,T_SOMEleft as T_SOME1left,T_SOMEright as 
  T_SOME1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((
  let val b = Id.new()
		       val bv = PRETVAR(b)
		       val idv = PRETVAR(id)
		   in PREALL(b,PREMEET[], 
			     PREARROW(PREALL(id, PREMEET[], 
					  PREARROW(tp, bv)),
				   bv))
		   end
  )))
  in (LrTable.NT 5,(result,T_SOME1left,tp1right),rest671)
  end
  | (22,(_,(MlyValue.tp (tp2),tp2left,tp2right)) :: (_,(_,T_DOTleft as 
  T_DOT1left,T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp),
  tpleft as tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as 
  T_LEQ1left,T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),
  idleft as id1left,idright as id1right)) :: (_,(_,T_SOMEleft as 
  T_SOME1left,T_SOMEright as T_SOME1right)) :: rest671) =>
  let val result = 
  MlyValue.tp (((
  let val b = Id.new()
		       val bv = PRETVAR(b)
		       val idv = PRETVAR(id)
		   in PREALL(b,PREMEET[], 
			     PREARROW(PREALL(id, tp1, 
					  PREARROW(tp2, bv)),
				   bv))
		   end
  )))
  in (LrTable.NT 5,(result,T_SOME1left,tp2right),rest671)
  end
  | (23,(_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,tpright as 
  tp1right)) :: rest671) =>
  let val result = 
  MlyValue.tplist ((([tp])))
  in (LrTable.NT 6,(result,tp1left,tp1right),rest671)
  end
  | (24,(_,(MlyValue.tplist (tplist1 as tplist),tplistleft as 
  tplist1left,tplistright as tplist1right)) :: (_,(_,T_COMMAleft as 
  T_COMMA1left,T_COMMAright as T_COMMA1right)) :: (_,(MlyValue.tp (tp1
   as tp),tpleft as tp1left,tpright as tp1right)) :: rest671) =>
  let val result = 
  MlyValue.tplist (((tp::tplist)))
  in (LrTable.NT 6,(result,tp1left,tplist1right),rest671)
  end
  | (25,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: rest671) =>
  let val result = 
  MlyValue.idlist ((([id])))
  in (LrTable.NT 3,(result,id1left,id1right),rest671)
  end
  | (26,(_,(MlyValue.idlist (idlist1 as idlist),idlistleft as 
  idlist1left,idlistright as idlist1right)) :: (_,(_,T_COMMAleft as 
  T_COMMA1left,T_COMMAright as T_COMMA1right)) :: (_,(MlyValue.id (id1
   as id),idleft as id1left,idright as id1right)) :: rest671) =>
  let val result = 
  MlyValue.idlist (((id::idlist)))
  in (LrTable.NT 3,(result,id1left,idlist1right),rest671)
  end
  | (27,(_,(MlyValue.T_ID (T_ID1 as T_ID),T_IDleft as T_ID1left,
  T_IDright as T_ID1right)) :: rest671) =>
  let val result = 
  MlyValue.id (((Id.intern T_ID)))
  in (LrTable.NT 2,(result,T_ID1left,T_ID1right),rest671)
  end
  | (28,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: rest671) =>
  let val result = 
  MlyValue.const (((id)))
  in (LrTable.NT 4,(result,id1left,id1right),rest671)
  end
  | (29,(_,(MlyValue.T_INT_CONST (T_INT_CONST1 as T_INT_CONST),
  T_INT_CONSTleft as T_INT_CONST1left,T_INT_CONSTright as 
  T_INT_CONST1right)) :: rest671) =>
  let val result = 
  MlyValue.const (((Id.intern T_INT_CONST)))
  in (LrTable.NT 4,(result,T_INT_CONST1left,T_INT_CONST1right),rest671)
  end
  | (30,(_,(MlyValue.T_STR_CONST (T_STR_CONST1 as T_STR_CONST),
  T_STR_CONSTleft as T_STR_CONST1left,T_STR_CONSTright as 
  T_STR_CONST1right)) :: rest671) =>
  let val result = 
  MlyValue.const (((Id.intern T_STR_CONST)))
  in (LrTable.NT 4,(result,T_STR_CONST1left,T_STR_CONST1right),rest671)
  end
  | (31,(_,(MlyValue.appl (appl1 as appl),applleft as appl1left,
  applright as appl1right)) :: rest671) =>
  let val result = 
  MlyValue.term (((appl)))
  in (LrTable.NT 7,(result,appl1left,appl1right),rest671)
  end
  | (32,(_,(MlyValue.bnd (bnd1 as bnd),bndleft as bnd1left,bndright as 
  bnd1right)) :: rest671) =>
  let val result = 
  MlyValue.term (((bnd)))
  in (LrTable.NT 7,(result,bnd1left,bnd1right),rest671)
  end
  | (33,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left,
  T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist)
  ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_,
  T_COLONleft as T_COLON1left,T_COLONright as T_COLON1right)) :: (_,(
  MlyValue.id (id1 as id),idleft as id1left,idright as id1right)) :: 
  (_,(_,T_LAMBDAleft as T_LAMBDA1left,T_LAMBDAright as T_LAMBDA1right
  )) :: rest671) =>
  let val result = 
  MlyValue.bnd (((
  case tplist of 
					      [t] => PREABS(id,t,term)
					    | ts  => 
						let val a = Id.new_from id
						in PREFOR(a,ts,
						     PREABS(id,PRETVAR(a),term))
						end
  )))
  in (LrTable.NT 9,(result,T_LAMBDA1left,term1right),rest671)
  end
  | (34,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left,
  T_DOTright as T_DOT1right)) :: (_,(MlyValue.id (id1 as id),idleft as 
  id1left,idright as id1right)) :: (_,(_,T_BIGLAMBDAleft as 
  T_BIGLAMBDA1left,T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) =>
  let val result = 
  MlyValue.bnd (((PRETABS(id,PREMEET[],term))))
  in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671)
  end
  | (35,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left,
  T_DOTright as T_DOT1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as 
  tp1left,tpright as tp1right)) :: (_,(_,T_LEQleft as T_LEQ1left,
  T_LEQright as T_LEQ1right)) :: (_,(MlyValue.id (id1 as id),idleft as 
  id1left,idright as id1right)) :: (_,(_,T_BIGLAMBDAleft as 
  T_BIGLAMBDA1left,T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) =>
  let val result = 
  MlyValue.bnd (((PRETABS(id,tp,term))))
  in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671)
  end
  | (36,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left,
  T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist)
  ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_,
  T_INleft as T_IN1left,T_INright as T_IN1right)) :: (_,(MlyValue.idlist
   (idlist1 as idlist),idlistleft as idlist1left,idlistright as 
  idlist1right)) :: (_,(_,T_BIGLAMBDAleft as T_BIGLAMBDA1left,
  T_BIGLAMBDAright as T_BIGLAMBDA1right)) :: rest671) =>
  let val result = 
  MlyValue.bnd (((
  let fun f [] = term
						 | f (v::vs) =
						      PREFOR(v, tplist, f vs)
					   in f idlist end
  )))
  in (LrTable.NT 9,(result,T_BIGLAMBDA1left,term1right),rest671)
  end
  | (37,(_,(MlyValue.term (term1 as term),termleft as term1left,
  termright as term1right)) :: (_,(_,T_DOTleft as T_DOT1left,
  T_DOTright as T_DOT1right)) :: (_,(MlyValue.tplist (tplist1 as tplist)
  ,tplistleft as tplist1left,tplistright as tplist1right)) :: (_,(_,
  T_INleft as T_IN1left,T_INright as T_IN1right)) :: (_,(MlyValue.idlist
   (idlist1 as idlist),idlistleft as idlist1left,idlistright as 
  idlist1right)) :: (_,(_,T_FORleft as T_FOR1left,T_FORright as 
  T_FOR1right)) :: rest671) =>
  let val result = 
  MlyValue.bnd (((
  let fun f [] = term
						 | f (v::vs) =
						      PREFOR(v, tplist, f vs)
					   in f idlist end
  )))
  in (LrTable.NT 9,(result,T_FOR1left,term1right),rest671)
  end
  | (38,(_,(MlyValue.const (const1 as const),constleft as const1left,
  constright as const1right)) :: rest671) =>
  let val result = 
  MlyValue.appl (((PREVAR(const))))
  in (LrTable.NT 8,(result,const1left,const1right),rest671)
  end
  | (39,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as 
  T_RPAREN1right)) :: (_,(MlyValue.term (term1 as term),termleft as 
  term1left,termright as term1right)) :: (_,(_,T_LPARENleft as 
  T_LPAREN1left,T_LPARENright as T_LPAREN1right)) :: rest671) =>
  let val result = 
  MlyValue.appl (((term)))
  in (LrTable.NT 8,(result,T_LPAREN1left,T_RPAREN1right),rest671)
  end
  | (40,(_,(MlyValue.id (id1 as id),idleft as id1left,idright as 
  id1right)) :: (_,(MlyValue.appl (appl1 as appl),applleft as appl1left,
  applright as appl1right)) :: rest671) =>
  let val result = 
  MlyValue.appl (((PREAPP(appl,PREVAR(id)))))
  in (LrTable.NT 8,(result,appl1left,id1right),rest671)
  end
  | (41,(_,(_,T_RPARENleft as T_RPAREN1left,T_RPARENright as 
  T_RPAREN1right)) :: (_,(MlyValue.term (term1 as term),termleft as 
  term1left,termright as term1right)) :: (_,(_,T_LPARENleft as 
  T_LPAREN1left,T_LPARENright as T_LPAREN1right)) :: (_,(MlyValue.appl (
  appl1 as appl),applleft as appl1left,applright as appl1right)) :: rest671) =>
  let val result = 
  MlyValue.appl (((PREAPP(appl,term))))
  in (LrTable.NT 8,(result,appl1left,T_RPAREN1right),rest671)
  end
  | (42,(_,(_,T_RBRACKleft as T_RBRACK1left,T_RBRACKright as 
  T_RBRACK1right)) :: (_,(MlyValue.tp (tp1 as tp),tpleft as tp1left,
  tpright as tp1right)) :: (_,(_,T_LBRACKleft as T_LBRACK1left,
  T_LBRACKright as T_LBRACK1right)) :: (_,(MlyValue.appl (appl1 as appl)
  ,applleft as appl1left,applright as appl1right)) :: rest671) =>
  let val result = 
  MlyValue.appl (((PRETAPP(appl,tp))))
  in (LrTable.NT 8,(result,appl1left,T_RBRACK1right),rest671)
  end
  | _ => raise (mlyAction i392)
  end
  val void = MlyValue.VOID
  val extract = fn a => (fn MlyValue.start x => x
  | _ => let exception ParseInternal
	  in raise ParseInternal end) a 
  end
  end
  structure Tokens : FMEET_TOKENS =
  struct
  type svalue = ParserData.svalue
  type ('a,'b) token = ('a,'b) Token.token
  fun T_EOF (p1,p2) = Token.TOKEN (ParserData.LrTable.T 0,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_DOT (p1,p2) = Token.TOKEN (ParserData.LrTable.T 1,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_COLON (p1,p2) = Token.TOKEN (ParserData.LrTable.T 2,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_SEMICOLON (p1,p2) = Token.TOKEN (ParserData.LrTable.T 3,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LEQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 4,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_COMMA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 5,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_APOST (p1,p2) = Token.TOKEN (ParserData.LrTable.T 6,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_EQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 7,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_DOUBLEEQ (p1,p2) = Token.TOKEN (ParserData.LrTable.T 8,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_DOLLAR (p1,p2) = Token.TOKEN (ParserData.LrTable.T 9,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_AT (p1,p2) = Token.TOKEN (ParserData.LrTable.T 10,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_ARROW (p1,p2) = Token.TOKEN (ParserData.LrTable.T 11,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_DARROW (p1,p2) = Token.TOKEN (ParserData.LrTable.T 12,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LPAREN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 13,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_RPAREN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 14,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LBRACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 15,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_RBRACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 16,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LANGLE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 17,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_RANGLE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 18,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LCURLY (p1,p2) = Token.TOKEN (ParserData.LrTable.T 19,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_RCURLY (p1,p2) = Token.TOKEN (ParserData.LrTable.T 20,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_INTER (p1,p2) = Token.TOKEN (ParserData.LrTable.T 21,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_LAMBDA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 22,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_BIGLAMBDA (p1,p2) = Token.TOKEN (ParserData.LrTable.T 23,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_ID (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 24,(
  ParserData.MlyValue.T_ID i,p1,p2))
  fun T_INT_CONST (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 25,(
  ParserData.MlyValue.T_INT_CONST i,p1,p2))
  fun T_STR_CONST (i,p1,p2) = Token.TOKEN (ParserData.LrTable.T 26,(
  ParserData.MlyValue.T_STR_CONST i,p1,p2))
  fun T_USE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 27,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_TYPE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 28,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_SET (p1,p2) = Token.TOKEN (ParserData.LrTable.T 29,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_RESET (p1,p2) = Token.TOKEN (ParserData.LrTable.T 30,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_DEBUG (p1,p2) = Token.TOKEN (ParserData.LrTable.T 31,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_CHECK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 32,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_WITH (p1,p2) = Token.TOKEN (ParserData.LrTable.T 33,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_ALL (p1,p2) = Token.TOKEN (ParserData.LrTable.T 34,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_IN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 35,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_NS (p1,p2) = Token.TOKEN (ParserData.LrTable.T 36,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_CASE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 37,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_OF (p1,p2) = Token.TOKEN (ParserData.LrTable.T 38,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_FOR (p1,p2) = Token.TOKEN (ParserData.LrTable.T 39,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_OBSERVE (p1,p2) = Token.TOKEN (ParserData.LrTable.T 40,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_INSTALL (p1,p2) = Token.TOKEN (ParserData.LrTable.T 41,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_SOME (p1,p2) = Token.TOKEN (ParserData.LrTable.T 42,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_OPEN (p1,p2) = Token.TOKEN (ParserData.LrTable.T 43,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_END (p1,p2) = Token.TOKEN (ParserData.LrTable.T 44,(
  ParserData.MlyValue.VOID,p1,p2))
  fun T_PACK (p1,p2) = Token.TOKEN (ParserData.LrTable.T 45,(
  ParserData.MlyValue.VOID,p1,p2))
  end
  end
  signature FILEUTILS = sig

  val open_fmeet_file: string -> (instream * string)

  end
  functor Main(
	   structure Globals: GLOBALS
	   structure Typ: TYP
	   structure Trm: TRM
	   structure FileUtils: FILEUTILS
	   structure Parse: PARSE
	   structure Leq: LEQ
	   structure Synth: SYNTH
	   sharing Typ.Globals = Globals
	       and Parse.ParseRes.Typ = Typ
	       and Parse.ParseRes.Trm = Trm
	       and Leq.Typ = Typ
	       and Trm.Typ = Typ
	       and Synth.Trm = Trm
	       and Synth.Leq = Leq
	   val buildtime : string
	  ) = struct

  open Globals;
  open Parse.ParseRes;

  val global_tenv = ref(Typ.empty_tenv)

  exception NotABoolean

  fun string_to_bool "true" = true
    | string_to_bool "True" = true
    | string_to_bool "TRUE" = true
    | string_to_bool "t" = true
    | string_to_bool "T" = true
    | string_to_bool "yes" = true
    | string_to_bool "Yes" = true
    | string_to_bool "YES" = true
    | string_to_bool "false" = false
    | string_to_bool "False" = false
    | string_to_bool "FALSE" = false
    | string_to_bool "f" = false
    | string_to_bool "F" = false
    | string_to_bool "no" = false
    | string_to_bool "No" = false
    | string_to_bool "NO" = false
    | string_to_bool _ = raise NotABoolean

  fun rep_loop done parser error =
    while (not (done())) do
      (case parser() of
	   Use(f) => 
	     rep_loop_on_file f
	 | Type_Assumption(i,pt) =>
	     let val t = Typ.debruijnify (!global_tenv) pt
	     in 
		write (Id.tostr i);
		write " <= ";
		Typ.prt (stdpp()) (!global_tenv) t;
		write "\n";
		global_tenv := Typ.push_bound (!global_tenv) i t
	     end
	 | Type_Abbrev(i,pt) =>
	     let val t = Typ.debruijnify (!global_tenv) pt
		 val _ = global_tenv := Typ.push_abbrev (!global_tenv) i t
	     in 
		write (Id.tostr i);
		write " == ";
		Typ.prt (stdpp()) (!global_tenv) t;
		write "\n"
	     end
	 | Term_Def(i,ptrm) =>
	     let val trm = Trm.debruijnify (!global_tenv) ptrm
		 val typ = Synth.synth (!global_tenv) trm
	     in 
		write (Id.tostr i);
		write " = ";
		Pp.setb (stdpp());
		Trm.prt (stdpp()) (!global_tenv) trm;
		Pp.break (stdpp()) true ~3;
		write " : ";
		Typ.prt (stdpp()) (!global_tenv) typ;
		Pp.break (stdpp()) true ~3;
		(* write " in ";
		   Typ.prt_tenv (stdpp()) (Typ.pop (!global_tenv)); *)
		Pp.endb (stdpp());
		write "\n";
		global_tenv := Typ.push_binding (!global_tenv) i typ
	     end
	 | Leq(pt1,pt2) =>
	     let val t1 = Typ.debruijnify (!global_tenv) pt1
		 val t2 = Typ.debruijnify (!global_tenv) pt2
	     in 
		if Leq.leq (!global_tenv) t1 t2 
		  then write "Yes\n"
		  else write "No\n"
		end
	 | Nothing => 
	     ()
	 | Set(name,v) => 
	     (set_flag name (string_to_bool v))
	 | _ => 
	   write "Unimplemented ParseResult!\n"
      )
      handle 
	Typ.WrongKindOfId(te,i,which) => 
	    (write ("Wrong kind of identifier: "^ (makestring i) ^" ("
		    ^ which ^ " expected)\nin "); 
	     Typ.prt_tenv (stdpp()) te;
	     error())
      | unknown => 
	    (write ("Exception: "^(System.exn_name unknown)^"\n"); 
	     error())

  and rep_loop_on_file fname =
	   let val (dev,real_name) = FileUtils.open_fmeet_file fname
	       val quit = ref false
	       fun parser() = Parse.stream_parse dev
	       fun done() = (!quit) orelse (end_of_stream dev)
	       fun error() = (quit := true);
	   in 
	      write ("Reading from \"" ^ real_name ^ "\"...\n\n");
	      (rep_loop done parser error;
	       write ("\nClosing " ^ real_name ^ "\n");
	       close_in dev)
	      handle Io(s) => write ("IO error on " ^ fname ^ ": " ^ s ^ "\n")
	   end

  fun top() = 
    let fun top_done () = (print "> "; flush_out std_out; end_of_stream(std_in))
	fun top_error () = ()
    in
      write ("Welcome to FMEET (" ^ buildtime ^ ")...\n\n");
      rep_loop top_done Parse.top_parse top_error;
      write "\n"
    end

  val read_from_file = ref "";

  fun parse_switches ("-i"::s::rest) 
	  = (read_from_file := s;
	     parse_switches rest)
    | parse_switches (s::rest) 
	  = (read_from_file := s;
	     parse_switches rest)
    | parse_switches ([]) 
	  = ()

  fun rep_command_line(argv,env) = 
    (parse_switches (tl argv);
     if (!read_from_file) = ""
	then top()
	else rep_loop_on_file (!read_from_file)
     )

  fun process_file s = rep_command_line (["",s^".fm"],nil);

  end


  functor WrMgt(
	      structure Wr: WR
	      structure Pp: PP
	      sharing Pp.Wr = Wr
	      ) : WRMGT 
	      = struct

  structure Wr = Wr;
  structure Pp = Pp;

  val current_underlying_wr = ref(Wr.to_stdout());
  val current_pp = ref(Pp.pp_from_wr (!current_underlying_wr));
  val current_wr = ref(Pp.wr_from_pp (!current_pp));

  fun stdpp() = !current_pp;

  fun get_current_wr() = !current_wr;

  fun set_current_wr wr =
    (current_underlying_wr := wr;
     current_pp := Pp.pp_from_wr (!current_underlying_wr);
     current_wr := Pp.wr_from_pp (!current_pp))

  fun write s = Pp.pwrite (!current_pp) s;

  end
  functor Id (structure SymTab: HASH
	      structure InvSymTab: TABLE
	      sharing type SymTab.elem = string
		  and type InvSymTab.key = int
	     ) : ID =
  struct

  val symtab = ref SymTab.empty;
  val invsymtab = ref (InvSymTab.empty: string InvSymTab.table);

  val DEBUG = ref false;

  type T = int

  exception CantHappen

  fun intern (s:string) = 
	let val _ = if not (SymTab.exists(s,!symtab))
			   then symtab := SymTab.add(s, (!symtab))
			   else ()
	    val i_opt = SymTab.find (s, (!symtab))
	in
	   case i_opt of
	     NONE => raise CantHappen
	   | SOME(i) => 
	       (invsymtab := InvSymTab.insert((i,s), (!invsymtab));
		i)
	end

  fun hashcode i = i

  exception UnknownId

  fun tostr (i:T) : string = 
	  let val s_opt = InvSymTab.find (i, (!invsymtab))
	  in
	      case s_opt of
		 NONE => raise UnknownId
	       | SOME(s) => s
	  end

  val newvarcount = ref 0;

  fun reset_new_counter() = (newvarcount := 0)

  fun new_from i =
      let val _ = newvarcount := !newvarcount + 1
	  val name = (tostr i) ^ "_" ^ (makestring (!newvarcount))
      in 
	 if SymTab.exists(name,!symtab)
	    then new_from i
	    else intern name
      end

  val id_x = intern "x"

  fun new() = new_from id_x

  fun == (i:T) (i':T) = (i = i')

  fun lexlt (i:T) (i':T) = ((tostr i) < (tostr i'))

  end
  functor FileUtils(): FILEUTILS = struct

  fun open_fmeet_file fname =
	  (open_in fname,fname)
	  handle Io(s) => 
	  (open_in (fname ^ ".fm"), fname ^ ".fm")
	  handle Io(s) => 
	  (open_in ("examples/" ^ fname), "examples/" ^ fname)
	  handle Io(s) => 
	  (open_in ("examples/" ^ fname ^ ".fm"), "examples/" ^ fname ^ ".fm")
	  handle Io(s) => raise Io(fname ^ " not found")

  end
  functor ParseRes 
	      (structure Typ: TYP
	       structure Trm: TRM
	       structure Globals: GLOBALS
	       sharing Typ.Globals = Globals
		   and Trm.Typ = Typ
	      ) : PARSERES 
	      = struct

  structure Typ = Typ
  structure Trm = Trm
  structure Globals = Globals

  datatype T =
      Leq of Typ.pretyp * Typ.pretyp
    | Type_Assumption of Globals.Id.T * Typ.pretyp
    | Type_Abbrev of Globals.Id.T * Typ.pretyp
    | Term_Def of Globals.Id.T * Trm.pretrm
    | Term_Assumption of Globals.Id.T * Typ.pretyp
    | Use of string
    | Set of string * string
    | Nothing

  end 
  (* ----------------------------------------------------------------------- *)
  (*									   *)
  (* Low-level prettyprinting stream package.  Based on notes by Greg Nelson *)
  (*									   *)
  (* ----------------------------------------------------------------------- *)

  functor Pp (structure Wr: WR) : PP =
  struct

  structure Wr = Wr

  (* ----------------------------------------------------------------------- *)
  (*				 Utilities				   *)
  (* ----------------------------------------------------------------------- *)

  val DEBUG = ref false;

  fun debug ss = if (!DEBUG) 
		     then print ((implode ss) ^ "\n")
		     else ()

  fun mapunit f = 
      let fun m ([]) = ()
	    | m (hd::tl) = ((f hd); m tl)
      in m
      end

  (* ----------------------------------------------------------------------- *)
  (*			      Data Structures				   *)
  (* ----------------------------------------------------------------------- *)

  datatype BreakBehavior =
	  NLINDENT of int
	| EXPLICIT of string

  datatype Token = 
	  CHAR of int
	| SETB
	| ENDB
	| BREAK of {united:bool, do_what:BreakBehavior}
	| LONG of string

  datatype RefList =
	  NIL 
	| CONS of Token * (RefList ref)

  exception CalledErrorCont
  val error_cont : unit cont = 
      callcc (fn k => (callcc (fn ek => throw k ek); raise CalledErrorCont))

  exception CoroutineBug
  exception PPQueueOverflowed

  type Pp = {wr:Wr.Wr, 
	    q: Token array,
	    qr: int ref, 
	    inp: int ref, 
	    m1: int ref,
	    m2: int ref,
	    m3: int ref,
	    outq: Token array,
	    outp: int ref,
	    indent: int ref,
	    margin: int ref,
	    empty: unit cont ref,
	    nonempty: unit cont ref}

  val qlen = 500;
  val outqlen = 500;
  val default_margin = 76;

  fun init_pp (wr:Wr.Wr) : Pp = 
      {wr = wr,
       q = array(qlen, CHAR(33)),
       qr = ref 0,
       inp = ref 0,
       m1 = ref 0,
       m2 = ref 0,
       m3 = ref 0,
       outq = array(outqlen, CHAR(33)),
       outp = ref 0,
       indent = ref 0,
       margin = ref default_margin,
       empty = ref(error_cont), 
       nonempty = ref(error_cont)}

  fun enqueue (pp:Pp) tok =
      let val {q=q, qr=qr, inp=inp, m1=m1, empty=empty, nonempty=nonempty, ...} 
	      = pp
	  val curqr = !qr
	  val _ = debug ["enqueue: "," qr=",makestring (!qr),
				     " inp=",makestring (!inp),
				     " m1=",makestring (!m1)]
      in
	 debug ["enqueue"];
	 if ((curqr+1) mod qlen = (!inp)) orelse ((curqr+1) mod qlen = (!m1)) 
	    then raise PPQueueOverflowed
	    else ();
	 update(q, curqr, tok);
	 qr := (curqr + 1) mod qlen;
	 debug ["enqueue: about to switch"];
	 callcc (fn k => (empty := k; throw (!nonempty) ()));
	 debug ["enqueue: returning"]
      end

  fun requeue (pp:Pp) =
      let val {q=q, qr=qr, inp=inp, empty=empty, nonempty=nonempty, m1=m1, ...} 
	      = pp
	  val _ = debug ["requeue: "," qr=",makestring (!qr),
				     " inp=",makestring (!inp),
				     " m1=",makestring (!m1)]
      in 
	 inp := ((!inp) - 1) mod qlen
      end

  fun dequeue (pp:Pp) =
      let val {q=q, qr=qr, inp=inp, empty=empty, nonempty=nonempty, m1=m1, ...} 
	      = pp
	  val _ = debug ["dequeue: "," qr=",makestring (!qr),
				     " inp=",makestring (!inp),
				     " m1=",makestring (!m1)]
	  val _ = (* Front make sure there's something to dequeue *)
		  callcc (fn k => 
			  (debug ["dequeue: checking for input"];
			   if (!inp) = (!qr) 
			       then (debug ["dequeue: blocking"];
				     nonempty := k; 
				     throw (!empty) ())
			   else ()))
	  val _ = debug ["dequeue: unblocked"]
	  val _ = if (!inp)<0 orelse (!inp)>qlen 
		     then print ("About to crash: "^(makestring (!inp))^"\n")
		     else ()
	  val c = q sub (!inp)
	  val _ = inp := ((!inp) + 1) mod qlen
      in 
	 debug ["dequeue: returning"];
	 c
      end

  (* ----------------------------------------------------------------------- *)
  (*				Processing				   *)
  (* ----------------------------------------------------------------------- *)

  exception LineTooLong
  exception HowdThatGetInHere

  fun raw_printline (pp as {wr=wr, outq=outq, outp=outp, ...}:Pp) =
	let val i = ref 0
	in 
	   while ((!i)<(!outp)) do
	     (case outq sub (!i) of
		  CHAR(c) => Wr.write_wr wr (chr c)
		| LONG(s) => Wr.write_wr wr s
		| _ => raise HowdThatGetInHere;
	      i := (!i)+1)
	end 

  fun write_tok (pp as {outq=outq, outp=outp, 
			indent=indent, margin=margin, ...}:Pp) 
		c raiseok =
      let in
	  update (outq,!outp,c);
	  if (!outp) < outqlen 
	     then outp := (!outp)+1
	     else ();
	  case c of
	      CHAR(10) => (raw_printline pp;
			   indent := 0;
			   outp := 0)
	    | _        => (indent := (!indent)+1;
					if (!indent) > (!margin)
					   andalso raiseok
					  then raise LineTooLong 
					  else ())
      end

  fun do_break pp indent (NLINDENT(n)) =
      let val i = ref 0
      in
	write_tok pp (CHAR(10)) true;
	while ((!i)<n+indent) do
	  (write_tok pp (CHAR(32)) true;
	   i := (!i)+1)
      end
    | do_break pp indent (EXPLICIT(s)) =
      mapunit (fn s => enqueue pp (CHAR(ord s))) (explode s)

  fun P1 pp = 
      let fun loop() = 
	       (debug ["P1_loop"];
		case dequeue pp of
		    (c as CHAR(_)) => (write_tok pp c true; loop())
		  | (c as LONG(_)) => (write_tok pp c true; loop())
		  | SETB => (P1 pp; loop())
		  | BREAK(_) => loop()
		  | ENDB => ())
      in debug ["P1"];
	 loop();
	 debug ["P1: finished"]
      end

  and P2 pp = 
      let fun loop() = 
	       (debug ["P2_loop"];
		case dequeue pp of
		    (c as CHAR(_)) => (write_tok pp c true; loop())
		  | (c as LONG(_)) => (write_tok pp c true; loop())
		  | SETB => (P1 pp; loop())
		  | BREAK(_) => ()
		  | ENDB => ())
      in debug ["P2"];
	 loop();
	 (* I think the input queue needs to be backed up by one now, so that
	    P3 sees this SETB or BREAK... *)
	 requeue pp;
	 debug ["P2: finished"]
      end

  and P3 (pp as {inp=inp, outp=outp, indent=indent, 
		 m1=m1, m2=m2, m3=m3, ...} :Pp) = 
      let val saved_indent = !indent
	  fun loop() = 
	       (debug ["P3_loop"];
		case dequeue pp of
		    (c as CHAR(_)) => (write_tok pp c false; loop())
		  | (c as LONG(_)) => (write_tok pp c false; loop())
		  | SETB => (PP pp; loop())
		  | BREAK({united=true,do_what=do_what}) => 
			(do_break pp saved_indent do_what;
			 m1 := ~1; (* Not in CGN's original note *)
			 loop())
		  | BREAK({united=false,do_what=do_what}) => 
			(m1 := (!inp); m2 := (!outp); m3 := (!indent);
			 ((P2 pp; 
			   m1 := ~1; (* This once seemed wrong *)
			   debug ["P3: looping back"]; 
			   loop())
			  handle LineTooLong =>
			     (debug ["P3: line too long"];
			      inp := (!m1); outp := (!m2); indent := (!m3);
			      do_break pp saved_indent do_what;
			      m1 := ~1;
			      loop())))
		  | ENDB => ())
      in debug ["P3"];
	 loop()
      end

  and PP (pp as {inp=inp, outp=outp, indent=indent, 
		 m1=m1, m2=m2, m3=m3, ...} :Pp) = 
      let 
      in debug ["PP"];
	 m1 := (!inp); m2 := (!outp); m3 := (!indent);
	 (P1 pp; m1 := ~1; debug ["PP finished"])
	 handle LineTooLong 
	   => (debug ["PP: line too long"];
	       inp := (!m1); outp := (!m2); indent := (!m3);
	       m1 := ~1;
	       P3 pp)
      end

  exception EndbWithNoMatchingSetb
  fun top_level pp = 
      let 
      in debug ["top_level"];
	 P3 pp;
	 raise EndbWithNoMatchingSetb
      end

  (* ----------------------------------------------------------------------- *)
  (*				Interaction				   *)
  (* ----------------------------------------------------------------------- *)

  fun setb pp = enqueue pp SETB

  fun endb pp = enqueue pp ENDB

  fun break pp b i = enqueue pp (BREAK {united=b, do_what=(NLINDENT i)})

  fun expbreak pp b s = enqueue pp (BREAK {united=b, do_what=(EXPLICIT s)})

  fun pwrite (pp as {wr=wr, ...} : Pp) s = 
      (debug ["write: '", s, "'"];
       mapunit (fn s => case ord(s) of
			  10 => break pp true 0
			| i  => enqueue pp (CHAR(i)))
	       (explode s))

  exception IllegalMargin

  fun set_margin (pp as {margin=margin, outp=outp , ...} : Pp) n =
      if (!outp) > n orelse n >= outqlen
	 then raise IllegalMargin
	 else margin := n

  (* ----------------------------------------------------------------------- *)
  (*				  Creation				   *)
  (* ----------------------------------------------------------------------- *)

  fun pp_from_wr wr =
      let val _ = debug ["new"];
	  val (pp as {empty=empty, ...}:Pp) = init_pp wr
      in 
	 callcc (fn k => (empty := k; top_level pp));
	 pp
      end

  fun wr_from_pp (pp as {wr=wr, ...} : Pp)
      = Wr.to_fn (fn s => pwrite pp s) (fn () => Wr.close wr)

  end (* Functor Pp *)

  functor Wr () : WR =
  struct

  datatype wr = 
	  WR of wr_spc * unit

  and wr_spc = 
	  TO_STDOUT
	| TO_FILE of string * outstream
	| TO_WRS of wr list
	| TO_STRING of string list ref
	| TO_FN of (string->unit) * (unit->unit)
	| TO_NOWHERE 

  type Wr = wr

  fun new spc = WR(spc, ())

  fun to_stdout () = new (TO_STDOUT)

  fun to_file name = 
      let val out = open_out name
      in new (TO_FILE(name,out))
      end

  fun to_wrs wrs = new (TO_WRS(wrs))

  fun to_fn f cl_f = new (TO_FN(f,cl_f))

  fun to_string () = new (TO_STRING(ref([]:string list)))

  fun to_nowhere () = new (TO_NOWHERE)

  exception Not_a_TOSTRING_Wr

  fun extract_str (WR(TO_STRING(ss),_)) = implode (rev (!ss))
    | extract_str _ = raise Not_a_TOSTRING_Wr

  fun mapunit f = 
      let fun m ([]) = ()
	    | m (hd::tl) = ((f hd); m tl)
      in m
      end

  fun close (WR(spc,gen)) = 
      case spc of
	 TO_STDOUT => ()
       | TO_FILE(name,out) => close_out out
       | TO_WRS(wrs) => mapunit close wrs
       | TO_FN(_,cl_f) => cl_f()
       | TO_STRING(ss) => ()
       | TO_NOWHERE => ()

  fun write_wr (WR(spc,gen)) s =
      case spc of
	 TO_STDOUT => output(std_out,s)
       | TO_FILE(_,out) => output(out,s)
       | TO_WRS(wrs) => mapunit (fn wr => write_wr wr s) wrs
       | TO_FN(f,_) => f s
       | TO_STRING(ss) => ss := (s :: (!ss))
       | TO_NOWHERE => ()

  end 

Status: not a bug.  caused by illegal redundancy from include specs.
  See tests/bug406a.sml for shortened example.
---------------------------------------------------------------------------
430. Subscript in lookTycPath
Submitter: Dave MacQueen
Date: 8/3/91
Version: 0.70
Severity: serious
Problem: 
  Following code causes
    $$ lookTycPath 2: [2,0]
    tyconInContext: [2,0]
  messages in d70, indicating Subscript has been raised while
  interpreting a relative type address.
Code: 
  signature S2 =
  sig
    structure A : sig type t end
    datatype u = ITEM of A.t
  end;

  functor F(X : sig type v end ) =
  struct
    type w = X.v
  end;

  functor G(Y : S2) =
  struct
    structure B = F(struct type v = Y.u end)
  end;

Comments:
Problem is bad env passed to redefineCon (typing/functor.sml) during the
application of functor F within the body of G.  The env for the instantiated
body of F is being used to interpret the type of datacon ITEM from the
parameter Y: S2.  lookTycPath aborts with a Subscript exception, which
gets caught by ArrayExt.app in redoTycs.

Status: fixed in 0.73
---------------------------------------------------------------------------
431. ml_writev
Submitter: Dave Tarditi
Date: 7/1/91
Version: 0.69
Severity: minor
Problem: 
    The function ml_writev in cfuns.c for version 0.69 appears to have
    a bug; the reference to callc_v in it should have 1 added to it, since
    callc_v is a label that points to the tag of a closure, not
    the closure itself.  By the way, callc_v is defined in the
    header file prim.h.
Fix:
    The diff of the old version with the new version is below.

    570d569
    < 		extern int callc_v[];
    577,578c576,577
    < 		MLState->ml_closure = PTR_CtoML(callc_v);
    < 		MLState->ml_pc	    = CODE_ADDR(PTR_CtoML(callc_v));
    ---
    > 		MLState->ml_closure = PTR_CtoML(callc_v+1);
    > 		MLState->ml_pc	    = CODE_ADDR(PTR_CtoML(callc_v+1));
Status: Fixed in 0.74 (or earlier).
---------------------------------------------------------------------------
432. corrupted (shell) environment
Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk>
Date: 7/1/91
Version: 0.66
System: Sparc
Problem: 
    NJ SML version 0.66 (running on Sparc) sometimes corrupts its
    environment: after compiling a piece of code, executed sub-processes get
    an environment with (apparently) random characters added to
    environment values. (The specific piece of code is too long to include
    here; I don't know how general the problem is.)
Comment: [dbm] sent mail asking for code to reproduce the problem.
    This is the same as #342.  [Bradfield confirms that problem is fixed in
    0.75 in mail sent 12/5/91.]
Status: fixed in 0.74 (JHR)
---------------------------------------------------------------------------
433. lexgen bug
Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk>
Date: 7/1/91
Version: 0.66
Problem: 
  In the lexgen.sml distributed with 0.66, there is a bug at line
  1047; when outputting the arguments for the "action" function, there
  should be a test for !UsesTrailingContext . If true, should the third
  argument just be nil ?
Status: fixed in 0.74
---------------------------------------------------------------------------
434. interactive input
Submitter: Lawrence Paulson <Larry.Paulson@computer-lab.cambridge.ac.uk>
Date: 1/1/91
Version: 0.66 (and later)
Problem: 
  I think there's something strange with interactive I/O.  Consider the
  following:

  fun prs s = output(std_out,s);
  val pause_tac = Tactic (fn state => 
    (prs"** Press RETURN to continue: ";
     if input(std_in,1) = "\n" then Sequence.single state
     else (prs"Goodbye\n";  Sequence.null)));

  New Jersey ML waits for input and prints the prompt afterwards.  The behavior
  of ML's I/O is not precisely defined, but most languages flush any awaiting
  output before demanding input.

  Really, I would like to accept single-character inputs (rather than lines
  ending with CR) but Standard ML seems to have no suitable primitive!
Status: not really a bug, but a sensible request
---------------------------------------------------------------------------
435. patrow syntax
Submitter:      Matti Jokinen, moj@utu.fi
Date:		28-Jul-1991
Version:        0.69
System:         Sun 3
Severity:       minor

Problem:        The compiler fails to accept the following patrow syntax:

			id:ty as pat

Code:           fun f {x:int as y} = x;

Transcript:     - fun f {x:int as y} = x;
		Error: Compiler bug: patType -- unexpected pattern

Comments:	The following patterns are translated correctly:

			{x = x:int as y}
			{x as y}
			{x:int}

		I think the bug is caused by a missing branch is in the
		patType function (lines 128-194 in src/typing/typecheck.sml).
		The parser appears to transform `id:ty as pat' into
		LAYEREDpat(CONSTAINTpat(_,ty),pat), which is not recognized
		by patType.
Status: fixed in 0.74
---------------------------------------------------------------------------
436. debugger type checking
Submitter:      Sergio Antoy, antoy@cs.pdx.edu
Date:           Jul 1, 1991
Version:        0.66
System:         Sparc IPC, SunOS 4.1.1
Problem:        the debugger reports tycon mismatch on a correct program
Code:
  (* dec (x,l) is the string decimal representation of x over l characters,
     right justified. If l characters are not enough, then l "*" are returned.
     If l <= 0, then an exception is raised. *)
  
  exception wrong_field_size
  fun dec (x, l) =
    if l <= 0
      then raise wrong_field_size
      else 
        let fun dok (0, "") = "0"
              | dok (0, s) = s
              | dok (x, s) = dok (x div 10, chr(x mod 10 + ord("0")) ^ s)
            fun fill (s, l) =
              if size s > l
                then
                  let fun dc 0 = ""
                        | dc l = "*" ^ dc (l-1)
                  in
                    dc l
                  end
                else
                  let fun dc 0 = ""
                        | dc l = " " ^ dc (l-1)
                  in
                    dc (l - size s) ^ s
                  end
        in if x < 0
             then fill ( "-" ^ (dok (~x, "")), l)
             else fill (dok (x, ""), l)
        end
  
Transcript:
  Standard ML of New Jersey, Version 0.66, 15 September 1990
  val it = () : unit
  - emacsInit (); cd "/home/antares/pizza/users/antoy/programs/sml/random-dir/";
  val it = () : unit
  val it = () : unit
  - usedbg "format.sml";
  [opening /home/antares/pizza/users/antoy/programs/sml/random-dir/format.sml]
  
  [Major collection... 63% used (1343748/2106244), 1520 msec]
  
  [Increasing heap to 4104k]
  exception wrong_field_size
  val dec = fn : int * int -> string
  [closing /home/antares/pizza/users/antoy/programs/sml/random-dir/format.sml]
  val it = () : unit
  - run "dec(12,4)";
  [opening <instream>]
  <instream>:1.1-1.9 Error: operator and operand don't agree (tycon mismatch)
    operator domain: int ref
    operand:         int * int
    in expression:
      dec (12,4)
  [closing <instream>]
  - dec(12,4);
  val it = "  12" : string
  - 
Comments:	Under epoch 3.2.4
		The debugger works for a trivial factorial program.


From apt@Princeton.EDU Tue Jul  2 10:28:41 1991
This is indeed a (minor) bug, which I'll handle in due course.
The problem seems to be that the run function is hiding the user's 
(re-)definition of dec with the pervasive Integer.dec.
There is a trivial work-around: call the user function something different.

Status: fixed as of 0.88
---------------------------------------------------------------------------
437. mlyacc syntax problem
Submitter: Andrew Wright <wright@rice.edu>
Date: 7/3/91
Version: 0.69
Problem: 
The source file "yacc.sml" of mlyacc from the 0.69 release does not compile
under the 0.69 release because of a syntax error at line 350:

		     EAPP(EVAR(valueStruct^"."^
			     if hasType (NONTERM lhs)
				  then saySym(NONTERM lhs)
                                  else ntvoid),
Fix:
The "if then else" needs to be parenthesized.

Status: fixed in 0.73
---------------------------------------------------------------------------
438. callcc typing unsound
Submitter: Robert Harper <rwh@proof.ergo.cs.cmu.edu>
Date: 7/3/91
Version: 0.70
Severity: critical
Problem: 
  Recently Mark Lillibridge and I have been trying to investigate a
  number of questions of type soundness in the presence of polymorphism
  and control operators.  As you may recall, I have been unable to find
  a cps transform that (1) is faithful to the ML operational semantics,
  and (2) admits a suitable typing result to guarantee soundness in
  Milner's sense.  We discovered that the central issue is to do with
  the scope of type variables.  This got us to thinking, and late last
  night Mark came up with the following example which demonstrates that
  ML with callcc and polymorphism is UNSOUND.  Run it in SML/NJ to see
  what I mean.  We plan to investigate the matter further, and will keep
  you posted.
Code: 
  fun left (x,y) = x;
  fun right (x,y) = y;

  let val later = (callcc (fn k =>
	  (  fn x => x,  fn f => throw k (f, fn f => ())  ) ))
  in
	  print (left(later)"hello");
	  right(later)(fn x => x+2)
  end
Fix:
  Making the type of callcc weakly polymorphic appears to fix the problem.
Status: fixed in 0.73 (by making callcc weakly polymorphic)
---------------------------------------------------------------------------
439. lexgen
Submitter: Julian Bradfield <jcb@lfcs.edinburgh.ac.uk>
Date: 7/8/91
Version: 0.66
Problem: 
  lexgen.sml distributed with NJ SML 0.66, lines 983 to 986.
  The variable i in the pattern clashes with i in a pattern much higher
  up. I *think* that all occurrences of i in these four lines should be 
  k, say, while the i on line 987 is indeed i.
  (The symptom of this bug is uncaught Substring exceptions, when a
  state identifier gets passed as a length to accept.)

  Has anybody got the look-ahead facility of ML-Lex to work?
Comment: Tarditi noticed that the ASU lookahead algorithm is buggy, so
	 this feature has been removed.
Status: fixed in 0.74
---------------------------------------------------------------------------
440. missing Perv.mos
Submitter:  Matti Jokinen, moj@utu.fi
Date:	    15-Jun-1991
Version:    0.69, 0.70, possibly others
System:     all
Severity:   major

Problem:    File src/runtime/Perv.mos is missing.
	    Consequently, `makeml -pervshare' fails.

Command:    makeml -sun3 sunos -pervshare

Transcript: makeml -sun3 sunos -pervshare
	    ./makeml> (cd runtime; make clean)
	    rm -f *.o lint.out prim.s linkdata allmo.s run
	    ./makeml> rm -f mo
	    ./makeml> ln -s ../mo.m68 mo
	    ./makeml> (cd runtime; rm -f run allmo.o allmo.s)
	    ./makeml> (cd runtime; make MACHINE=M68  'CFL=-n ' 'DEFS= -DBSD -Dsun3 -DSUNOS -
	    DRUNTIME=\"runtime\"' linkdata)
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -DRUNTIME=\"runtime\" -o linkdata linkdata.c
	    (cd runtime; grep -v mo/Math.mo Perv.mos > Tmp.mos)
    --->    grep: Perv.mos: No such file or directory
	    ./makeml> runtime/linkdata [runtime/Tmp.mos]
	    runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
	    ./makeml> (cd runtime; make  MACHINE=M68  'DEFS= -DBSD -Dsun3 -DSUNOS' CPP=/lib/
	    cpp 'CFL=-n ' 'AS=as')
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  run.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  run_ml.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  callgc.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  gc.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  M68.dep.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  export.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  timers.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  ml_objects.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  cfuns.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  cstruct.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  signal.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  exncode.c
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS  -target sun3 -c  malloc.c
	    /lib/cpp -DASM -DM68 -DBSD -Dsun3 -DSUNOS M68.prim.s > prim.s
	    as -o prim.o prim.s
	    cc -O -n -DM68 -DBSD -Dsun3 -DSUNOS -o run run.o run_ml.o callgc.o gc.o M68.dep.
	    o export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o
	    prim.o allmo.o
	    Undefined
	    _datalist
	    *** Error code 2
	    make: Fatal error: Command failed for target `run'

Fix:	    Copy the missing file from distribution 0.66.
Status: fixed in 0.73
---------------------------------------------------------------------------
441. parsing large positive integers
Submitter:      Olaf Burkart <burkart@zeus.informatik.rwth-aachen.de>
Date:           7/16/90
Version:        0.69
System:         SPARC, SunOS 4.1
Problem:
I have found the following bug in sml 0.69:

Can't parse large positive integers.
Can't load the Edinburgh SML Library.

Problem (1):        2^30 - 1 (maxint) could not be read
-----------
Transcript:     

Standard ML of New Jersey, Version 0.69, 3 April 1991
- ~1073741824;
val it = ~1073741824 : int
- 1073741823;

uncaught exception Overflow
- 
Comment: [dbm] Is this the same as bug 327, which is claimed to be fixed in 0.69?
Status: Fixed in 0.72. This is related to bug 327 and 444 [lg].
---------------------------------------------------------------------------
442. Runbind exception
Submitter:      Olaf Burkart <burkart@zeus.informatik.rwth-aachen.de>
Date:           7/16/90
Version:        0.69
System:         SPARC, SunOS 4.1
Problem:
It seems to me that the Runbind error from BUG 262. is back again.
I tried to load the Edinburgh SML Library, but after fixing problem (1)
the sml interpreter aborts with "uncaught exception Runbind" in the structure
definition:

structure Int: INT =
struct
	...
  exception Overflow = Overflow
  and Div = Div
	...
end
Status: probably fixed; can't check without source (related bug 419 is fixed)
---------------------------------------------------------------------------
443. equality attributes in datatype specs
Submitter: Colin Meldrum <colin@harlqn.co.uk>
Date: Wed, 17 Jul 91
Version: 0.66
Problem: 
In New Jersey v66, the following signature does not elaborate:

signature S =
  sig
    type 'a s

    datatype t = A of int -> int

    datatype
      v = D of w s
    and
      w = E of t
  end

It gives the error:

std_in:16.5-24.2 Error: inconsistent equality properties

However, by swapping the two datdesc clauses in the final datatype spec the
signature can be made to elaborate correctly:

signature S =
  sig
    type 'a s

    datatype t = A of int -> int

    datatype
      w = E of t
    and
      v = D of w s
  end

Status: fixed in 0.73
---------------------------------------------------------------------------
444. large constants and Overflow
This is an supplement to the bug:
	327 large constants cause overflow in compilation
	from Apr 23.
Submitter: 
	Juergen Buntrock,
	TU-Berlin,
	jubu@cs.tu-berlin.de
Date: Tue Apr 23 13:50:05 MET DST 1991
Version: 0.70
System: Sun4-60 / SunOS Release 4.1.1
Problem: 
	The function primops in (cps/cpsopt.sml line 658) transforms
	integer compare operation somtimes in arithmetic
	operations which may raise Overflow.

	An example is function sizeImmed (in sparc/sparc.sml).
	This functions raise an Overflow  for constant values
	bigger than (maxinit-4096)


Script:
Script started on Tue Jul 30 12:57:30 1991
jubu@flp 1) smln70
Standard ML of New Jersey, Version 0.70, 1 July 1991
val it = () : unit
- structure TT = struct
=     datatype A = A | B
=     fun sizeImmed n = if (~4096 <= n) andalso(n < 4096)
=         then A else B
=     val sizeImmed = fn n =>
=         (sizeImmed n) handle Overflow => (
=             outputc std_out (implode[
=                 "sizeImmed(",makestring n,
=                 ") overflow!\n"]);
=             raise Overflow )
=     val x = 107374182
=     val z = (sizeImmed (x * 10 + 2))
=     end
= ;
sizeImmed(1073741822) overflow!

uncaught exception Overflow

Status: Fixed in 0.72. This is had to do with an illegal 
        optimization and a bug in the sparc code generator [lg].
---------------------------------------------------------------------------
445. spurious error report
Submitter: Andrew Tolmach <apt@cs.princeton.edu>
Date: 7/30/91
Version: 0.70
Problem: 
  Following produces a spurious error in 0.70.
Code: 

  signature  T = 
  sig
   datatype debuglevel = A of instream option
  end

Status: fixed in 0.73
---------------------------------------------------------------------------
446. Compiler bug
Submitter:      jont%uk.co.harlqn@uk.ac.ukc
Date:		01/08/91
Version:        SML of NJ version number 0.66
System:         Sun 4/330 with SunOS 4.1.1
Severity:       minor
Problem:        Compiler warns of compiler bug in compiling some
		incorrect code
Code:
(* _mirprint.sml the functor *)
(*
$Log:	_mirprint.sml,v $
Revision 1.3  91/07/30  16:22:11  jont
Printed more opcodes (branch and cgt)

Revision 1.2  91/07/26  20:00:13  jont
Redid some printing in light of changes in mirtypes

Revision 1.1  91/07/25  15:45:09  jont
Initial revision

Copyright (c) 1991 Harlequin Ltd.
*)

require "../utils/integer";
require "../basics/identprint";
require "../lambda/pretty";
require "../lambda/lambdasub";
require "mirtypes";
require "mirprint";

functor MirPrint(
  structure Integer : INTEGER
  structure IdentPrint : IDENTPRINT
  structure MirTypes : MIRTYPES
  structure Pretty : PRETTY
  structure LambdaSub : LAMBDASUB
  sharing IdentPrint.Ident = MirTypes.Ident
  hsaring MirTypes.LambdaTypes = LambdaSub.LambdaTypes
) : MIRPRINT =
struct
  structure MirTypes = MirTypes
  structure P = Pretty

  exception pretty_not_done_yet

  fun decode_binary MirTypes.ADD = "ADD "
  | decode_binary MirTypes.SUB = "SUB "
  | decode_binary MirTypes.MUL = "MUL "
  | decode_binary MirTypes.DIV = "DIV "
  | decode_binary MirTypes.REM = "REM "
  | decode_binary MirTypes.AND = "AND "
  | decode_binary MirTypes.OR = "OR "
  | decode_binary MirTypes.EOR = "EOR "
  | decode_binary MirTypes.SHL = "SHL "
  | decode_binary MirTypes.SHR = "SHR "
  | decode_binary MirTypes.SHRL = "SHRL "
  | decode_binary MirTypes.DIVL = "DIVL "
  | decode_binary MirTypes.REML = "REML "

  fun decode_unary MirTypes.CMP = "CMP "
  | decode_unary MirTypes.CMPL = "CMPL "
  | decode_unary MirTypes.MOV = "MOV "
  | decode_unary MirTypes.NEG = "NEG "
  | decode_unary MirTypes.NOT = "NOT "

  fun decode_store MirTypes.LDX = "LDX "
  | decode_store MirTypes.STX = "STX "

  fun decode_allocate MirTypes.ALLOC = "ALLOC "
  | decode_allocate MirTypes.ALLOC_REAL = "ALLOC_REAL "
  | decode_allocate MirTypes.ALLOC_STRING = "ALLOC_STRING "

  fun decode_branch MirTypes.BRA = "BRA "
  | decode_branch MirTypes.BEQ = "BEQ "
  | decode_branch MirTypes.BNE = "BNE "
  | decode_branch MirTypes.BHI = "BHI "
  | decode_branch MirTypes.BLS = "BLS "
  | decode_branch MirTypes.BHS = "BHS "
  | decode_branch MirTypes.BLO = "BLO "
  | decode_branch MirTypes.BGT = "BGT "
  | decode_branch MirTypes.BLE = "BLE "
  | decode_branch MirTypes.BGE = "BGE "
  | decode_branch MirTypes.BLT = "BLT "
  | decode_branch MirTypes.BVS = "BVS "
  | decode_branch MirTypes.BVC = "BVC "
  | decode_branch MirTypes.BMI = "BMI "
  | decode_branch MirTypes.BPL = "BPL "

  fun decode_adr MirTypes.LEA = "LEA "

  fun decode_real_gc(MirTypes.GC_REAL gc_reg) =
    "REG " ^ MirTypes.print_gc_register gc_reg
  | decode_real_gc(MirTypes.GC_SPILL i) =
    "SPILL " ^ Integer.makestring i

  fun decode_real_non_gc(MirTypes.NON_GC_REAL gc_reg) =
    "REG " ^ MirTypes.print_non_gc_register gc_reg
  | decode_real_non_gc(MirTypes.NON_GC_SPILL i) =
    "SPILL " ^ Integer.makestring i

  fun decode_reg_operand(MirTypes.GC_REG(gc_reg, real_gc_reg_opt)) =
    "GC(" ^ MirTypes.print_gc_register gc_reg ^
    (case real_gc_reg_opt of
      MirTypes.ABSENT => ""
    | MirTypes.PRESENT real_gc => decode_real_gc real_gc)
    ^ ") "
  | decode_reg_operand(MirTypes.NON_GC_REG(non_gc_reg, real_non_gc_reg_opt)) =
    "NON_GC(" ^ MirTypes.print_non_gc_register non_gc_reg ^
    (case real_non_gc_reg_opt of
      MirTypes.ABSENT => ""
    | MirTypes.PRESENT real_non_gc => decode_real_non_gc real_non_gc)
    ^ ") "

  fun decode_gp_op(MirTypes.GP_GC_REG(gc_reg, real_gc_reg_opt)) =
    "GC(" ^ MirTypes.print_gc_register gc_reg ^
    (case real_gc_reg_opt of
      MirTypes.ABSENT => ""
    | MirTypes.PRESENT real_gc => decode_real_gc real_gc)
    ^ ") "
  | decode_gp_op(MirTypes.GP_NON_GC_REG(non_gc_reg, real_non_gc_reg_opt)) =
    "NON_GC(" ^ MirTypes.print_non_gc_register non_gc_reg ^
    (case real_non_gc_reg_opt of
      MirTypes.ABSENT => ""
    | MirTypes.PRESENT real_non_gc => decode_real_non_gc real_non_gc)
    ^ ") "
  | decode_gp_op(MirTypes.GP_IMM_INT imm) =
    "Int(" ^ Integer.makestring imm ^ ") "
  | decode_gp_op(MirTypes.GP_IMM_ANY imm) =
    "Any(" ^ Integer.makestring imm ^ ") "

  fun decode_op(MirTypes.BINARY(binary_op, reg_op, gp_op1, gp_op2)) =
    decode_binary binary_op ^ decode_reg_operand reg_op ^
    decode_gp_op gp_op1 ^ decode_gp_op gp_op2
  | decode_op(MirTypes.UNARY(unary_op, reg_op, gp_op)) =
    decode_unary unary_op ^ decode_reg_operand reg_op ^ decode_gp_op gp_op
  | decode_op(MirTypes.STOREOP(store_op, reg_op1, reg_op2, gp_op)) =
    decode_store store_op ^ decode_reg_operand reg_op1 ^
    decode_reg_operand reg_op2 ^ decode_gp_op gp_op
  | decode_op(MirTypes.ALLOCATE(allocate, gc_reg, imm)) =
    decode_allocate allocate ^ "GC(" ^ MirTypes.print_gc_register gc_reg ^
    ") " ^
    (case allocate of MirTypes.ALLOC_REAL => "" | _ => Integer.makestring imm)
  | decode_op(MirTypes.BRANCH(branch, tag)) =
    decode_branch branch ^ MirTypes.print_tag tag
  | decode_op(MirTypes.SWITCH(cgt, reg_op, tag_list)) =
    LambdaSub.reduce_left
    (fn (s, tag) => s ^ " " ^ MirTypes.print_tag tag)
    ("CGT " ^ decode_reg_operand reg_op, tag_list)
  | decode_op(MirTypes.VALUE scon) = (case scon of
      IdentPrint.Ident.REAL _ => "Real "
    | IdentPrint.Ident.STRING _ => "String "
    | _ => raise(LambdaSub.LambdaTypes.impossible"VALUE(int)")) ^ 
    IdentPrint.printSCon scon
  | decode_op(MirTypes.ADR(adr, reg_op, tag)) =
    decode_adr adr ^ decode_reg_operand reg_op ^ " " ^ MirTypes.print_tag tag
    (* Information points *)
  | decode_op(MirTypes.LOC_REF tag_list) =
    LambdaSub.reduce_left op ^
    ("Local references\n",
      map (fn tag => MirTypes.print_tag tag ^ " ") tag_list)
  | decode_op MirTypes.END = "End of code"
  | decode_op _ = raise(pretty_not_done_yet)
(*
  | decode_op(MirTypes.BINARYFP of binary_fp_op * fp_register * fp_register * fp_operand |
  | decode_op(MirTypes.UNARYFP of unary_fp_op * fp_register * fp_operand |
  | decode_op(MirTypes.STACKOP of stack_op * reg_operand |
  | decode_op(MirTypes.STOREFPOP of store_fp_op * fp_register * reg_operand * gp_operand |
  | decode_op(MirTypes.CONVOP of int_to_float * fp_register * reg_operand |
  | decode_op(MirTypes.BRANCH_AND_LINK of branch_and_link * bl_dest |
  | decode_op(MirTypes.INIT of any_register | (* Register is initialised here *)
  | decode_op(MirTypes.USE of any_register | (* Register is used here *)
  | decode_op(MirTypes.ENTER of int * reg_operand |
    (* Entry point for procedure, with n locals and arg reg *)
  | decode_op(MirTypes.EXIT of reg_operand | (* Return point from procedure, result in reg *)
    (* Data *)
*)

  fun decode_block(MirTypes.BLOCK(tag, op_list)) =
    P.blk(0, P.lst("", [P.nl], "")
      (P.blk(2, [P.str("Tag "), P.str(MirTypes.print_tag tag)]) ::
        (map (fn x => P.str("  " ^ decode_op x)) op_list)))

  fun print_mir_code(MirTypes.CODE block_list) =
    P.string_of_T(P.blk(0, P.lst("", [P.nl], "")
			(map decode_block block_list)))
end

Transcript:
make "../mir/_mirprint.sml";
[opening /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml]
val it = () : unit
val it = () : unit
val it = () : unit
val it = () : unit
val it = () : unit
val it = () : unit
/home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.9 Error: syntax error: inserting OPEN
/home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.54 Error: unbound structure in signature: hsaring
/home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml:30.3-30.54 Error: unbound structure in signature: MirTypes.LambdaTypes
Error: Compiler bug: lookPathSTRinSig.get
[closing /home/ml/jont/ml/ml_compiler/src/mir/_mirprint.sml]

Comments:	The code is incorrect, but it shouldn't cause the
compiler to claim it has a bug in itself! The cause seems somewhat
related to the fact that MirTypes has no substructure LambdaTypes,
simply misspelling sharing on a line which is an otherwise valid
sharing constraint line does not exhibit the problem.

Status: possibly fixed in 0.73?  (incomplete source, can't test)
---------------------------------------------------------------------------
447. identity type abbreviation
Submitter:      tmb@ai.mit.edu
Date:           08/02/91
Version:        0.70
System:         Sun4/OS4.1.1
Severity:       ?
Problem:        the type checker refuses to accept the following definition
Code:

structure S =
    struct
	type 'b data = 'b list
	type 'b value = 'b
	fun at(x:'b data):'b value = hd x
    end;

Transcript:

   hack.sml:5.2-5.34 Error: expression and constraint don't agree (bound type var)
     expression: 'bU
     constraint: 'bU value
     in expression:
       Initial.hd x

Comments:

   I'm not sure whether this is a bug, but certain types of functors
   seem to be difficult to express if you cannot write definitions like
   this.

   In particular, it seems like I have to write two separate functors
   depending on whether "'b value" is simply "'b" or whether it
   is some other type dependent on "'b" (e.g., "'b list"). This
   seems very unnatural.

signature S =
    sig
	type 'a data
	type 'a value
	val at: 'b data -> 'b value
    end;

functor F(structure X:S) =
    struct
	open X
	fun pair_at x = (at x,at x)
    end;

structure A =
    struct
	type 'a data = 'a list
	type 'a value = 'a list
	val at = (fn x => x)
    end;

structure FA = F(structure X = A);
    
structure B =
    struct
	type 'a data = 'a list
	type 'a value = 'a
	val at = hd
    end;

(* why can't I do this??? *)

structure FB = F(structure X = B);
Fix: type abbreviations must be expanded when unifying with UBOUND type variables
     in Unify (basics/unify.sml).  The definition of equalTypes in TypesUtil
     must be changed in a similar manner.
Status: fixed in 0.74
---------------------------------------------------------------------------
448. failure to build on MIPS 6280
Submitter: Dave MacQueen
Date: 8/10/91
Version: 0.71
System: MIPS 6280, RISCOS 4.52
Severity: critical (for 6280)
Problem: failure while trying to bootstap the compiler
Transcript: 
  % makeml -mips riscos -batch -m 60000 
  makeml> (cd runtime; make clean)
	  rm -f *.o lint.out prim.s linkdata allmo.s run
  makeml> rm -f mo
  makeml> ln -s ../mo.mipsb mo
  makeml> (cd runtime; rm -f run allmo.o allmo.s)
  makeml> (cd runtime; make MACHINE=MIPS  'CFL= -systype bsd43' 'LIBS=' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata)
	  cc -O -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c
  makeml> runtime/linkdata [runtime/CompMipsBig.mos]
  runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
  makeml> (cd runtime; make  MACHINE=MIPS  'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as' 'LIBS=')
	  cc -O -systype bsd43 -DMIPS -DRISCos -c run.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c run_ml.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c callgc.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c gc.c

  uopt: Warning: gc: this procedure not optimized because it
	exceeds size threshold; to optimize this procedure, use -Olimit option
	with value >=  553.
	  cc -O -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c export.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c timers.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c ml_objects.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c cfuns.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c cstruct.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c signal.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c exncode.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c malloc.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c mp.c
	  cc -O -systype bsd43 -DMIPS -DRISCos -c sync.c
	  /lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s
	  as -o prim.o prim.s
  as0: Warning: prim.s, line 281: missing .end preceding this .ent: set_request
	.ent set_request
  as0: Warning: prim.s, line 281: .ent/.end block never defined the procedure name
  as0: Warning: prim.s, line 407: missing .end preceding this .ent: go
	.ent go
	  cc -O -systype bsd43 -DMIPS -DRISCos -o run run.o run_ml.o callgc.o gc.o MIPS.dep.o export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o  mp.o sync.o prim.o allmo.o 
  makeml> runtime/run -m 60000 -r 5 -h 2048 CompMipsBig

  [Increasing heap to 2048k]
  [Loading mo/CoreFunc.mo]
  [Executing mo/CoreFunc.mo]
  [Loading mo/Math.mo]
  [Executing mo/Math.mo]
  [Loading mo/Initial.mo]
  [Executing mo/Initial.mo]
  Uncaught exception CFunNotFound with "argv"
  9.2u 7.8s 1:22 20% 182+737k 1269+1532io 2586pf+0w

Comments:
  The as0 warnings should be eliminated, and the -Olimit flag added or changed
  so that the gc code can be optimized.
Status: Fixed in 0.78
---------------------------------------------------------------------------
449. poor error message for mismatching datatype spec
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Mar 5 1991
Version: 0.66-0.69
Severity: minor
Problem: 

Here is another example of an error message that doesn't give enough
info:

  user/drawing.sml:9.3-12.5 Error: mismatching datatype spec: pen_val_t

In this case, pen_val_t has ~30 variants; figuring out the mismatch is
a pain.  This is like the problem with large labeled records.
  - John
Status: fixed in 0.91 (dbm)
---------------------------------------------------------------------------
450. Compiler bug: tycPath
Submitter: Andy Koenig (dopey!ark)
Date: 10/16/91
Version: 0.66
Severity: minor
Problem: After an unmatched type spec there is a Compiler bug message.
Transcript: 
  - signature I = sig type T end;
  signature I =
    sig
      type T
    end
  - abstraction J : I = struct type u = int end;
  std_in:1.21-1.43 Error: unmatched type spec: T
  Error: Compiler bug: tycPath
Status: fixed in 0.74
---------------------------------------------------------------------------
451. sharing constraints
Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk>
Date: 10/29/91
Version: 0.73
Severity: serious
Problem: 
  SML/NJ 0.73 gets the sharing constraints wrong in the following ML.
Code: 
  signature A = sig structure Base:sig end end;

  signature P = sig end;

  functor A (structure P:P) : A =
  struct
    structure Base = P;
  end;

  signature B = sig structure Base:sig end end;

  functor B (structure P:P structure A:A sharing P = A.Base ) : B =
  struct
    structure Base = P;
  end;

  functor Q(structure P : P
	    structure A : A 
	    structure B : B 
	    sharing P = A.Base = B.Base) = struct end ;

  structure P = struct end ;

  structure A = A(structure P = P);
  structure B = B(structure P = P structure A = A);

  structure Q = Q(structure P = P
		  structure A = A
		  structure B = B);

Status: fixed in 0.75
---------------------------------------------------------------------------
452. finding out what is in a structure
Submitter:      Tim Freeman, tsf@cs.cmu.edu
Date:		Wed Oct 30 15:30:02 1991
Version:        0.74
System:         Sun 4
Severity:       minor but chronic
Problem:        I used to be able to find out what was in a structure
		by opening it up.  Now there is apparently no way to
		remind myself of what is in a structure other than by
		reading the source.
Transcript:     - structure x = SourceGroup;
		structure x : SOURCEGROUP
		(* This used to tell me all of the things in the
		SourceGroup structure. *)
		- open x;
		open x
		(* I would be just as happy if this printed out the
		information I want too. *)
Comments:	Maybe this feature should have its own name, instead
		of hanging off of top level structure declarations.
---------------------------------------------------------------------------
453. unhandled exception crashes sml
Submitter:      Tim Freeman <tsf@cs.cmu.edu>
Date:		Thu Oct 31 15:32:46 1991
Version:        0.74
System:         Sun 4 running some version of Mach
Severity:       minor
Problem:        With some manipulations of structures, raising
		unhandled exceptions causes SML to bomb.
Code:           bug3.sml contains:
		structure Util = 
		    struct
			exception Bug of string
		    end
		
		structure InstProto = 
		struct
		    structure U = Util
		    structure S = struct end 
		end 
		
		open InstProto
		;
		raise U.Bug "hi"

Transcript:     % sml
		Standard ML of New Jersey, Version 0.74, 10 October, 1991
		Prerelease version.  Arrays have changed; see doc/NEWS
		val it = () : unit
		- use "bug3.sml";
		[opening bug3.sml]
		structure Util : 
		  sig
		    exception Bug of string
		  end
		structure InstProto : 
		  sig
		    structure S : ...
		    structure U : ...
		  end
		open InstProto
		SIGILL code 0x7
		% 				
Comments:	Earlier during the process of narrowing down this bug,
		it was saying 

			uncaught exception random binary garbage

		(except you have to imagine the string "random binary
		garbage" replaced by random binary garbage) instead of
		getting the SIGILL trap. 
Status: fixed in 0.75
---------------------------------------------------------------------------
454. running out of memory
Submitter: Andy Koenig
Date: 11/7/91
Version: 0.74
System: SPARCstation, 64MB
Severity: minor
Problem: 
  SML-NJ is not very nice about handling memory exhaustion.
Transcript: 

	[boojum] sml
	Standard ML of New Jersey, Version 0.74, 10 October, 1991
	Prerelease version.  Arrays have changed; see doc/NEWS
	val it = () : unit
	- fun f x = f(0::x);
	val f = fn : int list -> 'a
	- f nil;

	[Increasing heap to 3164k]

	[Increasing heap to 4452k]

	[Increasing heap to 5456k]

	[Major collection...
	[Increasing heap to 8192k]
	 76% used (3427160/4508104), 2610 msec]

	[Increasing heap to 13192k]

	[Major collection... 49% used (4497848/8999168), 4600 msec]

	[Increasing heap to 26380k]

	[Major collection... 49% used (8999168/18002072), 9250 msec]

	[Increasing heap to 27204k]

	[Major collection...
	[Increasing heap to 27620k]

	[Increasing heap to 27776k]

	[Increasing heap to 27860k]

	[Increasing heap to 27880k]

	Warning: can't increase heap

	Ran out of memory[boojum] 
Comments:
    While I do ultimately expect some kind of drastic termination,
    I do **NOT** expect to be unceremoniously dumped out of ML back
    into the Shell.  A more reasonable strategy might be to preallocate
    a chunk of memory to be used as secondary storage while recovering
    from exhaustion of primary storage.  That, at least, would allow
    for a return to top level and associated garbage collection, which,
    in many cases, would allow interactive execution to resume.

    Incidentally, this example was run on a Sparcstation with 64
    megabytes of physical memory and no limit on process size
    that I know of.  I don't know why it gave up the ghost at
    28 megabytes -- do you?
Status: open
---------------------------------------------------------------------------
455. handling Real.Div
Submitter:      olender@cs.colostate.edu <Kurt Olender>
Date:           Nov. 11, 1991
Version:        0.75
System:         Sparcstation-2/SunOS 4.1.1
Severity:       minor
Problem:        cannot handle Real.Div exception
Code:           1.0/0.0 handle Real.Div => 10.0;
Transcript:     
        (* At top level *)
        (* Integer works *)
        - 1 div 0 handle Integer.Div => 10;
        val it = 10 : int

        (* Real doesn't *)
        - 1.0/0.0 handle Real.Div => 10.0;

        uncaught exception Div

        (* Even when I don't specify the name *)
        - 1.0/0.0 handle _ => 10.0;

        uncaught exception Div
Fix:
  This was a bug in the scheduler dependencies for the SPARC.
Status: fixed in 0.76
---------------------------------------------------------------------------
456. signals on SPARC cause heap corruption
Submitter:      tyan@cs.cornell.edu & Greg_Morrisett@CS.CMU.EDU
Date:           Nov. 20, 1991
Version:        0.75 (and earlier)
System:         Sparc
Severity:       minor
Problem:        programs using signals to do pre-emption get corrupted heaps.
Code:
(* A simple preemptive thread structure *)
structure T =
    struct
	(* Queues *)
	type '1a queue = ('1a list ref * '1a list ref)
	fun create () = (ref [], ref [])
	fun enq ((f,r), x) = r := x :: (!r)
	fun deq (f,r) = 
	    (case (!f) of
		 (hd::tl) => (f := tl; SOME hd)
	       | [] => (case (rev (!r)) of
			    (hd::tl) => (f := tl; r := [];
					 SOME hd)
			  | [] => NONE))

	(* Flag for atomicity *)
	val atomic = ref false

	(* Ready queue *)
	val ready : unit cont queue = create ()

	exception Deadlock

	fun enterAtomic () = atomic := true
	fun leaveAtomic () = atomic := false

	fun reschedule k = enq (ready, k)

	fun get_next () = 
	    case (deq ready) of
		NONE => raise Deadlock
	      | SOME k => k

	(* fork a thread *)
	fun fork f =
	    (enterAtomic ();
	     callcc (fn c => (reschedule c;
			      leaveAtomic ();
			      f ();
			      enterAtomic ();
			      throw (get_next ()) ()));
	     leaveAtomic ())

	fun prepend f kont = 
	    (callcc (fn c => (callcc (fn k => (throw c k));
			      f ();
			      throw kont ())))

	(* context switch signal handler *)
	fun handler (n,kont) = 
	    if (!atomic) then (kont)
	    else
		(enterAtomic ();
		 reschedule (prepend leaveAtomic kont);
		 get_next ())

	local
	    open System.Signals System.Timer System.Unsafe.CInterface
	    val t0 = TIME {sec=0,usec=0}
	in
	    val _ = setHandler (SIGALRM, SOME handler)

	    fun setPreempt NONE = setitimer(0,t0,t0)
	      | setPreempt (SOME t) =
		let val t = TIME {sec=0,usec=1000*t}
		in
		    setitimer(0,t,t)
		end
	end

    end

fun spin_alloc l = spin_alloc (rev l);  (* make sure we fool compiler *)
fun spin () = spin_alloc [1,2];

fun bug () = (T.setPreempt (SOME 50);
	      T.fork spin; T.fork spin; T.fork spin)

Fix:
  The problem was that the SPARC has no callee saved FP registers, so the
  resumption continuation was pointing to its own descriptor.

Status: fixed in 0.76
---------------------------------------------------------------------------
457. Real.ceiling has wrong type
Submitter:      Lal George
Date:           Nov. 22, 1991
Version:        0.75 (and earlier)
System:         all
Severity:       minor
Problem:        Real.ceiling has wrong type
Code:
  - ceiling;
  val it = fn : real -> 'a
Remark:
  yet another example of the brain damage in perv.sml
Status: fixed in 0.76
---------------------------------------------------------------------------
458. incorrect 'Warning: binding not exhaustive' message
Submitter:      Lal George
Date:		Nov. 27, 1991
Version:        0.75 (and earlier)
System:         all
Severity:       minor
Code:           

	datatype register = Reg of int | Freg of int
	datatype ea = Direct of register | Immed of int 
	val dataptr as Direct dataptr' = Direct(Reg 23)

Transcript: 
    
- val dataptr as Direct dataptr' = Direct(Reg 23);
std_in:4.1-4.47 Warning: binding not exhaustive
        dataptr as Direct dataptr' = ...
val dataptr = Direct (Reg 23) : ea
val dataptr' = Reg 23 : register
Comment: [dbm] Further static analysis could verify that this
  pattern would be matched, but this analysis is not done.
Status: not a bug
---------------------------------------------------------------------------
459. signature matching
Submitter:      Robert Thau, rst@ai.mit.edu
Date:           10 December 1991
Version:        75
System:         Sparcstation 1 / SunOS 4.1.1
Severity:       
Problem:        The following two lines of admittedly questionable
		code seem to throw the SML/NJ compiler into a loop,
		madly consing with no apparent end in sight.

Code:           
	signature foosig = sig val foo: 'a -> int end;
	structure foostruct:foosig = struct fun foo x = x end;

Status: fixed in 0.80 (or earlier)
---------------------------------------------------------------------------
460. signature matching
Submitter:	Tsung-Min Kuo	(email : kuo@ecrc.de)
Date:		Dec 12, 1991
Version:        Version 0.75, November 11, 1991
System:         SPARCstation 1, SUNOS 4.1
Severity:	VERY severe
Problem:        Compiler blowup --- use up 24M heap
Code:
	signature A = sig val s : (unit -> 'a) -> unit end
	structure A : A = struct fun s f = f() end

Transcript:

	Standard ML of New Jersey, Version 75, November 11, 1991
	Arrays have changed; see Release Notes
	val it = () : unit
	- signature A = sig val s : (unit -> 'a) -> unit end;
	signature A = 
	  sig
	    val s : (unit -> 'a) -> unit
	  end
	- structure A : A = struct fun s f = f() end;
	
	[Increasing heap to 10003k]
	
	[Major collection... 69% used (3607244/5171504), 6790 msec]
	
	[Increasing heap to 15147k]
	
	[Major collection...
	[Increasing heap to 23187k]
	 80% used (7597900/9458020), 12920 msec]
	
	[Increasing heap to 23467k]
	
	[Major collection... 73% used (9457996/12885048), 17240 msec]
	
	[Increasing heap to 23575k]
	
	2[Major collection...
	[Increasing heap to 23647k]
	
	Warning: can't increase heap
	
	Ran out of memory

Comments: The signature was wrong. But, instead of reporting spec mismatch,
	  it keeps on doing heap allocation until runs out of memory.
	  By fixing the signature, or by avoiding signature constraint on
	  the structure definition, we can get around the bug.
	  The old version (0.66) seems working correctly on this example.

Submitter:      Francois Bourdoncle <bourdoncle@prl.dec.com>
Date:           3/13/92
Version:        0.75
System:         Ultrix 4.2 on a DECstation 5200 (but also VAX 8600)
Problem:        compiler loops on erroneous signature matching
Code:

	signature SIG =
	  sig
	    val F : 'a -> unit
	  end
	
	structure S : SIG =
	  struct
	    fun F x = x
	  end;

Transcript:

	Standard ML of New Jersey, Version 75, November 11, 1991
	Arrays have changed; see Release Notes
	val it = () : unit
	- use "bug.sml";
	[opening bug.sml]
	
	[Increasing heap to 4058k]
	
	[Increasing heap to 7678k]
	
	[Increasing heap to 14398k]
	
	[Increasing heap to 16386k]
	
	[Major collection... 69% used (5815684/8396812), 7367 msec]
	
	[Increasing heap to 24602k]
	^C[closing bug.sml]

	Interrupt
	- ^C

Status: fixed in 0.80 (or earlier)
---------------------------------------------------------------------------
461. overloading and weak polymorphism
Submitter:      jont@uk.co.harlqn
Date:
Version:        SML of NJ version number, 0.75
System:         Sun 4/330 with SunOS 4.1.1
Severity:       minor
Problem:        Problem with weak type variables
Code:

    local
      val x = ref nil
    in
      fun define(y: string list) = x := y
    end;

Transcript:
    - use "bug461.sml";
    bug461.sml:5.3-5.17 Error: nongeneric weak type variable
      x : '0Z list ref
    [closing bug461.sml]

Comments: 0.66 accepted this quite happily. As far as I can see,
  there is no problem deducing the type of overloads

Status: fixed in 0.89
---------------------------------------------------------------------------
462. location info in inexhaustive pattern warnings
Submitter: Bob Harper (Robert_Harper@cs.cmu.edu)
Date: 12/4/91
Version: 0.75
Problem: 
    My inexhaustive pattern warnings come out thus these days:

    .../src/type-check.sml:0.0-0.0 Warning: match not exhaustive

    The line and column number are not 0!  The messages always have 0 for both.
Comment: Is marking turned off?
Status: fixed in 0.89
---------------------------------------------------------------------------
463. unmatched datatype in signature matching
Submitter : Sylvie Thiebaux  sylvie@gmd.de
Date 10 - 07 - 91
Version SML 0.66
Severity major (critical ?)
Problem :  unmatched datatype
Code :
I cannot narrow down the cause of the problem more than I have already done.
I have got several files in which I let only the necessary things. All the
files excpeted the main file can be compliled. When I compile the main file
I get the error ``unmatched datatype literal'' at the point indicated in the
program. It is maybe a problem of a sharing constraint on this type that I have given in the file LOGIC.sml. But I have already used the LOGIC signature
in a larger programm and this sharing constraint seemed to cause no problem.

Here are all the modules involved in the error message. Please do not be
surprised about what each module contains. I need each of them but I wanted to
let in each of them only the minimal necessary code in order to make your task
easier.

(*file ELEMENT.sml*)
signature ELEMENT =
    sig
	type element
	val  put : outstream -> element -> unit 
    end

(************************************************************)

(*file EQ.sml*)
import "ELEMENT";

signature EQ =
    sig
	include ELEMENT
	val eq : element -> element -> bool
    end

(**********************************************************)

(*file SET.sml*)
import "EQ";

signature SET =
    sig
	structure Eq : EQ
        type element
	    sharing type element = Eq.element
        type set;
        val empty_set : set (* unrelated to the error *)
    end

(**********************************************************)

(*file ListSet.sml*)
import "EQ";
import "SET";

functor ListSet (Eq' :EQ)  : SET  =  
    struct 
	structure Eq = Eq'
	type element = Eq.element
	type set = element list
	val empty_set :set = []
    end

(********************************************************)

(* file ATOMS.sml *)

signature ATOMS =
    sig
	type term
	type atom
	val eq_at : atom -> atom -> bool
	val put_at : outstream -> atom -> unit
    end

(******************************************************)

(*file LOGIC.sml*)
import "SET";
import "ATOMS";

signature LOGIC =
    sig
	structure At : ATOMS

	datatype literal =
	    False 
	  | True 
	  | neg of At.atom 
	  | pos of At.atom

	 type conj_set
	 structure CS : SET
	 
	 sharing type literal = CS.element (* if you remove this sharing
constraint, the error does not exist any more. But I need this constraint
and anyway, it caused no problem whith other big programms including this
signature *)
	     and type conj_set = CS.set
  end

(************************************************************************)

(*file Logic.sml*)
import "ListSet";
import "ATOMS";
import "LOGIC";

functor Logic ( atoms : ATOMS ) : LOGIC =
    struct
	structure At = atoms

	datatype literal =
	    pos of At.atom
	  | neg of At.atom
	  | True
	  | False

	fun put_lit os (pos at) =
	    At.put_at os at
	  | put_lit os (neg at) = 
	    ((output (os,"-"));
	     (At.put_at os at))
	  | put_lit os (True) =
	    output(os,"true")
	  | put_lit os (False) =
	    output(os,"false")
    
	fun eq_lit (pos at1 :literal) (pos at2 :literal) =
	    At.eq_at at1 at2
	  | eq_lit (neg at1 :literal) (neg at2 :literal) =
	    At.eq_at at1 at2
	  | eq_lit True True =
	    true
	  | eq_lit False False =
	    true
	  | eq_lit _ _ =
	    false

	structure CS = ListSet (struct
				    type element = literal
				    val eq = eq_lit
				    val put = put_lit
				end)
	type conj_set = CS.set
    end

(*****************************************************************)

(*file LOGIC_JUSTIF.sml*)
import "LOGIC";

signature LOGIC_JUSTIF =
    sig
	structure L : LOGIC
        datatype rule = implication of L.literal list * L.literal
                      | inconsistency of L.literal list
    end

(***************************************************************)

(* file Logic_justif.sml*)
import "ATOMS";
import "Logic";
import "LOGIC_JUSTIF";


functor Logic_justif (atoms: ATOMS) : LOGIC_JUSTIF =
    struct
	structure L : LOGIC = Logic(atoms)

	        datatype rule = implication of L.literal list * L.literal
		              | inconsistency of L.literal list
    end

(****************************************************************)

(*file LOGIC_JUSTIF_AND_INIT.sml *)
import "LOGIC_JUSTIF";

signature LOGIC_JUSTIF_AND_INIT =
    sig
	structure LJ : LOGIC_JUSTIF
        val background_knowledge : LJ.rule list
    end

(****************************************************************)

(* file POSS.sml *)
import "LOGIC";

signature POSS =
    sig
	structure L : LOGIC
    end

(***************************************************)

(*file Poss.sml *)
import "LOGIC_JUSTIF_AND_INIT";
import "POSS";

functor Poss (lji : LOGIC_JUSTIF_AND_INIT) : POSS =
    struct
	structure L = lji.LJ.L
    end

(***************************************************)

(*file  NOTHING.sml*)
import "POSS";

signature NOTHING =
    sig
	structure P : POSS
    end

(***********************************)

(* file Nothing.sml*)
import "POSS";
import "NOTHING";

functor Nothing (PW:POSS) : NOTHING =
    struct
	structure P = PW
    end

(***********************************)
(* main programm  : Block.sml*)
import "Logic_justif";
import "Poss";
import "NOTHING";
(* curiously, if you remove this last import, the error message does not
appear *)

structure atoms =
    struct
	datatype term = a | b | c 
	datatype atom =
                    on of term * term
                  | ontable of term
                  | holding of term
                  | clear of term
                  | handempty
	   
	fun t2s a = "a"
	  | t2s b = "b"
	  | t2s c = "c"

	fun a2s (on(X,Y))   = "on("^(t2s X)^", "^(t2s Y)^")"
                  | a2s (ontable X) = "ontable("^(t2s X)^")"
                  | a2s (holding X) = "holding("^(t2s X)^")"
                  | a2s (clear X)   = "clear("^(t2s X)^")"
                  | a2s handempty   = "handempty"
	   
	fun put_at os (at:atom) = output(os, a2s(at))

	fun eq_at (at1:atom) (at2:atom) = at1=at2
	
    end

structure logic_justif : LOGIC_JUSTIF = Logic_justif(atoms)
open logic_justif
open L
open atoms

val back_klg = nil

structure logic_justif_and_init : LOGIC_JUSTIF_AND_INIT =
  struct
      structure LJ = logic_justif
      val background_knowledge = back_klg
  end

(******************************************)

structure poss : POSS = Poss(logic_justif_and_init)
(* this is the line where the error message appears *)

Comment: may be fixed in 0.75 -- check.

Status: fixed in 0.88
---------------------------------------------------------------------------
464. defining exception as data constructor
Submitter: David Tarditi
Date: 7/19/91
Version: 0.70
Severity: minor
Problem: 
  The following results in a compiler bug message in version 0.70:

  datatype d = D;
  exception e = D;

  The error message is:
  Error: Compiler bug: in makedec EXCEPTIONdec

Comment:

This is probably due to the fact that exceptions and constructors
share the same name space.  A check that the binding for the rhs of
"exception e = ..." is an exception is probably missing.

Status: fixed in 0.75
---------------------------------------------------------------------------
465. opening unbound structure id in signature
Submitter: David Tarditi
Date: 7/19/91
Version: 0.70
Severity: minor
Problem: 
    The compiler falls over with the exception UnboundTable if you
    try to open an undefined structure in a signature.
Code: 
  signature S =
  sig
    open T (* T is undefined *)
  end
Status: fixed in 0.75
---------------------------------------------------------------------------
466. looping error message
Submitter:      Matti Jokinen, moj@utu.fi
Date:		22-Jun-1991
Version:        0.69, 0.70, possibly others
System:         probably all
Severity:       minor for an experienced user, but confusing to novices

Problem:        unterminating error message

Code:           fun f (p,q) =
		    let fun g (p,q) = #1 q orelse f (p,q)
		    in g (p, #2 q)
		end;

Transcript:	- fun f (p,q) =
		=     let fun g (p,q) = #1 q orelse f (p,q)
		=     in g (p, #2 q)
		= end;
		std_in:2.9-2.41 Error: unresolved flex record in let pattern
		  type: {1:bool,...}
		std_in:1.1-4.3 Error: unresolved flex record in let pattern
		  type: {1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1
		:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1
		:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1
		:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1:bool,2:{1
		- - -

Comments:	Can be interrupted with ^c.
Status: fixed in 0.80
---------------------------------------------------------------------------
467. missing newline in declaration echo
Submitter:      Matti Jokinen (moj@utu.fi)
Date:		23-Jul-1991
Version:        0.69, 0.70, possibly others
System:         all
Severity:       minor

Problem:        Fixity declarations are echoed without newlines.

Code:           infix L; infixr R; nonfix N;

Transcript:	- infix L; infixr R; nonfix N;
		infix Linfixr Rnonfix N-
				       ^
				       This is the next prompt.

Fix:		Add `newline()' at the end of the printFixity function
		defined in src/print/printdec.sml:

*** printdec.sml.orig   Thu Mar 14 17:50:22 1991
--- printdec.sml        Mon Jul 22 04:11:27 1991
***************
*** 215,227 ****
        and printFixity{fixity,ops} =
            (case fixity of
               NONfix => print "nonfix "
             | INfix (i,_) =>
                 (if i mod 2 = 0 then
                    print "infix "
                  else print "infixr ";
                  if i div 2 > 0 then
                    (print (i div 2);
                     print " ")
                  else ());
!            printSequence " " printSym ops)

--- 215,228 ----
        and printFixity{fixity,ops} =
            (case fixity of
               NONfix => print "nonfix "
             | INfix (i,_) =>
                 (if i mod 2 = 0 then
                    print "infix "
                  else print "infixr ";
                  if i div 2 > 0 then
                    (print (i div 2);
                     print " ")
                  else ());
!            printSequence " " printSym ops;
!            newline())

Status: fixed in 0.75
---------------------------------------------------------------------------
468. extra comma in printing unit record
Submitter: Thomas Yan (Cornell)
Date: 11/18/91
Version: 0.75
Severity: minor
Problem: 
  Extra comma in printing unit record:
Transcript: 
  - val {...} = ();
  std_in:2.1-2.14 Warning: binding contains no variables
          {,...} = ...
Status: fixed in 0.85
---------------------------------------------------------------------------
469. infix precedence bound
Submitter: Thomas Yan (Cornell)
Date: 11/18/91
Version: 0.75
Severity: minor
Problem: 
  Infix declaration allows values greater than 9:
Transcript: 
  - infix 10 +;
  infix 10 +
Status: fixed in 0.90
---------------------------------------------------------------------------
470. top-level continuations
Submitter:	Francis.Dupont@inria.fr
Date:		Sat Nov 23 16:49:36 MET 1991
Version:	0.75
System:		all systems (tested on Sun4/75 running SunOS4.1.1)
Severity:	major
Problem:	the typing of toplevel continuation is incorrect
Code:		see later
Transcript:	see later
Comments:	this bug cannot be corrected because toplevel continuations
		(implied by call/cc) are not compatible with SML type system
		(see all the literature on this topics, for intance my
		PhD thesis if you can read French...)
Fix:		Easy : drop call/cc (use limited static continuations)

The code and the bug :

% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- datatype foo = None | Kont of int cont;
datatype  foo
con Kont : int cont -> foo
con None : foo
- val x = ref None;
val x = ref None : foo ref
- callcc (fn k => (x := Kont k; 1));
val it = 1 : int
- val y = (fn (Kont k) => k) (!x);
std_in:5.10-5.25 Warning: match not exhaustive
        Kont k => ...
val y = cont : int cont
- val f = (throw y : int -> bool);
val f = fn : int -> bool
- f 1;
val it = 1 : int

Francis.Dupont@inria.fr

PS : a variant of this bug is described in report 145 "stale top-level
continuations cause type bugs" (cf doc/bugs/masterbugs) and its status
is "fixed in 0.49" (sorry, it cannot be fixed) !

Status: fixed in 0.82 (but further investigation is warranted)
---------------------------------------------------------------------------
471. allocating large arrays
Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk>
Date: 11/26/91
Version: 0.75
Severity: serious
Problem: 
  Sometimes it will crash when allocating very large arrays.
Transcript: 
     Standard ML of New Jersey, Version 75, November 11, 1991
     Arrays have changed; see Release Notes
     val it = () : unit
     - open Array;
     open Array
     - infix 7 sub;
     infix 7 sub
     - fun Sieve n =
     let
       val A = array (n,false) ;

       fun set i di = if i < n then (update (A,i,true) ; set (i+di) di ) else () ;

       fun get 1 acc = acc
       |   get i acc = get (i-1) (if A sub i then acc else i :: acc) ;

       fun siv i = if i >= n then [] else
		   if (A sub i) = false then (set (i+i) i ; siv (i+1))
		   else siv (i+1) ;
     in
       siv 2 ; get (n-1) []
     end ;
     val Sieve = fn : int -> int list
     - Sieve 3628800;
  Segmentation fault (core dumped)

  But it works if I do it more gently.

  Standard ML of New Jersey, Version 75, November 11, 1991
  Arrays have changed; see Release Notes
  val it = () : unit
  - open Array;
  open Array
  - infix 7 sub;
  infix 7 sub
  - fun Sieve n =
  let
    val A = array (n,false) ;

    fun set i di = if i < n then (update (A,i,true) ; set (i+di) di ) else () ;

    fun get 1 acc = acc
    |   get i acc = get (i-1) (if A sub i then acc else i :: acc) ;

    fun siv i = if i >= n then [] else
		if (A sub i) = false then (set (i+i) i ; siv (i+1))
		else siv (i+1) ;
  in
    siv 2 ; get (n-1) []
  end ;
  val Sieve = fn : int -> int list
  - Sieve 1000000;

  [Increasing heap to 2952k]

  [Increasing heap to 5792k]

  [Increasing heap to 8192k]

  [Major collection... 63% used (412372/652688), 250 msec]

  [Increasing heap to 12544k]
  val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : int list
  - Sieve 3628800;

  [Major collection... 25% used (1354396/5356616), 880 msec]

  [Increasing heap to 14944k]

  [Major collection... 99% used (1354396/1354396), 870 msec]

  [Increasing heap to 24408k]

  [Major collection... 99% used (1354396/1354396), 860 msec]

  [Increasing heap to 38600k]

  [Increasing heap to 42544k]
  val it = [2,3,5,7,11,13,17,19,23,29,31,37,...] : int list
  - 
Comments:
  This occurs in
     Standard ML of New Jersey, Version 75, November 11, 1991
     Standard ML of New Jersey, Version 0.73, 10 September 1991
     Standard ML of New Jersey, Version 0.66, 15 September 1990
  so I think it is the memory allocation rather than the new Array structure.
Status: fixed in 0.84
---------------------------------------------------------------------------
472. growing heap
Submitter: Simon Finn <simon@abstract-hardware-ltd.co.uk>
Date: 11/26/91
Version: 0.75
System: ?
Severity: serious 
Problem: 
  SML/NJ version 0.75 seems to have a problem when asked to grow
  the heap by a large factor.
Transcript: 
 this works:
  Perky%  /ml/njml/mlsave.75/src/sml
  Standard ML of New Jersey, Version 75, November 11, 1991
  Arrays have changed; see Release Notes
  val it = () : unit
  - val y = Array.array (1000000,true);

  [Increasing heap to 4020k]

  [Increasing heap to 8192k]

  [Major collection... 98% used (409232/414048), 260 msec]

  [Increasing heap to 12884k]
  val y = prim? : bool array
  - val x = Array.array (2000000,true);

  [Increasing heap to 16636k]

  [Major collection... 99% used (4409484/4411876), 1770 msec]

  [Increasing heap to 31412k]
  val x = prim? : bool array

 but this doesn't:

  - Perky% !!
  /ml/njml/mlsave.75/src/sml
  Standard ML of New Jersey, Version 75, November 11, 1991
  Arrays have changed; see Release Notes
  val it = () : unit
  - val x = Array.array (2000000,true);
  Segmentation fault (core dumped)
  Perky% 

Status: fixed in 0.84
---------------------------------------------------------------------------
473. inadequate error message
Submitter: George Otto (ptah!otto)
Date: 11/27/91
Version: 0.75?
Severity: minor
Problem: 
  I put some ML datatype definitions into a file and then brought them into ML
  using the command

	  use "file";

  I got back the error message "duplicate constructor" with no other
  information.  Couldn't this be more helpful and mention the name of the
  constructor it is reporting about?
Status: fixed in 0.91 (dbm)
---------------------------------------------------------------------------
474. compiler bug: patType -- unexpected pattern
Submitter: John Reppy
Date: 12/6/91
Version: 0.75
Severity: minor
Problem: 
  Compiler bug: patType -- unexpected pattern
Code: 
    (* extract the draw_cmd, id and depth of a drawable *)
      fun infoOfDrawable (DRAWABLE{draw_cmd, DWIN w}) = let
	    val WIN{id, scr_depth=SCRDEPTH{depth, ...}, ...} = w
	    in
	      {draw_cmd=draw_cmd, id=id, depth=depth}
	    end
	| infoOfDrawable (DRAWABLE{draw_cmd, DPM pm}) = let
	    val PM{id, scr_depth=SCRDEPTH{depth, ...}, ...} = pm
	    in
	      {draw_cmd=draw_cmd, id=id, depth=depth}
	    end
Transcript: 
  window/draw.sml:16.51 Error: syntax error: inserting AS
  window/draw.sml:21.43-21.44 Error: syntax error: inserting AS
  Error: Compiler bug: patType -- unexpected pattern
Comments: couldn't isolate small example (same as #515)
Status: fixed in 0.83
---------------------------------------------------------------------------
475. LOOKUP exception from mllex (see also 510, 516)
Submitter:      Markus Freericks, mfx@cs.tu-berlin.de
Date:		12.12.91
Version:        Standard ML of New Jersey, Version 75, November 11, 1991
System:         Sparc
Severity:       quite minor		
Problem:        
When I use a regular expression that isn't defined, I get an unhelpful
exception LOOKUP. This exception is not mentioned in lexgen.doc, and
there is no indication as to where the problem occurs in the input
file.
Code:           

(* bug *)
%%
%%
{xxx}	=> {()};

Transcript:

	mfx@marx [77]% sml-lex bug
	? sml-lex: uncaught exception LOOKUP
or

- use "lexgen.sml";
[opening lexgen.sml]
lexgen.sml:1127.5-1131.57 Warning: match not exhaustive
        (true,129) => ...
        (true,256) => ...
        (false,129) => ...
        (false,256) => ...
lexgen.sml:876.2-895.10 Warning: match not exhaustive
        (nil,nil) => ...
        (a :: a',b :: b') => ...
lexgen.sml:854.19-855.48 Warning: match not exhaustive
        1 => ...
        2 => ...
        3 => ...
lexgen.sml:813.9-813.55 Warning: match not exhaustive
        (tl,el) :: r => ...
functor RedBlack : <sig>
signature LEXGEN = 
  sig
    val lexGen : string -> unit
  end
structure LexGen : LEXGEN
[closing lexgen.sml]
val it = () : unit

- LexGen.lexGen "bug";

uncaught exception LOOKUP

Comments:
Being what could be called a 'naive user', I first thought my
installation of SML and/or lexgen.sml to be in error. The warnings
encountered when loading lexgen.sml added to this impression.

Fix:
A change to the doc should be enough; the error in the input file is
easy enough to find when one knows what to search for.
Status: fixed in 0.91 (Tarditi)
---------------------------------------------------------------------------
476. sml-lex
Submitter: Denys Duchier <dduchier@csi.UOttawa.CA>
Date: 12/11/91
Version: 0.75
Severity: minor
Problem: 
  sml-lex (with SML V75) produces a lexer that contains D and T states
  when I use the special character $.  Here is the source:
Code: 

    datatype lexresult = EOF;
    fun eof () = EOF;
    %%
    %%
    ";".*$	=> (lex());

Comments: the rule is meant to parse a lisp-style comment.
  Andrew sez:  I'm not sure that this is really a bug.  Perhaps the
  documentation needs to be changed?
Status: fixed  in 0.91 (Tarditi)
---------------------------------------------------------------------------
477. duplicate specifications through include
Submitter: Nick Rothwell
Date: 21 Oct 91
Version: 0.73
Severity: minor
Problem: 
    I enclose a short-ish (40 line) program. It compiles under poplog and one
    version of poly. It fails under another version of poly and with different
    errors under two versions of SML/NJ. By my reckoning, the program is legal
    SML.
Code: 
  signature MONO_SET =
    sig
      type Element
      type Set
      type T sharing type T = Set
    end;

  functor MonoSet(type T): MONO_SET =
    struct
      abstype Set = Set of T list
      with
	type Element = T
	type T = Set
      end
    end;

  signature INPUT_VAR =
    sig
      type InputVar
      type InputVarSet

      include MONO_SET sharing type Element = InputVar
			   and type Set = InputVarSet

      type T sharing type T = InputVar
    end;

  functor InputVar(): INPUT_VAR =
    struct
      datatype InputVar = INPUT_VAR of string

      local
	structure S = MonoSet(type T = InputVar)
      in
	open S
	type InputVarSet = Set
      end

      type T = InputVar
    end;

Transcript: 
  X.sml:25.10 Error: duplicate specifications for type constructor T in signature
Comments: a deliberate divergence from the Definition.
Status: not a bug
----------------------------------------------------------------------
478. order of type definitions in withtype clause
Submitter: Andrew Appel
Date: 10/11/91
Version: 0.73
Severity: minor
Problem: 
  Type definitions in withtype clause have to be ordered properly.
Code: 
    datatype foo = T 
      withtype a = b and b = foo
Comments:
  I think this is correct.  Have to check Definition.
Status: not a bug
----------------------------------------------------------------------
479. Boxity exception in vector_n
Submitter: Andrew Koenig
Date: 10/22/91
Version: ?
Severity: major
Problem: 
  Applying vector_n with index out of bounds yields Boxity exception.
Transcript: 
    - open Vector;
    open Vector
    - infix 9 sub;
    infix 9 sub
    - val x = vector_n(10,[1,2,3]);
    val x = - : int vector
    - length(x);
    val it = 10 : int
    - x sub 0;
    val it = 1 : int
    - x sub 1;
    val it = 2 : int
    - x sub 2;
    val it = 3 : int
    - x sub 3;
    val it = 8 : int
    - x sub 4;
    val it = 
    uncaught exception Boxity
Comments:
  vector_n was not supposed to be exported.
Status: fixed in 0.75
----------------------------------------------------------------------
480. Exit status of makeml is 1.
Submitter: David Tarditi
Date: 10/23/91
Version: 0.75?
Severity: minor
Problem: 
    makeml almost always returns an exit status of 1, which
    indicates failure.   This is because as a shell program it
    returns the value of its last command, which is an if-statement
    that almost always "fails" (the value of the if-statement is
    the last simple command that it executes, which is a test that
    fails; there is no "else" clause to execute).

    This creates problems for me when I use a makefile that invokes
    makeml to build sml images.  Could you make the last statement
    in makeml "exit 0" ?
Comments:
Status: fixed in 0.89
----------------------------------------------------------------------
481. redeclared constructors
Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk>
Date: 10/28/91
Version: 0.73
Severity: minor
Problem: 
    SML/NJ 0.73 does not accept the following valid ML program
Code: 
    signature S = sig
      datatype a = A | B of string ;
      datatype b = B | C ;
    end ;

    functor F(S:S) =
    struct
      open S ;

      fun matchA A = true
      |   matchA _ = false ;

      fun matchB B = true
      |   matchB _ = false ;

      fun matchC C = true
      |   matchC _ = false ;
    end ;

    structure S = F ( datatype a = A | B of string ;
		      datatype b = B | C ) ;

Status: open
----------------------------------------------------------------------
482. "constant" unary type abbreviations in signature matching
Submitter: Mike Crawley <mjc@abstract-hardware-ltd.co.uk>
Date: 10/28/91
Version: 0.73
Severity: significant
Problem: 
   Poly/ML allows this; SML/NJ 0.73 doesn't
   It all depends whether or not you expand the type-abbreviation t
   when you match the datatype d.
Code: 
    signature A =
    sig
      eqtype 'a t
      datatype d = C | D of int t
    end;

    structure Z =
    struct
      type 'a t = bool
      datatype d = C | D of bool t
    end;

    structure X : A = Z;
Status: fixed at least as early as 0.80
----------------------------------------------------------------------
483. lexgen compilation blowup
Submitter:	Lie Ma, ma@cs.pdx.edu
Date:		10/29/1991
Version:	SML Ver.0.66
System:		Sun Sparc
Code:		lexgen.sml Ver. 1.3, Dec'89
Encl:		typescript
Problem:	
	
	I'm using lexgen to write a lexer for a formal specification language.
	According to the manual, I should use lexgen.sml in the following way:

	quote: 
		Running ML-Lex
		Use "lexgen.sml"; this will create a structre LexGen. 
		The function LexGen.lexGen creates a program for a
		lexer from an input specification. It takes a string
		argument -- the name of the file containing the input
		spacification. The output file name is determined by
		appending ".sml" to the input file name.
	end{quote}

	I got the extremly poor performance when I tried to use "lexgen.sml".
	I tried on two Suns, both taking appr. 25 to 28 minutes to evaluate
	"lexgen.sml". The maximum heap was about 16 MB. The process was so 
	huge that the system speeded donw and I had to kill it in most cases.
	And once other user even could not run latex within emacs.

	I want to know whether it is usual. If not, it's caused by ML or 
	"lexgen.sml"?

	Thank you to your attention to this. Your prompt reply will be 
	appreciated.
Status: fixed in 0.89
----------------------------------------------------------------------
484. interrupt is buggy (same as 511, 518)
Submitter: Mike Crawley
Date: 10/29/91
Version: 0.73
System: Sparc/SunOS
Severity: major
Problem: 
  I have been able to repeat the following
  bug a number of times. Pressing ^C to interrupt
  sml while it is busy can sometimes crash it.
  The saved image I was using was 10MB at the time.
  
  ^C
  SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0x9dd8)
  
Transcript: 
Comments:
    This is a very mysterious bug that has been around for a while.  The
    "0x9de3bfc0 @ 0x9dd8" means that the signal handler received a SIGEMT
    signal with the PC = 0x9dd8 and the instruction at that address being
    "save %sp,-0x40,%sp."  Under my reading of the documentation, this
    should never occur in SunOS.  The address 0x9dd8 is interesting, since
    it is the address of an assembly routine used to force a GC trap
    after a signal (such as ^C), but I don't understand how the sigcontext
    program counter gets that value.  [John Reppy]
Status: open
----------------------------------------------------------------------
485. structure manipulation bombs
Submitter:      Tim Freeman <tsf@cs.cmu.edu>
Date:		Thu Oct 31 15:32:46 1991
Version:        0.74
System:         Sun 4 running some version of Mach
Severity:       minor
Problem:        With some manipulations of structures, raising
		unhandled exceptions causes SML to bomb.
Code:           bug3.sml contains:
		structure Util = 
		    struct
			exception Bug of string
		    end
		
		structure InstProto = 
		struct
		    structure U = Util
		    structure S = struct end 
		end 
		
		open InstProto
		;
		raise U.Bug "hi"

Transcript:     % sml
		Standard ML of New Jersey, Version 0.74, 10 October, 1991
		Prerelease version.  Arrays have changed; see doc/NEWS
		val it = () : unit
		- use "bug3.sml";
		[opening bug3.sml]
		structure Util : 
		  sig
		    exception Bug of string
		  end
		structure InstProto : 
		  sig
		    structure S : ...
		    structure U : ...
		  end
		open InstProto
		SIGILL code 0x7
		% 				
Comments:	Earlier during the process of narrowing down this bug,
		it was saying 

			uncaught exception random binary garbage

		(except you have to imagine the string "random binary
		garbage" replaced by random binary garbage) instead of
		getting the SIGILL trap. 

Status: fixed in 0.84
----------------------------------------------------------------------
486. Regbind exception (same as bug 380?)
Submitter:      jont@harlqn.co.uk
Date:           31/10/91
Version:        SML of NJ version number, 0.66
System:         Sun 4/330 with SunOS 4.1.1
Severity:       critical
Problem:        The code generation phase blows up with an uncaught
		exception Regbind
Code:           
(* _testreals.sml the functor (used to be) *)
(*
Copyright (c) 1991 Harlequin Ltd.
*)

  fun div2 _ =
    let
      val new_y = if 0 mod 2 = 0 then "0" else chr(ord "0" + 1)
    in
      div2 []
    end

Transcript:
sml66
Standard ML of New Jersey, Version 0.66, 15 September 1990
val it = () : unit
- use"../main/_testreals.sml";
[opening ../main/_testreals.sml]
[closing ../main/_testreals.sml]

uncaught exception Regbind

Comments: This is the second time I have encountered this problem. The
first time I was unable to produce a small example, and it later went
away for reasons which were never clear. However, this time it cropped
up in a functor which was only 80 lines at the time, and I was able to
whittle it down to the above rather useless function.

Probably same as bug #380.
Status: fixed in 0.84
----------------------------------------------------------------------
487. clumsy memory exhaustion
Submitter: Andy Koenig
Date: 11/7/91
Version: 0.74
System: Sparc
Severity: minor 
Problem: 
   SML-NJ is not very nice about handling memory exhaustion.
Transcript: 

	[boojum] sml
	Standard ML of New Jersey, Version 0.74, 10 October, 1991
	Prerelease version.  Arrays have changed; see doc/NEWS
	val it = () : unit
	- fun f x = f(0::x);
	val f = fn : int list -> 'a
	- f nil;

	[Increasing heap to 3164k]

	[Increasing heap to 4452k]

	[Increasing heap to 5456k]

	[Major collection...
	[Increasing heap to 8192k]
	 76% used (3427160/4508104), 2610 msec]

	[Increasing heap to 13192k]

	[Major collection... 49% used (4497848/8999168), 4600 msec]

	[Increasing heap to 26380k]

	[Major collection... 49% used (8999168/18002072), 9250 msec]

	[Increasing heap to 27204k]

	[Major collection...
	[Increasing heap to 27620k]

	[Increasing heap to 27776k]

	[Increasing heap to 27860k]

	[Increasing heap to 27880k]

	Warning: can't increase heap

	Ran out of memory[boojum] 
Comments:

While I do ultimately expect some kind of drastic termination,
I do **NOT** expect to be unceremoniously dumped out of ML back
into the Shell.  A more reasonable strategy might be to preallocate
a chunk of memory to be used as secondary storage while recovering
from exhaustion of primary storage.  That, at least, would allow
for a return to top level and associated garbage collection, which,
in many cases, would allow interactive execution to resume.

Incidentally, this example was run on a Sparcstation with 64
megabytes of physical memory and no limit on process size
that I know of.  I don't know why it gave up the ghost at
28 megabytes -- do you?

Status: open
----------------------------------------------------------------------
488. wrong types in pervasives
Submitter: Thomas Yan
Date: 8/21/91
Version: 0.71
Severity: minor
Problem: 
  bugs in the pervasive environment
Transcript: 
  Standard ML of New Jersey, Version 0.71, 23 July 1991
  val it = () : unit
  - Array.tabulate;
  val it = fn : 'a * (int -> '1b) -> '1b array
  - String.chr;
  val it = fn : int -> 'a
  - 
Status: Fixed in 0.75
----------------------------------------------------------------------
489. exportFn image size too large
Submitter: Andy Koenig
Date: 11/17/91
Version: 0.75
System: Sparc
Severity: significant
Problem: 
    On a Sparc, here's the text and data space used by the executable
    produced by the following program (with an ML build with noshare):

	    exportFn ("a.out", fn _ => print "Hello world\n");

    Version		text	data

    0.66		57344	188416
    pre-74		81920	425984
    75			81920	294912

    Evidently some of the memory leaks in 0.66 have been fixed but not all.

    Anoither example from John Reppy:
    (sml-export was made with the -pervshare option)

    <jhr@bat> sml-export
    Standard ML of New Jersey, Version 0.89, September 4, 1992
    val it = () : unit
    - exportFn("foo", fn _ => ());

    [Major collection... 25% used (842428/3366736), 430 msec]

    [Major collection... 66% used (560264/844136), 310 msec]
    <jhr@bat> size foo
    text    data    bss     dec     hex
    241664  614400  0       856064  d1000
    <jhr@bat> size sml-export
    text    data    bss     dec     hex
    241664  3416064 0       3657728 37d000

Fix:
  Environment refs (pervasiveEnvRef, topLevelEnvRef) were added to
  Hooks and cleared on export.  Changed files boot/perv.sml and
  boot/system.sig.
Status: fixed in 0.93c (awa,dbm)
----------------------------------------------------------------------
490. function has bad type in pervasives
Submitter: Lal Geoge
Date: 11/20/91
Version: 0.75
Severity: significant
Problem: 
  ceiling has wrong type
Transcript: 
    Standard ML of New Jersey, Version 75, November 11, 1991
    Arrays have changed; see Release Notes
    - ceiling;
    val it = fn : real -> 'a
    -
Status: fixed in 0.76
----------------------------------------------------------------------
491. memory leak
Submitter:      Nevin Heintze (nch@cs.cmu.edu)
Date:  		Wed Nov 20 1991
Version:        0.75
System:         sparc1, pmax, sun3
		Mach 2.6 #5.1(CS8f): Wed Sep 11 14:39:14 EDT 1991; CS8/STD+WS
Severity:       major
Problem:        garbage collection when rebuilding structures
		(stuff in old structures does not seem to be reclaimed).
Code:           

signature MEM_HOG =
  sig
    val X : int Array.array
  end

functor Mem_hog() : MEM_HOG =
struct
    val X = Array.array(200000, 42) 
  end

structure Mem_hog : MEM_HOG = Mem_hog();
open Mem_hog;

structure Mem_hog : MEM_HOG = Mem_hog();
open Mem_hog;

(* etc...  (Following transcript uses 8 functor applications) *)

Transcript:   

Script started on Wed Nov 20 13:54:15 1991
[alonzo] % sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "mem.sml";
[opening mem.sml]

[Increasing heap to 3174k]
signature MEM_HOG = 
  sig
    val X : int array
  end
functor Mem_hog : <sig>
structure Mem_hog : MEM_HOG
open Mem_hog

[Increasing heap to 3990k]
structure Mem_hog : MEM_HOG

[Increasing heap to 4094k]
open Mem_hog
structure Mem_hog : MEM_HOG
open Mem_hog

[Major collection...
[Increasing heap to 6486k]
 98% used (2814944/2866068), 1930 msec]

[Increasing heap to 10022k]
structure Mem_hog : MEM_HOG
open Mem_hog
structure Mem_hog : MEM_HOG
open Mem_hog
structure Mem_hog : MEM_HOG
open Mem_hog
structure Mem_hog : MEM_HOG

[Major collection...
[Increasing heap to 17126k]
 73% used (4412384/6025784), 3670 msec]

[Increasing heap to 17646k]
open Mem_hog
structure Mem_hog : MEM_HOG
open Mem_hog
[closing mem.sml]
val it = () : unit
-
[alonzo] % exit
script done on Wed Nov 20 13:54:43 1991

Comments:
  I have been running into this problem for a while now in 
  some program analysis implementation work, but was not sure where
  the problem was.  After about 3-4 rebuilds of my system I usually
  have to start another core image.  

  The general problem occurs on sparc, sun4 and pmax machines;
  the specific code given above has been tried on a sparc (24MB) and a
  pmax (64MB?).  If the "open Mem_hog" is removed, then the problem goes
  away.  The problem is not specific to arrays; for example if X is
  bound to a list of a couple of thousand elements instead of an array,
  then similar behaviour occurs.
Status: fixed in 0.89
----------------------------------------------------------------------
492. compiler bug from sharing
Submitter: David Tarditi
Date: 7/19/91
Version: 0.70
Severity: major
Problem: 
    This code causes a compiler bug in version 0.70.  It should be
    an interesting test case in the future.
Code: 
(* This code shows that we'll need to augment structure instantiation
   arrays during functor abstraction to include structures which are
   not in the signature, but which have views that are in the
   signature.
*)

signature S0 = sig
	         type u
	       end

signature S1 = sig
	         type t
	         val v : t
	       end

(* define a structure A, but export only views of A *)

functor F1() : sig
	         structure B : S0
	         structure C : S1
	       end =
   struct
	structure A = struct
	                  datatype u = U
	                  datatype t = T
	                  val v = T
	              end
        structure B : S0 = A
	structure C : S1 = A
   end

structure D = F1()

(* the definitional sharing constraint implies that C.t = D.C.t,
   but we won't know this unless we keep the origin of D.B around.*)

functor F2(A : sig 
	        structure C : S1
	        sharing D.B = C
	       end) : sig
	 	         val v : A.C.t
	              end =
   struct
	val v = D.C.v
   end
Status: fixed in 0.84
----------------------------------------------------------------------
493. Compiler bugs from bad include specs
Submitter: Bruce Esrig
Date: 7/19/91
Version: ?
Severity: major
Problem: 
  Compiler bug from include specs
Code: 
(* Sigs.sml -- experiment with signatures and sharing *)

(* this is accepted *)
signature X' = sig datatype 'a Opt = None | Some of 'a end
signature Y' = sig datatype 'a Opt = None | Some of 'a end
signature Z' = sig include X' include Y' end;

(* this fails *)
signature X' = sig datatype 'a Opt = None | Some of 'a end
signature Y' = sig include X' end

(* signature Z' = sig include X' include Y' end *)
(* std_in:0.0 Compiler Bug: Signs.abstractSig.abstractType 2 *)

(* signature W' = sig include X' include Y' sharing type X'.Opt = Y'.Opt end *)
(* std_in:0.0 Compiler Bug: Signs.abstractSig.abstractType 2 *)

signature X' = sig type opt end
signature Y' = sig type opt end
(* signature Z' = sig include X' include Y' sharing type X'.opt = Y'.opt end *)
(* std_in:2.20-2.70 Error: unbound structure id in sharing specification: X' *)


(* How do I build a signature which brings a shared type to top level? *)

signature Z' =
    sig structure X : X' structure Y : Y'
	sharing type X.opt = Y.opt
	open X
    end

structure Z : Z' =
    struct
	structure X = struct type opt = int end
	structure Y = struct type opt = int end
	open X
    end;
(* structure Z :
  sig
    structure X : sig...end
    structure Y : sig...end
  end *)

(* 5 : Z.opt; *)
(* std_in:10.5-10.9 Error: unbound type in structure: opt *)
Status: fixed in 0.84
----------------------------------------------------------------------
494. bogus gc message
Submitter: Bob Harper
Date: 12/16/91
Version: 0.75
Severity: minor
Problem: 
  negative number in "[Increasing heap to -12217k]" message
Transcript: 
    [reading .../front/printback.sml]

    [Major collection...
    [Increasing heap to 8110k]

    [Increasing heap to 7942k]

    [Increasing heap to 7438k]

    [Increasing heap to 5926k]

    [Increasing heap to 1390k]
    smlsg: could not sbrk, return = 1

    [Increasing heap to -12217k]				*** NB
     48% used (2767236/5647472), 2570 msec]

    [Increasing heap to 8270k]
    [writing .../.@sys/printback.sml.bin... done]
    [closing .../front/printback.sml]

Status: open
--------------------------------------------------------------------
495. inaccurate emacs info file
Submitter:      dan@math.uiuc.edu
Date:		12/26/91
Version:        75
Severity:       minor
Problem:        

	From the IO node in the emacs info file "sml"

	    val execute : string -> instream * outstream

	From the program

	- execute;
	val it = fn : string * string list -> instream * outstream

Fix: edit the file "sml" to give the correct declaration for "execute"
Status: fixed (in /usr/local/sml/75/lib/emacs/info/sml)
----------------------------------------------------------------------
496. incorrect defn of dec in fastlib
Submitter:      Stephen Adams,  S.R.Adams@ecs.soton.ac.uk
Date:		3 Jan 1992
Version:        0.75
Severity:       curiosity
Problem:        Curious code in compiler source

I have been looking in the compiler source and I discovered
a small bug:
Code:
(* cpsopt.sml
 *
 * Copyright 1989 by AT&T Bell Laboratories
 *)
functor CPSopt(val maxfree : int) :
        sig val reduce : CPS.function * System.Unsafe.object option * bool
                                        -> CPS.function
        end =
struct

structure Fastlib = struct

structure Ref = 
  struct
    open Ref
    fun inc r = r := !r + 1
    fun dec r = r := !r + 1		(* this is the worrying bit!*)
  end

Comment:
  dec is used but only in the function `unescapeargs'.  I
  guess that it should be fixed before it causes any grief.
Status: Fixed in 0.75
----------------------------------------------------------------------
497. ML-Yacc doesn't open Array
Submitter:	Lie Ma, ma@cs.pdx.edu
Date:		12/26/91
Version:	SML Ver.77
System:		SUN Sparc
Code:		base.sml
Encl:		typescript
Problem:

		Error found when loading base.sml,
		while no problem using SML Ver.66.

		Or, is there new version of smlyacc
		corporated with the new version of SML?

---------------------- Typescript ----------------------

Script started on Thu Dec 26 22:45:01 1991
warning: could not update utmp entry
antares% cat makepaqrser.sml" ";
Unmatched ".
antares% cat makeparser.sml
(* ------------------------ FILE: makeparser.sml ----------------------------
   Author: Lie Ma						12/10/1991
   Usage:  Call the files "spec.grm.sig", "spec.grm.sml" (generated by 
	   "smlyacc.sml" according to "spec.grm") and "spec.lex.sml" 
	   (gnerated by "lexgen.sml" according to "spec.lex"). Then use
	   structure "SpecLrVals", "SpecLex" and "SpecParser" to generate 
	   the parser.

   Call:   spec.grm.sig, spec.grm.sml, spec.lex.sml
   Input:  nothing
   Output: parser
   -------------------------------------------------------------------------- *)

use "YACC/base.sml";	(* laod the common modules 	*)
use "spec.grm.sig";	(* load grammar signature file 	*)
use "spec.lex.sml";	(* load lexer program file 	*)
use "spec.grm.sml";	(* load grammar program file 	*)


(* --------- define structures ------------ *)

structure SpecLrVals =
	SpecLrValsFun(structure Token = LrParser.Token);
structure SpecLex = 
	SpecLexFun(structure Tokens =
		SpecLrVals.Tokens);
structure SpecParser =
	Join(structure ParserData = SpecLrVals.ParserData
		structure Lex=SpecLex
		structure LrParser=LrParser);


(* ----------- function parse to read file and parse it -------------- *)

val parse = fn s =>
  let val dev = open_in s
      val stream = SpecParser.makeLexer(fn i => input(dev,i))
      val _ = SpecLex.UserDeclarations.pos:=1
      val error = fn(e,i: int,_) => output(std_out, s ^ "," ^ " line "^
				    (makestring i) ^ ", Error: " ^ e ^ "\n")
  in SpecParser.parse(30,stream,error,()) before close_in dev
  end

val keybd = fn () =>
  let val dev = std_in
      val stream = SpecParser.makeLexer (fn i => input_line dev)
      val _ = SpecLex.UserDeclarations.pos:=1
      val error = fn(e,i: int,_) => output(std_out, "std_in, line "^
				    (makestring i) ^ ", Error: " ^ e ^ "\n")
  in SpecParser.parse(0,stream,error,()) 
  end
antares% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- " use "makeparser.sml";
[opening makeparser.sml]
[opening YACC/base.sml]
signature STREAM = 
  sig
    type 'a stream
    val streamify : (unit -> '1a) -> '1a stream
    val cons : '1a * '1a stream -> '1a stream
    val get : '1a stream -> '1a * '1a stream
  end
signature LR_TABLE = 
  sig
    datatype state
      con STATE : int -> state
    datatype term
      con T : int -> term
    datatype nonterm
      con NT : int -> nonterm
    datatype action
      con ACCEPT : action
      con ERROR : action
      con REDUCE : int -> action
      con SHIFT : state -> action
    type table
    val numStates : table -> int
    val describeActions : table -> state -> (term * action) list * action
    val describeGoto : table -> state -> (nonterm * state) list
    val action : table -> state * term -> action
    val goto : table -> state * nonterm -> state
    val initialState : table -> state
    exception Goto of state * nonterm
    val mkLrTable : {actions:((term * action) list * action) list,gotos:(nonterm * state) list list,initialState:state,numStates:int} -> table
  end
signature TOKEN = 
  sig
    structure LrTable : ...
    datatype ('a,'b) token
      con TOKEN : LrTable.term * ('a * 'b * 'b) -> ('a,'b) token
    val sameToken : ('a,'b) token * ('a,'b) token -> bool
  end
signature LR_PARSER = 
  sig
    structure Stream : ...
    structure LrTable : ...
    structure Token : ...
    exception ParseError
    val parse : {arg:'a,ec:{error:string * '1c * '1c -> unit,errtermvalue:LrTable.term -> '1b,is_keyword:LrTable.term -> bool,noShift:LrTable.term -> bool,preferred_insert:LrTable.term -> bool,preferred_subst:LrTable.term -> LrTable.term list,showTerminal> :LrTable.term -> string,terms:LrTable.term list},lexer:('1b,'1c) Token.token Stream.stream,lookahead:int,saction:int * '1c * (LrTable.state * ('1b * '1c * '1c)) list * 'a -> LrTable.nonterm * ('1b * '1c * '1c) * (LrTable.state * ('1b * '1c * '1c)) list,ta> ble:LrTable.table,void:'1b} -> '1b * ('1b,'1c) Token.token Stream.stream
    sharing Token.LrTable = LrTable
  end
signature LEXER = 
  sig
    structure UserDeclarations : ...
    val makeLexer : (int -> string) -> unit -> (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token
  end
signature ARG_LEXER = 
  sig
    structure UserDeclarations : ...
    val makeLexer : (int -> string) -> UserDeclarations.arg -> unit -> (UserDeclarations.svalue,UserDeclarations.pos) UserDeclarations.token
  end
signature PARSER_DATA = 
  sig
    type pos
    type svalue
    type arg
    type result
    structure LrTable : ...
    structure Token : ...
    structure Actions : ...
    structure EC : ...
    val table : LrTable.table
    sharing LrTable = Token.LrTable
  end
signature PARSER = 
  sig
    structure Token : ...
    structure Stream : ...
    exception ParseError
    type pos
    type result
    type arg
    type svalue
    val makeLexer : (int -> string) -> (svalue,pos) Token.token Stream.stream
    val parse : int * (svalue,pos) Token.token Stream.stream * (string * pos * pos -> unit) * arg -> result * (svalue,pos) Token.token Stream.stream
    val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool
  end
signature ARG_PARSER = 
  sig
    structure Token : ...
    structure Stream : ...
    exception ParseError
    type arg
    type lexarg
    type pos
    type result
    type svalue
    val makeLexer : (int -> string) -> lexarg -> (svalue,pos) Token.token Stream.stream
    val parse : int * (svalue,pos) Token.token Stream.stream * (string * pos * pos -> unit) * arg -> result * (svalue,pos) Token.token Stream.stream
    val sameToken : (svalue,pos) Token.token * (svalue,pos) Token.token -> bool
  end
structure Stream : STREAM
YACC/base.sml:340.14-340.16 Error: unbound variable or constructor sub
YACC/base.sml:342.10-342.25 Error: operator and operand don't agree (tycon mismatch)
  operator domain: 'Z array
  operand:         error -> int -> 'Y
  in expression:
    length a
YACC/base.sml:342.26 Error: overloaded variable "-" cannot be resolved
YACC/base.sml:395.36-395.38 Error: unbound variable or constructor sub
YACC/base.sml:395.28-395.45 Error: operator is not a function
  operator: (int array * int) array
  in expression:
    action bogus
YACC/base.sml:402.26-402.28 Error: unbound variable or constructor sub
YACC/base.sml:402.20-402.35 Error: operator is not a function
  operator: int array array
  in expression:
    goto bogus
YACC/base.sml:409.45-409.47 Error: unbound variable or constructor sub
YACC/base.sml:421.53-421.55 Error: unbound variable or constructor sub
YACC/base.sml:418.27-418.48 Error: operator and operand don't agree (tycon mismatch)
  operator domain: 'Z array
  operand:         error -> int -> int
  in expression:
    length row
YACC/base.sml:421.40-421.62 Error: operator is not a function
  operator: (int array * int) array
  in expression:
    action bogus
YACC/base.sml:418.46 Error: overloaded variable "-" cannot be resolved
YACC/base.sml:427.29-427.31 Error: unbound variable or constructor sub
YACC/base.sml:431.49-431.51 Error: unbound variable or constructor sub
YACC/base.sml:427.14-427.37 Error: operator is not a function
  operator: int array array
  in expression:
    goto bogus
YACC/base.sml:447.5-447.15 Error: unbound variable or constructor arrayoflist
YACC/base.sml:449.5-449.15 Error: unbound variable or constructor arrayoflist
YACC/base.sml:450.17-450.27 Error: unbound variable or constructor arrayoflist
YACC/base.sml:453.14-453.24 Error: unbound variable or constructor arrayoflist
[closing YACC/base.sml]
[closing makeparser.sml]
- ^Dantares% ^D
script done on Thu Dec 26 22:46:17 1991
Status: fixed in 0.84
----------------------------------------------------------------------
498. bad function type in perv.sig
Submitter: Embden Gansner
Date: 1/7/92
Version: ?
Severity: significant
Problem: 
    The BITS signature in perv.sig should have
	val notb : int -> int
    instead of 
	val notb : int * int -> int
Status: fixed in 0.81
----------------------------------------------------------------------
499. execute broken
Submitter: David Spooner (spoonerd@.cpsc.ucalgary.ca)
Date: 1/7/92
Version: 0.75
System: ?
Severity: major 
Problem: 
  No output availabe from execute.
Transcript: 
    Standard ML of New Jersey, Version 75, November 11, 1991
    Arrays have changed; see Release Notes
    val it = () :unit

    - val (instr,outstr) = execute ("ls", []);
    val instr = - :instream
    val outstr = - :outstream

    - input (instr, 5);
    val it = "" :string

    - can_input instr;
    val it = 0 :int
Fix: (luochen@shade.Princeton.EDU (Luoqi Chen))
    I believe the problem is in the runtime routine, ml_exec(), it calls
    execve(2) instead of execvp(3), so it won't look up in the PATH for the
    command. Try "/bin/ls" instead.

    The fix is simple, change the line (line 1238 of src/runtime/cfuns.c)
	    execve (cmd, argv, envp);
    to
	    { extern char **environ = envp;
	    execvp(cmd, argv);}
Status: fixed in 0.86
----------------------------------------------------------------------
500. memory leak
Submitter: Kjeld H. Mortensen, metasoft!kjeld@uunet.UU.NET, (617) 576.6920 x 22
Date: 1/7/92
Version: 0.75
System:
  SUN OS 4.1.1, ram 32Mb, swap 103Mb, and
  HPUX 8.0, ram 32Mb, swap 70Mb.
Severity: major
Problem: 
    During use of the extended compiler we see a significant slowdown of 
    this process when using v0.75 of SML/NJ (a factor 2 over a time period
    of 15 minutes reasonable heavy use, and doesn't seem to stop there).
Observations:
	1) We see absolutely no slow down when using v0.62 of SML/NJ on the
	   Sun4 (haven't been able to succesfully compile this version on
	   the HP9000 though).
	2) We see significant slow down when using v0.75 of SML/NJ on both
	   the Sun4 and HP9000. (In spite of the slow down, the compiler 
	   process gets more and more CPU-time.)
	3) Since we use the same ML-code in both cases 1) and 2), I'm lead to 
           conclude that it must be a problem in the SML/NJ system v0.75.

Example:
	Unfortunately I haven't been able to reproduce the phenomenon for a 
	reasonable small example.

Followup:
>...By the way, is your slow-down program mostly compiling things, or executing
>compiled code?

It is mostly executing compiled code.


I made some further investigations regarding the heap size. Each of the 
experiments performed, make up the same amount of work for the ML process
(work is measured in units of what I call "steps").

In the following table, "MEM-INC" is calculated using numbers from the first
and the last major collection. Let the output from the two major collections 
have the format:

	[Major collection... <P1>% used (<MUSED1>/<MTOT1>), <T1> msec]
	[Major collection... <Pn>% used (<MUSEDn>/<MTOTn>), <Tn> msec]

The numbers in "MEM-INC" then have the format: 

	<MUSEDn>-<MUSED1>/<MTOTn>-<MTOT1>,

"/" not to be confused with division.

The numbers in "Work" are only there to show that the compiler in each
experiment, did the same amount of computations.

Machine configurations:
   Sun4      , SUN OS 4.1.1, ram 32Mb, swap 103Mb, and
   HP9000s400, HPUX 8.0    , ram 32Mb, swap  70Mb.


Machine    | SML/NJ | Work/steps | MEM-INC/bytes | Number of major coll.
-----------+--------+------------+---------------+----------------------
Sun4       | v0.62  |     203    |  18292/179960 |          4
Sun4       | v0.75  |     201    | 425120/926324 |         12
HP9000s400 | v0.75  |     202    | 517352/931376 |         40

Comment: [dbm] This was probably fixed by restoring environment cleanup
(in 0.82).
Status: fixed in 0.84
----------------------------------------------------------------------
501. out of date yacc example code
Submitter: Andy Koenig
Date: 1/11/92
Version: ?
Severity: minor
Problem: 
  The calc.grm.sig, calc.grm.sml, and calc.lex.sml file in mlyacc/examples/calc
  needs to be updated.  Rerun ml-yacc and ml-lex on the appropriate files.
Fix:
In the calc directory are the following files:

README
calc.grm
calc.grm.desc
calc.grm.sig
calc.grm.sml
calc.lex
calc.lex.sml
join.sml
load.sml

Saying

	sml-lex calc.lex

rebuilds calc.lex.sml; saying

	sml-yacc calc.grm

rebuilds calc.grm.*

That should be done in the distribution directories so that people
will get the right versions.
[from Dave Tarditi:]
  The directory tools/mlyacc/examples contains some files
  which need to be regenerated by the new versions of
  the parser and lexer generator.

  You need to regenerate the files examples/calc/calc.grm.sml,
  examples/calc.lex.sml by running the parser generator
  on calc.grm and the lexer generator on calc.lex.

  Please remove the file examples/fol/fol.lex.sml.
Status: fixed in 0.91 (Tarditi)
----------------------------------------------------------------------
502. zombie sml processes
Submitter: Stephen Adams <S.R.Adams@ecs.southampton.ac.uk>
Date: 1/13/92
Version:        0.66, 0.75
System:         SunOS 4.1, sparc
Severity:       minor
Problem:        SML processes don't die if you log out
Code:           any running sml process
Comment:
    We use NJ-SML for teaching and research.  A common problem
    is if a user logs out (by selecting `exit' in X-windows, for
    example) the sml proces doesnt die, but sits there consuming
    cpu cycles (often > 40% of the cpu time).  With a large
    number of naive users this is a serious problem.  Even
    `sophisticated' users sometimes accidentally slug a machine
    for a few days.  It would be much friendlier to the
    community if an SML process running (foreground under a
    shell) under Xterm or under emacs would die when the user
    exits from X-windows or suntools.
Comment: [JHR]
	I was unable to reproduce this.  Perhaps there setup is such
	that a SIGHUP isn't getting generated.
Status: can't reproduce
----------------------------------------------------------------------
503. illegal instruction -- core dumps
Submitter:	Markus Freericks
		mfx@cs.tu-berlin.de
Date:		28.1.92
Version:	0.75
System:		Sparc 2 (4/50), 16M, SunOS
Severity:	Major, at least for me
Problem:
When running my compiled program, sml encounters an "illegal
instruction" and dumps core. When the program is interpreted,
there is a message
-----------------------------------------------------------------------------
Error: Compiler bug: no default in interp
-----------------------------------------------------------------------------
the bug seems to occur in a totally normal case expression. I am
currently trying to isolate the error, but would like to know whether
there is some special thing to look for. I use an sml image that
contains the full Edinburgh library; the code that dumps core is part
of the semantic rules of a parser written in sml-yacc. The code is
heavy with functionals.
Just to get an idea of what the code looks like, the function where
the error occurs is
-----------------------------------------------------------------------------
fun makeParamDecl(oflag:bool,headId:S.T,(id,arglists:((S.T * Texpr) list list)),body : Texpr)=
  fn {env=E} =>
  let
    fun loop ([]:(S.T*Texpr)list list,comb:ACexpr->ACexpr,env) 
      = let
	  val {free=f,used=u,expr=e} = body {env=env}
	in
	  {defs = [id],
	   expr = {free=f,
		   used=u,
		   expr=comb(e)
		   }}
	end
      | loop (args::argss,comb,env) 
	= let
	    (* rename the parameters if necessary *)
	    val params = map #1 args
	    val typtexprs = map #2 args
	    val typacterms= map (fn x => x {env=env}) typtexprs
	    val typcterms = map (fn x => (output(std_out,"mpdloop1\n");
					  (case x of
					     (Complex(_)) => output(std_out,"complex\n")
					   | (Atomic(_)) =>  output(std_out,"atomic\n"));
					     output(std_out,"mpdloop2\n");
					     (case x of 
						Atomic(X) => X
					      | Complex(Y)=> (output(std_out,"error: type var must be atomic:\n");
							      Cterm.print std_out (Y objVar);
							      objVar))
						)) typacterms
	    val renames = renameSyms env params
	    val env' = Env.addList (ListPair.zip(params,renames)) env
	    val env''= putNewEE(putNewState(env))
	    val k = S.gen("_k")
	    fun comb' x = comb(Atomic(C.Lambda((ListPair.zip(renames,typcterms))@
					       [(k,objVar),
						(getEE env'',objVar),
						(getState env'',objVar)],
					       applyK(x,C.Var(k),env''))))
	  in
	    loop(argss,comb',env')
	  end
  in
    loop(arglists,(fn x=>x),E)
  end

Comment:
  when called, "mpdloop1" gets printed, then the error message appears.
  This is independent of the value of "x" (Atomic of Complex).
  As I said, am trying to reduce the error-generating code to manageable
  size and send that to you, but that may take a while.
Status: fixed in 0.75
----------------------------------------------------------------------
504. Another core dump
Submitter:	Markus Freericks
		mfx@cs.tu-berlin.de
Date:		28.1.92
Version:	0.75
System:		Sparc 2 (4/50), 16M, SunOS
Severity:	Major, at least for me

This is a followup to my earlier message. The following code dumps
core on my machine, even though it is interpreted!
(I hadn't got the nerve to reduce it any further, because startup-time
for sml on this system is in the order of 30 seconds)

Code:
SML_NJ.Control.interp :=true;

structure Symbol=Int

signature CTERM =
  sig
    datatype CONV = Check | Cast

    datatype T =
      Var of Symbol.T
    | Const of String.T
    | Apply of T list

    val print : outstream -> T -> unit

    end

structure Cterm : CTERM =
  struct
    datatype CONV = Check | Cast
    datatype T = 
      Var of Symbol.T
    | Const of String.T
    | Apply of T list

    fun indStringList indent =      
      fn Var(x) => [(indent,"var")]
       | Const(s) => [(indent,"const")]
       | Apply(args) =>
	   (List.foldR' 
	     (fn a => fn b => a @ b)
	     (map 
	      (fn (expr) => 
	       (indStringList (indent+1) expr))
	      args))

    fun print os x = ((indStringList 1 x);())
      
  end

structure B =
  struct
    structure S = Symbol
    structure SS = Int
    structure C = Cterm

    type Env = bool
      
    datatype ACexpr = 
      Atomic of C.T
    | Complex of C.T -> C.T 
      
    type TexprResult = {free:SS.T,used:SS.T,expr:ACexpr}
    type Texpr = {env:Env} -> TexprResult

    fun mkDummyExpr(x) : Texpr = fn {env=E} => {free = 1 ,
						used = 2 ,
						expr = Atomic(C.Const("\"dummyE:"^x^"\""))}
      
    val dummyExpr = mkDummyExpr("")
	  
    val objVar = C.Var(1)

    fun makeParamDecl((id,arglists:((S.T * Texpr) list list)),body : Texpr)=
      fn {env=E} =>
      let
	fun loop ([],comb:ACexpr->ACexpr,env) 
	   = let
	       val {free=f,used=u,expr=e} = body {env=env}
	     in
	       {defs = [id],
		expr = {free=f,
			used=u,
			expr=comb(e)
			}}
	     end
	   | loop (args::argss,comb,env) 
	     = let
		 (* rename the parameters if necessary *)
		 val params = map #1 args (* typcon mismatch if *)
					  (* commented out *)
		 val typtexprs = map (fn (a,b)=>b) args
		 val typacterms= map (fn x => x {env=env}) typtexprs
					(* typacterms=[Atomic(objVar)] would be ok *)
					(* [] instead of typtexprs would be ok,too *)
		 val _ = output(std_out,"makeParamDecl-2\n")
		 val typcterms = map (fn x => (output(std_out,"mpdloop1\n");
(*XXXX*)
					       (case x of
						  (Complex _) => output(std_out,"complex\n")
						| (Atomic _) =>  output(std_out,"atomic\n"));
						  output(std_out,"mpdloop2\n");
						  (case x of 
						     Atomic(X) => (
								   (*this here print causes the error!*)
								   Cterm.print std_out X;
								   X)
						   | Complex(Y)=> (output(std_out,"error: type var must be atomic:\n");
								   Cterm.print std_out (Y objVar);
								   objVar))
						     )) typacterms
		 val _ = output(std_out,"makeParamDecl-5\n")
	       in
		 loop(argss,comb,env)
	       end
      in
	loop(arglists,(fn x=>x),E)
      end
    
  end;

val xx = B.makeParamDecl((12,
			  [[(1,B.dummyExpr)]]),
			 B.dummyExpr
			 );
  
  
fun killMe() = xx({env=true})

(* calling killMe results in a bus error *)

killMe()

Comment:
  The main problem seems to be the type error at (*XXXX*): 
  "typtexprs" is of type "Texpr", so "typacterms" is a "TexprResult",
  not an "ACterm", as assumed by the "case x of Atomic...".

  This being undetected, a runtime error follows quite naturally. Funny
  enough, if the "Apply" clause in "indStringList" is removed by some
  simple rhs that doesn't inspect the argument of the Apply, no runtime error
  occurs.

  PS. After having found the type error, the function runs fine. Guess
  that makes the Severity "minor, at least for me".

Status: fixed in 0.75
----------------------------------------------------------------------
505. bad datatype definition accepted
Submitter: John Reppy
Date: 1/28/92
Version: 0.76
Severity: minor
Problem: 
  The following is not legal SML (cf. Definition, sec 2.9), but is
  accepted by the compiler:
Transcript: 
  Standard ML of New Jersey, Version 0.76, December 14, 1991
  Arrays have changed; see Release Notes
  val it = () : unit
  - datatype foo = FOO of int | BAR and bar = BAR;
  datatype  foo
  con BAR : foo
  con FOO : int -> foo
  datatype  bar
  con BAR : bar
Status: fixed in 0.91 (dbm)
----------------------------------------------------------------------
506. Runbind exception
Submitter:      Thomas M. Breuel <tmb@ai.mit.edu>
Date:		31 Jan 1992
Version:        0.75
System:         SparcStation IPC SunOS 4.1.1
Severity:       major (?)
Problem:        code dies with "uncaught exception Runbind" when put
		into "structure All"
Code:

local type time = System.Timer.time
    val timeofday : unit -> time = 
	System.Unsafe.CInterface.c_function "timeofday"
in 
    fun timeit f  = 
	let open System.Timer
	    val t = start_timer()
	    val rt = timeofday()
	    val z = f ()
	    val rt' = sub_time(timeofday(),rt)
	    val t' = check_timer t
	    val ts = check_timer_sys t
	    val tg = check_timer_gc t
	in
	    print(implode["user: ",makestring t',
			  "  gc: ", makestring tg, 
			  "  system: ",makestring ts,
			  "  real: ",makestring rt',"\n"]);
	    z
	end
end;

structure All = struct

signature RA2 =
    sig
	exception Subscript
	type array
	val array : (int * int) * real -> array
	val dim : array * int -> int
	val sub : array * (int * int) -> real
	val update : array * (int * int) * real -> unit
    end;

structure X:RA2 =
    struct
	structure R = RealArray
	exception Subscript = R.RealSubscript
	datatype array = A of (int * int) * R.realarray
	fun array((d0,d1),initial) = A((d0,d1),R.array(d0*d1,initial))
	fun dim(A((d0,d1),_),0) = d0
	  | dim(A((d0,d1),_),1) = d1
	  | dim _ = raise Subscript
	fun sub(A((d0,d1),a),(i,j)) = R.sub(a,i*d1+j)
	fun update(A((d0,d1),a),(i,j),v) = R.update(a,i*d1+j,v)
    end;

structure Y:RA2 =
    struct
	structure R = RealArray
	structure A = Array
	exception Subscript = R.RealSubscript (*HACK*)
	type array = R.realarray A.array
	fun dim(a,0) = A.length(a)
	  | dim(a,1) = R.length(A.sub(a,0))
	  | dim _ = raise Subscript
	fun array((d0,d1),initial) = A.tabulate(d0,fn j => R.array(d1,initial))
	fun sub(a,(i,j)) = R.sub(A.sub(a,i),j)
	fun update(a,(i,j),v) = R.update(A.sub(a,i),j,v)
    end;

functor Test(A2:RA2) =
    struct
	fun dotimes(n,f) =
	    let
		fun loop(i) = if i>=n then () else (f(i); loop(i+1))
	    in
		loop(0)
	    end
	fun foldtimes(n,r,f) =
	    let
		fun loop(i,r) = if i>=n then r else loop(i+1,f(r,i))
	    in
		loop(0,r)
	    end
	fun a before b = a
	fun fold(a,r,f) =
	    foldtimes(A2.dim(a,1),r,fn (r,y) =>
		      foldtimes(A2.dim(a,0),0.0,fn (r,x) =>
				(f(r,A2.sub(a,(x,y)))) before (A2.update(a,(x,y),r))))
	fun bound(x) = if x>=1.0 then bound(x-1.0) else x
	fun combine(x,y) = bound(x*1.17812+y)
	fun doit() =
	    let
		val w = 512
		val h = 512
		val a = A2.array((w,h),0.0001)
	    in
		dotimes(2,fn i => fold(a,0.0,combine))
	    end
	val _ = timeit(doit)
    end;

end;

open All;

Transcript:

Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- [opening compare.sml]
val timeit = fn : (unit -> 'a) -> 'a
compare.sml:25.1-33.7 Warning: signature found inside structure or functor
compare.sml:62.1-92.7 Warning: functor found inside structure or functor
structure All : 
  sig
    signature RA2 = 
      sig
        exception Subscript
        type array
        val array : (int * int) * real -> array
        val dim : array * int -> int
        val sub : array * (int * int) -> real
        val update : array * (int * int) * real -> unit
      end
    functor Test : <sig>
    structure X : RA2
    structure Y : RA2
  end
open All
[closing compare.sml]
val it = () : unit
- structure Dummy = Test(X);

uncaught exception Runbind
- 

Comments:

This seems to be different from the bugs relating to Runbind in
the masterbugs list (all of those claim to have been fixed or
claim to be unreproducible).

Status: fixed in 0.84
----------------------------------------------------------------------
507. most negative integer causes compiler bug (see also 630, 632)
Submitter: Thomas Yan (tyan@cs.cornell.edu)
Date: 2/3/92
Version: 0.75?
Severity: minor
Problem: 
  Sometimes the compiler has problems with the most negative integer:
Transcript: 
    fun f ~0x40000000 = 7;
    std_in:1.1-1.21 Warning: match not exhaustive
    ~1073741824 => ...
    Error: Compiler bug: Overflow in cps/generic.sml
    - 
Status: fixed in 0.90
----------------------------------------------------------------------
508. xorb
Submitter: Thomas Yan (tyan@cs.cornell.edu)
Date: 2/3/92
Version: 0.75?
Severity: minor
Problem: 
  xorb gives wrong answer
Transcript:
    - fun f x = x xorb  ~0x40000000;
    val f = fn : int -> int
    - f 0;
    val it = 
    uncaught exception Boxity
    - fun f x = x xorb  ~0x40000000;
    val f = fn : int -> int
    - f 0;
    val it = ~1073741824 : int
    - 
Status: fixed in 0.84
----------------------------------------------------------------------
509. compiler bug in number pattern
Submitter: Thomas Yan (tyan@cs.cornell.edu)
Date: 2/3/92
Version: 0.75?
Severity: minor
Problem: 
  Compiler bug in hexidecimal pattern
Transcript:
    - fun f 0x3fffffff = 2;
    std_in:3.1-3.20 Warning: match not exhaustive
    1073741823 => ...
    Error: Compiler bug: Overflow in cps/generic.sml
Comment:
    After looking at cps/generic.sml, I think the problem is with generating code
    with immediate data.  Often, things like (INT u) op v get translated into
    <machine op> (immed (u+u)) v, where the u+u is for the boxity scheme (the +1
    comes from v).  But when u is already near the limit, then u+u overflows.
    Obviously, it would be nice for this to get fixed.
Status: open (duplicate of 507)
----------------------------------------------------------------------
510. poor error message in ml-lex (same as 475)
Submitter: Reppy
Date: 2/1/92
Version: 0.75?
Severity: minor?
Problem: 
The following lex file

  %%
  special = [@#$%^&*_+=|\\/<>-];
  %%
  <INITIAL>\n      => (inc ln; lex());

produces

  ? sml-lex: uncaught exception LOOKUP

Comments:
  I believe this is because there are special characters in the [...],
  but this is a poor error message.
Status: same as 475
----------------------------------------------------------------------
511. dying on interupt with SIGEMT (same as 484, 518)
Submitter:	tmb@ai.mit.edu (Thomas M. Breuel)
Date:		January 14, 1992
Version:	0.75
System:		SunOS 4.1.?, Sparc IPC
Severity:	major
Problem:	When typing Control-C, the system dies with a SIGEMT
Code:		(this doesn't seem to be specific to any code)
Transcript:

- trymatches(model,image,BoundedMatch.eval,5.0,10.0,0.4);
((17.0,11.0),(222.0,175.0))
((5.0,5.00028),(552.0,473.0))
((~217.0,~169.99972),(535.0,462.0))
~217.0
~212.0
SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0xa150)

Process Inferior mysml exited abnormally with code 3

Comments:
    This is also given as bug 304 in the "masterbugs" list, but it is not
    listed in the "openbugs" list anymore. Did this bug come back or was
    it never fixed?
    Based on the PC info, this was probably an OS bug.  Changes to the
    GC invocation mechanism mean that it is moot. -- JHR
Status: fixed
----------------------------------------------------------------------
512. compiler looping
Submitter:      tmb@ai.mit.edu
Date:		January 15, 1992
Version:        0.75 (loaded+dumped mylib)
System:         SunOS 4.1.?, Sparc IPC
Severity:       major
Problem:        compiling the red-black tree code below inside the
		"structure ... = struct ... end" fills up memory
		and doesn't seem to terminate; compiling at top-level
		works fine
Code:

(* Red-Black Trees *)

signature ODICT =
    sig
	type 'a Dict
	val lookup : ('a -> 'b) * ('b * 'b -> bool) * 'a Dict * 'b -> 'a
	val insert : ('a -> 'b) * ('b * 'b -> bool) * 'a Dict * 'a -> 'a Dict
	val aslist : 'a Dict -> 'a list
    end;

structure RBTree:ODICT =
    struct
	datatype Color = Rd | Bl
	datatype 'a Node = ND of Color * 'a * 'a Node * 'a Node | LEAF;

	type 'a Dict = 'a Node
	    
	fun aslist(LEAF) = []
	  | aslist(ND(c,k,l,r)) = aslist(l) @ k @ aslist(r)
	    
	exception Lookup
	
	fun lookup(key,less,LEAF,k) = raise Lookup
	  | lookup(key,less,ND(_,v,l,r),k) =
	    if less(k,key(v)) then lookup(key,less,l,k)
	    else if less(key(v),k) then lookup(key,less,r,k)
	    else v
		
	fun rewrite(ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))) =
	    (ND(Rd,B,ND(Bl,A,alpha,beta),ND(Bl,C,gamma,delta)))
	  | rewrite(ND(Bl,C,ND(Rd,A,alpha,ND(Rd,B,beta,gamma)),delta)) =
	    ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))
	  | rewrite(ND(Bl,C,ND(Rd,B,ND(Rd,A,alpha,beta),gamma),delta)) =
	    ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))
	  | rewrite(ND(Bl,A,alpha,ND(Rd,B,ND(Rd,C,beta,gamma),delta))) =
	    ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))
	  | rewrite(ND(Bl,A,alpha,ND(Rd,B,beta,ND(Rd,C,gamma,delta)))) =
	    ND(Bl,B,ND(Rd,A,alpha,beta),ND(Rd,C,gamma,delta))
	  | rewrite x = x;

	fun insert(key,less,v,tree) =
	    let
		fun insert'(LEAF) = ND(Rd,v,LEAF,LEAF)
		  | insert'(ND(Bl,v',left,right)) =
		    if less(key(v),key(v')) then
			rewrite(ND(Bl,v',insert'(left),right))
		    else if less(key(v'),key(v)) then
			rewrite(ND(Bl,v',left,insert'(right)))
		    else
			ND(Bl,v',left,right)
		  | insert'(ND(Rd,v',left,right)) =
		    if less(key(v),key(v')) then
			ND(Rd,v',insert'(left),right)
		    else if less(key(v'),key(v)) then
			ND(Rd,v',left,insert'(right))
		    else
			ND(Rd,v',left,right);
		val ND(_,v,l,r)=insert'(tree)
	    in
		ND(Bl,v,l,r)
	    end
	
	fun create(key,less,l) =
	    let
		fun loop([],r) = r
		  | loop(x::xs,r) = loop(xs,insert(key,less,x,r))
	    in
		loop(l,LEAF)
	    end;
	    
	fun id x = x
	fun lt(x:int,y) = x<y
    end;

Transcript:

NJ/SML, mylib
val it = () : unit
- 			<--- I've comented out the structure...
                             surrounding the Red-Black tree code
[opening redblack.sml]
signature ODICT = 
  sig
    type 'a Dict
    val lookup : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'a -> 'b
    val insert : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'b -> 'b Dict
    val aslist : 'a Dict -> 'a list
  end
datatype  Color
con Bl : Color
con Rd : Color
datatype 'a  Node
con LEAF : 'a Node
con ND : Color * 'a * 'a Node * 'a Node -> 'a Node
type 'a  Dict = 'a Node
val aslist = fn : 'a list Node -> 'a list
exception Lookup
val lookup = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a Node * 'b -> 'a
val rewrite = fn : 'a Node -> 'a Node
redblack.sml:56.3-56.31 Warning: binding not exhaustive
        ND (_,v,l,r) = ...
val insert = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a * 'a Node -> 'a Node
val create = fn : ('a -> 'b) * ('b * 'b -> bool) * 'a list -> 'a Node
val id = fn : 'a -> 'a
val lt = fn : int * int -> bool
[closing redblack.sml]
val it = () : unit
- 			<--- I've put the structure ... = struct ... end back
[opening redblack.sml]
signature ODICT = 
  sig
    type 'a Dict
    val lookup : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'a -> 'b
    val insert : ('b -> 'a) * ('a * 'a -> bool) * 'b Dict * 'b -> 'b Dict
    val aslist : 'a Dict -> 'a list
  end

[Major collection...
[Increasing heap to 3420k]

[Increasing heap to 3560k]

[Increasing heap to 4260k]

[Increasing heap to 7760k]
 69% used (1952632/2809440), 2100 msec]

[Increasing heap to 8192k]

[Major collection... 94% used (3980248/4209932), 4600 msec]

[Increasing heap to 12344k]

[Major collection...
[Increasing heap to 18924k]
 94% used (6180760/6516556), 7060 msec]

[Increasing heap to 19104k]

[Major collection...
[Increasing heap to 29280k]

Process Inferior sml killed		<--- kill -9 <pid>

Comments:

BTW, do you have code to delete from persistent red-black trees?  It
gets really messy...
Status: fixed in 0.84
----------------------------------------------------------------------
513. not waiting for execute children
Submitter: Robert S. Thau (rst@ai.mit.edu)
Date: 1/20/92
Version: ?
Severity: major
Problem: 
  SML/NJ appears not to wait for children forked off by execute.  This can be
  a problem in certain circumstances.  In my particular case, I wrote a
  routine which draws graphs for the user by forking off an xplot and sending
  down plot commands.  After fifty graphs or so, the zombie xplots had
  completely filled my per-user process limit, making it difficult to
  determine the nature of the problem (ps: cannot fork: no more processes).

  In this particular case, I'd be more than willing to do the wait myself,
  but execute gives me no process-id to wait for, just the input and output
  streams. 

  [from Phil Jeffcock <P.J.Jeffcock@bradford.ac.uk>, 3/2/92]
  I'm running SML/NJ 0.75 on my SUN Sparc IPC. I've been writing an application
  which I need to use execute frequently and in doing so the ML runtime is
  creating a zombie process each time I use it. After a short while I run out
  of process slots. Any ideas?
Fix:
  just before doing the execute, do wait3(&status,WNOHANG,NULL) to clean
  up previous children, if any.
Status: fixed in 0.91 
----------------------------------------------------------------------
514. uncaught exception ErrorStructure
Submitter: John Reppy
Date: 1/15/92
Version: 0.76
Severity: minor
Problem: 
    I got the following uncaught exception when working on my Amber stuff:

      ...
      [opening join.sml]
      join.sml:6.25-6.38 Error: unbound functor: AmberLrValsFun
      [closing join.sml]
      [closing load]

      uncaught exception ErrorStructure
      - 

    I tried a few small examples, but I wasn't able to reproduce the
    bug.  The offending file ("join.sml") is:

      structure AmberLrVals = AmberLrValsFun (structure Token = LrParser.Token)
      structure AmberLex = AmberLexFun (structure Tokens = AmberLrVals.Tokens)
      structure AmberParser = Join (
	structure ParserData = AmberLrVals.ParserData
	structure Lex = AmberLex
	structure LrParser = LrParser)

    If I add a ";" to the first line, then I just get the error message.

  [from Jon Thackray <jont@harlqn.co.uk>, 4/8/92]:
     Ok, here's a stripped down version of the ErrorStructure problem. I
  don't believe it can get any smaller. The significant factors seems to
  be twofold, firstly, the missing parameter to the Mir_Utils functor,
  and secondly the sharing constraint between the parameters of this
  functor. The first factor in isolation is not sufficient to produce
  the problem, as far as I can tell. Hope this helps.

  signature MIRTYPES =
    sig
    end;

  signature MIRPRINT =
    sig
      structure MirTypes	: MIRTYPES
    end;

  functor Mir_Utils(
    structure MirTypes : MIRTYPES
    structure MirPrint : MIRPRINT

    sharing MirTypes = MirPrint.MirTypes
  ) =
  struct
  end;

  structure MirTypes_ =
    struct
    end;

  structure Mir_Utils_ = Mir_Utils(
    structure MirTypes = MirTypes_
  );

Status: fixed in 0.84
----------------------------------------------------------------------
515.  Compiler bug: patType -- unexpected pattern
Submitter:      jont@uk.co.harlqn
Date:		24/01/92
Version:        SML of NJ version 0.75
System:         Sun 4/330 with Sunos 4.1.1
Severity:       minor
Problem:        Compiler bug
Code:
    | has_a_new_name (TYFUN (CONSTYPE (_,METATYNAME{ref tyfun, ...}),_)) =

Transcript:

/usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml:383.57-383.61 Error: syntax error: inserting AS
/usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml:1177.38 Error: syntax error: inserting ASTERISK
Error: Compiler bug: patType -- unexpected pattern
[closing /usr/users/jont/ml/ml_compiler/src/typechecker/_types.sml]
Comments: same as #474?
Status: probably fixed in 0.83
----------------------------------------------------------------------
516. ml-lex gives uncaught exception LOOKUP (same as 475, 510)
Submitter: John Reppy
Date: 2/4/92
Version: ?
Severity: significant
Problem: 
One of my students was getting the following mysterious error message
from mllex:

  ? sml-lex: uncaught exception LOOKUP

upon examination, the problem is that he misspelled a character class
name.  The following small file will produce this behavior:
Code: 
  <jhr@bat> cat foo.lex
  (* test file *)

  %%

  foo = [a-z];

  %%

  <INITIAL>{foob}+                => (lex());
Status: same as 475
----------------------------------------------------------------------
517. type errors in examples/cat.sml
Submitter: Doug McIlroy
Date: 2/4/92
Version: ?
Severity: minor
Problem: 
  doc/examples/cat.sml contains type errors
Status: fixed for 0.90 (in /usr/local/sml/75/doc/examples/cat.sml)
----------------------------------------------------------------------
518. interrupt causes core dump (same as 484, 511)
Submitter:      jont@uk.co.harlqn
Date:		12/02/92
Version:        SML of NJ version number 0.75
System:         Sun 4/330 with SunOS 4.1.1
Severity:       minor
Problem:        Unreliability of NJ 0.75 with ^c
Transcript:
SIGEMT not related to gc (bogus test: 0x9de3bfc0 @ 0xa150)

Comments:
  This seems to happen a lot when using ctrl-c to halt a looping or long
  running program. Even if this doesn't happen, the image sometimes
  seems corrupt afterwards, in that it exhibits strange (impossible)
  behaviour that doesn't occur if it is recompiled from scratch to
  supposedly the same state. I suspect there is a critcial region
  problem somewhere.
Status: open
----------------------------------------------------------------------
519. System.system broken after loading sml-yacc output
Submitter: John Nestoriak <nestorak@cs.psu.edu>
Date: 2/16/92
Version: 0.75
Severity: major
Problem: 
  I'm having a problem using system calls from sml 75.  Something like 
  System.system "ls"; works fine until I load the output from sml-yacc.  Then
  I get uncaught exception SystemCall.  

  [from cazin@tls-cs.cert.fr (Jacques Cazin), 3/26/92]
  But we use also lexgen and mlyacc which are in the distribution. After
  having loaded lexgen, we cannot use "System.system" anymore:

		  System.system "pwd";  (or anything else)
  gives rise to 
		  uncaught exception SystemCall

  We  previously used  version  0.56 with  lexgen as  well  and  did not
  observe this behaviour.
Status: fixed in 0.86
----------------------------------------------------------------------
520. broken under IRIX 4.0.1
Submitter: Lindsay Errington <lindsay@cs.mu.OZ.AU>
Date: 2/17/92
Version: 0.75
System: SGI/IRIX 4.0.1
Severity: major
Problem: 
  I'm sorry to bother you with such a vague problem but I'm having a
  little trouble with your compiler under IRIX.  We've just upgraded from
  Irix 3.3.x to version 4.0.1 and since then any attempt to use the "use"
  function made SML 0.75 hang. I tried to re-compile the runtime but then
  it only gets as far as [Executing IEEEReal] before it hangs again. I've
  done a little diddling and as far as I can tell it's hung in prim.s.
  Any suggestions on where to start looking or whom to contact?
Status: Fixed in 0.81
----------------------------------------------------------------------
521. type checking flex records
Submitter:      Mark Leone (mleone@cs.cmu.edu)
Date:		2/12/92
Version:        0.75
System:         Decstation 2100 under Mach 2.6
Severity:       major
Problem:        Type checker doesn't handle flex records correctly.
Code:           fun foo x = let val a = #1 x
                                val (a,b) = x
	                    in
      		                b ()
       	                    end
Transcript:
  Standard ML of New Jersey, Version 75, November 11, 1991
  Arrays have changed; see Release Notes
  val it = () : unit
  - fun foo x = let val a = #1 x
		    val (a,b) = x
		in
		    b ()
		end
  ;
  = = = = = val foo = fn : 'a * 'b -> 'c
  - foo (0,0);

  Process sml segmentation fault
Comments: Type of foo should be ('a * (unit -> 'b)) -> 'b
Status: fixed in 0.85
----------------------------------------------------------------------
522. redundent patterms in compiler
Submitter: John Reppy
Date: 2/18/92
Version: 0.76?
Severity: minor
Transcript: 
  build/index.sml:177.4 Warning: redundant patterns in match
	  VALdec vbs => ...
	  VALRECdec rvbs => ...
	  TYPEdec tbs => ...
	  DATATYPEdec {datatycs=datatycs,withtycs=withtycs} => ...
	  ABSTYPEdec {abstycs=abstycs,body=body,withtycs=withtycs} => ...
	  EXCEPTIONdec ebs => ...
	  STRdec sbs => ...
	  ABSdec sbs => ...
	  FCTdec fbs => ...
	  SIGdec sigvars => ...
	  LOCALdec (inner,outer) => ...
	  SEQdec decs => ...
	  OPENdec strVars => ...
	  MARKdec (dec,L1,L2) => ...
	  FIXdec _ => ...
	  OVLDdec _ => ...
	  IMPORTdec _ => ...
    -->   _ => ...
  translate/translate.sml:259.30 Warning: redundant patterns in match
	  VALtrans (PATH p) => ...
	  VALtrans (INLINE POLYEQL) => ...
	  VALtrans (INLINE POLYNEQ) => ...
	  VALtrans (INLINE INLSUBSCRIPT) => ...
	  VALtrans (INLINE INLUPDATE) => ...
	  VALtrans (INLINE INLBYTEOF) => ...
	  VALtrans (INLINE INLSTORE) => ...
	  VALtrans (INLINE INLORDOF) => ...
	  VALtrans (INLINE INLFSUBSCRIPTd) => ...
	  VALtrans (INLINE INLFUPDATEd) => ...
	  VALtrans (INLINE i) => ...
	  THINtrans (PATH p,v,locs) => ...
	  CONtrans (d as DATACON {const=true,...}) => ...
	  CONtrans (d as DATACON {const=false,...}) => ...
	  VALtrans a => ...
	  THINtrans (a,_,_) => ...
    -->   _ => ...

  cps/cpsopt.sml:1129.4 Warning: redundant patterns in match
	  RECORD (vl,w,e) => ...
	  SELECT (i,v,w,e) => ...
	  OFFSET (i,v,w,e) => ...
	  APP (f,vl) => ...
	  FIX (l,e) => ...
	  SWITCH (v,_,el) => ...
	  BRANCH (_,vl,c,e1,e2) => ...
	  LOOKER (_,vl,w,e) => ...
	  SETTER (_,vl,e) => ...
	  PURE (_,vl,w,e) => ...
	  ARITH (args as (floor,_,_,_)) => ...
	  ARITH (args as (round,_,_,_)) => ...
	  ARITH (args as (fadd,_,_,_)) => ...
	  ARITH (args as (fdiv,_,_,_)) => ...
	  ARITH (args as (fmul,_,_,_)) => ...
	  ARITH (args as (fsub,_,_,_)) => ...
	  ARITH (_,vl,w,e) => ...
    -->   PURE (args as (fnegd,v :: nil,w,e)) => ...
    -->   PURE (real,vl,w,e) => ...
Status: Fixed in 0.81
----------------------------------------------------------------------
523. printing uncaught exceptions
Submitter:      Richard O'Neill <richard@smaug.questor.wimsey.bc.ca>
Date:		Thu Feb 27 14:32:47 PST 1992
Version:        0.75
System:         NeXTstation, OS2.1
Severity:       Major annoyance
Problem:        
If a value happens to be of type exn, the top level loop won't
print out the value, but instead says 'val it = exn : exn'; this
is not acceptable behaviour in my opinion.

When debugging, I like to be able to pass back information when an
fatal exception is raised. It is bad enough that if you have:

	exception InvalidKey of int;
  ...
	raise InvalidKey 6502;

it gives the message

	uncaught exception InvalidKey
and not:
	uncaught exception: InvalidKey 6502

(But the 'Io' exception does 'do the right thing'- special case
treatment or what :o)

But I can put up with that - what really annoys me is that even
the top level won't print exception values, i.e.

	- val theException = InvalidKey 6502;
	val theException = exn : exn

In order to find the value, I need to do:

	- case theException of InvalidKey key => key;
	std_in:3.1-3.42 Warning: match not exhaustive
		InvalidKey key => ...
	val it = 6502 : int

This is annoying, because it means more work for me to do, especially
if the datastructure is a *chain* of exception values (e.g. something
like 'exception ReraiseBacktrace of functionName * parameters *
exn' - you get the idea anyway). In such a case, I have to follow
the chain *by hand*.

I realise that printing exeptions may be harder than printing
ordinary constructors, but don't think this is a good reason not
to print them.

[Richard O'Neill, 11/24/92]
Standard ML of New Jersey, Version 0.92, November 18, 1992
val it = () : unit
- val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"];
val some_exceptions = [exn,exn,exn,exn] : exn list
- ^D

If a value happens to be of the exception type, it is always printed
in a most uninformative way.

Obviously, I'd like to see:

Standard ML of New Jersey, Version 0.93, February 17, 1993 ;-)
val it = () : unit
- val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"];
val some_exceptions = [Interrupt, Match, Bind, Io "Foobar"] : exn list
- ^D

Thus bug already has a number, 523, but the title "printing uncaught
exceptions" is misleading, and I expect probably the reason it hasn't
been fixed (yet). (Better printing of uncaught exceptions would be nice
too, but that is far less important to me).

Unless I'm seriously mistaken, this bug would only take minutes to fix, for
someone who knows SML-NJ's data-structures.

Comment: (awa)
Fixed a little bit; exn values now print a top level, but not the
value carried by the constructor.

Status: not entirely a bug
----------------------------------------------------------------------
524. weak polymorphism
Submitter: shail@au-bon-pain.lcs.mit.edu (Shail Aditya)
Date: 12/19/91
Version: ?
Severity: major
Problem: 
	  I ran across this quirk in the ranked weak type inference in
  SML-NJ. I am running the version 0.75 on Sparc (sunos). 

  - val g3 = (fn f => (fn x => f x));
  val g3 = fn : ('a -> 'b) -> 'a -> 'b

  - g3 ref;
  std_in:5.1-5.6 Error: nongeneric weak type variable
    it : '0Z -> '0Z ref
  -

  The "ref" does not happen until another argument is supplied to "g3
  ref", so proper ranking analysis should have made its type to be 
  "'1a -> '1a ref" without any error.

  - val g = (fn x => x);
  val g = fn : 'a -> 'a
  - g ref;
  std_in:3.1-3.5 Error: nongeneric weak type variable
    it : '0Z -> '0Z ref

  But the following works.

  - val h = (fn x => let val g = fn x => x in g ref end);
  val h = fn : 'a -> '1b -> '1b ref
  -  val h = (fn x => let val g = (fn f => (fn x => f x)) in g ref end);
  val h = fn : 'a -> '1b -> '1b ref
  - 

  Basically, it seems that "ref" is opened up to the enclosing lambda
  rank unnecessarily when it is passed as an argument. This system works
  fine in first order situations but fails in higher order argument
  passing when the arguments are weakly polymorphic functions. 

  Am I to understand that the ranked system of SML-NJ is not powerful
  enough to keep track of weak polymorphism across higher order function
  applications? Or is this merely a bug? 

  I would like to obtain a clearer description of the ranked system you
  follow. Preferably in terms of a paper that gives the inference rules.
  I have a system that behaves similarly, only that it allows toplevel
  non-ground weak types as well. I would like to know the SML-NJ
  solution better. Do you have any pointers? 
Status: not a bug (a "feature" of weak polymorphism)
----------------------------------------------------------------------
525. IO.execute broken
Submitter:	Mikael Pettersson, mpe@ida.liu.se
Date:		Jan 7, 1992
Version:	0.75
System:		SPARCstation ELC, SunOS 4.1.1
Severity:	major
Problem:	the input stream from IO.execute is unusable:
		can_input and close_in fail with exceptions,
		input causes a segmentation violation
Transcript:
  ====
  - val (is,_) = execute("/bin/echo",["foo"]);
  val is = - : instream
  - close_in is;

  uncaught exception Io "close_in "<pipe_in>": close failed, Bad file number"
  ====
  - val (is,_) = execute("/bin/echo",["foo"]);
  val is = - : instream
  - input(is,1);
  Segmentation fault (core dumped)
  ====
  - val (is,_) = execute("/bin/echo",["foo"]);
  val is = - : instream
  - can_input is;

  uncaught exception SystemCall
  - (can_input is) handle (System.Unsafe.CInterface.SystemCall s) => (print s; print "\n"; 999);
  fionread failed, Bad file number
  val it = 999 : int
Status: fixed in 0.84
----------------------------------------------------------------------
526. Harlequin gripes
Submitter: Andrew Tolmach
Date: 3/2/92
Version: 0.75
Severity: minor
Problem: 
  1) If one uses polymorphic equality on, say, integer types, the equality test
  is much slower than using a type-specific equality operator.  This was probably
  in the context of functors, in which case its no big surprise, but might
  bear looking into further.

  2) They were unhappy with the time cost of referencing elements out of
  structures at runtime.  They often do something like inserting an explicit
  declaration

    val thing = A.thing

  same thing for them automatically.  They also suggested that we don't tend
  to notice this problem because we use "open" all over the place, a practice
  they abominate.
Status: not a bug
----------------------------------------------------------------------
527. uncaught exception Subscript while printing value of a datatype
Submitter: John Reppy
Date: 3/9/92
Version: 0.78
Severity: major
Problem: 
  compiling following code causes uncaught exception Subscript
Code: 
(* string-util.sml
 *
 * Various string utilities.
 *)

structure StringUtil =
  struct

    datatype relation_t = Equal | LessTh | GreaterTh

  (* lexically compare two strings and return their relation *)
    fun strcmp (s1, s2) = (case (size s1, size s2)
	   of (0, 0) => Equal
	    | (0, _) => LessTh
            | (_, 0) => GreaterTh
            | (n1, n2) => let
		fun loop i = let
		      val c1 = ordof(s1, i) and c2 = ordof(s2, i)
                      in
                         if (c1 = c2)
                           then loop(i+1)
                         else if (c1 < c2)
                           then LessTh
                           else GreaterTh
                      end
                in
                  (loop 0) handle _ => (
                     if (n1 = n2)
                       then Equal
                     else if (n1 < n2)
                       then LessTh
                       else GreaterTh)
		end (* strcmp *)
	    (* end case *))

  (* Lexically sort a list of values with unique string keys.  The function
   * proj extracts the key of an item.  Raise Repeat if two items have the
   * same key.
   *)
    exception Repeat of string
    fun sortStrings proj = let
	  fun le (f1, f2) = (case strcmp(proj f1, proj f2)
		 of LessTh => true
		  | GreaterTh => false
		  | Equal => raise Repeat(proj f1)
		(* end case *))
	  fun insert (f, []) = [f]
	    | insert (f, l as (f'::r)) =
		if le(f, f') then f::l else f'::insert(f, r)
	  fun sort ([], l) = l
	    | sort (f::r, l) = sort(r, insert(f, l))
	  in
	    fn l => sort (l, [])
	  end

  end (* StringUtil *)

(* this is a SML implementation of Luca's Amber code *)

(* Types are represented by values in the following type.  Rec bound variables
 * in a recursive type are represented by the RecTy node in which they are bound.
 * For example, the representation of the following Amber type
 *
 *   rec (t) [nil : Unit, cons : {hd : Int, tl : t}]
 *
 * is constructed by the following ML code:
 *
 * let
 *   val recBody = ref Any
 *   val recTy = RecTy{bind = "t", typ = recBody}
 *   val body = VariantTy[
 *           FieldTy{tag = "nil", typ = BaseTy UnitTy},
 *           FieldTy{tag = "cons", typ = RecordTy[
 *               FieldTy{tag = "hd", typ = BaseTy IntTy},
 *               FieldTy{tag = "tl", typ = recTy},
 *             ]
 *         ]
 * in
 *   recBody := body;
 *   recTy
 * end
 *)

datatype base_ty = UnitTy | BoolTy | IntTy | StringTy | DynamicTy

datatype typ
  = AnyTy
(*  | ExistTy of {name : string, instance : typ option, suptypes : typ list}*)
  | BaseTy of base_ty
  | FunTy of (typ * typ)
  | TupleTy of typ list
  | RecordTy of field_ty list		(* assume fields are sorted by tag *)
  | VariantTy of field_ty list
  | RecTy of {bind : string, typ : typ ref}
  | ArrayTy of typ
  | ChannelTy of typ
and field_ty = FieldTy of {tag : string, typ : typ}

fun seen (stk, ty1 : typ, ty2 : typ) = let
      val x = (ty1, ty2)
      fun look [] = false
	| look (y::r) = (x = y) orelse look r
      in
	look stk
      end

(* return true if the types are "equal" *)
fun sameType (ty1, ty2) = let
      fun sameTy (AnyTy, _, _) = true
	| sameTy (_, AnyTy, _) = true
	| sameTy (BaseTy b1, BaseTy b2, _) = (b1 = b2)
	| sameTy (FunTy(t1, s1), FunTy(t2, s2), stk) =
	    sameTy(t1, t2, stk) andalso sameTy(s1, s2, stk)
	| sameTy (TupleTy tl1, TupleTy tl2, stk) = let
	    fun sameTyList ([], []) = true
	      | sameTyList (ty1::r1, ty2::r2) =
		  sameTy(ty1, ty2, stk) andalso sameTyList(r1, r2)
	    in
	      sameTyList(tl1, tl2)
	    end
	| sameTy (RecordTy fl1, RecordTy fl2, stk) = sameFieldList (fl1, fl2, stk)
	| sameTy (VariantTy fl1, VariantTy fl2, stk) = sameFieldList (fl1, fl2, stk)
	| sameTy (ty1 as RecTy{typ=ty1', ...}, ty2 as RecTy{typ=ty2', ...}, stk) =
	    (ty1' = ty2')
	    orelse seen(stk, ty1, ty2)
	    orelse sameTy(!ty1', !ty2', (ty1, ty2)::stk)
	| sameTy (ty1 as RecTy{typ, ...}, ty2, stk) =
	    seen(stk, ty1, ty2) orelse sameTy(!typ, ty2, (ty1, ty2)::stk)
	| sameTy (ty1, ty2 as RecTy{typ, ...}, stk) =
	    seen(stk, ty1, ty2) orelse sameTy(ty1, !typ, (ty1, ty2)::stk)
	| sameTy (ArrayTy ty1, ArrayTy ty2, stk) = sameTy(ty1, ty2, stk)
	| sameTy (ChannelTy ty1, ChannelTy ty2, stk) = sameTy(ty1, ty2, stk)
	| sameTy _ = false
      and sameFieldList ([], [], _) = true
	| sameFieldList (FieldTy{tag=a, typ=t}::r1, FieldTy{tag=b, typ=s}::r2, stk) =
	    (a = b) andalso sameTy(t, s, stk) andalso sameFieldList(r1, r2, stk)
	| sameFieldList _ = false
      in
	sameTy (ty1, ty2, [])
      end

(* return true, if ty1 is a subtype of ty2 *)
fun isSubtyOf (ty1, ty2) = let
      exception TypeError
    (* given two sorted lists of field types, where the second should contain all of
     * tags of the first list, return the projection of those fields from the second
     * list.
     *)
      fun projFieldList (fl1, fl2) = let
	    fun proj ([], _, l) = rev l
	      | proj (_, [], _) = raise TypeError
	      | proj (
		  l1 as (FieldTy{tag=a, ...}::r1),
		  l2 as ((f as FieldTy{tag=b, ...})::r2), l
		) = (
print(implode["proj: a = ", a, ", b = ", b, "\n"]);
		  case (StringUtil.strcmp(a, b))
		   of StringUtil.Equal => proj (r1, r2, f::l)
		    | StringUtil.GreaterTh => proj (l1, r2, l)
		    | StringUtil.LessTh => proj (r1, l2, l)
		  (* end case *))
	    in
	      proj (fl1, fl2, [])
	    end
      fun subTy (AnyTy, _, _) = true
	| subTy (_, AnyTy, _) = true
	| subTy (BaseTy b1, BaseTy b2, _) = (b1 = b2)
	| subTy (ty1 as RecTy{typ=ty1', ...}, ty2 as RecTy{typ=ty2', ...}, stk) =
	    (ty1' = ty2')
	    orelse seen(stk, ty1, ty2)
	    orelse subTy(!ty1', !ty2', (ty1, ty2)::stk)
	| subTy (ty1 as RecTy{bind, typ}, ty2, stk) =
	    seen(stk, ty1, ty2) orelse subTy(!typ, ty2, (ty1, ty2)::stk)
	| subTy (ty1, ty2 as RecTy{bind, typ}, stk) =
	    seen(stk, ty1, ty2) orelse subTy(ty1, !typ, (ty1, ty2)::stk)
	| subTy (FunTy(ty1, ty2), FunTy(ty1', ty2'), stk) =
	    subTy(ty1', ty1, stk) andalso subTy(ty2, ty2', stk)
	| subTy (TupleTy tl1, TupleTy tl2, stk) = let
	    fun subTyList ([], []) = true
	      | subTyList (t1::r1, t2::r2) =
		  subTy(t1, t2, stk) andalso subTyList(r1, r2)
	      | subTyList _ = false
	    in
	      subTyList(tl1, tl2)
	    end
	| subTy (RecordTy f1, RecordTy f2, stk) = let
	    val f1' = projFieldList (f2, f1)
	    in
	      subFieldList (f1', f2, stk)
	    end
	| subTy (VariantTy f1, VariantTy f2, stk) = let
	    val f2' = projFieldList (f1, f2)
	    in
	      subFieldList (f1, f2', stk)
	    end
	| subTy (ArrayTy ty1, ArrayTy ty2, _) = sameType(ty1, ty2)
	| subTy (ChannelTy ty1, ChannelTy ty2, _) = sameType(ty1, ty2)
	| subTy _ = false
    (* this should only be called on field lists that have the same tags *)
      and subFieldList ([], [], _) = true
	| subFieldList (FieldTy{typ=t, ...}::r1, FieldTy{typ=s, ...}::r2, stk) =
	    subTy(t, s, stk) andalso subFieldList(r1, r2, stk)
      in
	(subTy (ty1, ty2, [])) handle TypeError => false
      end

fun revApp ([], l) = l
  | revApp (x::r, l) = revApp(r, x::l)

(* Return the union of two field lists, with f mapped over their intersection. *)
fun unionFieldMap f = let
      fun union ([], [], l) = revApp (l, [])
	| union ([], l2, l) = revApp (l, l2)
	| union (l1, [], l) = revApp (l, l1)
	| union (
	    l1 as ((f1 as FieldTy{tag=a, typ=t1})::r1),
	    l2 as ((f2 as FieldTy{tag=b, typ=t2})::r2), l
	  ) = (case (StringUtil.strcmp(a, b))
	     of StringUtil.Equal =>
		  union (r1, r2, FieldTy{tag = a, typ = f(t1, t2)}::l)
	      | StringUtil.GreaterTh => union (l1, r2, f2::l)
	      | StringUtil.LessTh => union (r1, l2, f1::l)
	    (* end case *))
      in
	fn (fl1, fl2) => union (fl1, fl2, [])
      end

(* Map f over the intersection of two field lists *)
fun interFieldMap f = let
      fun inter ([], _, l) = revApp (l, [])
	| inter (_, [], l) = revApp (l, [])
	| inter (
	    l1 as (FieldTy{tag=a, typ=t1}::r1),
	    l2 as (FieldTy{tag=b, typ=t2}::r2), l
	  ) = (case (StringUtil.strcmp(a, b))
	     of StringUtil.Equal =>
		  inter (r1, r2, FieldTy{tag = a, typ = f(t1, t2)}::l)
	      | StringUtil.GreaterTh => inter (r1, l2, l)
	      | StringUtil.LessTh => inter (l1, r2, l)
	    (* end case *))
      in
	fn (fl1, fl2) => inter (fl1, fl2, [])
      end

exception Join
fun joinTy (AnyTy, _) = AnyTy
  | joinTy (_, AnyTy) = AnyTy
  | joinTy (ty as BaseTy b1, BaseTy b2) =
      if (b1 = b2) then ty else raise Join
  | joinTy (TupleTy tl1, TupleTy tl2) = let
      fun joinTyList ([], []) = []
	| joinTyList ([], _) = raise Join
	| joinTyList (_, []) = raise Join
	| joinTyList (ty1::r1, ty2::r2) = joinTy(ty1, ty2) :: joinTyList(r1, r2)
      in
	TupleTy(joinTyList (tl1, tl2))
      end
  | joinTy (FunTy(ty1, ty2), FunTy(ty1', ty2')) =
      FunTy(meetTy (ty1, ty1'), joinTy (ty2, ty2'))
  | joinTy (RecordTy fl1, RecordTy fl2) =
      RecordTy (interFieldMap joinTy (fl1, fl2))
  | joinTy (VariantTy fl1, VariantTy fl2) =
      VariantTy (unionFieldMap joinTy (fl1, fl2))
and meetTy (AnyTy, _) = AnyTy
  | meetTy (_, AnyTy) = AnyTy
  | meetTy (ty as BaseTy b1, BaseTy b2) =
      if (b1 = b2) then ty else raise Join
  | meetTy (TupleTy tl1, TupleTy tl2) = let
      fun meetTyList ([], []) = []
	| meetTyList ([], _) = raise Join
	| meetTyList (_, []) = raise Join
	| meetTyList (ty1::r1, ty2::r2) = meetTy(ty1, ty2) :: meetTyList(r1, r2)
      in
	TupleTy(meetTyList (tl1, tl2))
      end
  | meetTy (FunTy(ty1, ty2), FunTy(ty1', ty2')) =
      FunTy(joinTy (ty1, ty1'), meetTy (ty2, ty2'))
  | meetTy (RecordTy fl1, RecordTy fl2) =
      RecordTy (unionFieldMap meetTy (fl1, fl2))
  | meetTy (VariantTy fl1, VariantTy fl2) =
      VariantTy (interFieldMap meetTy (fl1, fl2))


(**** Test code ***)

fun mkRecTy (id, mkTy) = let
      val recBody = ref AnyTy
      val recTy = RecTy{bind = id, typ = recBody}
      in
	recBody := mkTy(recTy);
	recTy
      end
fun mkVar1 (tag, ty) = VariantTy[FieldTy{tag = tag, typ = ty}]
val unitTy = BaseTy UnitTy
val intTy = BaseTy IntTy

(* rec (t) [nil : Unit, cons : {hd : Int, tl : t}] *)
val intListTy = mkRecTy("t",
      fn recTy => VariantTy[
              FieldTy{tag = "nil", typ = unitTy},
              FieldTy{tag = "cons", typ = RecordTy[
                  FieldTy{tag = "hd", typ = intTy},
                  FieldTy{tag = "tl", typ = recTy}
                ]}
            ])

(* [cons : {hd : Int, tl : [nil : Unit]}] *)
val intListTy' = VariantTy[
        FieldTy{tag = "cons", typ = RecordTy[
            FieldTy{tag = "hd", typ = intTy},
            FieldTy{tag = "tl", typ = VariantTy[
		FieldTy{tag = "nil", typ = unitTy}
	      ]}
          ]}
      ]
====
The following shorter example causes an uncaught subscript in 0.77 & 0.78 (but
not in 0.77b):

  datatype tree = Leaf of int | Plus of (tree * tree * int);
  (Plus (Leaf 0,Leaf 1,2),2);

for example:

  Standard ML of New Jersey, Version 0.78, February 26, 1992
  Arrays have changed; see Release Notes
  val it = () : unit
  - datatype tree = Leaf of int | Plus of (tree * tree * int);
  datatype  tree
  con Leaf : int -> tree
  con Plus : tree * tree * int -> tree
  - (Plus (Leaf 0,Leaf 1,2),2);
  val it = (Plus (
  uncaught exception Subscript
  - 
Comment: 
  Bug appeared between 0.77b and 0.77.  Possibly related to change
  in dataconstructor representations.

Submitter:      Andrzej Filinski <andrzej@cs.cmu.edu>
Date:		March 19, 1992
Version:        0.78
System:         All
Severity:       Major
Problem:        Printing certain datatype values raises Subscript
Transcript:     Standard ML of New Jersey, Version 0.78, February 26, 1992
		Arrays have changed; see Release Notes
		val it = () : unit
		- datatype foo = BAR of int | BAZ of foo * foo;
		datatype  foo
		con BAR : int -> foo
		con BAZ : foo * foo -> foo
		- BAZ (BAR 1, BAR 2);
		val it = BAZ (
		uncaught exception Subscript
		-
  [Bob Harper, 4/10/92]:
  Dave Tarditi suggested that the constructor printing problem might be due to
  the fact that something or other got reversed in the code generator, but this
  was forgotten in the print routines.  Apparently some representation is now
  done in reverse order.

  I consistently get the following behavior:
  1. Build a system using SourceGroup.make.
  2. Open a particular structure, making available a constructor Abs (among
     many others).
  3. Modify things, do another make.
  4. Uses of Abs suddenly get weird type errors.  Typing Abs at top level
     results in "val it = exn : exn".

  I could send the whole system, but this seems excessive....
Status: fixed in 0.84
----------------------------------------------------------------------
528. Compiler bug: ModuleUtil.teststr 2
Submitter:      Ian Green, aisb@ed.ac.uk
Date:		18-Mar-92
Version:        0.75
System:         Sun SPARC 1+, SunOS 4.1
Severity:       john major
Problem:        Error: Compiler bug: ModuleUtil.teststr 2
Code:           

************ UnifyFUN.sml *************
import "TermsSIG";
import "UnifySIG";

functor Unifier(structure Terms:TERMS):UNIFY = 
    struct
	local
	    open Terms
	    fun unifyst _ _ _ = []
	in
	    fun mgu t1 t2 = unifyst [] [(t1,t2)] []
		handle No_Unifier => []
	end
    end
****************************************

************ UnifySIG.sml **************
import "TermsSIG";

signature UNIFY =
    sig
	local
	    structure Terms:TERMS
	    open Terms
	in
	    val mgu : Terms.term -> Terms.term -> (Terms.atom * Terms.term) list
	end
    end
*****************************************

********** TermsSIG.sml ***************
signature TERMS =
    sig
	datatype atom = Var of string 
	  |  Const of string
	datatype term =
	    Atomic of atom
	  | Term of atom * term list
	  | WhereTerm of atom list * term * term;
	val subst : atom list -> (atom * term) list -> term -> term
    end;
****************************************
    
************ TermsFUN.sml *************
import "TermsSIG";

functor Terms( ):TERMS =
    struct
	datatype atom = Var of string 
	  |  Const of string
	datatype term =
	    Atomic of atom
	  | Term of atom * term list
	  | WhereTerm of atom list * term * term;
	fun subst _ _ t = t (* i like this case *)
    end;
****************************************

************ load ******************
import "TermsFUN";
import "UnifyFUN";

structure Term = Terms( );

structure Unify = Unifier(structure Terms = Term);
****************************************

Transcript: 

In summary, I do three `use "load"' starting with no bin files.  The
first gives no error, but i get <erro> types (what does that mean).
Second time a recompile is needed (odd?) and get a Compiler bug:

On the third try, no recompile needed, but get same compiler bug
report.  Here it is in all its (gory) detail. 
---------------------------------------------------------
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "load";
[opening load]
[reading TermsFUN.sml]
  [reading TermsSIG.sml]
  [writing TermsSIG.bin... done]
  [closing TermsSIG.sml]
[writing TermsFUN.bin... done]
[closing TermsFUN.sml]
functor Terms
signature TERMS
[reading UnifyFUN.sml]
  [reading TermsSIG.bin... done]
  [reading UnifySIG.sml]
    [reading TermsSIG.bin... done]
UnifySIG.sml:6.6-8.1 Warning: LOCAL specs are only partially implemented
  [writing UnifySIG.bin... done]
  [closing UnifySIG.sml]
[writing UnifyFUN.bin... done]
[closing UnifyFUN.sml]
functor Unifier
signature UNIFY
signature TERMS
structure Term :
  sig
    datatype atom
      con Const : string -> atom
      con Var : string -> atom
    datatype term
      con Atomic : atom -> term
      con Term : atom * term list -> term
      con WhereTerm : atom list * term * term -> term
    val subst : atom list -> (atom * term) list -> term -> term
  end

structure Unify : UNIFY
[closing load]
val it = () : unit
- Unify.mgu;
val it = fn : <error> -> <error> -> (<error> * <error>) list
- use "load";
[opening load]
[reading TermsFUN.bin... ]
[import(s) of TermsFUN are out of date; recompiling]
[closing TermsFUN.bin]
[reading TermsFUN.sml]
  [reading TermsSIG.bin... done]
[writing TermsFUN.bin... done]
[closing TermsFUN.sml]
functor Terms
signature TERMS
[reading UnifyFUN.bin... done]
functor Unifier
signature UNIFY
signature TERMS
structure Term :
  sig
    datatype atom
      con Const : string -> atom
      con Var : string -> atom
    datatype term
      con Atomic : atom -> term
      con Term : atom * term list -> term
      con WhereTerm : atom list * term * term -> term
    val subst : atom list -> (atom * term) list -> term -> term
  end

Error: Compiler bug: ModuleUtil.teststr 2
[closing load]
- use "load";
[opening load]
[reading TermsFUN.bin... done]
functor Terms
signature TERMS
[reading UnifyFUN.bin... done]
functor Unifier
signature UNIFY
signature TERMS
structure Term :
  sig
    datatype atom
      con Const : string -> atom
      con Var : string -> atom
    datatype term
      con Atomic : atom -> term
      con Term : atom * term list -> term
      con WhereTerm : atom list * term * term -> term
    val subst : atom list -> (atom * term) list -> term -> term
  end

Error: Compiler bug: ModuleUtil.teststr 2
[closing load]
-

Comments:  I see from the compiler that LOCAL specs are only partially
implemented, so this is probably the cause, though i dont get the
<error> bit.  As I am new to modules in ML, its all probably
meaningless code anyway, but I thought I ought to drop you a line.

Status: cannot reproduce (bug report incomplete); probably fixed.
----------------------------------------------------------------------
529. memory leak
Submitter: schristensen@daimi.aau.dk (Soren Christensen)
Date: 3/20/92
Version: 0.75
Severity: major
Problem: 
  I have a problem that my system slows down after running a short while.
  Instead of using the ordinary top-loop of the compiler I run my own. This
  means that I evaluate ML code in the following way:

  use_stream (open_string "code");

  It seems that this construct creates 16 bytes of "garbage" which is never
  collected.

  My first idea was that I needed to close the stream which is created, i.e.,

  let
    val is = open_string "code"
  in
   use_stream is;
   close_in is
  end;

  But this does not fix the problem.

  It seems that "close_in is" have no effect. At least it reports no errors
  when a use_string is performed on a stream which has been closed.

Status: fixed in 0.84
----------------------------------------------------------------------
530. missing space in printing abstype declaration
Submitter:      Mikael Pettersson, mpe@ida.liu.se
Date:           March 20 1992
Version:        0.75
System:         all
Severity:       minor
Problem:        when printing a polymorphic abstype, no space is inserted
                between the "type" symbol and the type variable
Transcript:

- abstype 'a foo = FOO of 'a list
= with
=   fun mkfoo() = FOO []
= end;
type'a  foo		(* note: missing space after "type" *)
val mkfoo = fn : unit -> 'a foo

Fix:

--cut here--
*** src/print/printdec.sml.~1~	Fri Oct 18 23:21:13 1991
--- src/print/printdec.sml	Fri Mar 20 14:00:07 1992
***************
*** 50,56 ****
  	     printSym name; print " = "; printType env def; newline())
  
  	and printAbsTyc(GENtyc{path=name::_, arity, eq, kind=ref(ABStyc _), ...}) =
! 	    (print(if (!eq=YES) then "eqtype" else "type"); 
  	     printFormals arity; print " ";
  	     printSym name; newline())
  
--- 50,56 ----
  	     printSym name; print " = "; printType env def; newline())
  
  	and printAbsTyc(GENtyc{path=name::_, arity, eq, kind=ref(ABStyc _), ...}) =
! 	    (print(if (!eq=YES) then "eqtype " else "type "); 
  	     printFormals arity; print " ";
  	     printSym name; newline())
  
--cut here--
Status: fixed in 0.86
----------------------------------------------------------------------
531. Compiler bug: CoreLang.makeOVERLOADdec.option
Submitter: John Reppy
Date: 3/24/92
Version: 0.78
Severity: major
Problem: 
  I noticed a "CoreLang.makeOVERLOADdec.option"
  compiler bug (this also occurs in 0.78):
Transcript: 
  <jhr@bat> cat boot/perv.sml
  structure Foo = struct
    val x = InLine.:=
  end
  <jhr@bat> smlc
  Standard ML of New Jersey, Version 0.78, February 26, 1992 (batch compiler)
  ~mBoot
  [mBoot()]
   ...
  [Compiling boot/perv.sml]
  structure Foo : ...
  [closing boot/perv.sml]
  boot/overloads.sml:4.15-4.21 Error: unbound structure Initial
  boot/overloads.sml:6.7-6.21 Error: unbound structure Bool in path Bool.makestring
  boot/overloads.sml:6.27-6.44 Error: unbound structure Integer in path Integer.makestring
  boot/overloads.sml:6.50-6.64 Error: unbound structure Real in path Real.makestring
  Error: Compiler bug: CoreLang.makeOVERLOADdec.option
  [closing boot/overloads.sml]
  [Failed on "~mBoot" with Syntax]
Comment: [dbm]
  This should never be visible to a user.
Status: not a bug
----------------------------------------------------------------------
532. squaring big real number dumps core on sparc (see also 638)
Submitter: rst@ai.mit.edu (Robert S. Thau)
Date: 3/24/92
Version: ?
System: Sparc
Severity: 
Problem: 
  To repeat this, just attempt to square 1.0E~160 on your nearest sparcstation
  in SML/NJ.  The process will die, complaining that "underflow should not trap".
Fix:
  As I read the source code, the machine-independant signal-handling code (in
  signal.c) expects floating point underflows not to trap, but the machine-
  dependant code does enable underflow trapping.  Accordingly, here's a
  one-line fix to SPARC.dep.c in the runtime directory:

  *** SPARC.dep.c	Tue Mar 24 18:08:57 1992
  --- SPARC.dep.c.~1~	Tue Aug 20 12:03:52 1991
  ***************
  *** 108,112 ****
	SETSIG (SIGILL, fpe_handler, mask);
    #endif MACH

  !     set_fsr (0x0d000000); /* enable FP exceptions NV, OF & DZ; disable UF */
    }
  --- 108,112 ----
	SETSIG (SIGILL, fpe_handler, mask);
    #endif MACH

  !     set_fsr (0x0f000000); /* enable FP exceptions NV, OF, UF & DZ */
    }
Status: fixed in 0.90
----------------------------------------------------------------------
533. typing record types
Submitter:      Richard O'Neill <richard@smaug.questor.wimsey.bc.ca>
Date:		Tue Mar 24 17:54:13 PST 1992
Version:        0.75 (and 0.73, don't know about 0.78)
System:         NeXTstation, OS2.1 & Sun4 SunOS 4.1.1.
Severity:       Major
Problem:        


The type system is *broken* w.r.t. record types. The problem is tied in
with use of flex records (but I do NOT mean the 'unresolved flex record
in let pattern' business that novice programmers sometimes fail to
understand).  The type checker gives an incorrect (too general) typing
for valid SML.  A very minor change causes a correct typing to be given.

The best way to show this bug is to give some code that reproduces it:

   (*
    * The compiler incorrectly types this function as:
    * {key:''a,value:'b} list -> {key:''a,value:'c} -> {key:''a,value:'b} list
    * 						 ^--- should be 'b
    *)
    

    fun insert1 alist (item as {key=desired, ...}) =
	let				  (* ^--- remember this bit *)
	    fun worker nil = item :: nil
	      | worker ({key,value} :: items) =
		if key = desired then
		    item :: items
		else
		    worker items
	in
	    (worker alist)
	end

   (*
    * The compiler correctly types this function as:
    * {key:''a,value:'b} list -> {key:''a,value:'b} -> {key:''a,value:'b} list
    * 						 ^--- correct
    *)
    

    fun insert2 alist (item as {key=desired, value = _}) =
	let				  (* ^--- the only difference *)
	    fun worker nil = item :: nil
	      | worker ({key,value} :: items) =
		if key = desired then
		    item :: items
		else
		    worker items
	in
	    (worker alist)
	end


Transcript:

unix% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "typing-bug.sml"	(* Just the source as shown above... *);
[opening typing-bug.sml]
val insert1 = fn : {key:''a,value:'b} list -> {key:''a,value:'c} -> {key:''a,value:'b} list
val insert2 = fn : {key:''a,value:'b} list -> {key:''a,value:'b} -> {key:''a,value:'b} list
[closing typing-bug.sml]
val it = () : unit
- val [{value=foo, ...}] = insert1 nil {key=17, value=100}	(* broken *)
= and [{value=bar, ...}] = insert2 nil {key=17, value=100}	(* okay   *) ;
std_in:3.1-4.56 Warning: binding not exhaustive
        {value=bar,...} :: nil = ...
std_in:3.1-4.56 Warning: binding not exhaustive
        {value=foo,...} :: nil = ...
val foo = - : 'a
val bar = 100 : int
- foo : int;
val it = 100 : int
- foo : string;
val it = "d" : string
- foo : real;			(* This one's cruel, I know... *)
Bus error (core dumped)
unix%
Comment:
  In practice, it isn't to much of a problem as one can always restrict
  the type or use the form that types correctly. Even so, it does reflect
  a problem in the type checker and ought to be fixed.
Status: fixed in 0.85
----------------------------------------------------------------------
534. .bin files for share and noshare compiler incompatible
Submitter: Bernard Sufrin
Date: 3/24/92
Version: 0.75
System: Sparc/SUNOS 4.1.1
Severity: minor
Problem: 
  I have a good deal of evidence that .bin files compiled by the shared
  compiler and those compiled by the unshared compiler are incompatible.
  Shared compiler generated .bin files cause the unshared compiler
  to crash with a bus error, and vice versa.
Status: open
----------------------------------------------------------------------
535. Problems with non-equality types (bug or language problem?) (see also 341)
Submitter:      Richard O'Neill <richard@smaug.questor.wimsey.bc.ca>
Date:		Wed Mar 25 09:41:51 PST 1992
Version:        0.75 (and 0.73, don't know about 0.78)
System:         NeXTstation, OS2.1 & Sun4 SunOS 4.1.1.
Severity:       Major
Problem:        

I'm not sure if this is a bug or a language 'feature' - whatever it is,
it is certainly unnecessarily restrictive and needs fixing...

If I have a reference to a type that does not admit equality, I can
still test  *references* to that type for equality. But, if that reference
is wrapped up as part of a structured type, I cannot.

It isn't necessarily tied to references. It also applies to any parametric
types which don't actually contain an element of the type, such as:
	datatype 'a type_only = TypeOnly

Take a look at the transcript below...

Transcript:

Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- abstype abstract = Abstract with val abstract = Abstract end;
type abstract
val abstract = - : abstract
- val abstract_ref = ref abstract;
val abstract_ref = ref - : abstract ref
- abstract_ref = abstract_ref;
val it = true : bool
-
- datatype 'a wrapped_ref = WrappedRef of 'a ref;
datatype 'a  wrapped_ref
con WrappedRef : 'a ref -> 'a wrapped_ref
- val wrapped_abstract_ref = WrappedRef (abstract_ref);
val wrapped_abstract_ref = WrappedRef (ref -) : abstract wrapped_ref
- wrapped_abstract_ref = wrapped_abstract_ref;
std_in:7.1-7.43 Error: operator and operand don't agree (equality type required)
  operator domain: ''Z * ''Z
  operand:         abstract wrapped_ref * abstract wrapped_ref
  in expression:
    = (wrapped_abstract_ref,wrapped_abstract_ref)
- 

- datatype 'a type_only = TypeOnly;
datatype 'a  type_only
con TypeOnly : 'a type_only
- fun equal (x as TypeOnly, y as TypeOnly) = x = y;
val equal = fn : ''a type_only * ''a type_only -> bool
- (*             ^--- doesn't really have to be an equality type *)
- 
Status: not a bug (language problem)
----------------------------------------------------------------------
536. twig out of date
Submitter: wgehrke@risc.uni-linz.ac.at (Wolfgang Gehrke)
Date: 3/26/92
Version: 0.75
Problem: 
  I had a small trouble to use twig together with this version of ML.
  There were two problems:

  1) The generated code contains identifiers beginning with '_'.

  2) I also changed "invoke.sml" to get a stand alone version.
Status: fixed in 0.90
----------------------------------------------------------------------
537. System.system fails in noshare compiler after Heap extension
Submitter: Eric Madelaine <Eric.Madelaine@sophia.inria.fr>
Date: 3/26/92
Version: 0.75
System: sparc
Severity: major
Problem: 
  When using an sml "-noshare" system, 
  and after the first "Heap extension",
  any call to System.system fails with:

	  uncaught exception SystemCall

  This error does not occur before having the heap extended, nor in
  a system built without the "-noshare" option, even after many heap
  extensions.
  [followup on 3/31/92]:
  It occurs now in any configuration of my system (may be because it is
  bigger now).
Status: fixed in 0.84
----------------------------------------------------------------------
538. uncaught exception subscript during compilation
Submitter: Dave MacQueen
Date: 3/30/92
Version: 0.78
Problem: 
Code: 
(* hacked version of code from David Ladd *)
(* Variables provide a more sophisticated and better packaged version
of ID's *)

signature VARIABLES =
sig
  datatype var  (* variables *)
   = PREVBL of string
   | VBL of {name: string, stamp: int}
  val varname : var -> string
  (* following are concerned with "alpha conversion" *)
  type varenv
  val newvar: string -> var
  val empty_env : varenv
  val lookup : varenv * string -> var option
  val bind : string * var * varenv -> varenv
end

structure Variables: VARIABLES =
struct
(* Rather than represent variables as simple strings, I introduce
   a variable type (var).  The first form (PREVBL) is a temporary variable
   produced on parsing, and then replaced when static analysis is performed
   to determine scoping and association between binding and applied occurences
   of variables.  If parsing is made a bit more complicated, this static
   analysis can be done on the fly during parsing and only the second form
   of variable would be needed (this is how it is currently done in the ML
   compiler.  For the VBL form, the stamp field is an integer that uniquely
   identifies that variable.
*)
  datatype var  (* variables *)
   = PREVBL of string
   | VBL of {name: string, stamp: int}

  fun varname(PREVBL s) = s
    | varname(VBL{name,stamp}) = name ^ "." ^ makestring stamp

  val count = ref 0

  fun newvar s = VBL{name=s, stamp=(inc count; !count)}

  type varenv = (string * var) list

  val empty_env = []

  fun lookup([],_) = NONE
    | lookup((s,v)::rest,s') = if s = s' then SOME v else lookup(rest,s')

  fun bind(s,v,env) = (s,v)::env
end (* structure Variables *)


(* it will probably be more convenient to have a smaller number of
   cases in the expression datatype.  One way of reducing the number
   of expression constructs is to have an APP constructor that takes
   an "operator" and a list of argument expressions.  If the set of
   possible operators is fixed, then they may be defined as the
   constructors of an operator datatype, as below.  If new operators
   can be introduced, then a more complicated operator type would be
   appropriate.  You might look at src/absyn/bareabsyn.sml to see how
   the ML abstract syntax is defined.

   Each operator needs to be assigned its arity, and when constructing
   an expression, or when checking its "well-formedness" (a mild form
   of type checking), one would verify that the length of the argument
   list matches the arity of the operator.

   For proper type checking, each operator would be assigned a type,
   which would presumably subsume its arity.
*)

structure Operators =
struct
  datatype operator
   = PLUS
   | MINUS
   | MUL
   | DIV
   | MOD
   | EXP
   | SHL
   | SHR
   | BAND
   | BOR
   | XOR
   | EQ
   | NEQ
   | GT
   | LT
   | GTE
   | LTE
   | AND
   | OR
   | IS_IN
   | UNION
   | INTERSECTION
   | SUBSE
   | SET_EQ
   | SET_MINUS
   | MATCH
   | NOT_MATCH
   | UMINUS
   | NOT
   | BNOT
   | COUNT
   | MIN
   | MAX
   | SUM

  (* following function is useful for printing expressions, as in ppexpr *)
  fun operName PLUS = "plus"
    | operName MINUS = "minus"
    | operName MUL = "mul"
    | operName DIV = "div"
    | operName MOD = "mod"
    | operName EXP = "exp"
    | operName SHL = "shl"
    | operName SHR = "shr"
    | operName BAND = "band"
    | operName BOR = "bor"
    | operName XOR = "xor"
    | operName EQ = "eq"
    | operName NEQ = "neq"
    | operName GT = "gt"
    | operName LT = "lt"
    | operName GTE = "gte"
    | operName LTE = "lte"
    | operName AND = "and"
    | operName OR = "or"
    | operName IS_IN = "is_in"
    | operName UNION = "union"
    | operName INTERSECTION = "intersection"
    | operName SUBSE = "subse"
    | operName SET_EQ = "set_eq"
    | operName SET_MINUS = "set_minus"
    | operName MATCH = "match"
    | operName NOT_MATCH = "not_match"
    | operName UMINUS = "uminus"
    | operName NOT = "not"
    | operName BNOT = "bnot"
    | operName COUNT = "count"
    | operName MIN = "min"
    | operName MAX = "max"
    | operName SUM = "sum"

  fun arity(oper: operator) : int =
      case oper
	of UMINUS => 1
	 | NOT => 1
	 | BNOT => 1
	 | COUNT => 1
	 | MIN => 1
	 | MAX => 1
	 | SUM => 1
	 | _ => 2

end (* structure Operators *)

open Variables Operators

(* the rest of this should be packaged in structures too, but its getting
   late so I'm not going to finish it. *)

datatype exp
 = INT of int  		(* was CONST *)
 | STR of string
 | ENUM of string	(* probably want something more specialized than string *)
 | VAR of var  		(* was ID *)
 | QUES of exp * exp * exp
 | SET of exp list
 | APP of operator * exp list

(* val test = PLUS(CONST(4),CONST(3)); *)
val test = APP(PLUS,[INT 4, INT 3])

datatype stmt
 = ASSERT of exp
 | FOR of var * exp * stmt
 | CMPD of stmt list;

val testprog = FOR(PREVBL "x",SET([INT(1),INT(2)]),
		ASSERT(APP(EQ,[VAR(PREVBL "x"),INT 0])));

val testprog2 = FOR(PREVBL "x",
		    SET([INT 1, INT 2]),
		    CMPD([
			  ASSERT(APP(EQ,[VAR(PREVBL "x"),INT 0])),
			  FOR(PREVBL "x",
			      SET([INT(3),INT(4)]),
			      ASSERT(APP(NEQ,[VAR(PREVBL "x"),INT 1]))
			      ),
			  ASSERT(APP(NEQ,[VAR(PREVBL "x"),INT 1]))
			  ])
		    );

(* for some useful printing utilities, you might look at 
   src/basics/printutil.sml in the ML source code.  But much more
   sophisticated pretty-printing support is likely to become available soon.
*)

(* all this concatenating of strings (in a quadratic fashion), is liable
   to get expensive if you start printing big objects.  It is probably
   more efficient to print directly rather than build a string.  There
   will be an sprintf-style facility in the new library we are building,
   so you could print "into" a string in a linear fashion.
*)

(* in src/absyn/printabsyn.sml you can find our rather crude 
   pretty printer for ML abstract syntax.  It attempts to cope
   with infix operators and their precedences and other complications.
*)

fun prvar (PREVBL s) = s
  | prvar (VBL{name,stamp}) = name ^ "." ^ makestring stamp

fun ppexpr (APP(EQ,[a,b])) = ppexpr a ^" == "^ ppexpr b
  | ppexpr (APP(NEQ,[a,b])) = ppexpr a ^" != "^ ppexpr b
  | ppexpr (INT i) = makestring i
  | ppexpr (STR s) = "\"" ^ s ^ "\""
  | ppexpr (VAR v) = prvar v
  | ppexpr (SET l) = "{" ^ pplist l ^ "}"
  | ppexpr (QUES(e1,e2,e3)) =
     "if " ^ ppexpr e1 ^ " then " ^ ppexpr e2 ^ " else " ^ ppexpr e3
  | ppexpr (APP(oper,args)) =
     operName oper ^ "(" ^ pplist args ^ ")"
     (* here you see the advantage of separating out the operators *)

and pplist ([h]) = ppexpr h   (* shorthand for h::[] *)
  | pplist (h::t) = ppexpr h ^ "," ^ pplist t 
  | pplist [] = "" 

(* this could be made a bit more efficient.  We probably need to provide
   a primitive to efficiently build such strings.
fun sp 0 = ""
  | sp n = " " ^ sp (n - 1);
Below is a somewhat faster version (especially as n gets larger.
*)

fun sp n =
    let fun collect(0,l) = l
	  | collect(n,l) = collect(n-1," "::l)
     in implode(collect(n,[]))
    end

fun ppstmt (t,ASSERT(x)) = "\n" ^ sp t ^ ppexpr x ^ ";"
  | ppstmt (t,FOR(a,b,c)) = 
      "\n"^ sp t ^"for " ^ (varname a) ^ " in " ^ ppexpr b ^ ppstmt(t+1,c)
  | ppstmt (t,CMPD(nil)) = ""
  | ppstmt (tab,CMPD(l)) = 
    let fun pplist (h::t) = ppstmt(tab,h) ^ pplist t
	  | pplist [] = "" 
    in 
	" begin" ^ pplist l ^ "\n" ^ sp (tab - 1) ^ "end"
    end;
    
fun prt (ex) = output(std_out,ppstmt(0,ex) ^ "\n");


(* to complete this evaluator sensibly you need a more general notion of
   the values that your expressions can evaluate to.  Presumably you
   need to deal with strings, booleans, and set values in addition
   to integers.  The value type will probably be a datatype. *)

datatype value
 = INTval of int
 | STRval of string
 | BOOLval of bool
 | SETval of value list  (* allows heterogeneous sets, which probably
			    don't occur. *)

fun seval (INT x) = INTval x
  | seval (APP(PLUS,[a,b])) =
     let val INTval va = seval a and INTval vb = seval b
      in INTval(va+vb)
     end
  | seval (APP(MINUS,[a,b])) =
     let val INTval va = seval a and INTval vb = seval b
      in INTval(va-vb)
     end
  | seval (QUES(x,y,z)) = 
     let val INTval vx = seval x and INTval vy = seval y and INTval vz = seval z
      in INTval(if vx <> 0 then vy else vz)
     end
  | seval (_) = INTval 0; (* ??? *)
    
(* what types of values does an operator like EQ apply to?  If it is
overloaded, and can apply to, say, integers and strings, then the
evaluation rule has to do a case analysis:

  | seval (APP(EQ,[a,b])) =
    case seval a
      of INTval va =>
	  (case seval b
	     of INTval vb => BOOLval(va = vb)
	      | _ => raise TypeError)
       | STRval va =>
	  (case seval b
	     of STRval vb => BOOLval(va = vb)
	      | _ => raise TypeError)
       | ...
*)


fun eaconv env (e as VAR(PREVBL x)) = 
     (case lookup(env,x)
       of SOME v => VAR v
        | NONE => e)
  | eaconv env (APP(oper,args)) = APP(oper, map (eaconv env) args)
  | eaconv env (QUES(e1,e2,e3)) = QUES(eaconv env e1, eaconv env e2, eaconv env e3)
  | eaconv env (SET elems) = SET(map (eaconv env) elems)
  | eaconv env e = e
    
fun alphasub (env,ASSERT(x)) = ASSERT(eaconv env x)
  | alphasub (env,CMPD(l)) =
      let fun mapped(x) = alphasub(env,x)
       in CMPD(map mapped l)
      end
  | alphasub (env,FOR(PREVBL a, b, c)) = 
      let val new = newvar a
       in FOR(new, (eaconv env b), alphasub( bind(a,new,env), c))
      end
  | alphasub (env,stmt) = stmt;

fun aconv(x) = alphasub(empty_env,x);

Status: fixed in 0.83
----------------------------------------------------------------------
539. weak typing bug
Submitter: John Greiner
Date: 4/2/92
Version: 0.75
Severity: major
Problem: 
  weak typing failure
Transcript: 
- (let val x = ref nil in fn y => x end) ();
val it = ref [] : '1a list ref

- let val a = (let val x = ref nil in fn y => x end) () in
= a:=[1]; hd(!a)^"hi" end;
val it = "\^Ahi" : string

In V.73 (I think) this wasn't there, as I have referenced in a file:
- (let val x = ref nil in fn y => x end) ();
std_in:2.1-2.41 Error: nongeneric weak type variable
  it : '~1Z list ref

Status: fixed in 0.89
----------------------------------------------------------------------
540. printing hanging on Mach
Submitter: Bob Harper
Date: 4/2/92
Version: 0.78
System: DecStation 5000, Mach, running over telnet
Severity: major
Problem: 
  Type "structure S = System".
  On my machine it prints about halfway through, then hangs.
Comment:
  Sometimes when running sml over a telnet, the printing hangs.  You can
  continue by typing space.  This is not new to 0.78. [Gene Rollins]

  [Bob Harper, 4/11/92]:
  Incidentally, on the PMAX (at least) I consistently get the following
  behavior.  I type in something, particularly something that incurs a type
  error.  I get back half or three quarters of a message, then it hangs.  The
  only way out is to type ^C, which gets me back to the prompt.  If I type the
  same thing again, I may or may not get the full message.  Often I just kill
  the session and start over, then it works (for a while).  We're running Mach
  on the PMAX, and I'm using ML via telnet, within an emacs ML interaction
  window, if it matters.
Status: fixed in 0.84
----------------------------------------------------------------------
541. warnings while compiling runtime
Submitter:      Kai Kein{nen <kmk@cc.tut.fi>
Date:		April 5, 1992
Version:        0.80 from research.att.com:/dist/ml/working on April 5
System:         RISC/OS 4.52, MIPS RC 6280
Severity:       minor
Problem:        compilation time warnings for gc.c and prim.s
Code:           ./makeml -mips riscos
Transcript:     

./makeml> (cd runtime; make clean)
	rm -f *.o lint.out prim.s linkdata allmo.s run
./makeml> rm -f mo
./makeml> ln -s ../mo.mipsb mo
./makeml> (cd runtime; rm -f run allmo.o allmo.s)
./makeml> (cd runtime; make MACHINE=MIPS  'CFL= -systype bsd43' 'LIBS=' 'DEFS= -DRISCos -DRUNTIME=\"runtime\"' linkdata)
	cc -O -systype bsd43 -DMIPS -DRISCos -DRUNTIME=\"runtime\" -o linkdata linkdata.c
./makeml> runtime/linkdata [runtime/IntMipsBig.mos]
runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
./makeml> (cd runtime; make  MACHINE=MIPS 'DEFS= -DRISCos' 'CPP=/lib/cpp -P' 'CFL= -systype bsd43' 'AS=as' 'LIBS=')
	cc -O -systype bsd43 -DMIPS -DRISCos -c run.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c run_ml.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c callgc.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c gc.c

uopt: Warning: gc: this procedure not optimized because it
      exceeds size threshold; to optimize this procedure, use -Olimit option
      with value >=  886.
	cc -O -systype bsd43 -DMIPS -DRISCos -c MIPS.dep.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c export.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c timers.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c ml_objects.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c cfuns.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c cstruct.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c signal.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c exncode.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c malloc.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c mp.c
	cc -O -systype bsd43 -DMIPS -DRISCos -c sync.c
	/lib/cpp -P -DASM -DMIPS -DRISCos MIPS.prim.s > prim.s
	as -o prim.o prim.s
as0: Warning: prim.s, line 305: missing .end preceding this .ent: set_request
      .ent set_request
as0: Warning: prim.s, line 305: .ent/.end block never defined the procedure name
as0: Warning: prim.s, line 434: missing .end preceding this .ent: go
      .ent go

Comments:
Some of the corrections needed earlier for MIPS R6000 seem to be
missing from this version.
The interpreter seems to work correctly in spite of these warnings.

Status: fixed in 0.90
----------------------------------------------------------------------
542. lack of environment cleanup in 0.80
Submitter: schristensen@daimi.aau.dk (Soren Christensen)
Date: 4/6/92
Version: 0.80
Severity: major
Problem: 
  The other question is related to a problem I had in 0.75:
  >fun x 0 = () | x n = (use_stream (open_string "3"); x (n-1));
  >fun test () = (exportML "pre"; x 1000; exportML "post");
  >
  >Try test(); and check the diff in size of pre and post.

  There seems to be a more grneral problem in 0.80. The toplevel environment
  seems to grow - even if I do not declare new names. Now that I can inspect
  the valuse in the environmet I find "VAL$it" repeted.
  try:
   map (fn x => print (System.Symbol.makestring x))(System.Env.catalogEnv
  (System.Env.staticPart (!System.Env.topLevelEnvRef)));

  Especially after running for a while.
Status: fixed in 0.82
----------------------------------------------------------------------
543. top-level printing fails
Submitter: Bob Harper
Date: 4/8/92
Version: ?
Severity: major
Problem: 
Code: 
    type OrdId = string
    type ModId = string

    datatype Ord =
	Kind
      | Type
      | Pi of Dec * Ord
      | Abs of Dec * Ord
      | App of Ord * Ord
      | Cast of Ord * Ord
      | One
      | Sub of Ord * Sub
      | Fst of Mod

    and Mod =
        KindM
      | Signature
      | PiM of DecM * Mod
      | AbsM of DecM * Mod
      | AppM of Mod * Mod
      | OneM
      | CastM of Mod * Mod
      | SubM of Mod * Sub
      | Nil
      | NilSig
      | OTuple of Def * Mod
      | OTupleSig of Dec * Mod
      | RTuple of DefM * Mod
      | RTupleSig of DecM * Mod
      | FstM of Mod
      | SndM of Mod

    and Sub =
	Id
      | Shift
      | ODef of Sub * (OrdId * Ord * Ord option)
      | MDef of Sub * (ModId * Mod * Mod option)
      | Comp of Sub * Sub

    and Ctx =
	Null
      | ODec of Ctx * Dec
      | MDec of Ctx * DecM

    and Dec = Dec of OrdId * Ord
    and Def = Def of OrdId * Ord

    and DecM = DecM of ModId * Mod
    and DefM = DefM of ModId * Mod ;
Transcript: 
  I type:

  val S = OTupleSig(Dec("t",Type),NilSIg);

  I get:

  val S = OTupleSig (
  uncaught exception Subscript

  The actual input is much larger: I build the system using SourceGroup, then
  open the structure IntSyn, which makes available this datatype, which then
  results in the exhibited behavior.
Status: fixed in 0.84
----------------------------------------------------------------------
544. poor error message
Submitter: John Reppy
Date: 4/16/92
Version: 0.81
Severity: minor
Problem: 
  The error message

    Error: non-constructor applied to argument in pattern

  would be much more useful if it gave the name of the  identifier.
Comment: [dbm, 10/7/92]
  There are two places where this message was generated.  In elabutil.sml
  code has been added to print the bogus rator.  In astutil.sml the message
  has been changed to "nonidentifier applied to argument in pattern",
  but bogus pattern is not printed because there is no ast printer yet.
Status: open (patially fixed in 0.91)
----------------------------------------------------------------------
545. signature matching looping?
Submitter: 	Amy Moormann Zaremski <amy+@cs.cmu.edu>
Date:		Mar 5, 1992
Version:	.75 (both with and without sourcegroup)
System:		Dec 3100, Mach ??(whatever default is right now) 
Severity:	minor
Problem:	Certain signature/structure combinations cause
		SML to "loop" (grow the heap until memory is
		exhausted).
Code:
		signature S = sig
		  val f : 'b -> int
		end

		structure S1:S = struct
		  fun f x = x
		end

Transcript:
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- signature S = sig
=   val f : 'b -> int
= end;
signature S = 
  sig
    val f : 'a -> int
  end
- structure S1:S = struct
=   fun f x = x
= end;

[Major collection...
[Increasing heap to 2478k]

[Increasing heap to 4798k]
 92% used (1550460/1673392), 1188 msec]

[Increasing heap to 7002k]

[Major collection... 74% used (2960732/3949436), 2797 msec]

[Increasing heap to 11582k]

[Major collection...
[Increasing heap to 17730k]
 80% used (5808988/7231036), 5062 msec]

[Increasing heap to 21198k]

[Major collection...
[Increasing heap to 32438k]
 80% used (10635356/13238652), 9407 msec]

[Increasing heap to 32634k]

[Major collection... 73% used (13238652/17984796), 12468 msec]

[Increasing heap to 32710k]

[Major collection...
[Increasing heap to 32734k]

[Increasing heap to 32746k]

[Increasing heap to 32750k]

[Increasing heap to 32754k]

Warning: can't increase heap

Ran out of memory
Process Inferior smlsg exited abnormally with code 3
Status: fixed in 0.83
----------------------------------------------------------------------
546. System.architecture not initialized
Submitter: Gene Rollins, Dave MacQueen
Date: 4/24/92
Version: 0.81
Severity: minor
Problem: 
  System.architecture not initialized because comment brackets
  in cps/shareglue.sml haven't been removed.
Status: fixed in 0.81
----------------------------------------------------------------------
547. interrupt not working (inside emacs)
Submitter:      slind@research.att.com
Date:           April 27, 1992
Version:        81
System:         mips (It doesn't occur on the sun4)
Severity:       major
Problem:     1) In gnu emacs, sml goes into an infinite loop when I hit the 
                interrupt key, i.e., on the DEL character. Then sml seems to
                ignore signals: the only way to regain control is to kill the
                sml process. Merely exiting emacs will not kill the sml 
                process.

             2) A related problem is that interrupt doesn't give the right
                exception (and not until a carriage return): it returns the
                Abort exception.
                
Transcript:     

1) (Inside gmacs.)

    $ sml
    Standard ML of New Jersey, Version 0.81, 9 April 1992
    Arrays have changed; see Release Notes
    val it = () : unit
    -
    \003
    \003
    \004


2) (In the shell)

    $ sml
    Standard ML of New Jersey, Version 0.81, 9 April 1992
    Arrays have changed; see Release Notes
    val it = () : unit
    - <DEL key struck: nothing happens; now issue a CR>
    std_in:3.1 Error: illegal token

    uncaught exception Abort
    -
Status: fixed in 0.82 (same as 550)
----------------------------------------------------------------------
548. blast_read on ints
Submitter:      slind@research.att.com
Date:           April 28, 1992
Version:        75, 81
System:         mips and sparc at least; probably all
Severity:       minor
Problem:        System.Unsafe.blast_X (where X probably = "read", but I'm not
                sure). Solitary ints aren't handled properly: in 81, core gets
                dumped; in 75, the wrong value is returned.
Transcript:     

In 81:
       $ sml
       Standard ML of New Jersey, Version 0.81, 9 April 1992
       Arrays have changed; see Release Notes
       val it = () : unit
       - val outs = open_out "foo";
       val outs = - : outstream
       - System.Unsafe.blast_write(outs,1);

       [Major collection...abandoned]
       val it = () : unit
       - close_out outs;
       val it = () : unit
       - val ins = open_in "foo";
       val ins = - : instream
       - System.Unsafe.blast_read ins : int;
       Memory fault - core dumped
       $ 


In 75:

       -  val outs = open_out "foo";
       val outs = - :outstream
       - System.Unsafe.blast_write(outs,1);
       [Major collection...abandoned]
       val it = () :unit
       - close_out outs;
       val it = () :unit
       - val ins = open_in "foo";
       val ins = - :instream
       - System.Unsafe.blast_read ins : int;
       val it = 3242475 :int
       -
Status: fixed in 0.86
----------------------------------------------------------------------
549. Match exception while compiling
Submitter:      jont@uk.co.harlqn
Date:		28/04/92
Version:        SML of NJ version 0.75
System:         Sun 4/330 with SunOS 4.1.1
Severity:       minor
Transcript:
- val _ = =;
std_in:1.9 Error: nonfix identifier required

uncaught exception Match

Comment: I guess this shouldn't happen. It's not the sort of
thing I type regularly, I was prompted to do it by the compiler's
habit of inserting = all over the place when it thinks I've left out
an identifier.
Comment: in 0.89 produces following
- val _ = = ;
std_in:0.0 Error: nonfix identifier required
Error: Compiler bug: elabVB
-
Status: fixed in 0.91 (dbm)
----------------------------------------------------------------------
550. interrupt on MIPS
Submitter: Lal George
Date: 4/29/92
Version: 0.81
System: MIPS/Riscos 4.52
Severity: major
Problem: 
0.81 on the MIPS has problems with signal handling. 
An interrupt (ctrl-c) causes it to go into deep space, 
eating up cpu time.
Status: fixed in 0.82
----------------------------------------------------------------------
551. large integers yield Illegal instruction
Submitter: Kjeld H. Mortensen | Email: kjeld@metasoft.com
Date: 4/29/92
Version: 0.81
System: ?
Severity: major
Problem: 
  Large integer literal causes illegal instruction.
Transcript: 
  metasparc 141 : /d1/tools/njsml/81/sml.sparc.ns
  Standard ML of New Jersey, Version 0.81, 9 April 1992
  Arrays have changed; see Release Notes
  val it = () : unit
  - 536870911;
  val it = 536870911 : int
  - 536870912;
  Illegal instruction
  metasparc 142 :
Comments:
  536870912 seems to be 2^29. (Similar behaviour, of course, for 
  corresponding negative numbers.)

  This compiler was build with 'makeml -noshare' on a Sun4, but
  compilers build with 'makeml' have same behaviour.

  In SML/NJ v0.80 this is no problem. Here integers can be 
  up to (2^30)-1 and it doesn't give 'Illegal instruction'.
Status: Fixed in 0.81 (?)
----------------------------------------------------------------------
552. Error message line numbers from std_in (see also 575)
Submitter:      Lal George
Date:		30th April, '92
Version:        0.81
System:         all
Severity:       major
Problem:        Error line numbers are incorrect in the interactive session.
Transcript:     

	Standard ML of New Jersey, Version 0.81, 9 April 1992
	Arrays have changed; see Release Notes
	val it = () : unit
	- val x = 1;
	val x = 1 : int
	- fun f x = val y = 2 in x + y end;
-->	std_in:4.11 Error: syntax error found at VAL
	- val x = 3;
	val x = 3 : int
	- val x = 4;
	val x = 4 : int
	-  fun f x = val y = 2 in x + y end;
-->	std_in:6.12 Error: syntax error found at VAL

Comments:
	This is a nuisance for programs that do regression testing,
or under emacs ML-mode.
Status: fixed in 0.91
----------------------------------------------------------------------
553. incorrect syntax accepted
Submitter: John Reppy
Date: 4/30/92
Version: 0.81a
Severity: minor
Problem: 
  The following things are not legal SML syntax, but we accept them:
Transcript: 
  Standard ML of New Jersey, Version 0.81, 9 April 1992
  Arrays have changed; see Release Notes
  val it = () : unit
  - let in 1 end;
  val it = 1 : int
  - let ; in 1 end;
  val it = 1 : int
  - let ;;; in 1 end;
  val it = 1 : int
  - 
Fix:
  change "LET ldecs IN " to "LET ldec ldecs IN"
Note that there are probably two places where this occurs; the other
is "LET sdecs IN" or something like that.
  Note: the Definition allows an "empty declaration" so this isn't a bug.
Status: not a bug
----------------------------------------------------------------------
554. unused token constructor QUERY
Submitter: John Reppy
Date: 4/29/92
Version: 0.81a
Severity: trivial
Problem: 
  I notice that there is a terminal symbol named QUERY declared in
  ml.grm, which is never used.
Fix: remove QUERY constructor
Status: fixed in 0.90
----------------------------------------------------------------------
555. window signal
Submitter:      John Reppy (jhr@research.att.com)
Date:           May 8, 1992
Version:        versions 75-81 (at least)
System:         RISCOS (R3000 & R6000)
Severity:       major
Problem:        resizing a shell window (xterm or cmdtool) that is running sml
		causes the sml process to either die or go into an infinite loop.
Comments:
  This is likely a problem with the handling of WINCH signals, but it doesn't seem
  to be related to the general problems with signals on the MIPS in 0.81.
Status: fixed in 0.82
----------------------------------------------------------------------
556. large integers on Sparc
Submitter:      <Sven Doerr, Univ. Karlsruhe, Germany; sd@ira.uka.de>
Date:		<Tue May 12 14:43:25 MET DST 1992>
Version:        <SML of NJ version number, 0.81>
System:         <sun4, SunOS Release 4.1.1>
Severity:       <minor>
Problem:        <typing large integers at top level or arithmetic overflow
		 aborts sml with: Illegal instruction>
Code:           < 0x80000000 <return> >
Transcript:     <
		Standard ML of New Jersey, Version 0.81, 9 April 1992
		Arrays have changed; see Release Notes
		val it = () : unit
		- 100000 * 100000;
		Illegal instruction
		>
Status: fixed in 0.83
----------------------------------------------------------------------
557. sparc signals
Submitter:      Andre Kramer akramer@ecrc.de
Date:           Thu May 14 
Version:        0.75 
System:         sparc
Severity:       <minor, major, or critical>
Problem:        asynchronous exceptions for sparc

       file SPARC.prim.s

                _savefpregs  
		          retl
        		  nop
       does nothing.

       in signal.c 

                 /*
     		  * save floating point registers.
                  */
                  savefpregs(msp);
                  fpregs = ((int *)(msp->ml_allocptr)) + 1;
                  msp->ml_allocptr += (NSAVED_FPREGS*2 + 1) * sizeof(int);

       allocates 1 word from heap and later saves a pointer to it (fpregs). 
       this word should contain a descriptor (len 0,tag string): 
Fix:
       (MAKE_DESC(NSAVED_FPREGS*8,tag_string)) 
       as is done in _savefpregs for the M68, MIPS.  
       (VAX is same as Sparc).

Comments:
        I have a another question on the new calling conventions 
        (CALLEESAVE) for sparc.
        If register masks in code strings don't contain the 
        CLOSURE_INDX the last bit is 0. 
        A mask then either looks like a pointer or an int.
        Does this not affect the garbage collector?  
Status: fixed in some version between 0.75 and 0.81
----------------------------------------------------------------------
558. local...end structure expressions not working in 0.80
Submitter:      Tim Freeman, tsf@cs.cmu.edu
Date:		Fri May 15 14:38:42 1992
Version:        0.80
System:         Sun 4 running Mach
Severity:       minor
Problem:        The new compiler doesn't know that local...end is
			sensible at the structure level.
Transcript:     val it = () : unit
		- System.Compile.makeSource ("foo",1,std_in,true,std_out);
		val it = prim? : source
		- val staticEmpty = System.Env.staticPart (System.Env.emptyEnv ());
		val staticEmpty = prim? : staticEnv
		- val s = System.Compile.makeSource ("foo",1,std_in,true,std_out);
		val s = prim? : source
		- System.Compile.compile (s,staticEmpty);
		- local
		=    structure x = struct val z = 3 end
		= in
		=    structure y = struct val w = x.z end
                = end;
		uncaught exception Compile
Status: fixed in 0.84
----------------------------------------------------------------------
559. static environment not cleaned up
Submitter: Dave MacQueen
Date: 5/17/92
Version: 0.81
Severity: average
Problem: 
  Top level static environment is not consolidated in the interactive
  loop, so hidden static bindings are not removed and static environment
  grows too fast.
Fix:
  Add a call of Environment.consolidate when newenv is built at the
  end of function evalLoop in functor Interact (build/interact.sml).
Status: fixed in 0.84
----------------------------------------------------------------------
560. blast functions and separate compilation
Submitter:      Emden R. Gansner, erg@ulysses.att.com
Date:           18 May 1992
Version:        0.81c
System:         Sparc 2, SunOS 4.1
Severity:       major
Problem:        Separate compilation facility is broken
Code:           
  structure SepComp =
    struct
  
    val fname = "a.o"
  
    fun compFile () = let
      open System.Compile System.Env
      val targetWrite : (outstream * compUnit) -> unit = System.Unsafe.blast_write
      val staticPerv = staticPart(!pervasiveEnvRef)
      val sourceF = open_string "structure A = struct end"
      val source = makeSource("", 1, sourceF, false, std_out)
      val compUnit as (static, code) =
              (compile(source,staticPerv)) 
                 handle e => (closeSource source; raise e)
      val outstr = open_out fname
      in
        targetWrite (outstr, compUnit);
        closeSource source;
        close_out outstr
      end
  
    fun loadFile () = let
      open System.Compile
      val targetRead : instream -> compUnit = System.Unsafe.blast_read
      val instr = open_in fname
      val effectiveEnv = !System.Env.pervasiveEnvRef
      val _ = print "starting load \n"
      val (staticUnit,codeUnit) = targetRead instr
      in
        print "readUnit done \n";
        close_in instr;
        print "starting execute \n";
        execute((changeLvars staticUnit,codeUnit), effectiveEnv);
        print "finished execute \n"
      end
    end
  
  val _ = SepComp.compFile ()
  val _ = SepComp.loadFile ()
  
Transcript:     loadFile hangs during execute; sending an interrupt
                signal produces a core dump

Comments:       This program works fine in 0.80. Changes made to
                blast_read and blast_write in 0.81 are probably the
                root of the problem. The above program also failed
                in 0.81b, but hung during blast_read. This was mentioned
                to Lal, who, I believe, produced 0.81c as a partial fix.
Status: fixed in 0.82
----------------------------------------------------------------------
561. exportFn images too big (same as 489)
Submitter: Andrew Koenig
Date: 5/19/92
Version: 0.75
System: Sparc
Severity: minor
Problem: 
  For practical reasons, it would be nice to get
  exportFn to create less bulky executables for small programs.
  For example, here is a somewhat simplified version of the
  `echo' command:

	  fun echo [] = print "\n"
	    | echo (h::nil) = print (h^"\n")
	    | echo (h::t) = (print(h ^ " "); echo t)

	  fun main(argv, envp) = echo(tl argv)

  When I use `exportFn' to make an executable of this, it takes
  136 kbytes using 0.53 on a 10th Edition machine.  Using 0.75
  on a Sparcstation, the executable is 471 kbytes.  Even if we
  allow that Sparc executables are bigger, it is hard to believe
  that that much baggage is truly necessary.
[from ark, 12/1/92:]
  I just built 0.92 and gave it a try.
  When built with -noshare, the following

	  fun main _ = print "Hello world\n";
	  exportFn ("xxx", main);

  yields a 946K executable with 860K of loadable data.
  This is as opposed to 376K/249K with 0.75,
  which in turn was about twice as big as 0.43.
[from Lal, 12/16/92]
  We mercifully had the result of exportFn for the lego theorem
  prover using version 0.66. So I built a noshare version of sml
  for the Sparc and rebuilt lego using version 0.92.

  There is more than a Mbyte increase in the size of the exported 
  image. Below, Olego is the image under 0.66, and lego is the version
  under 0.92.

  Either this is to be expected - which is bad, or there are references
  that are not being cleared - which is also bad.

  ----------------------------------------------------------------
  lutece:$ ls -l
  total 3104
  -rwxrwxrwx  1 dbm        999456 Mar 26  1991 Olego*
  -rwxr-xr-x  1 george    2146336 Dec 16 18:38 lego*
Status: fixed in 0.93c
----------------------------------------------------------------------
562. SML hanging under telnet (under Mach) (also #540)
Submitter:      tsf@cs.cmu.edu
Date:		Tue May 19 15:14:55 1992
Version:        0.80
System:         Pmax, running Mach.  Also Sun 4's running mach, but
		more rarely.  (I'm referring to the type of the
		machine running SML, not the type of the machine
		running telnet.) 
Severity:       minor
Problem:        When running under telnet, sml intermittently hangs on output.
Code:           Anything that produces lots of output will do.
Transcript:     It's long, so I put it at the end of this message.
		It's not very informative. 
Comments:	If I say "sml | cat -u" instead of "sml", things work
		fine.  If I create a remote xterm and run sml within
		that, or a remote gnu-emacs and run sml within that,
		things work fine.  The problem only happens when sml's
		standard output is a pty controlled by telnet.

		The type of the machine running sml seems to make
		more of a difference than the type of the machine at
		the other end of the telnet connection.
Fix:		Say "sml | cat -u" instead of "sml" to invoke sml at
		the other end of a telnet connection.

Looking at the code for flushbuf in boot/perv.sml, I see that you wait
for output to become possible before sending the first bytes of
output, but inside the loop in write_all in runtime/cfuns.c, you don't
wait for output to become possible after a partial write.  This
discrepancy is strange, but I don't see how it could give rise to this
bug.  Do you use nonblocking IO?  Why do you wait for output to become
possible before starting a write?

I wouldn't be surprised if telnet is the only device you output to
that doesn't always write all of the bytes you ask it to.

Here's the transcript.  The details don't matter much, anything that
produces this much chatter is very likely to hang.  This works fine
when run locally or when piped through "cat -u".

% telnet desert.fox
Trying 128.2.206.48...
Connected to DESERT.FOX.CS.CMU.EDU.
Escape character is '^]'.
DESERT.FOX.CS.CMU.EDU TCP Telnet service.

4.3 BSD UNIX (DESERT.FOX.CS.CMU.EDU) (ttyP0)

login: tsf
Password:
Last login: Thu May 14 13:11:17 from 128.2.222.175 (*Unknown*)
This login: Tue May 19 14:28:07 from 128.2.222.175 (*Unknown*)
% sml-sg
Standard ML of New Jersey, Version 0.80, April 2, 1992
  with SourceGroup 2.1b built on Fri May  8 10:02:15 EDT 1992
val it = () : unit
- use "load.sml";

[closing /afs/cs/user/tsf/sml/lib/setparams.sml]
Eof
val it = () : unit
/afs/cs/user/tsf/sml/lib/link.sml
/afs/cs/user/tsf/sml/lib/subst.sig.sml
/afs/cs/user/tsf/sml/lib/subst.sml
/afs/cs/user/tsf/sml/lib/util.sig.sml
/afs/cs/user/tsf/sml/lib/util.sml
val libg = 1 : ?.group
val makeload = fn : unit -> unit
[closing /afs/cs/user/tsf/sml/lib/lib.sml]
Eof
val it = () : unit
refine.lex.sml
refine.grm.sig
refine.grm.sml
unify.sml
unify.sig.sml
term.sml
term.sig.sml
subtypedata.sml
subtypedata.sig.sml
subtype.sml
subtype.sig.sml
parse.sml
parse.sig.sml
mltype.sml
mltype.sig.sml
link.sml
interface.sml
interface.sig.sml
interactive.sml
base.sml
absyn.sml
absyn.sig.sml
refine.lex
refine.grm
val newg = 3 : ?.group
val loadref = fn : unit -> unit
[reading /afs/cs/user/tsf/sml/lib/.@sys/util.sig.sml.bin]
signature UTIL
[reading /afs/cs/user/tsf/sml/lib/.@sys/util.sml.bin]
functor Util
[reading /afs/cs/user/tsf/sml/lib/.@sys/subst.sig.sml.bin]
signature SUBST
[reading /afs/cs/user/tsf/sml/lib/.@sys/subst.sml.bin]
functor Subst
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/term.sig.sml.bin]
signature TERM
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/unify.sig.sml.bin]
signature UNIFY
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/unify.sml.bin]
functor Unify
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/term.sml.bin]
functor Term
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtypedata.sig.sml.bin]
signature SUBTYPEDATA
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtypedata.sml.bin]
functor SubtypeData
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/mltype.sig.sml.bin]
signature MLTYPE
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtype.sig.sml.bin]
signature SUBTYPE
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/subtype.sml.bin]
functor Subtype
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/base.sml.bin]
signature LR_PARSER
functor Join
signature ARG_PARSER
signature STREAM
signature FIFO
functor JoinWithArg
signature TOKEN
<other binding>
<other binding>
signature PARSER_DATA
signature LR_TABLE
<other binding>
signature PARSER
signature LEXER
signature ARG_LEXER
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/refine.grm.sig.bin]
signature Refine_LRVALS
signature Refine_TOKENS
[reading /afs/cs.cmu.edu/project/ergo-tsf/sml/thesis/.@sys/interface.sig.sml.bin]

(and it hanged here!  Pressing ^C unhangs it and returns me to the top level.)

Status: fixed in 0.84
----------------------------------------------------------------------
563. trig functions return garbage on large args
Submitter:      Andrzej Filinski, andrzej@cs.cmu.edu
Date:		May 29, 1992
Version:        0.75 (also in 0.80)
System:         all
Severity:       minor
Problem:        trig. functions return huge, random results for arguments 
		greater than approx. 6.747E9 (= 2 pi * maxint).
Transcript:     Standard ML of New Jersey, Version 75, November 11, 1991
		Arrays have changed; see Release Notes
		val it = () : unit
		- sin 6.746E9;
		val it = 0.577192771297902 : real
	        (* correct to about 6 significant digits, as expectable *)
		- sin 6.747E9;
		val it = ~1.17525075405876E64 : real
Comments:	The problem seems to be with the overflow handling in 
		rtoi/drem, file boot/math.sml.
Status: fixed in 0.84
----------------------------------------------------------------------
564. problems on HP9000s400
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           6/2/92
Version:        0.81
System:         HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap
Severity:       minor (but might be major for other people)
Problem:        Bug in sun2hp.el
Code:           Do a 'makeml -m68 hpux8'
Transcript:     

neptune 125 : makeml -m68 hpux8
makeml> (cd runtime; make clean)
        rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.m68 mo
makeml> (cd runtime; rm -f run allmo.o allmo.s)
makeml> (cd runtime; make MACHINE=M68  'CFL=-Wl,-a,archive' 'LIBS=' 'DEFS= -DHPUX -DRUNTIME=\"runtime\"' linkdata)
        cc -g -Wl,-a,archive -DM68 -DHPUX -DRUNTIME=\"runtime\" -o linkdata linkdata.c
(cd runtime; grep -v mo/Math.mo IntM68.mos > Tmp.mos)
makeml> runtime/linkdata [runtime/Tmp.mos]
runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
makeml> (cd runtime; ...)
makeml>   /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s
makeml>   emacs -batch -l sun2hp.el prim.s prim.s
label <2> has moved

makeml>   as -o prim.o prim.s
as error: "prim.s" line 255: invalid instruction mnemonic (.text)
as error: "prim.s" line 255: syntax error
[...rest of error msgs deleted...]

Comments:

"label <2> has moved" is printed by the LISP fn replace-all-label-definitions.
It gets confused because there are more than one label on a line (this
kind of lines with multible labels are produced by the (new) macro 
"CHECKLIMIT" in M68.prim.s).

Fix:

Replace replace-all-label-definitions with the following fn: (the fix does
the following: instead of moving to the beginning of the line in order
to search for the label, the pointer is only moved 2 chars to the left
of the label.)

;; replace-all-label-definitions -- change each of the old label 
;; definitions to their new value.
;;
(defun replace-all-label-definitions (labels)
  (while labels
    (let* ((cur (car labels))
	   (old-label (label-old-label cur))
	   (point (label-point cur))
	   (new-label (label-new-label cur)))
      (goto-char (- point 2))
      (re-search-forward "\\([0-9]+\\):" (point-max) t)
      (if (not (string-equal (buffer-substring (match-beginning 1)
					       (match-end 1))
			     old-label))
	  (error "label <%s> has moved" old-label)
	(replace-match (concat new-label ":"))))
      (setq labels (cdr labels))))
[Reppy:]
Probably the easiest fix for this is to change the CHECKLIMIT macro to

#define CHECKLIMIT                                      \
            1: 						\
               jgt      2f;                             \
               lea      1b,a5;                          \
               rts;                                     \
            2:

[Mortensen:]
I don't think this will work since /lib/cpp on the HP9000s400 (at least
on ours) converts CHECKLIMIT into

  1: jgt 2f; lea 1b,a5; rts; 2:

If sun2hp.el is fixed, anybody can make changes to M68.prim.s without
having to remember that multible labels on a line are not allowed, just
because the translator algorithm in sun2hp.el cannot handle it.

Status: fixed in 0.87
----------------------------------------------------------------------
565. System.Directory.listDir on SGI
Submitter:      John Reppy (jhr@research.att.com)
Date:           June 4, 1992
Version:        0.81
System:         SGI 3D/480, SGI Crimson (Irix 4.0.1, 4.0.4)
Severity:       major
Problem:
  Using the function System.Directory.listDir causes
  sml to go into an uninterruptable infinite loop.
Transcript:     <transcript of session illustrating problem>
  Standard ML of New Jersey, Version 0.81, 15 May 1992
  val it = () : unit
  - System.Directory.listDir ".";
Comments:
  This code often seems to be flakey.  Maybe we should
  switch to using the underlying OS code.
Status: fixed
----------------------------------------------------------------------
566. An addition to sun2hp.el (?)
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           6/2/92
Version:        0.81
System:         HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap
Severity:       minor (but might be major for other people)
Problem:        Tranlation entry missing in sun2hp.el
Code:           Do a 'makeml -m68 hpux8' with the fix to sun2hp.el I send 
                earlier
Transcript:     

neptune 126 : makeml -m68 hpux8
makeml> (cd runtime; make clean)
        rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.m68 mo
makeml> (cd runtime; rm -f run allmo.o allmo.s)
makeml> (cd runtime; make MACHINE=M68  'CFL=-Wl,-a,archive' 'LIBS=' 'DEFS= -DHPUX -DRUNTIME=\"runtime\"' linkdata)
        cc -g -Wl,-a,archive -DM68 -DHPUX -DRUNTIME=\"runtime\" -o linkdata linkdata.c
(cd runtime; grep -v mo/Math.mo IntM68.mos > Tmp.mos)
makeml> runtime/linkdata [runtime/Tmp.mos]
runtime/linkdata> as runtime/allmo.s -o runtime/allmo.o
makeml> (cd runtime; ...)
makeml>   /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s
makeml>   emacs -batch -l sun2hp.el prim.s prim.s
Wrote /d1/release/tools/njsml/workatt81/src/runtime/prim.s
makeml>   as -o prim.o prim.s
as error: "prim.s" line 420: invalid instruction mnemonic (jpl)
as error: "prim.s" line 420: syntax error
as error: "prim.s" line 458: invalid instruction mnemonic (jpl)
as error: "prim.s" line 458: syntax error
as error: "prim.s" line 479: invalid instruction mnemonic (jpl)
as error: "prim.s" line 479: syntax error
as error: "prim.s" line 500: invalid instruction mnemonic (jpl)
as error: "prim.s" line 500: syntax error
as error: "prim.s" line 527: invalid instruction mnemonic (jpl)
as error: "prim.s" line 527: syntax error

Comments (+Fix?):

The intruction "jpl" is not know to the sun2hp translator (in fn do-subst).
I don't know what jpl is supposed to do, but my _guess_ is that it should
be translated into the branch instruction "bpl.w" (anologious to transl.
of jeq, jge, ... etc.).

Shouldn't the line

  (replace-re "\\<jpl" "bpl.w")

be added to the fn do-subst in sun2hp.el?
Status: fixed in 0.90
----------------------------------------------------------------------
567. makeml does not succeed on HPUX (680x0 problem)
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           6/2/92
Version:        0.81
System:         HP9000s400, HPUX 8.0, 32Mb ram, >70Mb swap
Severity:       minor (but might be major for other people)
Problem:        A makeml does not succeed (exception raised in Loader)
Code:           Do a 'makeml -m68 hpux8' with the two fixes to sun2hp.el 
                I send earlier
Transcript:     

>From time to time, I get different results:
---
> makeml -m68 hpux8
[...stuff deleted...]
signature CLEANUP = ...
signature WEAK = ...
signature SUSP = ...
signature POLY_CONT = ...
signature UNSAFE = ...
signature SYSTEM = ...
[closing boot/system.sig]
signature MATH = ...
structure Math : MATH
[closing boot/math.sml]

[Major collection... 20% used (339576/1680172), 250 msec]
uncaught exception (Loader): mlyAction
---
> makeml -m68 hpux8
[...stuff deleted...]
signature LIST = ...
signature VECTOR = ...
signature ARRAY = ...
signature REAL_ARRAY = ...
signature BYTEARRAY = ...
signature IO = ...
signature BOOL = ...
signature STRING = ...
signature INTEGER = ...
signature BITS = ...
signature REAL = ...
signature GENERAL = ...
[closing boot/perv.sig]
uncaught exception (Loader): Ord
---
> makeml -m68 hpux8
[...stuff deleted...]
structure Core : ...
[closing boot/dummy.sml]
signature REF = ...
signature LIST = ...
signature VECTOR = ...
signature ARRAY = ...
signature REAL_ARRAY = ...
signature BYTEARRAY = ...
signature IO = ...
signature BOOL = ...
signature STRING = ...
signature INTEGER = ...
signature BITS = ...
signature REAL = ...
signature GENERAL = ...
[closing boot/perv.sig]
uncaught exception (Loader): Ord
---
> makeml -m68 hpux8
[...stuff deleted...]
signature CLEANUP = ...
signature WEAK = ...
signature SUSP = ...
signature POLY_CONT = ...
signature UNSAFE = ...
signature SYSTEM = ...
[closing boot/system.sig]
signature MATH = ...
structure Math : MATH
[closing boot/math.sml]

[Major collection... 20% used (340948/1682456), 333 msec]
uncaught exception (Loader): Ord
---

Comments:

I cannot tell if this phenomenon is caused by the two fixes I made to 
sun2hp.el:

;; do-subst -- substitute mnemonics, register names, comment symbols etc.
;;
(defun do-subst ()
[...]
  (replace-re "\\<jpl" "bpl.w")
[...]

and the other in:

;; replace-all-label-definitions -- change each of the old label 
;; definitions to their new value.
;;
(defun replace-all-label-definitions (labels)
  (while labels
    (let* ((cur (car labels))
	   (old-label (label-old-label cur))
	   (point (label-point cur))
	   (new-label (label-new-label cur)))
      (goto-char (- point 2))
      (re-search-forward "\\([0-9]+\\):" (point-max) t)
      (if (not (string-equal (buffer-substring (match-beginning 1)
					       (match-end 1))
			     old-label))
	  (error "label <%s> has moved" old-label)
	(replace-match (concat new-label ":"))))
      (setq labels (cdr labels))))
[Reppy:]
This bug also occurs on the Sun-3 and NeXT machines.
It seems to be a general problem with the M68.
Status: fixed in 0.84
----------------------------------------------------------------------
568. crash on sparc on large compilations
Submitter: Pierre Cregut
Date: 6/5/92
Version: 0.82
System: sparc, SunOS 4.2
Severity: serious
Problem: 
  On large compilations (e.g. compiling the compiler) on sparcs that
  are shared with other large jobs (e.g. lisp or another sml), the
  compiler will die with a bus error or illegal instruction or something
  equally drastic.  This is fairly consistent.
Comments:
  Can this be avoided by forcing sml to grap a large memory chunk for
  the heap and hold onto it.
Status: open
----------------------------------------------------------------------
569. failed type inference with flexible records
Submitter:      jont@uk.co.harlqn
Date:		05-06-92
Version:        SML of NJ version number 0.75
System:         Sun 4/330 SunOS 4.1.1
Severity:       major
Problem:        Failed type inference with flexible records
Code:
fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end;
Transcript:
- fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end;
fun f x = let val y = #1 x val z = #2 x in (y, z, x:('a * 'b)) end;
val f = fn : 'a * 'b -> 'a * 'c * ('a * 'b)
- f(1,0);
val it = (1,-,(1,0)) : int * 'a * (int * int)
- 
Comments:	The type should be 'a * 'b * ('a * 'b)
Fix:		Better unification I suspect!
Status: fixed in 0.85
----------------------------------------------------------------------
570. flexrecord equality types
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		6/8/92
Version:        0.82
System:         RISC O/S, MIPS (?)
Severity:       minor
Problem:        Flexrecords are always assumed to contain non-equality
		types when this need not be so.  This leads to legal
		programs being rejected.
Code:           Consider the following code:

	fun force_record {x=x, y=y} = 3;

	fun force_eq x = (x = x);

		Then, the following function types ok since we close the
flexrecord before requiring equality:

	fun bar (r as {x=x, ...}) = (force_record r; force_eq r);

		But the following function fails with a "equality type
required" error because we attempt to require that the open flexrecord
be an equality type:

	fun foo (r as {x=x, ...}) = (force_eq r; force_record r);

Transcript:     

- use "bug.sml";	(* same code as above *)
val force_record = fn : {x:'a,y:'b} -> int
val force_eq = fn : ''a -> bool
val bar = fn : {x:''a,y:''b} -> bool
bug.sml:7.29-7.56 Error: operator and operand don't agree (equality type required)
  operator domain: ''Z
  operand:         {x:'Y,...}
  in expression:
    force_eq r
[closing bug.sml]

Comments:	This problem is due to incorrect code in the type-handling
part of the SML/NJ compiler.  Fixing this will require changing the
definition of types so that flexrecords carry a boolean telling if they
are required to have only equality types or not.  Unify then needs to be
updated to use this information in the proper way.

Status: fixed in 0.85
----------------------------------------------------------------------
571. no occurs check when instantiating flexrecords
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		6/8/92
Version:        0.82
System:         RISC O/S, MIPS (?)
Severity:       minor
Problem:        When flexrecords are instantiated (additional fields
		added/closed), no occurs check is done.  The failure to
		do this can result in cyclic types and hanging the type
		checker.
Code:           The following code hangs the typechecker:

	fun foo {x=x, y=y, z=(z as {...})} = foo z;

Transcript:     
	- fun foo {x=x, y=y, z=(z as {...})} = foo z;
	[hangs here, using more and more space forever]

Comments:	The problem is in the unify routine.  It needs to do
		an occurs check whenever it instantiates a flex record.
Status: fixed in 0.85
----------------------------------------------------------------------
572. unify doesn't update depth for flex record types
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		6/8/92
Version:        0.82
System:         RISC O/S, MIPS (?)
Severity:       major			(* can result in unsoundness *)
Problem:        The unify routine in the SML/NJ compiler fails to update
		the depth fields of variables when dealing with flex
		records.  This causes the type checker to generalize
		types that should not be generalized.
Code:           Many examples are possible.  The simplest I can
		think of is:

		fun snd {a,b} = b;

		fun f (x as {a,...}) =
			let val u = snd x
			in
			    u
			end;

		Here, snd has type {a:'a,b:'b} -> 'b and acts to extract
		the b field of an a-b record.

		So, we start out defining function f.  The (x as
		{a,...}) in the argument list causes x to be bound to
		the type {a: 'a#1, ...}.  [#i means the variable has
		depth i.  I am assuming for this discussion that depths
		start with 1 and go up 1 for each lambda level.]

		Now, in the let val u = snd x, we have to unify the type
		of x with the argument type of snd, namely {a:'c,b:'b}.
		This results in x being bound to type {a:'a#1, b:'b#2}.
		Note the error here.  Type 'b should have depth 1 not 2
		since it is bound at the 1st lambda level (by variable
		x).  However, due to incorrect code in the unifier, this
		doesn't happen and 'b has type 2.

		Thus, when we finish typing the function body we get the
		type 'b#2, which the depth indicates can be safely
		generalized.  Thus, the function body has polymorphic
		type 'c.  This results in f getting type {a:'a, b:'b} ->
		'c when it should have the type {a:'a, b:'b} -> 'b.

Transcript:     

	- fun snd {a,b} = b;
	val snd = fn : {a:'a,b:'b} -> 'b
	- fun f (x as {a,...}) = let val u = snd x in u end;
	val f = fn : {a:'a,b:'b} -> 'c
	- f {a=0, b=true};
	val it = - : 'a

Comments:	The problem is in the handling of types by the SML/NJ
		compiler.  Flexrecords need to have a depth associated
		with them just like normal variables.  This is so that
		you can unify {a:'a#1, ...#1} with {a:'c#3, b:'d#3} and
		get {a:'a#1, b:'d#1} not {a:'a#1, b:'d#3}.  (Note the
		depth associated with the dots in that example.  This is
		the critical information missing from the current type
		representation.)
		
Related-bugs:	Bug reports #521 from Mark Leone, #533 from Richard
		O'Neill, and #569 from jont@uk.co.harlqn are all just
		(less clear) instances of this bug.

Status: fixed in 0.85
----------------------------------------------------------------------
573. unifier detects spurious cycles with type abbrevs
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		6/9/92
Version:        0.82
System:         RISC O/S, MIPS (?)
Severity:       minor
Problem:        The unifier's occurs check sometimes detects a spurious
		cycle when a type variable is unified with a type
		abbreviation that stands for that type variable.
Code:           
		type 'a ID = 'a;

		fun f (x:'a) = (x:'a ID);

		fun g x = g (f x);

Transcript:

	- type 'a ID = 'a;
	type 'a  ID = 'a
	- fun f (x:'a) = (x:'a ID);
	val f = fn : 'a -> 'a ID
	- fun g x = g (f x);
	std_in:4.1-4.17 Error: pattern and expression in val rec dec don't agree (circularity)
	  pattern:    'Z ID -> 'Y
	  expression: 'Z -> 'Y
	  in declaration:
	    g = (fn x => g (<exp>))

	[The above is an incorrect error because 'Z ID = 'Z and hence
the two types should unify without problems.]

Status: fixed in 0.85
----------------------------------------------------------------------
574. redundant patterns in compiler
Submitter: John Reppy
Date: 6/12/92
Version: 0.83
Severity: minor
Problem: 
The compiler reports the following redundant patterns in 0.83:

modules/sigmatch.sml:0.0 Warning: redundant patterns in match
        (DATACON {name=n1,rep=r1,...},DATACON {rep=r2,...}) => ...
  -->   _ => ...

absyn/printabsyn.sml:0.0 Warning: redundant patterns in match
        FCTB {def=FCTfct {def=def,param=STRvar <pat>,...},fctvar=FCTvar {access=access,name=fname,...}} => ...
        FCTB {def=VARfct {def=FCTvar <pat>,...},fctvar=FCTvar {access=access,name=fname,...}} => ...
  -->   _ => ...

Status: fixed in 0.85
----------------------------------------------------------------------
575. line numbers in interactive error messages (same as 552)
Submitter:      Tim Freeman <tsf@cs.cmu.edu>
Date:		Sun Jun 14 12:15:40 1992
Version:        0.80
System:         Sun 4, mach
Severity:       minor
Problem:        The line numbers printed for errors on std_in are erratic.
Transcript:     
	% /usr/misc/.sml/bin/sml
	- aoeiaoei;
	std_in:3.1-3.8 Error: unbound variable or constructor aoeiaoei
	- aoeiaoei;
	std_in:0.0-0.0 Error: unbound variable or constructor aoeiaoei
	- aoeiaoei
	= ueoaoeuaoeu;
	std_in:0.0-0.0 Error: unbound variable or constructor aoeiaoei
	std_in:4.1-4.11 Error: unbound variable or constructor ueoaoeuaoeu
	-	 
Comments: 
	In my opinion, the line numbers reported for
	the above errors should all have been 1, except the last one should
	have been 2. 

Status: same as 552
----------------------------------------------------------------------
576. pattern matching in interpreter broken
Submitter:      slind@research.att.com
Date:           June 14, 1992
Version:        83
System:         mips and sparc at least; probably all
Severity:       major
Problem:        If System.Control.interp is true, pattern matching is broken.
                Manifested with list patterns.
Transcript:     

    $ sml
    Standard ML of New Jersey, Version 0.83, June 12, 1992
    val it = () : unit
    - System.Control.interp := true;
    val it = () : unit
    - val [_] = [1];
    std_in:0.0 Warning: binding not exhaustive
            _ :: nil = ...

    uncaught exception Match
    - System.Control.interp := false;
    val it = () : unit
    - val [_] = [1];
    std_in:0.0 Warning: binding not exhaustive
            _ :: nil = ...
    - ^D
    $ 

Comments:

There is a bug in the interpreter since version 77 caused by a change in
the representation of data constructors.
- System.Control.interp:= true;
val it = () : unit
- val [x] = [1];
std_in:3.1-3.13 Warning: binding not exhaustive
        x :: nil = ...

uncaught exception Match
-
The reason is that cons is tagged with UNTAGGEDREC 2 and the case UNTAGGEDREC
is not treated by the switch.
Lal and I have infered that the only thing the switch interpretor had to
figure out is whether the constructor is tagged or not. So the only necessary
lines to add are:
-cregut->diff codegen/interp.sml /usr/local/sml/77/src/codegen/interp.sml

291,296d290
<            | f((DATAcon(_,UNTAGGEDREC _),ans)::rest) =
<               let val rest' = f rest
<                   val ans' = M ans
<                in fn x => if (U.boxed x) then ans' else rest' x
<               end
<

Is it true or do we need something else ?

Pierre

Status: fixed in 0.86
--------------------------------------------------------------------
577. use of vectors crashes NeXT
Submitter:      Richard O'Neill <richard@smaug.questor.wimsey.bc.ca>
Date:		Thu Jun 18 13:24:53 PDT 1992
Version:        0.75
System:         NeXTstation, OS2.1  and NeXTstation Turbo Color, OS 2.2.
Severity:       Major.
Problem:        

Extensive use of vectors (and probably arrays) when running on NeXTs
causes SML to crash with either "Bus Error", "Segmentation Fault",
"Illegal instruction" or "EMT trap". The same code, when run on SPARC
based Sun machines does not exhibit the same problem.

The code below creates a function called 'bug', which takes an integer
argument. The larger the argument, the more likely SML is to crash,
values like 10000 create an almost immediate crash, values such as 500
sometimes work and sometimes crash SML. (The code is for example purposes
only, I don't actually use code as inefficient as this normally! ;o)

Code (stored in file "bug.sml"):

    open Vector

    fun update(array,index,value) = 
	let
	    fun copy i = 

		if i = index then value
		else sub(array,i)
	    val size = length array
	in
	    if index < size then
		tabulate (size,copy)
	    else
		raise Vector.Subscript
	end

    fun reverse original =
	let
	    val size = length original
	    fun rev (current,count) =
		if count < size then
		    let
			val count'  = count + 1
			val current' =
			    update(current, count, sub(original, size-count'))
		    in
			rev (current', count')
		    end
		else current
	in
	    rev (original,0)
	end

    fun bug n = reverse (tabulate (n, fn x => x))

Transcript:

NeXT-Mach% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "bug.sml";
[opening bug.sml]
open Vector
val update = fn : 'a vector * int * 'a -> 'a vector
val reverse = fn : 'a vector -> 'a vector
val bug = fn : int -> int vector
[closing bug.sml]
val it = () : unit
- bug 500;
val it = - : int vector
- bug 500;
Bus error
NeXT-Mach% 

NeXT-Mach% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "bug.sml";
[opening bug.sml]
open Vector
val update = fn : 'a vector * int * 'a -> 'a vector
val reverse = fn : 'a vector -> 'a vector
val bug = fn : int -> int vector
[closing bug.sml]
val it = () : unit
- bug 5000;
EMT trap
NeXT-Mach%
NeXT-Mach% sml
Standard ML of New Jersey, Version 75, November 11, 1991
Arrays have changed; see Release Notes
val it = () : unit
- use "bug.sml";
[opening bug.sml]
open Vector
val update = fn : 'a vector * int * 'a -> 'a vector
val reverse = fn : 'a vector -> 'a vector
val bug = fn : int -> int vector
[closing bug.sml]
val it = () : unit
- bug 5000;
Bus error

Comments:

It gives an idea how 'wild' the crash is since the latter two cases in
the transcript should be identical, and aren't. I suspect it is some
kind of memory allocation bug, but who knows....

Comment: [dbm, 10/29/92]
  Couldn't reproduce this on a Sun 3 with 0.91.  Either the bug is
  cured or it is NeXT specific.
Status: fixed in 0.92
----------------------------------------------------------------------
578. chatting (in runtime system) doesn't flush stdout
Submitter:      Mark Leone (mleone@cs.cmu.edu)
Date:           June 24, 1992
Version:        80
System:         all
Severity:       minor
Problem:        chatting() doesn't flush stdout
Code:           
Transcript:     
Comments:	GC messages (and other diagnostic compiler output)
		sometimes appear before things that have already been 
		printed to stdout  (e.g. when redirecting batch compiler 
		output to a log file).  This can make it hard to debug 
		the compiler.
Fix:		Add "fflush(stdout)" to chatting() in runtime/run.c
Status: not a bug (inaccurate report according to awa)
----------------------------------------------------------------------
579. Lexing an illegal token can lead to infinite loop
Submitter:      Andrew Tolmach (apt@research.att.com)
Date:		30 June
Version:        0.83
System:         MIPS and SPARC
Severity:       
Problem:        Lexing an illegal token can lead to infinite loop.
Code:           Typing an arbitrary control character (such as CTRL/A),
		followed by return, sends system into an infinite loop.
Transcript:     - ^A
		std_in:0.0 Error: illegal token
		... (infinite loop) ...
Comments:	(1) Looping doesn't occur if illegal token is followed by a 
			complete legal phrase, e.g., ^A1;
		(2) Loop can be interrupted with CTRL/C.
		(3) Didn't occur in 0.82.
Fix: 
  Exception handler in ml.lex.sml uses Reject instead of Internal.Reject
  when Internal is not open, thus producing a handler for all exceptions.
  Change Reject to Internal.Reject in lexgen.
Status: fixed in 0.84
----------------------------------------------------------------------
580. System.Compile, System.Env broken in 0.83
Submitter:      Emden R. Gansner erg@ulysses.att.com
Date:           3 July 1992
Version:        0.83
System:         Sparc 2, SunOS 4.1
Severity:       major
Problem:        Support for separate compilation is broken
Code:           
fun bug () = let
  open System.Compile System.Env
  val staticPerv = staticPart(!pervasiveEnvRef)
  val ins = open_string "signature T = sig end"
  val source = makeSource("<string>", 1, ins, false, std_out)
  val (static, _) = compile(source,staticPerv)
  in
    changeLvars static
  end
Transcript:
Standard ML of New Jersey, Version 0.83, June 12, 1992
val it = () : unit
- use "bug.sml";
val bug = fn : unit -> System.Compile.staticUnit
[closing bug.sml]
val it = () : unit
- bug();
Error: Compiler bug: CompileUnit 2
- 
Status: fixed in 0.86
----------------------------------------------------------------------
581. line numbers in error and warning messages
Submitter: Andrew Appel
Date: 7/3/92
Version: 0.83
Severity: serious
Problem: 
  Many of the error and warning messages have line numbers of 0.0.
Comments: Something wrong in the use of markabsyn.
Status: fixed in 0.88
----------------------------------------------------------------------
582. interaction of open declarations and eval_stream
Submitter:      Andrew Tolmach (apt@research.att.com)
Date:		7 July 92
Version:        0.83
System:         MIPS riscos
Severity:       minor
Problem:        If an open declaration is evaluated by 
		System.Compile.eval_stream, the resulting first-class
		environment is inconsistent: the static environment
		contains the elements of the opened structure, but the
		structure itself is not included in the dynamic environment.
		Subsequent attempts to look up these elements in the
		first-class environment trigger IntMapF exceptions.
Transcript:

Standard ML of New Jersey, Version 0.83, June 12, 1992
val it = () : unit
- open System.Compile System.Env System.Symbol;
open Compile Env Symbol
- structure Fred = struct val a = 10 end;
structure Fred : 
  sig
    val a : int
  end
- val e = eval_stream(open_string "open Fred", 
= layerEnv(!topLevelEnvRef,!pervasiveEnvRef));
open Fred
[closing <instream>]
val e = prim? : environment
- val e' = layerEnv(e,!pervasiveEnvRef); 
val e' = prim? : environment
- eval_stream(open_string "a",e');
[closing <instream>]

uncaught exception IntmapF
- 

Fix: (suggested by Tolmach)
	A top-level open should create a new structure entry in the 
	dynamic environment, and paths for entries in the static 
	environment should be adjusted to point at this new entry.
Fix: (implemented in 0.91)
  A top-level open causes all the runtime components of the structures
  opened to be rebound in the top-level environment.
Status: fixed in 0.91
----------------------------------------------------------------------
583. catalogEnv raises Match exception
Submitter:      Andrew Tolmach  (apt@research.att.com)
Date:		7 July 92
Version:        0.83
System:         Mips riscos
Severity:       minor
Problem:        Executing 
			System.Env.catalogEnv(staticPart (!pervasiveEnvRef))
		provokes a Match exception.

Comment:	Problem is evidently with 
		modules/moduleutil.sml:sortEnvBindings.binderGt,
		which contains an incomplete match.  Perhaps TAB binding
		entries need to be included?
Status: fixed in 0.85
----------------------------------------------------------------------
584. infinite loop in cpsopt
Submitter: John Reppy (jhr@research.att.com)
Date: 7/10/92
Version: 0.84
Severity: major
Problem: 
  The following program causes an infinite loop in cpsopt (I assume
  that this is another case of infinite loop unrolling):
Code: 
  fun foo () = let fun loop () = loop () in loop () end;
Status: fixed in 0.86
----------------------------------------------------------------------
585. wrong type for notb in perv.sig
Submitter: Nick Haines (Nick_Haines@VOILA.VENARI.CS.CMU.EDU)
Date: 7/10/92
Version: 0.84
Severity: minor
Problem: 
In boot/perv.sig, the type of `notb' is given as

		int * int -> int

not as

		int -> int

as it should be (and as boot/perv.sml has it).
Fix: change the type in perv.sig
Status: fixed in 0.86
----------------------------------------------------------------------
586. uncaught Match in interpreter
Submitter:      John Reppy (jhr@research.att.com)
Date:		July 10, 1992
Version:        0.77 and later
System:         any
Severity:       minor
Problem:        an uncaught exception Match in the interpreter
Code:
  System.Control.interp := true;
  datatype t = Z | S of t;
  fn (S _) => 0;
Transcript:
  Standard ML of New Jersey, Version 0.77, February 24, 1992
  Arrays have changed; see Release Notes
  val it = () : unit
  - datatype t = Z | S of t; System.Control.interp := true; fn (S _) => 0;
  datatype  t
  con S : t -> t
  con Z : t
  val it = () : unit
  std_in:2.57-2.69 Warning: match not exhaustive
          S _ => ...

  uncaught exception Match
  - 
Comments: Mark Lillibridge tracked this down to codegen/interp.sml;
  specifically, the function "f" in the case
    SWITCH(e,_, l as (DATAcon _, _)::_, d) => ...
  The problem seems to be a result of the changes in the datatype
  representation.

  Is this the same as bug #576?
  Bug # 591 is another instance of this
Status: fixed in 0.86
----------------------------------------------------------------------
587. Compiler bug: ModuleUtil: Instantiate:getSigPos.2<Argument>
Submitter: Olivier Nora
Date: 7/14/92
Version: 0.84
Severity: major
Problem: 
  Following code produces compiler bug:
  ModuleUtil: Instantiate:getSigPos.2<Argument>
Code:
signature SEQUENCE =
  sig
    exception LoopingError
    type 'a sequence
    val read        : '1a sequence  -> ('1a * '1a sequence) option
    val append : '1a list * '1a sequence -> '1a sequence
    val add_to : '1a sequence -> '1a sequence -> unit
    val app    : ('2a -> '2b) sequence -> '2a sequence 
                                            -> '2b sequence
    val value  : '1a -> '1a sequence
    val empty_sequence : unit -> '1a sequence
  end

signature SEMANTIC_VALUE = 
  sig
    type 'a semantic_type
    type semantic_value
    type 'a sequence
    exception SemanticValueError of string
    val add_semantic_value : semantic_value -> semantic_value -> unit
    val cast_from : 'a semantic_type -> semantic_value -> 'a sequence
    val cast_to : 'a semantic_type -> 'a sequence -> semantic_value
    val void_semantic_value : semantic_value
  end

funsig MK_SEMANTIC_VALUE (Sequence : SEQUENCE) = SEMANTIC_VALUE

functor MkWhole (functor MkSemanticValue : MK_SEMANTIC_VALUE) =
  struct
  end
Comment: [Cregut]
The bug can be obtained by the simple following code:

signature A=sig end
signature B=sig functor f():A end;

and comes from the fact that A is declared before so contains
no arguments. The fix is a 3 lines changed in extern.sml that
ask the function not to worry if the argument is not there.
It should be in .85

Status: fixed in 0.85
----------------------------------------------------------------------
588. wrong printing of flex records with no fields
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		July 14, 1992
Version:        0.83
Severity:       minor
Problem:        The abstract syntax printing routines print out flex
		records with no fields wrong.  I.e., as "{,...}" instead
		of "{...}".

Code:           (fn {...} => ()) 3;

Transcript:

- (fn {...} => ()) 3;
std_in:18.1-18.18 Error: operator and operand don't agree (type mismatch)
  operator domain: {...}
  operand:         int
  in expression:
    ((fn {,...} => ())) 3
	  ^^^^-------------------- note error

Comments: same as bug #468 which was mislabeled
Status: fixed in 0.85
----------------------------------------------------------------------
589. occurs check with nonstrict type abbreviations
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		July 14, 1992
Version:        0.83
Severity:       minor
Problem:        The occurs check is done wrong in the presense of
		non-strict type abbreviations.

Code:           type 'a CON = int;

		fun foo (x:'a) = (3:'a CON);

		fun bar x = bar (foo x);

Transcript:
		- type 'a CON = int;
		type 'a  CON = int
		- fun foo (x:'a) = (3:'a CON);
		val foo = fn : 'a -> 'a CON
		- fun bar x = bar (foo x);
		[type checker hangs at this point]

Status: fixed in 0.85
----------------------------------------------------------------------
590. Some user type variable names are handled incorrectly.
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		July 14, 1992
Version:        0.83
Severity:       minor
Problem:        Some user type variable names are handled incorrectly.

Code:           val x : '_1abcd = 3;

Transcript:
- val x : '_1abcd = 3;
std_in:0.0-0.0 Error: pattern and expression in val dec don't agree (type mismatch)
  pattern:    '1_1abcU
  expression: int
  in declaration:
    x : '1_1abcU = 3
	   ^^^^------------------- note no 'd' on end!

Comment:
  Note that this kind of type variable name is no longer legal
  as of 0.85.
Status: fixed in 0.85
----------------------------------------------------------------------
591. uncaught Match evaluating fn expressions.
Submitter: Elsa Gunter
Date: 7/15/92
Version: 0.84
Severity: major
Problem: 
  Match exception raised when evaluating innocuous "fn" expressions.
  This was in a version of 0.84 in which eXene was loaded.
Transcript: 
  - fn (th :: _) => [th] | nil => nil;

  uncaught exception Match

  - fn (SOME x) => [x] 
  = | NONE => [];

  uncaught exception Match
Comment:  does not occur in plain 0.84
	  Confirmed to be an instance of bug #586
Status: open
----------------------------------------------------------------------
592. unhelpful error messages for record type mismatches
Submitter:      thomas yan, tyan@cs.cornell.edu
Date:		7/17/92
Version:        <= .85
Severity:       minor, but annoying
Problem:        unhelpful error messages for record type mismatches
Code:           val {e:int, g:int, i:int, k:int option, m:int, p:int, ...} =
		    {e=0, g=0, j=0, k=[0], n=0, p=0, r=0, t=0, w=0, x=0, z=0}
		(* and similar variations *)
Transcript:     
    - val {e:int, g:int, i:int, k:int option, m:int, p:int, ...} =
	  {e=0, g=0, j=0, k=[0], n=0, p=0, r=0, t=0, w=0, x=0, z=0};
    std_in:0.0-331.117 Error: pattern and expression in val dec don't agree (record labels)
      pattern:    {e:int,g:int,i:int,k:int option,m:int,p:int,...}
      expression: {e:int,g:int,j:int,k:int list,n:int,p:int,r:int,t:int,w:int,x:int,z:int}
      in declaration:
        {e=e : int,g=g : int,i=i : int,k=k : int option,m=m : int,p=p : int,...} = {e=0,g=0,j=0,k=0 :: nil,n=0,p=0,r=0,t=0,w=0,x=0,z=0}

     - val {e:int, g:int, i:int, k:int option, m:int, p:int} = {e=0, g=0, j=0, k=[0], n=0, p=0};
     std_in:0.0-331.87 Error: pattern and expression in val dec don't agree (tycon mismatch)
       pattern:    {e:int,g:int,i:int,k:int option,m:int,p:int}
       expression: {e:int,g:int,j:int,k:int list,n:int,p:int}
       in declaration:
         {e=e : int,g=g : int,i=i : int,k=k : int option,m=m : int,p=p : int} = {e=0,g=0,j=0,k=0 :: nil,n=0,p=0}

Comments:	the error messages should indicate which labels are a) ok, b)
		extra/mispelled, c) missing.  also, (and this is a problem in
		general with type error messages), the field type mismatches
		should be highlighted, as just "tycon mismatch" gives one no
		idea where the mismatch is.

Fix:		use some kind of field by field comparison of the pattern and
		expression (a 2-column format, while verbose, might work well),
		perhaps first listing all fields that match, then listing all
		labels with mismatched types, then extra labels in the
		expression, then (possibly even for flex records) omitted
		labels.

Status: open
----------------------------------------------------------------------
593. Compiler bug from bad overload declaration
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		7/17/92
Version:        0.83
System:         Sparc
Severity:       minor
Problem:        When values supplied in an overload declaration fail to
		meet the spec given, a compiler bug sometimes occurs.
Code:		
		fun baz [x] = x + 1;
		overload quux : ('a -> 'a) as tl and baz;

Transcript:
		- fun baz [x] = x + 1;
		std_in:0.0 Warning: match not exhaustive
		        x :: nil => ...
		val baz = fn : int list -> int
		- overload quux : ('a -> 'a) as tl and baz;
		Error: Compiler bug: matchScheme: bad tyvar 0
Status: fixed in 0.93c
----------------------------------------------------------------------
594. "val _ = =;" now giving a different (wrong) error (same as 549)
Submitter:      Mark Lillibridge (mdl@cs.cmu.edu)
Date:		7/17/92
Version:        0.83
System:         Sparc
Severity:       minor
Problem:        "val _ = =;" now giving a different (wrong) error

Code:		
		val _ = =;

Transcript:
		- val _ = =;
		std_in:7.9 Error: nonfix identifier required
		Error: Compiler bug: elabVB

Comment:
		This bug report is an addeneum to bug report #549.  That
bug reported that a non-handled Match exception occured on this program.
This bug report is to report that that no longer happens in 0.83.
Instead, a "elabVB" compiler bug occurs.  Still a bug though.

Status: same as 549
----------------------------------------------------------------------
595. uncaught exception UnboundTable compiling bogus signature
Submitter: 	John Reppy
Date: 		July 22, 1992
Version: 	0.85
System: 	Sun 4/75
Severity: 	minor
Problem:	uncaught exception UnboundTable in compiler
Code:
  signature JGRAPH =
    sig
      structure IO
    end

  functor JGraph (IO : IO) : JGRAPH =
    struct
    end

Transcript: 
  Standard ML of New Jersey, Version 0.85, July 17, 1992
  val it = () : unit
  - use "bug.sml";
  bug.sml:3.5-3.13 Error: syntax error: replacing STRUCTURE with EQTYPE
  bug.sml:1.1-8.5 Error: unmatched type spec: IO
  [closing bug.sml]

  uncaught exception UnboundTable
  - 
Comments:
  If you type the code into the top-level loop, you get a different
  kind of syntax error, and the bug doesn't occur.
Status: fixed in 0.89
----------------------------------------------------------------------
596. bad line number info in error messages
Submitter: Andrew Appel
Date: 7/24/92
Version: 0.86
Severity: major
Problem: 
  Many error messages say line "0.0-0.0".
Status: fixed in 0.88
----------------------------------------------------------------------
597. Compiler bug: errors in cps/generic/extract
Submitter: Magnus Carlsson <magnus@cs.chalmers.se>
Date: 7/26/92
Version: 0.75
System: Sun-4
Severity: major
Problem: 
  Following code causes Compiler bug: errors in cps/generic/extract.
Code: 
    datatype 'a fcont = Fcont of 'a fcont cont | Thrown of 'a;

    case callcc Fcont of
	Fcont k => throw k (Thrown 5)
      | Thrown i => i;
Transcript: 
    animal> smlc
    Standard ML of New Jersey, Version 75, November 11, 1991
    Arrays have changed; see Release Notes
    val it = () : unit
    - use "callcc-error.ml";
    [opening callcc-error.ml]
    datatype 'a  fcont
    con Fcont : 'a fcont cont -> 'a fcont
    con Thrown : 'a -> 'a fcont
    Error: Compiler bug: errors in cps/generic/extract
    [closing callcc-error.ml]
    -
Status: fixed in 0.89
----------------------------------------------------------------------
598. Compiler bug: applyTyfun: not enough arguments
Submitter: Andrew Appel
Date: 7/27/92
Version: 0.86
Severity: minor
Problem: 
    Compiler bug after incorrect datatype/withtype declaration.
Code:
    datatype 'a t = A of u
      withtype 'a u = 'a list
Transcript: 
    foo.sml:0.0 Error: type constructor u has the wrong number of arguments: 0
    Error: Compiler bug: applyTyfun: not enough arguments
Comment: [mdl]
	Turned out to be another bug in the module system where a bad
tycon was returned in spite of an error being detected.  Fix is to
change so that ERRORtyc is returned on error.  The diffs to fix it
follow.  I tested the change on the 86 sources and it seems to work
fine.
Fix:
diff moduleutil.sml.86 moduleutil.sml:
------------------ cut here ------------------
524c524
< fun checkArity(tycon, arity,err) =
---
> fun checkArity(tycon, arity,err,result) =
526c526
<     of ERRORtyc => ()
---
>     of ERRORtyc => result
529,531c529,532
<        then err COMPLAIN ("type constructor "^(Symbol.name(tycName(tycon)))^
< 		     " has the wrong number of arguments: "^makestring arity)
<        else ()
---
>        then (err COMPLAIN ("type constructor "^(Symbol.name(tycName(tycon)))^
> 		     " has the wrong number of arguments: "^makestring arity);
> 	    ERRORtyc)
>        else result
537,538c538,539
< 			(checkArity(spec,arity,err);
< 			 RELtyc{name=name,pos=(relpos,pos)})
---
> 			checkArity(spec,arity,err,
> 				 RELtyc{name=name,pos=(relpos,pos)})
540,541c541,542
< 			(checkArity(spec,arity,err);
< 			 RELtyc{name=name,pos=pos})
---
> 			checkArity(spec,arity,err,
> 				 RELtyc{name=name,pos=pos})
544c545
< 	      | (TYCbind tyc,_,_) => (checkArity(tyc,arity,err); tyc)
---
> 	      | (TYCbind tyc,_,_) => checkArity(tyc,arity,err,tyc)

Status: fixed in 0.88
----------------------------------------------------------------------
599. symbolic path names are reversed in error messages.
Submitter: Andrew Appel
Date: 7/27/92
Version: 0.86
Severity: minor
Problem: 
  Symbolic path names are reversed in error messages.
  What should be "MipsInstrSet.instruction", is instruction.MipsInstrSet (etc.)
Transcript: 
    mips/mips.sml:0.0 Error: Inconsistent arities in sharing type instruction.MipsIn
    strSet = instruction.C.<Parameter> : instruction.MipsInstrSet has arity 1 and in
    struction.C.<Parameter> has arity 0.
    mips/mips.sml:0.0 Error: Inconsistent arities in sharing type sdi.MipsInstrSet =
     sdi.C.<Parameter> : sdi.MipsInstrSet has arity 1 and sdi.C.<Parameter> has arit
Status: fixed in 0.89
----------------------------------------------------------------------
600. Core dump running sourcegroup 2.1
Submitter: Amy Felty
Date: 7/28/92
Version: 0.86
System: Sparc, SunOS 4.1
Severity: major
Problem: 
  Core dump running sourcegroup 2.1
Code: 
  SMLTool.targetNamer := SourceAction.sysBinary;
  System.Control.Print.signatures := 0;
  System.Control.indexing := true;

  structure SG = SourceGroup;
  structure SA = SourceAction;
  structure FL = FileList;

  fun smlFiles dirs =
      FL.extensionsOnly ["fun", "sig", "sml"] (FL.inDir (false, dirs));

  fun mlyaccFiles dirs =
      FL.extensionsOnly ["lex", "grm"] (FL.inDir (false, dirs));

  val mlyaccGroup = 
      SG.create [SG.Sources (FL.inFile ["mlyacc/base/base.files"])];
Transcript: 
  - lutece:working> sml-sg
  Standard ML of New Jersey, Version 0.86, July 22, 1992
    with SourceGroup 2.1 built on Fri Jul 24 10:48:49 EDT 1992
  val it = () : unit
  - use "build-elp.sml";
  val it = () : unit
  val it = () : unit
  val it = () : unit
  structure SG : SOURCEGROUP
  structure SA : SOURCEACTION
  structure FL : FILELIST
  val smlFiles = fn : string list -> string list
  val mlyaccFiles = fn : string list -> string list
  Segmentation fault
  lutece:working>
Status: fixed in 0.87
----------------------------------------------------------------------
601. bad implementation of Assembly.A.logb
Submitter:      John Reppy (jhr@research.att.com)
Date:		7/29/92
Version:        0.75-0.85 (probably earlier versions too)
System:         SPARC
Severity:       minor
Problem:        The implementation of logb in runtime/SPARC.prim.s
		doesn't work for 0.0
Code:
  (System.Unsafe.Assembly.A.logb 0.0)
Transcript:
  Standard ML of New Jersey, Version 0.86, July 22, 1992
  val it = () : unit
  - (System.Unsafe.Assembly.A.logb 0.0);
  val it = 
  uncaught exception Boxity
Fix:  "beq 1f" should be "beq 2f"
Status: fixed in 0.87
----------------------------------------------------------------------
602. uncaught exception UnboundTable using System.Env.describe
Submitter: Dave MacQueen
Date: 9/29/92
Version: 0.85
Severity: major
Problem: 
  Invoking System.Env.describe on topLevelEnv with structure symbol
  "System" yields uncaught exception UnboundTable
Transcript: 
  Standard ML of New Jersey, Version 0.85, July 17, 1992
  val it = () : unit
  - System.Env.describe (System.Env.staticPart (!System.Env.topLevelEnvRef))
     (System.Symbol.strSymbol "System");
  uncaught exception UnboundTable
  - 
Comment: System is in Pervasives, not topLevelEnv, but describe should
	 catch the exception and give a report.
Status: fixed in 0.89 (Cregut)
----------------------------------------------------------------------
603. System.Symbol.makestring gives eroneous answer
Submitter:      cregut
Date:		7/29/92
Version:        .83 -> .86
System:         all
Severity:       minor
Problem:        System.Symbol.makestring gives eroneous answer
Code: 
Transcript:     
- open System.Symbol;
open Symbol
- makestring(sigSymbol "s");
val it = "TYC$s" : string
Comments:	bad order of namespaces
Fix:		change makestring in env.sml 
Test File:

let open System.Symbol 
in 
if (makestring(valSymbol "s")^makestring(tycSymbol "s")^
    makestring(sigSymbol "s")^makestring(strSymbol "s")^
    makestring(fctSymbol "s")^makestring(fixSymbol "s")) 
   = "VAL$sTYC$sSIG$sSTR$sFCT$sFIX$s"
then "System.Symbol.makestring seems O.K." 
else "Verify the behaviour of System.Symbol.makestring"
handle _ => "System.Symbol.makestring has a major bug"
end
Status: fixed in 0.87
----------------------------------------------------------------------
604. blast_read/blast_write broken
Submitter:      Emden R. Gansner erg@ulysses.att.com
Date:           30 July 1992
Version:        0.86
System:         Sparc 2, SunOS 4.1
Severity:       major
Problem:        blast_read/blast_write is broken
Code:           
  (* The following function writes a value, then reads it back in
   * and compares them. In 0.86, the values are not equal.
   * If one attempts to print v', the system hangs, causing a
   * core dump on interrupt.
   * You can replace 'int list' with your favorite eqtype
   *)
fun btest v = let
  val ofd = open_out "dump"
  val bwrite : outstream * int list -> int = System.Unsafe.blast_write
  val bread : instream * int -> int list = System.Unsafe.blast_read
  val sz = bwrite(ofd,v)
  val _ = close_out ofd
  val ifd = open_in "dump"
  val v' = bread(ifd,sz)
  in
    close_in ifd;
    if v = v' then print "v = v'\n" else print "print v <> v'\n"
  end
Transcript:
  Standard ML of New Jersey, Version 0.86, July 22, 1992
  val it = () : unit
  - use "btest.sml";
  val btest = fn : int list -> unit
  [closing btest.sml]
  val it = () : unit
  - btest [];
  
  [Major collection...abandoned]
  print v <> v'
  val it = () : unit
  - btest [1,2];

  [Major collection...abandoned]
  print v <> v'
  val it = () : unit
  - 
Comments: Does this have anything to do with bug 548 being fixed?
Fix: [Appel]
    at the beginning of ml_blast_out in cfuns.c, insert the following line
    after "blast_fd = REC_SEL..."

       msp->ml_arg = arg;

    Then do a makeml -noclean and things ought to work better.
Status: fixed in 0.87
----------------------------------------------------------------------
605. whose bug?
Submitter:      Charles Krasic
		cckrasic@plg.waterloo.edu
Date:		July 31, 1992
Version:        0.75
System:         Sparc, SunOS 4.1.2
Severity:       critical
Problem:        file compiles OK with batch compiler, but runtime/run
 	        fails with "uncaught exception (Loader): Syntax"
Comments:	I am working on the source code of NJSML itself.  I have made some
		fairly significant changes so it would be a non-trivial amount of
		work for me to give you all the code necessary to run NJSML and 
		reproduce my problem.   I have isolated my problem to 1 line of code
		in the source code which is will briefly summarize here.  The 
		file that contains the code in question is at the end of this message.
		This code is part of my modified type checker.  Roughly, it is
		called prior to the 0.75 typechecker (there are many changes...)

		This seems to be a very nasty bug to me. It should be noted that, while 
		I am changing the compiler, I am compiling my changed version with the 
		stock 0.75 version of the batch compiler.  My changes are confined
		entirely to the front end of the compiler (nothing after typechecking).

		Some of the things I tried:	

		The offending section of code is:

1.		(case var of
2.		    (VALvar{constraints,...}) => 
3.			(ConstraintsStack.push constraints;
4.			 constructList := (constraints :: (!constructList));
5.			 expType(env,exp,err,loc); 
6.			 ConstraintsStack.pop())
7.		  | _ => (ErrorMsg.impossible "MakeImplicitsPass.Pass2.valrecType"))

		If lines 3,4 and 6 are removed (and 5 has the semicolon removed), it
		will build OK.  Alternatively, if line 5 is removed, it also will
		build OK.  Of course, either of those things doesn't do what I want
		it to do.  I have tried many variations on the above code but could
		not get any to work.

Status: not a bug (bug was in his own code)
----------------------------------------------------------------------
606. Allocating space for saved FP registers is awkward
Submitter:      Mark Leone (mleone@cs.cmu.edu)
Date:		July 31, 1992
Version:        0.82
System:         i386
Severity:       Necessary change for i386 runtime
Problem:        Allocating space for saved FP registers is awkward
Code:           none
Transcript:	none
Comments:
   In runtime/signal.c, in make_ml_sigh_arg(), floating point registers
   are saved as follows:

   #if (NSAVED_FPREGS > 0)
       savefpregs (msp);
       fpregs = PTR_CtoML(msp->ml_allocptr + sizeof(long));
       msp->ml_allocptr += (NSAVED_FPREGS*2 + 1) * sizeof(long);
   #else
       ...

   This code assumes that savefpregs only needs NSAVED_FPREGS*2 + 1
   words.  This assumption fails on the 386, since the entire FP
   coprocessor state must be saved, not just the registers.  

Fix:		
   A better approach is for savefpregs() to update the allocptr itself
   and return a pointer to the saved state:

   #if (NSAVED_FPREGS > 0)
       fpregs = savefpregs (msp);
   #else
       ...
Comment: [jhr]
  A better fix might be introducing a machine dependent constant for the
  fp-save area size.  Also, savefpregs should probably get the save area
  pointer as its argument, since this would simplify the assembly code
  a bit.
Status: open
----------------------------------------------------------------------
607. weak typing
Submitter: John Greiner <John.Greiner@WAGOSH.FOX.CS.CMU.EDU>
Date: 8/4/92
Version: 0.86
Severity: major
Problem: 
  Weak typing error allows failure of type security.
Transcript: 
  - fn x => let val a = ref nil in
	  (let val b = a in b := [true]; hd (!b) + 1; (fn z => z) end) () end;
  val it = fn : 'a -> unit
Fix: This can be fixed by replacing "absd-abs" by "max(0,absd-abs)" in
     basics/typesutil.sml.
Status: fixed in 0.89
----------------------------------------------------------------------
608. minor error in runtime
Submitter: David Tarditi
Date: 8/4/92
Version: 0.85
Severity: minor
Problem: 
  In version 0.85, line 114: run.c, there's a function call of
  the form:
      init_externlist(msp)
  but you'll see in cfuns.c that init_externlist takes no arguments.
Status: fixed in 0.89
----------------------------------------------------------------------
609. include syntax
Submitter: Larry Paulson <Larry.Paulson@cl.cam.ac.uk>
Date: 7/31/92
Version: 0.75
Severity: minor
Problem: 
  Standard ML of New Jersey, Version 75, seems to reject the syntax

     include SIGID1 ... SIGIDn

  (See the definition of Standard ML, page 13.)
Status: fixed in 0.90
----------------------------------------------------------------------
610. changeLvars broken
Submitter: Gene Rollins
Date: 8/5/92
Version: 0.87
Severity: major (for separate compilation)
Problem: 
  There is a compiler bug in SML/NJ 0.85 and 0.87 that is not present in 0.80.
  I tracked it down to this: the function changeLvars when applied to
  a staticUnit sometimes eliminates bindings to fixity symbols.  So, if you try
  to read a compiled binary file, and then compile a file that uses symbols
  defined in the binary file, you sometimes get an error such as this:

      a.sig:1.15-1.19 Error: FIRST undefined (parser)

  If the symbol is really undefined you also get this message:
      a.sig:1.15-1.19 Error: unbound signature: FIRST

  This happens on pmax_mach and sun4_mach machines.  I found that once you have
  a binary file that this bug happens with, it is repeatable.  But, not all
  binary files tickle this bug.
Transcript: 
  - System.system "cat first.sig";
  signature FIRST = sig val x:int end

  - val perv = !System.Env.pervasiveEnvRef;
  val perv = prim? : environment

  - val se = System.Env.staticPart perv;
  val se = prim? : staticEnv

  - val (staticUnit, codeUnit) = SepComp.compileSource ("first.sig", se);
  [closing first.sig]
  val staticUnit = {boundLvars=[],staticEnv=prim?} : System.Compile.staticUnit
  val codeUnit = prim? : codeUnit

  - val delta = System.Compile.execute ((staticUnit, codeUnit), perv);
  signature FIRST
  <other binding>
  val delta = prim? : environment

  - appSE (findName "FIRST") delta; (* catalogEnv; filter for symbols "FIRST" *)
  FIRST
     fixity information of a module component
  FIRST
     signature
  val it = () : unit

  - val staticUnit2 = System.Compile.changeLvars staticUnit;
  val staticUnit2 = {boundLvars=[],staticEnv=prim?} : System.Compile.staticUnit

  - val delta2 = System.Compile.execute ((staticUnit2, codeUnit), perv);
  signature FIRST
  val delta2 = prim? : environment

  - appSE (findName "FIRST") delta2;
  FIRST
     signature
  val it = () : unit
  -
Fix: adjust for new representation of fixity bindings?
Status: fixed in 0.91 (dbm)
----------------------------------------------------------------------
611. batch compiler doesn't like local structure declarations
Submitter:      Mark Leone (mleone@cs.cmu.edu)
Date:		August 5, 1992
Version:        0.82
System:         all
Severity:       very minor
Problem:        batch compiler doesn't like local structure declarations
Code:         
	(* From bug report #278 *)
	local
	   structure Internal = struct val x=1 val y=2 end
	in
	   structure First  : sig val x : int end = Internal
	   structure Second : sig val y : int end = Internal
	end
Transcript:
	Standard ML of New Jersey, Version 82, June 1, 1992 (batch compiler)
	[Compiling tmp.sml]
	Error: signature, functor, or structure expected
	[closing tmp.sml]
Comments:
	This seems to be the same problem exhibited by the interactive
	top-level in bug report #278 (which has been fixed).
Status: open
----------------------------------------------------------------------
612. bad lambda depth calculated in type checker
Submitter:      Mark Lillbridge (mdl@cs.cmu.edu)
Date:		August 5, 1992
Version:        0.87
System:         Sparc
Severity:       major
Problem:        Lambda depth is miscalculated in some cases causing
		the compiler to core dump
Code:           
		fun id x = x;

		(fn y => id (let val u = y in u end)) 1 2;

Transcript:
		- fun id x = x;
		val id = fn : 'a -> 'a
		- (fn y => id (let val u = y in u end)) 1 2;
		Bus error (core dumped)

Comments:	The code in typesutil.sml that calculates lamdepth is
		wrong.  In cases like this, lamdepth can actually
		decrease instead of being monotonically increasing.
		(Here, lamdepth is 1 at the fn y => but 0 at the let.)

Status: fixed in 0.89
----------------------------------------------------------------------
613. Compiler bug message on occurence of typevar in signature
Submitter:      Kees van Schaik <kees@diku.dk>
Date:		August 7 1992
Version:        Version 75
System:         Sun 4 Sparc station running SunOS Release 4.1.1
Severity:       minor
Problem:        Compiler bug message on occurence of typevar in signature
Code: 		
		signature BuggySignature = 
		   sig exception IllegalException of '_a ref end

Transcript:	
		Standard ML of New Jersey, Version 75, November 11, 1991
		The Edinburgh SML Library Make is now pre-loaded.
		val it = () : unit
		- signature BuggySignature = 
		     sig exception IllegalException of '_a ref end;
		signature BuggySignature = 
		  sig
		    exception IllegalException of Error: Compiler bug: domain

Comments:	The signature is not a legal one since it is not allowed to
		use type variables in exception declarations in signatures.
		A somewhat more informative way of telling that would be
		nice (mostly to people who did not know/realise that their
		code was not legal when triggering the bug, who will most
		probably the only ones triggering it), but the bug does not
		cause any serious problems.

Comments: [dbm] Now generates an error message when signature is elaborated.

Status: fixed in 0.91 (dbm)
----------------------------------------------------------------------
614. high-order-functor thinning-in
Submitter:    Zhong Shao   (zsh@cs.princeton.edu)
Date:         August 6, 1992
Version:      0.86
System:       mipsb/riscos
Severity:     critical
Problem:      high-order-functor thinning-in
Code:
              signature SIG = sig val e : real
                              end

              funsig PROD (structure M : SIG
                           structure N : SIG) = SIG

              structure S = struct val e = 100.0
                            end

              structure P = struct val e = 0.0
                            end

              functor Square(structure X : SIG
                             functor Prod : PROD) : SIG =
                  Prod(structure M = S
                       structure N = X)

              functor F(structure N : SIG) = struct val e = (N.e * N.e)
                                             end

              structure A = Square(structure X = P
                                   functor Prod = F);

              A.e;

Transcript:
              .....................
              - A.e;
              val it = 10000.0 : real

Comments:     A.e should be 0.0 instead. The problem is that
              when F is applied to (structure M=S structure N=P) in
              the body of functor Square, the argument is not thinned
              against the parameter signature of the functor F.

Status: fixed in 0.89
----------------------------------------------------------------------
615. System.Symbol.makestring has incomplete implementation
Submitter:      Andrew Tolmach (apt@research.att.com)
Date:		10 Aug 92
Version:        0.85 through 0.88
System:         mips riscos
Severity:       minor
Problem:        Can't apply System.Symbol.makestring to pervasive environment.
Code:           - let open System.Env System.Symbol 
		  in map makestring (catalogEnv (staticPart(!pervasiveEnvRef)))
		  end;
Transcript:     above code causes 
		Compiler bug: Symbol.makestring
	
Fix:  Add TABspace case to Env.symbolToString (?)
Status: fixed in 0.89
----------------------------------------------------------------------
616. overloading versus user-bound type variable
Submitter: Lars Birkedal <birkedal@diku.dk>
Date: 8/12/92
Version: 0.87 (and earlier)
Severity: minor
Problem: 
  I assume you resolve arithmetic overloading in NJSml by 
  binding the operators, such as +, to a generel type-scheme, such 
  as \forall 'a. 'a *'a -> 'a, where the type-variables are marked
  as overloaded, and then elaborates as usual with the exception
  that overloaded type variables are not allowed to be quantified. 
  (Some examples I've run indicates this.)

  The following example seems to indicate that you allow unification of
  overloaded type variables with explicit type variables and when
  unifying marks the explicit type variables as overloaded. This mark
  prohibits quantification of the explicit type variable at its scoping
  declaration, hence violating rule 17 in the Definition.  My question
  is --- why allow unification of overloaded typevariables with explict
  type variables at all?; since quantification is not allowed,
  overlaoding cannot be resolved this way (as in let val f = fn x => x +
  x in f 2 end, which elaborates), so the only other way is to unify the
  explicit type variable with int or real, which is not allowed, hence
  overloading cannot be resolved this way either. So what do you gain?

Transcript: 
  - let val f = fn (x: 'a) => x + x in f 2 end;
  std_in:1.5-1.31 Error: explicit type variable cannot be generalized at its scoping declaration: 
  'a
  std_in:1.29 Error: overloaded variable "+" cannot be resolved

Comment: [dbm]
  The type variables of the type scheme of an overloaded variable are
  "marked as overloaded" when an instance of the type scheme is created
  for a particular applied occurence of the variable.  This marking is
  accomplished by a book-keeping device -- each type metavariable
  substituted for a bound variable of the scheme is given a "depth" of
  zero.  The depth attribute is used to determine whether a metavariable
  can be generalized at a val binding, and a depth of zero will prevent
  these metavariables (or metavariables in types substituted for them)
  from ever being generalized.

  When one of these metavariables is unified with a "user-bound" type
  variable like the 'a in your example, the depth of the metavariable is
  propagated to the user-bound variable, which in this case prevents the
  user-bound variable from being generalized at the appropriate place.
  This looks like a bug -- in fact, I think that the user-bound variable
  should probably not have a depth attribute at all.

Status: not a bug (but alternate handling might be better)
----------------------------------------------------------------------
617. interpreter fails with "no default in interp"
Submitter:      Andrew Tolmach (apt@research.att.com)
Date:		12 Aug 92
Version:        0.87
System:         mips riscos
Severity:       major
Problem:        On a variety of programs, the interpreter 
		fails with "no default in interp". 
Code:		System.Control.interp := true;
		use "/usr/local/sml/benchmarks/leroy.sml";
			(* the standard knuth-bendix benchmark *)

Transcript:   

signature KB = 
  sig
    datatype ordering
      con Equal : ordering
      con Greater : ordering
      con NotGE : ordering
    datatype term
      con Term : string * term list -> term
      con Var : int -> term
    val doit : unit -> unit
    val kb_complete : (term * term -> bool) -> (int * (int * (term * term))) list -> ('a * ('b * (term * term))) list -> unit
    val lex_ext : (term * term -> ordering) -> term * term -> ordering
    val rpo : (string -> string -> ordering) -> ((term * term -> ordering) -> term * term -> ordering) -> term * term -> ordering
  end
/usr/local/sml/benchmarks/leroy.sml:603.1-608.22 Warning: match not exhaustive
        "U" => ...
        "*" => ...
        "I" => ...
        "B" => ...
        "C" => ...
        "A" => ...
Error: Compiler bug: no default in interp
[closing /usr/local/sml/benchmarks/leroy.sml]
Comments: Failure to track changes in data representations?
  
If the debugger is built using makeml -i, this bug occurs
the first time a usedbg_live is tried.

Status: fixed in 0.90
----------------------------------------------------------------------
618. LOOKUP FAILS, Compiler bug: 110 in CPSgen
Submitter: Dave MacQueen
Date: 8/15/92
Version: 0.87
System: Sparc, Mips
Severity: critical
Code: 
  (* bug618.sml *)

  signature S0 =
  sig
    exception Error of string  (* string arg necessary *)
  end

  functor F (X : S0) =
  struct
    open X
    fun extend_one (i,v,r) j = if i = j then v else (r j) (* necessary *)
    fun extend_env _ = raise Error "foo"
  end

  structure A : S0 =
  struct
    exception Error of string
  end

  structure B = F(A)
Transcript: 
  skye$ sml
  Standard ML of New Jersey, Version 0.87, July 31, 1992
  val it = () : unit
  - use "bug618.sml";
  LOOKUP FAILS in close(FIX 2373
  ) on 2310
  in environment:
  2370 2368 2451 2448 2449 2450 
  2369/callee 2451 - 2448 2449 2450
  Error: Compiler bug: 110 in CPSgen
  [closing bug618.sml]
  - use "bug618.sml";
  Illegal instruction(coredump)
  skye$ 
Status: fixed in 0.89
----------------------------------------------------------------------
619. Compiler bug: Escapemap on xxxx
Submitter: Dave MacQueen
Date: 8/15/92
Version: 0.87
System: Sparc, Mips
Severity: critical
Code: 
  (* bug619.sml *)

  signature SIG =
  sig
    exception Error of string
  end

  functor F (X : SIG) =
  struct
    open X

    datatype Exp = APP of Exp * (Exp list)
    datatype Val = FUNC of Val list -> (Val -> unit) -> unit

    fun extend_one (i,v,r) j = if i = j then v else (r j)
    fun extend_env([],[],r) = r
      | extend_env(i::is,v::vs,r) = extend_env(is,vs,extend_one(i,v,r))
      | extend_env _ = raise Error "mismatching environment extension"

    fun  meaning (APP(e,es)) r k =
	  meaning e r (fn (FUNC f) => meaninglis es r (fn vs => f vs k))

    and meaninglis [] r k = k []
      | meaninglis (e :: es) r k =
	  meaning e r (fn v => meaninglis es r (fn vs => k (v :: vs)))
  end

  structure A : SIG =
  struct
    exception Error of string
  end

  structure B = F(A)  (* necessary *)
Transcript: 
  - skye$ sml
  Standard ML of New Jersey, Version 0.87, July 31, 1992
  val it = () : unit
  - use "bug619.sml";
  Error: Compiler bug: Escapemap on 2423
  [closing bug619.sml]
  - 
Comment: probably closely related to bug 618.  Minor simplifications
	 of the code produce a version of bug 618.
Status: fixed in 0.89
----------------------------------------------------------------------
620. higher-order functor causes Compiler bug
Submitter: Dave MacQueen
Date: 8/15/92
Version: 0.87
Severity: major
Problem: 
  Higher order functor definition fails with
  "Compiler bug: abstractfct:tyconSeries1: param tycon not found"
Code: 
  signature SIG =
  sig
    datatype d = D of unit   (* the "of unit" is necessary for bug *)
  end

  functor Twice(functor F(A:SIG):SIG) =
  struct
    functor TwiceF(A: SIG) = F(F(A))
  end
Transcript: 
  - use "bug620.sml";
  Error: Compiler bug: abstractfct:tyconSeries1: param tycon not found
  [closing bug620.sml]
Status: fixed in 0.89
----------------------------------------------------------------------
621. polymorphic equality not eliminated as often as it should be
Submitter:   aitken@cs.cornell.edu (William E. Aitken)
Date:        Aug 13, 1992
Version:     0.87 (also 0.88b)
System:      sun4 sunos 
Severity:    minor
Problem:     polymorphic equality not eliminated as often as it should be
Code:        
	     val eq = (op =)
	     val eq1 : int * int -> bool = (op =)
	     val eq2 = (op =) : int * int -> bool
	     
Transcript: 
(Script started on Thu Aug 13 11:46:13 1992)
ai $ sml
Standard ML of New Jersey, Version 0.87, July 31, 1992
val it = () : unit
- System.Control.CG.printit := true;
val it = () : unit
- (* this should be implemented as poly-eq *)
= val eq  = op =;

After convert:
2316(2314,2315) =
   2317(2313,2318) =
      2319(2320) =
         2318((I)0)
      2313((I)99,2319)
   2317(2314,2315)
.
.
.
val eq = - : ''a * ''a -> bool

- (* this should be implemented as integer equality, but isn't *)
= val eq1 : int * int -> bool = (op =) ;

After convert:
2346(2344,2345) =
   2347(2343,2348) =
      2349(2350) =
         2348((I)0)
      2343((I)99,2349)
   2347(2344,2345)
.
.
.
val eq1 = - : int * int -> bool
-
- (* this should be implemented as integer equality, and is *)
= val eq2 = (op =) : int * int -> bool;

After convert:
2376(2374,2375) =
   2377(2373,2378) =
      2379(2380) =
         2382(2381,2383) =
            2381.0 -> 2384
            2381.1 -> 2385
            if ieql(2384,2385) [2388] then
               2383((I)1)
            else
               2383((I)0)
         {2382} -> 2389
         2378(2389)
      2373((I)99,2379)
   2377(2374,2375)

.
.
.

val eq2 = fn : int * int -> bool

(script done on Thu Aug 13 11:47:39 1992)

Comments:

eq1 implements the equality check as a call to
polymorphic equality, while eq2 
inline expands the equality for the type int.

This is particularly obnoxious since, at least to me, 
the declaration of eq1 looks prettier.

Status: fixed in 0.89
----------------------------------------------------------------------
622. Bus error on DECstation 5000/200
Submitter: Urban Engberg <urban@daimi.aau.dk>
Date: 8/18/92
Version: 0.75-0.80
System: DECstation 5000/200 and 5000/240
Severity: major
Problem: 
  I have been using SML of NJ for a couple of years, mostly for writing
  compiler-related tools.  The tool I am currently working on contains about 7000
  lines of sml-code, including the code produced by sml-lex and -yacc.  The
  relatively large size of the program seems essential to my problem to be
  described.

  When compiling the code, by reading in the files with "use", the sml system
  once in a while crashes with messages such as

    pid 22613 (tlac.orig) was killed on an unaligned access, at pc 0x100a3550
    Bus error (core dumped)

  The problem has been specific to running on DECstations 5000/200 and 5000/240
  (at least) but occurs on all the machines of this kind that I have tried.

  I have been able to bear over with the problems for some time, without trying
  to find the error, as I would just have to restart the compilation at the right
  point a couple of times.

  Lately, however, the problem has started showing up more and more often when I
  execute the binary image I create with the library-construct "exportFn".  As my
  code has been growing, I have now got a ratio of well-functioning runs to ones
  crashing of about 1:10!  Thus it is beginning to be a very big problem.

  [added 8/19/92]
  The problem occurs at random.  But running a compilation which takes about five
  seconds will currently produce the crash nine times out of ten.

  I am running Ultrix version 4.2A (Apr 92), which I suppose is one of the
  newest.  I remember having had problems all the time since I began using DEC
  machines though, since March 91.  You are quite right in that `unaligned
  access' errors seems to indicate some sort of Ultrix bug.
Comments: [George]
  This brings back memories of when I was bringing up the new MIPS
  code generator. The regression tester specifically, would run
  just fine on a MIPSEB but would crash once in a while in a 
  non-deterministic manner on a MIPSEL. The error message was 
  identical - unaligned access, at pc ...

  At the time, we concluded that this was an operating system related 
  problem, and not the fault of the generated code. Unfortunately, I 
  did not persist in getting to the root of the problem. I am not 
  able to reproduce the error as the regression tester being used
  is gone!!

  My suggestion would be to try a post v 0.82 release that had
  even less reliance on the operating system - i.e., any trapless gc
  version.

Followup: [Urban Engberg, 8/24/92]
  It has been making me curious that the errors lately doesn't seem to show up in
  other programs than my compiler (where it with earlier sml versions has been a
  problem with many programs, and also when compiling the compiler).  So with a
  good guess, I tried removing some calls I had to `IO.execute'.  This made a
  crucial difference; the compiler now runs without any problems.

  To help finding the error, it should be noted that the compiler works fine
  *with* the `IO.execute' commands, when run from within an interactive sml
  session.

  I have tried to reproduce the error in a smaller program, but without success.

  The calls to `IO.execute' looked as follows:

	  val (datestream, dummy) =
		      IO.execute ("/bin/csh", ["-cfb", 
				  "/bin/date +\"%a %h %d%H:%M 19%y\""])
	  val date = input (datestream, 21) before (close_in datestream;
						    close_out dummy)
Status: fixed in 0.89
----------------------------------------------------------------------
623. wildcard is equivalent to a serie of wildcards (see also 629)
Submitter:      cregut 
Date:		20/8/92
Version:        .88
System:         all
Severity:       minor/major
Problem:        wildcard is equivalent to a serie of wildcards
Code:
  fun foo x 0 = x | foo _ = 0;  (* this failed in pre-0.88 versions *)
Transcript:
  val foo = fn : int -> int -> int
Status: fixed in 0.90
----------------------------------------------------------------------
624. System.Env.filterEnv causes Compiler bug: copystat.
Submitter: Gene Rollins
Date: 8/21/92
Version: 0.88
Severity: major
Problem: 
  System.Env.filterEnv causes compiler bug: copystat.
Code: 
==== env.sml ====
structure TestEnv = struct
 fun printEnv (e:System.Env.environment) =
   app (fn s=> (print ((System.Symbol.makestring s) ^ "\n")))
     (System.Env.catalogEnv (System.Env.staticPart e))
 val TestStructure = System.Symbol.strSymbol "Test";
 fun test() =
   (use "test.sml";
    printEnv (!System.Env.topLevelEnvRef); print "----------\n";
    printEnv(System.Env.filterEnv(!System.Env.topLevelEnvRef,[TestStructure])))
end
==== test.sml ====
structure Test = struct val x = 4 end
Transcript: 
Standard ML of New Jersey, Version 0.88, August 14, 1992
- use "env.sml";
structure TestEnv : sig
    val TestStructure : symbol
    val printEnv : environment -> unit
    val test : unit -> unit
  end
- TestEnv.test();
structure Test : sig val x : int end
[closing test.sml]
STRTAB$Test
STRTAB$TestEnv
STR$Test
STR$TestEnv
VAL$it
----------
Error: Compiler bug: copystat
- 

Status: fixed in 0.89 (Cregut)
----------------------------------------------------------------------
625. Runbind exception still being raised.
Submitter: Gene Rollins, Andrew Appel
Date: 8/21/92
Version: 0.88
Severity: major
Problem: Runbind exception still being raised.
Status: fixed in 0.91 (not verified)
----------------------------------------------------------------------
626. extra spaces in SPARC.prim.s
Submitter: Gene Rollins
Date: 8/21/92
Version: 0.88
System: SPARC
Severity: 
Problem: 
It appears that our assembler can't handle the extra spaces given in several
of the #defines in the original file SPARC.prim.s.0.  The new SPARC.prim.s
works fine.  Here are the differences.  They are all within the first 55 lines.
Fix:
% diff SPARC.prim.s.0 SPARC.prim.s
26c26
< #define exncont  g7  /* exception handler (ml_exncont)	*/
---
> #define exncont g7   /* exception handler (ml_exncont)	*/
29,35c29,35
< #define limit    g4  /* heap limit pointer (ml_limitptr)*/
< #define stdarg   i0  /* standard argument (ml_arg)  	*/
< #define stdcont  i1  /* standard continuation (ml_cont) */
< #define stdclos  i2  /* standard closure  (ml_clos)	*/
< #define baseptr  i3  /* base code pointer (ml_roots[])  */
< #define varptr   i5  /* var pointer       (ml_varptr)   */
< #define stdlink  g1  
---
> #define limit g4     /* heap limit pointer (ml_limitptr)*/
> #define stdarg i0    /* standard argument (ml_arg)  	*/
> #define stdcont i1   /* standard continuation (ml_cont) */
> #define stdclos i2   /* standard closure  (ml_clos)	*/
> #define baseptr i3   /* base code pointer (ml_roots[])  */
> #define varptr i5    /* var pointer       (ml_varptr)   */
> #define stdlink g1  
49,53c49,53
< #define tmp1  o2
< #define tmp2  o3
< #define tmp3  o4
< #define tmp4  o5  /* also used to pass register mask to g.c. */
< #define gclink  o7   /* link register for return from g.c.  (ml_pc) */
---
> #define tmp1 o2
> #define tmp2 o3
> #define tmp3 o4
> #define tmp4 o5     /* also used to pass register mask to g.c. */
> #define gclink o7   /* link register for return from g.c.  (ml_pc) */
Status: Fixed in 0.89
----------------------------------------------------------------------
627. blast-writing objects outside the heap leads to failure
Submitter: David Tarditi
Date: 8/21/92
Version: 0.88
Severity: major
Problem: 
  blast-write fails when given an object that is outside the
  heap.   The following program (for version 0.75, shareable) demonstrates this.
  You'll have to change the program slightly to run it in the latest version of
  the compiler, since the type of blast_read has changed.
Code: 
  structure blast =
      struct
	  val s = System.version
	  val outblast = fn () =>
	    let val outfd = open_out "testblast"
	     in (System.Unsafe.blast_write (outfd, s); close_out outfd)
	    end
	  val inblast = fn () =>
	    let val infd = open_in "testblast"
		val res : string = System.Unsafe.blast_read infd
		val _ = close_in infd
	    in
	      (print "Got back: "; print res; print " : from testblast\n")
	    end

	  val _ = outblast ()
	  val _ = inblast ()
  end
Transcript: 
  - use "/usr/dtarditi/tmp";
  [opening /usr/dtarditi/tmp]

  [Major collection...abandoned]
  Got back:  : from testblast
  structure blast : 
    sig
      val inblast : unit -> unit
      val outblast : unit -> unit
      val s : string
    end
  [closing /usr/dtarditi/tmp]
  val it = () : unit
Comments:
  In the shareable version of the compiler, where the code for the compiler
  is palced outside the heap, the string System.version ends up outside the
  heap.
Fix:
  The solution is to add a check to the code for blast-write, I think,
  for the case where the object being blasted out is a pointer that is outside
  the heap.
  [Tarditi, 8/21/92:]
  I remember there was some problem about import not working across 
  different compiled versions of the same compiler.  For example,
  I think import files created with a shareable version of the compiler
  caused the nonshared version to crash.   I've realized what the problem
  is, and it is worth noting down for future reference.

  The basic problem is that blast_write isn't fully generally, and only
  works with a particular executable.  If you blast-write an object which
  contains pointers that are outside the heap, the garbage collector
  just copies the pointers as though they were integers.   The problem is
  that with different executables, the objects outside the heap may not
  exist at all, may be different (that is, the pointer points to junk), or
  they may be at a different address.

  Think about what happens when you blast-write a function.   The function
  will most likely contain objects from the pervasive environment in its
  closure.  Suppose one of those objects from the pervasive environment
  is a closure.  It will contain a code pointer.  If the compiler is 
  shareable version, the code pointer will be outside the heap.  Now,
  if we try to read blast_read this function into a nonshareable version
  of the compiler, the code pointer will be junk!  

  Note that you'll have this problem even if only the runtime has been
  changed across executables.  This will change the address of code for
  the assembly language primitives, and the addresses of ML objects allocated
  as static C data structures.

  A possible solution to add a level of indirection between objects in the
  runtime system and blast-written objects.

  (1) give every possible ML object in the runtime system a unique name
  (2) when blast-writing an object, translate ML objects outside the heap to
      their unique names
  (3) when blast-reading an object, translate from the unique names back to the
      ML objects.

  We could hack something up to deal with the code strings for the pervasives
  being either in the heap or text segment.

  We'd have to put a limitation that you can only blast-read/blast-write objects
  outside the heap which are "registered" (i.e. you can't blast-write things
  like the code for the compiler).   At least things could fail gracefully
  instead of crashing.

Status: fixed in 0.89
----------------------------------------------------------------------
628. System.Env.filterEnv broken (accidental duplicate of 624)
----------------------------------------------------------------------
629. fun declaration syntax  (see 623)
Submitter:      aitken@cs.cornell.edu (William E. Aitken)
Date:		Sat Aug 29 1992
Version:        0.88 (back to 0.83 -- worked in 0.82)
System:         Sun 4m/670 MP Sparc, SunOS Release 4.1.2
Severity:       minor
Problem:        function declarations made using `fun' may
		arbitrarily mix clauses in which the 
		formal parameters are curried and 
		clauses in which they are uncurried.  
		Note that if they are uncurried, the formal
		pattern must be of n-tuple type.  That is,
		it may be a variable pattern or a wildcard pattern
		or a tuple pattern of the appropriate arity.

Code:           
		fun foo 1 x = 17
                  | foo (a, b) = a + b
		
		fun bar (1, x) = 17
		  | bar a b = a - b

		fun splat a b = 4
		  | splat x = 5

Transcript: 
    
% sml
Standard ML of New Jersey, Version 0.88, August 14, 1992
val it = () : unit
- fun foo 1 x = 17
=   | foo (a, b) = a + b;
val foo = fn : int -> int -> int
- fun bar (1, x) = 17
=   | bar a b = a - b;
val bar = fn : int * int -> int
- fun splat a b = 4
=   | splat x = 5;
std_in:5.17-6.15 Warning: redundant patterns in match
        (a,b) => ...
        x => ...
val splat = fn : 'a -> 'b -> int
- ^D
% 

Comments:

	There are two function declarations in
	translate/tempexpn.sml that (accidentally)
	exploit this bug.  They are the last two functions of
	the structure.  In the first case, the second argument needs
	to be uncurried, in the second case, the final clause
	needs a second wildcard pattern.  Similarly,
	the function labBranchOff in mips/mipsinstr.sml, needs
        a second wildcard pattern in its final clause's formal parameters.

	The problem occurs because no explicit test is ever made 
	to ensure that clauses have the same number of argument 
	patterns.  In elaborating a function declaration,
	the compiler produces something of the form

		fn x1 => ... => fn xn => case (x1, ..., xn) of
			p1 => e1
			.
			.
			.
			pm => em

	x1, ..., xn are distinct new variables.
	ei is the expression of the ith clause.
	n is the number of patterns in the *first* clause
	If the ith clause has r > 1 patterns (pi1, ..., pir), pi is the 
	the pattern (pi1, ..., pir).   If the ith clause has only
	one pattern, pi is that pattern.

	The type checker will detect most mis-matches between
	numbers of arguments --- e.g.,

		fun foo a b c = 4 
		  | foo a b = 5;
		std_in:7.17-7.31 Error: rules don't agree (tycon mismatch)
  		  expected: 'Z * 'Y * 'X -> int
  		  found:    'W * 'V -> int
  		  rule:
    		    (a,b) => 5

	but will not catch mis-matches between appropriately typed single 
	patterns and multiple patterns.  	
	
Fix:	Add a check that the number of formal parameters agrees in  
	each clause.  Rewriting checkFB in parse/astutils.sml as 
	follows should work, the compiler compiles itself to a fixpoint
	with it installed, but I have *not* tested the resulting code
	very thoroughly.   (Note that translate/tempexpn.sml and 
	mips/mipsinstr.sml need to be fixed too, as described above).

	fun checkFB(clauses as ({name,pats,...}:rawclause)::rest, err) = 
	      let 
	        val patslen = length pats
      	      in 
		if exists (fn {name=n,...} => not(Symbol.eq(n,name))) rest
      	          then err COMPLAIN "clauses don't all have same function-name"
      	        else if exists (fn {pats=p,...} => length p <> patslen) rest
      	        then 
		  err COMPLAIN "clauses don't all have same number of patterns"
	        else ();
	        clauses
	      end
  	  | checkFB _ = ErrorMsg.impossible "CoreLang.checkFB"

	if calculating the length is too expensive here, 
	using the function

	fun len1 [x] = true | len1 _ = false

	will suffice, at the expense of less good error reporting.
Status: same as 623
----------------------------------------------------------------------
630. smallest number literal in patterns (same as 507)
Submitter:      aitken@cs.cornell.edu (William E. Aitken)
Date:		Sat Aug 29 1992
Version:        0.88
System:         Sun 4m/670 MP Sparc, SunOS Release 4.1.2
Severity:       minor
Problem:        the special constant denoting the smallest 
		member of the type int (~1073741824) causes
		compilation failure if it appears in patterns. 
		It is legal in expressions.

Code:           
		 fun foo ~1073741824 = 5 
		       | foo x = 3

Transcript: 
    
% sml
Standard ML of New Jersey, Version 0.88, August 14, 1992
val it = () : unit
- ~1073741824;
val it = ~1073741824 : int
- fun foo ~1073741824 = 5 | foo x = 3;
Error: Compiler bug: Overflow in cps/generic.sml
- ~1073741824;
val it =
uncaught exception Boxity
- ~1073741824;
val it = ~1073741824 : int
1073741824;
std_in:2.1-2.10 Error: integer too large
- ^D
% 

Comments: 	If I've already submitted this bug, sorry.
	
Status: open
----------------------------------------------------------------------
631. PrintVal can't print a value of the Ast type
Submitter:      cregut
Date:		8/29/92
Version:        from .86
System:         sparc mips..
Severity:       
Problem:        PrintVal can't print a value of the Ast type
Code:
(* int.sml *)
structure interface = struct
  local
    open System.Compile System.Env
  in
  fun ast name =
     let val f = open_in name
         val source = makeSource (name,0,f,false,std_out)
         val (ast : System.Ast.dec,_) =
           parse(source,staticPart (!pervasiveEnvRef))
     in ast end
  end
end

Transcript:

- use "int.sml";
structure interface :
  sig
    val ast : string -> System.Ast.dec
  end
[closing int.sml]
val it = () : unit
- interface.ast "int.sml";
val it = SeqDec [MarkDec (Error: Compiler bug: PrintVal.switch: none of the data
cons matched
-

Comments: The AST type is built in parse/ast.sml but another version is
in system.sig and perv.sml so that the user can access it.
It is not a problem of consistency of defs (no changes with 85).
Fix: make sure ast.sml is compiled with newconreps having the
same value that will be default for the user.  That is, 
put "^newconreps !ast.sml ^newconreps" in the "all" file.
Status: fixed in 0.89
----------------------------------------------------------------------
632. minimal or maximal integer literals in patterns cause compiler bug
Submitter:      aitken@cs.cornell.edu (William E. Aitken)
Date:           August 30, 1992
Version:        0.88, also 0.75
System:         SunOS Release 4.1.2, Sun 4m/670 MP Sparc
Severity:       major
Problem:        Integer patterns larger than 2^29-1 or
	        smaller than ~2^29 trigger a compiler bug.
Code:           
		fun foo 0x20000000 = true | foo x = false;

Transcript:     Standard ML of New Jersey, Version 0.88, August 14, 1992
		val it = () : unit
		- fun foo 0x20000000 = 5 ;
		std_in:2.1-2.22 Warning: match not exhaustive
			536870912 => ...
		Error: Compiler bug: Overflow in cps/generic.sml
		- 12;
		val it = 
		uncaught exception Boxity
		- fun foo  ~0x20000000 = 5 ;
		std_in:0.0-0.0 Warning: match not exhaustive
		        ~536870912 => ...
		val foo = fn : int -> int
		- fun foo ~0x20000001 = 5; 
		std_in:2.1-2.23 Warning: match not exhaustive
		        ~536870913 => ...
		Error: Compiler bug: Overflow in cps/generic.sml
		- 

Comments:	This is just a generalization of a bug reported 
		yesterday.
Status: same as 507
----------------------------------------------------------------------
633. space leak
Submitter: John Reppy
Date: 1/9/92
Version: 0.88
Severity: major
Problem: 
The old space leak in capture/escape seems to have reappeared.
I ran my test on versions 0.75-0.88, and here is a summary of
the results:

  version    space leak?
    75		no
    76		no
    77		yes
    78		yes
    79		yes
    80		yes
    81		no
    82		no
    83		no
    84		yes
    85		yes
    86		yes
    87		yes
    88		yes

Note that the two rounds of contract before eta were eliminated in
version 0.84.

As a reminder, the simple example of this problem is the function
select.

Code: 
  local
    open System.Unsafe.PolyCont
  in
    fun select x = capture (fn k => let
          val return = escape k
          in
            return (x ())
          end)
  end;

  which is called in the following loop:

  fun loop () = select loop
Comments: This should be constant space!
Status: fixed (again!) in 0.90
----------------------------------------------------------------------
634. Uncaught expception NotDirectory
Submitter:    Zhong Shao   (zsh@cs.princeton.edu)
Date:         Sept. 4, 1992
Version:      0.88 
System:       mipsb/riscos and mipsl/ultrix
Severity:     major 
Problem:      Uncaught expception NotDirectory
Code:
(**************************************************************************
 * THIS IS THE FILE getwd.sml ---------  Modified from SourceGroup        *
 * version 2.2  tools/sourcegroup/local/System/getwd.sml                  *
 **************************************************************************)

  structure GetWorkingDirectory :sig val getwd :unit -> string end = struct

  fun withInOutStreams (inS :instream, outS :outstream)
      (action :instream * outstream -> 'a -> 'b) (argument:'a) :'b =
    let val result = action (inS, outS) argument
                       handle exn => (close_in inS; close_out outS; raise exn)
     in
      close_out outS; close_in inS;
      result
    end

  val SYS_wait = 84

  fun waitForProcess () =
   (while (((System.Unsafe.CInterface.syscall (SYS_wait, System.Unsafe.cast 0))
      handle System.Unsafe.CInterface.SysError _ => 0) > 0) do ())

  fun firstLine (program:string, args :string list) =
    let fun strip_newline str =
             let val len = size str in
               if len > 0 then substring (str, 0, len - 1)
                          else str end
        fun first_line (inS,outS) () = strip_newline (input_line inS)
        val result =
          withInOutStreams (execute (program, args)) first_line ()
     in
      waitForProcess(); result
    end

  fun getwd () = firstLine ("/bin/pwd", [])

  end

  val _ = 
   (let
      val cwd = GetWorkingDirectory.getwd() 
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd() 
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd() 
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd
      val cwd = GetWorkingDirectory.getwd()
      val _ = System.Directory.cd cwd

    in print "\n \n This is correct! \n \n"
   end) handle _ => 
          (print "\n\n This is wrong, Why exceptions? \n\n")

Transcript:

  - use "getwd.sml";


   This is wrong, Why exceptions?

  structure GetWorkingDirectory :
    sig
      val getwd : unit -> string
    end
  [closing /u/zsh/tcps/work/new/bug/tt.sml]
  val it = () : unit
  -

Comments:  "Uncaught exception NotDirectory" happened RANDOMLY(50%)
           when doing "val cwd = GetWorkingDirectory.getwd();
           System.Directory.cd cwd;" This is why I did ten runs
           of it in the above script. I suspect the getwd.sml
           in SourceGroup is coded in an incompatible way with 
           the version 88's Directory.cd function in perv.sml (or 
           runtime/cfuns.c), since the above bug did not occur in 87. 

           This bug occurs (sometimes,say one out of two times) when 
           making smlsg using version88.

	  ** This is probably another example of bug #651 (JHR, 10/6/92) **
Status: fixed
----------------------------------------------------------------------
635. byteArray.update and ByteArray.sub raise Ord
Submitter: 	Robert Cooper (rcbc@cs.cornell.edu)
Date: 		Sept 10, 1992
Version: 	0.75 (broken in 0.89)
System: 	any
Severity: 	minor
Problem: 	byteArray.update and ByteArray.sub raise Ord
		instead of Subscript
Transcript: 
	Standard ML of New Jersey, Version 0.89, September 4, 1992
	val it = () : unit
	- open ByteArray;
	open ByteArray
	- val a = array(2, 0);
	val a = - : bytearray
	- update (a, 2, 100);

	uncaught exception Ord
	- a sub 2;

	uncaught exception Ord

Comments:	The inline operators are incorrectly defined.
Status: fixed in 0.90
----------------------------------------------------------------------
636. Vector patterns don't work at top level
Submitter: Dave MacQueen
Date: 9/10/92
Version: 0.88
Severity: major
Problem: Vector patterns don't work at top level
Transcript: 
  Standard ML of New Jersey, Version 0.89, September 4, 1992
  val it = () : unit
  - val v = #[1,2,3];
  val v = #[1,2,3] : int vector
  - val #[a,b,c] = v;
  std_in:5.1-5.16 Warning: binding not exhaustive
          #[a,b,c] = ...
  - a;

  uncaught exception IntmapF
  - let val #[a,b,c] = v in a end;
  std_in:0.0-0.0 Warning: binding not exhaustive
          #[a,b,c] = ...
  val it = 1 : int
Status: fixed in 0.90
----------------------------------------------------------------------
637. Compiler bug printing signatures with polymorphic exceptions (same as 613)
Submitter: Gene Rollins
Date: 9/10/92
Version: 0.88?
Severity: minor
Problem: 
The Compiler reports a compiler bug when trying to print signatures that
contain polymorphic exceptions.  This happens with both 0.75 and 0.80 versions
on both sun4 and decstation machines running mach.
Code: 
Transcript: 
- signature SEQUENCE = sig 
   exception no_next of 'a
   end;
signature SEQUENCE = 
  sig
    exception no_next of Error: Compiler bug: domain
Comments:
If we set:
  System.Control.Print.signatures := 0;

the compiler compiles the signature fine, and does not report the compiler
bug.
[DBM:] Polymorphic exception specifications in signatures are (or should
be) illegal, so these should cause some error message.
Status: same as 613
----------------------------------------------------------------------
638. subnormal numbers
Submitter: Appel
Date: 9/15/92
Version: 0.89
System: Sparc
Severity: minor
Problem: The "ln" function does not expect subnormal numbers, and gives wrong
answers.  Other functions may have similar problems.

Code: 
Transcript: 
val x = 1.0E~160;
val x = 1.0E~160 : real
- x * x;
val it = 9.99988867182683E~321 : real
- ln it;
val it = ~4.05753556581235 : real
-
Comments:
Fix:
Status: fixed in 0.90
----------------------------------------------------------------------
639. multiple compiler compilations on sparc fail
Submitter: Pierre Cregut
Date: 9/15/92
Version: 0.89
System: SunOS 4.1, SPARC 2, 64MB
Severity: major
Problem: 
  When multiple compilations of the ML compiler are launched
  on a single sparc 2, some of them fail with "Bus error" or
  "Segmentation fault".
Transcript: 
I have done the experiment but forgot it... so here is the result of
launching 3 smlc (.89) on skye

One is Ok and has finished...
another:
> [closing elaborate/normalize.sml]
> [Compiling modules/moduleutil.sml]
> structure ModuleUtil : ...
> 
> [Major collection... 7% used (1403140/20038536), 1040 msec]
> Bus error
and the last
> signature GENERAL = ...
> [closing boot/perv.sig]
> [Loading boot/system.sig]
> 
> [Increasing heap to 24114k]
> Segmentation fault
who died very quickly !!
Comments:
Why did it asked for such a swap space suddenly: it is completely ridiculous
at that point...
Status: open
----------------------------------------------------------------------
640. flakiness of System.Env (particularly filterEnv)
Submitter: Sanjiva Prasad <sanjiva@ecrc.de>
Date: 9/16/92
Version: 0.88
Severity: major
Problem: 
Perhaps someone in your group has already discovered and fixed these bugs
in v88.  We had pulled over a copy of v88 to experiment with the new
environment features you had advertised (with the intention of trying out
an mini interpreter that does not maintain the application environment, but 
evaluates a syntax tree in a given environment). 

I mucked around a bit, trying to create some small environments by making 
type, structure, functor and value declarations, then using map, 
some list operations like rev and some auxiliary functions, and
(from System.Env) catalogEnv, topLevelEnvRef, staticPart and filterEnv.
Unfortunately, I kept getting Compiler Bug messages when I used filterEnv
(I organized my program carefully enough to isolate the occurrence of these
to the use of filterEnv).

The ugly part of the story is that although repeating the evaluation
resulted in the same bug message or exception being raised, there was
no pattern to it.  For instance, filtering out an environment from the top-level 
environment using a list of seven symbols -- obtained from applying
staticPart and then catalogEnv --  resulted in  a compiler bug message
"compstat" (I think it was that).  With a different list (again obtained
using list operations, catalogEnv, staticPart and topLevelEnvRef), I got
uncaught exception IntmapF,  and then with another list (this time built using
string-to-symbol functions in System.Symbol), I got another compiler bug
(I can't recall which).  In all cases, it is when trying to use filterEnv.
Comment: [dbm] can't reproduce
Status: open  
----------------------------------------------------------------------
641. higher-order functors give Compiler bug: PrintVal.switch: none ...
Submitter: Sanjiva Prasad <sanjiva@ecrc.de>
Date: 9/16/92
Version: 0.88
Severity: major
Problem: 
  Use of higher-order functors results in Compiler bug when a value
  of a datatype is printed.
Transcript: 
- signature SIG1 = sig type t	type u	val x:t	   val y:u end;
signature SIG1 = 
  sig
    type t
    type u
    val x : t
    val y : u
  end
- structure A:SIG1 = struct type t=int	type u=bool	val x=5    val y=true end;
structure A : SIG1
- 
- signature SIG2 = sig 
=                       functor Foo(X:SIG1) : sig val  z : A.t val  w: X.t end 
=                  end;

(* This was to test if the restriction on what names may be used -- relevant 
   for separate compilation -- was enforced in v88 *)

signature SIG2 = 
  sig
    functor Foo : <sig>
  end

- structure B : SIG2 = struct functor Foo(X:SIG1) = struct val z = A.x + 1 val w = X.x 
=                                                          type foo = bool 
=                                                   end
=                      end;
structure B : SIG2

(* This was to test if signature contraints of SIG2 were propagated down to the body
   of the functor. Pleasantly, it is *)

- open B;
open B

- structure C = Foo(A);
structure C : 
  sig
    val z : A.t
    val w : A.t
  end

- structure D :SIG1 = struct type t = bool type u = int val x = false val y = 7 end;
structure D : SIG1

- structure E = Foo(D);
structure E : 
  sig
    val z : A.t
    val w : D.t
  end

- C.w;
val it = 1 : A.t	(* should have been equal to A.x = 5  !!!!! *)

- A.x;
val it = 5 : A.t

- C.z;
val it = 6 : A.t	(* rightly so *)

- E.z;
val it = 6 : A.t	(* again rightly so *)

- E.w;			(* should have been false *)
val it = Error: Compiler bug: PrintVal.switch: none of the datacons matched

Status: fixed in 0.89
----------------------------------------------------------------------
642. Sourcegroup 2.1 dependency analysis fails (see also bug 649)
Submitter:      Amy Felty, felty@research.att.com
Date:		17 Sept 92
Version:        0.90a
System:         sun4 sparc
Severity:       major

Problem:        SG2.1 compiles, but doesn't execute propery. The last
version that I know of where it works properly is 0.87. In a call to
SourceGroup.make, one of the arguments is the name of the top-level
functor (ElpSymtab in this example). It should then be able to
determine all the necessary files to compile and build the structures.
Instead, it replies with:

% structure ElpSymtab undefined

Code:           I have put a tar file in ~felty/lp-sml/SGbug.tar. It
is not very large, but contains files in several subdirectories. (It
is a very small piece of the Lambda Prolog code.)

Transcript:     I'm including a transcript of the execution in 0.90a
with the bug, followed by a transcript of the working version in 0.87.

------------------------
transcript for SML 0.90a
------------------------
% /usr/local/sml/bin/sparc/sml-sg.90a
Standard ML of New Jersey, Version 0.90a September 16, 1992
  with SourceGroup 2.1 built on Wed Sep 16 20:11:34 EDT 1992
val it = () : unit
- use "build.sml";
val it = () : unit
val it = () : unit
val it = () : unit
structure SG : SOURCEGROUP
structure SA : SOURCEACTION
structure FL : FILELIST
val smlFiles = fn : string list -> string list
val mlyaccFiles = fn : string list -> string list
hash/Hash.sig
hash/Hash.sml
hash/link-hash.sml
val hashGroup = 1 : ?.group
sys/hasher.sml
sys/link-sys.sml
sys/location.sml
sys/profile.sml
sys/sys.sig
sys/sys_newjersey.fun
sys/time.sml
val sysGroup = 3 : ?.group
val libraries = [1,3] : ?.group list
[closing group-libraries.sml]
val it = () : unit
lam/basic.fun
lam/basic.sig
lam/term.fun
lam/term.sig
lam/naming.fun
lam/naming.sig
val lamGroup = 5 : ?.group
elp/elp_symtabs.fun
elp/elp_symtabs.sig
elp/link-elp.sml
val elpGroup = 7 : ?.group
val makeElp = fn : unit -> unit
[closing group.sml]
val it = () : unit
val make = fn : unit -> unit
% structure ElpSymtab undefined
val it = () : unit
[closing build.sml]
val it = () : unit
-----------------------
transcript for SML 0.87
-----------------------
% /usr/local/sml/bin/sparc/sml-sg
Standard ML of New Jersey, Version 0.87, July 31, 1992
  with SourceGroup 2.1 built on Mon Aug  3 14:02:28 EDT 1992
val it = () : unit
- use "build.sml";
val it = () : unit
val it = () : unit
val it = () : unit
structure SG : SOURCEGROUP
structure SA : SOURCEACTION
structure FL : FILELIST
val smlFiles = fn : string list -> string list
val mlyaccFiles = fn : string list -> string list
hash/Hash.sig
hash/Hash.sml
hash/link-hash.sml
val hashGroup = 1 : ?.group
sys/hasher.sml
sys/link-sys.sml
sys/location.sml
sys/profile.sml
sys/sys.sig
sys/sys_newjersey.fun
sys/time.sml
val sysGroup = 3 : ?.group
val libraries = [1,3] : ?.group list
[closing group-libraries.sml]
val it = () : unit
lam/basic.fun
lam/basic.sig
lam/term.fun
lam/term.sig
lam/naming.fun
lam/naming.sig
val lamGroup = 5 : ?.group
elp/elp_symtabs.fun
elp/elp_symtabs.sig
elp/link-elp.sml
val elpGroup = 7 : ?.group
val makeElp = fn : unit -> unit
[closing group.sml]
val it = () : unit
val make = fn : unit -> unit
[reading sys/time.sml]
[closing sys/time.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/time.sml.bin]
signature TIME
<other binding>
functor Time
<other binding>
[reading sys/sys.sig]
[closing sys/sys.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/sys.sig.bin]
signature SYS
<other binding>
[reading sys/sys_newjersey.fun]
[closing sys/sys_newjersey.fun]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/sys_newjersey.fun.bin]
functor NewJersey
<other binding>
[reading sys/location.sml]
[closing sys/location.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/location.sml.bin]
signature LOCATION
<other binding>
functor Location
<other binding>
[reading sys/hasher.sml]
[closing sys/hasher.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/hasher.sml.bin]
functor Hasher
<other binding>
signature HASHER
<other binding>
[reading sys/link-sys.sml]
[closing sys/link-sys.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/sys/.@sys/link-sys.sml.bin]
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
[reading lam/term.sig]
[closing lam/term.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/term.sig.bin]
signature TERM
<other binding>
[reading lam/term.fun]
[closing lam/term.fun]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/term.fun.bin]
functor Term
<other binding>
[reading lam/naming.sig]
[closing lam/naming.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/naming.sig.bin]
signature NAMING
<other binding>
[reading lam/basic.sig]
[closing lam/basic.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/basic.sig.bin]
signature BASIC
<other binding>
[reading lam/naming.fun]
[closing lam/naming.fun]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/naming.fun.bin]
functor Naming
<other binding>
[reading lam/basic.fun]
[closing lam/basic.fun]
[writing /shadow/12/people/felty/lp-sml/SGtest/lam/.@sys/basic.fun.bin]
functor Basic
<other binding>
[reading hash/Hash.sig]
[closing hash/Hash.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/Hash.sig.bin]
signature HASH
<other binding>
[reading hash/Hash.sml]
[closing hash/Hash.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/Hash.sml.bin]
functor HashFun
<other binding>
[reading hash/link-hash.sml]
[closing hash/link-hash.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/hash/.@sys/link-hash.sml.bin]
<other binding>
<other binding>
[reading elp/elp_symtabs.sig]
[closing elp/elp_symtabs.sig]
[writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/elp_symtabs.sig.bin]
signature ELPSYMTAB
<other binding>
[reading elp/elp_symtabs.fun]
[closing elp/elp_symtabs.fun]
[writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/elp_symtabs.fun.bin]
functor ElpSymtab
<other binding>
[reading elp/link-elp.sml]
[closing elp/link-elp.sml]
[writing /shadow/12/people/felty/lp-sml/SGtest/elp/.@sys/link-elp.sml.bin]
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
<other binding>
val it = () : unit
[closing build.sml]
val it = () : unit

Comments:	Lal and John suggest that a regression test be made
		for source groups.
Status: fixed in 0.91 (Shao)
----------------------------------------------------------------------
643. building smld produces Compiler bug: DebugError: ...
Submitter:	John Reppy (jhr@research.att.com)
Date: 		September 17, 1992
Version: 	0.89
System: 	n.a.
Severity: 	major
Problem: 	attempting to build smld produces an error
Code: 
  makeml -debug -sun4 sunos
Transcript: 
  makeml> (cd runtime; make clean)
  rm -f *.o lint.out prim.s linkdata allmo.s run
  makeml> rm -f mo
  makeml> ln -s ../mo.sparc mo
  ...
  [closing dbguser/hstore.sml]
  val it = () : unit
  val it = () : unit
  [debugging support included]
  structure DebugList : LIST
  [closing dbguser/list.sml]
  val it = () : unit
  Error: Compiler bug: DebugError:Static.locOfEvent bad APPev marking

  [closing dbguser/general.sml]
  [closing dbguser/load.sml]

Comments:
  This works in version 0.88.

Comments: [APT]
  I looked in and looked at this briefly.  I suspect some complication
  due to the introduction of type options in the absyn.
  The correct way to diagnose this sort of problem is:

  1) use makeml -debug0 to build a debugger version that doesn't attempt
  to execute dbguser/load.sml.

  2) execute dbguser/load.sml up to the file that causes problems.

  3) Set System.Control.debugging := true.  Under the debugger, this will
  cause the absyn of the pre- and post-instrumented versions of the code to
  be printed.  

  4) Try using "dbguser/general.sml" (in this case) and look where the MARKexps
  come in the absyn.  Compare this to what the code in debug/static.sml
  (where the exception was raised) is expecting.

  If you don't get anywhere with this, please leave the result of step 1
  around in 89/bin/mipsb (I usually call it smld0) and let me know; I'll try
  diagnosing from here.  Unfortunately, my machine is not up yet here, and
  telneting cross country is painfully slow...  I should have a proper environment
  for looking at this sort of bug by early next week.

Status: open
----------------------------------------------------------------------
644. checking for stale continuations
Submitter: MacQueen
Date: 9/17/92
Version: 0.89
Severity: major
Problem: 
  Checking for stale continuation returns at top level has been disabled
  (possibly by one of Tolmach's changes to interact).
Comments: See bug 145.
Status: open
----------------------------------------------------------------------
645. Compiler bug from bugs 183,228,343 code: CoreInfo.coreLty3
Submitter: Lal George
Date: 9/18/92
Version: 0.90
System: Sparc, SunOS
Severity: major
Problem: 
  Code for bugs 183, 228, 343 now causes "Error: Compiler bug: CoreInfo.coreLty3".
Code: /usr/local/sml/testing/bugs/tests/bug183.sml, etc.
Status: fixed in 0.91 (Shao)
----------------------------------------------------------------------
646. module test tile mod14.sml fails with Compiler bug: ModuleUtil: getFctStamp
Submitter: Lal George (regression testing)
Date: 9/18/92
Version: 0.90a (& 0.89)
Severity: major
Problem: 
  Module test case mod14.sml in /usr/local/sml/testing/hof/tests/mod14.sml
  fails with "Compiler bug: ModuleUtil: getFctStamp".
Status: fixed in 0.90
----------------------------------------------------------------------
647. PWR_2_CALLEESAVE not defined in some cases
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           9/22/92
Version:        0.89
System:         HP9000s400 HPUX8.0
Severity:       minor
Problem:        PWR_2_CALLEESAVE not defined in some cases, which shows
                up when assembling prim.s.
Code:           PWR_2_CALLEESAVE will not be defined when CALLEESAVE
                is already defined. This happens when HPUX (and M68) is 
                defined, because makeml has a special case for this and ends
                up calling cpp with -DCALLEESAVE=...
Transcript:     
Comments:
Fix:            If CALLEESAVE, HPUX, and M68 is defined then PWR_2_CALLEESAVE
                should be set to 1 because CALLEESAVE has the default value 0.
                I don't know if there are other cases (e.g. if -callee 
                is used with makeml).
Status: open
----------------------------------------------------------------------
648. Compiler core dumps in the boot process for HP9000s400 HPUX8.0
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           9/22/92
Version:        0.89
System:         HP9000s400 HPUX8.0
Severity:       critical
Problem:        Compiler core dumps in the boot process
Code:           
Transcript:     Both 'makeml -m68 hpux8 -noshare' and 'makeml -m68 hpux8'
                results in a core dump ("Illegal instruction" or 
                "Memory fault").

neptune 65: makeml -m68 hpux8 -noshare
makeml> (cd runtime; make clean)
	rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.m68 mo
makeml> (cd runtime; rm -f run allmo.o allmo.s)
makeml> (cd runtime; ...)
makeml>   /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s
makeml>   emacs -batch -l sun2hp.el prim.s prim.s
Wrote /d1/release/tools/njsml/work89/src/runtime/prim.s
makeml>   as -o prim.o prim.s
makeml> (cd runtime; make  MACHINE=M68 'DEFS= -DHPUX' CPP=/lib/cpp 'CFL=-Wl,-a,archive' 'AS=as' 'LIBS=')
	cc -O -Wl,-a,archive -DM68 -DHPUX -c run.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c run_ml.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c callgc.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c gc.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c export.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c timers.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c ml_objects.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c cfuns.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c cstruct.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c signal.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c exncode.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c malloc.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c mp.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c sync.c
	cc -O -Wl,-a,archive -DM68 -DHPUX -c allmo.c
"allmo.c", line 15: warning: incorrect combination of pointer and integer for operator '='
	cc -O -Wl,-a,archive -DM68 -DHPUX -o run run.o run_ml.o callgc.o gc.o export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o  mp.o sync.o prim.o allmo.o 
makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 -h 2048 IntM68

[Increasing heap to 2048k]
[Loading mo/CoreFunc.mo]
[Executing mo/CoreFunc.mo]
[Loading mo/Initial.mo]
...
[Loading ArrayExt]
[Executing ArrayExt]
[Executing TypesUtil]
[Loading Sort]
makeml: 988 Illegal instruction - core dumped
neptune 66: 

Comments: The compiler boots fine on a Sun3, so it doesn't have to be
          an MC680x0 related problem.
Comments: [Kjeld]
I have an additional comment: if -g is turned on in runtime/Makefile
(i.e. all the runtime sources are compiled with -g and without -O),
SML/NJ will boot. BUT, the compiler is flaky. It dumps a core if
large integers are evaluated, and it yields compiler bug messages
now and then in code that was compiled successfully on previous
versions.

Let me know if I can be of any help.  I'm not sure what the right
way is for debugging this.

**** From Kjeld H. Mortensen, 11/22/92, version 0.92:
I have tried to build the compiler on our HP9000s400. In order to get to
the boot point I had to make the following modifications:

-------------------------
diff cfuns.c.orig cfuns.c     (because the gethostid call isn't known)
-------------------------
30a31,33
> #ifdef HPUX
> #include <sys/utsname.h>
> #endif
1432a1436,1446
> #ifdef HPUX
>     char        buf[SNLEN+1];
>     ML_val_t    name;
>     struct utsname utsname;
>
>     uname(&utsname);
>     bcopy ((char *)(utsname.idnumber), buf, SNLEN);
>     buf[SNLEN] = '\0';  /* insure null termination */
>     name = ML_alloc_string (msp, buf);
>     RETURN(msp, name);
> #else /* !HPUX */
1442c1456
<
---
> #endif /* HPUX */

-----------------------------
diff sun2hp.el.orig sun2hp.el   (see also 564 in the masterbugs list)
-----------------------------
97,98c98
<       (goto-char point)
<       (beginning-of-line)
---
>       (goto-char (- point 2))
137a138
>   (replace-re "\\.word" "short")

The last change (converting .word to short) is new, and is thus not
mentioned
in 564.

These changes allowed me to get to the boot point (i.e. all C-sources could
be compiled). But then the compiler dumped a core. So, I have the following
bug report:

===========================================
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           11/22/92
Version:        0.92
System:         HP9000s400 (M68k), HPUX 8.0
Severity:       Major
Problem:        Compiler fails to boot.
Code:           
Transcript:     
neptune 180: makeml -m68 hpux8 -noshare
makeml> (cd runtime; make clean)
        rm -f *.o lint.out prim.s linkdata allmo.s run
makeml> rm -f mo
makeml> ln -s ../mo.m68 mo
makeml> (cd runtime; rm -f run allmo.o allmo.s)
makeml> (cd runtime; ...)
makeml>   /lib/cpp -DCALLEESAVE=0 -DM68 -DHPUX -DASM M68.prim.s > prim.s
makeml>   emacs -batch -l sun2hp.el prim.s prim.s
Wrote /d1/release/tools/njsml/work92/src/runtime/prim.s
makeml>   as -o prim.o prim.s
makeml> (cd runtime; make  MACHINE=M68 'DEFS= -DHPUX' CPP=/lib/cpp 
'CFL=-Wl,-a,archive' 'LDFLAGS=' 'AS=as' 'LIBS=')
        cc -O -Wl,-a,archive -DM68 -DHPUX -c run.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c run_ml.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c callgc.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c gc.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c export.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c timers.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c ml_objects.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c cfuns.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c cstruct.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c signal.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c exncode.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c malloc.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c mp.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c sync.c
        cc -O -Wl,-a,archive -DM68 -DHPUX -c allmo.c
        cc -O -Wl,-a,archive -DM68 -DHPUX  -o run run.o run_ml.o callgc.o
gc.o
export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o
malloc.o 
mp.o sync.o prim.o allmo.o
makeml> echo ( exportML "sml"; output(std_out,System.version);
output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 
-h 2048 IntM68

[Increasing heap to 2048k]
[Loading mo/CoreFunc.mo]
[Executing mo/CoreFunc.mo]
[Loading mo/Initial.mo]
[Executing mo/Initial.mo]
Initial done
[Loading mo/Loader.mo]
[Executing mo/Loader.mo]
makeml: 3591 Memory fault - core dumped

Comments:
  - I have been succesful building the compiler without '-noshare', 
    but sometimes it gives a bus error when it gets to "Go for it". 

  - The version that was successfully build with 'makeml -m68 hpux8' dumps 
    a core when evaluating an integer that is too large:
        neptune 205: sml
        Standard ML of New Jersey, Version 0.92, November 18, 1992
        val it = () : unit
        - 536870911;  (* 2^29 - 1 *)
        val it = 536870911 : int
        - 536870912;  (* 2^29 *)
        Illegal instruction (core dumped)

  - This is probably the same problem as in 648 (masterbugs).

  - The system builds fine on our Sun3 (also M68k) and doesn't core dump on
    large integers.


Status: open
----------------------------------------------------------------------
649. too strong optimization of datatype constructor (same as 642)
Submitter: Pierre Cregut
Date: 9/22/92
Version: 0.89
Severity: critical
Problem: 
  Printing simple datatype value causes "Compiler bug: constant datacon in
  decon".
Code: 
  datatype dt = a of int | b of unit; (* a is necessary *)
  b ();
Transcript: 
  datatype  dt
  con a : int -> dt
  con b : unit -> dt
  val it = b Error: Compiler bug: constant datacon in decon

  Another version is that a piece of code is not executed
  if it is an argument of such a constructor.
  ----------------------------------------------------
  - (b (print "aa\n") ; ());
  val it = () : unit
Comment:
  That is what happened in sourcegroup.
  To make connections, sourcegroup parse the file
  The toplevel rule is of type unit so a constructor
  " interdec of unit " is associated (interdec is the
  name of the rule). 
  Because of the too strong optimization, the body
  of the rule that updates the tables by side
  effect is never executed, so source group never hears
  about the structures contained in the files it looks at.
Status: fixed in 0.91 (Shao)
----------------------------------------------------------------------
650. Real.realfloor has wrong type
Submitter: John Reppy
Date: 9/27/92
Version: 0.90
Severity: minor
Problem: 
  Isn't realfloor supposed to have type real -> real?
Transcript: 
  Standard ML of New Jersey, Version 0.90 September 22, 1992
  val it = () : unit
  - Real.realfloor;
  val it = fn : 'a -> 'b
Fix: obvious
Status: fixed in 0.91 
----------------------------------------------------------------------
651. System.Directory.cd fails on numbers as directory names
Submitter: Konrad Slind
Date: 9/28/92
Version: 0.90
System: MIPS/RISCos 4.52
Severity: major
Problem: 
  System.Directory.cd doesn't seem to recognize numbers as possible directory
  names:
Transcript: 
  $ mkdir 7
  $ sml
  Standard ML of New Jersey, Version 0.90 September 22, 1992
  val it = () : unit
  - System.Directory.cd "7";

  uncaught exception NotDirectory
  -
Status: fixed in 0.91
----------------------------------------------------------------------
652. Compiler bug: contmap enterv 123 building HOL
Submitter:      elsa  elsa@research.att.com
Date:		28 September 
Version:        90, 91a
System:         MIPS & SPARC, UNIX
Severity:       critical
Problem:        compiler quits with Compiler bug: contmap enterv 123
Comment: [Elsa Gunter, 9/29/92]
  I spent some time last night removing the HOL code from the example.
Below is a mimimal example that causes the problem.  Along my descent
I found that the process of elimination was VERY NON-monotonic.  At
some time during the elimination process I had 
     if true then 2 else 2
which could note be replaced by 2 without the bug going away.
However, after removing some other aspects, the if_then_else was no
longer necessary.  At some point, the length of the string in the
exception being handled made a difference, but now it only matters
that there is a string.  There were other fluxuations as well.  I'm
afraid I left them on my machine at home, but if you need them, I can
try to bring them in tomorrow.
  This is very possibly not the only minimal code that causes this
bug.  I found that exceptions A and B must be different, that the one
being handled needed to take a record with at least one field having
string type and that that field had have a match against a string,
i.e., not a wild-card.
Code:
(* File: bug-652.sml *)

exception A

exception B of int*string

val _ = (raise A) handle B (_,"") => 2

(* end of file *)
Transcript:

shadow% sml
Standard ML of New Jersey, Version 0.90 September 22, 1992
val it = () : unit
- use "bug-652.sml";
Error: Compiler bug: contmap enterv 123
[closing bug-652.sml]
- exception A;
exception A
- exception B of int*string;
exception B
- val _ = (raise A) handle B (_,"") => 2;
Error: Compiler bug: CoreInfo.coreLty3

Another variation of the bug, still present in 91b:
Code:
(* File: bug.sml *)`

structure C =
struct
exception A
exception B of int * string
val C = (raise A) handle B (_,"") => 2
end

Transcript:
hunny% sml
Standard ML of New Jersey, Version 0.91a, October 1, 1992
val it = () : unit
- use "bug.sml";
Error: Compiler bug: contmap enterv 123
[closing bug.sml]
-

Another variation: (from Sheard at ogi)
- exception foo;
- fun bar x = raise foo;
Error: Compiler bug: CoreInfo.coreLty3

Comments:
  This is a variation on bug 652.  If you unwrap the code from within
the structure then things work.  However it still bombs if the code is
all inside a structure.

Comments:
  Konrad says that the problem was in 88 as well.

Comments: [Zhong Shao, 10/6/92]
   The compiler bug: contmap enterv 123 has been there for a long long time.
   Though previously, it occurs as a compiler bug: MipsCM.select: bad dst.
   These  are caused by meaningless cps expressions such as
                 SELECT(INT 0,1,v,...) , APP(INT 0, ...)
   which are produced by the constant folding optimization on data constructors
   and exception constructors. A short but temporary fix is to let contmap.sml
   not check the validity of these expressions and let each target code 
   generator generate some code for SELECT(INT 0,1,v,...). Ideally this should
   be fixed by letting the SELECT in Lambda and CPS depend on the auxiliary 
   variable generated in each branch and switch statement, and controlling 
   the constant-folding on SELECT. 

Status: open
----------------------------------------------------------------------
653. VECTOR signature isn't pervasive (unlike ARRAY)
Submitter:	Cliff Krumvieda (cliff@cs.cornell.edu)
Date: 		September 30, 1992
Version: 	0.90
System: 	all
Severity: 	minor
Problem: 	VECTOR signature isn't pervasive (unlike ARRAY)
Code: 
Transcript: 
  Standard ML of New Jersey, Version 0.90 September 22, 1992
  val it = () : unit
  - signature A = ARRAY;
  signature A = 
    sig
      type 'a array
      exception Size
      exception Subscript
      val array : int * '1a -> '1a array
      val arrayoflist : '1a list -> '1a array
      val length : 'a array -> int
      val sub : 'a array * int -> 'a
      val tabulate : int * (int -> '1a) -> '1a array
      val update : 'a array * int * 'a -> unit
    end
  - signature V = VECTOR;
  std_in:3.15-3.20 Error: VECTOR undefined (parser)
  std_in:3.15-3.20 Error: unbound signature: VECTOR
Comments:
Fix:		add VECTOR to boot environment
Status: fixed in 0.91
----------------------------------------------------------------------
654. System.Directory.cd fails on valid pathnames (same as 651)
Submitter:      Elsa L. Gunter, elsa@resaerch.att.com
Date:		1 October 1992
Version:        90 (although I haven't tried earlier)
System:         Sparc, SunOS (although I haven't tried others)
Severity:       major
Problem:        strings from execute don't mix with System.Directory.cd
                (or not all strings are ccreated equal)

Code: The following can cause problems when loaded with use, but more
      reliably causes problems when entered interactively, or so I've
      found.

fun strip_newline (str) = substring (str, 0, size(str) - 1);

fun cwd () =
    strip_newline (input_line ((fn (x,_) => x) (execute ("/bin/pwd",[]))));

val src_dir = cwd ();
val tmp = "/base/elsa/working/hol92/hol90.v5/src";
val t = (tmp = src_dir);
val _ = System.Directory.cd src_dir;
val _ = System.Directory.cd tmp;
val _ = System.Directory.cd (src_dir ^ "/..");
val _ = System.Directory.cd src_dir;

Transcript:

tiree% sml
Standard ML of New Jersey, Version 0.90 September 22, 1992
val it = () : unit
- fun strip_newline (str) = substring (str, 0, size(str) - 1);
val strip_newline = fn : string -> string
- fun cwd () =
    strip_newline (input_line ((fn (x,_) => x) (execute ("/bin/pwd",[]))));
= val cwd = fn : unit -> string
- val src_dir = cwd ();
val src_dir = "/base/elsa/working/hol92/hol90.v5/src" : string
- val tmp = "/base/elsa/working/hol92/hol90.v5/src";
val tmp = "/base/elsa/working/hol92/hol90.v5/src" : string
- val t = (tmp = src_dir);
val t = true : bool
- val _ = System.Directory.cd src_dir;

uncaught exception NotDirectory
- val _ = System.Directory.cd tmp;
- val _ = System.Directory.cd (src_dir ^ "/..");
- val _ = System.Directory.cd src_dir;

uncaught exception NotDirectory
- 

Comments:
-- The problem is intermittent; the same code seems to behave
differently on the same machine under similar circumstances.
-- Strings that are entered by hand, or are built by sml processes,
such as concatenation seem not to cause the problem.  Only strings
created by execute (and input_line) seem to cause it.
-- I haven't been able to reproduce it just now, but it I recollect
that multiple executions of the same coomand (namely
System.Directory.cd src_dir; without src_dir being rebound in between)
could succeed for a while and then fail.

Fix: add "\000" to pathnames
Status: fixed in 0.91
----------------------------------------------------------------------
655. Compiling Isabelle-92 generates a bus error
Submitter:      Lal George
Date:		4 Oct. '92
Version:        0.88, 0.91a (0.89, 0.90 expose the CoreLty3 bug)
System:         SPARC and MIPSEB
Severity:       critical
Problem:        Generates a bus error(coredump) during compilation.
Code:           
	
	I haven't tried to narrow the code down yet, however, at 
	Bell Labs the following is sufficient to expose the bug:

		cd /usr/local/sml/isabelle-92/92/Pure

	Under SML:

		app use ["NJ.ML","ROOT.ML"];

Transcript:

	<... lots of stuff deleted ...>

	structure Earley : PARSER
	structure TypeExt : TYPE_EXT
	structure SExtension : SEXTENSION
	structure Pretty : PRETTY
	structure Printer : PRINTER
	Bus error(coredump)

Code: [dbm, 10/10/92: following causes bus error in 91a]
  structure A = struct end;

  signature S =
  sig
    local open A in  (* this must be present *)
      val x : unit  (* must have second value beside f, either before or after *)
      val f: unit -> unit
    end
  end;

  structure B : S =  (* must be constrained by S *)
  struct
    val x = ()
    fun f() = ()
  end;

  val _ = B.f();  (* causes Bus error *)

Comment: [dbm] It's clear that the bug is called by the local spec form.

Status: open
----------------------------------------------------------------------
656. Excessive dead code
Submitter:      Lal George
Date:		5th October, 92
Version:        0.90
System:         SPARC
Severity:       major
Problem:        Lot of dead code left around.
Code:           

      structure X = struct

	(* fold function "f" over the sublists of "(x::xs)" of size "n", starting
	   with value "r", and appending "p" to each sublist *)

	fun folds_onto([],_,r,p,f) = r
	  | folds_onto(x::xs,1,r,p,f) = folds_onto(xs,1,f(r,x::p),p,f) 
	  | folds_onto(x::xs,n,r,p,f) = folds_onto(xs,n,
						   folds_onto(xs,n-1,r,x::p,f),
						   p,f)

	val l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
	val n = 10

	fun doit() = folds_onto(l,n,0,[],fn (total,l) => total+length(l))
     end

Transcript:

	Toggling the Control.saveLvarNames, and CG.printit flags, a 
	partial output  from cpsopt is shown below: 
	(arrows point to dead code)

	...
         folds_onto12224(12238,n12239,r12240,p12241,f12242,12124) =
            if boxed(12238) [12135] then
               12238.0 -> x12136
               12238.1 -> xs12137
               if ineq((I)1,n12239) [12169] then
                  12150(12226) =
-->                  {xs12137,n12239,12226,p12241,f12242} -> 12152
                     folds_onto12224(xs12137,n12239,12226,p12241,f12242,12124)
                  -(n12239,(I)1) -> 12153
                  {x12136,p12241} -> 12154
-->               {xs12137,12153,r12240,12154,f12242} -> 12155
                  folds_onto12224(xs12137,12153,r12240,12154,f12242,12150)
               else
                  12164(12228) =
-->                  {xs12137,(I)1,12228,p12241,f12242} -> 12166
                     folds_onto12224(xs12137,(I)1,12228,p12241,f12242,12124)
                  {x12136,p12241} -> 12167
                  {r12240,12167} -> 12168
                  f12242(12168,12164)
            else
               12124(r12240)
         {(I)20,(I)0} -> 12174
         {(I)19,12174} -> 12175
         {(I)18,12175} -> 12176
	...

Comment:
	I know that several rounds of contract are done on this
	fragment, and the dead code exists after each round. For 
	some mysterious reason, code in cps/contract, that should 
	remove this, does not seem to work.

  Andrew Says:
    This is because System.Control.CG.reducemore is 15, which causes
    cpsopt to give up early when it sees diminishing returns.
    For documentation that this is a good idea, see Compiling with Continuations,
     figure 15.11, page 192.

Status: not a bug.
----------------------------------------------------------------------
657. vector values not prettyprinted
Date:		Oct 12, 1992
Version: 	0.91c
System: 	all
Severity: 	minor
Problem: 	new pretty printing code doesn't handle vectors
Code: 
Transcript: 

  Standard ML of New Jersey, Version 0.90 September 22, 1992
  val it = () : unit
  - #[1,2,3];
  val it = #[1,2,3] : int vector

  Standard ML of New Jersey, Version 0.91c, October 12, 1992
  val it = () : unit
  - #[1,2,3];
  val it = prim? : int vector
Status: fixed in 0.92
----------------------------------------------------------------------
658. Compiler bug: PrintVal.switch: none of the datacons matched
Submitter: John Reppy
Date: 10/13/92
Version: 0.91c
System: SPARC 2, SunOS 4.0.1
Severity: critical
Problem: 
  Compiler bug: PrintVal.switch: none of the datacons matched
  caused by Format.compileFormat
Transcript: 
  - Format.compileFormat "x = %d";
  Error: Compiler bug: PrintVal.switch: none of the datacons matched
Status: fixed in 0.91
----------------------------------------------------------------------
659. uncaught exception SpillFreemap in closure profiling
Submitter:      Zhong Shao 
Date:           October 12, 1992
Version:        from 0.86 - 0.90
System:         mips 
Severity:       minor
Problem:        uncaught exception SpillFreemap in closure profiling
Code:           
(* bug.sml *)
  structure S =
    struct
      val a = fn x => x
      val b = fn x => x
      val c = fn x => x
      val d = fn x => x
      val e = fn x => x
      val f = fn x => x
      val g = fn x => x
      val h = fn x => x
      val i = fn x => x
      val j = fn x => x
    end

Transcript:     
  haven% sml
  Standard ML of New Jersey, Version 0.90 September 22, 1992
  val it = () : unit
  - System.Control.CG.allocprof := true;
  val it = () : unit
  - use "bug.sml";
  [closing src/bug.sml]

  uncaught exception SpillFreemap
  -

Comments:
  in cps/spill.sml, the instrumenting code for profiling spill records
  are inserted at the wrong place. 
Status: fixed in 0.91
----------------------------------------------------------------------
660. signals in background sml
Submitter: 	Doug McIlroy (doug@research.att.com)
Date: 		October 22, 1992
Version: 	0.90
System: 	all
Severity: 	major for non-interactive programs

Problem: 	the inherited signal handler state of the SML process
		is getting trashed.  This means that an SML program
		running in the background still receives signals, even
		though the shell has disabled them.

Fix:		The fix will take a bit of work, since the responsibility
		for signal handling is spread throughout the system.
		We will have to make the signal handler state (enabled,
		default, ignored) more visible at the System.Signals
		level, and the top-level loop and other initialization
		code will have to check for ignored signals when setting
		the default handlers.  (JHR)
Status: open
----------------------------------------------------------------------
661. prettyprinter -- Compiler bug: PPTable.install_pp
Submitter:      Lal George
Date:		28 October 1992
Version:        0.91
System:         all
Severity:       minor
Problem:        install_pp incorrectly raises a compiler bug message
Code:           
	val _ = System.PrettyPrint.install_pp ["foo","bar"] Array.update
	
Transcript:

	 Error: unbound structure foo in path foo.bar
	Error: Compiler bug: PPTable.install_pp
Comments:

	The first error message is also printed with an additional 
	blank space. 
Fix:
	In file print/pptable and function install_pp, replace:
	     | _ => ErrorMsg.impossible "PPTable.install_pp"
	with
	     | _ => ErrorMsg.complain "install_pp: Malformed path"
	May as well do the same thing with fun make_path.
	[dbm] Used ErrorMsg.errorNoFile for this and make_path --
	no more calls of ErrorMsg.impossible in pptable.sml.
Status: fixed in 0.92 (dbm)
----------------------------------------------------------------------
662. delayed interrupt on MIPS
Submitter: Dave MacQueen
Date: 10/28/92
Version: 0.91
System: MIPS/RISCOS 4.52
Severity: minor
Problem: 
  Typing the interrupt character (e.g. ^C) doesn't interrupt sml until
  after a newline is typed.
Comments:
  This could be fixed, but the piping into sml would hang under csh.
  This is really a RISCos bug.
Status: not our bug
----------------------------------------------------------------------
663. gc loop on illegal character
Submitter: Lal George
Date: 10/28/92
Version: 0.91
System: SPARC, MIPS
Severity: major
Problem: 
  Typing an illegal character (e.g. ^H) at top level causes an
  infinite gc loop after the illegal character message.
Fix: [Lal George]
  The fix is to generate ml.lex.sml with a version of lexgen.sml 
  that has the latest bug fixes. The one on /usr/local/sml/bin/sparc
  does fine.
Status: fixed in 0.92a
----------------------------------------------------------------------
664. installing on Sony RISC NEWS
Submitter:      KONO Shinji <kono@csl.sony.co.jp>
Date:		Wed Nov  4 17:34:01 JST 1992
Version:        0.75
System:         Sony RISC NEWS, NEWS-OS Release 4.1R
Severity:       minor
Problem:        Installation 
Code:           makeml -mips news
Transcript:     EXC_OV and cache clear system call are machine dependent
Comments:       I'm afraid this type of mahcine is not famous in U.S. But
		I'm sure it is used in Japan...
Fix:		Diffs are appended..
--------
Shinji Kono          kono@csl.sony.jp
Sony Computer Science Laboratory, Inc.


diff -c ./makeml /site/unicorn/export/src/Language/sml-0.75/src/makeml
*** ./makeml	Wed Nov  4 15:35:55 1992
--- /site/unicorn/export/src/Language/sml-0.75/src/makeml	Tue Sep  8 09:55:11 1992
***************
*** 129,135 ****
  	    ENDIAN=Big
  	    case $1 in
  		riscos) OPSYS=RISCos; CFL="$CFL -systype bsd43" ;;
- 		news)   OPSYS=BSD;;
  		mach)   OPSYS=MACH; DEFS="$DEFS -DBSD" ;;
  		*)
  		    echo "$CMD must specify opsys arg for MIPS (riscos or mach)"
--- 129,134 ----
*** runtime/MIPS.dep.c	Wed Nov  4 16:28:06 1992
--- /site/unicorn/export/src/Language/sml-0.75/src/runtime/MIPS.dep.c	Tue Sep  8 09:54:00 1992
***************
*** 5,18 ****
   * MIPS dependent code for SML/NJ runtime kernel.
   */
  
- #ifdef sony_news
- #include <machine/cpu.h>  /* for EXC_OV */
- #else
  #ifndef SGI
  #include <mips/cpu.h>  /* for EXC_OV */
  #else
  #include <sys/sbd.h>  /* for EXC_OV */
- #endif
  #endif
  #ifndef SGI
  #include <syscall.h>
--- 5,14 ----
diff -c runtime/exncode.c /site/unicorn/export/src/Language/sml-0.75/src/runtime/exncode.c
*** runtime/exncode.c	Wed Nov  4 16:27:33 1992
--- /site/unicorn/export/src/Language/sml-0.75/src/runtime/exncode.c	Tue Sep  8 09:54:03 1992
***************
*** 6,19 ****
   */
  
  #ifdef MIPS
- #ifdef sony_news
- #include <machine/cpu.h>   /* for EXC_OV */
- #else
  #ifndef SGI
  #include <mips/cpu.h>   /* for EXC_OV */
  #else
  #include <sys/sbd.h>   /* for EXC_OV */
- #endif
  #endif
  #endif
  #include <signal.h>
--- 6,15 ----
diff -c runtime/ml_os.h /site/unicorn/export/src/Language/sml-0.75/src/runtime/ml_os.h
*** runtime/ml_os.h	Wed Nov  4 16:47:12 1992
--- /site/unicorn/export/src/Language/sml-0.75/src/runtime/ml_os.h	Tue Sep  8 09:54:05 1992
***************
*** 94,106 ****
  /* cache-flushing stuff */
  
  #if defined(MIPS)
- #ifdef sony_news
- #include <machine/sysnews.h>
- #    define FlushICache(addr, size)	  \
-         sysnews(NEWS_CACHEFLUSH, addr, size, FLUSH_ICACHE)
- /* SYS_sysnews will be defined in syscall.h, in OS 4.1 */
- #undef SYS_sysnews
- #else
  #ifndef MACH
  #include <sys/sysmips.h>
  #endif
--- 94,99 ----
***************
*** 117,122 ****
--- 110,116 ----
  #    define FlushICache(addr, size)	  \
          (syscall(SYS_sysmips, MIPS_CACHEFLUSH, (addr), (size), ICACHE, 0))
  #  endif
+ #else
  #ifdef NeXT
  #  define FlushICache(addr, size)     asm ("trap #2")
  #else
***************
*** 123,129 ****
  #  define FlushICache(addr, size)
  #endif
  #endif
- #endif
  
  #if defined(MACH) && defined(MIPS)
  
--- 117,122 ----
***************
*** 139,145 ****
  #endif
  
  /* where to find syscall.h, used for getting the #define SYS_open */
! #if defined(VAX) || defined(NeXT) || defined(MORE) || defined(sony_news)
  #include <syscall.h>
  #else
  #ifndef SGI
--- 132,138 ----
  #endif
  
  /* where to find syscall.h, used for getting the #define SYS_open */
! #if defined(VAX) || defined(NeXT) || defined(MORE)
  #include <syscall.h>
  #else
  #ifndef SGI
Status: open
----------------------------------------------------------------------
665. Compiler bug: getSymbols on opening nonexistent structures.
Submitter: Pierre Cregut
Date: 11/5/92
Version: 0.91, 0.92a
Severity: minor
Problem: Compiler bug: getSymbols on opening nonexistent structures.
Transcript: 
Standard ML of New Jersey, Version 0.92a, November 2, 1992
val it = () : unit
- open A;
std_in:2.1-2.6 Error: unbound structure A
Error: Compiler bug: getSymbols
Fix: add ERROR_STR case to getSymbols function in elabstr.sml.
Status: fixed in 0.92 (dbm)
----------------------------------------------------------------------
666. top-level printout on open declarations
Submitter: John Reppy
Date: 11/6/92
Version: 0.91
Severity: minor
Problem: 
  When opening a structure, the bound datatypes don't get printed.
Transcript: 
  - structure Foo = struct datatype t = A | B val x = A end;
  structure Foo :
    sig
      datatype t
	con A : t
	con B : t
      val x : t
    end
  - open Foo;
  open Foo
  val x = A : t
  -
Comments:
  In fact, only dynamic components are printed, since only they are
  rebound in the top-level environment (to simplify stale-lvars cleanup).
Fix:
  Change printing of open declarations?
Status: open
----------------------------------------------------------------------
667. Compiler bug: getvars(STRdec)/fn opening a structure
Submitter:      Thomas Yan, tyan@cs.cornell.edu
Date:           11/10/92
Version:        0.91
Severity:       minor, but potentially very annoying
Problem:        ? pretty printing a structure created by functor application ?
Code:           functor A(type aa) = struct type a = aa list val a =[] end
                structure A = A(type aa = int)
                open A
Transcript:     Error: Compiler bug: getvars(STRdec)/fn
Fix: ignore special name "<Argument>" in elabDecl/makeDecl.
Status: fixed in 0.92 (dbm)
-----------------------------------------------------------------------
668. missing info in syntax error messages
Submitter: Lal George
Date: 11/13/92
Version: 0.92c
Severity: major
Problem: 
  Some information has been lost from syntax error messages.
Transcript: (bug103.sml)
  {999}

  -----------------------diff new old ----------------------
  diff tsml.tmp /usr/local/sml/testing/bugs/outputs/bug103.out
  2,3c2
  < std_in:8.5 Error: syntax error
  < 
  ---
  > std_in:8.5 Error: syntax error found at RBRACE
Comments:
  The "found at" part of the message is missing from the new mlyacc/base.sml
  supplied by Tarditi.
Fix:
  This was a non-error-correcting version of base.sml that was inadvertently
  left in the mlyacc directory sent by Tarditi.  The fix was to build and 
  install the error-correcting version of base.sml.
Status: fixed in 0.92c
----------------------------------------------------------------------
669. redundant rule added in some matches
Submitter: Dave MacQueen
Date: 11/16/92
Version: 0.92c
Severity: major
Problem: 
  A rule is added to raise the match exception (and save a location
  message) in cases where it is redundant.

Code: 
Transcript: 
  - fun f(s,w) = f s w;
  std_in:0.0-0.0 Error: pattern and expression in val rec dec don't agree (circularity)
    pattern:    'Z -> 'Y -> 'X
    expression: 'Z * 'Y -> 'X
    in declaration:
      f =
	(fn (s,w) => <exp> <exp> w
	 | _ => (<exp> := <exp>; raise <exp>))   <==== redundent rule
Fix:	 
  Caused by switch to prettyprinter for absyn.  Left out call of trim
  to trim last default rule when printing match in CASEexp and FNexp.
Status: fixed in 0.92 (dbm)
----------------------------------------------------------------------
670. missing indicators in redundant match warning messages
Submitter: Dave MacQueen
Date: 11/16/92
Version: 0.88 through 0.92c
Severity: major
Problem: 
  In version 0.87 and earlier an arrow "-->" was printed in front of
  redundant rules in the warning message for redundant matches.
Code: (in file bug670.sml)
  fun f (true,x) = 0
    | f (true,nil) = 1
    | f (false, x) = 2
    | f w = 3;
Transcript: 
  Standard ML of New Jersey, Version 0.87, July 31, 1992
  val it = () : unit
  - use "bug670.sml";
  bug670.sml:1.1-4.11 Warning: redundant patterns in match
	  (true,x) => ...
    -->   (true,nil) => ...
	  (false,x) => ...
    -->   w => ...
  val f = fn : bool * 'a list -> int

  Standard ML of New Jersey, Version 0.92b, November 11, 1992
  val it = () : unit
  - use "bug670.sml";
  [opening bug670.sml]
  bug670.sml:1.1-4.11 Warning: redundant patterns in match
	    (true,x) => ...
	    (true,nil) => ...
	    (false,x) => ...
	    w => ...

  val f = fn : bool * 'a list -> int
Comments:
  I think that 0.88 was the version that incorporated Bill Aitken's
  rewrite of the match compiler, so it is probably caused by that
  change.
Fix: added a rev around call of fixupUnused in doMatchCompile in
     translate/mc.sml.  fixupUnused was returning a list of ints
     sorted in the wrong order.
Status: fixed in 0.92 (dbm)
----------------------------------------------------------------------
671. visibility of parameter in functor signature
Submitter:    Zhong Shao   (zsh@cs.princeton.edu)
Date:         Nov. 17, 1992
Version:      0.91
System:       all 
Severity:     major
Problem:      unbound structure in functor signature definitions
Code:
(* case 1 *)
 funsig FSIG(B : sig type t end) = sig val f : B.t end

(* case 2 *)
 funsig FSIG(structure B : sig type t end) = sig val f : B.t end

(* case 3 *)
 funsig FSIG(B : sig type t end) = sig val f : t end

(* case 4 *)
 funsig FSIG(structure B : sig type t end) = sig val f : t end

Transcript:

 haven% sml
 Standard ML of New Jersey, Version 0.91, October 26, 1992
 val it = () : unit
 -  funsig FSIG(B : sig type t end) = sig val f : B.t end;
 std_in:2.47-2.49 Error: unbound structure B in path B.t

 -  funsig FSIG(structure B : sig type t end) = sig val f : B.t end;
 std_in:0.0-0.0 Error: unbound structure B in path B.t

 -  funsig FSIG(B : sig type t end) = sig val f : t end;
 funsig FSIG(B:<sig>) = sig val f : <Argument>.<Parameter>.t end

 -  funsig FSIG(structure B : sig type t end) = sig val f : t end;
 std_in:2.57 Error: unbound type constructor t

Comments:  

 The code for case 1 and 2 should be valid, as they are in 89. 
 The code for case 3 and 4 should be rejected (intuitively) 

Fix:
  Here is the fix for the bug in signatures of functors:
  tulipe-cregut->diff elabsig.sml elabsig.sml~
  539,540c539,540
  <           of (NONE,_) => Normalize.openX(name_X,sgnArg,symtotalParent)
  <            | (SOME _ ,_) => 
  ---
  >           of (SOME _,_) => Normalize.openX(name_X,sgnArg,symtotalParent)
  >            | (NONE,_) => 
  It is just a stupid inversion...
Status: fixed in 0.93
----------------------------------------------------------------------
672. start() in i386 Mach
Submitter:      Mark Leone (mleone@cs.cmu.edu)
Date:		11/18/92
Version:        0.91
System:         i386 Mach
Severity:       minor
Problem:        start() is now _start() in i386 Mach.
Comments:	I386.prim.s used to require an #ifdef for Mach to set startptr 
		to start(), not _start().  This is no longer necessary.
Fix:
*** I386.prim.s.orig    Wed Nov 18 13:25:23 1992
--- I386.prim.s Wed Nov 18 13:24:13 1992
***************
*** 651,658 ****
  /* this bogosity is for export.c */
        .globl  _startptr
  _startptr: 
- #if defined(I386) && defined(MACH)
-       .long   _start
- #else
        .long   start
- #endif
--- 651,654 ----
Status: fixed in 0.92
----------------------------------------------------------------------
673. failure of type propagation with higher-order functors
Submitter: Dave MacQueen
Date: 11/20/92
Version: 0.92
Severity: major
Problem: 
  Type information is not propagated through application of
  a parameter functor.
Code:  (bug673.sml)
  signature MONOID = 
  sig
    type t
    val plus: t*t -> t
    val e: t
  end;

  (* functor signature declaration *)
  funsig PROD (structure M: MONOID
	       structure N: MONOID) = MONOID

  functor Square(structure X: MONOID
		 functor Prod: PROD): MONOID =
      Prod(structure M = X
	   structure N = X);

  functor Prod(structure M: MONOID
	       structure N: MONOID): MONOID =
  struct
    type t = M.t * N.t
    val e = (M.e, N.e)
    fun plus((m1,n1),(m2,n2))=(M.plus(m1,m2),N.plus(n1,n2))
  end;

  structure Int =
  struct
    type t = int
    val e = 0
    val plus = (op +): int*int -> int
  end;

  structure Int2 = Square(
    structure X = Int
    functor Prod = Prod);

  #1(Int2.e);
Transcript:
  Standard ML of New Jersey, Version 0.92, November 18, 1992
  val it = () : unit
  - use "bug673.sml";
  [opening bug673.sml]
  signature MONOID =
    sig
      type t
      val plus : t * t -> t
      val e : t
    end
  funsig PROD(<Parameter>:<sig>) =
    sig
      type t
      val plus : t * t -> t
      val e : t
    end
  functor Square : <sig>
  functor Prod : <sig>
  structure Int :
    sig
      eqtype t
      val e : int
      val plus : int * int -> int
    end
  structure Int2 : MONOID
  bug673.sml:39.1-39.10 Error: operator and operand don't agree (type mismatch)
    operator domain: {1:'Y, '...Z}
    operand:         Int2.t
    in expression:
      (fn {1=1,...} => 1) (e)
  [closing bug673.sml]
  - 
Fix: [Cregut]
  diff elaborate/elabstr.sml elaborate/elabstr.sml~
  525,528c525,528
  < 		 fun computeSelf (StructStr _) = true
  < 		   | computeSelf (MarkStr(def,_,_)) = computeSelf def
  < 		   | computeSelf _ = false
  < 		 val self = computeSelf def
  ---
  > 		 val self = 
  > 		  (case def of VarStr _ => false 
  > 		             | MarkStr(VarStr _,_,_) => false
  > 			     | _ => true)

  Ok I think it fixes the problem: match thought that it could suppress its
  origin whereas it was a computed application to be done at each functor
  application. In the bogus version you could correct the problem 
  - by suppressing the signature MONOID
  - by putting an intermediate level of structure so that the optimisation
  of self was irrelevant (which is a kind of bug but we have already talked
  about it)
  (an intermediate level = functor Square(,,,) = struct structure result =
  Prod(...) end; )

Status: fixed in 0.93
----------------------------------------------------------------------
674. System.Env.filterEnv raises exception IntmapF
Submitter: Dave MacQueen
Date: 11/22/92
Version: 0.92
Severity: major
Problem: 
  System.Env.filterEnv raises exception IntmapF.
Transcript: 
- System.Env.filterEnv(!System.Env.pervasiveEnvRef,[System.Symbol.valSymbol "hd"]);

uncaught exception IntmapF
Comments: Probably related to bug 640.
Fix: fix lvarOfBinding in modules/moduleutil.sml
Status: fixed in 0.93a (dbm)
----------------------------------------------------------------------
675. prettyprinter doesn't sense System.Print.linewidth
Submitter: Konrad Slind
Date: 11/23/92
Version: 0.92
Severity: major
Problem: 
  System.Print.linewidth doesn't seem to control the linewidth used by the
system prettyprinter. 
Transcript: 
  $ sml
  Standard ML of New Jersey, Version 0.92, November 18, 1992
  val it = () : unit
  - System.Print.printLength := 10000;
  val it = () : unit
  - val L = ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa"];
  val L =
    ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd",
     "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa",
     "adsfasd","afasdfa","adsfasd","afasdfa"] : string list
  - System.Print.linewidth := 20;
  val it = () : unit
  - L;
  val it =
    ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd",
     "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa",
     "adsfasd","afasdfa","adsfasd","afasdfa"] : string list
  - System.Print.linewidth := 150;
  val it = () : unit
  - L;
  val it =
    ["adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd",
     "afasdfa","adsfasd","afasdfa","adsfasd","afasdfa","adsfasd","afasdfa",
     "adsfasd","afasdfa","adsfasd","afasdfa"] : string list
  - 
Status: open
----------------------------------------------------------------------
676. Out of order record field evaluation.
Submitter: Andrew Appel
Date: 11/24/92
Version: 0.92
Severity: Critical
Problem: 
  Out of order record field evaluation.
Transcript: 
  Standard ML of New Jersey, Version 0.92, November 18, 1992
  val it = () : unit
  - val r = ref 0;
  val r = ref 0 : int ref
  - fun g() = (inc r; !r);
  val g = fn : unit -> int
  - {last=g(),first=g()};
  val it = {first=1,last=2} : {first:int, last:int}
Status: fixed in 0.93 (Zhong Shao)
----------------------------------------------------------------------
677. memory leak
Submitter:      Kjeld H. Mortensen (kjeld@metasoft.com)
Date:           11/24/92
Version:        0.92
Systems:        Sparc server 330, SunOS 4.1.1,
                HP9000s400, HPUX 8.0
Severity:       Major
Problem:        Memory leaks (heap grown when not supposed to).
Code:           
Transcript:    
Comments:
I have made experiments with SML/NJ v0.92 in order to see if there were
any memory leaks. It seems to me that it is the case.

My standard experiment is the same as from bug report #500, which was fixed
by v0.82. The bug was present in v0.75 and now in v0.92, but not to the 
same degree. I've included a bug report in case you think it should be
added to the masterbugs list. 

It is very important for us that the compiler doesn't slow down over a
longer period of usage, as a result of memory leaks. So I've given the
bug a high priority.

Using the compiler over a long period of time where stuff is only evaluated
or values "overwritten", the heap size increases unnecessarely (see also
bug #500).


(v0.92)  ----------Mem Size----------    
          start      end    end-start  ratio  softmax   slow down
 Sparc   19968 kb  21096 kb  1128 kb     3      28 Mb     26 %
 HPs400  11224 kb  11900 kb   676 kb     3      32 Mb     16 %

The table shows memory usage (as show by 'ps') at the beginning and end
of the experiment, the difference between end and start, ratio and softmax
(from System.Control.Runtime), and how much slower the compiler is at
the end as compared with the beginning of the experiment. The session lasts
45 and 60 minutes for the HP and Sparc respectively.

I want to point out that the earlier version 0.82 doesn't have any
detectable memory leak and therefore no slow down.
Status: fixed in 0.93c
----------------------------------------------------------------------
678. emacs tags broken
Submitter:      Charlie Krasic (cckrasic@plg.uwaterloo.ca)
Date:           Nov. 24/92
Version:        0.92
System:         Sun 670/MP (Sparc) w/SunOS 4.3 (?)
Severity:       minor
Problem:        emacs tags broken when trying to create TAGS file for SML/NJ
Code:           modified the file 'all' to contain directives to toggle
                indexing and markabsyn, then run smlc < all, then run
                sml-tags -r.  I tried both my old version of sml-tags and
                a newly built version of sml-tags.
Transcript:     no transcript.  Re-compiling the entire system creates the
                various .i.xxx tag files.  Running "sml-tags -r" gives:
	                uncaught exception getIntError
Comments:	This precedure works fine if I use a batch compiler based on 0.91
Status: open
----------------------------------------------------------------------
679. "Compiler bug: addObject" while compiling the Edinburgh library
Submitter: wkh@dce.austin.ibm.com (Ward K. Harold)
Date: 11/25/92
Version: 0.92  (works up through version 0.82, fails in version 0.83)
System: RS6000, AIX 3.2, MIPS, SPARC
Severity: major
Problem: 
  "Compiler bug: addObject" while compiling the Edinburgh library, version
  1.20 or 1.21.  Occurs when loading MonoSet.sml in the MonoSet functor.
Code: (* simplified version: bug679.sml *)
  functor F (X: sig end) = (* has to be a functor, not a structure *)
  struct
    abstype s = S
    with
      type t = unit  (* type definition necessary *)
    end
  end
Transcript: 
  Standard ML of New Jersey, Version 0.92, November 18, 1992
  val it = () : unit
  - use "foo.sml";
  [opening foo.sml]
  Error: Compiler bug: addObject
  [closing foo.sml]
  - 
Fix: [Pierre Cregut]
  When I counted the number of components created in a structure that have a
  representation in the core, I forgot to count the components coming from the
  body of an abstype

  tulipe-cregut->diff elabstr.sml elabstr.sml~
  42,44c42,43
  <       | (AbstypeDec {abstycs,withtycs,body,...}, t) => 
  <          let val (strN,fctN,typN) = count (body,t)
  <          in (strN,fctN,typN+length abstycs+length withtycs) end
  ---
  >       | (AbstypeDec {abstycs,withtycs,...}, (strN,fctN,typN)) => 
  >          (strN,fctN,typN + length abstycs + length withtycs)

Status: fixed in 0.93
----------------------------------------------------------------------
680. Bad vertical alignment prettyprinting case expression.
Submitter: Dave MacQueen
Date: 11/20/92
Version: 0.92
Severity: minor
Problem: 
  Bad veritcal allignment prettyprinting case expression.
Transcript: 
  - if 2 then 3 else 4;
  std_in:0.0-0.0 Error: case object and rules don't agree (tycon mismatch)
    rule domain: bool
    object:      int
    in expression:
      (case 2
	of true => 3
       | false => 4)
Status: fixed in 0.93c
----------------------------------------------------------------------
681. building on SGI Indigos with cc version 3.10
Submitter: asgeir@viking.asd.sgi.com (Asgeir Eiriksson), Fernando Pereira
Date: 12/2/92
Version: 0.92
System: SGI R3000 and R4000 Indigo
Severity: Major
Problem: 
  sml fails to build with /usr/bin/cc version 3.10 (the latest)
Transcript: 
	cc -O  -DMIPS -D_BSD_SIGNALS -D__STDC__ -Dsgi -DSGI  -o run run.o run_ml.o callgc.o gc.o export.o timers.o  ml_objects.o cfuns.o cstruct.o signal.o exncode.o malloc.o  mp.o sync.o prim.o allmo.o 
/usr/bin/ld:
This executable contains branch instruction(s) at end-of-page
makeml> echo ( exportML "sml"; output(std_out,System.version); output(std_out,(chr 10)); output(std_out, "")); | runtime/run -m 8192 -r 5 -h 2048 IntMipsBig

[Increasing heap to 2051k]
[Loading mo/CoreFunc.mo]
...
  
[closing boot/perv.sml]
[Loading boot/overloads.sml]
structure Overloads : ...
[closing boot/overloads.sml]
Go for it
- 
[Major collection... 15% used (550960/3548736), 350 msec]

[Decreasing heap to 2699k]

[Major collection... 100% used (552208/552208), 320 msec]
==> Inconsistent object for export: !(0)

uncaught exception Io "exportML "sml": Error 0"
-
Comments:
  This does not occur with the 2.10 version of cc.
  Reproducible on Fernando Pereira's Indigo.
Status: fixed in 0.93
----------------------------------------------------------------------
682. excess newlines in compiler warning message
Submitter:      Thomas Yan  tyan@cs.cornell.edu
Date:           12/2/92
Version:        .92
Severity:       minor
Problem:        extraneous blank lines printed during compilation
Code:           val [1,2,3] = [1,2,3]
Transcript:
    - val [1,2,3] = [1,2,3];
    std_in:55.1-55.21 Warning: binding not exhaustive
              1 :: 2 :: 3 :: nil = ...
    
    
    
    
    
    
    
    -
Comments: baffling the first time it appears
Fix: In print/ppdec.sml, make each declaration responsible for
  printing it's own terminating newline.
Status: fixed in 0.93c
----------------------------------------------------------------------
683. Compiler bug: Extern: update_structure 2
Submitter: Sanjiva Prasad <sanjiva@ecrc.de>
Date: 12/2/92
Version: 0.92
Severity: minor
Problem: 
 Elaborating an illegal signature decl leads to Compiler bug:
 Extern: update_structure 2.
Code:
  signature S =
  sig
    functor Foo(X: S) : S
  end
Transcript: 
  Standard ML of New Jersey, Version 0.92, November 18, 1992
  val it = () : unit
  - signature S =
  = sig
  =   functor Foo(X: S) : S
  = end;
  std_in:4.18 Error: unbound signature: S
  std_in:4.23 Error: unbound signature: S
  Error: Compiler bug: Extern: update_structure 2
Fix: [Pierre Cregut]
  update_structure didn't consider the case where an error had already been
  encountered. I have added two cases: the structure is an error, the
  signature is an error. Only the second one is proved to be necessary but the
  first one is safe.

  tulipe-cregut->diff extern.sml extern.sml~
  102,103d101
  <    | ERROR_STR => ()
  <    | INSTANCE{sign as ERROR_SIG,...} => ()
Status: fixed in 0.93
----------------------------------------------------------------------
684. Compiler bug: checkList
Submitter: Sanjiva Prasad <sanjiva@ecrc.de>
Date: 12/2/92
Version: 0.92
Severity: major
Problem: 
  A functor definition causes "Compiler bug: checkList".
Transcript: 
  - signature S1 = sig end;
  signature S1 = sig  end
  - funsig FOO (X:S1) (Y:S1) = S1;
  funsig FOO(X:<sig>) = sig functor <functor> : <sig> end
  - structure A:S1 = struct end;
  structure A : S1
  - functor Bar (C:S1) = C;
  functor Bar : <sig>
  - functor Foo (X:S1) (Y:S1) = X;
  functor Foo : <sig>
  - functor Foo:FOO = Foo;
  functor Foo : <sig>
  - funsig FOO2 (X:S1) = S1;      
  funsig FOO2(X:<sig>) = sig  end
  - functor Dummy (W: sig functor F :FOO2) (functor Z:FOO2) = Z(A);     
  std_in:9.38 Error: syntax error found at RPAREN
  - functor Dummy (W: sig functor F :FOO2 end ) (functor Z:FOO2) = Z(A); 
  functor Dummy : <sig>
  - functor Bar1 = Dummy (Foo(A)) (functor Z = Bar);
  std_in:10.16-10.47 Error: unmatched structure spec: F
  std_in:10.16-10.47 Error: unbound functor: <functor> in path <hidden>.<functor>
  - functor Dummy (W: S1)  (functor Z:FOO2) = Z(A); 
  functor Dummy : <sig>
  - functor Bar1 = Dummy (Foo(A)) (functor Z = Bar);
  std_in:11.16-11.47 Error: unbound functor: <functor> in path <hidden>.<functor>
  - structure C:S1 = struct functor G=Bar end;
  structure C : S1
  - open C;
  open C
  - structure C:S1 = Foo(A);
  structure C : S1
  - open C;
  open C
  - funsig ARBIT (B:S1) (type t) = S1;
  funsig ARBIT(B:<sig>) = sig functor <functor> : <sig> end
  - 
  - 
  - functor Bar5 = Foo (Foo A);
  std_in:18.25 Error: syntax error found at ID
  - functor Bar5 = Foo (Foo (A) );
  Error: Compiler bug: checkList

Code: (* bug684.sml *)
  (* the following reproduces the bug in 0.92 *)
  signature S = sig end;
  funsig FOO (X:S) (Y:S) = S;
  functor Foo (X:S) (Y:S) = X;
  functor Foo: FOO = Foo;  (* with this deleted produces different strange e