diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-10-22 12:08:10 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-10-22 12:08:10 -0700 |
commit | ada5eb55cb185edf30dcac48b25cc485d44677ef (patch) | |
tree | e147838f053a582e33146ac4fc4ab30ac8434e0e /047check_type_by_name.cc | |
parent | a6deb48067f8049922f16ed3489896f7749fd39f (diff) | |
download | mu-ada5eb55cb185edf30dcac48b25cc485d44677ef.tar.gz |
3552
Stop requiring jump instructions to explicitly provide a ':label' type for jump targets. This has been a source of repeated confusion for my students: a) They'd add the ':label' to the label definition rather than the jump target (label use) b) They'd spend time thinking about whether the initial '+' prefix was part of the label name. In the process I cleaned up a couple of things: - the space of names is more cleanly partitioned into labels and non-labels (clarifying that '_' and '-' are non-label prefixes) - you can't use label names as regular variables anymore - you can infer the type of a label just from its name
Diffstat (limited to '047check_type_by_name.cc')
-rw-r--r-- | 047check_type_by_name.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/047check_type_by_name.cc b/047check_type_by_name.cc index 62a6107c..96a703ce 100644 --- a/047check_type_by_name.cc +++ b/047check_type_by_name.cc @@ -37,6 +37,10 @@ void check_or_set_types_by_name(const recipe_ordinal r) { void deduce_missing_type(set<reagent>& known, reagent& x) { if (x.type) return; + if (is_jump_target(x.name)) { + x.type = new type_tree("label"); + return; + } if (known.find(x) == known.end()) return; x.type = new type_tree(*known.find(x)->type); trace(9992, "transform") << x.name << " <= " << names_to_string(x.type) << end(); @@ -46,6 +50,11 @@ void check_type(set<reagent>& known, const reagent& x, const recipe& caller) { if (is_literal(x)) return; if (is_integer(x.name)) return; // if you use raw locations you're probably doing something unsafe if (!x.type) return; // might get filled in by other logic later + if (is_jump_target(x.name)) { + if (!x.type->atom || x.type->name != "label") + raise << maybe(caller.name) << "non-label '" << x.name << "' must begin with a letter\n" << end(); + return; + } if (known.find(x) == known.end()) { trace(9992, "transform") << x.name << " => " << names_to_string(x.type) << end(); known.insert(x); @@ -90,6 +99,14 @@ def main [ # x is in location 1 +mem: storing 2 in location 1 +:(scenario transform_fills_in_missing_label_type) +def main [ + jump +target + 1:num <- copy 0 + +target +] +-mem: storing 0 in location 1 + :(scenario transform_fails_on_missing_types_in_first_mention) % Hide_errors = true; def main [ @@ -98,6 +115,13 @@ def main [ ] +error: main: missing type for 'x' in 'x <- copy 1' +:(scenario transform_fails_on_wrong_type_for_label) +% Hide_errors = true; +def main [ + +foo:num <- copy 34 +] ++error: main: non-label '+foo' must begin with a letter + :(scenario typo_in_address_type_fails) % Hide_errors = true; def main [ |