variables are reset to their declared value when entering the scope again

This commit is contained in:
Irmen de Jong 2018-10-07 00:21:13 +02:00
parent 314e5ca9e2
commit 30b58c8567
7 changed files with 81 additions and 40 deletions

View File

@ -36,8 +36,7 @@
_vm_gfx_text(8, 6, 1, "Spin") _vm_gfx_text(8, 6, 1, "Spin")
_vm_gfx_text(29, 11, 1, "to Win !") _vm_gfx_text(29, 11, 1, "to Win !")
byte i for byte i in 0 to width//10 {
for i in 0 to width//10 {
_vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6) _vm_gfx_line(i*2+width//2-width//10, 130, i*10.w, 199, 6)
} }
@ -109,7 +108,6 @@
_vm_gfx_pixel(sx-1, sy+1, color) _vm_gfx_pixel(sx-1, sy+1, color)
_vm_gfx_pixel(sx, sy+1, color) _vm_gfx_pixel(sx, sy+1, color)
_vm_gfx_pixel(sx+1, sy+1, color) _vm_gfx_pixel(sx+1, sy+1, color)
_vm_gfx_pixel(sx, sy-2, color) _vm_gfx_pixel(sx, sy-2, color)
_vm_gfx_pixel(sx+2, sy, color) _vm_gfx_pixel(sx+2, sy, color)
_vm_gfx_pixel(sx, sy+2, color) _vm_gfx_pixel(sx, sy+2, color)

View File

@ -15,17 +15,13 @@
for word pixelx in xoffset to xoffset+width-1 { for word pixelx in xoffset to xoffset+width-1 {
float xx = flt((pixelx-xoffset))/width/3.0+0.2 float xx = flt((pixelx-xoffset))/width/3.0+0.2
float xsquared
float ysquared
float x
float y
byte iter ; @todo re-initialize variable when entering scope
x = 0.0 float xsquared = 0.0
y = 0.0 float ysquared = 0.0
xsquared = 0 float x = 0.0
ysquared = 0 float y = 0.0
iter = 0 byte iter = 0
while (iter<32 and xsquared+ysquared<4.0) { while (iter<32 and xsquared+ysquared<4.0) {
y = x*y*2.0 + yy y = x*y*2.0 + yy
x = xsquared - ysquared + xx x = xsquared - ysquared + xx
@ -37,10 +33,8 @@
_vm_gfx_pixel(pixelx, pixely, iter) _vm_gfx_pixel(pixelx, pixely, iter)
} }
} }
_vm_gfx_text(11, 21, 1, "Finished!") _vm_gfx_text(11, 21, 1, "Finished!")
} }
} }

View File

@ -4,15 +4,46 @@
~ main { ~ main {
byte mainb = 44
sub start() { sub start() {
test()
test()
}
; word [20] prime_numbers = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] ; todo array_w!!! sub test() {
word [20] fibonacci_numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
for word fibnr in fibonacci_numbers { ; @todo test assigning values to array vars
_vm_write_num(fibnr) ; @todo test creating const array vars
byte subb=42
for byte i in 0 to 2 {
float ff=3.3
byte bb=99
word ww=1999
_vm_write_num(ff)
_vm_write_char('\n') _vm_write_char('\n')
_vm_write_num(bb)
_vm_write_char('\n')
_vm_write_num(ww)
_vm_write_char('\n')
_vm_write_num(subb)
_vm_write_char('\n')
_vm_write_num(mainb)
_vm_write_char('\n')
_vm_write_char('\n')
ff += 3
bb += 3
ww += 3
subb += 3
mainb += 3
} }
return
} }
} }

View File

