Add support for variadic function types and ellipsis in type declarations, stricter lamda types compile-time checks and object binding for Kotlin bridges

This commit is contained in:
sergeych committed 2026-02-19 11:12:39 +03:00
1 parent e7c1adb2c5
commit d82302dd01
15 files changed
+387 -12

No files matched your search

+5
View File
@@ -34,6 +34,11 @@ Valid examples:
Ellipsis are used to declare variadic arguments. It basically means "all the arguments available here". It means, ellipsis argument could be in any part of the list, being, end or middle, but there could be only one ellipsis argument and it must not have default value, its default value is always `[]`, en empty list.
Ellipsis can also appear in **function types** to denote a variadic position:
var f: (Int, Object..., String)->Real
var anyArgs: (...)->Int // shorthand for (Object...)->Int
Ellipsis argument receives what is left from arguments after processing regular one that could be before or after.
Ellipsis could be a first argument:
+39
View File
@@ -225,6 +225,45 @@ Notes:
- Use [LyngClassBridge] to bind by name/module, or by an already resolved `ObjClass`.
- Use `ObjInstance.data` / `ObjClass.classData` to attach Kotlin‑side state when needed.
### 6.5a) Bind Kotlin implementations to declared Lyng objects
For `extern object` declarations, bind implementations to the singleton instance using `ModuleScope.bindObject`.
This mirrors class binding but targets an already created object instance.
```lyng
// Lyng side (in a module)
extern object HostObject {
extern fun add(a: Int, b: Int): Int
extern val status: String
extern var count: Int
}
```
```kotlin
// Kotlin side (binding)
val moduleScope = importManager.createModuleScope(Pos.builtIn, "bridge.obj")
moduleScope.bindObject("HostObject") {
classData = "OK"
init { _ -> data = 0L }
addFun("add") { _, _, args ->
val a = args.requiredArg<ObjInt>(0).value
val b = args.requiredArg<ObjInt>(1).value
ObjInt.of(a + b)
}
addVal("status") { _, _ -> ObjString(classData as String) }
addVar(
"count",
get = { _, inst -> ObjInt.of((inst as ObjInstance).data as Long) },
set = { _, inst, value -> (inst as ObjInstance).data = (value as ObjInt).value }
)
}
```
Notes:
- Members must be marked `extern` so the compiler emits ABI slots for Kotlin bindings.
- You can also bind by name/module via `LyngObjectBridge.bind(...)`.
### 6.6) Preferred: Kotlin reflection bridge for call‑by‑name
For Kotlin code that needs dynamic access to Lyng variables, functions, or members, use the bridge resolver.
+12
View File
@@ -518,6 +518,13 @@ Examples:
fun inc(x=0) = x + 1 // (Int)->Int
fun maybe(flag) { if(flag) 1 else null } // ()->Int?
Function types are written as `(T1, T2, ...)->R`. You can include ellipsis in function *types* to
express a variadic position:
var fmt: (String, Object...)->String
var f: (Int, Object..., String)->Real
var anyArgs: (...)->Int // shorthand for (Object...)->Int
Untyped locals are allowed, but their type is fixed on the first assignment:
var x
@@ -735,6 +742,11 @@ one could be with ellipsis that means "the rest pf arguments as List":
assert( { a, b...-> [a,...b] }(100, 1, 2, 3) == [100, 1, 2, 3])
void
Type-annotated lambdas can use variadic *function types* as well:
val f: (Int, Object..., String)->Real = { a, rest..., b -> 0.0 }
val anyArgs: (...)->Int = { -> 0 }
### Using lambda as the parameter
See also: [Testing and Assertions](Testing.md)