mirror of
https://github.com/irmen/prog8.git
synced 2025-02-28 09:29:26 +00:00
fix Return when dealing with non-subroutine scopes
This commit is contained in:
parent
268856823a
commit
b11d10e2ff
@ -17,7 +17,6 @@ class RuntimeVariables {
|
||||
val where = vars.getValue(scope)
|
||||
where[name] = initialValue
|
||||
vars[scope] = where
|
||||
println("DEFINE RUNTIMEVAR: ${scope.name}.$name = $initialValue") // TODO
|
||||
}
|
||||
|
||||
fun set(scope: INameScope, name: String, value: RuntimeValue) {
|
||||
@ -27,7 +26,6 @@ class RuntimeVariables {
|
||||
throw VmExecutionException("new value is of different datatype ${value.type} expected ${existing.type} for $name")
|
||||
where[name] = value
|
||||
vars[scope] = where
|
||||
println("SET RUNTIMEVAR: ${scope.name}.$name = $value") // TODO
|
||||
}
|
||||
|
||||
fun get(scope: INameScope, name: String): RuntimeValue {
|
||||
@ -110,14 +108,11 @@ class AstVm(val program: Program) {
|
||||
class LoopControlContinue: Exception()
|
||||
class LoopControlReturn(val returnvalues: List<RuntimeValue>): Exception()
|
||||
|
||||
internal fun executeSubroutine(sub: INameScope, arguments: List<RuntimeValue>): List<RuntimeValue> {
|
||||
internal fun executeSubroutine(sub: Subroutine, arguments: List<RuntimeValue>): List<RuntimeValue> {
|
||||
assert(!sub.isAsmSubroutine)
|
||||
if (sub.statements.isEmpty())
|
||||
if(sub !is AnonymousScope)
|
||||
throw VmTerminationException("scope contains no statements: $sub")
|
||||
if(sub is Subroutine) {
|
||||
assert(!sub.isAsmSubroutine)
|
||||
// TODO process arguments if it's a subroutine
|
||||
}
|
||||
throw VmTerminationException("scope contains no statements: $sub")
|
||||
// TODO process arguments if it's a subroutine
|
||||
try {
|
||||
for (s in sub.statements) {
|
||||
executeStatement(sub, s)
|
||||
@ -125,14 +120,18 @@ class AstVm(val program: Program) {
|
||||
} catch (r: LoopControlReturn) {
|
||||
return r.returnvalues
|
||||
}
|
||||
if(sub !is AnonymousScope)
|
||||
throw VmTerminationException("instruction pointer overflow, is a return missing? $sub")
|
||||
return emptyList()
|
||||
throw VmTerminationException("instruction pointer overflow, is a return missing? $sub")
|
||||
}
|
||||
|
||||
internal fun executeAnonymousScope(scope: INameScope) {
|
||||
for (s in scope.statements) {
|
||||
executeStatement(scope, s)
|
||||
}
|
||||
}
|
||||
|
||||
private fun executeStatement(sub: INameScope, stmt: IStatement) {
|
||||
instructionCounter++
|
||||
if(instructionCounter % 10 == 0)
|
||||
if(instructionCounter % 100 == 0)
|
||||
Thread.sleep(1)
|
||||
when (stmt) {
|
||||
is NopStatement, is Label, is Subroutine -> {
|
||||
@ -249,15 +248,13 @@ class AstVm(val program: Program) {
|
||||
is InlineAssembly -> {
|
||||
throw VmExecutionException("can't execute inline assembly in $sub")
|
||||
}
|
||||
is AnonymousScope -> {
|
||||
throw VmExecutionException("anonymous scopes should have been flattened")
|
||||
}
|
||||
is AnonymousScope -> executeAnonymousScope(stmt)
|
||||
is IfStatement -> {
|
||||
val condition = evaluate(stmt.condition, program, runtimeVariables, ::executeSubroutine)
|
||||
if(condition.asBoolean)
|
||||
executeSubroutine(stmt.truepart, emptyList())
|
||||
executeAnonymousScope(stmt.truepart)
|
||||
else
|
||||
executeSubroutine(stmt.elsepart, emptyList())
|
||||
executeAnonymousScope(stmt.elsepart)
|
||||
}
|
||||
is BranchStatement -> {
|
||||
TODO("$stmt")
|
||||
@ -276,8 +273,7 @@ class AstVm(val program: Program) {
|
||||
var condition = evaluate(stmt.condition, program, runtimeVariables, ::executeSubroutine)
|
||||
while (condition.asBoolean) {
|
||||
try {
|
||||
println("STILL IN WHILE LOOP ${stmt.position}")
|
||||
executeSubroutine(stmt.body, emptyList())
|
||||
executeAnonymousScope(stmt.body)
|
||||
condition = evaluate(stmt.condition, program, runtimeVariables, ::executeSubroutine)
|
||||
} catch(b: LoopControlBreak) {
|
||||
break
|
||||
@ -285,13 +281,12 @@ class AstVm(val program: Program) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
println(">>>>WHILE LOOP EXITED")
|
||||
}
|
||||
is RepeatLoop -> {
|
||||
do {
|
||||
val condition = evaluate(stmt.untilCondition, program, runtimeVariables, ::executeSubroutine)
|
||||
try {
|
||||
executeSubroutine(stmt.body, emptyList())
|
||||
executeAnonymousScope(stmt.body)
|
||||
} catch(b: LoopControlBreak) {
|
||||
break
|
||||
} catch(c: LoopControlContinue){
|
||||
|
@ -56,7 +56,7 @@ fun evaluate(expr: IExpression, program: Program, runtimeVars: RuntimeVariables,
|
||||
is AddressOf -> {
|
||||
// we support: address of heap var -> the heap id
|
||||
val heapId = expr.identifier.heapId(program.namespace)
|
||||
return RuntimeValue(DataType.UWORD, heapId = heapId)
|
||||
return RuntimeValue(DataType.UWORD, heapId)
|
||||
}
|
||||
is DirectMemoryRead -> {
|
||||
TODO("$expr")
|
||||
|
135
examples/test.p8
135
examples/test.p8
@ -3,106 +3,49 @@
|
||||
|
||||
~ main {
|
||||
|
||||
ubyte[256] sieve
|
||||
ubyte candidate_prime = 2 ; is increased in the loop
|
||||
|
||||
sub start() {
|
||||
memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs
|
||||
|
||||
ubyte ub = 10
|
||||
byte bb=-100
|
||||
uword uw = 1000
|
||||
word ww = -25000
|
||||
ubyte i = 0
|
||||
; calculate primes
|
||||
c64scr.print("prime numbers up to 255:\n\n")
|
||||
ubyte amount=0
|
||||
while true {
|
||||
ubyte prime = find_next_prime()
|
||||
if prime==0
|
||||
break
|
||||
c64scr.print_ub(prime)
|
||||
c64scr.print(", ")
|
||||
amount++
|
||||
}
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print("number of primes (expected 54): ")
|
||||
c64scr.print_ub(amount)
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
|
||||
while i < 100 {
|
||||
bb += 10
|
||||
c64scr.print_b(bb)
|
||||
c64.CHROUT(',')
|
||||
i++
|
||||
|
||||
sub find_next_prime() -> ubyte {
|
||||
|
||||
while sieve[candidate_prime] {
|
||||
candidate_prime++
|
||||
if candidate_prime==0
|
||||
return 0 ; we wrapped; no more primes available in the sieve
|
||||
}
|
||||
|
||||
; c64scr.print("while1\n")
|
||||
; while(ub < 220) {
|
||||
; c64scr.print_ub(ub)
|
||||
; c64.CHROUT(',')
|
||||
; ub += 25
|
||||
; if ub < 150 continue else break
|
||||
; ub=99
|
||||
; }
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("while2\n")
|
||||
; while(bb < 120) {
|
||||
; c64scr.print_b(bb)
|
||||
; c64.CHROUT(',')
|
||||
; bb += 25
|
||||
; if bb < 50 continue else break
|
||||
; bb=99
|
||||
; }
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("while3\n")
|
||||
; while(uw < 50000) {
|
||||
; c64scr.print_uw(uw)
|
||||
; c64.CHROUT(',')
|
||||
; uw += 2500
|
||||
; if uw < 30000 continue else break
|
||||
; uw=9999
|
||||
; }
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("while4\n")
|
||||
; while(ww < 30000) {
|
||||
; c64scr.print_w(ww)
|
||||
; c64.CHROUT(',')
|
||||
; ww += 2500
|
||||
; if ww < 10000 continue else break
|
||||
; ww=9999
|
||||
; }
|
||||
; c64.CHROUT('\n')
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; ub=22
|
||||
; bb=-111
|
||||
; uw=2222
|
||||
; ww=-22222
|
||||
;
|
||||
; c64scr.print("repeat1\n")
|
||||
; repeat {
|
||||
; c64scr.print_ub(ub)
|
||||
; c64.CHROUT(',')
|
||||
; ub += 22
|
||||
; ; if ub < 150 continue else break
|
||||
; ;ub=99
|
||||
; } until ub>200
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("repeat2\n")
|
||||
; repeat {
|
||||
; c64scr.print_b(bb)
|
||||
; c64.CHROUT(',')
|
||||
; bb += 22
|
||||
; ;if bb < 50 continue else break
|
||||
; ;bb=99
|
||||
; } until bb > 100
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("repeat3\n")
|
||||
; repeat {
|
||||
; c64scr.print_uw(uw)
|
||||
; c64.CHROUT(',')
|
||||
; uw += 2222
|
||||
; ;if uw < 30000 continue else break
|
||||
; ;uw=9999
|
||||
; } until uw>50000
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; c64scr.print("repeat4\n")
|
||||
; repeat {
|
||||
; c64scr.print_w(ww)
|
||||
; c64.CHROUT(',')
|
||||
; ww += 2222
|
||||
; ;if ww < 10000 continue else break
|
||||
; ;ww=9999
|
||||
; } until ww > 20000
|
||||
; c64.CHROUT('\n')
|
||||
; c64.CHROUT('\n')
|
||||
; found next one, mark the multiples and return it.
|
||||
sieve[candidate_prime] = true
|
||||
uword multiple = candidate_prime
|
||||
|
||||
|
||||
while multiple < len(sieve) {
|
||||
sieve[lsb(multiple)] = true
|
||||
multiple += candidate_prime
|
||||
; c64scr.print_uw(multiple) ; TODO
|
||||
; c4.CHROUT('\n') ; TODO
|
||||
}
|
||||
return candidate_prime
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user