1
0
mirror of https://github.com/irmen/prog8.git synced 2025-01-14 01:29:55 +00:00

fix vm crash on empty string

This commit is contained in:
Irmen de Jong 2023-03-04 15:35:54 +01:00
parent fd269453a4
commit 448d176c24
5 changed files with 35 additions and 9 deletions
codeCore/src/prog8/code
compiler/test
docs/source
intermediate
src/prog8/intermediate
test

@ -54,7 +54,17 @@ class SymbolTable(astProgram: PtProgram) : StNode(astProgram.name, StNodeType.GL
} }
val allMemorySlabs: Collection<StMemorySlab> by lazy { val allMemorySlabs: Collection<StMemorySlab> by lazy {
children.mapNotNull { if (it.value.type == StNodeType.MEMORYSLAB) it.value as StMemorySlab else null } val vars = mutableListOf<StMemorySlab>()
fun collect(node: StNode) {
for(child in node.children) {
if(child.value.type== StNodeType.MEMORYSLAB)
vars.add(child.value as StMemorySlab)
else
collect(child.value)
}
}
collect(this)
vars
} }
override fun lookup(scopedName: String) = flat[scopedName] override fun lookup(scopedName: String) = flat[scopedName]
@ -168,7 +178,9 @@ class StStaticVariable(name: String,
} }
if(onetimeInitializationArrayValue!=null) { if(onetimeInitializationArrayValue!=null) {
require(dt in ArrayDatatypes) require(dt in ArrayDatatypes)
require(onetimeInitializationArrayValue.any { it.number!=0.0} ) { "array of all zerors as init value should just remain uninitialized"} if(onetimeInitializationArrayValue.all { it.number!=null} ) {
require(onetimeInitializationArrayValue.any { it.number != 0.0 }) { "array of all zerors as init value should just remain uninitialized" }
}
} }
if(onetimeInitializationStringValue!=null) { if(onetimeInitializationStringValue!=null) {
require(dt == DataType.STR) require(dt == DataType.STR)

@ -59,7 +59,7 @@ class TestSymbolTable: FunSpec({
sub1.name shouldBe "sub1" sub1.name shouldBe "sub1"
sub1.scopedName shouldBe "block1.sub1" sub1.scopedName shouldBe "block1.sub1"
sub1.type shouldBe StNodeType.SUBROUTINE sub1.type shouldBe StNodeType.SUBROUTINE
sub1.children.size shouldBe 2 sub1.children.size shouldBe 4
val v1 = sub1.lookupUnscopedOrElse("v1") { fail("v1 must be found") } as StStaticVariable val v1 = sub1.lookupUnscopedOrElse("v1") { fail("v1 must be found") } as StStaticVariable
v1.type shouldBe StNodeType.STATICVAR v1.type shouldBe StNodeType.STATICVAR
@ -75,7 +75,13 @@ class TestSymbolTable: FunSpec({
subsub.lookupUnscoped("label") shouldNotBe null subsub.lookupUnscoped("label") shouldNotBe null
} }
// TODO add more SymbolTable tests test("symboltable collections") {
val st= makeSt()
st.allVariables.size shouldBe 4
st.allMemMappedVariables.single().scopedName shouldBe "block1.sub1.v3"
st.allMemorySlabs.single().scopedName shouldBe "block1.sub1.slab1"
}
}) })
@ -93,10 +99,14 @@ private fun makeSt(): SymbolTable {
val astSub2 = PtSub("sub2", emptyList(), null, Position.DUMMY) val astSub2 = PtSub("sub2", emptyList(), null, Position.DUMMY)
val astSub1v1 = PtVariable("v1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY) val astSub1v1 = PtVariable("v1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)
val astSub1v2 = PtVariable("v2", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY) val astSub1v2 = PtVariable("v2", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY)
val astSub1v3 = PtVariable("v3", DataType.FLOAT, ZeropageWish.DONTCARE,null, null, Position.DUMMY)
val astSub1v4 = PtVariable("slab1", DataType.UWORD, ZeropageWish.DONTCARE,null, null, Position.DUMMY)
val astSub2v1 = PtVariable("v1", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY) val astSub2v1 = PtVariable("v1", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY)
val astSub2v2 = PtVariable("v2", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY) val astSub2v2 = PtVariable("v2", DataType.BYTE, ZeropageWish.DONTCARE,null, null, Position.DUMMY)
astSub1.add(astSub1v1) astSub1.add(astSub1v1)
astSub1.add(astSub1v2) astSub1.add(astSub1v2)
astSub1.add(astSub1v3)
astSub1.add(astSub1v4)
astSub2.add(astSub2v2) astSub2.add(astSub2v2)
astSub2.add(astSub2v2) astSub2.add(astSub2v2)
astBlock1.add(astSub1) astBlock1.add(astSub1)
@ -126,9 +136,10 @@ private fun makeSt(): SymbolTable {
block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2)) block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2))
sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v1)) sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v1))
sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2)) sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub1v2))
sub11.add(StMemVar("v3", DataType.FLOAT, 12345u, null, astSub1v3))
sub11.add(StMemorySlab("slab1", 200u, 64u, astSub1v4))
sub12.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1)) sub12.add(StStaticVariable("v1", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v1))
sub12.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2)) sub12.add(StStaticVariable("v2", DataType.BYTE, null, null, null, null, ZeropageWish.DONTCARE, astSub2v2))
val block2 = StNode("block2", StNodeType.BLOCK, astBlock2) val block2 = StNode("block2", StNodeType.BLOCK, astBlock2)
val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21) val sub21 = StNode("sub1", StNodeType.SUBROUTINE, astSub21)
val sub22 = StNode("sub2", StNodeType.SUBROUTINE, astSub22) val sub22 = StNode("sub2", StNodeType.SUBROUTINE, astSub22)

