about summary refs log tree commit diff stats
path: root/021check_instruction.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-15 00:37:29 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-15 00:37:29 -0800
commitef96f57ce264c8e0bd98f6e8622d1c1e2eceafb2 (patch)
treef2113d385fde9c4b9579521402eab5ec9c1f208d /021check_instruction.cc
parent7ecb3374340c02cc2c54abf4a5d4a617f362b4c4 (diff)
downloadmu-ef96f57ce264c8e0bd98f6e8622d1c1e2eceafb2.tar.gz
2441 - never miss any specializations
I was failing to specialize calls containing literals. And then I had to
deal with whether literals should map to numbers or characters. (Answer:
both.)

One of the issues that still remains: shape-shifting recipes can't be
called with literals for addresses, even if it's 0.
Diffstat (limited to '021check_instruction.cc')
-rw-r--r--021check_instruction.cc11
1 files changed, 10 insertions, 1 deletions
diff --git a/021check_instruction.cc b/021check_instruction.cc
index 1d831369..fc1f0a1f 100644
--- a/021check_instruction.cc
+++ b/021check_instruction.cc
@@ -81,11 +81,18 @@ bool types_match(reagent lhs, reagent rhs) {
   if (is_raw(rhs)) return true;
   // allow writing 0 to any address
   if (rhs.name == "0" && is_mu_address(lhs)) return true;
-  if (is_literal(rhs)) return !is_mu_array(lhs) && !is_mu_address(lhs) && size_of(rhs) == size_of(lhs);
+  if (is_literal(rhs)) return valid_type_for_literal(lhs) && size_of(rhs) == size_of(lhs);
   if (!lhs.type) return !rhs.type;
   return types_match(lhs.type, rhs.type);
 }
 
+bool valid_type_for_literal(const reagent& r) {
+  if (is_mu_array(r)) return false;
+  if (is_mu_address(r)) return false;
+  // End valid_type_for_literal Special-cases
+  return true;
+}
+
 // two types match if the second begins like the first
 // (trees perform the same check recursively on each subtree)
 bool types_match(type_tree* lhs, type_tree* rhs) {
@@ -95,6 +102,8 @@ bool types_match(type_tree* lhs, type_tree* rhs) {
     if (lhs->value == get(Type_ordinal, "address")) return false;
     return size_of(rhs) == size_of(lhs);
   }
+  if (lhs->value == get(Type_ordinal, "character") && rhs->value == get(Type_ordinal, "number")) return true;
+  if (lhs->value == get(Type_ordinal, "number") && rhs->value == get(Type_ordinal, "character")) return true;
   if (lhs->value != rhs->value) return false;
   return types_match(lhs->left, rhs->left) && types_match(lhs->right, rhs->right);
 }