@ -623,7 +623,7 @@ class VarDecl(val type: VarDeclType,
} }
class Assignment(var target: AssignTarget, val aug_op : String?, var value: IExpression, override val position: Position) : IStatement { open class Assignment(var target: AssignTarget, val aug_op : String?, var value: IExpression, override val position: Position) : IStatement {
override lateinit var parent: Node override lateinit var parent: Node
override fun linkParents(parent: Node) { override fun linkParents(parent: Node) {
@ -639,6 +639,12 @@ class Assignment(var target: AssignTarget, val aug_op : String?, var value: IExp
} }
} }
// This is a special class so the compiler can see if the assignments are for initializing the vars in the scope,
// or just a regular assignment. It may optimize the initialization step from this.
class VariableInitializationAssignment(target: AssignTarget, aug_op: String?, value: IExpression, position: Position)
: Assignment(target, aug_op, value, position)
data class AssignTarget(val register: Register?, data class AssignTarget(val register: Register?,
val identifier: IdentifierReference?, val identifier: IdentifierReference?,
val arrayindexed: ArrayIndexedExpression?, val arrayindexed: ArrayIndexedExpression?,

View File

@ -95,21 +95,22 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
override fun process(decl: VarDecl): IStatement { override fun process(decl: VarDecl): IStatement {
super.process(decl) super.process(decl)
if(decl.type==VarDeclType.VAR || decl.type==VarDeclType.CONST) { if(decl.type!=VarDeclType.VAR || decl.value==null)
if(decl.value!=null && decl.value?.constValue(namespace, heap)==null) { return decl
// the value assigned to the variable isn't a constant.
// replace the var decl with an assignment and add a new vardecl with the default constant value. // for variables that are not on the heap (so: byte, word, float),
val scope = decl.definingScope() // replace the var decl with an assignment and add a new vardecl with the default constant value.
if(scope !in vardeclsToAdd) if(decl.datatype == DataType.BYTE || decl.datatype==DataType.WORD || decl.datatype==DataType.FLOAT) {
vardeclsToAdd[scope] = mutableListOf() val scope = decl.definingScope()
vardeclsToAdd[scope]!!.add(decl.asDefaultValueDecl()) if(scope !in vardeclsToAdd)
return Assignment( vardeclsToAdd[scope] = mutableListOf()
AssignTarget(null, IdentifierReference(decl.scopedname.split("."), decl.position), null, decl.position), vardeclsToAdd[scope]!!.add(decl.asDefaultValueDecl())
null, return VariableInitializationAssignment(
decl.value!!, AssignTarget(null, IdentifierReference(decl.scopedname.split("."), decl.position), null, decl.position),
decl.position null,
) decl.value!!,
} decl.position
)
} }
return decl return decl
} }

View File

@ -389,6 +389,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
when (stmt) { when (stmt) {
is Label -> translate(stmt) is Label -> translate(stmt)
is Return -> translate(stmt) is Return -> translate(stmt)
is VariableInitializationAssignment -> translate(stmt) // for initializing vars in a scope
is Assignment -> translate(stmt) // normal and augmented assignments is Assignment -> translate(stmt) // normal and augmented assignments
is PostIncrDecr -> translate(stmt) is PostIncrDecr -> translate(stmt)
is Jump -> translate(stmt) is Jump -> translate(stmt)
@ -1174,6 +1175,13 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
} }
} }
private fun translate(stmt: VariableInitializationAssignment) {
// this is an assignment to initialize a variable's value in the scope.
// the compiler can perhaps optimize this phase.
translate(stmt as Assignment)
}
private fun translate(stmt: Assignment) { private fun translate(stmt: Assignment) {
stackvmProg.line(stmt.position) stackvmProg.line(stmt.position)
translate(stmt.value) translate(stmt.value)

View File

@ -298,12 +298,15 @@ The largest 5-byte MFLPT float that can be stored is: **1.7014118345e+38** (ne
Initial values across multiple runs of the program Initial values across multiple runs of the program
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. todo:: When declaring values with an initial value, this value will be set into the variable each time
The initial values of your variables will be restored automatically when the program is (re)started, the program reaches the declaration again. This can be in loops, multiple subroutine calls,
*except for string variables, arrays and matrices*. It is assumed these are left unchanged by the program. or even multiple invocations of the entire program.
If you do modify them in-place, you should take care yourself that they work as
expected when the program is restarted.
This only works for simple types, *and not for string variables, arrays and matrices*.
It is assumed these are left unchanged by the program.
If you do modify them in-place, you should take care yourself that they work as
expected when the program is restarted.
(This is an optimization choice to avoid having to store two copies of every string and array)
Indirect addressing and address-of Indirect addressing and address-of