some cleanups

This commit is contained in:
Irmen de Jong 2023-02-09 01:46:23 +01:00
parent 623329fb33
commit 6aabbffc62
34 changed files with 232 additions and 266 deletions

View File

@ -78,7 +78,7 @@ enum class StNodeType {
open class StNode(val name: String,
val type: StNodeType,
val position: Position,
val astNode: PtNode, // TODO keep reference to the node in the AST
val astNode: PtNode,
val children: MutableMap<String, StNode> = mutableMapOf()
) {
@ -151,8 +151,8 @@ class StStaticVariable(name: String,
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
val onetimeInitializationStringValue: StString?,
val onetimeInitializationArrayValue: StArray?,
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
val zpwish: ZeropageWish,
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
val zpwish: ZeropageWish, // used in the variable allocator
astNode: PtNode,
position: Position) : StNode(name, StNodeType.STATICVAR, position, astNode = astNode) {

View File

@ -36,8 +36,6 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
return st
}
// TODO INITIAL VALUES / BSS
private fun addToSt(node: PtNode, scope: Stack<StNode>) {
val stNode = when(node) {
is PtAsmSub -> {
@ -59,7 +57,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
StNode(node.name, StNodeType.LABEL, node.position, node)
}
is PtMemMapped -> {
StMemVar(node.name, node.type, node.address, null, node, node.position) // TODO missing node.length
StMemVar(node.name, node.type, node.address, node.arraySize?.toInt(), node, node.position)
}
is PtSub -> {
val params = node.parameters.map {StSubroutineParameter(it.name, it.type) }

View File

@ -37,7 +37,7 @@ sealed class PtNode(val position: Position) {
fun definingBlock() = findParentNode<PtBlock>(this)
fun definingSub() = findParentNode<PtSub>(this)
fun definingAsmSub() = findParentNode<PtAsmSub>(this)
fun definingISub() = findParentNode<IPtSubroutine>(this) // TODO null assert here?
fun definingISub() = findParentNode<IPtSubroutine>(this)
}

View File

@ -239,7 +239,7 @@ class PtTypeCast(type: DataType, position: Position) : PtExpression(type, positi
}
// special node that isn't created from compiling user code, but used internally
// special node that isn't created from compiling user code, but used internally in the Intermediate Code
class PtMachineRegister(val register: Int, type: DataType, position: Position) : PtExpression(type, position) {
override fun printProperties() {
print("reg=$register $type")

View File

@ -135,6 +135,7 @@ fun printAst(root: PtNode, output: (text: String) -> Unit) {
output(" ".repeat(depth) + txt(node))
}
}
println()
} else {
walkAst(root) { node, depth ->
val txt = txt(node)

View File

@ -426,8 +426,8 @@ class AsmGen(
internal fun translateBuiltinFunctionCallExpression(bfc: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? =
builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister)
internal fun translateFunctionCall(functionCallExpr: PtFunctionCall, isExpression: Boolean) =
functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression)
internal fun translateFunctionCall(functionCallExpr: PtFunctionCall) =
functioncallAsmGen.translateFunctionCall(functionCallExpr)
internal fun saveXbeforeCall(functionCall: PtFunctionCall) =
functioncallAsmGen.saveXbeforeCall(functionCall)
@ -930,7 +930,7 @@ $repeatLabel lda $counterVar
}
}
internal fun isZpVar(variable: PtIdentifier): Boolean = allocator.isZpVar(variable.name.split('.')) // TODO as dotted string
internal fun isZpVar(variable: PtIdentifier): Boolean = allocator.isZpVar(variable.name.split('.')) // TODO dotted string
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
if(indirect) {
@ -1055,6 +1055,13 @@ $repeatLabel lda $counterVar
return false
}
internal fun findSubroutineParameter(name: String, asmgen: AsmGen): PtSubroutineParameter? {
val node = asmgen.symbolTable.lookup(name)!!.astNode
if(node is PtSubroutineParameter)
return node
return node.definingSub()?.parameters?.singleOrNull { it.name===name }
}
private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpression, jump: PtJump) {
if(expr.operator !in ComparisonOperators)
throw AssemblyError("must be comparison expression")
@ -2977,14 +2984,6 @@ $repeatLabel lda $counterVar
}
}
internal fun popCpuStack(dt: DataType, targetAsmVarName: String) {
when(dt) {
in ByteDatatypes -> out(" pla | sta $targetAsmVarName")
in WordDatatypes -> out(" pla | sta $targetAsmVarName+1 | pla | sta $targetAsmVarName")
else -> throw AssemblyError("can't pop $dt")
}
}
internal fun pushCpuStack(dt: DataType, value: PtExpression) {
val signed = value.type.oneOf(DataType.BYTE, DataType.WORD)
if(dt in ByteDatatypes) {

View File

@ -62,7 +62,7 @@ internal class AssemblyProgram(
"atari" -> {
// Atari800XL .xex generation.
// TODO are these options okay?
// TODO are these options okay for atari?
val command = mutableListOf("64tass", "--ascii", "--case-sensitive", "--long-branch",
"-Wall", "-Wno-strict-bool", "-Wno-shadow", // "-Werror",
"--no-monitor"

View File

@ -36,7 +36,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
is PtContainmentCheck -> throw AssemblyError("containment check as complex expression value is not supported")
is PtArray, is PtString -> throw AssemblyError("no asm gen for string/array literal value assignment - should have been replaced by a variable")
is PtRange -> throw AssemblyError("range expression should have been changed into array values")
is PtMachineRegister -> TODO("machine register expression node")
is PtMachineRegister -> throw AssemblyError("machine register ast node should not occur in 6502 codegen it is for IR code")
else -> TODO("missing expression asmgen for $expression")
}
}
@ -47,7 +47,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
val symbol = asmgen.symbolTable.lookup(call.name)
val sub = symbol!!.astNode as IPtSubroutine
asmgen.saveXbeforeCall(call)
asmgen.translateFunctionCall(call, true)
asmgen.translateFunctionCall(call)
if(sub.regXasResult()) {
// store the return value in X somewhere that we can access again below
asmgen.out(" stx P8ZP_SCRATCH_REG")

View File

@ -48,7 +48,7 @@ fun PtExpression.isSimple(): Boolean {
is PtContainmentCheck -> false
is PtFunctionCall -> false
is PtIdentifier -> true
is PtMachineRegister -> TODO()
is PtMachineRegister -> true
is PtMemoryByte -> address is PtNumber || address is PtIdentifier
is PtNumber -> true
is PtPrefix -> value.isSimple()
@ -133,11 +133,3 @@ internal fun PtSub.returnRegister(): RegisterOrStatusflag? {
else -> RegisterOrStatusflag(RegisterOrPair.AY, null)
}
}
// TODO move into AsmGen:
internal fun findSubroutineParameter(name: String, asmgen: AsmGen): PtSubroutineParameter? {
val node = asmgen.symbolTable.lookup(name)!!.astNode
if(node is PtSubroutineParameter)
return node
return node.definingSub()?.parameters?.singleOrNull { it.name===name }
}

View File

@ -12,7 +12,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
internal fun translateFunctionCallStatement(stmt: PtFunctionCall) {
saveXbeforeCall(stmt)
translateFunctionCall(stmt, false)
translateFunctionCall(stmt)
restoreXafterCall(stmt)
// just ignore any result values from the function call.
}
@ -51,7 +51,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
(sub.parameters.size==1 && sub.parameters[0].type in IntegerDatatypes)
|| (sub.parameters.size==2 && sub.parameters[0].type in ByteDatatypes && sub.parameters[1].type in ByteDatatypes)
internal fun translateFunctionCall(call: PtFunctionCall, isExpression: Boolean) { // TODO remove isExpression unused parameter
internal fun translateFunctionCall(call: PtFunctionCall) {
// Output only the code to set up the parameters and perform the actual call
// NOTE: does NOT output the code to deal with the result values!
// NOTE: does NOT output code to save/restore the X register for this call! Every caller should deal with this in their own way!!

View File

@ -28,12 +28,9 @@ internal class ProgramAndVarsGen(
private val zeropage: Zeropage
) {
private val compTarget = options.compTarget
// TODO ???? private val callGraph = CallGraph(program, true)
private val blockVariableInitializers = program.allBlocks().associateWith { it.children.filterIsInstance<PtAssignment>() }
internal fun generate() {
val allInitializers = blockVariableInitializers.asSequence().flatMap { it.value } // TODO unused?
header()
val allBlocks = program.allBlocks()
if(allBlocks.first().name != "main")
@ -278,7 +275,7 @@ internal class ProgramAndVarsGen(
if(sub.inline) {
if(options.optimize) {
TODO("check if sub is unused")
TODO("check if sub is unused, is this even still reached?")
// if(callGraph.unused(sub))
// return

View File

@ -4,7 +4,6 @@ import prog8.code.ast.*
import prog8.code.core.*
import prog8.codegen.cpu6502.AsmGen
import prog8.codegen.cpu6502.asConstInteger
import prog8.codegen.cpu6502.findSubroutineParameter
import prog8.codegen.cpu6502.returnsWhatWhere
@ -53,11 +52,11 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
}
companion object {
fun fromAstAssignment(assign: PtAssignment, program: PtProgram, asmgen: AsmGen): AsmAssignTarget {
fun fromAstAssignment(assign: PtAssignment, asmgen: AsmGen): AsmAssignTarget {
with(assign.target) {
when {
identifier != null -> {
val parameter = findSubroutineParameter(identifier!!.name, asmgen)
val parameter = asmgen.findSubroutineParameter(identifier!!.name, asmgen)
if (parameter!=null) {
val sub = parameter.definingAsmSub()
if (sub!=null) {
@ -136,7 +135,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
is PtString -> throw AssemblyError("string literal value should not occur anymore for asm generation")
is PtArray -> throw AssemblyError("array literal value should not occur anymore for asm generation")
is PtIdentifier -> {
val parameter = findSubroutineParameter(value.name, asmgen)
val parameter = asmgen.findSubroutineParameter(value.name, asmgen)
if(parameter?.definingAsmSub() != null)
throw AssemblyError("can't assign from a asmsub register parameter $value ${value.position}")
val varName=asmgen.asmVariableName(value)

View File

@ -11,7 +11,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
fun translate(assignment: PtAssignment) {
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
val target = AsmAssignTarget.fromAstAssignment(assignment, asmgen)
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
val assign = AsmAssignment(source, target, assignment.isInplaceAssign, program.memsizer, assignment.position)
target.origAssign = assign
@ -180,7 +180,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
val symbol = asmgen.symbolTable.lookup(value.name)
val sub = symbol!!.astNode as IPtSubroutine
asmgen.saveXbeforeCall(value)
asmgen.translateFunctionCall(value, true)
asmgen.translateFunctionCall(value)
val returnValue = sub.returnsWhatWhere().singleOrNull() { it.second.registerOrPair!=null } ?: sub.returnsWhatWhere().single() { it.second.statusflag!=null }
when (returnValue.first) {
DataType.STR -> {

View File

@ -1,66 +0,0 @@
package prog8tests.codegencpu6502
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe
import prog8.code.core.BuiltinFunctions
import prog8.code.core.DataType
import prog8.code.core.NumericDatatypesNoBool
import prog8.code.core.RegisterOrPair
class TestBuiltinFunctions: FunSpec({
test("pure func with fixed type") {
val func = BuiltinFunctions.getValue("sgn")
func.parameters.size shouldBe 1
func.parameters[0].name shouldBe "value"
func.parameters[0].possibleDatatypes shouldBe NumericDatatypesNoBool
func.pure shouldBe true
func.returnType shouldBe DataType.BYTE
val conv = func.callConvention(listOf(DataType.UBYTE))
conv.params.size shouldBe 1
conv.params[0].dt shouldBe DataType.UBYTE
conv.params[0].reg shouldBe RegisterOrPair.A
conv.params[0].variable shouldBe false
conv.returns.dt shouldBe DataType.BYTE
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe RegisterOrPair.A
}
test("not-pure func with varying result value type") {
val func = BuiltinFunctions.getValue("cmp")
func.parameters.size shouldBe 2
func.pure shouldBe false
func.returnType shouldBe null
val conv = func.callConvention(listOf(DataType.UWORD, DataType.UWORD))
conv.params.size shouldBe 2
conv.returns.dt shouldBe null
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe null
}
test("func without return type") {
val func = BuiltinFunctions.getValue("poke")
func.parameters.size shouldBe 2
func.parameters[0].name shouldBe "address"
func.parameters[0].possibleDatatypes shouldBe arrayOf(DataType.UWORD)
func.parameters[1].name shouldBe "value"
func.parameters[1].possibleDatatypes shouldBe arrayOf(DataType.UBYTE)
func.pure shouldBe false
func.returnType shouldBe null
val conv = func.callConvention(listOf(DataType.UWORD, DataType.UBYTE))
conv.params.size shouldBe 2
conv.params[0].dt shouldBe DataType.UWORD
conv.params[0].reg shouldBe null
conv.params[0].variable shouldBe true
conv.params[1].dt shouldBe DataType.UBYTE
conv.params[1].reg shouldBe null
conv.params[1].variable shouldBe true
conv.returns.dt shouldBe null
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe null
}
})

View File

@ -0,0 +1,10 @@
package prog8tests.codegencpu6502
import io.kotest.core.spec.style.FunSpec
class TestCodegen: FunSpec({
// TODO there are no 6502 specific codegen tests yet
})

View File

@ -206,13 +206,13 @@ private fun compileMain(args: Array<String>): Boolean {
}
if(startEmulator1==true || startEmulator2==true) {
if (compilationResult.program.name.isEmpty()) {
if (compilationResult.compilerAst.name.isEmpty()) {
println("\nCan't start emulator because no program was assembled.")
return true
}
}
val programNameInPath = outputPath.resolve(compilationResult.program.name)
val programNameInPath = outputPath.resolve(compilationResult.compilerAst.name)
if(startEmulator1==true || startEmulator2==true) {
if (compilationResult.compilationOptions.launcher != CbmPrgLauncherType.NONE || compilationTarget=="atari") {

View File

@ -2,14 +2,11 @@ package prog8.compiler
import com.github.michaelbull.result.onFailure
import prog8.ast.IBuiltinFunctions
import prog8.ast.IStatementContainer
import prog8.ast.Program
import prog8.ast.base.AstException
import prog8.ast.expressions.Expression
import prog8.ast.expressions.NumericLiteral
import prog8.ast.statements.Directive
import prog8.ast.statements.VarDecl
import prog8.ast.walk.IAstVisitor
import prog8.code.SymbolTableMaker
import prog8.code.ast.PtProgram
import prog8.code.core.*
@ -25,7 +22,8 @@ import kotlin.math.round
import kotlin.system.measureTimeMillis
class CompilationResult(val program: Program,
class CompilationResult(val compilerAst: Program, // deprecated, use codegenAst instead
val codegenAst: PtProgram?,
val compilationOptions: CompilationOptions,
val importedFiles: List<Path>)
@ -63,6 +61,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
}
var compilationOptions: CompilationOptions
var ast: PtProgram? = null
try {
val totalTime = measureTimeMillis {
@ -113,10 +112,22 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
args.errors.report()
if (args.writeAssembly) {
if(!createAssemblyAndAssemble(program, args.errors, compilationOptions)) {
compilationOptions.compTarget.machine.initializeMemoryAreas(compilationOptions)
program.processAstBeforeAsmGeneration(compilationOptions, args.errors)
args.errors.report()
val intermediateAst = IntermediateAstMaker(program, compilationOptions).transform()
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
// printProgram(program)
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
// printAst(intermediateAst, ::println)
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
System.err.println("Error in codegeneration or assembler")
return null
}
ast = intermediateAst
}
}
@ -124,7 +135,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
System.err.flush()
val seconds = totalTime/1000.0
println("\nTotal compilation+assemble time: ${round(seconds*100.0)/100.0} sec.")
return CompilationResult(program, compilationOptions, importedFiles)
return CompilationResult(program, ast, compilationOptions, importedFiles)
} catch (px: ParseError) {
System.err.print("\n\u001b[91m") // bright red
System.err.println("${px.position.toClickableStr()} parse error: ${px.message}".trim())
@ -385,25 +396,11 @@ private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOpt
errors.report()
}
private fun createAssemblyAndAssemble(program: Program,
private fun createAssemblyAndAssemble(program: PtProgram,
errors: IErrorReporter,
compilerOptions: CompilationOptions
): Boolean {
compilerOptions.compTarget.machine.initializeMemoryAreas(compilerOptions)
program.processAstBeforeAsmGeneration(compilerOptions, errors)
errors.report()
// TODO make removing all VarDecls work, but this needs inferType to be able to get its information from somewhere else as the VarDecl nodes in the Ast,
// or don't use inferType at all anymore and "bake the type information" into the Ast somehow.
// Note: we don't actually *need* to remove the VarDecl nodes, but it is nice as a temporary measure
// to help clean up the code that still depends on them.
// removeAllVardeclsFromAst(program)
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
// printProgram(program)
val intermediateAst = IntermediateAstMaker(program, compilerOptions).transform()
val assembly = asmGeneratorFor(intermediateAst, compilerOptions, errors).compileToAssembly()
val assembly = asmGeneratorFor(program, compilerOptions, errors).compileToAssembly()
errors.report()
return if(assembly!=null && errors.noErrors()) {
@ -413,26 +410,6 @@ private fun createAssemblyAndAssemble(program: Program,
}
}
private fun removeAllVardeclsFromAst(program: Program) {
// remove all VarDecl nodes from the AST.
// code generation doesn't require them anymore, it operates only on the 'variables' collection.
class SearchAndRemove: IAstVisitor {
private val allVars = mutableListOf<VarDecl>()
init {
visit(program)
for (it in allVars) {
require((it.parent as IStatementContainer).statements.remove(it))
}
}
override fun visit(decl: VarDecl) {
allVars.add(decl)
}
}
SearchAndRemove()
}
internal fun asmGeneratorFor(program: PtProgram,
options: CompilationOptions,
errors: IErrorReporter): IAssemblyGenerator

View File

@ -136,7 +136,7 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati
internal fun Program.variousCleanups(errors: IErrorReporter, options: CompilationOptions) {
val process = VariousCleanups(this, errors, options)
process.visit(this)
while(errors.noErrors() && process.applyModifications()>0) { // TODO limit the number of cycles here?
while(errors.noErrors() && process.applyModifications()>0) {
process.visit(this)
}
}

View File

@ -5,11 +5,69 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import prog8.ast.expressions.NumericLiteral
import prog8.ast.statements.Assignment
import prog8.code.core.BuiltinFunctions
import prog8.code.core.DataType
import prog8.code.core.NumericDatatypesNoBool
import prog8.code.core.RegisterOrPair
import prog8.code.target.Cx16Target
import prog8tests.helpers.compileText
class TestBuiltinFunctions: FunSpec({
test("pure func with fixed type") {
val func = BuiltinFunctions.getValue("sgn")
func.parameters.size shouldBe 1
func.parameters[0].name shouldBe "value"
func.parameters[0].possibleDatatypes shouldBe NumericDatatypesNoBool
func.pure shouldBe true
func.returnType shouldBe DataType.BYTE
val conv = func.callConvention(listOf(DataType.UBYTE))
conv.params.size shouldBe 1
conv.params[0].dt shouldBe DataType.UBYTE
conv.params[0].reg shouldBe RegisterOrPair.A
conv.params[0].variable shouldBe false
conv.returns.dt shouldBe DataType.BYTE
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe RegisterOrPair.A
}
test("not-pure func with varying result value type") {
val func = BuiltinFunctions.getValue("cmp")
func.parameters.size shouldBe 2
func.pure shouldBe false
func.returnType shouldBe null
val conv = func.callConvention(listOf(DataType.UWORD, DataType.UWORD))
conv.params.size shouldBe 2
conv.returns.dt shouldBe null
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe null
}
test("func without return type") {
val func = BuiltinFunctions.getValue("poke")
func.parameters.size shouldBe 2
func.parameters[0].name shouldBe "address"
func.parameters[0].possibleDatatypes shouldBe arrayOf(DataType.UWORD)
func.parameters[1].name shouldBe "value"
func.parameters[1].possibleDatatypes shouldBe arrayOf(DataType.UBYTE)
func.pure shouldBe false
func.returnType shouldBe null
val conv = func.callConvention(listOf(DataType.UWORD, DataType.UBYTE))
conv.params.size shouldBe 2
conv.params[0].dt shouldBe DataType.UWORD
conv.params[0].reg shouldBe null
conv.params[0].variable shouldBe true
conv.params[1].dt shouldBe DataType.UBYTE
conv.params[1].reg shouldBe null
conv.params[1].variable shouldBe true
conv.returns.dt shouldBe null
conv.returns.floatFac1 shouldBe false
conv.returns.reg shouldBe null
}
test("push pop") {
val src="""
main {
@ -37,7 +95,7 @@ main {
}
}"""
val result = compileText(Cx16Target(), false, src, writeAssembly = false)
val statements = result!!.program.entrypoint.statements
val statements = result!!.compilerAst.entrypoint.statements
statements.size shouldBe 6
val a1 = statements[2] as Assignment
val a2 = statements[3] as Assignment

View File

@ -27,11 +27,11 @@ class TestCallgraph: FunSpec({
}
"""
val result = compileText(C64Target(), false, sourcecode)!!
val graph = CallGraph(result.program)
val graph = CallGraph(result.compilerAst)
graph.imports.size shouldBe 1
graph.importedBy.size shouldBe 1
val toplevelModule = result.program.toplevelModule
val toplevelModule = result.compilerAst.toplevelModule
val importedModule = graph.imports.getValue(toplevelModule).single()
importedModule.name shouldBe "string"
val importedBy = graph.importedBy.getValue(importedModule).single()
@ -46,7 +46,7 @@ class TestCallgraph: FunSpec({
graph.calls shouldNotContainKey sub
graph.calledBy shouldNotContainKey sub
if(sub === result.program.entrypoint)
if(sub === result.compilerAst.entrypoint)
withClue("start() should always be marked as used to avoid having it removed") {
graph.unused(sub) shouldBe false
}
@ -68,11 +68,11 @@ class TestCallgraph: FunSpec({
}
"""
val result = compileText(C64Target(), false, sourcecode)!!
val graph = CallGraph(result.program)
val graph = CallGraph(result.compilerAst)
graph.imports.size shouldBe 1
graph.importedBy.size shouldBe 1
val toplevelModule = result.program.toplevelModule
val toplevelModule = result.compilerAst.toplevelModule
val importedModule = graph.imports.getValue(toplevelModule).single()
importedModule.name shouldBe "string"
val importedBy = graph.importedBy.getValue(importedModule).single()
@ -111,7 +111,7 @@ class TestCallgraph: FunSpec({
}
"""
val result = compileText(C64Target(), false, sourcecode)!!
val graph = CallGraph(result.program)
val graph = CallGraph(result.compilerAst)
graph.allIdentifiers.size shouldBeGreaterThanOrEqual 5
val empties = graph.allIdentifiers.keys.filter { it.nameInSource==listOf("empty") }
empties.size shouldBe 3

View File

@ -33,7 +33,7 @@ class TestCompilerOnCharLit: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
@ -57,7 +57,7 @@ class TestCompilerOnCharLit: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
@ -92,7 +92,7 @@ class TestCompilerOnCharLit: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]

View File

@ -30,7 +30,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
val platform = Cx16Target()
val result = compileFile(platform, optimize = false, fixturesDir, filepath.name)!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val strLits = startSub.statements
.filterIsInstance<FunctionCallStatement>()
@ -52,7 +52,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
val platform = Cx16Target()
val result = compileFile(platform, optimize = false, fixturesDir, filepath.name)!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val args = startSub.statements
.filterIsInstance<FunctionCallStatement>()

View File

@ -40,7 +40,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val decl = startSub
.statements.filterIsInstance<VarDecl>()[0]
@ -72,7 +72,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val decl = startSub
.statements.filterIsInstance<VarDecl>()[0]
@ -143,7 +143,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val iterable = startSub
.statements.filterIsInstance<ForLoop>()
@ -177,7 +177,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val rangeExpr = startSub
.statements.filterIsInstance<ForLoop>()
@ -203,7 +203,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val rangeExpr = startSub
.statements.filterIsInstance<ForLoop>()
@ -247,7 +247,7 @@ class TestCompilerOnRanges: FunSpec({
}
""")!!
val program = result.program
val program = result.compilerAst
val startSub = program.entrypoint
val iterable = startSub
.statements.filterIsInstance<ForLoop>()
@ -279,7 +279,7 @@ class TestCompilerOnRanges: FunSpec({
}
}
""")!!
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
val array = (statements[0] as VarDecl).value
array shouldBe instanceOf<ArrayLiteral>()
(array as ArrayLiteral).value.size shouldBe 26
@ -301,7 +301,7 @@ class TestCompilerOnRanges: FunSpec({
}
}
""")!!
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
val forloop = (statements.dropLast(1).last() as ForLoop)
forloop.iterable shouldBe instanceOf<RangeExpression>()
(forloop.iterable as RangeExpression).step shouldBe NumericLiteral(DataType.UBYTE, -2.0, Position.DUMMY)

View File

@ -28,9 +28,9 @@ main {
}
}
""")!!
result.program.toplevelModule.name shouldStartWith "on_the_fly_test"
result.compilerAst.toplevelModule.name shouldStartWith "on_the_fly_test"
val moduleNames = result.program.modules.map { it.name }
val moduleNames = result.compilerAst.modules.map { it.name }
withClue("main module must be first") {
moduleNames[0] shouldStartWith "on_the_fly_test"
}
@ -46,7 +46,7 @@ main {
"prog8_lib"
)
}
result.program.toplevelModule.name shouldStartWith "on_the_fly_test"
result.compilerAst.toplevelModule.name shouldStartWith "on_the_fly_test"
}
test("testCompilationOptionsCorrectFromMain") {
@ -63,8 +63,8 @@ main {
}
}
""")!!
result.program.toplevelModule.name shouldStartWith "on_the_fly_test"
val options = determineCompilationOptions(result.program, C64Target())
result.compilerAst.toplevelModule.name shouldStartWith "on_the_fly_test"
val options = determineCompilationOptions(result.compilerAst, C64Target())
options.floats shouldBe true
options.zeropage shouldBe ZeropageType.DONTUSE
options.noSysInit shouldBe true

View File

@ -198,7 +198,7 @@ class TestNumbers: FunSpec({
}
"""
val result = compileText(C64Target(), false, src, writeAssembly = false)!!
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
statements.size shouldBe 8
(statements[1] as Assignment).value shouldBe NumericLiteral(DataType.UWORD, 32768.0, Position.DUMMY)
(statements[3] as Assignment).value shouldBe NumericLiteral(DataType.UWORD, 65535.0, Position.DUMMY)

View File

@ -31,10 +31,10 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), true, sourcecode)!!
val toplevelModule = result.program.toplevelModule
val toplevelModule = result.compilerAst.toplevelModule
val mainBlock = toplevelModule.statements.single() as Block
val startSub = mainBlock.statements.single() as Subroutine
result.program.entrypoint shouldBeSameInstanceAs startSub
result.compilerAst.entrypoint shouldBeSameInstanceAs startSub
withClue("only start sub should remain") {
startSub.name shouldBe "start"
}
@ -56,11 +56,11 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), true, sourcecode)!!
val toplevelModule = result.program.toplevelModule
val toplevelModule = result.compilerAst.toplevelModule
val mainBlock = toplevelModule.statements.single() as Block
val startSub = mainBlock.statements[0] as Subroutine
val emptySub = mainBlock.statements[1] as Subroutine
result.program.entrypoint shouldBeSameInstanceAs startSub
result.compilerAst.entrypoint shouldBeSameInstanceAs startSub
startSub.name shouldBe "start"
emptySub.name shouldBe "empty"
withClue("compiler has inserted return in empty subroutines") {
@ -130,7 +130,7 @@ class TestOptimization: FunSpec({
// cx16.r5s -= 1899
// cx16.r7s = llw
// cx16.r7s += 99
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 14
val addR0value = (stmts[5] as Assignment).value
@ -182,7 +182,7 @@ class TestOptimization: FunSpec({
// cx16.r4s = llw
// cx16.r4s *= 90
// cx16.r4s /= 5
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 13
val mulR0Value = (stmts[3] as Assignment).value
@ -224,7 +224,7 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), false, sourcecode)!!
val mainsub = result.program.entrypoint
val mainsub = result.compilerAst.entrypoint
mainsub.statements.size shouldBe 10
val declTest = mainsub.statements[0] as VarDecl
val declX1 = mainsub.statements[1] as VarDecl
@ -264,7 +264,7 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), false, src, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 8
val value1 = (stmts[4] as Assignment).value as BinaryExpression
@ -296,7 +296,7 @@ class TestOptimization: FunSpec({
bb = prog8_lib.retval_interm_b
return
*/
val st = result.program.entrypoint.statements
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 8
st.last() shouldBe instanceOf<Return>()
var assign = st[3] as Assignment
@ -322,7 +322,7 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly = false)!!
val assignFF = result.program.entrypoint.statements.last() as Assignment
val assignFF = result.compilerAst.entrypoint.statements.last() as Assignment
assignFF.isAugmentable shouldBe true
assignFF.target.identifier!!.nameInSource shouldBe listOf("ff")
val value = assignFF.value as BinaryExpression
@ -348,8 +348,8 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
result.program.entrypoint.statements.size shouldBe 7
val alldecls = result.program.entrypoint.allDefinedSymbols.toList()
result.compilerAst.entrypoint.statements.size shouldBe 7
val alldecls = result.compilerAst.entrypoint.allDefinedSymbols.toList()
alldecls.map { it.first } shouldBe listOf("unused_but_shared", "usedvar_only_written", "usedvar")
}
@ -371,11 +371,11 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
result.program.entrypoint.statements.size shouldBe 3
val ifstmt = result.program.entrypoint.statements[0] as IfElse
result.compilerAst.entrypoint.statements.size shouldBe 3
val ifstmt = result.compilerAst.entrypoint.statements[0] as IfElse
ifstmt.truepart.statements.size shouldBe 1
(ifstmt.truepart.statements[0] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "r0")
val func2 = result.program.entrypoint.statements[2] as Subroutine
val func2 = result.compilerAst.entrypoint.statements[2] as Subroutine
func2.statements.size shouldBe 1
(func2.statements[0] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "r0")
}
@ -415,7 +415,7 @@ class TestOptimization: FunSpec({
z6 = z1
z6 -= 5
*/
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
statements.size shouldBe 14
val z1decl = statements[0] as VarDecl
val z1init = statements[1] as Assignment
@ -466,7 +466,7 @@ class TestOptimization: FunSpec({
"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
val assign=stmts.last() as Assignment
(assign.target.memoryAddress?.addressExpression as IdentifierReference).nameInSource shouldBe listOf("aa")
@ -483,7 +483,7 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
val assign=stmts.last() as Assignment
(assign.target.memoryAddress?.addressExpression as IdentifierReference).nameInSource shouldBe listOf("aa")
@ -502,7 +502,7 @@ class TestOptimization: FunSpec({
}
"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 10
stmts.filterIsInstance<VarDecl>().size shouldBe 5
stmts.filterIsInstance<Assignment>().size shouldBe 5
@ -551,8 +551,8 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=true)!!
result.program.entrypoint.statements.size shouldBe 11
result.program.entrypoint.statements.last() shouldBe instanceOf<Return>()
result.compilerAst.entrypoint.statements.size shouldBe 11
result.compilerAst.entrypoint.statements.last() shouldBe instanceOf<Return>()
}
test("keep the value initializer assignment if the next one depends on it") {
@ -579,7 +579,7 @@ class TestOptimization: FunSpec({
xx = abs(xx)
xx += 6
*/
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 8
stmts.filterIsInstance<VarDecl>().size shouldBe 3
stmts.filterIsInstance<Assignment>().size shouldBe 5
@ -608,7 +608,7 @@ class TestOptimization: FunSpec({
yy = 0
xx += 10
*/
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 7
stmts.filterIsInstance<VarDecl>().size shouldBe 2
stmts.filterIsInstance<Assignment>().size shouldBe 5
@ -645,7 +645,7 @@ class TestOptimization: FunSpec({
if source in auto_heap_var
thingy++
*/
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
val ifStmt = stmts[5] as IfElse
val containment = ifStmt.condition as ContainmentCheck
@ -675,7 +675,7 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 5
val ifStmt = stmts[4] as IfElse
ifStmt.condition shouldBe instanceOf<BinaryExpression>()
@ -693,7 +693,7 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 5
val ifStmt = stmts[4] as IfElse
ifStmt.condition shouldBe instanceOf<BinaryExpression>()
@ -711,7 +711,7 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 5
val ifStmt = stmts[4] as IfElse
ifStmt.condition shouldBe instanceOf<BinaryExpression>()
@ -728,7 +728,7 @@ class TestOptimization: FunSpec({
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 3
}
@ -750,15 +750,15 @@ main {
}
}"""
var result = compileText(Cx16Target(), true, srcX16, writeAssembly = true)!!
var statements = result.program.entrypoint.statements
var statements = result.compilerAst.entrypoint.statements
statements.size shouldBe 9
(statements[1] as Assignment).target.identifier!!.nameInSource shouldBe listOf("xx")
(statements[2] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
(statements[3] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
(statements[4] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 0x9fff
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 0x9fff
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 0x9fff
val srcC64="""
main {
@ -777,14 +777,14 @@ main {
}
}"""
result = compileText(C64Target(), true, srcC64, writeAssembly = true)!!
statements = result.program.entrypoint.statements
statements = result.compilerAst.entrypoint.statements
statements.size shouldBe 9
(statements[1] as Assignment).target.identifier!!.nameInSource shouldBe listOf("xx")
(statements[2] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
(statements[3] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
(statements[4] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 53281.0
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 53281.0
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.compilerAst)!!.number shouldBe 53281.0
}
})

View File

@ -27,9 +27,9 @@ class TestScoping: FunSpec({
"""
val result = compileText(C64Target(), false, src, writeAssembly = false)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
module.parent shouldBe instanceOf<GlobalNamespace>()
module.program shouldBeSameInstanceAs result.program
module.program shouldBeSameInstanceAs result.compilerAst
module.parent.parent shouldBe instanceOf<ParentSentinel>()
}
@ -46,7 +46,7 @@ class TestScoping: FunSpec({
"""
val result = compileText(C64Target(), false, src, writeAssembly = false)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
val mainBlock = module.statements.single() as Block
val start = mainBlock.statements.single() as Subroutine
val repeatbody = start.statements.filterIsInstance<RepeatLoop>().single().body
@ -120,7 +120,7 @@ class TestScoping: FunSpec({
"""
val result = compileText(C64Target(), false, src, writeAssembly = true)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
val mainBlock = module.statements.single() as Block
val start = mainBlock.statements.single() as Subroutine
val labels = start.statements.filterIsInstance<Label>()

View File

@ -60,7 +60,7 @@ class TestSubroutines: FunSpec({
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
val mainBlock = module.statements.single() as Block
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
@ -116,7 +116,7 @@ class TestSubroutines: FunSpec({
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
val mainBlock = module.statements.single() as Block
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
@ -178,7 +178,7 @@ class TestSubroutines: FunSpec({
"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val module = result.program.toplevelModule
val module = result.compilerAst.toplevelModule
val mainBlock = module.statements.single() as Block
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
@ -284,7 +284,7 @@ class TestSubroutines: FunSpec({
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.last() shouldBe instanceOf<Subroutine>()
stmts.dropLast(1).last() shouldBe instanceOf<Return>() // this prevents the fallthrough

View File

@ -49,7 +49,7 @@ class TestTypecasts: FunSpec({
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 4
val expr = (stmts[3] as Assignment).value as BinaryExpression
expr.operator shouldBe "and"
@ -57,7 +57,7 @@ class TestTypecasts: FunSpec({
(expr.left as IdentifierReference).nameInSource shouldBe listOf("bb2") // no cast
val result2 = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts2 = result2.program.entrypoint.statements
val stmts2 = result2.compilerAst.entrypoint.statements
stmts2.size shouldBe 6
val expr2 = (stmts2[4] as Assignment).value as BinaryExpression
expr2.operator shouldBe "&"
@ -86,7 +86,7 @@ main {
}
}"""
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
/*
ubyte ub1
ub1 = 1
@ -130,7 +130,7 @@ main {
}
}"""
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 2
val assignValue = (stmts[0] as Assignment).value as BinaryExpression
assignValue.left shouldBe instanceOf<IdentifierReference>()
@ -148,7 +148,7 @@ main {
}
}"""
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 2
val assignValue = (stmts[0] as Assignment).value as BinaryExpression
assignValue.left shouldBe instanceOf<BinaryExpression>() // as a result of the cast to boolean
@ -365,7 +365,7 @@ main {
}
"""
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBeGreaterThan 10
}
@ -578,7 +578,7 @@ main {
}
"""
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBeGreaterThan 10
}
@ -597,7 +597,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
val arraydecl = stmts[0] as VarDecl
arraydecl.datatype shouldBe DataType.ARRAY_BOOL
@ -631,7 +631,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 9
val fcall1 = ((stmts[6] as Assignment).value as IFunctionCall)
fcall1.args[0] shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY)
@ -664,7 +664,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBeGreaterThan 10
}
@ -683,7 +683,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 3
}
@ -706,7 +706,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 8
val arg1 = (stmts[2] as IFunctionCall).args.single()
val arg2 = (stmts[3] as IFunctionCall).args.single()
@ -743,7 +743,7 @@ main {
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
result.program.entrypoint.statements.size shouldBe 15
result.compilerAst.entrypoint.statements.size shouldBe 15
}
test("invalid typecasts of numbers") {
@ -863,7 +863,7 @@ main {
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
statements.size shouldBeGreaterThan 10
}
@ -890,7 +890,7 @@ main {
}
}"""
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
val statements = result.program.entrypoint.statements
val statements = result.compilerAst.entrypoint.statements
statements.size shouldBeGreaterThan 10
}

View File

@ -37,8 +37,8 @@ class TestIntermediateAst: FunSpec({
loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
)
val result = compileText(target, false, text, writeAssembly = false)!!
val ast = IntermediateAstMaker(result.program, options).transform()
ast.name shouldBe result.program.name
val ast = IntermediateAstMaker(result.compilerAst, options).transform()
ast.name shouldBe result.compilerAst.name
ast.allBlocks().any() shouldBe true
val entry = ast.entrypoint() ?: fail("no main.start() found")
entry.children.size shouldBe 5

View File

@ -862,7 +862,7 @@ class TestProg8Parser: FunSpec( {
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val start = result.program.entrypoint
val start = result.compilerAst.entrypoint
val string = (start.statements[0] as VarDecl).value as StringLiteral
withClue("x-escapes are hacked to range 0x8000-0x80ff") {
string.value[0].code shouldBe 0x8000
@ -901,7 +901,7 @@ class TestProg8Parser: FunSpec( {
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val start = result.program.entrypoint
val start = result.compilerAst.entrypoint
val containmentChecks = start.statements.takeLast(4)
(containmentChecks[0] as IfElse).condition shouldBe instanceOf<ContainmentCheck>()
(containmentChecks[1] as IfElse).condition shouldBe instanceOf<ContainmentCheck>()
@ -942,7 +942,7 @@ class TestProg8Parser: FunSpec( {
}
"""
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
val stmt = result.program.entrypoint.statements
val stmt = result.compilerAst.entrypoint.statements
stmt.size shouldBe 12
val var1 = stmt[0] as VarDecl
var1.sharedWithAsm shouldBe true

View File

@ -85,7 +85,7 @@ main {
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
}
@ -101,7 +101,7 @@ main {
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=true)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 6
val name1 = stmts[0] as VarDecl
val rept1 = stmts[1] as VarDecl
@ -111,8 +111,8 @@ main {
val rept2strcopy = stmts[4] as IFunctionCall
val name2 = name2strcopy.args.first() as IdentifierReference
val rept2 = rept2strcopy.args.first() as IdentifierReference
(name2.targetVarDecl(result.program)!!.value as StringLiteral).value shouldBe "xx1xx2"
(rept2.targetVarDecl(result.program)!!.value as StringLiteral).value shouldBe "xyzxyzxyzxyz"
(name2.targetVarDecl(result.compilerAst)!!.value as StringLiteral).value shouldBe "xx1xx2"
(rept2.targetVarDecl(result.compilerAst)!!.value as StringLiteral).value shouldBe "xyzxyzxyzxyz"
}
test("pointervariable indexing allowed with >255") {
@ -144,15 +144,15 @@ main {
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 7
val assign1expr = (stmts[3] as Assignment).value as BinaryExpression
val assign2expr = (stmts[5] as Assignment).value as BinaryExpression
assign1expr.operator shouldBe "<<"
val leftval1 = assign1expr.left.constValue(result.program)!!
val leftval1 = assign1expr.left.constValue(result.compilerAst)!!
leftval1.type shouldBe DataType.UWORD
leftval1.number shouldBe 1.0
val leftval2 = assign2expr.left.constValue(result.program)!!
val leftval2 = assign2expr.left.constValue(result.compilerAst)!!
leftval2.type shouldBe DataType.UWORD
leftval2.number shouldBe 1.0
}
@ -175,7 +175,7 @@ main {
}
}"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 9
}
@ -190,7 +190,7 @@ main {
}
"""
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
val stmts = result.compilerAst.entrypoint.statements
stmts.size shouldBe 3
val value1 = (stmts[1] as Assignment).value as BinaryExpression
val value2 = (stmts[2] as Assignment).value as BinaryExpression

View File

@ -35,7 +35,7 @@ main {
}"""
val target = VMTarget()
val result = compileText(target, true, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
}
@ -57,7 +57,7 @@ main {
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val result = compileText(target, true, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
}
@ -75,11 +75,11 @@ main {
}"""
val target = VMTarget()
var result = compileText(target, false, src, writeAssembly = true)!!
var virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
var virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
result = compileText(target, true, src, writeAssembly = true)!!
virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
}
@ -169,7 +169,7 @@ skipLABEL:
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val result = compileText(target, true, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.memory.getUB(0) shouldBe 42u
vm.memory.getUB(3) shouldBe 66u
@ -189,10 +189,10 @@ main {
}"""
val target = VMTarget()
val result = compileText(target, true, src, writeAssembly = true)!!
val start = result.program.entrypoint
val start = result.compilerAst.entrypoint
start.statements.size shouldBe 9
((start.statements[1] as Assignment).value as BuiltinFunctionCall).name shouldBe "memory"
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.memory.getUB(2) shouldBe 42u
vm.memory.getUB(3) shouldBe 43u
@ -213,7 +213,7 @@ main {
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.stepCount shouldBe 49
}
@ -283,7 +283,7 @@ main {
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
}
@ -304,7 +304,7 @@ main {
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
}
@ -329,7 +329,7 @@ mylabel:
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
}
@ -381,8 +381,8 @@ main {
}
}"""
val result = compileText(VMTarget(), true, src, writeAssembly = true)!!
result.program.entrypoint.statements.size shouldBe 9
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
result.compilerAst.entrypoint.statements.size shouldBe 9
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
val irProgram = IRFileReader().read(virtfile)
val start = irProgram.blocks[0].children[0] as IRSubroutine
val instructions = start.chunks.flatMap { c->c.instructions }

View File

@ -729,6 +729,7 @@ class Subroutine(override val name: String,
private val asmParamsDecls = mutableMapOf<String, VarDecl>()
fun searchParameter(name: String): VarDecl? {
// TODO can we get rid of this routine? it makes temporary vardecls...
val existingDecl = asmParamsDecls[name]
if(existingDecl!=null)
return existingDecl