mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
for loops can now be over an iterable literal value directly (don't require a variable to hold the iterable)
This commit is contained in:
parent
0820716e7b
commit
1e5b2e0be3
@ -139,9 +139,6 @@ private class AstChecker(private val namespace: INameScope,
|
||||
if(forLoop.body.isEmpty())
|
||||
printWarning("for loop body is empty", forLoop.position)
|
||||
|
||||
if(forLoop.iterable is LiteralValue)
|
||||
checkResult.add(SyntaxError("currently not possible to loop over a literal value directly, define it as a variable instead", forLoop.position)) // todo loop over literals (by creating a generated variable)
|
||||
|
||||
if(!forLoop.iterable.isIterable(namespace, heap)) {
|
||||
checkResult.add(ExpressionError("can only loop over an iterable type", forLoop.position))
|
||||
} else {
|
||||
|
@ -14,23 +14,29 @@ fun Module.checkIdentifiers(heap: HeapValues): MutableMap<String, IStatement> {
|
||||
val checker = AstIdentifiersChecker(heap)
|
||||
this.process(checker)
|
||||
|
||||
// add any anonymous variables for heap values that are used, and replace literalvalue by identifierref
|
||||
// add any anonymous variables for heap values that are used,
|
||||
// and replace an iterable literalvalue by identifierref to new local variable
|
||||
for (variable in checker.anonymousVariablesFromHeap) {
|
||||
val scope = variable.first.definingScope()
|
||||
scope.statements.add(variable.second)
|
||||
val parent = variable.first.parent
|
||||
when {
|
||||
parent is Assignment && parent.value === variable.first -> {
|
||||
val idref = IdentifierReference(listOf("auto_heap_value_${variable.first.heapId}"), variable.first.position)
|
||||
val idref = IdentifierReference(listOf("$autoHeapValuePrefix${variable.first.heapId}"), variable.first.position)
|
||||
idref.linkParents(parent)
|
||||
parent.value = idref
|
||||
}
|
||||
parent is IFunctionCall -> {
|
||||
val parameterPos = parent.arglist.indexOf(variable.first)
|
||||
val idref = IdentifierReference(listOf("auto_heap_value_${variable.first.heapId}"), variable.first.position)
|
||||
val idref = IdentifierReference(listOf("$autoHeapValuePrefix${variable.first.heapId}"), variable.first.position)
|
||||
idref.linkParents(parent)
|
||||
parent.arglist[parameterPos] = idref
|
||||
}
|
||||
parent is ForLoop -> {
|
||||
val idref = IdentifierReference(listOf("$autoHeapValuePrefix${variable.first.heapId}"), variable.first.position)
|
||||
idref.linkParents(parent)
|
||||
parent.iterable = idref
|
||||
}
|
||||
else -> TODO("replace literalvalue by identifierref: $variable (in $parent)")
|
||||
}
|
||||
variable.second.linkParents(scope as Node)
|
||||
@ -228,13 +234,16 @@ private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
||||
|
||||
internal val anonymousVariablesFromHeap = mutableSetOf<Pair<LiteralValue, VarDecl>>()
|
||||
|
||||
|
||||
override fun process(literalValue: LiteralValue): LiteralValue {
|
||||
if(literalValue.heapId!=null && literalValue.parent !is VarDecl) {
|
||||
// a literal value that's not declared as a variable, which refers to something on the heap.
|
||||
// we need to introduce an auto-generated variable for this to be able to refer to the value!
|
||||
val variable = VarDecl(VarDeclType.VAR, literalValue.type, false, null, "auto_heap_value_${literalValue.heapId}", literalValue, literalValue.position)
|
||||
val variable = VarDecl(VarDeclType.VAR, literalValue.type, false, null, "$autoHeapValuePrefix${literalValue.heapId}", literalValue, literalValue.position)
|
||||
anonymousVariablesFromHeap.add(Pair(literalValue, variable))
|
||||
}
|
||||
return super.process(literalValue)
|
||||
}
|
||||
}
|
||||
|
||||
private const val autoHeapValuePrefix = "auto_heap_value_"
|
||||
|
@ -6,35 +6,14 @@
|
||||
; @todo see problem in looplabelproblem.p8
|
||||
|
||||
sub start() {
|
||||
uword z2 = sqrt16(50000)
|
||||
for ubyte i in "hello\n" {
|
||||
c64.CHROUT(i)
|
||||
}
|
||||
|
||||
c64scr.print_ub(sqrt16(0))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(sqrt16(200))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(sqrt16(20000))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(sqrt16(63333))
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(sqrt16(65535))
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
z2=0
|
||||
c64scr.print_ub(sqrt16(z2))
|
||||
c64.CHROUT('\n')
|
||||
z2=200
|
||||
c64scr.print_ub(sqrt16(z2))
|
||||
c64.CHROUT('\n')
|
||||
z2=20000
|
||||
c64scr.print_ub(sqrt16(z2))
|
||||
c64.CHROUT('\n')
|
||||
z2=63333
|
||||
c64scr.print_ub(sqrt16(z2))
|
||||
c64.CHROUT('\n')
|
||||
z2=65535
|
||||
c64scr.print_ub(sqrt16(z2))
|
||||
c64.CHROUT('\n')
|
||||
A=99
|
||||
for ubyte j in [1,2,3,4,5] {
|
||||
c64scr.print_ub(j)
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user