mirror of
https://github.com/irmen/prog8.git
synced 2024-12-01 15:52:54 +00:00
Fixed namespace lookup errors related to variable initialization. Removed many X register clobbers.
This commit is contained in:
parent
56e0f4c525
commit
6e3820c6b8
@ -47,9 +47,10 @@ asmsub byte2decimal (ubyte value @ A) -> clobbers() -> (ubyte @ Y, ubyte @ X,
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub ubyte2hex (ubyte value @ A) -> clobbers(X) -> (ubyte @ A, ubyte @ Y) {
|
asmsub ubyte2hex (ubyte value @ A) -> clobbers() -> (ubyte @ A, ubyte @ Y) {
|
||||||
; ---- A to hex string in AY (first hex char in A, second hex char in Y)
|
; ---- A to hex string in AY (first hex char in A, second hex char in Y)
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
pha
|
pha
|
||||||
and #$0f
|
and #$0f
|
||||||
tax
|
tax
|
||||||
@ -61,6 +62,7 @@ asmsub ubyte2hex (ubyte value @ A) -> clobbers(X) -> (ubyte @ A, ubyte @ Y) {
|
|||||||
lsr a
|
lsr a
|
||||||
tax
|
tax
|
||||||
lda hex_digits,x
|
lda hex_digits,x
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
|
|
||||||
hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well
|
hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as well
|
||||||
@ -69,13 +71,13 @@ hex_digits .text "0123456789abcdef" ; can probably be reused for other stuff as
|
|||||||
|
|
||||||
|
|
||||||
str word2hex_output = "1234" ; 0-terminated, to make printing easier
|
str word2hex_output = "1234" ; 0-terminated, to make printing easier
|
||||||
asmsub uword2hex (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub uword2hex (uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string into memory 'word2hex_output'
|
; ---- convert 16 bit uword in A/Y into 4-character hexadecimal string into memory 'word2hex_output'
|
||||||
%asm {{
|
%asm {{
|
||||||
sta c64.SCRATCH_ZPREG
|
sta c64.SCRATCH_ZPREG
|
||||||
tya
|
tya
|
||||||
jsr ubyte2hex
|
jsr ubyte2hex
|
||||||
stx word2hex_output
|
sta word2hex_output
|
||||||
sty word2hex_output+1
|
sty word2hex_output+1
|
||||||
lda c64.SCRATCH_ZPREG
|
lda c64.SCRATCH_ZPREG
|
||||||
jsr ubyte2hex
|
jsr ubyte2hex
|
||||||
@ -86,7 +88,7 @@ asmsub uword2hex (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ubyte[3] word2bcd_bcdbuff = [0, 0, 0]
|
ubyte[3] word2bcd_bcdbuff = [0, 0, 0]
|
||||||
asmsub uword2bcd (uword value @ AY) -> clobbers(A,X) -> () {
|
asmsub uword2bcd (uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; Convert an 16 bit binary value to BCD
|
; Convert an 16 bit binary value to BCD
|
||||||
;
|
;
|
||||||
; This function converts a 16 bit binary value in A/Y into a 24 bit BCD. It
|
; This function converts a 16 bit binary value in A/Y into a 24 bit BCD. It
|
||||||
@ -103,7 +105,7 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,X) -> () {
|
|||||||
sta word2bcd_bcdbuff+0
|
sta word2bcd_bcdbuff+0
|
||||||
sta word2bcd_bcdbuff+1
|
sta word2bcd_bcdbuff+1
|
||||||
sta word2bcd_bcdbuff+2
|
sta word2bcd_bcdbuff+2
|
||||||
ldx #16 ; the number of source bits
|
ldy #16 ; the number of source bits
|
||||||
|
|
||||||
- asl c64.SCRATCH_ZPB1 ; shift out one bit
|
- asl c64.SCRATCH_ZPB1 ; shift out one bit
|
||||||
rol c64.SCRATCH_ZPREG
|
rol c64.SCRATCH_ZPREG
|
||||||
@ -116,7 +118,7 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,X) -> () {
|
|||||||
lda word2bcd_bcdbuff+2 ; ... thru whole result
|
lda word2bcd_bcdbuff+2 ; ... thru whole result
|
||||||
adc word2bcd_bcdbuff+2
|
adc word2bcd_bcdbuff+2
|
||||||
sta word2bcd_bcdbuff+2
|
sta word2bcd_bcdbuff+2
|
||||||
dex ; and repeat for next bit
|
dey ; and repeat for next bit
|
||||||
bne -
|
bne -
|
||||||
cld ; back to binary
|
cld ; back to binary
|
||||||
cli ; enable interrupts again
|
cli ; enable interrupts again
|
||||||
@ -126,7 +128,7 @@ asmsub uword2bcd (uword value @ AY) -> clobbers(A,X) -> () {
|
|||||||
|
|
||||||
|
|
||||||
ubyte[5] word2decimal_output = 0
|
ubyte[5] word2decimal_output = 0
|
||||||
asmsub uword2decimal (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub uword2decimal (uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- convert 16 bit uword in A/Y into decimal string into memory 'word2decimal_output'
|
; ---- convert 16 bit uword in A/Y into decimal string into memory 'word2decimal_output'
|
||||||
%asm {{
|
%asm {{
|
||||||
jsr uword2bcd
|
jsr uword2bcd
|
||||||
@ -471,11 +473,12 @@ _loop sta c64.Colors,y
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, X, Y) -> () {
|
asmsub scroll_left_full (ubyte alsocolors @ Pc) -> clobbers(A, Y) -> () {
|
||||||
; ---- scroll the whole screen 1 character to the left
|
; ---- scroll the whole screen 1 character to the left
|
||||||
; contents of the rightmost column are unchanged, you should clear/refill this yourself
|
; contents of the rightmost column are unchanged, you should clear/refill this yourself
|
||||||
; Carry flag determines if screen color data must be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
|
|
||||||
@ -525,16 +528,18 @@ _scroll_screen ; scroll the screen memory
|
|||||||
dey
|
dey
|
||||||
bpl -
|
bpl -
|
||||||
|
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
|
asmsub scroll_right_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
|
||||||
; ---- scroll the whole screen 1 character to the right
|
; ---- scroll the whole screen 1 character to the right
|
||||||
; contents of the leftmost column are unchanged, you should clear/refill this yourself
|
; contents of the leftmost column are unchanged, you should clear/refill this yourself
|
||||||
; Carry flag determines if screen color data must be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
|
|
||||||
@ -576,16 +581,18 @@ _scroll_screen ; scroll the screen memory
|
|||||||
dex
|
dex
|
||||||
bpl -
|
bpl -
|
||||||
|
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
|
asmsub scroll_up_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
|
||||||
; ---- scroll the whole screen 1 character up
|
; ---- scroll the whole screen 1 character up
|
||||||
; contents of the bottom row are unchanged, you should refill/clear this yourself
|
; contents of the bottom row are unchanged, you should refill/clear this yourself
|
||||||
; Carry flag determines if screen color data must be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
|
|
||||||
@ -627,16 +634,18 @@ _scroll_screen ; scroll the screen memory
|
|||||||
dex
|
dex
|
||||||
bpl -
|
bpl -
|
||||||
|
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A,X) -> () {
|
asmsub scroll_down_full (ubyte alsocolors @ Pc) -> clobbers(A) -> () {
|
||||||
; ---- scroll the whole screen 1 character down
|
; ---- scroll the whole screen 1 character down
|
||||||
; contents of the top row are unchanged, you should refill/clear this yourself
|
; contents of the top row are unchanged, you should refill/clear this yourself
|
||||||
; Carry flag determines if screen color data must be scrolled too
|
; Carry flag determines if screen color data must be scrolled too
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
bcs +
|
bcs +
|
||||||
jmp _scroll_screen
|
jmp _scroll_screen
|
||||||
|
|
||||||
@ -678,6 +687,7 @@ _scroll_screen ; scroll the screen memory
|
|||||||
dex
|
dex
|
||||||
bpl -
|
bpl -
|
||||||
|
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
@ -703,11 +713,12 @@ asmsub print (str text @ AY) -> clobbers(A,Y) -> () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_p (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
|
asmsub print_p (str_p text @ AY) -> clobbers(A) -> (ubyte @ Y) {
|
||||||
; ---- print pstring (length as first byte) from A/Y, returns str len in Y
|
; ---- print pstring (length as first byte) from A/Y, returns str len in Y
|
||||||
%asm {{
|
%asm {{
|
||||||
sta c64.SCRATCH_ZPB1
|
sta c64.SCRATCH_ZPB1
|
||||||
sty c64.SCRATCH_ZPREG
|
sty c64.SCRATCH_ZPREG
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (c64.SCRATCH_ZPB1),y
|
lda (c64.SCRATCH_ZPB1),y
|
||||||
beq +
|
beq +
|
||||||
@ -717,14 +728,16 @@ asmsub print_p (str_p text @ AY) -> clobbers(A,X) -> (ubyte @ Y) {
|
|||||||
jsr c64.CHROUT
|
jsr c64.CHROUT
|
||||||
dex
|
dex
|
||||||
bne -
|
bne -
|
||||||
+ rts ; output string length is in Y
|
+ ldx c64.SCRATCH_ZPREGX
|
||||||
|
rts ; output string length is in Y
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_ub0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
|
asmsub print_ub0 (ubyte value @ A) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
|
; ---- print the ubyte in A in decimal form, with left padding 0s (3 positions total)
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
jsr c64utils.ubyte2decimal
|
jsr c64utils.ubyte2decimal
|
||||||
pha
|
pha
|
||||||
tya
|
tya
|
||||||
@ -732,14 +745,17 @@ asmsub print_ub0 (ubyte value @ A) -> clobbers(A,X,Y) -> () {
|
|||||||
txa
|
txa
|
||||||
jsr c64.CHROUT
|
jsr c64.CHROUT
|
||||||
pla
|
pla
|
||||||
jmp c64.CHROUT
|
jsr c64.CHROUT
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_ub (ubyte value @ A) -> clobbers(A,X,Y) -> () {
|
asmsub print_ub (ubyte value @ A) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the ubyte in A in decimal form, without left padding 0s
|
; ---- print the ubyte in A in decimal form, without left padding 0s
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
jsr c64utils.ubyte2decimal
|
jsr c64utils.ubyte2decimal
|
||||||
_print_byte_digits
|
_print_byte_digits
|
||||||
pha
|
pha
|
||||||
@ -754,13 +770,16 @@ _print_hundreds tya
|
|||||||
_print_tens txa
|
_print_tens txa
|
||||||
jsr c64.CHROUT
|
jsr c64.CHROUT
|
||||||
pla
|
pla
|
||||||
jmp c64.CHROUT
|
jsr c64.CHROUT
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub print_b (byte value @ A) -> clobbers(A,X,Y) -> () {
|
asmsub print_b (byte value @ A) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the byte in A in decimal form, without left padding 0s
|
; ---- print the byte in A in decimal form, without left padding 0s
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
pha
|
pha
|
||||||
cmp #0
|
cmp #0
|
||||||
bpl +
|
bpl +
|
||||||
@ -768,14 +787,17 @@ asmsub print_b (byte value @ A) -> clobbers(A,X,Y) -> () {
|
|||||||
jsr c64.CHROUT
|
jsr c64.CHROUT
|
||||||
+ pla
|
+ pla
|
||||||
jsr c64utils.byte2decimal
|
jsr c64utils.byte2decimal
|
||||||
jmp print_ub._print_byte_digits
|
jsr print_ub._print_byte_digits
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) -> () {
|
asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
|
; ---- print the ubyte in A in hex form (if Carry is set, a radix prefix '$' is printed as well)
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
bcc +
|
bcc +
|
||||||
pha
|
pha
|
||||||
lda #'$'
|
lda #'$'
|
||||||
@ -784,14 +806,17 @@ asmsub print_ubhex (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) ->
|
|||||||
+ jsr c64utils.ubyte2hex
|
+ jsr c64utils.ubyte2hex
|
||||||
jsr c64.CHROUT
|
jsr c64.CHROUT
|
||||||
tya
|
tya
|
||||||
jmp c64.CHROUT
|
jsr c64.CHROUT
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) ->() {
|
asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,Y) ->() {
|
||||||
; ---- print the ubyte in A in binary form (if Carry is set, a radix prefix '%' is printed as well)
|
; ---- print the ubyte in A in binary form (if Carry is set, a radix prefix '%' is printed as well)
|
||||||
%asm {{
|
%asm {{
|
||||||
|
stx c64.SCRATCH_ZPREGX
|
||||||
sta c64.SCRATCH_ZPB1
|
sta c64.SCRATCH_ZPB1
|
||||||
bcc +
|
bcc +
|
||||||
lda #'%'
|
lda #'%'
|
||||||
@ -804,12 +829,13 @@ asmsub print_ubbin (ubyte prefix @ Pc, ubyte value @ A) -> clobbers(A,X,Y) ->(
|
|||||||
+ jsr c64.CHROUT
|
+ jsr c64.CHROUT
|
||||||
dey
|
dey
|
||||||
bne -
|
bne -
|
||||||
|
ldx c64.SCRATCH_ZPREGX
|
||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) ->() {
|
asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) ->() {
|
||||||
; ---- print the uword in A/Y in binary form (if Carry is set, a radix prefix '%' is printed as well)
|
; ---- print the uword in A/Y in binary form (if Carry is set, a radix prefix '%' is printed as well)
|
||||||
%asm {{
|
%asm {{
|
||||||
pha
|
pha
|
||||||
@ -822,7 +848,7 @@ asmsub print_uwbin (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the uword in A/Y in hexadecimal form (4 digits)
|
; ---- print the uword in A/Y in hexadecimal form (4 digits)
|
||||||
; (if Carry is set, a radix prefix '$' is printed as well)
|
; (if Carry is set, a radix prefix '$' is printed as well)
|
||||||
%asm {{
|
%asm {{
|
||||||
@ -836,7 +862,7 @@ asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_uw0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub print_uw0 (uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
|
; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
|
||||||
%asm {{
|
%asm {{
|
||||||
jsr c64utils.uword2decimal
|
jsr c64utils.uword2decimal
|
||||||
@ -851,7 +877,7 @@ asmsub print_uw0 (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmsub print_uw (uword value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub print_uw (uword value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the uword in A/Y in decimal form, without left padding 0s
|
; ---- print the uword in A/Y in decimal form, without left padding 0s
|
||||||
%asm {{
|
%asm {{
|
||||||
jsr c64utils.uword2decimal
|
jsr c64utils.uword2decimal
|
||||||
@ -883,7 +909,7 @@ _pr_decimal
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub print_w (word value @ AY) -> clobbers(A,X,Y) -> () {
|
asmsub print_w (word value @ AY) -> clobbers(A,Y) -> () {
|
||||||
; ---- print the (signed) word in A/Y in decimal form, without left padding 0s
|
; ---- print the (signed) word in A/Y in decimal form, without left padding 0s
|
||||||
%asm {{
|
%asm {{
|
||||||
cpy #0
|
cpy #0
|
||||||
@ -904,7 +930,7 @@ asmsub print_w (word value @ AY) -> clobbers(A,X,Y) -> () {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub input_chars (uword buffer @ AY) -> clobbers(A, X) -> (ubyte @ Y) {
|
asmsub input_chars (uword buffer @ AY) -> clobbers(A) -> (ubyte @ Y) {
|
||||||
; ---- Input a string (max. 80 chars) from the keyboard. Returns length in Y.
|
; ---- Input a string (max. 80 chars) from the keyboard. Returns length in Y.
|
||||||
; It assumes the keyboard is selected as I/O channel!
|
; It assumes the keyboard is selected as I/O channel!
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ private fun compileMain(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
//println(" time2: $time2")
|
//println(" time2: $time2")
|
||||||
val time3 = measureTimeMillis {
|
val time3 = measureTimeMillis {
|
||||||
StatementReorderer(namespace, heap).process(moduleAst) // reorder statements to please the compiler later
|
moduleAst.reorderStatements(namespace,heap) // reorder statements to please the compiler later
|
||||||
}
|
}
|
||||||
//println(" time3: $time3")
|
//println(" time3: $time3")
|
||||||
val time4 = measureTimeMillis {
|
val time4 = measureTimeMillis {
|
||||||
|
@ -692,7 +692,7 @@ class VarDecl(val type: VarDeclType,
|
|||||||
return "VarDecl(name=$name, vartype=$type, datatype=$datatype, value=$value, pos=$position)"
|
return "VarDecl(name=$name, vartype=$type, datatype=$datatype, value=$value, pos=$position)"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asDefaultValueDecl(): VarDecl {
|
fun asDefaultValueDecl(parent: Node?): VarDecl {
|
||||||
val constValue = when(declaredDatatype) {
|
val constValue = when(declaredDatatype) {
|
||||||
DataType.UBYTE -> LiteralValue(DataType.UBYTE, 0, position=position)
|
DataType.UBYTE -> LiteralValue(DataType.UBYTE, 0, position=position)
|
||||||
DataType.BYTE -> LiteralValue(DataType.BYTE, 0, position=position)
|
DataType.BYTE -> LiteralValue(DataType.BYTE, 0, position=position)
|
||||||
@ -701,7 +701,10 @@ class VarDecl(val type: VarDeclType,
|
|||||||
DataType.FLOAT -> LiteralValue(DataType.FLOAT, floatvalue=0.0, position=position)
|
DataType.FLOAT -> LiteralValue(DataType.FLOAT, floatvalue=0.0, position=position)
|
||||||
else -> throw FatalAstException("can only set a default value for a numeric type")
|
else -> throw FatalAstException("can only set a default value for a numeric type")
|
||||||
}
|
}
|
||||||
return VarDecl(type, declaredDatatype, arrayspec, name, constValue, position)
|
val decl = VarDecl(type, declaredDatatype, arrayspec, name, constValue, position)
|
||||||
|
if(parent!=null)
|
||||||
|
decl.linkParents(parent)
|
||||||
|
return decl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ fun printWarning(msg: String, position: Position, detailInfo: String?=null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AstChecker(private val namespace: INameScope,
|
private class AstChecker(private val namespace: INameScope,
|
||||||
private val compilerOptions: CompilationOptions,
|
private val compilerOptions: CompilationOptions,
|
||||||
private val heap: HeapValues) : IAstProcessor {
|
private val heap: HeapValues) : IAstProcessor {
|
||||||
private val checkResult: MutableList<AstException> = mutableListOf()
|
private val checkResult: MutableList<AstException> = mutableListOf()
|
||||||
|
@ -40,7 +40,7 @@ fun Module.checkIdentifiers(heap: HeapValues): MutableMap<String, IStatement> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
private class AstIdentifiersChecker(val heap: HeapValues) : IAstProcessor {
|
||||||
private val checkResult: MutableList<AstException> = mutableListOf()
|
private val checkResult: MutableList<AstException> = mutableListOf()
|
||||||
|
|
||||||
var symbols: MutableMap<String, IStatement> = mutableMapOf()
|
var symbols: MutableMap<String, IStatement> = mutableMapOf()
|
||||||
|
@ -11,7 +11,7 @@ fun Module.checkRecursion(namespace: INameScope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DirectedGraph<VT> {
|
private class DirectedGraph<VT> {
|
||||||
private val graph = mutableMapOf<VT, MutableSet<VT>>()
|
private val graph = mutableMapOf<VT, MutableSet<VT>>()
|
||||||
private var uniqueVertices = mutableSetOf<VT>()
|
private var uniqueVertices = mutableSetOf<VT>()
|
||||||
val numVertices : Int
|
val numVertices : Int
|
||||||
@ -81,7 +81,7 @@ class DirectedGraph<VT> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AstRecursionChecker(private val namespace: INameScope) : IAstProcessor {
|
private class AstRecursionChecker(private val namespace: INameScope) : IAstProcessor {
|
||||||
private val callGraph = DirectedGraph<INameScope>()
|
private val callGraph = DirectedGraph<INameScope>()
|
||||||
|
|
||||||
fun result(): List<AstException> {
|
fun result(): List<AstException> {
|
||||||
|
@ -13,7 +13,7 @@ fun Module.checkImportedValid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ImportedAstChecker : IAstProcessor {
|
private class ImportedAstChecker : IAstProcessor {
|
||||||
private val checkResult: MutableList<SyntaxError> = mutableListOf()
|
private val checkResult: MutableList<SyntaxError> = mutableListOf()
|
||||||
|
|
||||||
fun result(): List<SyntaxError> {
|
fun result(): List<SyntaxError> {
|
||||||
|
@ -2,7 +2,15 @@ package prog8.ast
|
|||||||
|
|
||||||
import prog8.compiler.HeapValues
|
import prog8.compiler.HeapValues
|
||||||
|
|
||||||
class StatementReorderer(private val namespace: INameScope, private val heap: HeapValues): IAstProcessor {
|
fun Module.reorderStatements(namespace: INameScope, heap: HeapValues) {
|
||||||
|
val initvalueCreator = VarInitValueCreator()
|
||||||
|
this.process(initvalueCreator)
|
||||||
|
|
||||||
|
val checker = StatementReorderer(namespace, heap)
|
||||||
|
this.process(checker)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class StatementReorderer(private val namespace: INameScope, private val heap: HeapValues): IAstProcessor {
|
||||||
// Reorders the statements in a way the compiler needs.
|
// Reorders the statements in a way the compiler needs.
|
||||||
// - 'main' block must be the very first statement UNLESS it has an address set.
|
// - 'main' block must be the very first statement UNLESS it has an address set.
|
||||||
// - blocks are ordered by address, where blocks without address are put at the end.
|
// - blocks are ordered by address, where blocks without address are put at the end.
|
||||||
@ -14,9 +22,7 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.
|
// - the 'start' subroutine in the 'main' block will be moved to the top immediately following the directives.
|
||||||
// - all other subroutines will be moved to the end of their block.
|
// - all other subroutines will be moved to the end of their block.
|
||||||
|
|
||||||
|
|
||||||
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
|
private val directivesToMove = setOf("%output", "%launcher", "%zeropage", "%zpreserved", "%address", "%option")
|
||||||
private val vardeclsToAdd = mutableMapOf<INameScope, MutableList<VarDecl>>()
|
|
||||||
|
|
||||||
override fun process(module: Module) {
|
override fun process(module: Module) {
|
||||||
super.process(module)
|
super.process(module)
|
||||||
@ -37,14 +43,6 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
module.statements.removeAll(directives)
|
module.statements.removeAll(directives)
|
||||||
module.statements.addAll(0, directives)
|
module.statements.addAll(0, directives)
|
||||||
|
|
||||||
// add any new vardecls
|
|
||||||
// @todo doing it this late causes problems with namespace lookups elsewhere in sortConstantAssignments
|
|
||||||
for(decl in vardeclsToAdd)
|
|
||||||
for(d in decl.value) {
|
|
||||||
d.linkParents(decl.key as Node)
|
|
||||||
decl.key.statements.add(0, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
sortConstantAssignments(module.statements)
|
sortConstantAssignments(module.statements)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +153,7 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun sortConstantAssignmentSequence(first: Assignment, stmtIter: MutableIterator<IStatement>): Pair<List<Assignment>, IStatement?> {
|
private fun sortConstantAssignmentSequence(first: Assignment, stmtIter: MutableIterator<IStatement>): Pair<List<Assignment>, IStatement?> {
|
||||||
val sequence= mutableListOf<Assignment>(first)
|
val sequence= mutableListOf(first)
|
||||||
var trailing: IStatement? = null
|
var trailing: IStatement? = null
|
||||||
while(stmtIter.hasNext()) {
|
while(stmtIter.hasNext()) {
|
||||||
val next = stmtIter.next()
|
val next = stmtIter.next()
|
||||||
@ -176,20 +174,40 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
return Pair(sorted, trailing)
|
return Pair(sorted, trailing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class VarInitValueCreator: IAstProcessor {
|
||||||
|
// Replace the var decl with an assignment and add a new vardecl with the default constant value.
|
||||||
|
// This makes sure the variables get reset to the intended value on a next run of the program.
|
||||||
|
// Variable decls without a value don't get this treatment, which means they retain the last
|
||||||
|
// value they had when restarting the program.
|
||||||
|
// This is done in a separate step because it interferes with the namespace lookup of symbols
|
||||||
|
// in other ast processors.
|
||||||
|
|
||||||
|
private val vardeclsToAdd = mutableMapOf<INameScope, MutableList<VarDecl>>()
|
||||||
|
|
||||||
|
override fun process(module: Module) {
|
||||||
|
super.process(module)
|
||||||
|
|
||||||
|
// add any new vardecls to the various scopes
|
||||||
|
for(decl in vardeclsToAdd)
|
||||||
|
for(d in decl.value) {
|
||||||
|
d.linkParents(decl.key as Node)
|
||||||
|
decl.key.statements.add(0, d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun process(decl: VarDecl): IStatement {
|
override fun process(decl: VarDecl): IStatement {
|
||||||
super.process(decl)
|
super.process(decl)
|
||||||
if(decl.type!=VarDeclType.VAR || decl.value==null)
|
if(decl.type!=VarDeclType.VAR || decl.value==null)
|
||||||
return decl
|
return decl
|
||||||
|
|
||||||
// Replace the var decl with an assignment and add a new vardecl with the default constant value.
|
|
||||||
// This makes sure the variables get reset to the intended value on a next run of the program.
|
|
||||||
// Variable decls without a value don't get this treatment, which means they retain the last
|
|
||||||
// value they had when restarting the program.
|
|
||||||
if(decl.datatype in NumericDatatypes) {
|
if(decl.datatype in NumericDatatypes) {
|
||||||
val scope = decl.definingScope()
|
val scope = decl.definingScope()
|
||||||
if(scope !in vardeclsToAdd)
|
if(scope !in vardeclsToAdd)
|
||||||
vardeclsToAdd[scope] = mutableListOf()
|
vardeclsToAdd[scope] = mutableListOf()
|
||||||
vardeclsToAdd[scope]!!.add(decl.asDefaultValueDecl())
|
vardeclsToAdd[scope]!!.add(decl.asDefaultValueDecl(null))
|
||||||
val declvalue = decl.value!!
|
val declvalue = decl.value!!
|
||||||
val value =
|
val value =
|
||||||
if(declvalue is LiteralValue) {
|
if(declvalue is LiteralValue) {
|
||||||
@ -207,4 +225,5 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
}
|
}
|
||||||
return decl
|
return decl
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user