News: calling class methods on class instance now works. As mentioned earlier - all class methods have intrinsic "this" argument handled by compiler that holds pointer to dereferenced instance. Here's an example with dummy allocMem function that would obviously always alloc the same memory location (30000) for all objects
Of course that's only start of the solution, as class methods should be called via jump table depending on real instance being derferenced. Currently bottom field of instance heap contains class id reserved for runtime class discrimination.
EDIT: fixed 6502 asm source.
Code:
package pl.qus.wolin
var border: ubyte^53280
var ekran: ubyte[]^1024
var i: uword = 0
var znak: ubyte = 0
fun allocMem(size: uword, count: uword): Any {
return 30000
}
class Test {
var x: ubyte = 3
var y: ubyte = 7
fun suma(): ubyte {
return x+y
}
}
fun main() {
val testowa : Test
testowa = Test()
border = testowa.suma()
}
pseudoasm:
Code:
setup HEADER
setup SPF = 251[ubyte], 40959[uword] // call stack pointer at 251 = 40959
setup SP = 143[ubyte] // register stack top = 142
setup HEAP = 176[ubyte]
// main function entry
goto __wolin_pl_qus_wolin_main[adr]
// ****************************************
// funkcja: fun pl.qus.wolin.allocMem(pl.qus.wolin.allocMem.size: uword = 0 (), pl.qus.wolin.allocMem.count: uword = 0 ()):Any
// ****************************************
label __wolin_pl_qus_wolin_allocMem
alloc SP<__wolin_reg1>, #2 // for expression
let SP(0)<__wolin_reg1>[ptr] = #30000[uword] // atomic ex
let SPF(4)<returnValue>[ptr] = SP(0)<__wolin_reg1>[ptr] // przez sprawdzacz typow - jump expression
free SP<__wolin_reg1>, #2 // for expression
free SPF, #4 // free fn arguments and locals for pl.qus.wolin.allocMem
ret
// ****************************************
// konstruktor: fun pl.qus.wolin.Test():pl.qus.wolin.Test
// ****************************************
label __wolin_pl_qus_wolin_Test
alloc SP<__wolin_reg2>, #2 // for returning this
alloc SPF, #6
let SPF(2)[uword] = #3[uword]
let SPF(0)[uword] = #1[uword]
call __wolin_pl_qus_wolin_allocMem[adr]
let SP(0)<__wolin_reg2>[ptr] = SPF(0)<returnValue>[ptr]
free SPF <Any>, #2 // free return value of pl.qus.wolin.allocMem from call stack
let SPF(0)<pl.qus.wolin.Test.returnValue>[ptr] = SP(0)<__wolin_reg2>[ptr] // przez sprawdzacz typow - zwrotka alloc do zwrotki konstruktora
setup HEAP = SP(0)<__wolin_reg2>[ptr]
free SP<__wolin_reg2>, #2 // for returning this
alloc SP<__wolin_reg3>, #1 // for var init expression
let SP(0)<__wolin_reg3>[ubyte] = #3[ubyte] // atomic ex
let HEAP(2)<pl.qus.wolin.Test.x>[ubyte] = SP(0)<__wolin_reg3>[ubyte] // podstawic wynik inicjalizacji expression do zmiennej pl.qus.wolin.Test.x
free SP<__wolin_reg3>, #1 // for var init expression
alloc SP<__wolin_reg4>, #1 // for var init expression
let SP(0)<__wolin_reg4>[ubyte] = #7[ubyte] // atomic ex
let HEAP(1)<pl.qus.wolin.Test.y>[ubyte] = SP(0)<__wolin_reg4>[ubyte] // podstawic wynik inicjalizacji expression do zmiennej pl.qus.wolin.Test.y
free SP<__wolin_reg4>, #1 // for var init expression
ret
// ****************************************
// funkcja: fun pl.qus.wolin.Test.suma(pl.qus.wolin.Test.suma.this: pl.qus.wolin.Test = 65535 ()):ubyte
// ****************************************
label __wolin_pl_qus_wolin_Test_suma
setup HEAP = this
alloc SP<__wolin_reg6>, #1 // for expression
let SP(0)<__wolin_reg6>[ubyte] = HEAP(2)<pl.qus.wolin.Test.x>[ubyte] // simple id from var
alloc SP<__wolin_reg7>, #1 // RIGHT adding operator
let SP(0)<__wolin_reg7>[ubyte] = HEAP(1)<pl.qus.wolin.Test.y>[ubyte] // simple id from var
add SP(1)<__wolin_reg6>[ubyte] = SP(1)<__wolin_reg6>[ubyte], SP(0)<__wolin_reg7>[ubyte]
free SP<__wolin_reg7>, #1 // RIGHT adding operator
let SPF(2)<returnValue>[ubyte] = SP(0)<__wolin_reg6>[ubyte] // przez sprawdzacz typow - jump expression
free SP<__wolin_reg6>, #1 // for expression
free SPF, #2 // free fn arguments and locals for pl.qus.wolin.Test.suma
ret
// ****************************************
// funkcja: fun pl.qus.wolin.main():unit
// ****************************************
label __wolin_pl_qus_wolin_main
alloc SP<__wolin_reg11>, #2 // For assignment left side
alloc SP<__wolin_reg12>, #2 // for value that gets assigned to left side
alloc SPF, #2
call __wolin_pl_qus_wolin_Test[adr]
let SP(0)<__wolin_reg12>[ptr] = SPF(0)<returnValue>[ptr]// copy return parameter - TODO sprawdzić co jeśli wywołanie funkcji było bez podstawienia!!!
free SPF <pl.qus.wolin.Test>, #2
let SPF(0)<pl.qus.wolin.main..testowa>[ptr] = SP(0)<__wolin_reg12>[ptr] // przez sprawdzacz typow - process assignment
free SP<__wolin_reg12>, #2 // for value that gets assigned to left side, type = pl.qus.wolin.Test
free SP<__wolin_reg11>, #2 // For assignment left side
alloc SP<__wolin_reg14>, #1 // For assignment left side
alloc SP<__wolin_reg15>, #1 // for value that gets assigned to left side
alloc SP<__wolin_reg16>, #2 // dereferenced var
let SP(0)<__wolin_reg16>[ptr] = SPF(0)<pl.qus.wolin.main..testowa>[ptr] // simple id from var
alloc SP<__wolin_reg17>, #1 // for right side of deref
alloc SPF, #3
let SPF(0)[ptr] = SP(1)<__wolin_reg16>[ptr]
call __wolin_pl_qus_wolin_Test_suma[adr]
let SP(0)<__wolin_reg17>[ubyte] = SPF(0)<returnValue>[ubyte]// copy return parameter - TODO sprawdzić co jeśli wywołanie funkcji było bez podstawienia!!!
free SPF <ubyte>, #1
free SP<__wolin_reg17>, #1 // for right side of deref
free SP<__wolin_reg16>, #2 // dereferenced var
let __wolin_pl_qus_wolin_result<pl.qus.wolin.result>[ubyte] = SP(0)<__wolin_reg15>[ubyte] // przez sprawdzacz typow - process assignment
free SP<__wolin_reg15>, #1 // for value that gets assigned to left side, type = ubyte
free SP<__wolin_reg14>, #1 // For assignment left side
free SPF, #2 // free fn arguments and locals for pl.qus.wolin.main
ret
// ****************************************
// LAMBDAS
// ****************************************
// ****************************************
// STATIC SPACE
// ****************************************
label __wolin_indirect_jsr
goto 65535[adr]
label __wolin_pl_qus_wolin_result
alloc 0[ubyte] // pl.qus.wolin.result
Code:
; setupHEADER
;**********************************************
;*
;* BASIC header
;*
;* compile with:
;* cl65.exe -o assembler.prg -t c64 -C c64-asm.cfg -Ln labels.txt assembler.s
;*
;**********************************************
.org 2049
.export LOADADDR = *
Bas10: .word BasEnd
.word 10
.byte 158 ; sys
.byte " 2064"
.byte 0
BasEnd: .word 0
.word 0
;
; setupSPF=251[ubyte],40959[uword]
; prepare function stack
__wolin_spf := 251 ; function stack ptr
__wolin_spf_top := 40959 ; function stack top
lda #<__wolin_spf_top ; set function stack top
sta __wolin_spf
lda #>__wolin_spf_top
sta __wolin_spf+1
; setupSP=143[ubyte]
; prepare program stack
__wolin_sp_top := 143 ; program stack top
ldx #__wolin_sp_top ; set program stack top
; setupHEAP=176[ubyte]
__wolin_this_ptr := 176
; allocSP<__wolin_reg0>,#1
dex
; letSP(0)<__wolin_reg0>[ubyte]=#0[ubyte]
lda #0
sta 0,x
; let__wolin_pl_qus_wolin_znak<pl.qus.wolin.znak>[ubyte]=SP(0)<__wolin_reg0>[ubyte]
lda 0,x
sta __wolin_pl_qus_wolin_znak
; freeSP<__wolin_reg0>,#1
inx
; allocSP<__wolin_reg1>,#1
dex
; letSP(0)<__wolin_reg1>[ubyte]=#0[ubyte]
lda #0
sta 0,x
; let__wolin_pl_qus_wolin_i<pl.qus.wolin.i>[uword]=SP(0)<__wolin_reg1>[ubyte]
lda 0,x
sta __wolin_pl_qus_wolin_i
lda #0
sta __wolin_pl_qus_wolin_i+1
; freeSP<__wolin_reg1>,#1
inx
; goto__wolin_pl_qus_wolin_main[adr]
jmp __wolin_pl_qus_wolin_main
; label__wolin_pl_qus_wolin_allocMem
__wolin_pl_qus_wolin_allocMem:
; allocSP<__wolin_reg2>,#2
dex
dex
; allocSP<__wolin_reg3>,#2
dex
dex
; letSP(0)<__wolin_reg3>[ptr]=#30000[uword]
lda #<30000
sta 0,x
lda #>30000
sta 0+1,x
; letSPF(4)<returnValue>[ptr]=SP(0)<__wolin_reg3>[ptr]
ldy #4
lda 0,x
sta (__wolin_spf),y
iny
lda 0+1,x
sta (__wolin_spf),y
; freeSP<__wolin_reg3>,#2
inx
inx
; freeSP<__wolin_reg2>,#2
inx
inx
; freeSPF,#4
clc
lda __wolin_spf
adc #4
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; ret
rts
; label__wolin_pl_qus_wolin_Test
__wolin_pl_qus_wolin_Test:
; allocSP<__wolin_reg4>,#2
dex
dex
; allocSPF,#6
clc
lda __wolin_spf
sbc #6
sta __wolin_spf
bcs :+
dec __wolin_spf+1
:
; letSPF(2)[uword]=#3[uword]
ldy #2
lda #<3
sta (__wolin_spf),y
iny
lda #>3
sta (__wolin_spf),y
; letSPF(0)[uword]=#1[uword]
ldy #0
lda #<1
sta (__wolin_spf),y
iny
lda #>1
sta (__wolin_spf),y
; call__wolin_pl_qus_wolin_allocMem[adr]
jsr __wolin_pl_qus_wolin_allocMem
; letSP(0)<__wolin_reg4>[ptr]=SPF(0)<returnValue>[ptr]
ldy #0
lda (__wolin_spf),y
sta 0,x
iny
lda (__wolin_spf),y
sta 0+1,x
; freeSPF<Any>,#2
clc
lda __wolin_spf
adc #2
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; letSPF(0)<pl.qus.wolin.Test.returnValue>[ptr]=SP(0)<__wolin_reg4>[ptr]
ldy #0
lda 0,x
sta (__wolin_spf),y
iny
lda 0+1,x
sta (__wolin_spf),y
; setupHEAP=SP(0)<__wolin_reg4>[ptr]
lda 0,x
sta __wolin_this_ptr
lda 0+1,x
sta __wolin_this_ptr+1
; freeSP<__wolin_reg4>,#2
inx
inx
; allocSP<__wolin_reg5>,#1
dex
; letSP(0)<__wolin_reg5>[ubyte]=#3[ubyte]
lda #3
sta 0,x
; letHEAP(2)<pl.qus.wolin.Test.x>[ubyte]=SP(0)<__wolin_reg5>[ubyte]
lda 0,x
ldy #2
sta (__wolin_this_ptr),y
; freeSP<__wolin_reg5>,#1
inx
; allocSP<__wolin_reg6>,#1
dex
; letSP(0)<__wolin_reg6>[ubyte]=#7[ubyte]
lda #7
sta 0,x
; letHEAP(1)<pl.qus.wolin.Test.y>[ubyte]=SP(0)<__wolin_reg6>[ubyte]
lda 0,x
ldy #1
sta (__wolin_this_ptr),y
; freeSP<__wolin_reg6>,#1
inx
; ret
rts
; label__wolin_pl_qus_wolin_Test_suma
__wolin_pl_qus_wolin_Test_suma:
; setupHEAP=this
ldy #0 ; this pointer from SPF to this pointer on ZP
lda (__wolin_spf),y
sta __wolin_this_ptr
iny
lda (__wolin_spf),y
sta __wolin_this_ptr+1
; allocSP<__wolin_reg8>,#1
dex
; letSP(0)<__wolin_reg8>[ubyte]=HEAP(2)<pl.qus.wolin.Test.x>[ubyte]
ldy #2 ; assuming this ZP is set!
lda (__wolin_this_ptr),y
sta 0,x
; allocSP<__wolin_reg9>,#1
dex
; letSP(0)<__wolin_reg9>[ubyte]=HEAP(1)<pl.qus.wolin.Test.y>[ubyte]
ldy #1 ; assuming this ZP is set!
lda (__wolin_this_ptr),y
sta 0,x
; addSP(1)<__wolin_reg8>[ubyte]=SP(1)<__wolin_reg8>[ubyte],SP(0)<__wolin_reg9>[ubyte]
clc
lda 1,x
adc 0,x
sta 1,x
; freeSP<__wolin_reg9>,#1
inx
; letSPF(2)<returnValue>[ubyte]=SP(0)<__wolin_reg8>[ubyte]
lda 0,x
ldy #2
sta (__wolin_spf),y
; freeSP<__wolin_reg8>,#1
inx
; freeSPF,#2
clc
lda __wolin_spf
adc #2
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; ret
rts
; label__wolin_pl_qus_wolin_main
__wolin_pl_qus_wolin_main:
; allocSP<__wolin_reg13>,#2
dex
dex
; allocSP<__wolin_reg14>,#2
dex
dex
; allocSPF,#2
clc
lda __wolin_spf
sbc #2
sta __wolin_spf
bcs :+
dec __wolin_spf+1
:
; call__wolin_pl_qus_wolin_Test[adr]
jsr __wolin_pl_qus_wolin_Test
; letSP(0)<__wolin_reg14>[ptr]=SPF(0)<returnValue>[ptr]
ldy #0
lda (__wolin_spf),y
sta 0,x
iny
lda (__wolin_spf),y
sta 0+1,x
; freeSPF<pl.qus.wolin.Test>,#2
clc
lda __wolin_spf
adc #2
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; letSPF(0)<pl.qus.wolin.main..testowa>[ptr]=SP(0)<__wolin_reg14>[ptr]
ldy #0
lda 0,x
sta (__wolin_spf),y
iny
lda 0+1,x
sta (__wolin_spf),y
; freeSP<__wolin_reg14>,#2
inx
inx
; freeSP<__wolin_reg13>,#2
inx
inx
; allocSP<__wolin_reg16>,#1
dex
; allocSP<__wolin_reg17>,#1
dex
; allocSP<__wolin_reg18>,#2
dex
dex
; letSP(0)<__wolin_reg18>[ptr]=SPF(0)<pl.qus.wolin.main..testowa>[ptr]
ldy #0
lda (__wolin_spf),y
sta 0,x
iny
lda (__wolin_spf),y
sta 0+1,x
; allocSP<__wolin_reg19>,#1
dex
; allocSPF,#3
clc
lda __wolin_spf
sbc #3
sta __wolin_spf
bcs :+
dec __wolin_spf+1
:
; letSPF(0)[ptr]=SP(1)<__wolin_reg18>[ptr]
ldy #0
lda 1,x
sta (__wolin_spf),y
iny
lda 1+1,x
sta (__wolin_spf),y
; call__wolin_pl_qus_wolin_Test_suma[adr]
jsr __wolin_pl_qus_wolin_Test_suma
; letSP(0)<__wolin_reg19>[ubyte]=SPF(0)<returnValue>[ubyte]
ldy #0
lda (__wolin_spf),y
sta 0,x
; freeSPF<ubyte>,#1
clc
lda __wolin_spf
adc #1
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; letSP(3)<__wolin_reg17>[ubyte]=SP(0)<__wolin_reg19>[ubyte]
lda 0,x
sta 3,x
; freeSP<__wolin_reg19>,#1
inx
; freeSP<__wolin_reg18>,#2
inx
inx
; let53280[ubyte]=SP(0)<__wolin_reg17>[ubyte]
lda 0,x
sta 53280
; freeSP<__wolin_reg17>,#1
inx
; freeSP<__wolin_reg16>,#1
inx
; freeSPF,#2
clc
lda __wolin_spf
adc #2
sta __wolin_spf
bcc :+
inc __wolin_spf+1
:
; ret
rts
; label__wolin_indirect_jsr
__wolin_indirect_jsr:
; goto65535[adr]
jmp 65535
; label__wolin_pl_qus_wolin_znak
__wolin_pl_qus_wolin_znak:
; alloc0[ubyte]
.byte 0
; label__wolin_pl_qus_wolin_i
__wolin_pl_qus_wolin_i:
; alloc0[uword]
.word 0