diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-08 20:26:13 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-08 20:35:53 -0800 |
commit | e5302026cca04c23cba1431d5e0fceab8667bc08 (patch) | |
tree | 6a79d50a0e620503a8c53a4d92e9cdd827586395 | |
parent | a9a233715cbec202e90259ab95d97e35f143c146 (diff) | |
download | mu-e5302026cca04c23cba1431d5e0fceab8667bc08.tar.gz |
2401
I tried to not populate the type at an early stage, and to pull out the type computations for all reagents into a separate transform grouped with but before the other type deduction transforms. But it seemed less readable to not mention types at all in layer 10. So we'll stick with our current approach, but try to be disciplined about grouping all the type transforms together, so that we can reason about whether a pass belongs before or after type deduction. (Doesn't seem rigorous enough for the name 'type inference'.) In particular, static dispatch and specialization of generics (resolve_ambiguous_calls) needs to happen after all type inference has completed, so that the only missing types are the generic type ingredients. In general I've been living in constant fear of the phase-ordering problem. No matter how many tests I write, I can't be sure that there isn't some corner case where my phases will be proven to be in a sub-optimal ordering. When I build the mu compiler in mu I'll want to also use the ability to perform static analyses in mu programs using mu userland capabilities. That would allow me to be sure that no phase writes to some field of reagent after some other purely checking phase reads it. Then all you have to do is be disciplined about not doing checking in mutating phases (which we currently aren't; hello check_or_set_invalid_types). Hmm, but I think this line of thought gives me some confidence now that I'm ok so far. The only field of reagents being modified after parsing/initialization is the type. So all I care about is whether each transform happens before or after all types are available. If I later start writing other fields or properties then I'll need to perform similar analysis for them, and it might get complicated enough to need a state diagram where partially filled out properties inhabit separate states from completely inferred properties.
-rw-r--r-- | 042name.cc | 2 | ||||
-rw-r--r-- | 048check_type_by_name.cc | 2 |
2 files changed, 2 insertions, 2 deletions
diff --git a/042name.cc b/042name.cc index b66de8a2..b25ca533 100644 --- a/042name.cc +++ b/042name.cc @@ -18,7 +18,7 @@ recipe main [ +error: main: use before set: y # todo: detect conditional defines -:(after "Begin Transforms") +:(after "Transform.push_back(check_or_set_invalid_types") // there'll be other transforms relating to types; they all need to happen first Transform.push_back(transform_names); // idempotent :(before "End Globals") diff --git a/048check_type_by_name.cc b/048check_type_by_name.cc index e9b65b8c..fff48395 100644 --- a/048check_type_by_name.cc +++ b/048check_type_by_name.cc @@ -14,7 +14,7 @@ recipe main [ ] +error: main: x used with multiple types -:(before "Transform.push_back(transform_names)") +:(after "Transform.push_back(check_or_set_invalid_types)") Transform.push_back(check_types_by_name); // idempotent :(code) |