mirror of
https://github.com/irmen/prog8.git
synced 2025-02-06 17:30:30 +00:00
working on new Ast and XML export to test it
This commit is contained in:
parent
e227cc92ff
commit
40e9fba312
@ -3,6 +3,7 @@ package prog8.code.ast
|
||||
import prog8.code.core.IMemSizer
|
||||
import prog8.code.core.IStringEncoding
|
||||
import prog8.code.core.Position
|
||||
import java.util.*
|
||||
|
||||
// New (work-in-progress) simplified AST for the code generator.
|
||||
|
||||
@ -62,6 +63,9 @@ class PtProgram(
|
||||
print("'$name'")
|
||||
}
|
||||
|
||||
fun allModuleDirectives(): Sequence<PtDirective> =
|
||||
children.asSequence().flatMap { it.children }.filterIsInstance<PtDirective>().distinct()
|
||||
|
||||
fun allBlocks(): Sequence<PtBlock> =
|
||||
children.asSequence().flatMap { it.children }.filterIsInstance<PtBlock>()
|
||||
|
||||
@ -72,7 +76,7 @@ class PtProgram(
|
||||
|
||||
class PtModule(
|
||||
name: String,
|
||||
val loadAddress: UInt,
|
||||
val loadAddress: UInt?,
|
||||
val library: Boolean,
|
||||
position: Position
|
||||
) : PtNamedNode(name, position) {
|
||||
@ -100,6 +104,18 @@ class PtDirective(var name: String, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return Objects.hash(name, args)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other !is PtDirective)
|
||||
return false
|
||||
if(other===this)
|
||||
return true
|
||||
return(name==other.name && args.zip(other.args).all { it.first==it.second })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,6 +127,18 @@ class PtDirectiveArg(val str: String?,
|
||||
override fun printProperties() {
|
||||
print("str=$str name=$name int=$int")
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return Objects.hash(str, name, int)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if(other !is PtDirectiveArg)
|
||||
return false
|
||||
if(other===this)
|
||||
return true
|
||||
return str==other.str || name==other.name || int==other.int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,76 +5,115 @@ import prog8.code.core.Encoding
|
||||
import prog8.code.core.Position
|
||||
|
||||
|
||||
class PtAddressOf(position: Position) : PtNode(position) {
|
||||
val identifier: PtIdentifier
|
||||
get() = children.single() as PtIdentifier
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtArrayIndexer(position: Position): PtNode(position) {
|
||||
val variable: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
val index: PtNode
|
||||
get() = children[1]
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtArrayLiteral(val type: DataType, position: Position): PtNode(position) {
|
||||
sealed class PtExpression(val type: DataType, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(type)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtBinaryExpression(val operator: String, position: Position): PtNode(position) {
|
||||
val left: PtNode
|
||||
get() = children[0]
|
||||
val right: PtNode
|
||||
get() = children[1]
|
||||
class PtAddressOf(position: Position) : PtExpression(DataType.UWORD, position) {
|
||||
val identifier: PtIdentifier
|
||||
get() = children.single() as PtIdentifier
|
||||
}
|
||||
|
||||
|
||||
class PtArrayIndexer(type: DataType, position: Position): PtExpression(type, position) {
|
||||
val variable: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
val index: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
}
|
||||
|
||||
|
||||
class PtArrayLiteral(type: DataType, position: Position): PtExpression(type, position)
|
||||
|
||||
|
||||
class PtBuiltinFunctionCall(val name: String, val void: Boolean, type: DataType, position: Position) : PtExpression(type, position) {
|
||||
init {
|
||||
if(!void)
|
||||
require(type!=DataType.UNDEFINED)
|
||||
}
|
||||
|
||||
val args: List<PtExpression>
|
||||
get() = children.map { it as PtExpression }
|
||||
override fun printProperties() {
|
||||
print(operator)
|
||||
print("$name void=$void")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtContainmentCheck(position: Position): PtNode(position) {
|
||||
val element: PtNode
|
||||
get() = children[0]
|
||||
val iterable: PtNode
|
||||
get() = children[0]
|
||||
override fun printProperties() {}
|
||||
}
|
||||
class PtBinaryExpression(val operator: String, type: DataType, position: Position): PtExpression(type, position) {
|
||||
val left: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val right: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
|
||||
|
||||
class PtIdentifier(val ref: List<String>, val targetName: List<String>, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$ref --> $targetName")
|
||||
print("$operator -> $type")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtMemoryByte(position: Position) : PtNode(position) {
|
||||
val address: PtNode
|
||||
get() = children.single()
|
||||
class PtContainmentCheck(position: Position): PtExpression(DataType.UBYTE, position) {
|
||||
val element: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val iterable: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
}
|
||||
|
||||
|
||||
class PtFunctionCall(val functionName: List<String>,
|
||||
val void: Boolean,
|
||||
type: DataType,
|
||||
position: Position) : PtExpression(type, position) {
|
||||
init {
|
||||
if(!void)
|
||||
require(type!=DataType.UNDEFINED)
|
||||
}
|
||||
|
||||
val args: List<PtExpression>
|
||||
get() = children.map { it as PtExpression }
|
||||
override fun printProperties() {
|
||||
print("${functionName.joinToString(".")} void=$void")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtIdentifier(val ref: List<String>, val targetName: List<String>, type: DataType, position: Position) : PtExpression(type, position) {
|
||||
override fun printProperties() {
|
||||
print("$ref --> $targetName $type")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position) {
|
||||
val address: PtExpression
|
||||
get() = children.single() as PtExpression
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtNumber(val type: DataType, val number: Double, position: Position) : PtNode(position) {
|
||||
class PtNumber(type: DataType, val number: Double, position: Position) : PtExpression(type, position) {
|
||||
override fun printProperties() {
|
||||
print("$number ($type)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtPrefix(val operator: String, position: Position): PtNode(position) {
|
||||
val value: PtNode
|
||||
get() = children.single()
|
||||
class PtPipe(type: DataType, val void: Boolean, position: Position) : PtExpression(type, position) {
|
||||
init {
|
||||
if(!void)
|
||||
require(type!=DataType.UNDEFINED)
|
||||
}
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtPrefix(val operator: String, type: DataType, position: Position): PtExpression(type, position) {
|
||||
val value: PtExpression
|
||||
get() = children.single() as PtExpression
|
||||
|
||||
override fun printProperties() {
|
||||
print(operator)
|
||||
@ -82,27 +121,26 @@ class PtPrefix(val operator: String, position: Position): PtNode(position) {
|
||||
}
|
||||
|
||||
|
||||
class PtRange(position: Position) : PtNode(position) {
|
||||
val from: PtNode
|
||||
get() = children[0]
|
||||
val to: PtNode
|
||||
get() = children[1]
|
||||
val step: PtNode
|
||||
get() = children[2]
|
||||
class PtRange(type: DataType, position: Position) : PtExpression(type, position) {
|
||||
val from: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val to: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
val step: PtExpression
|
||||
get() = children[2] as PtExpression
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtString(val value: String, val encoding: Encoding, position: Position) : PtNode(position) {
|
||||
class PtString(val value: String, val encoding: Encoding, position: Position) : PtExpression(DataType.STR, position) {
|
||||
override fun printProperties() {
|
||||
print("$encoding:\"$value\"")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtTypeCast(val type: DataType, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(type)
|
||||
}
|
||||
}
|
||||
class PtTypeCast(type: DataType, position: Position) : PtExpression(type, position) {
|
||||
val value: PtExpression
|
||||
get() = children.single() as PtExpression
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
package prog8.code.ast
|
||||
|
||||
import prog8.code.core.*
|
||||
import javax.xml.crypto.Data
|
||||
|
||||
|
||||
class PtAsmSub(
|
||||
name: String,
|
||||
val address: UInt?,
|
||||
val clobbers: Set<CpuRegister>,
|
||||
val paramRegisters: List<RegisterOrStatusflag>,
|
||||
val parameters: List<Pair<PtSubroutineParameter, RegisterOrStatusflag>>,
|
||||
val retvalRegisters: List<RegisterOrStatusflag>,
|
||||
val inline: Boolean,
|
||||
position: Position
|
||||
@ -41,8 +42,8 @@ class PtSubroutineParameter(val name: String, val type: DataType, position: Posi
|
||||
class PtAssignment(val augmentable: Boolean, position: Position) : PtNode(position) {
|
||||
val target: PtAssignTarget
|
||||
get() = children[0] as PtAssignTarget
|
||||
val value: PtNode
|
||||
get() = children[1]
|
||||
val value: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
|
||||
override fun printProperties() {
|
||||
print("aug=$augmentable")
|
||||
@ -62,13 +63,6 @@ class PtAssignTarget(position: Position) : PtNode(position) {
|
||||
}
|
||||
|
||||
|
||||
class PtBuiltinFunctionCall(val name: String, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtConditionalBranch(val condition: BranchCondition, position: Position) : PtNode(position) {
|
||||
val trueScope: PtNodeGroup
|
||||
get() = children[0] as PtNodeGroup
|
||||
@ -84,8 +78,8 @@ class PtConditionalBranch(val condition: BranchCondition, position: Position) :
|
||||
class PtForLoop(position: Position) : PtNode(position) {
|
||||
val variable: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
val iterable: PtNode
|
||||
get() = children[1]
|
||||
val iterable: PtExpression
|
||||
get() = children[1] as PtExpression
|
||||
val statements: PtNodeGroup
|
||||
get() = children[2] as PtNodeGroup
|
||||
|
||||
@ -93,18 +87,6 @@ class PtForLoop(position: Position) : PtNode(position) {
|
||||
}
|
||||
|
||||
|
||||
class PtFunctionCall(val void: Boolean, position: Position) : PtNode(position) {
|
||||
val target: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
val args: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {
|
||||
print("void=$void")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtGosub(val identifier: PtIdentifier?,
|
||||
val address: UInt?,
|
||||
val generatedLabel: String?,
|
||||
@ -118,8 +100,8 @@ class PtGosub(val identifier: PtIdentifier?,
|
||||
|
||||
|
||||
class PtIfElse(position: Position) : PtNode(position) {
|
||||
val condition: PtNode
|
||||
get() = children[0]
|
||||
val condition: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val ifScope: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
val elseScope: PtNodeGroup
|
||||
@ -141,11 +123,6 @@ class PtJump(val identifier: PtIdentifier?,
|
||||
}
|
||||
|
||||
|
||||
class PtPipe(position: Position) : PtNode(position) {
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtPostIncrDecr(val operator: String, position: Position) : PtNode(position) {
|
||||
val target: PtAssignTarget
|
||||
get() = children.single() as PtAssignTarget
|
||||
@ -157,8 +134,10 @@ class PtPostIncrDecr(val operator: String, position: Position) : PtNode(position
|
||||
|
||||
|
||||
class PtRepeatLoop(position: Position) : PtNode(position) {
|
||||
val count: PtNode
|
||||
get() = children.single()
|
||||
val count: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val statements: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
@ -166,10 +145,10 @@ class PtRepeatLoop(position: Position) : PtNode(position) {
|
||||
|
||||
class PtReturn(position: Position) : PtNode(position) {
|
||||
val hasValue = children.any()
|
||||
val value: PtNode?
|
||||
val value: PtExpression?
|
||||
get() {
|
||||
return if(children.any())
|
||||
children.single()
|
||||
children.single() as PtExpression
|
||||
else
|
||||
null
|
||||
}
|
||||
@ -200,8 +179,8 @@ class PtMemMapped(name: String, val type: DataType, val address: UInt, position:
|
||||
|
||||
|
||||
class PtWhen(position: Position) : PtNode(position) {
|
||||
val value: PtNode
|
||||
get() = children[0]
|
||||
val value: PtExpression
|
||||
get() = children[0] as PtExpression
|
||||
val choices: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
|
||||
@ -210,5 +189,9 @@ class PtWhen(position: Position) : PtNode(position) {
|
||||
|
||||
|
||||
class PtWhenChoice(val isElse: Boolean, position: Position) : PtNode(position) {
|
||||
val values: PtNodeGroup
|
||||
get() = children[0] as PtNodeGroup
|
||||
val statements: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out("")
|
||||
asmgen.out(".cpu '$cpu'\n.enc 'none'\n")
|
||||
|
||||
program.actualLoadAddress = program.definedLoadAddress
|
||||
program.actualLoadAddress = program.definedLoadAddress ?: 0u
|
||||
if (program.actualLoadAddress == 0u) {
|
||||
when(options.output) {
|
||||
OutputType.RAW -> {
|
||||
|
@ -1,11 +1,11 @@
|
||||
package prog8.codegen.experimental
|
||||
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.ast.PtProgram
|
||||
import prog8.code.core.CompilationOptions
|
||||
import prog8.code.core.IAssemblyGenerator
|
||||
import prog8.code.core.IAssemblyProgram
|
||||
import prog8.code.core.IErrorReporter
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
import javax.xml.stream.XMLOutputFactory
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.div
|
||||
|
||||
/*
|
||||
|
||||
@ -17,21 +17,578 @@ import prog8.code.core.IErrorReporter
|
||||
|
||||
*/
|
||||
|
||||
|
||||
class AsmGen(internal val program: PtProgram,
|
||||
internal val errors: IErrorReporter,
|
||||
internal val symbolTable: SymbolTable,
|
||||
internal val options: CompilationOptions
|
||||
): IAssemblyGenerator {
|
||||
|
||||
private lateinit var xml: IndentingXmlWriter
|
||||
|
||||
override fun compileToAssembly(): IAssemblyProgram? {
|
||||
|
||||
println("\n** experimental code generator **\n")
|
||||
|
||||
symbolTable.print()
|
||||
symbolTable.flat.forEach { println(it) }
|
||||
program.print()
|
||||
|
||||
val writer = (options.outputDir / Path(program.name+"-ast.xml")).toFile().printWriter()
|
||||
xml = IndentingXmlWriter(XMLOutputFactory.newFactory().createXMLStreamWriter(writer))
|
||||
xml.doc()
|
||||
xml.elt("program")
|
||||
xml.attr("name", program.name)
|
||||
xml.startChildren()
|
||||
program.allModuleDirectives().forEach { writeNode(it) }
|
||||
program.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
xml.endDoc()
|
||||
xml.close()
|
||||
println("..todo: create assembly code into ${options.outputDir.toAbsolutePath()}..")
|
||||
return AssemblyProgram("dummy")
|
||||
}
|
||||
|
||||
private fun writeNode(it: PtNode) {
|
||||
when(it) {
|
||||
is PtModule -> write(it)
|
||||
is PtBlock -> write(it)
|
||||
is PtDirective -> write(it)
|
||||
is PtSub -> write(it)
|
||||
is PtVariable -> write(it)
|
||||
is PtAssignment -> write(it)
|
||||
is PtConstant -> write(it)
|
||||
is PtAsmSub -> write(it)
|
||||
is PtAddressOf -> write(it)
|
||||
is PtArrayIndexer -> write(it)
|
||||
is PtArrayLiteral -> write(it)
|
||||
is PtBinaryExpression -> write(it)
|
||||
is PtBuiltinFunctionCall -> write(it)
|
||||
is PtConditionalBranch -> write(it)
|
||||
is PtContainmentCheck -> write(it)
|
||||
is PtForLoop -> write(it)
|
||||
is PtFunctionCall -> write(it)
|
||||
is PtGosub -> write(it)
|
||||
is PtIdentifier -> write(it)
|
||||
is PtIfElse -> write(it)
|
||||
is PtInlineAssembly -> write(it)
|
||||
is PtJump -> write(it)
|
||||
is PtMemoryByte -> write(it)
|
||||
is PtMemMapped -> write(it)
|
||||
is PtNumber -> write(it)
|
||||
is PtPipe -> write(it)
|
||||
is PtPostIncrDecr -> write(it)
|
||||
is PtPrefix -> write(it)
|
||||
is PtRange -> write(it)
|
||||
is PtRepeatLoop -> write(it)
|
||||
is PtReturn -> write(it)
|
||||
is PtString -> write(it)
|
||||
is PtTypeCast -> write(it)
|
||||
is PtWhen -> write(it)
|
||||
is PtWhenChoice -> write(it)
|
||||
is PtLabel -> write(it)
|
||||
is PtNodeGroup -> it.children.forEach { writeNode(it) }
|
||||
else -> TODO("$it")
|
||||
}
|
||||
}
|
||||
|
||||
private fun write(pipe: PtPipe) {
|
||||
xml.elt("pipe")
|
||||
xml.attr("type", pipe.type.name)
|
||||
xml.startChildren()
|
||||
pipe.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(array: PtArrayLiteral) {
|
||||
xml.elt("array")
|
||||
xml.attr("type", array.type.name)
|
||||
xml.startChildren()
|
||||
array.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(prefix: PtPrefix) {
|
||||
xml.elt("prefix")
|
||||
xml.attr("op", prefix.operator)
|
||||
xml.attr("type", prefix.type.name)
|
||||
xml.startChildren()
|
||||
xml.elt("value")
|
||||
xml.startChildren()
|
||||
writeNode(prefix.value)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(string: PtString) {
|
||||
xml.elt("string")
|
||||
xml.attr("encoding", string.encoding.name)
|
||||
xml.startChildren()
|
||||
xml.text(string.value)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(rept: PtRepeatLoop) {
|
||||
xml.elt("repeat")
|
||||
xml.startChildren()
|
||||
xml.pos(rept.position)
|
||||
xml.elt("count")
|
||||
xml.startChildren()
|
||||
writeNode(rept.count)
|
||||
xml.endElt()
|
||||
xml.elt("statements")
|
||||
writeNode(rept.statements)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(branch: PtConditionalBranch) {
|
||||
xml.elt("conditionalbranch")
|
||||
xml.attr("condition", branch.condition.name)
|
||||
xml.startChildren()
|
||||
xml.pos(branch.position)
|
||||
xml.elt("true")
|
||||
xml.startChildren()
|
||||
writeNode(branch.trueScope)
|
||||
xml.endElt()
|
||||
if(branch.falseScope.children.isNotEmpty()) {
|
||||
xml.elt("false")
|
||||
xml.startChildren()
|
||||
writeNode(branch.falseScope)
|
||||
xml.endElt()
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(check: PtContainmentCheck) {
|
||||
xml.elt("containment")
|
||||
xml.attr("type", check.type.name)
|
||||
xml.startChildren()
|
||||
xml.elt("element")
|
||||
xml.startChildren()
|
||||
writeNode(check.element)
|
||||
xml.endElt()
|
||||
xml.elt("iterable")
|
||||
xml.startChildren()
|
||||
writeNode(check.iterable)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(range: PtRange) {
|
||||
xml.elt("range")
|
||||
xml.attr("type", range.type.name)
|
||||
xml.startChildren()
|
||||
xml.elt("from")
|
||||
xml.startChildren()
|
||||
writeNode(range.from)
|
||||
xml.endElt()
|
||||
xml.elt("to")
|
||||
xml.startChildren()
|
||||
writeNode(range.to)
|
||||
xml.endElt()
|
||||
xml.elt("step")
|
||||
xml.startChildren()
|
||||
writeNode(range.step)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(forLoop: PtForLoop) {
|
||||
xml.elt("for")
|
||||
xml.attr("var", strTargetName(forLoop.variable))
|
||||
xml.startChildren()
|
||||
xml.pos(forLoop.position)
|
||||
xml.elt("iterable")
|
||||
xml.startChildren()
|
||||
writeNode(forLoop.iterable)
|
||||
xml.endElt()
|
||||
xml.elt("statements")
|
||||
xml.startChildren()
|
||||
writeNode(forLoop.statements)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(membyte: PtMemoryByte) {
|
||||
xml.elt("membyte")
|
||||
xml.attr("type", membyte.type.name)
|
||||
xml.startChildren()
|
||||
xml.elt("address")
|
||||
xml.startChildren()
|
||||
writeNode(membyte.address)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(whenStmt: PtWhen) {
|
||||
xml.elt("when")
|
||||
xml.startChildren()
|
||||
xml.pos(whenStmt.position)
|
||||
xml.elt("value")
|
||||
xml.startChildren()
|
||||
writeNode(whenStmt.value)
|
||||
xml.endElt()
|
||||
xml.elt("choices")
|
||||
xml.startChildren()
|
||||
writeNode(whenStmt.choices)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(choice: PtWhenChoice) {
|
||||
xml.elt("choice")
|
||||
if(choice.isElse) {
|
||||
xml.attr("else", "true")
|
||||
xml.startChildren()
|
||||
} else {
|
||||
xml.startChildren()
|
||||
xml.elt("values")
|
||||
xml.startChildren()
|
||||
writeNode(choice.values)
|
||||
xml.endElt()
|
||||
}
|
||||
xml.elt("statements")
|
||||
xml.startChildren()
|
||||
writeNode(choice.statements)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(inlineAsm: PtInlineAssembly) {
|
||||
xml.elt("assembly")
|
||||
xml.startChildren()
|
||||
xml.pos(inlineAsm.position)
|
||||
xml.elt("code")
|
||||
xml.text(inlineAsm.assembly)
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(fcall: PtBuiltinFunctionCall) {
|
||||
xml.elt("builtinfcall")
|
||||
xml.attr("name", fcall.name)
|
||||
if(fcall.void)
|
||||
xml.attr("type", "VOID")
|
||||
else
|
||||
xml.attr("type", fcall.type.name)
|
||||
xml.startChildren()
|
||||
fcall.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(cast: PtTypeCast) {
|
||||
xml.elt("cast")
|
||||
xml.attr("type", cast.type.name)
|
||||
xml.startChildren()
|
||||
writeNode(cast.value)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(aix: PtArrayIndexer) {
|
||||
xml.elt("arrayindexed")
|
||||
xml.attr("type", aix.type.name)
|
||||
xml.startChildren()
|
||||
write(aix.variable)
|
||||
writeNode(aix.index)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(binexpr: PtBinaryExpression) {
|
||||
xml.elt("binexpr")
|
||||
xml.attr("op", binexpr.operator)
|
||||
xml.attr("type", binexpr.type.name)
|
||||
xml.startChildren()
|
||||
writeNode(binexpr.left)
|
||||
writeNode(binexpr.right)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(addrof: PtAddressOf) {
|
||||
xml.elt("addrof")
|
||||
xml.startChildren()
|
||||
write(addrof.identifier)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(fcall: PtFunctionCall) {
|
||||
xml.elt("fcall")
|
||||
xml.attr("name", strTargetName(fcall))
|
||||
if(fcall.void)
|
||||
xml.attr("type", "VOID")
|
||||
else
|
||||
xml.attr("type", fcall.type.name)
|
||||
xml.startChildren()
|
||||
xml.pos(fcall.position)
|
||||
fcall.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(number: PtNumber) {
|
||||
xml.elt("number")
|
||||
xml.attr("type", number.type.name)
|
||||
xml.attr("value", intOrDouble(number.type, number.number).toString())
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(symbol: PtIdentifier) {
|
||||
xml.elt("symbol")
|
||||
xml.attr("name", strTargetName(symbol))
|
||||
xml.attr("type", symbol.type.name)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(assign: PtAssignment) {
|
||||
xml.elt("assign")
|
||||
xml.attr("aug", assign.augmentable.toString())
|
||||
xml.startChildren()
|
||||
xml.pos(assign.position)
|
||||
write(assign.target)
|
||||
writeNode(assign.value)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(ifElse: PtIfElse) {
|
||||
xml.elt("ifelse")
|
||||
xml.startChildren()
|
||||
xml.pos(ifElse.position)
|
||||
xml.elt("condition")
|
||||
xml.startChildren()
|
||||
writeNode(ifElse.condition)
|
||||
xml.endElt()
|
||||
xml.elt("true")
|
||||
xml.startChildren()
|
||||
xml.pos(ifElse.ifScope.position)
|
||||
writeNode(ifElse.ifScope)
|
||||
xml.endElt()
|
||||
if(ifElse.elseScope.children.isNotEmpty()) {
|
||||
xml.elt("false")
|
||||
xml.startChildren()
|
||||
xml.pos(ifElse.elseScope.position)
|
||||
writeNode(ifElse.elseScope)
|
||||
xml.endElt()
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(ret: PtReturn) {
|
||||
xml.elt("return")
|
||||
if(ret.hasValue) {
|
||||
xml.startChildren()
|
||||
writeNode(ret.value!!)
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(incdec: PtPostIncrDecr) {
|
||||
if(incdec.operator=="++") xml.elt("inc") else xml.elt("dec")
|
||||
xml.startChildren()
|
||||
write(incdec.target)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(label: PtLabel) {
|
||||
xml.elt("label")
|
||||
xml.attr("name", label.name)
|
||||
xml.startChildren()
|
||||
xml.pos(label.position)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(module: PtModule) {
|
||||
xml.elt("module")
|
||||
xml.attr("name", module.name)
|
||||
xml.attr("library", module.library.toString())
|
||||
if(module.loadAddress!=null)
|
||||
xml.attr("loadaddress", module.loadAddress.toString())
|
||||
xml.startChildren()
|
||||
xml.pos(module.position)
|
||||
module.children.asSequence().filter { it !is PtDirective }.forEach { write(it as PtBlock) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(block: PtBlock) {
|
||||
xml.elt("block")
|
||||
xml.attr("name", block.name)
|
||||
if(block.address!=null)
|
||||
xml.attr("address", block.address!!.toString())
|
||||
xml.attr("library", block.library.toString())
|
||||
xml.startChildren()
|
||||
xml.pos(block.position)
|
||||
block.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(memMapped: PtMemMapped) {
|
||||
xml.elt("memvar")
|
||||
xml.attr("type", memMapped.type.name)
|
||||
xml.attr("name", memMapped.name)
|
||||
xml.attr("address", memMapped.address.toString())
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(target: PtAssignTarget) {
|
||||
xml.elt("target")
|
||||
xml.startChildren()
|
||||
if(target.identifier!=null) {
|
||||
writeNode(target.identifier!!)
|
||||
} else if(target.memory!=null) {
|
||||
writeNode(target.memory!!)
|
||||
} else if(target.array!=null) {
|
||||
writeNode(target.array!!)
|
||||
} else
|
||||
throw InternalCompilerException("weird assign target")
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(jump: PtJump) {
|
||||
xml.elt("jump")
|
||||
if(jump.identifier!=null) xml.attr("symbol", strTargetName(jump.identifier!!))
|
||||
else if(jump.address!=null) xml.attr("address", jump.address!!.toString())
|
||||
else if(jump.generatedLabel!=null) xml.attr("label", jump.generatedLabel!!)
|
||||
else
|
||||
throw InternalCompilerException("weird jump target")
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(gosub: PtGosub) {
|
||||
xml.elt("gosub")
|
||||
if(gosub.identifier!=null) xml.attr("symbol", strTargetName(gosub.identifier!!))
|
||||
else if(gosub.address!=null) xml.attr("address", gosub.address!!.toString())
|
||||
else if(gosub.generatedLabel!=null) xml.attr("label", gosub.generatedLabel!!)
|
||||
else
|
||||
throw InternalCompilerException("weird jump target")
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(sub: PtSub) {
|
||||
xml.elt("sub")
|
||||
xml.attr("name", sub.name)
|
||||
if(sub.inline)
|
||||
xml.attr("inline", "true")
|
||||
xml.attr("returntype", sub.returntype?.toString() ?: "VOID")
|
||||
xml.startChildren()
|
||||
xml.pos(sub.position)
|
||||
if(sub.parameters.isNotEmpty()) {
|
||||
xml.elt("parameters")
|
||||
xml.startChildren()
|
||||
sub.parameters.forEach { write(it) }
|
||||
xml.endElt()
|
||||
}
|
||||
xml.elt("statements")
|
||||
xml.startChildren()
|
||||
sub.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(parameter: PtSubroutineParameter, registerOrStatusflag: RegisterOrStatusflag? = null) {
|
||||
xml.elt("param")
|
||||
xml.attr("name", parameter.name)
|
||||
xml.attr("type", parameter.type.name)
|
||||
if(registerOrStatusflag?.statusflag!=null) {
|
||||
xml.attr("statusflag", registerOrStatusflag.statusflag!!.toString())
|
||||
}
|
||||
if(registerOrStatusflag?.registerOrPair!=null){
|
||||
xml.attr("registers", registerOrStatusflag.registerOrPair!!.name)
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(asmSub: PtAsmSub) {
|
||||
if(asmSub.address!=null) {
|
||||
xml.elt("romsub")
|
||||
xml.attr("name", asmSub.name)
|
||||
xml.attr("address", asmSub.address!!.toString())
|
||||
if(asmSub.inline)
|
||||
xml.attr("inline", "true")
|
||||
xml.startChildren()
|
||||
xml.pos(asmSub.position)
|
||||
paramsEtcetera(asmSub)
|
||||
xml.endElt()
|
||||
}
|
||||
else {
|
||||
xml.elt("asmsub")
|
||||
xml.attr("name", asmSub.name)
|
||||
if(asmSub.inline)
|
||||
xml.attr("inline", "true")
|
||||
xml.startChildren()
|
||||
xml.pos(asmSub.position)
|
||||
paramsEtcetera(asmSub)
|
||||
xml.elt("code")
|
||||
xml.startChildren()
|
||||
asmSub.children.forEach { writeNode(it) }
|
||||
xml.endElt()
|
||||
xml.endElt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun paramsEtcetera(asmSub: PtAsmSub) {
|
||||
if(asmSub.parameters.isNotEmpty()) {
|
||||
xml.elt("parameters")
|
||||
xml.startChildren()
|
||||
asmSub.parameters.forEach { (param, reg) -> write(param, reg) }
|
||||
xml.endElt()
|
||||
}
|
||||
if(asmSub.clobbers.isNotEmpty()) {
|
||||
xml.elt("clobbers")
|
||||
xml.attr("registers", asmSub.clobbers.map {it.name}.joinToString(","))
|
||||
xml.endElt()
|
||||
}
|
||||
if(asmSub.retvalRegisters.isNotEmpty()) {
|
||||
xml.elt("returns")
|
||||
xml.startChildren()
|
||||
asmSub.retvalRegisters.forEach {
|
||||
xml.elt("register")
|
||||
if(it.statusflag!=null)
|
||||
xml.attr("statusflag", it.statusflag!!.toString())
|
||||
if(it.registerOrPair!=null)
|
||||
xml.attr("registers", it.registerOrPair!!.toString())
|
||||
xml.endElt()
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
}
|
||||
|
||||
private fun write(constant: PtConstant) {
|
||||
xml.elt("const")
|
||||
xml.attr("name", constant.name)
|
||||
xml.attr("type", constant.type.name)
|
||||
xml.attr("value", intOrDouble(constant.type, constant.value).toString())
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(variable: PtVariable) {
|
||||
// TODO get this from the AST only?
|
||||
xml.elt("var")
|
||||
xml.attr("name", variable.name)
|
||||
xml.attr("type", variable.type.name)
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
private fun write(directive: PtDirective) {
|
||||
if(directive.name=="%import")
|
||||
return
|
||||
xml.elt("directive")
|
||||
xml.attr("name", directive.name.substring(1))
|
||||
if(directive.args.isNotEmpty()) {
|
||||
xml.startChildren()
|
||||
directive.args.forEach {
|
||||
xml.elt("arg")
|
||||
if(it.name!=null)
|
||||
xml.attr("name", it.name!!)
|
||||
if(it.str!=null)
|
||||
xml.attr("string", it.str!!)
|
||||
if(it.int!=null)
|
||||
xml.attr("number", it.int!!.toString())
|
||||
xml.endElt()
|
||||
}
|
||||
}
|
||||
xml.endElt()
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun strTargetName(ident: PtIdentifier): String = ident.targetName.joinToString(".")
|
||||
|
||||
private fun strTargetName(call: PtFunctionCall): String = call.functionName.joinToString(".")
|
||||
|
||||
private fun intOrDouble(type: DataType, value: Double): Number =
|
||||
if(type in IntegerDatatypes) value.toInt() else value
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package prog8.codegen.experimental
|
||||
|
||||
import prog8.code.core.Position
|
||||
import java.util.*
|
||||
import javax.xml.stream.XMLStreamWriter
|
||||
|
||||
class IndentingXmlWriter(val xml: XMLStreamWriter): XMLStreamWriter by xml {
|
||||
private var indent = 0
|
||||
private var content = Stack<Boolean>()
|
||||
|
||||
fun doc(version: String? = null) = if(version==null) writeStartDocument() else writeStartDocument(version)
|
||||
fun endDoc() = writeEndDocument()
|
||||
fun elt(name: String) = writeStartElement(name)
|
||||
fun attr(name: String, value: String) = writeAttribute(name, value)
|
||||
fun attrs(attributes: List<Pair<String, String>>) = attributes.forEach { writeAttribute(it.first, it.second) }
|
||||
fun text(text: String) = writeCData(text)
|
||||
fun startChildren() {
|
||||
xml.writeCharacters("\n")
|
||||
content.pop()
|
||||
content.push(true)
|
||||
}
|
||||
fun endElt() = this.writeEndElement()
|
||||
fun pos(pos: Position) {
|
||||
elt("src")
|
||||
attr("pos", pos.toString())
|
||||
endElt()
|
||||
}
|
||||
fun comment(text: String) {
|
||||
writeComment(text)
|
||||
writeCharacters("\n")
|
||||
}
|
||||
|
||||
override fun writeStartDocument() {
|
||||
xml.writeStartDocument()
|
||||
xml.writeCharacters("\n")
|
||||
content.push(true)
|
||||
}
|
||||
|
||||
override fun writeStartDocument(version: String) {
|
||||
xml.writeStartDocument(version)
|
||||
xml.writeCharacters("\n")
|
||||
content.push(true)
|
||||
}
|
||||
|
||||
override fun writeEndDocument() {
|
||||
xml.writeEndDocument()
|
||||
xml.writeCharacters("\n")
|
||||
require(indent==0)
|
||||
require(content.size==1)
|
||||
}
|
||||
|
||||
override fun writeStartElement(name: String) {
|
||||
xml.writeCharacters(" ".repeat(indent))
|
||||
xml.writeStartElement(name)
|
||||
indent++
|
||||
content.push(false)
|
||||
}
|
||||
|
||||
override fun writeStartElement(name: String, ns: String) {
|
||||
xml.writeCharacters(" ".repeat(indent))
|
||||
xml.writeStartElement(name, ns)
|
||||
indent++
|
||||
content.push(false)
|
||||
}
|
||||
|
||||
override fun writeEndElement() {
|
||||
indent--
|
||||
if(content.pop())
|
||||
xml.writeCharacters(" ".repeat(indent))
|
||||
xml.writeEndElement()
|
||||
xml.writeCharacters("\n")
|
||||
}
|
||||
|
||||
override fun writeStartElement(name: String, ns: String, p2: String) {
|
||||
xml.writeCharacters(" ".repeat(indent))
|
||||
xml.writeStartElement(name, ns, p2)
|
||||
indent++
|
||||
content.push(false)
|
||||
}
|
||||
}
|
@ -6,21 +6,22 @@ import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.DataType
|
||||
|
||||
|
||||
class IntermediateAstMaker(val srcProgram: Program) {
|
||||
class IntermediateAstMaker(val program: Program) {
|
||||
fun transform(): PtProgram {
|
||||
val program = PtProgram(
|
||||
srcProgram.name,
|
||||
srcProgram.memsizer,
|
||||
srcProgram.encoding
|
||||
val ptProgram = PtProgram(
|
||||
program.name,
|
||||
program.memsizer,
|
||||
program.encoding
|
||||
)
|
||||
|
||||
for (module in srcProgram.modules) {
|
||||
program.add(transform(module))
|
||||
for (module in program.modules) {
|
||||
ptProgram.add(transform(module))
|
||||
}
|
||||
|
||||
return program
|
||||
return ptProgram
|
||||
}
|
||||
|
||||
private fun transform(srcModule: Module): PtModule {
|
||||
@ -71,7 +72,7 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformExpression(expr: Expression): PtNode {
|
||||
private fun transformExpression(expr: Expression): PtExpression {
|
||||
return when(expr) {
|
||||
is AddressOf -> transform(expr)
|
||||
is ArrayIndexedExpression -> transform(expr)
|
||||
@ -112,13 +113,19 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
return target
|
||||
}
|
||||
|
||||
private fun transform(identifier: IdentifierReference): PtIdentifier {
|
||||
val target=identifier.targetStatement(srcProgram)!! as INamedStatement
|
||||
val targetname = if(target.name in srcProgram.builtinFunctions.names)
|
||||
private fun targetOf(identifier: IdentifierReference): Pair<List<String>, DataType> {
|
||||
val target=identifier.targetStatement(program)!! as INamedStatement
|
||||
val targetname = if(target.name in program.builtinFunctions.names)
|
||||
listOf("<builtin>", target.name)
|
||||
else
|
||||
target.scopedName
|
||||
return PtIdentifier(identifier.nameInSource, targetname, identifier.position)
|
||||
val type = identifier.inferType(program).getOr(DataType.UNDEFINED)
|
||||
return Pair(targetname, type)
|
||||
}
|
||||
|
||||
private fun transform(identifier: IdentifierReference): PtIdentifier {
|
||||
val (target, type) = targetOf(identifier)
|
||||
return PtIdentifier(identifier.nameInSource, target, type, identifier.position)
|
||||
}
|
||||
|
||||
private fun transform(srcBlock: Block): PtBlock {
|
||||
@ -131,7 +138,8 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transform(srcNode: BuiltinFunctionCallStatement): PtBuiltinFunctionCall {
|
||||
val call = PtBuiltinFunctionCall(srcNode.name, srcNode.position)
|
||||
val type = builtinFunctionReturnType(srcNode.name, srcNode.args, program).getOr(DataType.UNDEFINED)
|
||||
val call = PtBuiltinFunctionCall(srcNode.name, true, type, srcNode.position)
|
||||
for (arg in srcNode.args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
@ -173,22 +181,19 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transform(srcCall: FunctionCallStatement): PtFunctionCall {
|
||||
val call = PtFunctionCall(true, srcCall.position)
|
||||
call.add(transform(srcCall.target))
|
||||
val args = PtNodeGroup()
|
||||
val (target, type) = targetOf(srcCall.target)
|
||||
val call = PtFunctionCall(target,true, type, srcCall.position)
|
||||
for (arg in srcCall.args)
|
||||
args.add(transformExpression(arg))
|
||||
call.add(args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
}
|
||||
|
||||
private fun transform(srcCall: FunctionCallExpression): PtFunctionCall {
|
||||
val call = PtFunctionCall(false, srcCall.position)
|
||||
call.add(transform(srcCall.target))
|
||||
val args = PtNodeGroup()
|
||||
val (target, _) = targetOf(srcCall.target)
|
||||
val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val call = PtFunctionCall(target, false, type, srcCall.position)
|
||||
for (arg in srcCall.args)
|
||||
args.add(transformExpression(arg))
|
||||
call.add(args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
}
|
||||
|
||||
@ -229,7 +234,8 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
PtLabel(label.name, label.position)
|
||||
|
||||
private fun transform(srcPipe: Pipe): PtPipe {
|
||||
val pipe = PtPipe(srcPipe.position)
|
||||
val type = srcPipe.segments.last().inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val pipe = PtPipe(type, true, srcPipe.position)
|
||||
pipe.add(transformExpression(srcPipe.source))
|
||||
for (segment in srcPipe.segments)
|
||||
pipe.add(transformExpression(segment))
|
||||
@ -247,9 +253,11 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
throw FatalAstException("repeat-forever loop should have been replaced with label+jump")
|
||||
val repeat = PtRepeatLoop(srcRepeat.position)
|
||||
repeat.add(transformExpression(srcRepeat.iterations!!))
|
||||
val scope = PtNodeGroup()
|
||||
for (statement in srcRepeat.body.statements) {
|
||||
repeat.add(transformStatement(statement))
|
||||
scope.add(transformStatement(statement))
|
||||
}
|
||||
repeat.add(scope)
|
||||
return repeat
|
||||
}
|
||||
|
||||
@ -261,10 +269,13 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transformAsmSub(srcSub: Subroutine): PtAsmSub {
|
||||
val params = srcSub.parameters
|
||||
.map { PtSubroutineParameter(it.name, it.type, it.position) }
|
||||
.zip(srcSub.asmParameterRegisters)
|
||||
val sub = PtAsmSub(srcSub.name,
|
||||
srcSub.asmAddress,
|
||||
srcSub.asmClobbers,
|
||||
srcSub.asmParameterRegisters,
|
||||
params,
|
||||
srcSub.asmReturnvaluesRegisters,
|
||||
srcSub.inline,
|
||||
srcSub.position)
|
||||
@ -334,7 +345,8 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
||||
val array = PtArrayIndexer(srcArr.position)
|
||||
val type = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val array = PtArrayIndexer(type, srcArr.position)
|
||||
array.add(transform(srcArr.arrayvar))
|
||||
array.add(transformExpression(srcArr.indexer.indexExpr))
|
||||
return array
|
||||
@ -348,14 +360,16 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transform(srcExpr: BinaryExpression): PtBinaryExpression {
|
||||
val expr = PtBinaryExpression(srcExpr.operator, srcExpr.position)
|
||||
val type = srcExpr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val expr = PtBinaryExpression(srcExpr.operator, type, srcExpr.position)
|
||||
expr.add(transformExpression(srcExpr.left))
|
||||
expr.add(transformExpression(srcExpr.right))
|
||||
return expr
|
||||
}
|
||||
|
||||
private fun transform(srcCall: BuiltinFunctionCall): PtBuiltinFunctionCall {
|
||||
val call = PtBuiltinFunctionCall(srcCall.name, srcCall.position)
|
||||
val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val call = PtBuiltinFunctionCall(srcCall.name, false, type, srcCall.position)
|
||||
for (arg in srcCall.args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
@ -384,7 +398,8 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
PtNumber(number.type, number.number, number.position)
|
||||
|
||||
private fun transform(srcPipe: PipeExpression): PtPipe {
|
||||
val pipe = PtPipe(srcPipe.position)
|
||||
val type = srcPipe.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val pipe = PtPipe(type, false, srcPipe.position)
|
||||
pipe.add(transformExpression(srcPipe.source))
|
||||
for (segment in srcPipe.segments)
|
||||
pipe.add(transformExpression(segment))
|
||||
@ -392,13 +407,15 @@ class IntermediateAstMaker(val srcProgram: Program) {
|
||||
}
|
||||
|
||||
private fun transform(srcPrefix: PrefixExpression): PtPrefix {
|
||||
val prefix = PtPrefix(srcPrefix.operator, srcPrefix.position)
|
||||
val type = srcPrefix.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val prefix = PtPrefix(srcPrefix.operator, type, srcPrefix.position)
|
||||
prefix.add(transformExpression(srcPrefix.expression))
|
||||
return prefix
|
||||
}
|
||||
|
||||
private fun transform(srcRange: RangeExpression): PtRange {
|
||||
val range=PtRange(srcRange.position)
|
||||
val type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val range=PtRange(type, srcRange.position)
|
||||
range.add(transformExpression(srcRange.from))
|
||||
range.add(transformExpression(srcRange.to))
|
||||
range.add(transformExpression(srcRange.step))
|
||||
|
@ -285,9 +285,8 @@ open class Module(final override var statements: MutableList<Statement>,
|
||||
.substringAfterLast("/")
|
||||
.substringAfterLast("\\")
|
||||
|
||||
val loadAddress: UInt by lazy {
|
||||
val address = (statements.singleOrNull { it is Directive && it.directive == "%address" } as? Directive)?.args?.single()?.int ?: 0u
|
||||
address
|
||||
val loadAddress: UInt? by lazy {
|
||||
(statements.singleOrNull { it is Directive && it.directive == "%address" } as? Directive)?.args?.single()?.int
|
||||
}
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
|
@ -67,7 +67,7 @@ class Program(val name: String,
|
||||
val toplevelModule: Module
|
||||
get() = modules.first { it.name!= internedStringsModuleName }
|
||||
|
||||
val definedLoadAddress: UInt
|
||||
val definedLoadAddress: UInt?
|
||||
get() = toplevelModule.loadAddress
|
||||
|
||||
var actualLoadAddress = 0u
|
||||
|
@ -3,6 +3,8 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- unit test for PtProgram AST: should also test new things such as the Datatype in nodes.
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -28,11 +28,11 @@ main {
|
||||
txt.print_ub(amount)
|
||||
txt.nl()
|
||||
|
||||
; test_stack.test()
|
||||
}
|
||||
uword[] @shared array = [111,222,333,444,555]
|
||||
|
||||
sub derp() -> ubyte, ubyte {
|
||||
return 0, 1
|
||||
amount = amount |> sin8u() |> cos8u() |> sin8u()
|
||||
|
||||
; test_stack.test()
|
||||
}
|
||||
|
||||
sub find_next_prime() -> ubyte {
|
||||
|
Loading…
x
Reference in New Issue
Block a user