some ast2 var tweaks

This commit is contained in:
Irmen de Jong 2024-10-21 00:20:54 +02:00
parent 6de760885f
commit 0247fb0d84
8 changed files with 42 additions and 11 deletions

View File

@ -66,23 +66,26 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
val numElements: Int?
val value = node.value
if(value!=null) {
val number = (value as? PtNumber)?.number
initialNumeric = if(number==0.0) null else number // 0 as init value -> just uninitialized
when (value) {
is PtString -> {
initialString = StString(value.value, value.encoding)
initialArray = null
initialNumeric = null
numElements = value.value.length + 1 // include the terminating 0-byte
}
is PtArray -> {
initialArray = makeInitialArray(value)
initialString = null
initialNumeric = null
numElements = initialArray.size
require(node.arraySize?.toInt()==numElements)
}
else -> {
require(value is PtNumber)
initialString = null
initialArray = null
val number = value.number
initialNumeric = if(number==0.0) null else number // 0 as init value -> just uninitialized TODO weird?
numElements = node.arraySize?.toInt()
}
}

View File

@ -238,6 +238,13 @@ class PtFunctionCall(val name: String,
position: Position) : PtExpression(type, position) {
val args: List<PtExpression>
get() = children.map { it as PtExpression }
init {
if(void) require(type==DataType.UNDEFINED) {
"void fcall should have undefined datatype"
}
// note: non-void calls can have UNDEFINED type: is if they return more than 1 value
}
}

View File

@ -0,0 +1,16 @@
package prog8.code.ast
import prog8.code.SymbolTable
import prog8.code.core.*
fun verifyFinalAstBeforeAsmGen(program: PtProgram, options: CompilationOptions, st: SymbolTable, errors: IErrorReporter) {
/*
walkAst(program) { node, _ ->
if(node is PtVariable) {
if(node.value!=null) {
// require(node.type in ArrayDatatypes || node.type==DataType.STR) { "final check before asmgen: only string and array variables can still have an init value ${node.name} ${node.type} ${node.position}"}
}
}
}
*/
}

View File

@ -60,7 +60,7 @@ private fun optimizeAssignTargets(program: PtProgram, st: SymbolTable, errors: I
if(node.children.dropLast(1).all { (it as PtAssignTarget).void }) {
// all targets are now void, the whole assignment can be discarded and replaced by just a (void) call to the subroutine
val index = node.parent.children.indexOf(node)
val voidCall = PtFunctionCall(functionName, true, value.type, value.position)
val voidCall = PtFunctionCall(functionName, true, DataType.UNDEFINED, value.position)
value.children.forEach { voidCall.add(it) }
node.parent.children[index] = voidCall
voidCall.parent = node.parent

View File

@ -12,6 +12,7 @@ import prog8.ast.statements.Directive
import prog8.code.SymbolTableMaker
import prog8.code.ast.PtProgram
import prog8.code.ast.printAst
import prog8.code.ast.verifyFinalAstBeforeAsmGen
import prog8.code.core.*
import prog8.code.optimize.optimizeIntermediateAst
import prog8.code.target.AtariTarget
@ -146,6 +147,9 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
println("*********** INTERMEDIATE AST END *************\n")
}
verifyFinalAstBeforeAsmGen(intermediateAst, compilationOptions, symbolTable, args.errors)
args.errors.report()
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
System.err.println("Error in codegeneration or assembler")
return null

View File

@ -1,17 +1,11 @@
package prog8tests.ast
import io.kotest.assertions.fail
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.ints.shouldBeGreaterThan
import io.kotest.matchers.shouldBe
import io.kotest.matchers.types.instanceOf
import prog8.code.ast.*
import prog8.code.ast.PtBinaryExpression
import prog8.code.ast.PtNumber
import prog8.code.core.DataType
import prog8.code.core.Position
import prog8.code.target.C64Target
import prog8.compiler.astprocessing.IntermediateAstMaker
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.compileText
class TestIntermediateAst: FunSpec({

View File

@ -134,6 +134,7 @@ rol (x)
(essentially, it is a 9-bit or 17-bit rotation)
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can rol a memory location directly by using the direct memory access syntax, so like ``rol(@($5000))``
You can use ``if_cc`` or ``if_cs`` after a rol to act on the new carry bit, if required.
rol2 (x)
Like ``rol`` but now as 8-bit or 16-bit rotation.
@ -148,6 +149,7 @@ ror (x)
(essentially, it is a 9-bit or 17-bit rotation)
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can ror a memory location directly by using the direct memory access syntax, so like ``ror(@($5000))``
You can use ``if_cc`` or ``if_cs`` after a ror to act on the new carry bit, if required.
ror2 (x)
Like ``ror`` but now as 8-bit or 16-bit rotation.

View File

@ -1,6 +1,11 @@
TODO
====
In ast2 allow PtVariable to still have a numeric initialization value in codegen. (instead of only array and string)
why is 0 as value stored as null in symboltablemaker?
are variables initialized with 0 reset to 0 with an assignment? WHY is the BSS area then cleared with memset? shouldn't be necessary?
- defers that haven't been reached yet should not be executed (how will we do this? some kind of runtime support needed? refcount or bitmask, not a boolean var per defer that would be wasteful)
- unit test for defer
- describe defer in the manual