mirror of
https://github.com/irmen/prog8.git
synced 2026-04-19 20:16:51 +00:00
no more Gosub node in new Ast, back to Functioncalls there.
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user