about summary refs log tree commit diff stats
path: root/subx/033non_code_segment.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-08-03 23:34:27 -0700
committerKartik Agaram <vc@akkartik.com>2018-08-03 23:34:27 -0700
commit96a09ee9f9017294313cfb6daf04864ace78ba75 (patch)
treebd9f790fb6b594c04ce290632ba746b408eacf92 /subx/033non_code_segment.cc
parent12adb3da8a8979c207b2e7fd17bdb05bacefeb44 (diff)
downloadmu-96a09ee9f9017294313cfb6daf04864ace78ba75.tar.gz
4468
Diffstat (limited to 'subx/033non_code_segment.cc')
-rw-r--r--subx/033non_code_segment.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/subx/033non_code_segment.cc b/subx/033non_code_segment.cc
new file mode 100644
index 00000000..5006e9a1
--- /dev/null
+++ b/subx/033non_code_segment.cc
@@ -0,0 +1,29 @@
+//: Raise an error when operand metadata is used in non-code segments.
+
+:(scenario operand_metadata_outside_code_segment)
+% Hide_errors = true;
+== 0x1  # code segment
+cd 0x80/imm8
+== 0x1000  # data segment
+cd 12/imm8
++error: 12/imm8: metadata imm8 is only allowed in the (first) code segment
+
+:(before "End One-time Setup")
+Transform.push_back(ensure_operands_only_in_code_segments);
+:(code)
+void ensure_operands_only_in_code_segments(/*const*/ program& p) {
+  trace(99, "transform") << "-- ensure operands only in code segments" << end();
+  if (p.segments.empty()) return;
+  for (int i = /*skip code segment*/1;  i < SIZE(p.segments);  ++i) {
+    const segment& seg = p.segments.at(i);
+    for (int j = 0;  j < SIZE(seg.lines);  ++j) {
+      const line& l = seg.lines.at(j);
+      for (int k = 0;  k < SIZE(l.words);  ++k) {
+        const word& w = l.words.at(k);
+        for (map<string, uint32_t>::iterator p = Operand_bound.begin();  p != Operand_bound.end();  ++p)
+          if (has_metadata(w, p->first))
+            raise << w.original << ": metadata " << p->first << " is only allowed in the (first) code segment\n" << end();
+      }
+    }
+  }
+}