@ -3,7 +3,6 @@ TODO
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
- fix compiler crash on Virtual Textelite example
- add optimizations for integer X <= Y-1 ---> X<Y , X >= Y+1 ---> X>Y - add optimizations for integer X <= Y-1 ---> X<Y , X >= Y+1 ---> X>Y
- add optimizations for integer: - add optimizations for integer:
X >= 1 => X > 0 (signed and unsigned) X >= 1 => X > 0 (signed and unsigned)
@ -11,8 +10,6 @@ For next minor release
X <= -1 => X >= 0 (signed only) X <= -1 => X >= 0 (signed only)
X > -1 => X >= 0 (signed only) X > -1 => X >= 0 (signed only)
- TestSymbolTable: add some more tests
... ...

@ -215,6 +215,9 @@ class IRFileReader {
else -> throw IRParseException("weird dt") else -> throw IRParseException("weird dt")
} }
val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY) val dummyNode = PtVariable(name, dt, zp, null, null, Position.DUMMY)
if(arraysize!=null && initArray!=null && initArray.all { it.number==0.0 }) {
initArray=null // arrays with just zeros can be left uninitialized
}
variables.add(StStaticVariable(name, dt, initNumeric, null, initArray, arraysize, zp, dummyNode)) variables.add(StStaticVariable(name, dt, initNumeric, null, initArray, arraysize, zp, dummyNode))
} }
return variables return variables

@ -59,6 +59,7 @@ uword sys.bssvar zp=DONTCARE
</VARIABLESNOINIT> </VARIABLESNOINIT>
<VARIABLESWITHINIT> <VARIABLESWITHINIT>
uword sys.wait.jiffies=10 zp=DONTCARE uword sys.wait.jiffies=10 zp=DONTCARE
ubyte[3] sys.emptystring=0,0,0 zp=DONTCARE
</VARIABLESWITHINIT> </VARIABLESWITHINIT>
<MEMORYMAPPEDVARIABLES> <MEMORYMAPPEDVARIABLES>
@ -106,10 +107,12 @@ return
tempfile.deleteExisting() tempfile.deleteExisting()
program.name shouldBe "test-ir-reader" program.name shouldBe "test-ir-reader"
program.blocks.size shouldBe 2 program.blocks.size shouldBe 2
program.st.allVariables().count() shouldBe 2 program.st.allVariables().count() shouldBe 3
val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable
val var2 = program.st.lookup("sys.bssvar") as StStaticVariable val var2 = program.st.lookup("sys.bssvar") as StStaticVariable
val var3 = program.st.lookup("sys.emptystring") as StStaticVariable
var1.uninitialized shouldBe false var1.uninitialized shouldBe false
var2.uninitialized shouldBe true var2.uninitialized shouldBe true
var3.uninitialized shouldBe true
} }
}) })