vm: fixed non-byte array indexing

This commit is contained in:
Irmen de Jong 2022-05-17 18:53:18 +02:00
parent 52f9956e92
commit dc6475c91b
4 changed files with 45 additions and 57 deletions

View File

@ -701,7 +701,7 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, value=variableAddr)
} else {
val indexReg = vmRegisters.nextFree()
code += expressionEval.translateExpression(array.index, indexReg, -1)
code += loadIndexReg(array, itemsize, indexReg)
code += VmCodeInstruction(Opcode.STOREZX, VmDataType.FLOAT, reg1=indexReg, value=variableAddr)
}
} else {
@ -711,7 +711,7 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, value=variableAddr)
} else {
val indexReg = vmRegisters.nextFree()
code += expressionEval.translateExpression(array.index, indexReg, -1)
code += loadIndexReg(array, itemsize, indexReg)
code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, value=variableAddr)
}
} else {
@ -720,7 +720,7 @@ class CodeGen(internal val program: PtProgram,
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, value=variableAddr)
} else {
val indexReg = vmRegisters.nextFree()
code += expressionEval.translateExpression(array.index, indexReg, -1)
code += loadIndexReg(array, itemsize, indexReg)
code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, value=variableAddr)
}
}
@ -751,6 +751,20 @@ class CodeGen(internal val program: PtProgram,
return code
}
private fun loadIndexReg(array: PtArrayIndexer, itemsize: Int, indexReg: Int): VmCodeChunk {
val code = VmCodeChunk()
if(itemsize==1) {
code += expressionEval.translateExpression(array.index, indexReg, -1)
}
else {
val mult = PtBinaryExpression("*", DataType.UBYTE, array.position)
mult.children += array.index
mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position)
code += expressionEval.translateExpression(mult, indexReg, -1)
}
return code
}
private fun translate(ret: PtReturn): VmCodeChunk {
val code = VmCodeChunk()
val value = ret.value

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: animals example game breaks after adding first new animal...
- vm: add more instructions operating directly on memory instead of only registers? (translate assignment self-assigns)
- complete the Inliner
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?

View File

@ -4,19 +4,19 @@
; Animal guessing game where the computer gets smarter every time.
; Note: this program is compatible with C64 and CX16.
main {
const ubyte database_size = 100
uword animal_names_buf = memory("animalnames", 500, 0)
uword questions_buf = memory("questions", 2000, 0)
uword animal_names_buf = memory("animalnames", 500, 0) ; area to store all animal names in, in sequence
uword questions_buf = memory("questions", 2000, 0) ; area to store all question texts in, in sequence
uword animal_names_ptr
uword questions_ptr
uword[database_size] animals
uword[database_size] questions
uword[database_size] answers_questions
uword[database_size] answers_animals
uword[database_size] animals ; pointers to the animal names
uword[database_size] questions ; pointers to the question texts
uword[database_size] answers_questions ; tree entries for question choices, indexed by question id, pair of (msb=yes, lsb=no) follow up question id (or 0 if it's an animal leaf node)
uword[database_size] answers_animals ; tree entries for animal leafs, indexed by question id, pair of (msb=yes, lsb=no) animal id
ubyte new_animal_number
ubyte new_question_number
str userinput = "x"*80
@ -137,6 +137,5 @@ main {
new_question_number++
txt.print("\n\nthanks, i know more animals now! let's try again.\n")
}
}

View File

@ -22,57 +22,33 @@ main {
return first * second
}
ubyte ix
sub start() {
ubyte @shared value = inline_candidate()
uword[] array = [1111,2222,3333,4444]
str name = "irmen123ABC"
str other = "zrmen123zzz"
sub pa() {
uword ww
for ww in array {
txt.print_uw(ww)
txt.spc()
}
txt.nl()
}
txt.print(name)
txt.nl()
uword otherptr = &other + 2
name = otherptr
txt.print(name)
txt.nl()
txt.nl()
txt.print_ub(string.upper(name))
txt.print(name)
txt.nl()
txt.print_ub(string.lower(name))
txt.print(name)
txt.nl()
uword otheraddr = &other
txt.print_ub(name!=other)
txt.spc()
txt.print_ub(name==other)
txt.nl()
txt.print_ub(name>other)
txt.spc()
txt.print_ub(name>=other)
txt.nl()
txt.print_ub(name<other)
txt.spc()
txt.print_ub(name<=other)
txt.nl()
txt.nl()
other[0]='i'
txt.print_ub(name!=other)
txt.spc()
txt.print_ub(name==other)
txt.nl()
txt.print_ub(name>other)
txt.spc()
txt.print_ub(name>=other)
txt.nl()
txt.print_ub(name<other)
txt.spc()
txt.print_ub(name<=other)
; pa()
; array[2] = 9999
; pa()
ix=2
array[ix]= 8888 ; TODO fix indexing offset in vm
pa()
txt.print_uw(array[ix])
txt.spc()
txt.print_uw(array[ix+1])
txt.nl()
; ubyte @shared value = inline_candidate()
; txt.print_ub(inline_candidate())
; txt.nl()