vardecl value inits must not be shuffled around but stay at their original line at all times

This commit is contained in:
Irmen de Jong 2020-09-18 22:24:26 +02:00
parent def06dbc0b
commit 5d900800f2
4 changed files with 78 additions and 7 deletions

View File

@ -744,7 +744,7 @@ internal class AstChecker(private val program: Program,
checkValueTypeAndRangeArray(array.type.typeOrElse(DataType.STRUCT), null, arrayspec, array)
}
if(!array.value.all { it.constValue(program)!=null }) {
if(!array.value.all { it is NumericLiteralValue || it is AddressOf || it is StringLiteralValue }) {
// TODO for now, array literals have to consist of all compile time constant values...
errors.err("array literal doesn't consist of only compile time constant values", array.position)
}

View File

@ -55,17 +55,16 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E
}
}
if (!conflicts) {
// move vardecls of the scope into the upper scope. Make sure the order remains the same!
val numericVarsWithValue = decls.filter { it.value != null && it.datatype in NumericDatatypes }.reversed()
// move vardecls of the scope into the upper scope. Make sure the position remains the same!
val numericVarsWithValue = decls.filter { it.value != null && it.datatype in NumericDatatypes }
return numericVarsWithValue.map {
val initValue = it.value!! // assume here that value has always been set by now
it.value = null // make sure no value init assignment for this vardecl will be created later (would be superfluous)
val target = AssignTarget(IdentifierReference(listOf(it.name), it.position), null, null, it.position)
val assign = Assignment(target, initValue, it.position)
initValue.parent = assign
IAstModification.InsertFirst(assign, scope)
} + decls.map { IAstModification.ReplaceNode(it, NopStatement(it.position), scope) } +
decls.map { IAstModification.InsertFirst(it, sub) } // move it up to the subroutine
IAstModification.ReplaceNode(it, assign, scope)
} + decls.map { IAstModification.InsertFirst(it, sub) } // move it up to the subroutine
}
}
return noModifications

View File

@ -38,7 +38,8 @@ main {
cx16.GRAPH_draw_rect(true)
cx16.GRAPH_set_colors(1, 0, 0)
draw_lines()
draw_lines_hiddenremoval()
;draw_lines()
anglex -= 505
angley += 217
@ -128,6 +129,7 @@ main {
const ubyte screen_height = 200
sub draw_lines() {
; simple routine that draw all edges, exactly once, but no hidden line removal.
ubyte @zp i
for i in shipdata.totalNumberOfEdges -1 downto 0 {
ubyte @zp vFrom = shipdata.edgesFrom[i]
@ -141,6 +143,45 @@ main {
cx16.GRAPH_draw_line()
}
}
sub draw_lines_hiddenremoval() {
; complex routine that draws the ship model based on its faces
; where it uses the surface normals to determine visibility.
; TODO use a pointer to the edges instead of indexing
ubyte @zp edgeIdx = 0
ubyte @zp i
for i in shipdata.totalNumberOfFaces -1 downto 0 {
ubyte e1
ubyte e2
ubyte e3
e1 = shipdata.facesEdges[edgeIdx]
edgeIdx ++
e2 = shipdata.facesEdges[edgeIdx]
edgeIdx ++
e3 = shipdata.facesEdges[edgeIdx]
edgeIdx ++
draw_edge(e1)
draw_edge(e2)
while e3!=255 {
draw_edge(e3)
e3 = shipdata.facesEdges[edgeIdx]
edgeIdx ++
}
}
}
sub draw_edge(ubyte edgeidx) {
; todo: keep track of edges that are already drawn, don't redraw
ubyte vFrom = shipdata.edgesFrom[edgeidx]
ubyte vTo = shipdata.edgesTo[edgeidx]
word persp1 = 200 + rotatedz[vFrom]/256
word persp2 = 200 + rotatedz[vTo]/256
cx16.r0 = rotatedx[vFrom] / persp1 + screen_width/2 as uword
cx16.r1 = rotatedy[vFrom] / persp1 + screen_height/2 as uword
cx16.r2 = rotatedx[vTo] / persp2 + screen_width/2 as uword
cx16.r3 = rotatedy[vTo] / persp2 + screen_height/2 as uword
cx16.GRAPH_draw_line()
}
}
shipdata {

View File

@ -16,5 +16,36 @@ main {
sub start() {
ubyte edgeIdx=0
ubyte i
; TODO the following gives the correct output:
for i in 2 downto 0 {
ubyte e1
ubyte e2
e1 = edgeIdx
edgeIdx ++
e2 = edgeIdx
edgeIdx ++
txt.print_ub(e1)
c64.CHROUT(',')
txt.print_ub(e2)
c64.CHROUT('\n')
}
c64.CHROUT('\n')
edgeIdx=0
; TODO however with inline vardecl initializers the result is WRONG:
for i in 2 downto 0 {
ubyte e1 = edgeIdx
edgeIdx++
ubyte e2 = edgeIdx
edgeIdx++
txt.print_ub(e1)
c64.CHROUT(',')
txt.print_ub(e2)
c64.CHROUT('\n')
}
}
}