mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
added new intermediate (simplified) AST meant for new codegen
This commit is contained in:
parent
e7c4bf5ebf
commit
0a04e626d7
@ -14,6 +14,9 @@ class AsmGen(internal val program: Program,
|
||||
|
||||
symbolTable.print()
|
||||
|
||||
// TODO temporary location to do this:
|
||||
val intermediateAst = IntermediateAstMaker.transform(program)
|
||||
intermediateAst.print()
|
||||
|
||||
println("..todo: create assembly code into ${options.outputDir.toAbsolutePath()}..")
|
||||
return AssemblyProgram("dummy")
|
||||
|
@ -0,0 +1,412 @@
|
||||
package prog8.codegen.experimental6502
|
||||
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.base.VarDeclType
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.*
|
||||
import prog8.compilerinterface.intermediate.*
|
||||
|
||||
|
||||
object IntermediateAstMaker {
|
||||
fun transform(srcProgram: Program): PtProgram {
|
||||
val program = PtProgram(
|
||||
srcProgram.name,
|
||||
srcProgram.builtinFunctions,
|
||||
srcProgram.memsizer,
|
||||
srcProgram.encoding
|
||||
)
|
||||
|
||||
for (module in srcProgram.modules) {
|
||||
program.add(transform(module))
|
||||
}
|
||||
|
||||
return program
|
||||
}
|
||||
|
||||
private fun transform(srcModule: Module): PtModule {
|
||||
val module = PtModule(
|
||||
srcModule.name,
|
||||
srcModule.source,
|
||||
srcModule.loadAddress,
|
||||
srcModule.isLibrary,
|
||||
srcModule.position
|
||||
)
|
||||
|
||||
for (statement in srcModule.statements)
|
||||
module.add(transformStatement(statement))
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
private fun transformStatement(statement: Statement): PtNode {
|
||||
return when (statement) {
|
||||
is AnonymousScope -> throw FatalAstException("AnonymousScopes should have been flattened")
|
||||
is Assignment -> transform(statement)
|
||||
is Block -> transform(statement)
|
||||
is Break -> throw FatalAstException("break should have been replaced by Goto")
|
||||
is BuiltinFunctionCallStatement -> transform(statement)
|
||||
is BuiltinFunctionPlaceholder -> throw FatalAstException("BuiltinFunctionPlaceholder should not occur in Ast here")
|
||||
is ConditionalBranch -> transform(statement)
|
||||
is Directive -> transform(statement)
|
||||
is ForLoop -> transform(statement)
|
||||
is FunctionCallStatement -> transform(statement)
|
||||
is GoSub -> transform(statement)
|
||||
is IfElse -> transform(statement)
|
||||
is InlineAssembly -> transform(statement)
|
||||
is Jump -> transform(statement)
|
||||
is Label -> transform(statement)
|
||||
is Pipe -> transform(statement)
|
||||
is PostIncrDecr -> transform(statement)
|
||||
is RepeatLoop -> transform(statement)
|
||||
is Return -> transform(statement)
|
||||
is Subroutine -> {
|
||||
if(statement.isAsmSubroutine)
|
||||
transformAsmSub(statement)
|
||||
else
|
||||
transformSub(statement)
|
||||
}
|
||||
is UntilLoop -> throw FatalAstException("until loops must have been converted to jumps")
|
||||
is VarDecl -> transform(statement)
|
||||
is When -> transform(statement)
|
||||
is WhileLoop -> throw FatalAstException("while loops must have been converted to jumps")
|
||||
}
|
||||
}
|
||||
|
||||
private fun transformExpression(expr: Expression): PtNode {
|
||||
return when(expr) {
|
||||
is AddressOf -> transform(expr)
|
||||
is ArrayIndexedExpression -> transform(expr)
|
||||
is ArrayLiteral -> transform(expr)
|
||||
is BinaryExpression -> transform(expr)
|
||||
is BuiltinFunctionCall -> transform(expr)
|
||||
is CharLiteral -> throw FatalAstException("char literals should have been converted into bytes")
|
||||
is ContainmentCheck -> transform(expr)
|
||||
is DirectMemoryRead -> transform(expr)
|
||||
is FunctionCallExpression -> transform(expr)
|
||||
is IdentifierReference -> transform(expr)
|
||||
is NumericLiteral -> transform(expr)
|
||||
is PipeExpression -> transform(expr)
|
||||
is PrefixExpression -> transform(expr)
|
||||
is RangeExpression -> transform(expr)
|
||||
is StringLiteral -> transform(expr)
|
||||
is TypecastExpression -> transform(expr)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transform(srcAssign: Assignment): PtAssignment {
|
||||
val assign = PtAssignment(srcAssign.isAugmentable, srcAssign.origin, srcAssign.position)
|
||||
assign.add(transform(srcAssign.target))
|
||||
assign.add(transformExpression(srcAssign.value))
|
||||
return assign
|
||||
}
|
||||
|
||||
private fun transform(srcTarget: AssignTarget): PtAssignTarget {
|
||||
val target = PtAssignTarget(srcTarget.position)
|
||||
if(srcTarget.identifier!=null)
|
||||
target.add(transform(srcTarget.identifier!!))
|
||||
else if(srcTarget.arrayindexed!=null)
|
||||
target.add(transform(srcTarget.arrayindexed!!))
|
||||
else if(srcTarget.memoryAddress!=null)
|
||||
target.add(transform(srcTarget.memoryAddress!!))
|
||||
else
|
||||
throw FatalAstException("invalid AssignTarget")
|
||||
return target
|
||||
}
|
||||
|
||||
private fun transform(identifier: IdentifierReference): PtIdentifier =
|
||||
PtIdentifier(identifier.nameInSource, identifier.position)
|
||||
|
||||
private fun transform(srcBlock: Block): PtBlock {
|
||||
val block = PtBlock(srcBlock.name, srcBlock.address, srcBlock.isInLibrary, srcBlock.position)
|
||||
|
||||
for (stmt in srcBlock.statements)
|
||||
block.add(transformStatement(stmt))
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
private fun transform(srcNode: BuiltinFunctionCallStatement): PtBuiltinFunctionCall {
|
||||
val call = PtBuiltinFunctionCall(srcNode.name, srcNode.position)
|
||||
for (arg in srcNode.args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
}
|
||||
|
||||
private fun transform(srcBranch: ConditionalBranch): PtConditionalBranch {
|
||||
val branch = PtConditionalBranch(srcBranch.condition, srcBranch.position)
|
||||
val trueScope = PtNodeGroup()
|
||||
val falseScope = PtNodeGroup()
|
||||
for (stmt in srcBranch.truepart.statements)
|
||||
trueScope.add(transformStatement(stmt))
|
||||
for (stmt in srcBranch.elsepart.statements)
|
||||
falseScope.add(transformStatement(stmt))
|
||||
branch.add(trueScope)
|
||||
branch.add(falseScope)
|
||||
return branch
|
||||
}
|
||||
|
||||
private fun transform(directive: Directive): PtDirective {
|
||||
val dir = PtDirective(directive.directive, directive.position)
|
||||
for (arg in directive.args) {
|
||||
dir.add(transform(arg))
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
private fun transform(arg: DirectiveArg): PtDirectiveArg =
|
||||
PtDirectiveArg(arg.str, arg.name, arg.int, arg.position)
|
||||
|
||||
private fun transform(srcFor: ForLoop): PtForLoop {
|
||||
val forloop = PtForLoop(srcFor.position)
|
||||
forloop.add(transform(srcFor.loopVar))
|
||||
forloop.add(transformExpression(srcFor.iterable))
|
||||
val statements = PtNodeGroup()
|
||||
for (stmt in srcFor.body.statements)
|
||||
statements.add(transformStatement(stmt))
|
||||
forloop.add(statements)
|
||||
return forloop
|
||||
}
|
||||
|
||||
private fun transform(srcCall: FunctionCallStatement): PtFunctionCall {
|
||||
val call = PtFunctionCall(true, srcCall.position)
|
||||
call.add(transform(srcCall.target))
|
||||
val args = PtNodeGroup()
|
||||
for (arg in srcCall.args)
|
||||
args.add(transformExpression(arg))
|
||||
call.add(args)
|
||||
return call
|
||||
}
|
||||
|
||||
private fun transform(srcCall: FunctionCallExpression): PtFunctionCall {
|
||||
val call = PtFunctionCall(false, srcCall.position)
|
||||
call.add(transform(srcCall.target))
|
||||
val args = PtNodeGroup()
|
||||
for (arg in srcCall.args)
|
||||
args.add(transformExpression(arg))
|
||||
call.add(args)
|
||||
return call
|
||||
}
|
||||
|
||||
private fun transform(gosub: GoSub): PtGosub {
|
||||
val identifier = if(gosub.identifier!=null) transform(gosub.identifier!!) else null
|
||||
return PtGosub(identifier,
|
||||
gosub.address,
|
||||
gosub.generatedLabel,
|
||||
gosub.position)
|
||||
}
|
||||
|
||||
private fun transform(srcIf: IfElse): PtIfElse {
|
||||
val ifelse = PtIfElse(srcIf.position)
|
||||
ifelse.add(transformExpression(srcIf.condition))
|
||||
val ifScope = PtNodeGroup()
|
||||
val elseScope = PtNodeGroup()
|
||||
for (stmt in srcIf.truepart.statements)
|
||||
ifScope.add(transformStatement(stmt))
|
||||
for (stmt in srcIf.elsepart.statements)
|
||||
elseScope.add(transformStatement(stmt))
|
||||
ifelse.add(ifScope)
|
||||
ifelse.add(elseScope)
|
||||
return ifelse
|
||||
}
|
||||
|
||||
private fun transform(srcNode: InlineAssembly): PtInlineAssembly =
|
||||
PtInlineAssembly(srcNode.assembly, srcNode.position)
|
||||
|
||||
private fun transform(srcJump: Jump): PtJump {
|
||||
val identifier = if(srcJump.identifier!=null) transform(srcJump.identifier!!) else null
|
||||
return PtJump(identifier,
|
||||
srcJump.address,
|
||||
srcJump.generatedLabel,
|
||||
srcJump.position)
|
||||
}
|
||||
|
||||
private fun transform(label: Label): PtLabel =
|
||||
PtLabel(label.name, label.position)
|
||||
|
||||
private fun transform(srcPipe: Pipe): PtPipe {
|
||||
val pipe = PtPipe(srcPipe.position)
|
||||
pipe.add(transformExpression(srcPipe.source))
|
||||
for (segment in srcPipe.segments)
|
||||
pipe.add(transformExpression(segment))
|
||||
return pipe
|
||||
}
|
||||
|
||||
private fun transform(src: PostIncrDecr): PtPostIncrDecr {
|
||||
val post = PtPostIncrDecr(src.operator, src.position)
|
||||
post.add(transform(src.target))
|
||||
return post
|
||||
}
|
||||
|
||||
private fun transform(srcRepeat: RepeatLoop): PtRepeatLoop {
|
||||
val repeat = PtRepeatLoop(srcRepeat.iterations==null, srcRepeat.position)
|
||||
if(srcRepeat.iterations!=null)
|
||||
repeat.add(transformExpression(srcRepeat.iterations!!))
|
||||
for (statement in srcRepeat.body.statements) {
|
||||
repeat.add(transformStatement(statement))
|
||||
}
|
||||
return repeat
|
||||
}
|
||||
|
||||
private fun transform(srcNode: Return): PtReturn {
|
||||
val ret = PtReturn(srcNode.position)
|
||||
if(srcNode.value!=null)
|
||||
ret.add(transformExpression(srcNode.value!!))
|
||||
return ret
|
||||
}
|
||||
|
||||
private fun transformAsmSub(srcSub: Subroutine): PtAsmSub {
|
||||
val sub = PtAsmSub(srcSub.name,
|
||||
srcSub.asmAddress,
|
||||
srcSub.asmClobbers,
|
||||
srcSub.asmParameterRegisters,
|
||||
srcSub.asmReturnvaluesRegisters,
|
||||
srcSub.inline,
|
||||
srcSub.position)
|
||||
if(srcSub.asmAddress==null) {
|
||||
var combinedAsm = ""
|
||||
for (asm in srcSub.statements)
|
||||
combinedAsm += (asm as InlineAssembly).assembly + "\n"
|
||||
if(combinedAsm.isNotEmpty())
|
||||
sub.add(PtInlineAssembly(combinedAsm, srcSub.statements[0].position))
|
||||
else
|
||||
sub.add(PtInlineAssembly("", srcSub.position))
|
||||
}
|
||||
|
||||
return sub
|
||||
}
|
||||
|
||||
private fun transformSub(srcSub: Subroutine): PtSub {
|
||||
val sub = PtSub(srcSub.name,
|
||||
srcSub.parameters,
|
||||
srcSub.returntypes,
|
||||
srcSub.inline,
|
||||
srcSub.position)
|
||||
|
||||
for (statement in srcSub.statements)
|
||||
sub.add(transformStatement(statement))
|
||||
|
||||
return sub
|
||||
}
|
||||
|
||||
private fun transform(srcVar: VarDecl): PtNode {
|
||||
return when(srcVar.type) {
|
||||
VarDeclType.VAR -> PtVariable(srcVar.name, srcVar.datatype, srcVar.position)
|
||||
VarDeclType.CONST -> PtConstant(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number, srcVar.position)
|
||||
VarDeclType.MEMORY -> PtMemMapped(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number.toUInt(), srcVar.position)
|
||||
}
|
||||
}
|
||||
|
||||
private fun transform(srcWhen: When): PtWhen {
|
||||
val w = PtWhen(srcWhen.position)
|
||||
w.add(transformExpression(srcWhen.condition))
|
||||
val choices = PtNodeGroup()
|
||||
for (choice in srcWhen.choices)
|
||||
choices.add(transform(choice))
|
||||
w.add(choices)
|
||||
return w
|
||||
}
|
||||
|
||||
private fun transform(srcChoice: WhenChoice): PtWhenChoice {
|
||||
val choice = PtWhenChoice(srcChoice.values==null, srcChoice.position)
|
||||
val values = PtNodeGroup()
|
||||
val statements = PtNodeGroup()
|
||||
if(!choice.isElse) {
|
||||
for (value in srcChoice.values!!)
|
||||
values.add(transformExpression(value))
|
||||
}
|
||||
for (stmt in srcChoice.statements.statements)
|
||||
statements.add(transformStatement(stmt))
|
||||
choice.add(values)
|
||||
choice.add(statements)
|
||||
return choice
|
||||
}
|
||||
|
||||
private fun transform(src: AddressOf): PtAddressOf {
|
||||
val addr = PtAddressOf(src.position)
|
||||
addr.add(transform(src.identifier))
|
||||
return addr
|
||||
}
|
||||
|
||||
private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer {
|
||||
val array = PtArrayIndexer(srcArr.position)
|
||||
array.add(transform(srcArr.arrayvar))
|
||||
array.add(transformExpression(srcArr.indexer.indexExpr))
|
||||
return array
|
||||
}
|
||||
|
||||
private fun transform(srcArr: ArrayLiteral): PtArrayLiteral {
|
||||
val arr = PtArrayLiteral(srcArr.type.getOrElse { throw FatalAstException("array must know its type") }, srcArr.position)
|
||||
for (elt in srcArr.value)
|
||||
arr.add(transformExpression(elt))
|
||||
return arr
|
||||
}
|
||||
|
||||
private fun transform(srcExpr: BinaryExpression): PtBinaryExpression {
|
||||
val expr = PtBinaryExpression(srcExpr.operator, 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)
|
||||
for (arg in srcCall.args)
|
||||
call.add(transformExpression(arg))
|
||||
return call
|
||||
}
|
||||
|
||||
private fun transform(srcCheck: ContainmentCheck): PtContainmentCheck {
|
||||
val check = PtContainmentCheck(srcCheck.position)
|
||||
check.add(transformExpression(srcCheck.element))
|
||||
check.add(transformExpression(srcCheck.iterable))
|
||||
return check
|
||||
}
|
||||
|
||||
private fun transform(memory: DirectMemoryWrite): PtMemoryByte {
|
||||
val mem = PtMemoryByte(memory.position)
|
||||
mem.add(transformExpression(memory.addressExpression))
|
||||
return mem
|
||||
}
|
||||
|
||||
private fun transform(memory: DirectMemoryRead): PtMemoryByte {
|
||||
val mem = PtMemoryByte(memory.position)
|
||||
mem.add(transformExpression(memory.addressExpression))
|
||||
return mem
|
||||
}
|
||||
|
||||
private fun transform(number: NumericLiteral): PtNumber =
|
||||
PtNumber(number.type, number.number, number.position)
|
||||
|
||||
private fun transform(srcPipe: PipeExpression): PtPipe {
|
||||
val pipe = PtPipe(srcPipe.position)
|
||||
pipe.add(transformExpression(srcPipe.source))
|
||||
for (segment in srcPipe.segments)
|
||||
pipe.add(transformExpression(segment))
|
||||
return pipe
|
||||
}
|
||||
|
||||
private fun transform(srcPrefix: PrefixExpression): PtPrefix {
|
||||
val prefix = PtPrefix(srcPrefix.operator, srcPrefix.position)
|
||||
prefix.add(transformExpression(srcPrefix.expression))
|
||||
return prefix
|
||||
}
|
||||
|
||||
private fun transform(srcRange: RangeExpression): PtRange {
|
||||
val range=PtRange(srcRange.position)
|
||||
range.add(transformExpression(srcRange.from))
|
||||
range.add(transformExpression(srcRange.to))
|
||||
range.add(transformExpression(srcRange.step))
|
||||
return range
|
||||
}
|
||||
|
||||
private fun transform(srcString: StringLiteral): PtString =
|
||||
PtString(srcString.value, srcString.encoding, srcString.position)
|
||||
|
||||
private fun transform(srcCast: TypecastExpression): PtTypeCast {
|
||||
val cast = PtTypeCast(srcCast.type, srcCast.position)
|
||||
cast.add(transformExpression(srcCast.expression))
|
||||
return cast
|
||||
}
|
||||
}
|
32
compiler/test/ast/TestIntermediateAst.kt
Normal file
32
compiler/test/ast/TestIntermediateAst.kt
Normal file
@ -0,0 +1,32 @@
|
||||
package prog8tests.ast
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import prog8.codegen.experimental6502.IntermediateAstMaker
|
||||
import prog8.codegen.target.C64Target
|
||||
import prog8tests.helpers.assertSuccess
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
class TestIntermediateAst: FunSpec({
|
||||
|
||||
test("creation") {
|
||||
val text="""
|
||||
%import textio
|
||||
%import graphics
|
||||
main {
|
||||
sub start() {
|
||||
ubyte cc
|
||||
ubyte[] array = [1,2,3]
|
||||
cc = 11 in array
|
||||
cc = cc |> sin8u() |> cos8u()
|
||||
}
|
||||
}
|
||||
"""
|
||||
val result = compileText(C64Target(), false, text, writeAssembly = false).assertSuccess()
|
||||
val ast = IntermediateAstMaker.transform(result.program)
|
||||
ast.name shouldBe result.program.name
|
||||
ast.builtinFunctions.names shouldBe result.program.builtinFunctions.names
|
||||
ast.print()
|
||||
}
|
||||
|
||||
})
|
@ -0,0 +1,110 @@
|
||||
package prog8.compilerinterface.intermediate
|
||||
|
||||
import prog8.ast.IBuiltinFunctions
|
||||
import prog8.ast.base.Position
|
||||
import prog8.compilerinterface.IMemSizer
|
||||
import prog8.compilerinterface.IStringEncoding
|
||||
import prog8.parser.SourceCode
|
||||
|
||||
// TODO : once the CodeGen doesn't need the old Ast anymore, get rid of the 'Pt' prefixes.
|
||||
|
||||
|
||||
abstract class PtNode(val position: Position, val children: MutableList<PtNode> = mutableListOf()) {
|
||||
|
||||
lateinit var parent: PtNode
|
||||
|
||||
protected fun printIndented(indent: Int) {
|
||||
print(" ".repeat(indent))
|
||||
print("${this.javaClass.simpleName} ")
|
||||
printProperties()
|
||||
println()
|
||||
children.forEach { it.printIndented(indent+1) }
|
||||
}
|
||||
|
||||
abstract fun printProperties()
|
||||
|
||||
fun add(child: PtNode) {
|
||||
children.add(child)
|
||||
child.parent = this
|
||||
}
|
||||
|
||||
fun add(index: Int, child: PtNode) {
|
||||
children.add(index, child)
|
||||
child.parent = this
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtNodeGroup(): PtNode(Position.DUMMY) {
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtProgram(
|
||||
val name: String,
|
||||
val builtinFunctions: IBuiltinFunctions,
|
||||
val memsizer: IMemSizer,
|
||||
val encoding: IStringEncoding
|
||||
) : PtNode(Position.DUMMY) {
|
||||
fun print() = printIndented(0)
|
||||
override fun printProperties() {
|
||||
print("'$name'")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtModule(
|
||||
val name: String,
|
||||
val source: SourceCode,
|
||||
val loadAddress: UInt,
|
||||
val library: Boolean,
|
||||
position: Position
|
||||
) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$name addr=$loadAddress library=$library")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtBlock(val name: String,
|
||||
val address: UInt?,
|
||||
val library: Boolean,
|
||||
position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$name addr=$address library=$library")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtDirective(val name: String, position: Position) : PtNode(position) {
|
||||
val args: List<PtDirectiveArg>
|
||||
get() = children.map { it as PtDirectiveArg }
|
||||
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtDirectiveArg(val str: String?,
|
||||
val name: String?,
|
||||
val int: UInt?,
|
||||
position: Position
|
||||
): PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("str=$str name=$name int=$int")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtInlineAssembly(val assembly: String, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtLabel(val name: String, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,108 @@
|
||||
package prog8.compilerinterface.intermediate
|
||||
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.Position
|
||||
import prog8.compilerinterface.Encoding
|
||||
|
||||
|
||||
class PtAddressOf(position: Position) : PtNode(position) {
|
||||
val addr: PtNode
|
||||
get() = children.single()
|
||||
|
||||
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) {
|
||||
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]
|
||||
|
||||
override fun printProperties() {
|
||||
print(operator)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtContainmentCheck(position: Position): PtNode(position) {
|
||||
val element: PtNode
|
||||
get() = children[0]
|
||||
val iterable: PtNode
|
||||
get() = children[0]
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtIdentifier(val name: List<String>, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtMemoryByte(position: Position) : PtNode(position) {
|
||||
val address: PtNode
|
||||
get() = children.single()
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtNumber(val type: DataType, val number: Double, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$number ($type)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtPrefix(val operator: String, position: Position): PtNode(position) {
|
||||
val value: PtNode
|
||||
get() = children.single()
|
||||
|
||||
override fun printProperties() {
|
||||
print(operator)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtRange(position: Position) : PtNode(position) {
|
||||
val from: PtNode
|
||||
get() = children[0]
|
||||
val to: PtNode
|
||||
get() = children[1]
|
||||
val step: PtNode
|
||||
get() = children[2]
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtString(val value: String, val encoding: Encoding, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$encoding:\"$value\"")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtTypeCast(val type: DataType, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(type)
|
||||
}
|
||||
}
|
@ -0,0 +1,213 @@
|
||||
package prog8.compilerinterface.intermediate
|
||||
|
||||
import prog8.ast.base.BranchCondition
|
||||
import prog8.ast.base.CpuRegister
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.statements.AssignmentOrigin
|
||||
import prog8.ast.statements.RegisterOrStatusflag
|
||||
import prog8.ast.statements.SubroutineParameter
|
||||
import prog8.ast.toHex
|
||||
|
||||
|
||||
class PtAsmSub(
|
||||
val name: String,
|
||||
val address: UInt?,
|
||||
val clobbers: Set<CpuRegister>,
|
||||
val paramRegisters: List<RegisterOrStatusflag>,
|
||||
val retvalRegisters: List<RegisterOrStatusflag>,
|
||||
val inline: Boolean,
|
||||
position: Position
|
||||
) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$name inline=$inline")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtSub(
|
||||
val name: String,
|
||||
val parameters: List<SubroutineParameter>,
|
||||
val returntypes: List<DataType>,
|
||||
val inline: Boolean,
|
||||
position: Position
|
||||
) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print(name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtAssignment(val augmentable: Boolean, val origin: AssignmentOrigin, position: Position) : PtNode(position) {
|
||||
val target: PtAssignTarget
|
||||
get() = children[0] as PtAssignTarget
|
||||
val value: PtNode
|
||||
get() = children[1]
|
||||
|
||||
override fun printProperties() {
|
||||
print("aug=$augmentable origin=$origin")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtAssignTarget(position: Position) : PtNode(position) {
|
||||
val identifier: PtIdentifier?
|
||||
get() = children.single() as? PtIdentifier
|
||||
val array: PtArrayIndexer?
|
||||
get() = children.single() as? PtArrayIndexer
|
||||
val memory: PtMemoryByte?
|
||||
get() = children.single() as? PtMemoryByte
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
val falseScope: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {
|
||||
print(condition)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtForLoop(position: Position) : PtNode(position) {
|
||||
val variable: PtIdentifier
|
||||
get() = children[0] as PtIdentifier
|
||||
val iterable: PtNode
|
||||
get() = children[1]
|
||||
val statements: PtNodeGroup
|
||||
get() = children[2] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
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?,
|
||||
position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
identifier?.printProperties()
|
||||
if(address!=null) print(address.toHex())
|
||||
if(generatedLabel!=null) print(generatedLabel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtIfElse(position: Position) : PtNode(position) {
|
||||
val condition: PtNode
|
||||
get() = children[0]
|
||||
val ifScope: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
val elseScope: PtNodeGroup
|
||||
get() = children[2] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtJump(val identifier: PtIdentifier?,
|
||||
val address: UInt?,
|
||||
val generatedLabel: String?,
|
||||
position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
identifier?.printProperties()
|
||||
if(address!=null) print(address.toHex())
|
||||
if(generatedLabel!=null) print(generatedLabel)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
override fun printProperties() {
|
||||
print(operator)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtRepeatLoop(val forever: Boolean, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("forever=$forever")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtReturn(position: Position) : PtNode(position) {
|
||||
val hasValue = children.any()
|
||||
val value: PtNode?
|
||||
get() {
|
||||
return if(children.any())
|
||||
children.single()
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtVariable(val name: String, val type: DataType, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$type $name")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtConstant(val name: String, val type: DataType, val value: Double, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("$type $name = $value")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtMemMapped(val name: String, val type: DataType, val address: UInt, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {
|
||||
print("&$type $name = ${address.toHex()}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PtWhen(position: Position) : PtNode(position) {
|
||||
val value: PtNode
|
||||
get() = children[0]
|
||||
val choices: PtNodeGroup
|
||||
get() = children[1] as PtNodeGroup
|
||||
|
||||
override fun printProperties() {}
|
||||
}
|
||||
|
||||
|
||||
class PtWhenChoice(val isElse: Boolean, position: Position) : PtNode(position) {
|
||||
override fun printProperties() {}
|
||||
}
|
@ -12,6 +12,9 @@ main {
|
||||
sub start() {
|
||||
sys.memset(sieve, 256, false) ; clear the sieve, to reset starting situation on subsequent runs
|
||||
|
||||
ubyte qq = candidate_prime |> sin8u() |> cos8u()
|
||||
candidate_prime |> sin8u() |> txt.print_ub()
|
||||
|
||||
; calculate primes
|
||||
txt.print("prime numbers up to 255:\n\n")
|
||||
ubyte amount=0
|
||||
|
Loading…
Reference in New Issue
Block a user