mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
working on vm
This commit is contained in:
parent
30cbb6c9a8
commit
bb1bf6a88c
@ -119,7 +119,7 @@ open class StNode(val name: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun printIndented(indent: Int) {
|
fun printIndented(indent: Int) {
|
||||||
print(" ".repeat(indent))
|
print(" ".repeat(indent))
|
||||||
when(type) {
|
when(type) {
|
||||||
StNodeType.GLOBAL -> print("SYMBOL-TABLE:")
|
StNodeType.GLOBAL -> print("SYMBOL-TABLE:")
|
||||||
@ -152,21 +152,24 @@ class StStaticVariable(name: String,
|
|||||||
val initialNumericValue: Double?,
|
val initialNumericValue: Double?,
|
||||||
val initialStringValue: StString?,
|
val initialStringValue: StString?,
|
||||||
val initialArrayValue: StArray?,
|
val initialArrayValue: StArray?,
|
||||||
val arraysize: Int?,
|
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
|
||||||
val zpwish: ZeropageWish,
|
val zpwish: ZeropageWish,
|
||||||
position: Position) : StNode(name, StNodeType.STATICVAR, position) {
|
position: Position) : StNode(name, StNodeType.STATICVAR, position) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if(arraysize!=null && initialArrayValue!=null)
|
if(length!=null) {
|
||||||
require(arraysize == initialArrayValue.size)
|
require(initialNumericValue == null)
|
||||||
if(arraysize!=null || initialArrayValue!=null)
|
if(initialArrayValue!=null)
|
||||||
require(initialStringValue==null && initialNumericValue==null)
|
require(length == initialArrayValue.size)
|
||||||
|
}
|
||||||
if(initialNumericValue!=null)
|
if(initialNumericValue!=null)
|
||||||
require(dt in NumericDatatypes)
|
require(dt in NumericDatatypes)
|
||||||
if(initialArrayValue!=null || arraysize!=null)
|
if(initialArrayValue!=null)
|
||||||
require(dt in ArrayDatatypes)
|
require(dt in ArrayDatatypes)
|
||||||
if(initialStringValue!=null)
|
if(initialStringValue!=null) {
|
||||||
require(dt == DataType.STR)
|
require(dt == DataType.STR)
|
||||||
|
require(length == initialStringValue.first.length+1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun printProperties() {
|
override fun printProperties() {
|
||||||
|
@ -11,7 +11,7 @@ sealed class PtNode(val position: Position) {
|
|||||||
val children = mutableListOf<PtNode>()
|
val children = mutableListOf<PtNode>()
|
||||||
lateinit var parent: PtNode
|
lateinit var parent: PtNode
|
||||||
|
|
||||||
protected fun printIndented(indent: Int) {
|
fun printIndented(indent: Int) {
|
||||||
print(" ".repeat(indent))
|
print(" ".repeat(indent))
|
||||||
print("${this.javaClass.simpleName} ")
|
print("${this.javaClass.simpleName} ")
|
||||||
printProperties()
|
printProperties()
|
||||||
|
@ -480,7 +480,7 @@ internal class ProgramAndVarsGen(
|
|||||||
DataType.STR -> {
|
DataType.STR -> {
|
||||||
throw AssemblyError("all string vars should have been interned into prog")
|
throw AssemblyError("all string vars should have been interned into prog")
|
||||||
}
|
}
|
||||||
in ArrayDatatypes -> arrayVariable2asm(name, variable.dt, variable.initialArrayValue, variable.arraysize)
|
in ArrayDatatypes -> arrayVariable2asm(name, variable.dt, variable.initialArrayValue, variable.length)
|
||||||
else -> {
|
else -> {
|
||||||
throw AssemblyError("weird dt")
|
throw AssemblyError("weird dt")
|
||||||
}
|
}
|
||||||
|
@ -63,11 +63,10 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
var numberOfNonIntegerVariables = 0
|
var numberOfNonIntegerVariables = 0
|
||||||
|
|
||||||
varsRequiringZp.forEach { variable ->
|
varsRequiringZp.forEach { variable ->
|
||||||
val numElements = numArrayElements(variable)
|
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName,
|
||||||
variable.dt,
|
variable.dt,
|
||||||
numElements,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -83,11 +82,10 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
|
|
||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
varsPreferringZp.forEach { variable ->
|
varsPreferringZp.forEach { variable ->
|
||||||
val numElements = numArrayElements(variable)
|
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName,
|
||||||
variable.dt,
|
variable.dt,
|
||||||
numElements,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -103,11 +101,10 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
if(zeropage.free.isEmpty()) {
|
if(zeropage.free.isEmpty()) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
val numElements = numArrayElements(variable)
|
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName,
|
||||||
variable.dt,
|
variable.dt,
|
||||||
numElements,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
errors
|
errors
|
||||||
)
|
)
|
||||||
@ -137,11 +134,4 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
collect(st)
|
collect(st)
|
||||||
return vars
|
return vars
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun numArrayElements(variable: StStaticVariable) =
|
|
||||||
when(variable.dt) {
|
|
||||||
DataType.STR -> variable.initialStringValue!!.first.length+1 // 1 extra because of 0 termination char
|
|
||||||
in ArrayDatatypes -> variable.arraysize!!
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ class AstToXmlConverter(internal val program: PtProgram,
|
|||||||
xml.elt("var")
|
xml.elt("var")
|
||||||
xml.attr("type", node.dt.name)
|
xml.attr("type", node.dt.name)
|
||||||
xml.attr("zpwish", node.zpwish.name)
|
xml.attr("zpwish", node.zpwish.name)
|
||||||
if(node.arraysize!=null)
|
if(node.length!=null)
|
||||||
xml.attr("arraysize", node.arraysize.toString())
|
xml.attr("length", node.length.toString())
|
||||||
if(node.initialNumericValue!=null || node.initialArrayValue!=null || node.initialStringValue!=null) {
|
if(node.initialNumericValue!=null || node.initialArrayValue!=null || node.initialStringValue!=null) {
|
||||||
xml.startChildren()
|
xml.startChildren()
|
||||||
if(node.initialNumericValue!=null) {
|
if(node.initialNumericValue!=null) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package prog8.codegen.virtual
|
package prog8.codegen.virtual
|
||||||
|
|
||||||
|
import prog8.code.StStaticVariable
|
||||||
import prog8.code.SymbolTable
|
import prog8.code.SymbolTable
|
||||||
import prog8.code.ast.*
|
import prog8.code.ast.*
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
@ -58,7 +59,7 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
is PtJump -> translate(node)
|
is PtJump -> translate(node)
|
||||||
is PtWhen -> TODO("when")
|
is PtWhen -> TODO("when")
|
||||||
is PtPipe -> expressionEval.translate(node, regUsage.nextFree(), regUsage)
|
is PtPipe -> expressionEval.translate(node, regUsage.nextFree(), regUsage)
|
||||||
is PtForLoop -> TODO("for-loop")
|
is PtForLoop -> translate(node, regUsage)
|
||||||
is PtIfElse -> translate(node, regUsage)
|
is PtIfElse -> translate(node, regUsage)
|
||||||
is PtPostIncrDecr -> translate(node, regUsage)
|
is PtPostIncrDecr -> translate(node, regUsage)
|
||||||
is PtRepeatLoop -> translate(node, regUsage)
|
is PtRepeatLoop -> translate(node, regUsage)
|
||||||
@ -90,6 +91,30 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translate(forLoop: PtForLoop, regUsage: RegisterUsage): VmCodeChunk {
|
||||||
|
val loopvar = symbolTable.lookup(forLoop.variable.targetName) as StStaticVariable
|
||||||
|
val iterable = forLoop.iterable
|
||||||
|
val code = VmCodeChunk()
|
||||||
|
when(iterable) {
|
||||||
|
is PtRange -> {
|
||||||
|
println("forloop ${loopvar.dt} ${loopvar.scopedName} in range ${iterable} ")
|
||||||
|
iterable.printIndented(0)
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
is PtIdentifier -> {
|
||||||
|
val address = allocations.get(iterable.targetName)
|
||||||
|
val variable = symbolTable.lookup(iterable.targetName) as StStaticVariable
|
||||||
|
val length = variable.length!!
|
||||||
|
println("forloop ${loopvar.dt} ${loopvar.scopedName} in $iterable @${address.toHex()} ${length}")
|
||||||
|
val indexReg = regUsage.nextFree()
|
||||||
|
val loopvarReg = regUsage.nextFree()
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
else -> throw AssemblyError("weird for iterable")
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
private fun translate(ifElse: PtIfElse, regUsage: RegisterUsage): VmCodeChunk {
|
private fun translate(ifElse: PtIfElse, regUsage: RegisterUsage): VmCodeChunk {
|
||||||
var branch = Opcode.BZ
|
var branch = Opcode.BZ
|
||||||
var condition = ifElse.condition
|
var condition = ifElse.condition
|
||||||
|
@ -83,14 +83,14 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
val call = PtFunctionCall(listOf("prog8_lib", "bytearray_contains"), false, DataType.UBYTE, check.position)
|
val call = PtFunctionCall(listOf("prog8_lib", "bytearray_contains"), false, DataType.UBYTE, check.position)
|
||||||
call.children.add(check.element)
|
call.children.add(check.element)
|
||||||
call.children.add(check.iterable)
|
call.children.add(check.iterable)
|
||||||
call.children.add(PtNumber(DataType.UBYTE, iterable.arraysize!!.toDouble(), iterable.position))
|
call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position))
|
||||||
code += translate(call, resultRegister, regUsage)
|
code += translate(call, resultRegister, regUsage)
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||||
val call = PtFunctionCall(listOf("prog8_lib", "wordarray_contains"), false, DataType.UBYTE, check.position)
|
val call = PtFunctionCall(listOf("prog8_lib", "wordarray_contains"), false, DataType.UBYTE, check.position)
|
||||||
call.children.add(check.element)
|
call.children.add(check.element)
|
||||||
call.children.add(check.iterable)
|
call.children.add(check.iterable)
|
||||||
call.children.add(PtNumber(DataType.UBYTE, iterable.arraysize!!.toDouble(), iterable.position))
|
call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position))
|
||||||
code += translate(call, resultRegister, regUsage)
|
code += translate(call, resultRegister, regUsage)
|
||||||
}
|
}
|
||||||
DataType.ARRAY_F -> TODO("containment check in float-array")
|
DataType.ARRAY_F -> TODO("containment check in float-array")
|
||||||
@ -204,21 +204,17 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
TODO("floating point not yet supported")
|
TODO("floating point not yet supported")
|
||||||
when(cast.value.type) {
|
// when(cast.value.type) {
|
||||||
DataType.BYTE -> {
|
// DataType.BYTE -> {
|
||||||
// TODO("byte -> float")
|
// }
|
||||||
}
|
// DataType.UBYTE -> {
|
||||||
DataType.UBYTE -> {
|
// }
|
||||||
// TODO("ubyte -> float")
|
// DataType.WORD -> {
|
||||||
}
|
// }
|
||||||
DataType.WORD -> {
|
// DataType.UWORD -> {
|
||||||
// TODO("word -> float")
|
// }
|
||||||
}
|
// else -> throw AssemblyError("weird cast value type")
|
||||||
DataType.UWORD -> {
|
// }
|
||||||
// TODO("uword -> float")
|
|
||||||
}
|
|
||||||
else -> throw AssemblyError("weird cast value type")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird cast type")
|
else -> throw AssemblyError("weird cast type")
|
||||||
}
|
}
|
||||||
@ -229,7 +225,8 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
val leftResultReg = regUsage.nextFree()
|
val leftResultReg = regUsage.nextFree()
|
||||||
val rightResultReg = regUsage.nextFree()
|
val rightResultReg = regUsage.nextFree()
|
||||||
// TODO: optimized codegen when left or right operand is known 0 or 1 or whatever.
|
// TODO: optimized codegen when left or right operand is known 0 or 1 or whatever. But only if this would result in a different opcode such as ADD 1 -> INC, MUL 1 -> NOP
|
||||||
|
// actually optimizing the code should not be done here but in a tailored code optimizer step.
|
||||||
val leftCode = translateExpression(binExpr.left, leftResultReg, regUsage)
|
val leftCode = translateExpression(binExpr.left, leftResultReg, regUsage)
|
||||||
val rightCode = translateExpression(binExpr.right, rightResultReg, regUsage)
|
val rightCode = translateExpression(binExpr.right, rightResultReg, regUsage)
|
||||||
code += leftCode
|
code += leftCode
|
||||||
@ -288,7 +285,7 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
val ins = if(binExpr.type in SignedDatatypes) Opcode.SGES else Opcode.SGE
|
val ins = if(binExpr.type in SignedDatatypes) Opcode.SGES else Opcode.SGE
|
||||||
code += VmCodeInstruction(Instruction(ins, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg))
|
code += VmCodeInstruction(Instruction(ins, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg))
|
||||||
}
|
}
|
||||||
else -> TODO("operator ${binExpr.operator}")
|
else -> throw AssemblyError("weird operator ${binExpr.operator}")
|
||||||
}
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
@ -357,9 +354,11 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
"msb" -> {
|
"msb" -> {
|
||||||
code += translateExpression(call.args.single(), resultRegister, regUsage)
|
code += translateExpression(call.args.single(), resultRegister, regUsage)
|
||||||
code += VmCodeInstruction(Instruction(Opcode.SWAP, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister))
|
code += VmCodeInstruction(Instruction(Opcode.SWAP, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister))
|
||||||
|
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||||
}
|
}
|
||||||
"lsb" -> {
|
"lsb" -> {
|
||||||
code += translateExpression(call.args.single(), resultRegister, regUsage)
|
code += translateExpression(call.args.single(), resultRegister, regUsage)
|
||||||
|
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||||
}
|
}
|
||||||
"memory" -> {
|
"memory" -> {
|
||||||
val name = (call.args[0] as PtString).value
|
val name = (call.args[0] as PtString).value
|
||||||
@ -391,12 +390,6 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
|||||||
code += translateExpression(call.args.single(), addressReg, regUsage)
|
code += translateExpression(call.args.single(), addressReg, regUsage)
|
||||||
code += VmCodeInstruction(Instruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2=addressReg))
|
code += VmCodeInstruction(Instruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2=addressReg))
|
||||||
}
|
}
|
||||||
"memory" -> {
|
|
||||||
val memname = (call.args[0] as PtString).value
|
|
||||||
val size = (call.args[1] as PtNumber).number.toInt()
|
|
||||||
val align = (call.args[2] as PtNumber).number.toInt()
|
|
||||||
TODO("memory '$memname', $size, $align")
|
|
||||||
}
|
|
||||||
else -> {
|
else -> {
|
||||||
TODO("builtinfunc ${call.name}")
|
TODO("builtinfunc ${call.name}")
|
||||||
// code += VmCodeInstruction(Instruction(Opcode.NOP))
|
// code += VmCodeInstruction(Instruction(Opcode.NOP))
|
||||||
|
@ -19,7 +19,7 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
|
|||||||
when (variable.dt) {
|
when (variable.dt) {
|
||||||
DataType.STR -> variable.initialStringValue!!.first.length + 1 // include the zero byte
|
DataType.STR -> variable.initialStringValue!!.first.length + 1 // include the zero byte
|
||||||
in NumericDatatypes -> program.memsizer.memorySize(variable.dt)
|
in NumericDatatypes -> program.memsizer.memorySize(variable.dt)
|
||||||
in ArrayDatatypes -> program.memsizer.memorySize(variable.dt, variable.arraysize!!)
|
in ArrayDatatypes -> program.memsizer.memorySize(variable.dt, variable.length!!)
|
||||||
else -> throw InternalCompilerException("weird dt")
|
else -> throw InternalCompilerException("weird dt")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,14 +55,14 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
|
|||||||
if(variable.initialArrayValue!=null) {
|
if(variable.initialArrayValue!=null) {
|
||||||
variable.initialArrayValue!!.joinToString(",") { it.number!!.toString() }
|
variable.initialArrayValue!!.joinToString(",") { it.number!!.toString() }
|
||||||
} else {
|
} else {
|
||||||
(1..variable.arraysize!!).joinToString(",") { "0" }
|
(1..variable.length!!).joinToString(",") { "0" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in ArrayDatatypes -> {
|
in ArrayDatatypes -> {
|
||||||
if(variable.initialArrayValue!==null) {
|
if(variable.initialArrayValue!==null) {
|
||||||
variable.initialArrayValue!!.joinToString(",") { it.number!!.toHex() }
|
variable.initialArrayValue!!.joinToString(",") { it.number!!.toHex() }
|
||||||
} else {
|
} else {
|
||||||
(1..variable.arraysize!!).joinToString(",") { "0" }
|
(1..variable.length!!).joinToString(",") { "0" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw InternalCompilerException("weird dt")
|
else -> throw InternalCompilerException("weird dt")
|
||||||
|
@ -63,7 +63,14 @@ internal class SymbolTableMaker: IAstVisitor {
|
|||||||
val initialArray = makeInitialArray(initialArrayLit)
|
val initialArray = makeInitialArray(initialArrayLit)
|
||||||
if(decl.isArray && decl.datatype !in ArrayDatatypes)
|
if(decl.isArray && decl.datatype !in ArrayDatatypes)
|
||||||
throw FatalAstException("array vardecl has mismatched dt ${decl.datatype}")
|
throw FatalAstException("array vardecl has mismatched dt ${decl.datatype}")
|
||||||
StStaticVariable(decl.name, decl.datatype, initialNumeric, initialString, initialArray, decl.arraysize?.constIndex(), decl.zeropage, decl.position)
|
val numElements =
|
||||||
|
if(decl.isArray)
|
||||||
|
decl.arraysize!!.constIndex()
|
||||||
|
else if(initialStringLit!=null)
|
||||||
|
initialStringLit.value.length+1 // include the terminating 0-byte
|
||||||
|
else
|
||||||
|
null
|
||||||
|
StStaticVariable(decl.name, decl.datatype, initialNumeric, initialString, initialArray, numElements, decl.zeropage, decl.position)
|
||||||
}
|
}
|
||||||
VarDeclType.CONST -> StConstant(decl.name, decl.datatype, (decl.value as NumericLiteral).number, decl.position)
|
VarDeclType.CONST -> StConstant(decl.name, decl.datatype, (decl.value as NumericLiteral).number, decl.position)
|
||||||
VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position)
|
VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position)
|
||||||
|
@ -3,6 +3,21 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
- vm codegen: ForLoop
|
||||||
|
- vm codegen: fix primes endless loop stuck on '2'
|
||||||
|
- x16: screen_set_mode -> screen_mode + other api https://github.com/commanderx16/x16-docs/blob/master/Commander%20X16%20Programmer's%20Reference%20Guide.md#function-name-screen_mode
|
||||||
|
- optimize diskio load_raw on X16 because headerless files are now supported https://github.com/commanderx16/x16-rom/pull/216
|
||||||
|
note: must still work on c64/c128 that don't have this!
|
||||||
|
- major version bump once X16 r39 rom is officially finalized
|
||||||
|
- vm codegen: When
|
||||||
|
- vm codegen: Pipe expression
|
||||||
|
- vm codegen: validate that PtFunctionCall translation works okay with resultregister
|
||||||
|
- vm: support no globals re-init option
|
||||||
|
- vm codegen/assembler: variable memory locations should also be referenced by the variable name instead of just the address
|
||||||
|
- when the vm is stable and *if* its language can get promoted to prog8 IL, the variable allocation should be changed.
|
||||||
|
It's now done before the vm code generation, but the IL should probably not depend on the allocations already performed.
|
||||||
|
So the CodeGen doesn't do VariableAlloc *before* the codegen, but as a last step.
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@ -62,10 +77,8 @@ Expressions:
|
|||||||
|
|
||||||
Optimizations:
|
Optimizations:
|
||||||
|
|
||||||
- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once (if?) 6502-codegen is no longer done from
|
- various optimizers should/do skip stuff if compTarget.name==VMTarget.NAME. Once (if?) 6502-codegen is no longer done from
|
||||||
the old CompilerAst, those checks should probably be removed.
|
the old CompilerAst, those checks should probably be removed.
|
||||||
(most of them avoid the case where extra temporary variables are introduced in an attempt to simplify
|
|
||||||
the expression code generation)
|
|
||||||
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served
|
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served
|
||||||
- translateUnaryFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable
|
- translateUnaryFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable
|
||||||
compare ``aa = startvalue(1) |> sin8u() |> cos8u() |> sin8u() |> cos8u()``
|
compare ``aa = startvalue(1) |> sin8u() |> cos8u() |> sin8u() |> cos8u()``
|
||||||
|
@ -7,32 +7,40 @@ main {
|
|||||||
txt.clear_screen()
|
txt.clear_screen()
|
||||||
txt.print("Welcome to a prog8 pixel shader :-)\n")
|
txt.print("Welcome to a prog8 pixel shader :-)\n")
|
||||||
|
|
||||||
uword @shared chunk = memory("irmen", 4000, 256)
|
uword ww = 0
|
||||||
txt.print_uwhex(chunk,true)
|
ubyte bc
|
||||||
|
uword wc
|
||||||
|
|
||||||
|
for bc in "irmen" {
|
||||||
|
; +5 -> 17
|
||||||
|
txt.chrout(bc)
|
||||||
|
ww++
|
||||||
|
}
|
||||||
|
txt.print_uw(ww)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
ubyte bb = 4
|
for wc in [1000,1111,1222] {
|
||||||
ubyte[] array = [1,2,3,4,5,6]
|
txt.print_uw(wc)
|
||||||
uword[] warray = [1111,2222,3333]
|
txt.spc()
|
||||||
str tekst = "test"
|
ww++ ; +3 -> 20
|
||||||
uword ww = 19
|
}
|
||||||
bb = bb in "teststring"
|
txt.print_uw(ww)
|
||||||
bb++
|
|
||||||
bb = bb in [1,2,3,4,5,6]
|
|
||||||
bb++
|
|
||||||
bb = bb in array
|
|
||||||
bb++
|
|
||||||
bb = bb in tekst
|
|
||||||
bb++
|
|
||||||
bb = ww in warray
|
|
||||||
bb++
|
|
||||||
bb = 666 in warray
|
|
||||||
bb ++
|
|
||||||
bb = '?' in tekst
|
|
||||||
bb++
|
|
||||||
txt.print("bb=")
|
|
||||||
txt.print_ub(bb)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
|
for bc in 10 to 20 step 3 {
|
||||||
|
; 10,13,16,19 -> 4
|
||||||
|
ww++
|
||||||
|
}
|
||||||
|
txt.print_uw(ww)
|
||||||
|
txt.nl()
|
||||||
|
for bc in 30 to 10 step -4 {
|
||||||
|
; 30,26,22,18,14,10,6,2 -> +8 -> 12
|
||||||
|
ww++
|
||||||
|
}
|
||||||
|
txt.print_uw(ww)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
|
||||||
sys.exit(99)
|
sys.exit(99)
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,6 +220,7 @@ data class Instruction(
|
|||||||
val reg2: Int?=null, // 0-$ffff
|
val reg2: Int?=null, // 0-$ffff
|
||||||
val reg3: Int?=null, // 0-$ffff
|
val reg3: Int?=null, // 0-$ffff
|
||||||
val value: Int?=null, // 0-$ffff
|
val value: Int?=null, // 0-$ffff
|
||||||
|
// TODO add string symbol here as alternative to value
|
||||||
) {
|
) {
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val result = mutableListOf(opcode.name.lowercase())
|
val result = mutableListOf(opcode.name.lowercase())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user