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) 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... // 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) 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) { if (!conflicts) {
// move vardecls of the scope into the upper scope. Make sure the order remains the same! // 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 }.reversed() val numericVarsWithValue = decls.filter { it.value != null && it.datatype in NumericDatatypes }
return numericVarsWithValue.map { return numericVarsWithValue.map {
val initValue = it.value!! // assume here that value has always been set by now 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) 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 target = AssignTarget(IdentifierReference(listOf(it.name), it.position), null, null, it.position)
val assign = Assignment(target, initValue, it.position) val assign = Assignment(target, initValue, it.position)
initValue.parent = assign initValue.parent = assign
IAstModification.InsertFirst(assign, scope) IAstModification.ReplaceNode(it, assign, scope)
} + decls.map { IAstModification.ReplaceNode(it, NopStatement(it.position), scope) } + } + decls.map { IAstModification.InsertFirst(it, sub) } // move it up to the subroutine
decls.map { IAstModification.InsertFirst(it, sub) } // move it up to the subroutine
} }
} }
return noModifications return noModifications

View File

@ -38,7 +38,8 @@ main {
cx16.GRAPH_draw_rect(true) cx16.GRAPH_draw_rect(true)
cx16.GRAPH_set_colors(1, 0, 0) cx16.GRAPH_set_colors(1, 0, 0)
draw_lines() draw_lines_hiddenremoval()
;draw_lines()
anglex -= 505 anglex -= 505
angley += 217 angley += 217
@ -128,6 +129,7 @@ main {
const ubyte screen_height = 200 const ubyte screen_height = 200
sub draw_lines() { sub draw_lines() {
; simple routine that draw all edges, exactly once, but no hidden line removal.
ubyte @zp i ubyte @zp i
for i in shipdata.totalNumberOfEdges -1 downto 0 { for i in shipdata.totalNumberOfEdges -1 downto 0 {
ubyte @zp vFrom = shipdata.edgesFrom[i] ubyte @zp vFrom = shipdata.edgesFrom[i]
@ -141,6 +143,45 @@ main {
cx16.GRAPH_draw_line() 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 { shipdata {

View File

@ -16,5 +16,36 @@ main {
sub start() { 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')
}
} }
} }