about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--mu.arc25
-rw-r--r--mu.arc.t21
2 files changed, 40 insertions, 6 deletions
diff --git a/mu.arc b/mu.arc
index 8774b6bc..1db0ef09 100644
--- a/mu.arc
+++ b/mu.arc
@@ -44,7 +44,7 @@
               integer-array-address (obj size 1  address t  elem 'integer-array)
               integer-address (obj size 1  address t  elem 'integer)  ; pointer to int
               ; records consist of a series of elems, corresponding to a list of types
-              integer-boolean-pair (obj size 2  record t  elems '(integer boolean))
+              integer-boolean-pair (obj size 2  record t  elems '(integer boolean)  fields '(int bool))
               integer-boolean-pair-address (obj size 1  address t  elem 'integer-boolean-pair)
               integer-boolean-pair-array (obj array t  elem 'integer-boolean-pair)
               integer-boolean-pair-array-address (obj size 1  address t  elem 'integer-boolean-pair-array)
@@ -647,15 +647,28 @@
 ;; convert symbolic names to integer offsets
 
 (def convert-names (instrs)
-  (let offset (table)
+  (with (offset  (table)
+         isa-field  (table))
     (let idx 1
       (each instr instrs
         (let (oargs op args)  (parse-instr instr)
-          (each arg args
-            (when (maybe-add arg offset idx)
-              (err "use before set: @arg")
-              (++ idx)))
+          (if (in op 'get 'get-address)
+            (with (fields  ((typeinfo args.0) 'fields)
+                   field  (v args.1))
+              (when (isa field 'sym)
+                (assert (~offset field) "field @args.1 is also a variable")
+                (assert fields "no field names available for @instr")
+                (iflet idx (pos field fields)
+                  (do (set isa-field.field)
+                      (= offset.field idx))
+                  (assert nil "couldn't find field in @instr"))))
+            (each arg args
+              (assert (~isa-field v.arg) "arg @arg is also a field name")
+              (when (maybe-add arg offset idx)
+                (err "use before set: @arg")
+                (++ idx))))
           (each arg oargs
+            (assert (~isa-field v.arg) "oarg @arg is also a field name")
             (when (maybe-add arg offset idx)
               (++ idx))))))
     (each instr instrs
diff --git a/mu.arc.t b/mu.arc.t
index 14d1bced..e0bc6bd5 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -1309,6 +1309,27 @@
             ((z fn) <- add (1 integer) (2 integer))))
   (prn "F - convert-names never renames nil"))
 
+(reset)
+(new-trace "convert-names-record-fields")
+(if (~iso (convert-names
+            '(((x integer) <- get (34 integer-boolean-pair) (bool offset))))
+          '(((1 integer) <- get (34 integer-boolean-pair) (1 offset))))
+  (prn "F - convert-names replaces record field offsets"))
+
+(reset)
+(new-trace "convert-names-record-fields-ambiguous")
+(if (errsafe (convert-names
+               '(((bool boolean) <- copy (t literal))
+                 ((x integer) <- get (34 integer-boolean-pair) (bool offset)))))
+  (prn "F - convert-names doesn't allow offsets and variables with the same name in a function"))
+
+(reset)
+(new-trace "convert-names-record-fields-ambiguous-2")
+(if (errsafe (convert-names
+               '(((x integer) <- get (34 integer-boolean-pair) (bool offset))
+                 ((bool boolean) <- copy (t literal)))))
+  (prn "F - convert-names doesn't allow offsets and variables with the same name in a function - 2"))
+
 ; A rudimentary memory allocator. Eventually we want to write this in mu.
 ;
 ; No deallocation yet; let's see how much code we can build in mu before we