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.
--------------------------------------------------------------------------------
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: half-open (considered a wish, not a bug)
------------------------------------------------------------------------------
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: half-open  (not required by the Definition)
--------------------------------------------------------------------------------
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: open
--------------------------------------------------------------------------------
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
    -
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
Code:           <example code that reproduces the problem>
Transcript:     <transcript of session illustrating problem>
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: open
--------------------------------------------------------------------------------
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: cannot duplicate without source code
--------------------------------------------------------------------------------
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: open
-------------------------------------------------------------------------------
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: open
-------------------------------------------------------------------------------
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.

Status: Not a bug, but should be flagged by makeml
-------------------------------------------------------------------------------
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.

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: open
-------------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
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"
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:
Status: fixed in 0.73
------------------------------------------------------------------------------
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:
Status: fixed in 0.70
------------------------------------------------------------------------------
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
System: 
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: open
---------------------------------------------------------------------------
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: open	
-------------------------------------------------------------------------
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: Apr 17 1991
Version: 0.68
System: 
Severity: major
Problem: not consistent about allowing equality
Code: 
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:
From: murthy (Chet Murthy)
To: jhr
Subject: ML question
Date: Sun, 21 Apr 91 10:06:44 +0100

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: open
---------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
345. export should return a code and have different type
Submitter: ???
Date: Nov 8, 1990
Version: ?
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: open (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: open
---------------------------------------------------------------------------
347. dec function in fastlib wrong
Submitter: Andrew Appel (appel@princeton.edu)
Date: Apr 15 1991
Version: 0.69 (and all previous)
System: 
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. 
Code: 
Transcript: 
Comments: 
Fix: 
Status: fixed in 0.70
---------------------------------------------------------------------------
348. connect_inet bug 
Submitter: John Reppy (jhr@cs.cornell.edu)
Date: Mar 23 1991
Version: 0.68
System: 
Severity: minor
Problem: 
Code: 
Transcript: 
Comments: 
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
Comments: 
Fix: 
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: open
---------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
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";
Status: the first problem is open, the second is fixed as of 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
Version: 
System: 
Severity: 
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).
Code: 
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: open
---------------------------------------------------------------------------
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.
Code:
Transcript:
Comments:
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: open
---------------------------------------------------------------------------
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.
Status: Works on SUNOS 4.1.1 in version 0.73 [lg]
---------------------------------------------------------------------------
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: ?
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
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.
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.
Status: open
---------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
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.
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: open
---------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
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: open
---------------------------------------------------------------------------
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
---------------------------------------------------------------------------
