diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 6f938ef72..a83af52cc 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -3127,6 +3127,14 @@ $endLabel""") RegisterOrPair.XY -> asmgen.out(" stx $targetAsmVarName | sty $targetAsmVarName+1") else -> throw AssemblyError("non-word regs") } + } else if(targetDt.isLong) { + when(regs) { + RegisterOrPair.AX -> asmgen.out(" sta $targetAsmVarName | stx $targetAsmVarName+1") + RegisterOrPair.AY -> asmgen.out(" sta $targetAsmVarName | sty $targetAsmVarName+1") + RegisterOrPair.XY -> asmgen.out(" stx $targetAsmVarName | sty $targetAsmVarName+1") + else -> throw AssemblyError("non-word regs") + } + asmgen.out(" lda #0 | sta $targetAsmVarName+2 | sta $targetAsmVarName+3") } else { throw AssemblyError("cannot assign pointer to $targetDt") } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index d2158ba9f..5c4c45657 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -815,7 +815,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = wordreg, reg2=tr.resultReg), null) addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.WORD, reg1 = actualResultReg2, reg2=wordreg), null) } - BaseDataType.UWORD -> { + BaseDataType.UWORD, BaseDataType.POINTER -> { actualResultReg2 = codeGen.registers.next(IRDataType.LONG) addInstr(result, IRInstruction(Opcode.EXT, type = IRDataType.WORD, reg1 = actualResultReg2, reg2=tr.resultReg), null) } @@ -823,7 +823,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { actualResultReg2 = codeGen.registers.next(IRDataType.LONG) addInstr(result, IRInstruction(Opcode.EXTS, type = IRDataType.WORD, reg1 = actualResultReg2, reg2=tr.resultReg), null) } - else -> throw AssemblyError("weird cast value type ${cast.position}") + else -> throw AssemblyError("weird cast $valueDt to long ${cast.position}") } } BaseDataType.FLOAT -> { diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index e66de8444..328fd2dc8 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -1639,6 +1639,10 @@ internal class AstChecker(private val program: Program, errors.err("invalid type cast", typecast.position) } + if(typecast.implicit && typecast.type.isLong && typecast.expression.inferType(program).isPointer) { + errors.err("cannot use a pointer as a long, a pointer is an unsigned word", typecast.position) + } + super.visit(typecast) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 249bacf40..0d9b15218 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -8,8 +8,6 @@ TODO - (not needed anymore if everything is saved on the stack?:) can the compiler give a warning if you use R0/R1 (or whatever the temp storage is) in expressions and/or statements together with long integers? (because R0/R1 are likely to be clobbered as temporary storage) -- fix crash for txt.print_l(conv.str_l(0)) - STRUCTS and TYPED POINTERS -------------------------- diff --git a/examples/test.p8 b/examples/test.p8 index e0dd6751e..2ea660193 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -35,14 +35,8 @@ main { txt.nl() -; txt.print_l(conv.str_l(0)) ; TODO fix crash -; txt.print_l(conv.str_l(987654)) ; TODO fix crash -; txt.print_l(conv.str_l(-12345)) ; TODO fix crash - - lv1 = 999999 lv2 = 555555 lv3 = 222222 - txt.print_bool(lv1 >= lv2+4*lv3) txt.nl()