Lower typed IntArray builders to Kotlin

ober

8ad34fe4996d9ad6fa55b319d79af396b83bd34b

diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index 8c0b15f..4e3f29d 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -1502,6 +1502,49 @@
                  'jvm-float-array 'float-array arg-irs '()))
           (append errors type-errors)))))
 
+  (def (infer-int-array-build args env type-names expr)
+    ;; (int-array-build size (idx body)): a fresh JVM IntArray of length size
+    ;; whose idx-th element is body. This is the typed counterpart to Kotlin's
+    ;; IntArray(size) { idx -> body } constructor.
+    (cond
+      [(not (= (length args) 2))
+       (values #f
+         (list (error-at expr 'bad-int-array-build
+                 "int-array-build expects a size and an (index body) clause"
+                 expr)))]
+      [(not (and (expr-list? (cadr args))
+                 (= (expr-length (cadr args)) 2)
+                 (expr-symbol? (expr-car (cadr args)))))
+       (values #f
+         (list (error-at expr 'bad-int-array-build
+                 "int-array-build clause must be (index body)"
+                 expr)))]
+      [else
+       (let ([size-expr (car args)]
+             [idx-name (expr-value (expr-car (cadr args)))]
+             [body-expr (expr-cadr (cadr args))])
+         (let*-values
+           ([(size-ir size-errors) (infer-expression size-expr env type-names)]
+            [(body-ir body-errors)
+             (infer-expression body-expr
+               (extend-env idx-name 'Int32 env) type-names)])
+           (let* ([type-errors
+                   (argument-type-errors
+                     'int-array-build
+                     (list 'Int32 'Int32)
+                     (list (ir-type size-ir) (ir-type body-ir))
+                     (list size-expr body-expr))]
+                  [ok? (and size-ir body-ir
+                            (null? size-errors) (null? body-errors)
+                            (null? type-errors))])
+             (values
+               (and ok?
+                    (make-typed-ir-call 'IntArray (expr-source expr)
+                      'jvm-int-array-build 'int-array-build
+                      (list size-ir body-ir)
+                      (list (cons 'index idx-name))))
+               (append size-errors body-errors type-errors)))))]))
+
   (def (infer-make-bytevector args env type-names expr)
     ;; (make-bytevector size) or (make-bytevector size fill). Size and fill are
     ;; numeric; the result is a fresh Bytes buffer. A missing fill defaults to a
@@ -1917,6 +1960,8 @@
               (infer-to-int args env type-names expr)]
              [(float-array)
               (infer-float-array args env type-names expr)]
+             [(int-array-build)
+              (infer-int-array-build args env type-names expr)]
              [(bytes-build)
               (infer-bytes-build args env type-names expr)]
              [(option-some)
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index cb1d152..57a23fe 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -288,6 +288,14 @@
          (make-kt-index-get (car args) (cadr args))]
         [(jvm-int-array-length)
          (make-kt-member-get (car args) 'size)]
+        [(jvm-int-array-build)
+         (make-kt-call
+           (kt-name1 'IntArray)
+           (list
+             (car args)
+             (make-kt-lambda
+               (list (info-ref info 'index 'index))
+               (cadr args))))]
         [(jvm-boolean-array-ref)
          (make-kt-index-get (car args) (cadr args))]
         [(jvm-boolean-array-length)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index de26ce2..32ce571 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -354,6 +354,23 @@
 (test-contains "IntArray length lowers to Kotlin size" array-kotlin
   "return items.size")
 
+(define int-array-build-form
+  '(typed-library (sample typed intarraybuild)
+     (export copyPlusOne)
+     (type Int32)
+     (type IntArray)
+     (def (copyPlusOne (items : IntArray)) : IntArray
+       (int-array-build
+         (int-array-length items)
+         (index (+ (int-array-ref items index) (int32 1)))))))
+
+(define int-array-build-kotlin
+  (typed-library-form->kotlin-string int-array-build-form))
+
+(test-contains "IntArray build lowers to Kotlin IntArray constructor"
+  int-array-build-kotlin
+  "IntArray(items.size, { index -> (items[index] + 1) })")
+
 (define note-form
   '(typed-library (sample typed notes)
      (export appendNote)