mirror of
https://github.com/irmen/prog8.git
synced 2025-08-15 14:27:37 +00:00
some ast2 var tweaks
This commit is contained in:
@@ -66,23 +66,26 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
|||||||
val numElements: Int?
|
val numElements: Int?
|
||||||
val value = node.value
|
val value = node.value
|
||||||
if(value!=null) {
|
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) {
|
when (value) {
|
||||||
is PtString -> {
|
is PtString -> {
|
||||||
initialString = StString(value.value, value.encoding)
|
initialString = StString(value.value, value.encoding)
|
||||||
initialArray = null
|
initialArray = null
|
||||||
|
initialNumeric = null
|
||||||
numElements = value.value.length + 1 // include the terminating 0-byte
|
numElements = value.value.length + 1 // include the terminating 0-byte
|
||||||
}
|
}
|
||||||
is PtArray -> {
|
is PtArray -> {
|
||||||
initialArray = makeInitialArray(value)
|
initialArray = makeInitialArray(value)
|
||||||
initialString = null
|
initialString = null
|
||||||
|
initialNumeric = null
|
||||||
numElements = initialArray.size
|
numElements = initialArray.size
|
||||||
require(node.arraySize?.toInt()==numElements)
|
require(node.arraySize?.toInt()==numElements)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
require(value is PtNumber)
|
||||||
initialString = null
|
initialString = null
|
||||||
initialArray = 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()
|
numElements = node.arraySize?.toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -238,6 +238,13 @@ class PtFunctionCall(val name: String,
|
|||||||
position: Position) : PtExpression(type, position) {
|
position: Position) : PtExpression(type, position) {
|
||||||
val args: List<PtExpression>
|
val args: List<PtExpression>
|
||||||
get() = children.map { it as 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 }) {
|
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
|
// 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 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) }
|
value.children.forEach { voidCall.add(it) }
|
||||||
node.parent.children[index] = voidCall
|
node.parent.children[index] = voidCall
|
||||||
voidCall.parent = node.parent
|
voidCall.parent = node.parent
|
||||||
|
@@ -12,6 +12,7 @@ import prog8.ast.statements.Directive
|
|||||||
import prog8.code.SymbolTableMaker
|
import prog8.code.SymbolTableMaker
|
||||||
import prog8.code.ast.PtProgram
|
import prog8.code.ast.PtProgram
|
||||||
import prog8.code.ast.printAst
|
import prog8.code.ast.printAst
|
||||||
|
import prog8.code.ast.verifyFinalAstBeforeAsmGen
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import prog8.code.optimize.optimizeIntermediateAst
|
import prog8.code.optimize.optimizeIntermediateAst
|
||||||
import prog8.code.target.AtariTarget
|
import prog8.code.target.AtariTarget
|
||||||
@@ -146,6 +147,9 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
println("*********** INTERMEDIATE AST END *************\n")
|
println("*********** INTERMEDIATE AST END *************\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verifyFinalAstBeforeAsmGen(intermediateAst, compilationOptions, symbolTable, args.errors)
|
||||||
|
args.errors.report()
|
||||||
|
|
||||||
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
|
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
|
||||||
System.err.println("Error in codegeneration or assembler")
|
System.err.println("Error in codegeneration or assembler")
|
||||||
return null
|
return null
|
||||||
|
@@ -1,17 +1,11 @@
|
|||||||
package prog8tests.ast
|
package prog8tests.ast
|
||||||
|
|
||||||
import io.kotest.assertions.fail
|
|
||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.matchers.ints.shouldBeGreaterThan
|
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.types.instanceOf
|
import prog8.code.ast.PtBinaryExpression
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.PtNumber
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.Position
|
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({
|
class TestIntermediateAst: FunSpec({
|
||||||
|
|
||||||
|
@@ -134,6 +134,7 @@ rol (x)
|
|||||||
(essentially, it is a 9-bit or 17-bit rotation)
|
(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).
|
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 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)
|
rol2 (x)
|
||||||
Like ``rol`` but now as 8-bit or 16-bit rotation.
|
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)
|
(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).
|
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 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)
|
ror2 (x)
|
||||||
Like ``ror`` but now as 8-bit or 16-bit rotation.
|
Like ``ror`` but now as 8-bit or 16-bit rotation.
|
||||||
|
@@ -1,6 +1,11 @@
|
|||||||
TODO
|
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)
|
- 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
|
- unit test for defer
|
||||||
- describe defer in the manual
|
- describe defer in the manual
|
||||||
|
Reference in New Issue
Block a user