(***********************************************************************) (* *) (* Applied Type System *) (* *) (***********************************************************************) (* ** ATS/Postiats - Unleashing the Potential of Types! ** Copyright (C) 2011-2013 Hongwei Xi, ATS Trustful Software, Inc. ** All rights reserved ** ** ATS is free software; you can redistribute it and/or modify it under ** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the ** Free Software Foundation; either version 3, or (at your option) any ** later version. ** ** ATS is distributed in the hope that it will be useful, but WITHOUT ANY ** WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ** for more details. ** ** You should have received a copy of the GNU General Public License ** along with ATS; see the file COPYING. If not, please write to the ** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301, USA. *) (* ****** ****** *) // // Author: Hongwei Xi // Authoremail: gmhwxi AT gmail DOT com // Start Time: July, 2012 // (* ****** ****** *) // staload ATSPRE = "./pats_atspre.dats" // (* ****** ****** *) staload "./pats_basics.sats" (* ****** ****** *) staload SYM = "./pats_symbol.sats" (* ****** ****** *) staload "./pats_staexp2.sats" staload "./pats_staexp2_util.sats" (* ****** ****** *) staload S2C = "./pats_stacst2.sats" (* ****** ****** *) staload "./pats_histaexp.sats" (* ****** ****** *) // #define ATSTYPE_BOXED "atstype_boxed" #define ATSTYPE_UNBOXED "atstype_unboxed" #define ATSTYPE_UNDEFINED "atstype_undefined" // (* ****** ****** *) // val HITNAM_BOXED = HITNAM(1(*ptr*), 1(*fin*), ATSTYPE_BOXED) // val HITNAM_UNBOXED = HITNAM(0(*non*), 1(*fin*), ATSTYPE_UNBOXED) // val HITNAM_UNDEFINED = HITNAM(0(*non*), 1(*fin*), ATSTYPE_UNDEFINED) // (* ****** ****** *) // val HITNAM_FUNPTR = HITNAM(1(*ptr*), 1(*fin*), "atstype_funptr") val HITNAM_CLOPTR = HITNAM(1(*ptr*), 1(*fin*), "atstype_cloptr") val HITNAM_CLOTYP = HITNAM(0(*non*), 1(*fin*), "atstype_clotyp") // val HITNAM_ARRPTR = HITNAM(1(*ptr*), 1(*fin*), "atstype_arrptr") // val HITNAM_DATCONPTR = HITNAM(1(*ptr*), 1(*fin*), "atstype_datconptr") val HITNAM_DATCONTYP = HITNAM(1(*ptr*), 1(*fin*), "atstype_datcontyp") // val HITNAM_EXNCONPTR = HITNAM(1(*ptr*), 1(*fin*), "atstype_exnconptr") // (* ****** ****** *) // #define POSTIATS_TYABS "postiats_tyabs" #define POSTIATS_TYPTR "postiats_typtr" // val HITNAM_TYABS = HITNAM(0(*non*), 0(*fin*), POSTIATS_TYABS) val HITNAM_TYPTR = HITNAM(1(*ptr*), 1(*fin*), POSTIATS_TYPTR) // val HITNAM_TYAPP = HITNAM(0(*non*), 0(*tmp*), "postiats_tyapp") val HITNAM_TYCLO = HITNAM(0(*non*), 0(*tmp*), "postiats_tyclo") // val HITNAM_TYARR = HITNAM(0(*non*), 0(*tmp*), "postiats_tyarr") val HITNAM_TYREC = HITNAM(0(*non*), 0(*tmp*), "postiats_tyrec") val HITNAM_TYRECSIN = HITNAM(0(*non*), 0(*tmp*), "postiats_tyrecsin") val HITNAM_TYSUM = HITNAM(0(*non*), 0(*tmp*), "postiats_tysum") // val HITNAM_TYVAR = HITNAM(0(*non*), 0(*tmp*), "postiats_tyvar") val HITNAM_TYVARET = HITNAM(0(*non*), 0(*tmp*), "postiats_tyvaret") // val HITNAM_VARARG = HITNAM(0(*non*), 0(*tmp*), "postiats_vararg") // val HITNAM_S2EXP = HITNAM(0(*non*), 0(*tmp*), "postiats_s2exp") val HITNAM_S2ZEXP = HITNAM(0(*non*), 0(*tmp*), "postiats_s2zexp") // (* ****** ****** *) implement hisexp_get_boxknd (hse0) = let in // case+ hse0.hisexp_node of // | HSEtyrec(knd, _) => if tyreckind_is_boxed(knd) then 1 else 0 // | HSEtysum(d2c, _) => 0 // HX: it is not [1]! // | _ (*non-rec-sum*) => (~1) // HX: meaningless // end // end of [hisexp_get_boxknd] implement hisexp_get_extknd (hse0) = let in // case+ hse0.hisexp_node of // | HSEtyrec (knd, _) => if tyreckind_is_fltext(knd) then 1 else 0 // | _(*non-HSEtyrec*) => ~1 // HX: meaningless // end // end of [hisexp_get_extknd] (* ****** ****** *) implement hisexp_is_boxed(hse0) = let // val+HITNAM(knd, _, _) = hse0.hisexp_name in knd > 0 // end // end of [hisexp_is_boxed] (* ****** ****** *) local // fun s2cst_is_void (s2c: s2cst): bool = $S2C.s2cstref_equ_cst ($S2C.the_atsvoid_t0ype, s2c) // fun s2exp_is_void (s2e0: s2exp): bool = ( case+ s2e0.s2exp_node of (* | S2EVar(s2V) => let val s2ze = s2Var_get_szexp(s2V) in case+ s2ze of | S2ZEcst(s2c) => s2cst_is_void(s2c) | _ => false end // end of [S2EVar] *) | _(*non-S2EVar*) => $S2C.s2cstref_equ_exp ($S2C.the_atsvoid_t0ype, s2e0) // end of [non-S2EVar] ) // in (* in-of-local *) implement hisexp_is_void (hse0) = let in // case+ hse0.hisexp_node of // case+ // | HSEcst(s2c) => s2cst_is_void(s2c) // | HSEtyrecsin (lhse) => let val HSLABELED (_, _, hse) = lhse in hisexp_is_void(hse) end // end of [HSEtyrecsin] // | HSEs2exp(s2e) => s2exp_is_void(s2e) // | _ (*rest-of-hisexp*) => false // end // end of [hisexp_is_void] end // end of [local] (* ****** ****** *) implement hisexp_fun_is_void (hse_fun) = let in // case+ hse_fun.hisexp_node of // | HSEfun ( fc, _(*arg*), hse_res ) => hisexp_is_void(hse_res) | _ (*non-HSEfun*) => false // end // end of [hisexp_fun_is_void] (* ****** ****** *) implement hisexp_is_noret (hse0) = let in // case+ hse0.hisexp_node of // | HSEcst(s2c) => $S2C.s2cstref_equ_cst($S2C.the_atsvoid_t0ype, s2c) // end of [HSEcst] | HSEtyvar (s2v) => true // | HSEtyrecsin(lhse) => let val HSLABELED (_, _, hse) = lhse in hisexp_is_noret(hse) end // end of [HSEtyrecsin] // | _(*rest-of-hisexp*) => false // end // end of [hisexp_is_noret] implement hisexp_fun_is_noret (hse_fun) = let in // case+ hse_fun.hisexp_node of | HSEfun ( fc, _(*arg*), hse_res ) => hisexp_is_noret (hse_res) | _(*non-HSEfun*) => false // end // end of [hisexp_fun_is_void] (* ****** ****** *) implement hisexp_is_tyarr (hse0) = let in case+ hse0.hisexp_node of HSEtyarr _ => true | _ => false end // end of [hisexp_is_tyarr] implement hisexp_is_tyrecsin (hse0) = let in case+ hse0.hisexp_node of HSEtyrecsin _ => true | _ => false end // end of [hisexp_is_tyrecsin] (* ****** ****** *) implement labhisexp_get_elt (lhse) = let val HSLABELED (lab, opt, hse) = lhse in hse end // end of [labhisexp_get_elt] (* ****** ****** *) implement hisexp_tybox = '{ hisexp_name= HITNAM_BOXED, hisexp_node= HSEtybox () } (* end of [hisexp_tybox] *) implement hisexp_typtr = let in '{ hisexp_name= HITNAM_TYPTR, hisexp_node= HSEtybox () } end // end of [hisexp_typtr] (* ****** ****** *) local // val ATSTYCLO_TOP = $SYM.symbol_make_string ("atstyclo_top") // in (* in-of-local *) implement hisexp_clotyp = '{ hisexp_name= HITNAM_TYCLO , hisexp_node= HSEtyabs (ATSTYCLO_TOP) } (* [hisexp_clotyp] *) end (* end of [local] *) (* ****** ****** *) implement hisexp_funptr = '{ hisexp_name= HITNAM_FUNPTR, hisexp_node= HSEtybox () } implement hisexp_cloptr = '{ hisexp_name= HITNAM_CLOPTR, hisexp_node= HSEtybox () } implement hisexp_arrptr = '{ hisexp_name= HITNAM_ARRPTR, hisexp_node= HSEtybox () } (* end of [hisexp_arrptr] *) (* ****** ****** *) implement hisexp_datconptr = '{ hisexp_name= HITNAM_DATCONPTR, hisexp_node= HSEtybox () } (* end of [hisexp_datconptr] *) implement hisexp_datcontyp = '{ hisexp_name= HITNAM_DATCONTYP, hisexp_node= HSEtybox () } (* end of [hisexp_datcontyp] *) (* ****** ****** *) implement hisexp_exnconptr = '{ hisexp_name= HITNAM_EXNCONPTR, hisexp_node= HSEtybox () } (* end of [hisexp_exnconptr] *) (* ****** ****** *) // implement hisexp_undefined = let // val sym = $SYM.symbol_make_string(ATSTYPE_UNDEFINED) // in '{ hisexp_name= HITNAM_UNDEFINED, hisexp_node= HSEtyabs (sym) } end // end of [hisexp_undefined] // (* ****** ****** *) implement hisexp_int_t0ype () = let // val s2c = $S2C.s2cstref_get_cst ($S2C.the_atstype_int) // in '{ hisexp_name= HITNAM_TYABS, hisexp_node= HSEcst (s2c) } end // end of [hisexp_int_t0ype] (* ****** ****** *) implement hisexp_bool_t0ype () = let // val s2c = $S2C.s2cstref_get_cst ($S2C.the_atstype_bool) // in '{ hisexp_name= HITNAM_TYABS, hisexp_node= HSEcst (s2c) } end // end of [hisexp_bool_t0ype] (* ****** ****** *) implement hisexp_size_t0ype () = let // val s2c = $S2C.s2cstref_get_cst ($S2C.the_atstype_size) // in '{ hisexp_name= HITNAM_TYABS, hisexp_node= HSEcst (s2c) } end // end of [hisexp_size_t0ype] (* implement hisexp_size_t0ype () = let // val s2c1 = $S2C.s2cstref_get_cst ($S2C.the_atstkind_t0ype) val hse1 = hisexp_cst (s2c1) val s2c2 = $S2C.s2cstref_get_cst ($S2C.the_size_kind) val hse2 = hisexp_cst (s2c2) // in hisexp_app (hse1, list_sing(hse2)) end (* end of [hisexp_size_t0ype] *) *) (* ****** ****** *) implement hisexp_void_t0ype () = let // val s2c = $S2C.s2cstref_get_cst ($S2C.the_atsvoid_t0ype) // in '{ hisexp_name= HITNAM_TYABS, hisexp_node= HSEcst (s2c) } end // end of [hisexp_void_t0ype] (* ****** ****** *) fun hisexp_make_node ( hit: hitnam, node: hisexp_node ) : hisexp = '{ hisexp_name= hit, hisexp_node= node } (* end of [hisexp_make_node] *) (* ****** ****** *) // implement hisexp_tyabs(sym) = hisexp_make_node(HITNAM_TYABS, HSEtyabs(sym)) // (* ****** ****** *) implement hisexp_make_srt (s2t) = let // val isbox = s2rt_is_boxed_fun (s2t) // in // if isbox then hisexp_tybox else let val sym = $SYM.symbol_make_string(ATSTYPE_UNBOXED) // in hisexp_tyabs (sym) end // end of [else] // end // end of [hisexp_make_srt] implement hisexp_make_srtsym (s2t, sym) = let // val isbox = s2rt_is_boxed_fun (s2t) // in if isbox then hisexp_tybox else hisexp_tyabs (sym) // end of [if] end // end of [hisexp_make_srtsym] (* ****** ****** *) // implement hisexp_cst (s2c) = hisexp_make_node (HITNAM_TYABS, HSEcst (s2c)) // (* ****** ****** *) implement hisexp_fun ( funclo, arg, res ) = let // val node = HSEfun(funclo, arg, res) // in // case+ funclo of | FUNCLOfun() => hisexp_make_node(HITNAM_FUNPTR, node) | FUNCLOclo(knd) => if knd = 0 then hisexp_make_node(HITNAM_CLOTYP, node) else hisexp_make_node(HITNAM_CLOPTR, node) // end of [if] // end // end of [hisexp_fun] (* ****** ****** *) implement hisexp_app (_fun, _arg) = hisexp_make_node (HITNAM_TYAPP, HSEapp (_fun, _arg)) // end of [hisexp_app] (* ****** ****** *) implement hisexp_extype (name, s2ess) = let val hit = HITNAM(0(*non*), 1(*fin*), name) in hisexp_make_node (hit, HSEextype (name, s2ess)) end // end of [hisexp_extype] (* ****** ****** *) implement hisexp_refarg (knd, arg) = let // val hitnam = HITNAM (knd, 0(*fin*), "postiats_refarg") // in '{ hisexp_name= hitnam, hisexp_node= HSErefarg (knd, arg) } end // end of [hisexp_refarg] (* ****** ****** *) implement hisexp_tyarr (hse, dim) = hisexp_make_node (HITNAM_TYARR, HSEtyarr (hse, dim)) // end of [hisexp_tyarr] (* ****** ****** *) implement hisexp_tyrec (knd, lhses) = hisexp_make_node (HITNAM_TYREC, HSEtyrec (knd, lhses)) // end of [hisexp_tyrec] implement hisexp_tyrecsin (lhse) = hisexp_make_node (HITNAM_TYRECSIN, HSEtyrecsin (lhse)) // end of [hisexp_tyrecsin] implement hisexp_tyrec2 (knd, lhses) = let val isflt = tyreckind_is_flted (knd) in // if isflt then let val issin = list_is_sing (lhses) in // if issin then let val+ list_cons (lhse, _) = lhses in hisexp_tyrecsin (lhse) end else let in hisexp_tyrec (knd, lhses) end // end of [if] // end else hisexp_tyrec (knd, lhses) // end of [if] // end // end of [hisexp_tyrec2] (* ****** ****** *) implement hisexp_tysum (d2c, lhses) = hisexp_make_node (HITNAM_TYSUM, HSEtysum (d2c, lhses)) // end of [hisexp_tysum] (* ****** ****** *) implement hisexp_tyvar (s2v) = let val s2t = s2var_get_srt (s2v) val isbox = s2rt_is_boxed (s2t) val hit = ( if isbox then HITNAM_BOXED else HITNAM_TYVAR ) : hitnam // end of [val] in hisexp_make_node (hit, HSEtyvar (s2v)) end // end of [hisexp_tyvar] (* ****** ****** *) implement hisexp_tyclo (flab) = hisexp_make_node (HITNAM_TYCLO, HSEtyclo (flab)) // end of [hisexp_tyclo] (* ****** ****** *) implement hisexp_vararg (s2e) = '{ hisexp_name= HITNAM_VARARG, hisexp_node= HSEvararg (s2e) } // end of [hisexp_vararg] (* ****** ****** *) implement hisexp_s2exp (s2e) = hisexp_make_node (HITNAM_S2EXP, HSEs2exp (s2e)) // end of [hisexp_s2exp] implement hisexp_s2zexp (s2ze) = hisexp_make_node (HITNAM_S2ZEXP, HSEs2zexp (s2ze)) // end of [hisexp_s2zexp] (* ****** ****** *) local fun aux ( sub: !stasub, hse0: hisexp, flag: &int ) : hisexp = let in // case+ hse0.hisexp_node of // of [case] // | HSEcst _ => hse0 // | HSEtyabs _ => hse0 | HSEtybox _ => hse0 // | HSEapp ( hse_fun, hses_arg ) => let val f0 = flag val hse_fun = aux (sub, hse_fun, flag) val hses_arg = auxlst (sub, hses_arg, flag) in if flag > f0 then hisexp_app (hse_fun, hses_arg) else hse0 // end of [if] end // end of [HSEapp] // | HSEextype (name, hsess) => let val f0 = flag val hsess = auxlstlst (sub, hsess, flag) in if flag > f0 then hisexp_extype (name, hsess) else hse0 // end of [if] end // end of [HSEextype] // | HSEfun ( fc, hses_arg, hse_res ) => let val f0 = flag val hse_res = aux (sub, hse_res, flag) val hses_arg = auxlst (sub, hses_arg, flag) in if flag > f0 then hisexp_fun (fc, hses_arg, hse_res) else hse0 // end of [if] end // end of [HSEfun] // | HSErefarg (knd, hse) => let val f0 = flag val hse = aux (sub, hse, flag) in if flag > f0 then hisexp_refarg (knd, hse) else hse0 // end of [if] end // end of [HSErefarg] // | HSEtyarr (hse_elt, s2es) => let val f0 = flag val s2es = s2explst_subst_flag (sub, s2es, flag) val hse_elt = aux (sub, hse_elt, flag) in if flag > f0 then hisexp_tyarr (hse_elt, s2es) else hse0 // end of [if] end // end of [HSEtyarr] | HSEtyrec (knd, lhses) => let val f0 = flag val lhses = auxlablst (sub, lhses, flag) in if flag > f0 then hisexp_tyrec (knd, lhses) else hse0 end // end of [HSEtyrec] | HSEtyrecsin (lhse) => let val f0 = flag val lhse = auxlab (sub, lhse, flag) in if flag > f0 then hisexp_tyrecsin (lhse) else hse0 end // end of [HSEtyrecsin] | HSEtysum (d2c, lhses) => let val f0 = flag val lhses = auxlablst (sub, lhses, flag) in if flag > f0 then hisexp_tysum (d2c, lhses) else hse0 end // end of [HSEtysum] // | HSEtyvar (s2v) => let val ans = stasub_find (sub, s2v) in case+ ans of | ~Some_vt (s2e) => let val () = flag := flag + 1 in hisexp_s2exp (s2e) end // end of [Some_vt] | ~None_vt () => hse0 end // end of [HSEtyvar] // | HSEtyclo (flab) => hse0 // | HSEvararg (s2e) => let val f0 = flag val s2e = s2exp_subst_flag (sub, s2e, flag) in if flag > f0 then hisexp_vararg (s2e) else hse0 end // end of [HSEvararg] // | HSEs2exp (s2e) => let val f0 = flag val s2e = s2exp_subst_flag (sub, s2e, flag) in if flag > f0 then hisexp_s2exp (s2e) else hse0 end // end of [HSEs2exp] // | HSEs2zexp (s2ze) => let val f0 = flag val s2ze = s2zexp_subst_flag (sub, s2ze, flag) in if flag > f0 then hisexp_s2zexp (s2ze) else hse0 end // end of [HSEs2zexp] // (* | _ (*rest-of-hisexp*) => hse0 *) // end // end of [aux] and auxlab ( sub: !stasub, lhse0: labhisexp, flag: &int ) : labhisexp = let val f0 = flag val+HSLABELED (lab, opt, hse) = lhse0 val hse = aux (sub, hse, flag) in if flag > f0 then HSLABELED (lab, opt, hse) else lhse0 end // end of [auxlab] and auxlst ( sub: !stasub, hses0: hisexplst, flag: &int ) : hisexplst = let in // case+ hses0 of | list_cons (hse, hses) => let val f0 = flag val hse = aux (sub, hse, flag) val hses = auxlst (sub, hses, flag) in if flag > f0 then list_cons (hse, hses) else hses0 end // end of [list_cons] | list_nil () => list_nil () // end // end of [auxlst] and auxlablst ( sub: !stasub, lhses0: labhisexplst, flag: &int ) : labhisexplst = let in // case+ lhses0 of | list_cons (lhse, lhses) => let val f0 = flag val lhse = auxlab (sub, lhse, flag) val lhses = auxlablst (sub, lhses, flag) in if flag > f0 then list_cons (lhse, lhses) else lhses0 end // end of [list_cons] | list_nil () => list_nil () // end // end of [auxlablst] and auxlstlst ( sub: !stasub, hsess0: hisexplstlst, flag: &int ) : hisexplstlst = let in // case+ hsess0 of | list_cons (hses, hsess) => let val f0 = flag val hses = auxlst (sub, hses, flag) val hsess = auxlstlst (sub, hsess, flag) in if flag > f0 then list_cons (hses, hsess) else hsess0 end // end of [list_cons] | list_nil () => list_nil () // end // end of [auxlstlst] in // in of [local] implement hisexp_subst (sub, hse0) = let var flag: int = 0 in aux (sub, hse0, flag) end // end of [hisexp_subst] end // end of [local] (* ****** ****** *) (* end of [pats_histaexp.dats] *)