f147682661ae — Leonard Ritter a month ago
* compiler: `attrof` does the job of `replaceof`
M lib/scopes/compiler/noir/Index.sc +8 -27
@@ 564,34 564,12 @@ struct ProcSchema
                                 downcast iid Module.Id.Instruction
                             else
                                 raise;
-                            name := 'follow module procid (op.operands @ 1)
-                            name := try
-                                downcast name Module.Id.Const
-                            else
-                                raise;
-                            row := proc.body @ iid
-                            if (row.op != 'instance)
-                                raise;
-                            subprocid := 'follow module procid (row.operands @ 0)
-                            subprocid := try
-                                downcast subprocid Module.Id.Procedure
+                            idx := 'follow module procid (op.operands @ 1)
+                            idx := try
+                                downcast idx Module.Id.IndexAttr
                             else
                                 raise;
-                            proc-order := 'scheduleof module-index subprocid
-                            valueid := try
-                                'get proc-order.export name
-                            else
-                                raise;
-                            md := 'schemaof module-index subprocid
-                            'sizeofvalue md module valueid
-                        else UNKNOWN
-                    case 'replaceof
-                        iid := 'follow module procid (op.operands @ 0)
-                        try
-                            iid := try
-                                downcast iid Module.Id.Instruction
-                            else
-                                raise;
+                            idx := idx as usize
                             row := proc.body @ iid
                             if (row.op != 'instance)
                                 raise;

          
@@ 601,8 579,11 @@ struct ProcSchema
                             else
                                 raise;
                             proc := module.proc @ subprocid
+                            if (idx >= (countof proc.body))
+                                raise;
+                            valueid := 'wrap Module.Id.Instruction idx
                             md := 'schemaof module-index subprocid
-                            'sizeofvalue md module proc.replace
+                            'sizeofvalue md module valueid
                         else UNKNOWN
                     case 'pcall
                         try

          
M lib/scopes/compiler/noir/effects.sc +2 -4
@@ 146,10 146,8 @@ EFFECT_DESC := sugar-quote
     inattr index size
     # create instance of macro with given inattrs
     ! instance proc ...
-    # get attribute from instance with given name
-    attrof proc name
-    # get replace value from instance
-    replaceof proc
+    # get attribute from instance with given instruction index
+    attrof x index
 
     # immutable values
       ----------------

          
M lib/scopes/compiler/noir/renoir.sc +63 -0
@@ 1623,6 1623,44 @@ FACTOR_TYPES := do
             default
                 assert false
 
+    struct RRANGE < FactorType
+        @@ memo
+        inline match-configs (cls)
+            using cls.Bits
+            pass fully-defined i
+
+        i : Module.Id.IndexAttr
+        begin : Module.Id.IndexAttr
+        end : Module.Id.IndexAttr
+
+        inline next (cls reducer factor state builder i begin_ end_)
+            from cls let Bits
+            begin := begin_ as usize
+            end := end_ as usize
+            if (begin >= end)
+                return false
+            switch factor.itmask
+            case Bits.fully-defined # i
+                if (not state.init)
+                    state.init = 1
+                    i := i as usize
+                    return ((i - begin) < end)
+                else
+                    return false
+            case Bits.i # i?
+                if (not state.init)
+                    state.init = 1
+                    i = 'wrap Module.Id.IndexAttr (end - 1)
+                    return true
+                else
+                    idx := i as usize
+                    if (idx <= begin)
+                        return false
+                    i = 'wrap Module.Id.IndexAttr (idx - 1)
+                    return true
+            default
+                assert false
+
     struct VACOUNT < FactorType
         Opts := FactorOpts.All
 

          
@@ 1870,6 1908,31 @@ FACTOR_TYPES := do
                     else
                         return false
 
+    struct INDEXOF < FactorType
+        @@ memo
+        inline match-configs (cls)
+            using cls.Bits
+            pass fully-defined index
+
+        value : Module.Id
+        index : Module.Id.IndexAttr
+
+        inline next (cls reducer factor state builder value index)
+            from cls let Bits
+            'dispatch-match cls factor
+                inline "#hidden" (mask)
+                    __ k := 'unwrap value
+                    k := 'wrap Module.Id.IndexAttr k
+                    if (state.init == 0)
+                        state.init = 1
+                        static-if (Bits.index in mask)
+                            index = k
+                            return true
+                        else
+                            return (index == k)
+                    else
+                        return false
+
     struct METAOP? < FactorType
         @@ memo
         inline match-configs (cls)

          
M lib/scopes/compiler/noir/rules-reducer.sx +109 -6
@@ 1,3 1,6 @@ 
+# TODO:
+    an unreachable instance effect using a macro that has no side effects can be
+    removed.
 OP2-fold
     # fold constant arithmetic operations
     ;

          
@@ 211,8 214,11 @@ ATTROF
                 KINDOF $value Instruction
                 OP $src $value $valop
                 METAOP? $valop false
+                SIZEOF $src $value _
+                INDEXOF $value $value_idx
             ;
                 OP $ctx $id attrof
+                ARG $ctx $id 1 $value_idx
 REPLACEOF
     ;
         OP $ctx $id REPLACEOF

          
@@ 237,8 243,10 @@ REPLACEOF
                 OP $src $value $valop
                 METAOP? $valop false
                 SIZEOF $src $value _
+                INDEXOF $value $value_idx
             ;
-                OP $ctx $id replaceof
+                OP $ctx $id attrof
+                ARG $ctx $id 1 $value_idx
 FUNC-MACRO-instance
     # instantiate FUNC-enveloped macros and translate INATTR to sized inattr
     ;

          
@@ 329,11 337,7 @@ CLOSURE-remove-unused-upval
             ;
                 VA 1 _ $i
         VACOUNT 1 $numunused
-        # TODO: RRANGE
-        RANGE $k__ 0 $numunused
-        SUB $k_ $numunused $k__
-        SUB $k $k_ 1
-        #
+        RRANGE $k 0 $numunused
         VA 1 $k $i
         ARGCOUNT $ctx $id $n_
         SUB $n $n_ 1

          
@@ 503,6 507,99 @@ inline-global
             ;
                 ALIAS $instance $mid $value
                 ARG $ctx $id $valuei none
+or-elide-unused
+    # elide undefined arguments from `or` expression
+    ;
+        OP $ctx $id or
+        ARGCOUNT $ctx $id $n
+        SUB $n-1 $n 1
+        RULE () ((VACOUNT 0 0))
+        RULE
+            ;
+                ARG $ctx $id $i $arg_
+                FOLLOW $ctx $arg_ $arg
+                KINDOF $arg ConstUndef
+            ;
+                VA 0 _ $i
+        VACOUNT 0 $numunused
+        RRANGE $k 0 $numunused
+        VA 0 $k $i
+    ;
+        RULE # case 1: unused element is last arg; truncate
+            ;
+                EQ true $i $n-1
+            ;
+                ARGCOUNT $ctx $id $n-1
+        RULE # case 2: unused element is before last arg; swap out
+            ;
+                LT true $i $n-1
+                ARG $ctx $id $n-1 $tail
+            ;
+                ARG $ctx $id $i $tail
+                ARGCOUNT $ctx $id $n-1
+or-1
+    # elide `or` with single argument
+    ;
+        OP $ctx $id or
+        ARGCOUNT $ctx $id 1
+        ARG $ctx $id 0 $target
+    ;
+        OP $ctx $id pass
+
+pass-elide-constant
+    # elide pass effect with constant
+    ;
+        OP $ctx $id pass
+        ARG $ctx $id 0 $arg_
+        FOLLOW $ctx $arg_ $arg
+        NOT
+            KINDOF $arg Instruction
+    ;
+        ALIAS $ctx $id $arg_
+DEP-fold
+    # fold decidable dependencies
+    ;
+        OP $ctx $id _
+        DEP $ctx $id $src_ $mode
+        FOLLOW $ctx $src_ $src
+        KINDOF $src $srckind
+        NE true $srckind Instruction
+    ;
+        RULE
+            ;
+                EQ true $mode Defined
+            ;
+                RULE
+                    ;
+                        EQ true $srckind ConstUndef
+                    ;
+                        ALIAS $ctx $id $srckind
+                        NDEP $ctx $id _ _
+                RULE
+                    ;
+                        NE true $srckind ConstUndef
+                    ;
+                        NDEP $ctx $id $src_ $mode
+        RULE
+            ;
+                EQ true $mode Undefined
+            ;
+                RULE
+                    ;
+                        EQ true $srckind ConstUndef
+                    ;
+                        NDEP $ctx $id $src_ $mode
+                RULE
+                    ;
+                        NE true $srckind ConstUndef
+                    ;
+                        ALIAS $ctx $id undef
+                        NDEP $ctx $id _ _
+        RULE
+            ;
+                EQ true $mode Ordered
+            ;
+                NDEP $ctx $id $src_ $mode
 #5|UNUSED-elide
     # rewrite unused effects to UNUSED
     ;

          
@@ 567,3 664,9 @@ inline-global
             ;
                 CGENERROR $proc $id "failed to compute size of {$op} effect \
                     in {$proc}."
+9|TRACE
+    ;
+        OP $ctx $id TRACE
+        ARG $ctx $id 0 $value
+    ;
+        TRACE $ctx $value