no more Gosub node in new Ast, back to Functioncalls there.

This commit is contained in:
Irmen de Jong
2022-03-22 22:48:07 +01:00
parent 7b27d270a2
commit dbc7ad2ec4
7 changed files with 93 additions and 72 deletions
@@ -1,43 +0,0 @@
package prog8.codegen.virtual
import prog8.code.ast.PtBuiltinFunctionCall
import prog8.code.ast.PtNumber
import prog8.vm.Instruction
import prog8.vm.Opcode
internal class BuiltinFunctionsGen(val codegen: CodeGen) {
fun translate(call: PtBuiltinFunctionCall): VmCodeChunk {
val chunk = VmCodeChunk()
when(call.name) {
"syscall" -> {
val vExpr = call.args.single() as PtNumber
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall1" -> {
val vExpr = call.args[0] as PtNumber
val vExpr1 = call.args[1] as PtNumber
// TODO assign regs
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall2" -> {
val vExpr = call.args[0] as PtNumber
val vExpr1 = call.args[1] as PtNumber
val vExpr2 = call.args[2] as PtNumber
// TODO assign regs
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall3" -> {
val vExpr = call.args[0] as PtNumber
val vExpr1 = call.args[1] as PtNumber
val vExpr2 = call.args[2] as PtNumber
val vExpr3 = call.args[3] as PtNumber
// TODO assign regs
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
else -> {
TODO("builtinfunc ${call.name}")
}
}
return chunk
}
}
@@ -15,8 +15,7 @@ class CodeGen(internal val program: PtProgram,
): IAssemblyGenerator {
internal val allocations = VariableAllocator(symbolTable, program, errors)
private val builtinFunctions = BuiltinFunctionsGen(this)
private val expressionEval = ExpressionGen(this, builtinFunctions)
private val expressionEval = ExpressionGen(this)
private val instructions = mutableListOf<String>()
init {
@@ -93,7 +92,7 @@ class CodeGen(internal val program: PtProgram,
is PtArrayIndexer -> TODO()
is PtArrayLiteral -> TODO()
is PtBinaryExpression -> TODO()
is PtBuiltinFunctionCall -> builtinFunctions.translate(node)
is PtBuiltinFunctionCall -> expressionEval.translate(node)
is PtContainmentCheck -> TODO()
is PtFunctionCall -> translate(node)
is PtIdentifier -> TODO()
@@ -105,7 +104,6 @@ class CodeGen(internal val program: PtProgram,
is PtString -> TODO()
is PtTypeCast -> TODO()
is PtForLoop -> TODO()
is PtGosub -> translate(node)
is PtIfElse -> TODO()
is PtJump -> TODO()
is PtNodeGroup -> TODO()
@@ -128,17 +126,17 @@ class CodeGen(internal val program: PtProgram,
private fun translate(fcall: PtFunctionCall): VmCodeChunk {
val chunk = VmCodeChunk()
// TODO evaluate function call arguments
for ((index, arg) in fcall.args.withIndex()) {
// TODO make sure the expressions code doesn't clobber the previous registers, and doesn't use the r0, r1, r2... which are needed to pass the args
val (expressionChunk, resultRegister) = expressionEval.translateExpression(arg)
chunk += expressionChunk
if(resultRegister!=index)
chunk += VmCodeInstruction(Instruction(Opcode.LOADR, vmType(arg.type), reg1=0, reg2=resultRegister))
}
chunk += VmCodeOpcodeWithStringArg(Opcode.GOSUB, gosubArg(fcall.functionName))
return chunk
}
private fun translate(gosub: PtGosub): VmCodeChunk {
val chunk = VmCodeChunk()
chunk += VmCodeOpcodeWithStringArg(Opcode.GOSUB, gosubArg(gosub.identifier.targetName))
return chunk
}
private fun translate(ret: PtReturn): VmCodeChunk {
val chunk = VmCodeChunk()
val value = ret.value
@@ -5,7 +5,7 @@ import prog8.code.core.AssemblyError
import prog8.vm.Instruction
import prog8.vm.Opcode
internal class ExpressionGen(val codeGen: CodeGen, val builtinFunctions: BuiltinFunctionsGen) {
internal class ExpressionGen(val codeGen: CodeGen) {
fun translateExpression(expr: PtExpression): Pair<VmCodeChunk, Int> {
// TODO("Not yet implemented")
val chunk = VmCodeChunk()
@@ -80,4 +80,50 @@ internal class ExpressionGen(val codeGen: CodeGen, val builtinFunctions: Builtin
return Pair(chunk, 0) // TODO function result always in r0?
}
fun translate(call: PtBuiltinFunctionCall): VmCodeChunk {
val chunk = VmCodeChunk()
when(call.name) {
"syscall" -> {
val vExpr = call.args.single() as PtNumber
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall1" -> {
val vExpr = call.args[0] as PtNumber
// TODO make sure it evaluates into r0
val (expressionChunk0, resultRegister0) = translateExpression(call.args[1])
chunk += expressionChunk0
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall2" -> {
val vExpr = call.args[0] as PtNumber
// TODO make sure it evaluates into r0
val (expressionChunk0, resultRegister0) = translateExpression(call.args[1])
chunk += expressionChunk0
// TODO make sure it evaluates into r1
val (expressionChunk1, resultRegister1) = translateExpression(call.args[2])
chunk += expressionChunk1
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
"syscall3" -> {
val vExpr = call.args[0] as PtNumber
// TODO make sure it evaluates into r0
val (expressionChunk0, resultRegister0) = translateExpression(call.args[1])
chunk += expressionChunk0
// TODO make sure it evaluates into r1
val (expressionChunk1, resultRegister1) = translateExpression(call.args[2])
chunk += expressionChunk1
// TODO make sure it evaluates into r2
val (expressionChunk2, resultRegister2) = translateExpression(call.args[3])
chunk += expressionChunk2
chunk += VmCodeInstruction(Instruction(Opcode.SYSCALL, value=vExpr.number.toInt()))
}
else -> {
TODO("builtinfunc ${call.name}")
}
}
return chunk
}
}