Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplified "zigzagging" in monom. #46

Merged
merged 4 commits into from
Jan 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 18 additions & 41 deletions fgg/fgg_monom.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var _ = fmt.Errorf

func Monomorph(p FGGProgram) fg.FGProgram {
ds_fgg := p.GetDecls()
omega := GetOmega(ds_fgg, p.GetMain().(FGGExpr))
omega := GetOmega(ds_fgg, p.GetMain().(FGGExpr)) // TODO: do "supertype closure" over omega (cf. collectSuperMethInstans)

var ds_monom []Decl
for _, v := range p.decls {
Expand Down Expand Up @@ -62,7 +62,7 @@ func Monomorph(p FGGProgram) fg.FGProgram {
func monomTDecl(ds []Decl, omega Omega, td TDecl,
wv GroundTypeAndSigs) fg.TDecl {

subs := make(map[TParam]Type) // Type is a TName
subs := make(map[TParam]Type) // Type is a TNamed
psi := td.GetPsi()
for i := 0; i < len(psi.tFormals); i++ {
subs[psi.tFormals[i].name] = wv.u_ground.u_args[i]
Expand Down Expand Up @@ -97,25 +97,10 @@ func monomTDecl(ds []Decl, omega Omega, td TDecl,
t_ret_monom := toMonomId(omega[toWKey(u_ret)].u_ground)
ss = append(ss, fg.NewSig(s.meth, pds, t_ret_monom))
} else {
// Instantiate sig for all calls of this method on this type or any subtype.
// (Similarly, collectZigZagMethInstans.)
// N.B. Omega itself does not "respect" subtyping -- i.e., calls recorded
// .. on a receiver are not necessarily reflected on its super/subtypes.

// forall u s.t. u <: wv.u_ground, collect add-meth-targs for all meths called on u
gs := methods(ds, wv.u_ground)
delta_empty := make(Delta)
// Instantiate sig for all calls of this method on this type.
// Collect add-meth-targs for all meths called on wv.u_ground.
mInstans := make(map[string][]Type) // Key is getTypeArgsHash([]Type)
for _, wv1 := range omega {
if wv1.u_ground.Impls(ds, delta_empty, wv.u_ground) {
// Collect meth instans from *all* subtypes
// Includes calls on i/face receivers -- cf. map.fgg, Bool().Cond(Bool())(...)
// Includes reflexive case
for _, v1 := range gs {
addMethInstans(wv1, v1.meth, mInstans)
}
}
}
addMethInstans(wv, s.meth, mInstans)
// CHECKME: if targs empty, methods "discarded" -- replace meth-params by bounds?
for _, targs := range mInstans {
subs1 := make(map[TParam]Type)
Expand Down Expand Up @@ -157,11 +142,12 @@ func monomTDecl(ds []Decl, omega Omega, td TDecl,
/* Monom MDecl */

// Pre: `wv` (an Omega map value) represents an instantiation of `md.t_recv`
// N.B. `md.t_recv` is a t_S
// TODO: decompose
func monomMDecl(ds []Decl, omega Omega, md MDecl,
wv GroundTypeAndSigs) (res []fg.MDecl) {

subs := make(map[TParam]Type) // Type is a TName
subs := make(map[TParam]Type) // Type is a TNamed
for i := 0; i < len(md.psi_recv.tFormals); i++ {
subs[md.psi_recv.tFormals[i].name] = wv.u_ground.u_args[i]
}
Expand All @@ -178,15 +164,9 @@ func monomMDecl(ds []Decl, omega Omega, md MDecl,
e_monom := monomExpr(omega, md.e_body.TSubs(subs))
res = append(res, fg.NewMDecl(recv, md.name, pds, t_ret_monom, e_monom))
} else {
// Instantiate method for all calls on not only any supertype, ..
// but also on any subtype of any supertype (to preserve subtyping).
// N.B. Omega itself does not "respect" subtyping -- i.e., calls recorded
// .. on a receiver are not necessarily reflected on its super/subtypes.
mInstans := collectZigZagMethInstans(ds, omega, md, wv)
if len(mInstans) == 0 {
// ^Means no u_I, if len(wv.sigs) > 0 -- mInstans doesn't (yet) include wv.sigs
addMethInstans(wv, md.name, mInstans)
}
// Instantiate method for all calls of md.name on any supertype.
mInstans := collectSuperMethInstans(ds, omega, md, wv)
addMethInstans(wv, md.name, mInstans)
for _, targs := range mInstans {
subs1 := make(map[TParam]Type)
for k1, v1 := range subs {
Expand Down Expand Up @@ -214,27 +194,24 @@ func monomMDecl(ds []Decl, omega Omega, md MDecl,
return res
}

// Collect all instantations of calls to md on any subtype of any supertype of wv.u_ground.
// N.B. return is empty, i.e., does not include wv.sigs, if no u_I
// N.B. return is a map, so "duplicate" add-meth-param type instans are implicitly set-ified
// Collect all instantations of calls to md on any supertype of wv.u_ground.
// - return is empty, i.e., does not include wv.sigs, if no u_I with md.name call
// - return is a map, so "duplicate" add-meth-param type instans are implicitly set-ified
// ^E.g., Calling m(A()) on some struct separately via two interfaces T1 and T2 where T2 <: T1
func collectZigZagMethInstans(ds []Decl, omega Omega, md MDecl,
// Pre: `wv` (an Omega map value) represents an instantiation of `md.t_recv`
// N.B. `md.t_recv` is a t_S
func collectSuperMethInstans(ds []Decl, omega Omega, md MDecl,
wv GroundTypeAndSigs) (mInstans map[string][]Type) {

empty := make(Delta)
mInstans = make(map[string][]Type)
// Given m = md.m, forall u_I s.t. m in meths(u_I) && wv.u_ground <: u_I,
// .. forall u s.t. u <: u_I, collect targs from all calls of m on u
// .. collect targs from all calls of m on u_I
for _, wv1 := range omega {
if IsNamedIfaceType(ds, wv1.u_ground) && wv.u_ground.Impls(ds, empty, wv1.u_ground) {
gs := methods(ds, wv1.u_ground) // Includes embedded meths for i/face wv1.u_ground
if _, ok := gs[md.name]; ok {
addMethInstans(wv1, md.name, mInstans)
for _, wv2 := range omega {
if wv2.u_ground.Impls(ds, empty, wv1.u_ground) {
addMethInstans(wv2, md.name, mInstans)
}
}
}
}
}
Expand Down Expand Up @@ -310,7 +287,7 @@ func monomExpr(omega Omega, e FGGExpr) fg.FGExpr {

func toMonomId(u TNamed) fg.Type {
res := u.String()
res = strings.Replace(res, ",", ",,", -1)
res = strings.Replace(res, ",", ",,", -1) // TODO: refactor, cf. main.go, doMonom
res = strings.Replace(res, "(", "<", -1)
res = strings.Replace(res, ")", ">", -1)
res = strings.Replace(res, " ", "", -1)
Expand Down
2 changes: 1 addition & 1 deletion fgg/fgg_omega.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type GroundEnv map[Name]TNamed // Pre: forall TName, isGround
// sigs should include all potential such calls that may occur at run-time
type GroundTypeAndSigs struct {
u_ground TNamed // Pre: isGround(u_ground)
sigs map[string]GroundSig // string key is Sig.String
sigs map[string]GroundSig // string key is GroundSig.sig.String()
// Morally, sigs is a map: fgg.Sig -> []Type -- all sigs on u_ground receiver, including empty add-meth-targs
}

Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func doMonom(prog base.Program, monom bool, compile string) {
if compile != "" {
vPrintln("\nMonomorphising, FG output: [Warning] WIP [Warning]")
out := p_mono.String()
out = strings.Replace(out, ",,", "", -1)
out = strings.Replace(out, ",,", "", -1) // TODO: refactor -- cf. fgg_monom, toMonomId
out = strings.Replace(out, "<", "", -1)
out = strings.Replace(out, ">", "", -1)
if compile == "--" {
Expand Down