mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
some ast2 var tweaks
This commit is contained in:
parent
6de760885f
commit
0247fb0d84
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
16
codeCore/src/prog8/code/ast/Verify.kt
Normal file
16
codeCore/src/prog8/code/ast/Verify.kt
Normal 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}"}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user