anchor.diff:                        id type var new-indices)))
         (unless (equal *current-form* new)
           (setf *current-form* new)))))
  +
  +(defmethod pass1 :around ((op (eql 'spirv-core:composite-construct)) args)
  +  (destructuring-bind (name type &rest values) args
  +    (let ((nv (mapcar 'normalize-literals-and-types values)))
  +      (cond
  +        ;; all arguments are literals, convert to a constant
  +        ;; fixme: make sure this catches named constants too
  +        ((every (lambda (x) (typep x '(cons (eql :literal)))) nv)
  +         ;; add name as an alias for the literal
  +         (let* ((l (composite-literal (normalize-literals-and-types type) nv)))
  +           #+=(format t "~&cc ~s ->~% ~s~% @ ~s (~s)->   ~s~%" values
  +                      nv
  +                      type (normalize-literals-and-types type)
  +                      l)
  +           (use-type l)
  +           (setf (gethash name *literal-names*) l))
  +         ;; and drop the instruction since it will be created as a
  +         ;; constant instead
  +         (setf *current-form* nil))
  +        ;; non-constant arguments, handle normally
  +        (t (call-next-method))))))
   
   (defun first-pass (code)
     (loop for form in code
  
positive.code:        ((gethash x *base-types*)
          ;; expand base types (:int, :vec4 etc)
          (use-type (gethash x *base-types*)))
         (force
          (cond
            ((eq force :variable)
  
negative.code:          (*types* (make-hash-table :test #'equal))
           (*struct-types* (make-hash-table :test #'equal))
           (*variables* (make-hash-table :test #'equal))
           (*literal-names* (make-hash-table :test #'equal))
           (*type-deps* (make-hash-table :test #'equal))
           (*extensions* (make-hash-table :test #'equal))
           (*entry-points* (make-hash-table :test #'equal)))
  