for loop optimization

This commit is contained in:
Sergey Chernov 2025-06-03 18:13:16 +04:00
parent 148d1b6d24
commit b331f4edaa
2 changed files with 45 additions and 3 deletions

11
happy.py Normal file
View File

@ -0,0 +1,11 @@
count = 0
for n1 in range(10):
for n2 in range(10):
for n3 in range(10):
for n4 in range(10):
for n5 in range(10):
for n6 in range(10):
if n1 + n2 + n3 == n4 + n5 + n6:
count += 1
print(count)

View File

@ -683,7 +683,14 @@ class Compiler(
// insofar we suggest source object is enumerable. Later we might need to add checks // insofar we suggest source object is enumerable. Later we might need to add checks
val sourceObj = source.execute(forContext) val sourceObj = source.execute(forContext)
if (sourceObj.isInstanceOf(ObjIterable)) { if (sourceObj is ObjRange && sourceObj.isIntRange) {
loopIntRange(
forContext,
sourceObj.start!!.toInt(),
if (sourceObj.isEndInclusive) sourceObj.end!!.toInt() + 1 else sourceObj.end!!.toInt(),
loopSO, body, elseStatement, label, canBreak
)
} else if (sourceObj.isInstanceOf(ObjIterable)) {
loopIterable(forContext, sourceObj, loopSO, body, elseStatement, label, canBreak) loopIterable(forContext, sourceObj, loopSO, body, elseStatement, label, canBreak)
} else { } else {
val size = runCatching { sourceObj.invokeInstanceMethod(forContext, "size").toInt() } val size = runCatching { sourceObj.invokeInstanceMethod(forContext, "size").toInt() }
@ -718,8 +725,7 @@ class Compiler(
} else } else
throw lbe throw lbe
} }
} } else result = body.execute(forContext)
else result = body.execute(forContext)
if (++index >= size) break if (++index >= size) break
current = sourceObj.getAt(forContext, index) current = sourceObj.getAt(forContext, index)
} }
@ -736,6 +742,31 @@ class Compiler(
} }
} }
private suspend fun loopIntRange(
forContext: Context, start: Int, end: Int, loopVar: StoredObj,
body: Statement, elseStatement: Statement?, label: String?, catchBreak: Boolean
): Obj {
var result: Obj = ObjVoid
val iVar = ObjInt(0)
loopVar.value = iVar
for( i in start ..< end) {
iVar.value = i.toLong()
if (catchBreak)
try {
result = body.execute(forContext)
} catch (lbe: LoopBreakContinueException) {
if (lbe.label == label || lbe.label == null) {
if (lbe.doContinue) continue
}
return lbe.result
}
else {
result = body.execute(forContext)
}
}
return elseStatement?.execute(forContext) ?: result
}
private suspend fun loopIterable( private suspend fun loopIterable(
forContext: Context, sourceObj: Obj, loopVar: StoredObj, forContext: Context, sourceObj: Obj, loopVar: StoredObj,
body: Statement, elseStatement: Statement?, label: String?, body: Statement, elseStatement: Statement?, label: String?,