Skip to content

Commit

Permalink
enforce variable init values are only strings or arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Jan 20, 2025
1 parent 0c88283 commit 7a13f57
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 27 deletions.
12 changes: 12 additions & 0 deletions codeCore/src/prog8/code/ast/AstStatements.kt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ class PtVariable(
position: Position
) : PtNamedNode(name, position), IPtVariable {
init {

if(value!=null) {
require(value is PtArray || value is PtString) { "variable initializer value must only be array or string" }
// NOTE: the 6502 code generator expects numerical variables to not have an initialization value,
// because that is done via assignment statements. There are no "inline" variables with a given value.
// All variables are put into zeropage or into the BSS section and initialized afterwards during program
// startup or at the start of the subroutine.
// The IR codegen however is different it has a special section <VARIABLESWITHINIT> for all variables
// that have a non-zero initialization value, regardless of the datatype. It removes the initialization
// assignment and puts the value back into the variable (but only in the symboltable).
}

value?.let {it.parent=this}
}
}
Expand Down
44 changes: 25 additions & 19 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -674,28 +674,34 @@ internal class ProgramAndVarsGen(
}

private fun staticVariable2asm(variable: StStaticVariable) {
val initialValue: Number =
if(variable.initializationNumericValue!=null) {
if(variable.dt.isFloat)
variable.initializationNumericValue!!
else
variable.initializationNumericValue!!.toInt()
} else 0
if(!variable.dt.isArray && !variable.dt.isString) {
throw AssemblyError("static variables with an initialization value can only be an array or a string, not ${variable.dt} (${variable.name} ${variable.astNode?.position}")
// because numeric variables are in the BSS section and get initialized via assignment statements
}

// val initialValue: Number =
// if(variable.initializationNumericValue!=null) {
// if(variable.dt.isFloat)
// variable.initializationNumericValue!!
// else
// variable.initializationNumericValue!!.toInt()
// } else 0
//

val dt=variable.dt
when {
dt.isBool || dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
dt.isSignedByte -> asmgen.out("${variable.name}\t.char $initialValue")
dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
dt.isSignedWord -> asmgen.out("${variable.name}\t.sint $initialValue")
dt.isFloat -> {
if(initialValue==0) {
asmgen.out("${variable.name}\t.byte 0,0,0,0,0 ; float")
} else {
val floatFill = compTarget.getFloatAsmBytes(initialValue)
asmgen.out("${variable.name}\t.byte $floatFill ; float $initialValue")
}
}
// dt.isBool || dt.isUnsignedByte -> asmgen.out("${variable.name}\t.byte ${initialValue.toHex()}")
// dt.isSignedByte -> asmgen.out("${variable.name}\t.char $initialValue")
// dt.isUnsignedWord -> asmgen.out("${variable.name}\t.word ${initialValue.toHex()}")
// dt.isSignedWord -> asmgen.out("${variable.name}\t.sint $initialValue")
// dt.isFloat -> {
// if(initialValue==0) {
// asmgen.out("${variable.name}\t.byte 0,0,0,0,0 ; float")
// } else {
// val floatFill = compTarget.getFloatAsmBytes(initialValue)
// asmgen.out("${variable.name}\t.byte $floatFill ; float $initialValue")
// }
// }
dt.isString -> {
throw AssemblyError("all string vars should have been interned into prog")
}
Expand Down
4 changes: 2 additions & 2 deletions codeGenCpu6502/test/TestCodegen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class TestCodegen: FunSpec({
DataType.forDt(BaseDataType.UBYTE),
ZeropageWish.DONTCARE,
0u,
PtNumber(BaseDataType.UBYTE, 0.0, Position.DUMMY),
null,
null,
Position.DUMMY
))
Expand All @@ -81,7 +81,7 @@ class TestCodegen: FunSpec({
DataType.forDt(BaseDataType.WORD),
ZeropageWish.DONTCARE,
0u,
PtNumber(BaseDataType.WORD, 1.0, Position.DUMMY),
null,
null,
Position.DUMMY
))
Expand Down
4 changes: 2 additions & 2 deletions codeGenIntermediate/test/TestVmCodeGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TestVmCodeGen: FunSpec({
DataType.forDt(BaseDataType.UBYTE),
ZeropageWish.DONTCARE,
0u,
PtNumber(BaseDataType.UBYTE, 0.0, Position.DUMMY),
null,
null,
Position.DUMMY
))
Expand All @@ -78,7 +78,7 @@ class TestVmCodeGen: FunSpec({
DataType.forDt(BaseDataType.WORD),
ZeropageWish.DONTCARE,
0u,
PtNumber(BaseDataType.WORD, 1.0, Position.DUMMY),
null,
null,
Position.DUMMY
))
Expand Down
8 changes: 6 additions & 2 deletions compiler/test/codegeneration/TestAsmGenSymbols.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import prog8.code.source.SourceCode
import prog8.code.target.C64Target
import prog8.code.target.VMTarget
import prog8.codegen.cpu6502.AsmGen6502Internal
import prog8.compiler.astprocessing.AstChecker
import prog8.compiler.astprocessing.SimplifiedAstMaker
import prog8tests.helpers.*

Expand All @@ -31,7 +32,7 @@ class TestAsmGenSymbols: StringSpec({
uword var_outside
sub start () {
uword localvar = 1234
uword localvar
uword tgt
locallabel:
Expand All @@ -48,7 +49,7 @@ class TestAsmGenSymbols: StringSpec({
*/
val varInSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UWORD), ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "localvar", emptyList(), NumericLiteral.optimalInteger(1234, Position.DUMMY), false, 0u, false, Position.DUMMY)
SplitWish.DONTCARE, null, "localvar", emptyList(), null, false, 0u, false, Position.DUMMY)
val var2InSub = VarDecl(VarDeclType.VAR, VarDeclOrigin.USERCODE, DataType.forDt(BaseDataType.UWORD), ZeropageWish.DONTCARE,
SplitWish.DONTCARE, null, "tgt", emptyList(), null, false, 0u, false, Position.DUMMY)
val labelInSub = Label("locallabel", Position.DUMMY)
Expand Down Expand Up @@ -79,6 +80,9 @@ class TestAsmGenSymbols: StringSpec({
fun createTestAsmGen6502(program: Program): AsmGen6502Internal {
val errors = ErrorReporterForTests()
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), CompilationOptions.AllZeropageAllowed, false, true, C64Target(), 999u, 0xffffu)
val astchecker = AstChecker(program, errors, options)
astchecker.visit(program)
errors.report()
val ptProgram = SimplifiedAstMaker(program, errors).transform()
val st = SymbolTableMaker(ptProgram, options).make()
return AsmGen6502Internal(ptProgram, st, options, errors, 0)
Expand Down
7 changes: 5 additions & 2 deletions examples/test.p8
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@


main {

ubyte @nozp @shared staticvar=51

sub start() {
ubyte x = math.rnd()
ubyte a,b = multi1()
ubyte c,d = 99
ubyte c,d = multi2()

x++
x=irmen
txt.print_ub(a)
txt.spc()
txt.print_ub(b)
Expand Down

0 comments on commit 7a13f57

Please sign in to comment.