Lower typed IntArray builders to Kotlin
ober
8ad34fe4996d9ad6fa55b319d79af396b83bd34b
--- 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) --- 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) --- 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)