Annotation of researchv10no/cmd/sml/src/boot/perv.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: structure Initial =
                      3: struct
                      4: 
                      5: structure  Inside : sig structure System : SYSTEM
                      6:                        structure List : LIST
                      7:                        structure ByteArray : BYTEARRAY
                      8:                        structure IO : IO
                      9:                        structure Bool : BOOL
                     10:                        structure String : STRING
                     11:                    end =
                     12: struct
                     13: 
                     14: open Core
                     15: 
                     16: (* create a type-safe version of the InLine structure while preserving
                     17:    the inline property of the functions. *)
                     18: structure InLine =
                     19:   struct
                     20:     infix 7 * div
                     21:     infix 6 + -
                     22:     infix 4 < > <= >=
                     23:     infix 3 :=
                     24:     val callcc : ('a cont -> 'a) -> 'a = InLine.callcc
                     25:     val throw : 'a cont -> 'a -> 'b = InLine.throw
                     26:     val ! : 'a ref -> 'a = InLine.!
                     27:     val op * : int * int -> int = InLine.*
                     28:     val op + : int * int -> int = InLine.+
                     29:     val op - : int * int -> int = InLine.-
                     30:     val op := : 'a ref * 'a -> unit = InLine.:=
                     31:     val op < : int * int -> bool = InLine.<
                     32:     val op <= : int * int -> bool = InLine.<=
                     33:     val op > : int * int -> bool = InLine.>
                     34:     val op >= : int * int -> bool = InLine.>=
                     35:     val alength : 'a array -> int = InLine.alength
                     36:     val boxed : 'a -> bool = InLine.boxed
                     37:     val cast : 'a -> 'b = InLine.cast
                     38:     val op div : int * int -> int = InLine.div
                     39:     val fadd : real * real -> real = InLine.fadd
                     40:     val fdiv : real * real -> real = InLine.fdiv
                     41:     val feql : real * real -> bool = InLine.feql
                     42:     val fge : real * real -> bool = InLine.fge
                     43:     val fgt : real * real -> bool = InLine.fgt
                     44:     val fle : real * real -> bool = InLine.fle
                     45:     val flt : real * real -> bool = InLine.flt
                     46:     val fmul : real * real -> real = InLine.fmul
                     47:     val fneg : real -> real = InLine.fneg
                     48:     val fneq : real * real -> bool = InLine.fneq
                     49:     val fsub : real * real -> real = InLine.fsub
                     50:     val ieql : int * int -> bool = InLine.ieql
                     51:     val ineq : int * int -> bool = InLine.ineq
                     52:     val makeref : 'a -> 'a ref = InLine.makeref
                     53:     val ordof : string * int -> int = InLine.ordof
                     54:     val slength : string -> int = InLine.slength
                     55:     val store : string * int * int -> unit = InLine.store
                     56:     val subscript : 'a array * int -> 'a = InLine.subscript
                     57:     val update : 'a array * int * 'a -> unit = InLine.update
                     58:     val        ~ : int -> int = InLine.~
                     59:     val reql : 'a ref * 'a ref -> bool = InLine.ieql
                     60:     val aeql : 'a array * 'a array -> bool = InLine.ieql
                     61:     val andb : int * int -> int = InLine.andb
                     62:     val orb : int * int -> int = InLine.orb
                     63:     val xorb : int * int -> int = InLine.xorb
                     64:     val rshift : int * int -> int = InLine.rshift
                     65:     val lshift : int * int -> int = InLine.lshift
                     66:     val notb : int -> int = InLine.notb
                     67:   end  (* structure InLine *)
                     68: 
                     69: fun c_function s = 
                     70:     let exception C_function_not_found of string
                     71:         fun f (Assembly.FUNC(p,t,rest)) =
                     72:                if stringequal(s,t) then p
                     73:                else if stringequal(t,"xxxx") then raise (C_function_not_found s)
                     74:                else f rest
                     75:         val cfun = f Assembly.external
                     76:      in fn x => Assembly.A.callc(cfun,x)
                     77:     end
                     78: 
                     79: val isV9 = InLine.ieql(Assembly.opsys,3)
                     80: 
                     81: val bigEndian =
                     82:     case InLine.!(InLine.cast "\001\003\005\007")
                     83:      of 8487555 => true
                     84:       | 58884480 => false
                     85: 
                     86: 
                     87: (* The datatype ref is defined in the built-in structure PrimTypes.
                     88:    It is not mention here because it has a unique representation; an
                     89:    explicit datatype declaration would destroy this representation.
                     90:    Similarly, there is no datatype specification in the REF signature
                     91:    itself. *)
                     92: structure Ref = 
                     93:   struct
                     94:     infix 3 :=
                     95:     val ! = InLine.!
                     96:     val op := = InLine.:=
                     97:     fun inc r = r := InLine.+(!r,1)
                     98:     fun dec r = r := InLine.-(!r,1)
                     99:   end (* structure Ref *)
                    100:    
                    101: structure List : LIST =
                    102:   struct
                    103:     infixr 5 :: @
                    104:     open PrimTypes InLine
                    105:     exception Hd
                    106:     exception Tl
                    107:     exception Nth
                    108:     exception NthTail
                    109:     fun hd (a::r) = a | hd nil = raise Hd
                    110:     fun tl (a::r) = r | tl nil = raise Tl    
                    111:     fun null nil = true | null _ = false
                    112:     fun length l = 
                    113:        let fun j(k,nil) = k
                    114:              | j(k, a::x) = j(k+1,x)
                    115:         in j(0,l)
                    116:        end
                    117:     fun op @ (nil,l) = l
                    118:       | op @ (a::r, l) = a :: (r@l)
                    119:     fun rev l =
                    120:        let fun f (nil, h) = h
                    121:              | f (a::r, h) = f(r, a::h)
                    122:        in  f(l,nil)
                    123:        end
                    124:     fun map f =
                    125:        let fun m nil = nil
                    126:              | m (a::r) = f a :: m r
                    127:        in  m
                    128:        end
                    129:     fun fold f [] = (fn b => b)
                    130:       | fold f (a::r) = (fn b => let fun f2(e,[]) = f(e,b)
                    131:                                       | f2(e,a::r) = f(e,f2(a,r))
                    132:                                 in f2(a,r)
                    133:                                 end)
                    134:     fun revfold f [] = (fn b => b)
                    135:       | revfold f (a::r) = (fn b => let fun f2(e,[],b) = f(e,b)
                    136:                                          | f2(e,a::r,b) = f2(a,r,f(e,b))
                    137:                                    in f2(a,r,b)
                    138:                                    end)        
                    139:     fun app f = let fun a2 (e::r) = (f e; a2 r) | a2 nil = () in a2 end
                    140:     fun revapp f = let fun a2 (e::r) = (a2 r; f e; ()) | a2 nil = () in a2 end
                    141:     fun nthtail(e,0) = e 
                    142:       | nthtail(e::r,n) = nthtail(r,n-1)
                    143:       | nthtail _ = raise NthTail
                    144:     fun nth x = hd(nthtail x) handle NthTail => raise Nth | Hd => raise Nth
                    145:     fun exists pred =
                    146:        let fun f nil = false
                    147:              | f (hd::tl) = pred hd orelse f tl
                    148:        in  f
                    149:        end
                    150:   end (* structure List *)
                    151: 
                    152: structure PreString : sig exception Substring
                    153:                          infix 6 ^
                    154:                          val substring : string * int * int -> string
                    155:                          val ^ : string * string -> string
                    156:                          val imakestring : int -> string
                    157:                      end =
                    158:   struct
                    159:     open InLine
                    160:     exception Substring
                    161:     fun substring("",0,0) = "" (* never call create_s with 0 *)
                    162:       | substring("",_,_) = raise Substring
                    163:       | substring(s,i,0) = if i>=0 
                    164:                            then if boxed s then if i <= slength s
                    165:                                                 then "" else raise Substring
                    166:                                            else if i<=1 
                    167:                                                 then "" else raise Substring
                    168:                            else raise Substring
                    169:       | substring(s,0,1) = if boxed s then cast(ordof(s,0)) else s
                    170:       | substring(s,i,1) =
                    171:             if boxed s then if i>=0 andalso i < slength s 
                    172:                                    then cast(ordof(s,i))
                    173:                                    else raise Substring
                    174:                        else if ieql(i,0) then s else raise Substring
                    175:       | substring(s,i,len) = 
                    176:          if boxed s andalso i>=0 andalso i+len <= slength s
                    177:                andalso len >= 0
                    178:          then let val a = Assembly.A.create_s(len)
                    179:                   fun copy j = if ieql(j,len) then ()
                    180:                                else (store(a,j,ordof(s,i+j)); copy(j+1))
                    181:               in  copy 0; a
                    182:               end
                    183:          else raise Substring
                    184: 
                    185:     infix 6 ^
                    186:     fun op ^ ("",s) = s
                    187:       | op ^ (s,"") = s
                    188:       | op ^ (x,y) =
                    189:          if boxed x 
                    190:          then if boxed y
                    191:               then let val xl = slength x and yl = slength y
                    192:                        val a = Assembly.A.create_s(xl+yl)
                    193:                        fun copyx n = if ieql(n,xl) then ()
                    194:                              else (store(a,n,ordof(x,n)); copyx(n+1))
                    195:                        fun copyy n = if ieql(n,yl) then ()
                    196:                              else (store(a,xl+n,ordof(y,n)); copyy(n+1))
                    197:                     in copyx 0; copyy 0; a
                    198:                    end
                    199:              else let val xl = slength x
                    200:                       val a = Assembly.A.create_s(xl+1)
                    201:                        fun copyx n = if ieql(n,xl) then ()
                    202:                              else (store(a,n,ordof(x,n)); copyx(n+1))
                    203:                    in copyx 0; store(a,xl,cast y); a
                    204:                   end
                    205:          else if boxed y                      
                    206:               then let val yl = slength y
                    207:                        val a = Assembly.A.create_s(1+yl)
                    208:                        fun copyy n = if ieql(n,yl) then ()
                    209:                              else (store(a,1+n,ordof(y,n)); copyy(n+1))
                    210:                     in store(a,0,cast x); copyy 0; a
                    211:                    end
                    212:              else let val a = Assembly.A.create_s 2
                    213:                    in store(a,0,cast x); store(a,1,cast y); a
                    214:                   end
                    215:     fun imakestring i =
                    216:          if i<0 then "~" ^ imakestring(~i)
                    217:          else if i<10 then InLine.cast(InLine.cast "0" + i)
                    218:          else let val j = i div 10
                    219:               in  imakestring j ^ imakestring(i-j*10)
                    220:               end
                    221: 
                    222:   end (* structure PreString *)           
                    223: 
                    224: abstraction ByteArray : BYTEARRAY =
                    225:   struct
                    226:     open InLine PreString
                    227:     infix 3 sub
                    228:     type bytearray = string
                    229:     exception Subscript
                    230:     exception Range
                    231:     fun array(len,v) =
                    232:        if len<0 then raise Subscript
                    233:        else if v<0 orelse v>=256 then raise Range
                    234:        else if ieql(len,0) then Assembly.bytearray0
                    235:        else let val a = Assembly.A.create_b len
                    236:                 fun init i = if ieql(i,len) then ()
                    237:                              else (store(a,i,v); init(i+1))
                    238:              in init 0; a
                    239:             end
                    240:     val length = cast slength
                    241:     fun update(arg as (s,i,c)) =
                    242:        if i<0 orelse i >= slength s then raise Subscript
                    243:        else if c<0 orelse c>255 then raise Range
                    244:        else store arg
                    245:     val op sub = fn (s,i) => if i<0 orelse i>= slength s then raise Subscript
                    246:                             else ordof(s,i)
                    247:     fun extract(ba,i,1) = if i<0 orelse i >= slength ba then raise Subscript
                    248:                          else cast(ordof(ba,i))
                    249:       | extract(s,i,len) = 
                    250:          if i<0 orelse i+len > slength s orelse len<0 then raise Subscript
                    251:          else if ieql(len,0) then ""
                    252:          else let val a = Assembly.A.create_s len
                    253:                   fun copy j =  if ieql(j,len) then ()
                    254:                                 else (store(a,j,ordof(s,i+j)); copy(j+1))
                    255:               in  copy 0; a
                    256:               end
                    257:     fun app f ba = 
                    258:        let val len = slength ba
                    259:            fun app' i = if i >= len then ()
                    260:                         else (f(ba sub i); app'(i+1))
                    261:        in  app' 0
                    262:        end
                    263:     fun revapp f ba = 
                    264:        let fun revapp' i = if i < 0 then ()
                    265:                            else (f(ba sub i); revapp'(i-1))
                    266:        in  revapp'(slength ba - 1)
                    267:        end
                    268:     fun fold f ba x = 
                    269:        let fun fold'(i,x) = if i < 0 then x else fold'(i-1, f(ordof(ba,i),x))
                    270:        in  fold'(slength ba - 1, x)
                    271:        end
                    272:     fun revfold f ba x = 
                    273:        let val len = slength ba
                    274:            fun revfold'(i,x) = if i >= len then x
                    275:                                else revfold'(i+1,f(ordof(ba,i),x))
                    276:        in  revfold'(0,x)
                    277:        end
                    278:   end (* abstraction ByteArray *)
                    279: 
                    280: structure PreLim =
                    281:   struct
                    282:     val exn_name : exn -> string = InLine.cast(fn(_,ref s) => s)
                    283:     val interactive = Core.Refs.interactive
                    284:     val prLambda = Core.Refs.prLambda
                    285:     fun getargs s = 
                    286:        let val f : int -> string = c_function s
                    287:            fun strlen(s,i) =
                    288:                if InLine.ieql(InLine.ordof(s,i),0) then i
                    289:                    else strlen(s,InLine.+(i,1))
                    290:            fun mlstr x =
                    291:                let val len = strlen(x,0)
                    292:                    val ba = Assembly.A.create_s len
                    293:                    fun copy ~1 = ()
                    294:                      | copy i = (InLine.store(ba,i,InLine.ordof(x,i));
                    295:                                  copy(InLine.-(i,1)))
                    296:                 in copy (InLine.-(len,1));
                    297:                    ba
                    298:                end
                    299:            fun g i =
                    300:                let val x = f i
                    301:                 in if InLine.ineq(InLine.cast x,0)
                    302:                    then mlstr x :: g (InLine.+(i,1))
                    303:                    else nil
                    304:                end
                    305:         in fn () => g 0
                    306:         end
                    307:     val argv : unit -> string list = getargs "argv"
                    308:     val environ : unit -> string list = getargs "envi"
                    309:   end (* structure PreLim *)
                    310: 
                    311: structure PreStats =
                    312:   struct
                    313:     datatype time = TIME of {sec : int, usec : int}
                    314:     local open Assembly.A Ref
                    315:     in
                    316:     val zerotime = TIME{sec=0,usec=0}
                    317:     val lines = Core.Refs.lines
                    318:     val parse = InLine.cast Core.Refs.parse
                    319:     val translate = InLine.cast Core.Refs.translate
                    320:     val codeopt = InLine.cast Core.Refs.codeopt
                    321:     val convert = InLine.cast Core.Refs.convert
                    322:     val hoist = InLine.cast Core.Refs.hoistx
                    323:     val cpsopt = InLine.cast Core.Refs.cpsopt
                    324:     val closure = InLine.cast Core.Refs.closure
                    325:     val globalfix = InLine.cast Core.Refs.globalfix
                    326:     val spill = InLine.cast Core.Refs.spill
                    327:     val codegen = InLine.cast Core.Refs.codegen
                    328:     val freemap = InLine.cast Core.Refs.freemap
                    329:     val execution = InLine.cast Core.Refs.execution
                    330:     fun reset() = 
                    331:        (lines := 0;
                    332:         parse := zerotime;
                    333:         translate := zerotime;
                    334:         codeopt := zerotime;
                    335:         convert := zerotime;
                    336:         cpsopt := zerotime;
                    337:         closure := zerotime;
                    338:         globalfix := zerotime;
                    339:         spill := zerotime;
                    340:         codegen := zerotime;
                    341:         freemap := zerotime;
                    342:         execution := zerotime)
                    343:     end
                    344:   end
                    345: 
                    346: val errn = c_function "errn"
                    347: 
                    348: fun syserror s = 
                    349:     let val n = errn()
                    350:         open PreString
                    351:         val m = InLine.alength Assembly.errorstrings
                    352:         val w = if InLine.>=(n,m) orelse InLine.<(n,0)
                    353:                  then "Error " ^ imakestring n
                    354:                  else InLine.subscript(Assembly.errorstrings,n)
                    355:      in raise Assembly.SystemCall (s ^ " failed, " ^ w)
                    356:     end
                    357:        
                    358: structure IOx = 
                    359: struct
                    360:  local open InLine Ref PreString PrimTypes in
                    361:   type bytearray = string
                    362:   exception Io of string
                    363:   type instream = {filid : int, pos : int ref, len : int ref, name : string,
                    364:                   closed : bool ref, buf : bytearray, tty : bool ref}
                    365:   type outstream = {filid : int, pos : int ref, name : string,
                    366:                    closed : bool ref, buf : bytearray, tty : bool ref}
                    367: 
                    368:   val isatty = c_function "isat"
                    369: 
                    370:   val bufsize = Core.bufsize
                    371: 
                    372:   val std_in = Core.std_in
                    373:   val std_out = Core.std_out
                    374:   val _ = (#tty std_in := isatty 0; #tty std_out := isatty 1)
                    375: 
                    376:   (* should be flushed on exportML, flushed and closed on exportFn *)
                    377:   val outstreams = Core.Refs.outstreams
                    378:   (* should be closed on exportFn *)
                    379:   val instreams = Core.Refs.instreams
                    380:   fun add_in s = instreams := s :: !instreams
                    381:   fun add_out s = outstreams := s :: !outstreams
                    382:   fun init_streams() =
                    383:       let val {pos=pos_in,tty=tty_in,closed=closed_in,len,...} = std_in
                    384:          val {pos=pos_out,tty=tty_out,closed=closed_out,...} = std_out
                    385:       in  pos_in := 0; tty_in := isatty 0; closed_in := false; len := 0;
                    386:          pos_out := 0; tty_out := isatty 1; closed_out := false;
                    387:          PreLim.interactive := !tty_in;
                    388:          instreams := [std_in];
                    389:          outstreams := [std_out]
                    390:       end
                    391: 
                    392:   (* the filename passed to Assembly.A.openf must be zero-padded;
                    393:      you need 2 zeros in case padding a null string. *)
                    394:   val c00 = "\000\000"
                    395: 
                    396:   fun close filid = case Assembly.A.syscall(6,[cast filid],1)
                    397:                      of ~1 => syserror "close"
                    398:                       | _ => ()
                    399: 
                    400:   datatype mode = READ | WRITE | APPEND
                    401: 
                    402:   val openf =
                    403:       if isV9
                    404:       then fn(name,mode) =>
                    405:            let open Assembly.A
                    406:             in case mode
                    407:                 of READ =>
                    408:                     (case syscall(5,[name,cast 0],2)
                    409:                       of ~1 => syserror "open"
                    410:                        | n => n)
                    411:                  | WRITE =>
                    412:                     (case syscall(8,[name, cast 438],2)
                    413:                       of ~1 => syserror "creat"
                    414:                        | n => n)
                    415:                  | APPEND =>
                    416:                     (case syscall(5,[name,cast 1],2)
                    417:                       of ~1 => (case syscall(8,[name, cast 438],2)
                    418:                                  of ~1 => syserror "creat"
                    419:                                   | n => n)
                    420:                        | n => (case syscall(19,[cast n,cast 0,cast 2],3)
                    421:                                 of ~1 => (close n; syserror "lseek")
                    422:                                  | _ => n))
                    423:            end          
                    424:       else fn (name,mode) =>
                    425:            let open Assembly.A
                    426:                val flag = case mode of READ => 0 | WRITE => 1537 | APPEND => 521
                    427:             in case syscall(5,[name, cast flag, cast 438],3)
                    428:                 of ~1 => syserror "open"
                    429:                  | n => n
                    430:            end
                    431: 
                    432:   fun open_in s =
                    433:       let val f = openf(s ^ c00,READ)
                    434:                      handle Assembly.SystemCall message =>
                    435:                              raise Io("open_in \"" ^ s ^ "\": " ^ message)
                    436:          val s = {filid = f, pos = ref 0, closed = ref false,
                    437:                   len = ref 0, name = s,
                    438:                   buf = Assembly.A.create_b bufsize, tty = ref(isatty f)}
                    439:       in  add_in s; s
                    440:       end
                    441:   fun open_o mode = fn s =>
                    442:       let val f = openf(s ^ c00,mode)
                    443:          val s = {filid = f, pos = ref 0, closed = ref false, name=s,
                    444:                   buf = Assembly.A.create_b bufsize, tty = ref(isatty f)}
                    445:       in  add_out s; s
                    446:       end
                    447: 
                    448:   fun open_out name = open_o WRITE name
                    449:                      handle Assembly.SystemCall message =>
                    450:                              raise Io("open_out \"" ^ name ^ "\": " ^ message)
                    451: 
                    452:   fun open_append name = open_o APPEND name
                    453:                      handle Assembly.SystemCall message =>
                    454:                              raise Io("open_append \"" ^ name ^ "\": " ^ message)
                    455: 
                    456: 
                    457:   fun open_string s =
                    458:       if boxed s
                    459:       then {filid = ~1, pos = ref 0, len = ref (slength s),
                    460:            closed = ref false, tty = ref false, name="<string>",
                    461:            buf = s}
                    462:       else {filid = ~1, pos = ref 0, len = ref 1,
                    463:            closed = ref false, tty = ref false, name="<string>",
                    464:            buf =let val a = Assembly.A.create_s 1
                    465:                  in  store(a,0,cast s); a
                    466:                 end}
                    467: 
                    468:   fun read(filid, buf) =
                    469:       case Assembly.A.syscall(3,[cast filid, buf, cast(slength buf)],3)
                    470:        of ~1 => syserror "read"
                    471:        | n => n
                    472: 
                    473:   fun filbuf ({closed = ref true,...} : instream) =
                    474:        raise Assembly.SystemCall "closed instream" 
                    475:     | filbuf {filid = ~1,pos,len,...} = (len := 0; pos := 0)
                    476:     | filbuf {filid,pos,buf,len,...} =
                    477:        (pos := 0; len := read(filid,buf))
                    478: 
                    479:   fun write(filid,s,l) = 
                    480:       case Assembly.A.syscall(4,[cast filid, s, cast l],3)
                    481:        of ~1 => syserror "write"
                    482:        | n => n
                    483: 
                    484:   fun write_sure(filid,s,l) =
                    485:       let val k = write(filid,s,l)
                    486:        in if ieql(k,l) then ()
                    487:          else let val subs = PreString.substring
                    488:                   fun f i = if i+k<l 
                    489:                              then (write_sure(filid,subs(s,i,k),k); f(i+k))
                    490:                              else write_sure(filid,subs(s,i,l-i),l-i)
                    491:                in f k
                    492:               end
                    493:       end
                    494: 
                    495:   fun flush_out ({closed = ref true,name,...} : outstream) =
                    496:        raise Io ("flush_out \"" ^ name ^ "\": closed stream")
                    497:     | flush_out {pos = ref 0,...} = ()
                    498:     | flush_out {filid,pos,buf,name,...} =
                    499:        (write_sure(filid,buf,!pos);
                    500:         pos := 0)
                    501:         handle Assembly.SystemCall s =>
                    502:         raise Io("flush_out \"" ^ name ^ "\": " ^ s)
                    503: 
                    504:   val flsbuf = flush_out
                    505: 
                    506:   fun close_in ({closed = ref true,name,...} : instream) =
                    507:        raise Io("close_in \"" ^ name ^ "\": closed stream")
                    508:     | close_in {filid = ~1,closed,len,pos,...} = 
                    509:        (closed := true; len := 0; pos := 1)
                    510:     | close_in {filid,pos,len,closed,name,...} = 
                    511:        (closed := true; len := 0; pos := 1;
                    512:         instreams := List.fold
                    513:                        (fn(s as {pos=p,...}:instream, tl) =>
                    514:                            if ieql(cast pos, cast p) then tl else s::tl)
                    515:                        (!instreams)
                    516:                        nil;
                    517:         close filid handle Assembly.SystemCall s =>
                    518:                              raise Io("close_in \"" ^ name ^ "\": " ^ s))
                    519: 
                    520:   fun close_out ({closed = ref true,name,...} : outstream) =
                    521:        raise(Io("close_out \"" ^ name ^ "\": closed stream"))
                    522:     | close_out (f as {filid,pos,closed,name,...}) = 
                    523:        (flsbuf f; pos := 0; closed := true;
                    524:         outstreams := List.fold
                    525:                        (fn(s as {filid=f,...}:outstream,tl) =>
                    526:                            if ieql(filid,f) then tl else s::tl)
                    527:                        (!outstreams)
                    528:                        nil;
                    529:         close filid)
                    530:         handle Assembly.SystemCall s =>
                    531:                      raise Io("close_out \"" ^ name ^ "\": " ^ s)
                    532: 
                    533:   fun look ({closed = ref true,...} : instream) =
                    534:        raise Assembly.SystemCall "closed stream"
                    535:     | look (f as {len,pos,buf,...}) =
                    536:        if !len > !pos
                    537:        then cast(ordof(buf,!pos))
                    538:        else (filbuf f; if ieql(!len,0) then "" else look f)
                    539: 
                    540:   fun lookahead f = look f handle Assembly.SystemCall s =>
                    541:                            raise Io("lookahead \"" ^ #name f ^ "\": " ^ s)
                    542: 
                    543:   fun end_of_stream ({closed = ref true,name,...} : instream) =
                    544:        raise Io("end_of_stream \"" ^ name ^ "\": closed stream")
                    545:     | end_of_stream f = case look f of "" => true | _ => false
                    546:        handle Assembly.SystemCall s =>
                    547:                 raise Io("end_of_stream \"" ^ #name f ^ "\": " ^ s)
                    548: 
                    549:   fun biginput(filid,k) =   (* k must be larger than 1 *)
                    550:        let val a = Assembly.A.create_s k
                    551:            val len = read(filid,a)
                    552:          in if ieql(len,k) then a
                    553:            else PreString.substring(a,0,len)
                    554:        end
                    555: 
                    556:   local
                    557:     val mtim: int -> int = c_function "mtim"   (* "mtim" gives ~1 on error *)
                    558:   in
                    559:     fun mtime({filid, closed,name, ...}: instream): int =
                    560:       if !closed then
                    561:        raise Io("mtime \"" ^ name ^ "\": closed stream")
                    562:       else
                    563:        let val tim = mtim filid
                    564:        in  if InLine.ieql(tim, ~1) then raise Io("mtime \"" ^ name ^ "\"")
                    565:                                    else tim
                    566:        end
                    567:   end
                    568: 
                    569:   val fionread : int -> int = c_function "fion"
                    570: 
                    571:   fun input(f as {filid,pos,len,buf,closed,name,...} : instream) =
                    572:       let val filbuf = fn f => (filbuf f
                    573:                                handle Assembly.SystemCall s =>
                    574:                                raise Io("input \"" ^ name ^ "\": " ^ s))
                    575:          fun get i =
                    576:              if (!len - !pos) >= i then
                    577:                 if ieql(i,1) then
                    578:                    let val p = !pos
                    579:                     in pos := p+1; cast(ordof(buf,p))
                    580:                    end
                    581:                 else if i < 0 then
                    582:                    raise Io("input \"" ^ name ^ "\": negative character count")
                    583:                 else let val s = substring(buf,!pos,i)
                    584:                       in pos := !pos+i; s
                    585:                      end
                    586:              else if !closed then raise Io("input \"" ^ name ^ "\": closed stream")
                    587:              else let val remaining = !len - !pos
                    588:                       val s = substring(buf,!pos, remaining)
                    589:                       val j = i - remaining
                    590:                       val avail = if filid < 0 then 0
                    591:                                    else if j<=bufsize then j
                    592:                                    else let val c = fionread filid
                    593:                                          in if j<c then j else c
                    594:                                         end
                    595:                   in  if avail >= bufsize
                    596:                       then let val s' = biginput(filid,avail)
                    597:                                handle Assembly.SystemCall s =>
                    598:                                raise Io("input \"" ^ name ^ "\": " ^ s)
                    599:                             in if boxed s'
                    600:                                  then if ieql(slength s',0)
                    601:                                        then s
                    602:                                        else s ^ s' ^ get(j-slength s')
                    603:                                  else s ^ s' ^ get(j-1)
                    604:                            end
                    605:                       else (filbuf f;
                    606:                             if ieql(!len,0) then s
                    607:                             else s ^ get j)
                    608:                   end
                    609:        in get
                    610:       end
                    611: 
                    612:   fun input_line({closed = ref true,name,...} : instream) =
                    613:        raise Io ("input_line \"" ^ name ^ "\": closed stream")
                    614:     | input_line(f as {pos,len,buf,name,...}) =
                    615:        let val l = !len
                    616:            val filbuf = fn f => (filbuf f
                    617:                                  handle Assembly.SystemCall s =>
                    618:                                  raise Io("input_line \"" ^ name ^ "\": " ^ s))
                    619:            fun next j = if ieql(j,l) then
                    620:                            let val s = substring(buf, !pos, l - !pos)
                    621:                             in  filbuf f;
                    622:                                 if ieql(!len,0) then s
                    623:                                 else s ^ input_line f
                    624:                            end
                    625:                         else if ieql(ordof(buf,j),10) then input f (j+1 - !pos)
                    626:                         else next(j+1)
                    627:         in next (!pos)
                    628:        end
                    629: 
                    630:   fun output(f as {filid,buf,pos,tty,closed,name,...} : outstream) =
                    631:       let fun put s =
                    632:              if !closed then raise Assembly.SystemCall "closed outstream"
                    633:              else if boxed s then
                    634:                 let val l = slength s
                    635:                  in if l > 4 * bufsize
                    636:                     then (flsbuf f; write_sure(filid,s,l))
                    637:                                 handle Assembly.SystemCall s =>
                    638:                                  raise Io("output \"" ^ name ^ "\": " ^ s)
                    639:                     else let val i = ref 0
                    640:                           in while !i < l
                    641:                                do let val c = ordof(s,!i)
                    642:                                    in store(buf,!pos,c);
                    643:                                       pos := !pos + 1; i := !i + 1;
                    644:                                       if ieql(!pos,bufsize)
                    645:                                           orelse (!tty andalso ieql(c,10))
                    646:                                       then flsbuf f 
                    647:                                         handle Assembly.SystemCall s =>
                    648:                                          raise Io("output \"" ^ name ^ "\": " ^ s)
                    649:                                       else ()
                    650:                                   end
                    651:                          end
                    652:                 end
                    653:              else (store(buf,!pos,cast s);
                    654:                    pos := !pos + 1;
                    655:                    if ieql(!pos,bufsize)
                    656:                              orelse (!tty andalso ieql(cast s,10))
                    657:                    then flsbuf f 
                    658:                                 handle Assembly.SystemCall s =>
                    659:                                  raise Io("output \"" ^ name ^ "\": " ^ s)
                    660:                    else ())
                    661:        in put
                    662:       end
                    663: 
                    664:   fun can_input ({closed = ref true,name,...} : instream) =
                    665:        raise Io("can_input \"" ^ name ^ "\": closed stream")
                    666:     | can_input {filid = ~1,pos,len,...} = !len - !pos
                    667:     | can_input {filid,pos,len,name,...} =
                    668:        !len - !pos + fionread filid
                    669:              handle Assembly.SystemCall s => raise Io("can_input \"" ^ name ^ "\": " ^ s)
                    670: 
                    671:   local val buf = Assembly.A.create_b 8
                    672:    in fun pipe() =  (* won't work for more than 256 file descriptors! *)
                    673:          (case Assembly.A.syscall(42,[buf],1)
                    674:            of ~1 => syserror "pipe"
                    675:             | _ => if bigEndian then (InLine.ordof(buf,3),InLine.ordof(buf,7))
                    676:                    else (InLine.ordof(buf,0),InLine.ordof(buf,4)))
                    677:   end
                    678: 
                    679:   val exec : (string * int ref * int ref) -> int = c_function "exec"
                    680: 
                    681:   fun execute s =
                    682:       let val fdin=ref 0 and fdout = ref 0
                    683:        in case exec(s^c00,fdin,fdout)
                    684:           of ~1 => raise Io("Cannot execute "^s)
                    685:            | _ => 
                    686:                let val r = {filid = !fdin, pos = ref 0, len = ref 0, 
                    687:                             closed = ref false, name="<pipe_in>",
                    688:                             buf = Assembly.A.create_b bufsize,
                    689:                             tty = ref false}
                    690:                    val w = {filid = !fdout, pos = ref 0, 
                    691:                             closed = ref false, name="<pipe_out>",
                    692:                             buf = Assembly.A.create_b bufsize,
                    693:                             tty = ref false}
                    694:                in  add_in r;
                    695:                    add_out w;
                    696:                    (r,w)
                    697:                end
                    698:      end
                    699: 
                    700:   fun is_term_in ({closed = ref true,name,...} : instream) =
                    701:        raise Io("is_term_in \"" ^ name ^ "\": closed stream")
                    702:     | is_term_in {tty=ref x,...} = x
                    703: 
                    704:   fun is_term_out ({closed = ref true,name,...} : outstream) =
                    705:        raise Io("is_term_out \"" ^ name ^ "\": closed stream")
                    706:     | is_term_out {tty=ref x,...} = x
                    707: 
                    708:   fun set_term_in ({closed = ref true,name,...} : instream,_) =
                    709:        raise Io("set_term_in \"" ^ name ^ "\": closed stream")
                    710:     | set_term_in ({tty,...},t) = tty := t
                    711: 
                    712:   fun set_term_out ({closed = ref true,name,...} : outstream,_) =
                    713:        raise Io("set_term_out \"" ^ name ^ "\": closed stream")
                    714:     | set_term_out ({tty,...},t) = tty := t
                    715: 
                    716:   val expo = c_function "expo"
                    717:   fun exportML filename = 
                    718:       let val filid = openf(filename ^ c00,WRITE)
                    719:              handle Assembly.SystemCall s => raise Io("exportML \"" ^ filename ^ "\": " ^ s)
                    720:       in  List.app flush_out (!outstreams);
                    721:          if expo filid
                    722:          then ((* mark previously opened streams as closed
                    723:                   without flushing them *)
                    724:                List.app (fn {closed,...} : outstream => closed := true)
                    725:                         (!outstreams);
                    726:                List.app (fn {closed,...} : instream => closed := true)
                    727:                         (!instreams);
                    728:                (* restore std_in and std_out *)
                    729:                init_streams();
                    730:                (* reset timing statistics *)
                    731:                PreStats.reset();
                    732:                true)
                    733:          else (close filid; false)
                    734:       end
                    735: 
                    736:   val use_f = Core.Refs.use_f
                    737:   val use_s : (instream -> unit) ref = cast Core.Refs.use_s
                    738:   fun use f = !use_f f
                    739:   fun use_stream s = !use_s s
                    740:   val reduce_r = Core.Refs.reduce_r
                    741:   val reduce : ('a -> 'b) -> ('a -> 'b) = fn x => cast(!reduce_r) x
                    742: 
                    743:   (* close/flush all streams; watch out, some may be damaged. *)
                    744:   fun cleanup () =
                    745:       let fun c_out s = close_out s handle  _ => ()
                    746:          fun c_in s = close_in s handle _ => ()
                    747:       in  List.app c_out (!outstreams);
                    748:          List.app c_in (!instreams)
                    749:       end
                    750: 
                    751:   fun quit _ = (Assembly.A.syscall(1,[cast 0],1); ())
                    752: 
                    753:   fun exportFn (filename,func) = 
                    754:       let val filid=openf(filename ^ c00,WRITE)
                    755:              handle Assembly.SystemCall s => raise Io("exportFn \"" ^ filename ^ "\": " ^ s)
                    756:          val pr = output std_out
                    757:       in  cleanup();
                    758:          use_f := (fn (_ : string) => ());
                    759:          use_s := (fn (_ : instream) => ());
                    760:          reduce_r := (fn (x:unit->unit) => x);
                    761:          Core.Refs.lookup_r := cast(fn ()=>());
                    762:          Core.Refs.compreturn := 
                    763:            [cast(quit, fn e => (pr "uncaught exception ";
                    764:                                 pr (PreLim.exn_name e);
                    765:                                 pr "\n"; cleanup(); quit()))];
                    766:          PreLim.prLambda := (fn () => ());
                    767:          if expo filid
                    768:          then (init_streams();
                    769:                func(PreLim.argv(),PreLim.environ());
                    770:                cleanup();
                    771:                quit())
                    772:               handle exn =>
                    773:                 (pr "uncaught exception ";
                    774:                  pr (PreLim.exn_name exn);
                    775:                  pr "\n";
                    776:                  cleanup())
                    777:          else ()
                    778:       end
                    779: 
                    780:   val blas : int * 'a -> 'a = c_function "blas"
                    781:   val salb : string -> 'a = c_function "salb"
                    782:   fun blast_write((s as {filid,...}) : outstream, obj) = 
                    783:                    (flush_out s; blas(filid,obj); ())
                    784:   fun blast_read f = salb (input f (can_input f))
                    785: 
                    786:  end (* local open ... *)
                    787: end (* structure IOx *)
                    788: 
                    789: abstraction IO : IO = IOx;
                    790: 
                    791: 
                    792: structure Bool : BOOL =
                    793:   struct
                    794:     open PrimTypes (* for datatype bool *)
                    795:     fun not true = false
                    796:       | not false = true
                    797:     fun makestring true = "true"
                    798:       | makestring false = "false"
                    799:     local val pr = IO.output IO.std_out in
                    800:     fun print b = pr(makestring b)
                    801:     end
                    802:   end (* structure Bool *)
                    803: 
                    804: 
                    805: structure String : STRING =
                    806:   struct
                    807:     open PrimTypes InLine
                    808:     infix 4 > < >= <=
                    809:     infix 6 ^
                    810:     type string = string
                    811:     fun length s = if boxed s then slength s else 1
                    812:     val size = length
                    813:     exception Substring = PreString.Substring
                    814:     val substring = PreString.substring
                    815:     fun explode s =
                    816:          if boxed s
                    817:            then let fun f(l,~1) = l
                    818:                       | f(l, i) = f(cast(ordof(s,i)) :: l, i-1)
                    819:                  in f(nil, slength s - 1)
                    820:                 end
                    821:            else [s]
                    822:     val op ^ = PreString.^
                    823:     exception Chr
                    824:     fun chr i = if i<0 orelse i>255 then raise Chr else cast i
                    825:     exception Ord
                    826:     fun ord "" = raise Ord
                    827:       | ord s = if boxed s then ordof(s,0) else cast s
                    828:     val ordof = fn (s,i) =>
                    829:          if boxed s
                    830:             then if i<0 orelse i>= slength s then raise Ord else ordof(s,i)
                    831:            else if ieql(i,0) then cast s else raise Ord
                    832:     val print = IO.output IO.std_out
                    833:     fun implode (sl:string list) =
                    834:          let val len = List.fold(fn(s,l) => length s + l) sl 0
                    835:          in  case len
                    836:               of 0 => ""
                    837:                | 1 => let fun find (""::tl) = find tl
                    838:                             | find (hd::_) = cast hd
                    839:                             | find nil = "" (* impossible *)
                    840:                       in  find sl
                    841:                       end
                    842:                | _ => let val new = Assembly.A.create_s len
                    843:                           fun copy (nil,_) = ()
                    844:                             | copy (s::tl,base) =
                    845:                                let val len = length s
                    846:                                    fun copy0 0 = ()
                    847:                                      | copy0 i =
                    848:                                        let val next = i-1
                    849:                                        in  store(new,base+next,ordof(s,next));
                    850:                                            copy0 next
                    851:                                        end
                    852:                                in  copy0 len;
                    853:                                    copy(tl,base+len)
                    854:                                end
                    855:                        in  copy(sl,0);
                    856:                            new
                    857:                        end
                    858:          end
                    859:     fun sgtr("","") = false
                    860:       | sgtr(_,"") = true
                    861:       | sgtr("",_) = false
                    862:       | sgtr(a,b) =
                    863:        if boxed a
                    864:         then if boxed b
                    865:             then let val al = slength a and bl = slength b
                    866:                      val n = if al<bl then al else bl
                    867:                      fun f i = 
                    868:                          if ieql(i,n) then al > bl
                    869:                          else if ieql(InLine.ordof(a,i),InLine.ordof(b,i)) then f(i+1)
                    870:                          else InLine.ordof(a,i) > InLine.ordof(b,i)
                    871:                   in  f 0
                    872:                  end
                    873:             else InLine.ordof(a,0) >= cast(b)
                    874:        else if boxed b
                    875:             then cast(a) > InLine.ordof(b,0)
                    876:             else cast(a) > cast(b)  
                    877:     fun op <= (a,b) = Bool.not(sgtr(a,b))
                    878:     fun op < (a,b) = sgtr(b,a)
                    879:     fun op >= (a,b) = Bool.not(sgtr(b,a))
                    880:     val op > = sgtr
                    881:   end  (* structure String *)
                    882: 
                    883: structure System : SYSTEM =
                    884:   struct
                    885:     structure ByteArray : BYTEARRAY = ByteArray
                    886:     structure Control : CONTROL =
                    887:       struct
                    888:        structure Runtime : RUNTIMECONTROL = Assembly
                    889:         structure MC : MCCONTROL =
                    890:          struct
                    891:             val printArgs = Core.Refs.printArgs
                    892:             val printRet = Core.Refs.printRet
                    893:             val bindContainsVar = Core.Refs.bindContainsVar
                    894:             val bindExhaustive = Core.Refs.bindExhaustive
                    895:             val matchExhaustive = Core.Refs.matchExhaustive
                    896:             val matchRedundant = Core.Refs.matchRedundant
                    897:            val expandResult = Core.Refs.expandResult
                    898:           end
                    899:         structure CG : CGCONTROL =
                    900:          struct
                    901:            structure M68 =
                    902:              struct
                    903:                val trapv = Core.Refs.trapv
                    904:              end
                    905:             val tailrecur = Core.Refs.tailrecur
                    906:             val recordopt = Core.Refs.recordopt
                    907:             val tail = Core.Refs.tail
                    908:             val profile = Core.Refs.profile
                    909:             val closureprint = Core.Refs.closureprint
                    910:             val closureStrategy = Core.Refs.closureStrategy
                    911:            val rounds = Core.Refs.rounds
                    912:            val path = Core.Refs.path
                    913:             val hoist = Core.Refs.hoist
                    914:             val reduce = Core.Refs.reduce
                    915:            val bodysize = Core.Refs.bodysize
                    916:            val reducemore = Core.Refs.reducemore
                    917:            val alphac = Core.Refs.alphac
                    918:            val comment = Core.Refs.comment
                    919:            val knowngen = Core.Refs.knowngen
                    920:            val stdgen = Core.Refs.stdgen
                    921:            val knowncl = Core.Refs.knowncl
                    922:            val foldconst = Core.Refs.foldconst
                    923:            val etasplit = Core.Refs.etasplit
                    924:            val printit = Core.Refs.printit
                    925:            val printsize = Core.Refs.printsize
                    926:            val scheduling = Core.Refs.scheduling
                    927:           end
                    928:        structure Print : PRINTCONTROL =
                    929:          struct
                    930:            val printDepth = Core.Refs.printDepth
                    931:            val stringDepth = Core.Refs.stringDepth
                    932:            val signatures = Core.Refs.signatures
                    933:          end
                    934:         structure ProfileInternals : PROFILEINTERNALS =
                    935:          struct
                    936:             structure ByteArray = ByteArray
                    937:            open InLine
                    938:            val other : ByteArray.bytearray = cast(Core.other)
                    939:            val toplevel : ByteArray.bytearray = cast(Core.toplevel)
                    940:            val gc : ByteArray.bytearray = cast(Core.gc)
                    941:            val globalProfile : ByteArray.bytearray list ref
                    942:                        = InLine.cast Core.Refs.globalProfile
                    943: 
                    944:            fun setToplevel () = 
                    945:                cast(Assembly.current) := toplevel
                    946: 
                    947:            fun setOther () = 
                    948:                cast(Assembly.current) := other
                    949: 
                    950:            fun listofarray a =
                    951:                let fun loop(~1,x) = x
                    952:                      | loop(i,x) = loop(i-1, InLine.subscript(a,i) :: x)
                    953:                in loop(InLine.alength a - 1, nil)
                    954:                end
                    955: 
                    956:             fun zeroCount e = (InLine.update(cast e,0,0);
                    957:                               InLine.update(cast e,1,0))
                    958: 
                    959:            val timerval = if bigEndian then "\000\000\000\000\
                    960:                                             \\000\000\039\016\
                    961:                                             \\000\000\000\000\
                    962:                                             \\000\000\039\016"
                    963:                                        else "\000\000\000\000\
                    964:                                             \\016\039\000\000\
                    965:                                             \\000\000\000\000\
                    966:                                             \\016\039\000\000"
                    967:            val timerval0 = "\000\000\000\000\000\000\000\000\
                    968:                            \\000\000\000\000\000\000\000\000"
                    969: 
                    970:            fun setitimer t = 
                    971:               case Assembly.A.syscall(83,[cast 1,t,cast 0],3)
                    972:                of ~1 => syserror "setitimer"
                    973:                 | x => x
                    974: 
                    975:            fun copy(ba,str) =
                    976:                let val len = slength str
                    977:                    fun loop i = 
                    978:                        if ieql(i,len)
                    979:                        then ()
                    980:                        else (ByteArray.update(ba,i,ordof(str,i)); loop(i+1))
                    981:                 in loop 0
                    982:                end
                    983: 
                    984:            val _ = copy(other,   "aaaaaaaa(unprofiled)")
                    985:            val _ = copy(toplevel,"aaaaaaaa(toplevel)")
                    986:            val _ = copy(gc,      "aaaaaaaa(gc)")
                    987: 
                    988:            fun add profile =
                    989:                if boxed profile
                    990:                then let val entries = listofarray profile
                    991:                      in List.app zeroCount entries;
                    992:                         globalProfile := List.@(entries,!globalProfile)
                    993:                     end
                    994:                else ()
                    995: 
                    996:            fun extractInt(ba,start,len) =
                    997:                !(cast(ByteArray.extract(ba,start,len)):int ref)
                    998: 
                    999:            fun trans ba =
                   1000:                (extractInt(ba,0,4), extractInt(ba,4,4),
                   1001:                 ByteArray.extract(ba,8,ByteArray.length ba - 8))
                   1002: 
                   1003:            local fun insert (a,nil) = [a]
                   1004:                    | insert (a0 as (a',a,_),l as (x0 as (x',x,_))::y) =
                   1005:                       if a<x orelse ieql(a,x) andalso a'<x'
                   1006:                         then x0::insert(a0,y)  else a0::l
                   1007:              in  fun sort nil = nil
                   1008:                    | sort (a::b) = insert(a,sort b)
                   1009:              end
                   1010: 
                   1011: 
                   1012:            fun field (st,w) = 
                   1013:                let val s = PreString.^("                    ", st)
                   1014:                 in PreString.substring(s,String.length s - w, w)
                   1015:                end
                   1016: 
                   1017:            fun decimal(st,w) =
                   1018:              PreString.^(PreString.^(
                   1019:                                (PreString.substring(st,0,String.length st - w)
                   1020:                                  handle PreString.Substring => "")
                   1021:                                ,"."),
                   1022:                    let val st' = PreString.^("0000000000",st)
                   1023:                     in PreString.substring(st',String.length st' - w,w)
                   1024:                    end)
                   1025: 
                   1026:            fun muldiv(i,j,k) =
                   1027:                (i*j div k) 
                   1028:                   handle Assembly.Overflow => muldiv(i,j div 2, k div 2)
                   1029: 
                   1030:            fun decfield(n,j,k,w1,w2) = 
                   1031:                field(decimal(PreString.imakestring (muldiv(n,j,k)),w1)
                   1032:                        handle Assembly.Div => "",w2)
                   1033: 
                   1034:            fun printReport f l = 
                   1035:              let val l' as (_,_,_,ticks)::_
                   1036:                    = List.fold (fn((n,m,s),l as (_,_,_,cum)::_)=>(n,m,s,m+cum)::l
                   1037:                                  |((n,m,s),nil)=>[(n,m,s,m)]) (sort l) nil
                   1038:                  val pr = IO.output f
                   1039:              in pr(field("%time",6));
                   1040:                 pr(field("cumsecs",9));
                   1041:                 pr(field("#call",10));
                   1042:                 pr(field("ms/call",10));
                   1043:                 pr("  name\n");
                   1044:                 List.app (fn (n,m,s,cumm) =>
                   1045:                            (pr(decfield(m,10000,ticks,2,6));
                   1046:                             pr(decfield((ticks-cumm+m),2,1,2,9));
                   1047:                             pr(field(PreString.imakestring n,10));
                   1048:                             pr(decfield(m,50000,n,4,10));
                   1049:                             pr "  "; pr s; pr "\n"))
                   1050:                          l';
                   1051:                 ()
                   1052:               end
                   1053: 
                   1054:            structure P =
                   1055:             struct
                   1056:               structure IO = IO
                   1057:               val profiling = Core.Refs.profiling
                   1058:               fun profileOn () = (setitimer timerval; ())
                   1059:               fun profileOff () = (setitimer timerval0; ())
                   1060:               fun reset () = List.app zeroCount (!globalProfile)
                   1061:               fun clear () = (globalProfile := [toplevel,gc,other]; reset())
                   1062:               fun report f =
                   1063:                   printReport f (List.map trans (!globalProfile))
                   1064:               val _ = clear()
                   1065:              end
                   1066:            val add = InLine.cast add
                   1067:          end (* structure ProfileInternals *)
                   1068:         structure Profile = ProfileInternals.P
                   1069:         structure Debug : DEBUG =
                   1070:           struct
                   1071:            val debugging = Core.Refs.debug1
                   1072:            val getDebugf = InLine.cast Core.Refs.getDebugf
                   1073:            val interface = InLine.cast Core.Refs.debugInterface
                   1074:           end
                   1075:        val prLambda = PreLim.prLambda
                   1076:         val debugging = Core.Refs.debugging
                   1077:         val primaryPrompt = Core.Refs.primaryPrompt
                   1078:         val secondaryPrompt = Core.Refs.secondaryPrompt
                   1079:         val internals = Core.Refs.internals
                   1080:        val weakUnderscore = Core.Refs.weakUnderscore
                   1081:         val interp = Core.Refs.interp
                   1082:         val debugLook = Core.Refs.debugLook
                   1083:         val debugCollect = Core.Refs.debugCollect
                   1084:         val debugBind = Core.Refs.debugBind
                   1085:        val saveLambda = Core.Refs.saveLambda
                   1086:        val saveLvarNames = Core.Refs.saveLvarNames
                   1087:        val timings = Core.Refs.timings
                   1088:         val reopen = Core.Refs.reopen
                   1089:       end (* structure Control *)
                   1090:     structure Tags : TAGS = (* taken from runtime/tags.h *)
                   1091:       struct
                   1092:        val width_tags = 4
                   1093:        val power_tags = 16
                   1094:        val tag_record =        1
                   1095:        val tag_array = 9
                   1096:        val tag_bytearray =     11
                   1097:        val tag_string =        15
                   1098:        val tag_embedded =      7
                   1099:        val tag_suspension =    13
                   1100:        val tag_backptr =       5
                   1101:        val tag_forwarded =     3
                   1102:       end (* structure Tags *)
                   1103:     structure Timer : TIMER =
                   1104:       struct
                   1105:        structure P : sig datatype time = TIME of {sec : int, usec : int} end
                   1106:                 = PreStats
                   1107:        open P
                   1108:        open InLine PreString
                   1109:        type timer = time * time
                   1110:         val gettime : int ref * int ref * int ref * int ref -> unit
                   1111:                    = c_function "time"
                   1112:         fun timer() =
                   1113:         let val gu = ref 0 and gs = ref 0 and tu = ref 0 and ts = ref 0
                   1114:           in gettime(gu,gs,tu,ts);
                   1115:              (TIME{sec= !ts, usec = !tu},TIME{sec= !gs, usec = !gu})
                   1116:          end
                   1117:            
                   1118:        val start_timer = timer
                   1119:        fun delta(s2,u2,s1,u1) =
                   1120:              let val (sec,usec) = (s2-s1,u2-u1)
                   1121:                  val (sec,usec) = if usec < 0
                   1122:                                     then (sec-1,usec+1000000)
                   1123:                                     else (sec,usec)
                   1124:              in  (sec,usec)
                   1125:              end
                   1126:        fun check_timer (TIME{sec=start_s,usec=start_u},
                   1127:                         TIME{sec=gstart_s,usec=gstart_u}) =
                   1128:              let val (TIME{sec=curr_s,usec=curr_u},
                   1129:                       TIME{sec=gcurr_s,usec=gcurr_u}) = timer()
                   1130:                  val (sec,usec) = delta(curr_s,curr_u,start_s,start_u)
                   1131:                  val (g_sec,g_usec) = delta(gcurr_s,gcurr_u,gstart_s,gstart_u)
                   1132:                  val (sec,usec) = delta(sec,usec,g_sec,g_usec)
                   1133:              in  TIME{sec=sec,usec=usec}
                   1134:              end
                   1135:        fun check_timer_gc (TIME{sec=start_s,usec=start_u},
                   1136:                         TIME{sec=gstart_s,usec=gstart_u}) =
                   1137:              let val (TIME{sec=curr_s,usec=curr_u},
                   1138:                       TIME{sec=gcurr_s,usec=gcurr_u}) = timer()
                   1139:                  val (g_sec,g_usec) = delta(gcurr_s,gcurr_u,gstart_s,gstart_u)
                   1140:              in  TIME{sec=g_sec,usec=g_usec}
                   1141:              end
                   1142:        fun makestring(TIME{sec,usec}) =
                   1143:              let val filler = if usec <= 0 then ""
                   1144:                               else if usec < 10 then "00000"
                   1145:                               else if usec < 100 then "0000"
                   1146:                               else if usec < 1000 then "000"
                   1147:                               else if usec < 10000 then "00"
                   1148:                               else if usec < 100000 then "0"
                   1149:                               else ""
                   1150:              in  imakestring sec ^ "." ^ filler ^ imakestring usec
                   1151:              end
                   1152:        fun add_time(TIME{sec=s0,usec=u0},TIME{sec=s1,usec=u1}) =
                   1153:              let val (s,u) = (s0+s1,u0+u1)
                   1154:                  val (s,u) = if u > 1000000 then (s+1,u-1000000)
                   1155:                              else (s,u)
                   1156:              in  TIME{sec=s,usec=u}
                   1157:              end
                   1158:       end (* structure Timer *)
                   1159:     structure Stats : STATS =
                   1160:       struct
                   1161:        open Timer Ref PreStats Control.Runtime PreString
                   1162:        fun update(a,b) = a := add_time(!a,b)
                   1163:        fun summary() =
                   1164:              let val pr = IO.output IO.std_out
                   1165:                  val (total,garbagetime) = start_timer()
                   1166:              in  pr (imakestring(!lines));
                   1167:                  pr " lines\n";
                   1168:                  pr "parse, "; pr(makestring(!parse)); pr "s\n";
                   1169:                  pr "translate, "; pr(makestring(!translate)); pr "s\n";
                   1170:                  pr "codeopt, "; pr(makestring(!codeopt)); pr "s\n";
                   1171:                  pr "convert, "; pr(makestring(!convert)); pr "s\n";
                   1172:                  pr "cpsopt, "; pr(makestring(!cpsopt)); pr "s\n";
                   1173:                  pr "closure, "; pr(makestring(!closure)); pr "s\n";
                   1174:                  pr "globalfix, "; pr(makestring(!globalfix)); pr "s\n";
                   1175:                  pr "spill, "; pr(makestring(!spill)); pr "s\n";
                   1176:                  pr "codegen, "; pr(makestring(!codegen)); pr "s\n";
                   1177:                  pr "freemap, "; pr(makestring(!freemap)); pr "s\n";
                   1178:                  pr "execution, "; pr(makestring(!execution)); pr "s\n";
                   1179:                  pr "garbagetime, "; pr(makestring garbagetime); pr "s\n";
                   1180:                  pr "total "; pr(makestring total); pr "s\n";
                   1181:                  pr "collections: "; pr(imakestring(!minorcollections));
                   1182:                  pr " minor, "; pr(imakestring(!majorcollections));
                   1183:                  pr " major\n"; pr(imakestring(!collected));
                   1184:                  pr " collected from "; pr(imakestring(!collectedfrom));
                   1185:                  pr " possible (";
                   1186:                  case !collectedfrom of
                   1187:                    0 => ()
                   1188:                  | _ => pr(imakestring(InLine.div(InLine.*(!collected,100),
                   1189:                                            !collectedfrom)));
                   1190:                  pr "%)\n";
                   1191:                  ()
                   1192:              end
                   1193:        abstraction Timer : TIMER = Timer
                   1194:       end (* structure Stats *)
                   1195:     abstraction Timer : TIMER = Timer (* to hide timer datatype *)
                   1196: 
                   1197:     structure Unsafe : UNSAFE =
                   1198:       struct
                   1199:         structure Assembly : ASSEMBLY = Assembly
                   1200:         type object = Assembly.object
                   1201:         val boxed=InLine.cast()
                   1202:         val ordof=InLine.cast()
                   1203:         val slength=InLine.cast()
                   1204:         val store=InLine.cast()
                   1205:         val subscript=InLine.cast()
                   1206:         val update=InLine.cast()
                   1207:        val delay= InLine.cast()
                   1208:        val force = InLine.cast()
                   1209:        fun boot (x: string) : 'a -> 'b = 
                   1210:            InLine.cast(InLine.+(InLine.cast x, 4),0)
                   1211:        val cast = InLine.cast
                   1212:        val syscall = Assembly.A.syscall
                   1213:        val blast_write = cast IOx.blast_write
                   1214:        val blast_read = cast IOx.blast_read
                   1215:        val create_s = Assembly.A.create_s
                   1216:        val store_s : string * int * int -> unit
                   1217:                        = InLine.cast ByteArray.update
                   1218:        val lookup_r : (int->object) ref= cast Core.Refs.lookup_r
                   1219:         val lookup = fn i => case lookup_r of ref f => f i
                   1220: 
                   1221:         val do_it =
                   1222:          InLine.callcc(fn c0 => 
                   1223:           let val v = 
                   1224:                InLine.callcc(fn c => InLine.throw c0 (InLine.throw c)) ()
                   1225:                handle e =>
                   1226:                     let val ref(op ::((k,h),r)) = cast Core.Refs.compreturn
                   1227:                      in InLine.:=(Core.Refs.compreturn, cast r); h e
                   1228:                     end
                   1229:               val ref(op ::((k,h),r)) = cast Core.Refs.compreturn
                   1230:            in InLine.:=(Core.Refs.compreturn, cast r); k v
                   1231:           end)
                   1232: 
                   1233:         fun isolate f = InLine.callcc(fn c => 
                   1234:                raise(InLine.callcc(fn c' =>
                   1235:                (InLine.:=(cast Core.Refs.compreturn,
                   1236:                 op ::( (InLine.throw c, InLine.throw c'),
                   1237:                         cast(InLine.! Core.Refs.compreturn))); do_it f))))
                   1238: 
                   1239:        val pstruct = cast Core.Refs.pstruct
                   1240:        local
                   1241:            datatype A = unboxed | boxed of object
                   1242:            val cast = InLine.cast
                   1243:        in  exception Boxity
                   1244:            val tuple : object -> object array
                   1245:                        = cast(fn unboxed => raise Boxity
                   1246:                                | x as boxed _ => x)
                   1247:            val string : object -> string = cast (fn x=>x)
                   1248:            val real : object -> real = cast (fn x=>x)
                   1249:            val int : object -> int
                   1250:                        = cast(fn x as unboxed => x
                   1251:                                | boxed _ => raise Boxity)
                   1252:        end (* local datatype A ... *)
                   1253:        structure AA : sig
                   1254:          datatype datalist = DATANIL | DATACONS of (string * string * datalist)
                   1255:          val datalist : datalist
                   1256:        end = Assembly
                   1257:        open AA
                   1258:       end (* Unsafe *)
                   1259: 
                   1260:     open PreLim
                   1261:     val version = "Standard ML of New Jersey, Version 0.44, 4 December 1989"
                   1262:     val cleanup = IO.cleanup
                   1263:     val c00 = "\000\000"
                   1264:     val syst = c_function "syst"
                   1265:     fun system x =
                   1266:        case syst(PreString.^(x,c00))
                   1267:         of 0 => ()
                   1268:          | _ => raise Assembly.SystemCall "system"
                   1269:     fun cd s =
                   1270:        case Unsafe.syscall(12,[PreString.^(s,c00)],1)
                   1271:         of ~1 => syserror "chdir"
                   1272:          | _ => ()
                   1273: 
                   1274:   end (* structure System *)
                   1275: 
                   1276: end (* structure Inside *)
                   1277: 
                   1278: open Inside PrimTypes
                   1279: 
                   1280: (* The following structures must be without signatures so that inlining 
                   1281:    can take place *)
                   1282: 
                   1283: structure General =
                   1284:   struct
                   1285:     infix 3 o
                   1286:     infix before
                   1287:     exception Bind = Core.Bind
                   1288:     exception Match = Core.Match
                   1289:     exception Interrupt = Core.Assembly.Interrupt
                   1290:     exception SystemCall = Core.Assembly.SystemCall
                   1291: 
                   1292:     val callcc : ('a cont -> 'a) -> 'a = InLine.callcc
                   1293:     val throw : 'a cont -> 'a -> 'b = InLine.throw
                   1294:     fun f o g = fn x => f(g x)
                   1295:     fun a before b = a
                   1296:     datatype 'a option = NONE | SOME of 'a
                   1297:     type 'a cont = 'a cont
                   1298:     type exn = exn
                   1299:     type unit = unit
                   1300:     infix 4 = <>
                   1301:     val op = : ''a * ''a -> bool  = InLine.=
                   1302:     val op <> : ''a * ''a -> bool = InLine.<>
                   1303:   end (* structure General *)
                   1304: 
                   1305: structure Bits =
                   1306:   struct
                   1307:     val andb : int * int -> int = InLine.andb
                   1308:     val orb : int * int -> int = InLine.orb
                   1309:     val lshift : int * int -> int = InLine.lshift
                   1310:     val rshift : int * int -> int = InLine.rshift
                   1311:     val notb : int -> int = InLine.notb
                   1312:     val xorb : int * int -> int = InLine.xorb
                   1313:   end
                   1314: 
                   1315: structure Ref = 
                   1316:   struct
                   1317:     infix 3 :=
                   1318:     val ! : 'a ref -> 'a = InLine.!
                   1319:     val op := : 'a ref * 'a -> unit = InLine.:=
                   1320:     fun inc r = r := (InLine.+ : int * int -> int) (!r,1)
                   1321:     fun dec r = r := (InLine.- : int * int -> int) (!r,1)
                   1322:   end
                   1323: 
                   1324: structure Array =
                   1325:   struct
                   1326:    local open InLine in
                   1327:     infix 3 sub
                   1328:     type 'a array = 'a array
                   1329:     exception Subscript
                   1330:     val array : int * '1a -> '1a array =
                   1331:          fn arg as (n,v) =>
                   1332:             if <=(n,0) then if <(n,0) then raise Subscript
                   1333:                             else Core.Assembly.array0
                   1334:             else Core.Assembly.A.array arg
                   1335:     val op sub : 'a array * int -> 'a =
                   1336:          fn (a,i) =>
                   1337:             if <(i,0) orelse >=(i,alength a) then raise Subscript
                   1338:             else subscript(a,i)
                   1339:     val length : 'a array -> int = alength
                   1340:     fun arrayoflist nil = Core.Assembly.array0
                   1341:       | arrayoflist (l as (e::r)) =
                   1342:          let val a = array(List.length l, e)
                   1343:              fun init ((e::r),n) = (update(a,n,e); init(r,+(n,1)))
                   1344:                | init (nil,_) = ()
                   1345:          in  init(r,1); a
                   1346:           end
                   1347:     val update : 'a array * int * 'a -> unit =
                   1348:          fn (a,i,v) => 
                   1349:             if <(i,0) orelse >=(i,alength a) then raise Subscript
                   1350:             else update(a,i,v)
                   1351:    end (* local open ... *)
                   1352:   end (* structure Array *)
                   1353: 
                   1354: structure Integer =
                   1355:   struct
                   1356:     infix 7 * div mod
                   1357:     infix 6 + -
                   1358:     infix 4 > < >= <=
                   1359:     exception Div = Core.Assembly.Div
                   1360:     exception Overflow = Core.Assembly.Overflow
                   1361:     type int = int
                   1362:     val ~ : int -> int = InLine.~
                   1363:     val op * : int * int -> int = InLine.*
                   1364:     val op div : int * int -> int = InLine.div
                   1365:     fun op mod(a:int,b:int):int = InLine.-(a,InLine.*(InLine.div(a,b),b))
                   1366:     val op + : int * int -> int = InLine.+
                   1367:     val op - : int * int -> int = InLine.-
                   1368:     val op > : int * int -> bool = InLine.>
                   1369:     val op >= : int * int -> bool = InLine.>=
                   1370:     val op < : int * int -> bool = InLine.<
                   1371:     val op <= : int * int -> bool = InLine.<=
                   1372:     fun min(a,b) = if a<b then a else b
                   1373:     fun max(a,b) = if a>b then a else b
                   1374:     fun abs a = if a<0 then ~a else a
                   1375:     fun makestring i =
                   1376:          if i<0 then String.^("~", makestring(~i))
                   1377:          else if i<10 then InLine.cast(InLine.cast "0" + i)
                   1378:          else let val j = i div 10
                   1379:               in  String.^(makestring j, makestring(i-j*10))
                   1380:               end
                   1381:     local val pr = IO.output IO.std_out in
                   1382:     fun print i = pr(makestring i)
                   1383:     end
                   1384:   end  (* structure Integer *)
                   1385: 
                   1386: structure Real =
                   1387:   struct
                   1388:    local 
                   1389:     open Math String
                   1390:     val negone = ~1.0
                   1391:     val zero = 0.0
                   1392:     val half = 0.5
                   1393:     val one = 1.0
                   1394:     val two = 2.0
                   1395:     val five = 5.0
                   1396:     val ten = 10.0
                   1397:    in
                   1398:     infix 7 * /
                   1399:     infix 6 + -
                   1400:     infix 4 > < >= <=
                   1401:     type real = real
                   1402:     exception Real = Core.Assembly.Real
                   1403:     exception Float = Real
                   1404:     val ~ : real -> real = InLine.fneg
                   1405:     val op + : real * real -> real = InLine.fadd
                   1406:     val op - : real * real -> real = InLine.fsub
                   1407:     val op * : real * real -> real = InLine.fmul
                   1408:     val op / : real * real -> real = InLine.fdiv
                   1409:     val op > : real * real -> bool = InLine.fgt
                   1410:     val op < : real * real -> bool = InLine.flt
                   1411:     val op >= : real * real -> bool = InLine.fge
                   1412:     val op <= : real * real -> bool = InLine.fle
                   1413:     val sin = sin and cos = cos and sqrt = sqrt and arctan = arctan
                   1414:     and exp = exp and ln = ln
                   1415:     exception Sqrt = Sqrt and Exp = Exp and Ln = Ln
                   1416:     exception Floor
                   1417:     local
                   1418:       fun rtoi (pred,init) =
                   1419:          let fun loop n =
                   1420:              if pred n
                   1421:              then init
                   1422:              else let val (i,r) = loop(n * half)
                   1423:                       val i' = InLine.lshift(i,1)
                   1424:                       val r' = r+r
                   1425:                   in if n-r' < one then (i',r') else (InLine.+(i',1),r'+one)
                   1426:                   end
                   1427:           in loop
                   1428:          end
                   1429:       val pton = rtoi(fn x => x < one, (0,zero))
                   1430:       val nton = rtoi(fn x => x >= negone, (~1,negone))
                   1431:       fun fl n = if n < zero then nton n else pton n
                   1432:       fun tr n = #1(pton n)
                   1433:     in 
                   1434:       fun truncate n = if n < zero then InLine.~(tr(~n)) else tr n
                   1435:       fun realfloor n = #2(fl n)
                   1436:       fun floor n = Core.Assembly.A.floor n handle Integer.Overflow => raise Floor
                   1437:       fun ceiling n : int = InLine.~(floor(~n))
                   1438:     end
                   1439:     fun abs x = if x < zero then ~x else x
                   1440:     local
                   1441:       fun loop 0 = zero
                   1442:        | loop n = let val x = two * loop(InLine.rshift(n,1))
                   1443:                    in case InLine.andb(n,1) of 0 => x | 1 => x + one
                   1444:                   end
                   1445:     in
                   1446:       fun real n = if InLine.<(n,0) then ~(loop(InLine.~ n)) else loop n
                   1447:     end
                   1448:     fun makestring r =
                   1449:          let val itoa = Integer.makestring
                   1450:              fun scistr(a::b::tl,e) =
                   1451:                    let fun trail nil = ""
                   1452:                          | trail (0::tl) =
                   1453:                            let val rest = trail tl
                   1454:                            in  case rest of "" => ""
                   1455:                                           | _ => "0"^rest
                   1456:                            end
                   1457:                          | trail (hd::tl) = itoa hd ^ trail tl
                   1458:                        val rest = trail tl
                   1459:                    in  itoa a ^ "." ^ itoa b ^ rest ^ "E" ^ itoa e
                   1460:                    end
                   1461:                | scistr _ = "" (* prevents non-exhaustive match *)
                   1462:              fun normstr(digits,e) =
                   1463:                    let fun n(nil,_) = ""
                   1464:                          | n(hd::nil,0) = itoa hd ^ ".0"
                   1465:                          | n(hd::tl,0) = itoa hd ^ "." ^ n(tl,~1)
                   1466:                          | n(0::tl,d) =
                   1467:                              let val rest = n(tl,InLine.-(d,1))
                   1468:                              in  case (InLine.<(d,~1),rest) of
                   1469:                                    (true,"") => rest
                   1470:                                    | _ => "0" ^ rest
                   1471:                              end
                   1472:                          | n(hd::tl,d) = itoa hd ^ n(tl,InLine.-(d,1))
                   1473:                        fun header n =
                   1474:                          let fun zeros 1 = ""
                   1475:                                | zeros n = "0" ^ zeros(InLine.-(n,1))
                   1476:                          in  "0." ^ zeros n
                   1477:                          end
                   1478:                    in  if InLine.<(e,0)
                   1479:                        then header(InLine.~ e) ^ n(digits,e)
                   1480:                        else n(digits,e)
                   1481:                    end
                   1482:              fun mkdigits(f,0) = (nil,if f < five then 0 else 1)
                   1483:                | mkdigits(f,i) =
                   1484:                    let val digit = floor f
                   1485:                        val new = ten * (f - real digit)
                   1486:                        val (digits,carry) = mkdigits(new,InLine.-(i,1))
                   1487:                        val (digit,carry) = case (digit,carry) of
                   1488:                                         (9,1) => (0,1)
                   1489:                                        | _ => (InLine.+(digit,carry),0)
                   1490:                    in  (digit::digits,carry)
                   1491:                    end
                   1492:              (* should eventually speed this up by using log10 *)
                   1493:              fun mkstr(f,e) =
                   1494:                  if f >= ten then mkstr(f/ten,InLine.+(e,1))
                   1495:                  else if f < one then mkstr(f*ten,InLine.-(e,1))
                   1496:                  else let val (digits,carry) = mkdigits(f,15)
                   1497:                           val (digits,e) = case carry of
                   1498:                                              0 => (digits,e)
                   1499:                                            | _ => (1::digits,InLine.+(e,1))
                   1500:                       in  if InLine.>(e,~5) andalso InLine.<(e,15)
                   1501:                           then normstr(digits,e)
                   1502:                           else scistr(digits,e)
                   1503:                       end
                   1504:          in  if r < zero then "~" ^ mkstr(~r,0)
                   1505:              else if InLine.feql(r,zero) then "0.0"
                   1506:              else mkstr(r,0)
                   1507:          end (* fun makestring *)
                   1508:     local
                   1509:       val pr = IO.output IO.std_out
                   1510:     in
                   1511:       fun print r = pr(makestring r)
                   1512:     end
                   1513:    end (* local *)
                   1514:   end (* structure Real *)
                   1515: 
                   1516:   structure System =
                   1517:   struct open System
                   1518:          structure Unsafe =
                   1519:         struct open Unsafe
                   1520:                val cast : 'a -> 'b = InLine.cast
                   1521:                val boxed : 'a -> bool = InLine.boxed
                   1522:                val ordof : string * int -> int = InLine.ordof
                   1523:                val slength : string -> int = InLine.slength
                   1524:                val store : string * int * int -> unit = InLine.store
                   1525:                val subscript : 'a array * int -> 'a = InLine.subscript
                   1526:                val update : 'a array * int * 'a -> unit = InLine.update
                   1527:                val delay : int * 'a -> 'a = InLine.delay
                   1528:                val force : 'a -> 'a = InLine.force
                   1529:         end
                   1530:   end
                   1531:        
                   1532:   open Array Ref String IO Bool List Integer Real General
                   1533: 
                   1534:   val _ = IO.output IO.std_out "Initial done\n"
                   1535: 
                   1536: end (* structure Initial *)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.