mirror of
https://github.com/irmen/prog8.git
synced 2024-11-27 03:50:27 +00:00
Initial variable values semantics changed: now always sets value at program (re)start (except strings/arrays).
This may change later by introducing a compiler option to choose a strategy, perhaps.
This commit is contained in:
parent
7232134931
commit
3a99115070
@ -19,8 +19,13 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
|
||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
// collect all variables that have an initialisation value
|
||||
if(decl.value!=null && decl.type== VarDeclType.VAR && decl.datatype in NumericDatatypes)
|
||||
decl.definingBlock().initialValues += decl
|
||||
val declValue = decl.value
|
||||
if(declValue!=null
|
||||
&& decl.type== VarDeclType.VAR
|
||||
&& decl.datatype in NumericDatatypes
|
||||
&& declValue.constValue(program)!=null) {
|
||||
decl.definingBlock().initialValues[decl.scopedname] = decl
|
||||
}
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ class Block(override val name: String,
|
||||
val idx = statements.indexOf(node)
|
||||
statements[idx] = replacement
|
||||
}
|
||||
val initialValues = mutableListOf<VarDecl>() // will be gathered by one of the Ast processing steps
|
||||
val initialValues = mutableMapOf<String, VarDecl>() // will be gathered by one of the Ast processing steps
|
||||
|
||||
override fun accept(visitor: IAstModifyingVisitor) = visitor.visit(this)
|
||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
|
@ -175,10 +175,10 @@ internal class AsmGen(private val program: Program,
|
||||
// it will be called from program init.
|
||||
if(block.initialValues.isNotEmpty()) {
|
||||
out("prog8_init_vars\t.proc\n")
|
||||
block.initialValues.forEach {
|
||||
val target = AssignTarget(null, IdentifierReference(listOf(it.scopedname), it.position), null, null, it.position)
|
||||
val assign = Assignment(target, null, it.value!!, it.position)
|
||||
assign.linkParents(it.parent)
|
||||
block.initialValues.forEach { (scopedName, decl) ->
|
||||
val target = AssignTarget(null, IdentifierReference(scopedName.split('.'), decl.position), null, null, decl.position)
|
||||
val assign = Assignment(target, null, decl.value!!, decl.position)
|
||||
assign.linkParents(decl.parent)
|
||||
assignmentAsmGen.translate(assign)
|
||||
}
|
||||
out(" rts\n .pend")
|
||||
|
@ -198,6 +198,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
when(expr.operator) {
|
||||
">>" -> {
|
||||
// bit-shifts are always by a constant number (for now)
|
||||
// TODO for everything except UBYTE, if shifting > 2 bits, use a subroutine
|
||||
translateExpression(expr.left)
|
||||
val amount = expr.right.constValue(program)!!.number.toInt()
|
||||
when (leftDt) {
|
||||
@ -211,6 +212,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
||||
}
|
||||
"<<" -> {
|
||||
// bit-shifts are always by a constant number (for now)
|
||||
// TODO for the word types, if shifting > 3 bits, use a subroutine
|
||||
translateExpression(expr.left)
|
||||
val amount = expr.right.constValue(program)!!.number.toInt()
|
||||
if (leftDt in ByteDatatypes)
|
||||
|
@ -369,18 +369,7 @@ Initial values across multiple runs of the program
|
||||
When declaring values with an initial value, this value will be set into the variable each time
|
||||
the program reaches the declaration again. This can be in loops, multiple subroutine calls,
|
||||
or even multiple invocations of the entire program.
|
||||
|
||||
.. sidebar::
|
||||
Zeroing not for ZP
|
||||
|
||||
If a variable gets allocated in zero-page, it will *not* be set to zero for you at
|
||||
the start of the program. Instead, it will simply be whatever the last value in that zero page
|
||||
location was. Code should not depend on the uninitialized starting value of such variables.
|
||||
|
||||
If you omit an initial value, it will
|
||||
be set to zero *but only for the first run of the program*. A second run will utilize the last value
|
||||
where it left off (but your code will be a bit smaller because no initialization instructions
|
||||
are generated)
|
||||
If you omit the initial value, zero will be used instead.
|
||||
|
||||
This only works for simple types, *and not for string variables and arrays*.
|
||||
It is assumed these are left unchanged by the program; they are not re-initialized on
|
||||
|
@ -216,7 +216,8 @@ Variable declarations
|
||||
|
||||
Variables should be declared with their exact type and size so the compiler can allocate storage
|
||||
for them. You can give them an initial value as well. That value can be a simple literal value,
|
||||
or an expression. You can add a ``@zp`` zeropage-tag, to tell the compiler to prioritize it
|
||||
or an expression. If you don't provide an intial value yourself, zero will be used.
|
||||
You can add a ``@zp`` zeropage-tag, to tell the compiler to prioritize it
|
||||
when selecting variables to be put into zeropage.
|
||||
The syntax is::
|
||||
|
||||
@ -321,7 +322,7 @@ Constants
|
||||
^^^^^^^^^
|
||||
|
||||
All variables can be assigned new values unless you use the ``const`` keyword.
|
||||
The initial value will now be evaluated at compile time (it must be a compile time constant expression).
|
||||
The initial value must be known at compile time (it must be a compile time constant expression).
|
||||
This is only valid for the simple numeric types (byte, word, float)::
|
||||
|
||||
const byte max_age = 99
|
||||
|
@ -4,7 +4,9 @@ TODO
|
||||
|
||||
- remove statements after an exit() or return
|
||||
- fix warnings about that unreachable code?
|
||||
- why are some programs for example cube3d increasing in size when compiling with optimizations???
|
||||
|
||||
- add a compiler option to not include variable initialization code (useful if the program is expected to run only once, such as a game)
|
||||
the program will then rely solely on the values as they are in memory at the time of program startup.
|
||||
|
||||
- create real assembly routines for the bresenham line and circle code
|
||||
- also add assembly routines in c64scr for drawing rectangles (filled/open)
|
||||
|
@ -1,55 +1,68 @@
|
||||
%import c64utils
|
||||
;%import c64flt
|
||||
;%option enable_floats
|
||||
%zeropage basicsafe
|
||||
%zeropage dontuse
|
||||
|
||||
main {
|
||||
|
||||
sub subje() {
|
||||
ubyte xyz = 123
|
||||
ubyte foo
|
||||
c64scr.print_ub(xyz)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(foo)
|
||||
c64.CHROUT('\n')
|
||||
xyz++
|
||||
foo++
|
||||
}
|
||||
|
||||
sub start() {
|
||||
ubyte xyz = 99 ; TODO fix compiler error when removing unused var
|
||||
word wcosa = cos8(xyz)
|
||||
word wcosa_sinb = wcosa / 128
|
||||
; TODO fix too much assembly in prog8_init_vars
|
||||
|
||||
subje()
|
||||
subje()
|
||||
subje()
|
||||
|
||||
ubyte ub1
|
||||
ubyte ub2 = 99
|
||||
uword uw1
|
||||
uword uw2 = 9999
|
||||
ubyte[5] array1
|
||||
ubyte[5] array2 = [22,33,44,55,66]
|
||||
|
||||
c64scr.print_ub(ub1)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(ub2)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_uw(uw1)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_uw(uw2)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(array1[0])
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(array2[0])
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ub1++
|
||||
ub2++
|
||||
uw1++
|
||||
uw2++
|
||||
array1[0]++
|
||||
array2[0]++
|
||||
|
||||
c64scr.print_ub(ub1)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(ub2)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_uw(uw1)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_uw(uw2)
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(array1[0])
|
||||
c64.CHROUT(',')
|
||||
c64scr.print_ub(array2[0])
|
||||
c64.CHROUT('\n')
|
||||
; ubyte ub1
|
||||
; ubyte ub2 = 99
|
||||
; uword uw1
|
||||
; uword uw2 = 9999
|
||||
; ubyte[5] array1
|
||||
; ubyte[5] array2 = [22,33,44,55,66]
|
||||
;
|
||||
; c64scr.print_ub(ub1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(ub2)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uw(uw1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uw(uw2)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(array1[0])
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(array2[0])
|
||||
; c64.CHROUT('\n')
|
||||
;
|
||||
; ub1++
|
||||
; ub2++
|
||||
; uw1++
|
||||
; uw2++
|
||||
; array1[0]++
|
||||
; array2[0]++
|
||||
;
|
||||
; c64scr.print_ub(ub1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(ub2)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uw(uw1)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_uw(uw2)
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(array1[0])
|
||||
; c64.CHROUT(',')
|
||||
; c64scr.print_ub(array2[0])
|
||||
; c64.CHROUT('\n')
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user