fixed samples test
This commit is contained in:
parent
a0ecbfd334
commit
dc9885c218
@ -1,23 +1,23 @@
|
||||
// Sample: Operator Overloading in Lyng
|
||||
|
||||
class Vector(val x, val y) {
|
||||
class Vector<T>(val x: T, val y: T) {
|
||||
// Overload +
|
||||
fun plus(other) = Vector(x + other.x, y + other.y)
|
||||
fun plus(other: Vector<U>) = Vector(x + other.x, y + other.y)
|
||||
|
||||
// Overload -
|
||||
fun minus(other) = Vector(x - other.x, y - other.y)
|
||||
fun minus(other: Vector<U>) = Vector(x - other.x, y - other.y)
|
||||
|
||||
// Overload unary -
|
||||
fun negate() = Vector(-x, -y)
|
||||
|
||||
// Overload ==
|
||||
fun equals(other) {
|
||||
if (other is Vector) x == other.x && y == other.y
|
||||
if (other is Vector<U>) x == other.x && y == other.y
|
||||
else false
|
||||
}
|
||||
|
||||
// Overload * (scalar multiplication)
|
||||
fun mul(scalar) = Vector(x * scalar, y * scalar)
|
||||
fun mul(scalar: Int | Real) = Vector(x * scalar, y * scalar)
|
||||
|
||||
override fun toString() = "Vector(${x}, ${y})"
|
||||
}
|
||||
|
||||
@ -13,7 +13,6 @@ fun findSumLimit(f) {
|
||||
println("limit reached after "+n+" rounds")
|
||||
break sum
|
||||
}
|
||||
n++
|
||||
}
|
||||
else {
|
||||
println("limit not reached")
|
||||
|
||||
@ -6797,6 +6797,118 @@ class Compiler(
|
||||
return t.pos
|
||||
}
|
||||
|
||||
private data class SmartCastTarget(
|
||||
val name: String? = null,
|
||||
val scopeId: Int? = null,
|
||||
val slot: Int? = null,
|
||||
val typeDecl: TypeDecl,
|
||||
)
|
||||
|
||||
private data class SmartCastRestore(
|
||||
val name: String?,
|
||||
val nameHad: Boolean,
|
||||
val namePrev: TypeDecl?,
|
||||
val scopeId: Int?,
|
||||
val slot: Int?,
|
||||
val slotHad: Boolean,
|
||||
val slotPrev: TypeDecl?,
|
||||
val slotMapCreated: Boolean,
|
||||
)
|
||||
|
||||
private fun smartCastTargetFromRef(ref: ObjRef, typeDecl: TypeDecl): SmartCastTarget? = when (ref) {
|
||||
is LocalSlotRef -> {
|
||||
val ownerScopeId = ref.captureOwnerScopeId ?: ref.scopeId
|
||||
val ownerSlot = ref.captureOwnerSlot ?: ref.slot
|
||||
SmartCastTarget(scopeId = ownerScopeId, slot = ownerSlot, typeDecl = typeDecl)
|
||||
}
|
||||
is LocalVarRef -> SmartCastTarget(name = ref.name, typeDecl = typeDecl)
|
||||
is FastLocalVarRef -> SmartCastTarget(name = ref.name, typeDecl = typeDecl)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun extractSmartCasts(condition: Statement): Pair<List<SmartCastTarget>, List<SmartCastTarget>> {
|
||||
val ref = unwrapDirectRef(condition) ?: return emptyList<SmartCastTarget>() to emptyList()
|
||||
if (ref !is BinaryOpRef) return emptyList<SmartCastTarget>() to emptyList()
|
||||
if (ref.op != BinOp.IS && ref.op != BinOp.NOTIS) return emptyList<SmartCastTarget>() to emptyList()
|
||||
val typeRef = ref.right as? net.sergeych.lyng.obj.TypeDeclRef ?: return emptyList<SmartCastTarget>() to emptyList()
|
||||
val typeDecl = expandTypeAliases(typeRef.decl(), typeRef.pos())
|
||||
val target = smartCastTargetFromRef(ref.left, typeDecl) ?: return emptyList<SmartCastTarget>() to emptyList()
|
||||
return if (ref.op == BinOp.IS) {
|
||||
listOf(target) to emptyList()
|
||||
} else {
|
||||
emptyList<SmartCastTarget>() to listOf(target)
|
||||
}
|
||||
}
|
||||
|
||||
private fun applySmartCasts(overrides: List<SmartCastTarget>): List<SmartCastRestore> {
|
||||
if (overrides.isEmpty()) return emptyList()
|
||||
val restores = ArrayList<SmartCastRestore>(overrides.size)
|
||||
for (override in overrides) {
|
||||
if (override.name != null) {
|
||||
val had = nameTypeDecl.containsKey(override.name)
|
||||
val prev = nameTypeDecl[override.name]
|
||||
nameTypeDecl[override.name] = override.typeDecl
|
||||
restores.add(
|
||||
SmartCastRestore(
|
||||
name = override.name,
|
||||
nameHad = had,
|
||||
namePrev = prev,
|
||||
scopeId = null,
|
||||
slot = null,
|
||||
slotHad = false,
|
||||
slotPrev = null,
|
||||
slotMapCreated = false,
|
||||
)
|
||||
)
|
||||
} else if (override.scopeId != null && override.slot != null) {
|
||||
val map = slotTypeDeclByScopeId[override.scopeId]
|
||||
val mapCreated = map == null
|
||||
val targetMap = map ?: mutableMapOf<Int, TypeDecl>().also { slotTypeDeclByScopeId[override.scopeId] = it }
|
||||
val had = targetMap.containsKey(override.slot)
|
||||
val prev = targetMap[override.slot]
|
||||
targetMap[override.slot] = override.typeDecl
|
||||
restores.add(
|
||||
SmartCastRestore(
|
||||
name = null,
|
||||
nameHad = false,
|
||||
namePrev = null,
|
||||
scopeId = override.scopeId,
|
||||
slot = override.slot,
|
||||
slotHad = had,
|
||||
slotPrev = prev,
|
||||
slotMapCreated = mapCreated,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return restores
|
||||
}
|
||||
|
||||
private fun restoreSmartCasts(restores: List<SmartCastRestore>) {
|
||||
if (restores.isEmpty()) return
|
||||
for (restore in restores.asReversed()) {
|
||||
if (restore.name != null) {
|
||||
if (restore.nameHad) {
|
||||
nameTypeDecl[restore.name] = restore.namePrev!!
|
||||
} else {
|
||||
nameTypeDecl.remove(restore.name)
|
||||
}
|
||||
} else if (restore.scopeId != null && restore.slot != null) {
|
||||
val map = slotTypeDeclByScopeId[restore.scopeId]
|
||||
if (map != null) {
|
||||
if (restore.slotHad) {
|
||||
map[restore.slot] = restore.slotPrev!!
|
||||
} else {
|
||||
map.remove(restore.slot)
|
||||
}
|
||||
if (restore.slotMapCreated && map.isEmpty()) {
|
||||
slotTypeDeclByScopeId.remove(restore.scopeId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun parseIfStatement(): Statement {
|
||||
val start = ensureLparen()
|
||||
|
||||
@ -6805,7 +6917,13 @@ class Compiler(
|
||||
|
||||
val pos = ensureRparen()
|
||||
|
||||
val ifBody = parseStatement() ?: throw ScriptError(pos, "Bad if statement: expected statement")
|
||||
val (trueCasts, falseCasts) = extractSmartCasts(condition)
|
||||
val ifRestores = applySmartCasts(trueCasts)
|
||||
val ifBody = try {
|
||||
parseStatement() ?: throw ScriptError(pos, "Bad if statement: expected statement")
|
||||
} finally {
|
||||
restoreSmartCasts(ifRestores)
|
||||
}
|
||||
|
||||
cc.skipTokenOfType(Token.Type.NEWLINE, isOptional = true)
|
||||
// could be else block:
|
||||
@ -6813,8 +6931,12 @@ class Compiler(
|
||||
|
||||
// we generate different statements: optimization
|
||||
val stmt = if (t2.type == Token.Type.ID && t2.value == "else") {
|
||||
val elseBody =
|
||||
val elseRestores = applySmartCasts(falseCasts)
|
||||
val elseBody = try {
|
||||
parseStatement() ?: throw ScriptError(pos, "Bad else statement: expected statement")
|
||||
} finally {
|
||||
restoreSmartCasts(elseRestores)
|
||||
}
|
||||
IfStatement(condition, ifBody, elseBody, start)
|
||||
} else {
|
||||
cc.previous()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
|
||||
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -18,11 +18,11 @@
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.sergeych.lyng.Scope
|
||||
import net.sergeych.lyng.Script
|
||||
import net.sergeych.lyng.toSource
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.extension
|
||||
import kotlin.test.Ignore
|
||||
import kotlin.test.Test
|
||||
import kotlin.time.Clock
|
||||
|
||||
@ -31,9 +31,9 @@ suspend fun executeSampleTests(fileName: String) {
|
||||
Files.readString(Paths.get(fileName))
|
||||
}
|
||||
runBlocking {
|
||||
val c = Scope()
|
||||
val c = Script.newScope()
|
||||
val start = Clock.System.now()
|
||||
c.eval(sample)
|
||||
c.eval(sample.toSource(fileName))
|
||||
val time = Clock.System.now() - start
|
||||
println("$time: $fileName")
|
||||
// delay(100)
|
||||
@ -41,7 +41,6 @@ suspend fun executeSampleTests(fileName: String) {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("TODO(compile-time-res): legacy tests disabled")
|
||||
class SamplesTest {
|
||||
|
||||
@Test
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user