mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-17 10:30:43 +00:00
Added examples of 2 problems
This commit is contained in:
parent
0185370732
commit
e3427796d3
@ -507,6 +507,18 @@ public class TestPrograms {
|
||||
}
|
||||
*/
|
||||
|
||||
/* TODO: Fix array of struct containing array https://gitlab.com/camelot/kickc/issues/274
|
||||
@Test
|
||||
public void testStructPtr23() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-ptr-23");
|
||||
}
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testStructPtr22() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-ptr-22");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructPtr21() throws IOException, URISyntaxException {
|
||||
compileAndCompare("struct-ptr-21");
|
||||
|
25
src/test/kc/struct-ptr-22.kc
Normal file
25
src/test/kc/struct-ptr-22.kc
Normal file
@ -0,0 +1,25 @@
|
||||
// Demonstrates problem with missing parenthesis in double-dereferencing
|
||||
// https://gitlab.com/camelot/kickc/issues/270
|
||||
|
||||
|
||||
import "print"
|
||||
|
||||
struct fileentry {
|
||||
char *bufEdit;
|
||||
};
|
||||
|
||||
typedef struct fileentry ENTRY;
|
||||
|
||||
ENTRY[10] files;
|
||||
ENTRY *file;
|
||||
|
||||
int main(void) {
|
||||
file = files;
|
||||
file->bufEdit = 0x4000;
|
||||
file->bufEdit[3] = 0xAA; // writes address 0x0000 (wrong!)
|
||||
((char *)file->bufEdit)[4] = 0xCC; // writes address 0x4004 (right!)
|
||||
print_cls();
|
||||
print_str("$0000="); print_byte(*(char *)0x0000); print_ln();
|
||||
print_str("$4004="); print_byte(*(char *)0x4004); print_ln();
|
||||
return 0;
|
||||
}
|
31
src/test/kc/struct-ptr-23.kc
Normal file
31
src/test/kc/struct-ptr-23.kc
Normal file
@ -0,0 +1,31 @@
|
||||
// Example of a struct containing an array
|
||||
// Currently fails when put into an array itself
|
||||
|
||||
|
||||
struct Person {
|
||||
char id;
|
||||
char[2] initials;
|
||||
};
|
||||
|
||||
struct Person[] persons =
|
||||
{ { 1, "jg" },
|
||||
{ 8, "hg" }
|
||||
};
|
||||
|
||||
void main() {
|
||||
struct Person *person = persons;
|
||||
print_person(person);
|
||||
person++;
|
||||
print_person(person);
|
||||
}
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
char idx = 0;
|
||||
|
||||
void print_person(struct Person *person) {
|
||||
SCREEN[idx++] = '0'+person->id;
|
||||
SCREEN[idx++] = ' ';
|
||||
SCREEN[idx++] = person->initials[0];
|
||||
SCREEN[idx++] = person->initials[1];
|
||||
SCREEN[idx++] = ' ';
|
||||
}
|
170
src/test/ref/struct-ptr-22.asm
Normal file
170
src/test/ref/struct-ptr-22.asm
Normal file
@ -0,0 +1,170 @@
|
||||
// Demonstrates problem with missing parenthesis in double-dereferencing
|
||||
// https://gitlab.com/camelot/kickc/issues/270
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label print_char_cursor = 6
|
||||
.label print_line_cursor = 4
|
||||
main: {
|
||||
.label _0 = 6
|
||||
lda #<$4000
|
||||
sta files
|
||||
lda #>$4000
|
||||
sta files+1
|
||||
lda #$aa
|
||||
ldy #3
|
||||
ldx files,y
|
||||
stx !+ +1
|
||||
ldx files+1,y
|
||||
stx !+ +2
|
||||
!:
|
||||
sta $ffff
|
||||
lda files
|
||||
sta.z _0
|
||||
lda files+1
|
||||
sta.z _0+1
|
||||
// writes address 0x0000 (wrong!)
|
||||
lda #$cc
|
||||
ldy #4
|
||||
sta (_0),y
|
||||
jsr print_cls
|
||||
lda #<$400
|
||||
sta.z print_char_cursor
|
||||
lda #>$400
|
||||
sta.z print_char_cursor+1
|
||||
lda #<str
|
||||
sta.z print_str.str
|
||||
lda #>str
|
||||
sta.z print_str.str+1
|
||||
jsr print_str
|
||||
ldx 0
|
||||
jsr print_byte
|
||||
lda #<$400
|
||||
sta.z print_line_cursor
|
||||
lda #>$400
|
||||
sta.z print_line_cursor+1
|
||||
jsr print_ln
|
||||
lda.z print_line_cursor
|
||||
sta.z print_char_cursor
|
||||
lda.z print_line_cursor+1
|
||||
sta.z print_char_cursor+1
|
||||
lda #<str1
|
||||
sta.z print_str.str
|
||||
lda #>str1
|
||||
sta.z print_str.str+1
|
||||
jsr print_str
|
||||
ldx $4004
|
||||
jsr print_byte
|
||||
jsr print_ln
|
||||
rts
|
||||
str: .text "$0000="
|
||||
.byte 0
|
||||
str1: .text "$4004="
|
||||
.byte 0
|
||||
}
|
||||
// Print a newline
|
||||
print_ln: {
|
||||
b1:
|
||||
lda #$28
|
||||
clc
|
||||
adc.z print_line_cursor
|
||||
sta.z print_line_cursor
|
||||
bcc !+
|
||||
inc.z print_line_cursor+1
|
||||
!:
|
||||
lda.z print_line_cursor+1
|
||||
cmp.z print_char_cursor+1
|
||||
bcc b1
|
||||
bne !+
|
||||
lda.z print_line_cursor
|
||||
cmp.z print_char_cursor
|
||||
bcc b1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
// Print a byte as HEX
|
||||
// print_byte(byte register(X) b)
|
||||
print_byte: {
|
||||
txa
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
tay
|
||||
lda print_hextab,y
|
||||
jsr print_char
|
||||
lda #$f
|
||||
axs #0
|
||||
lda print_hextab,x
|
||||
jsr print_char
|
||||
rts
|
||||
}
|
||||
// Print a single char
|
||||
// print_char(byte register(A) ch)
|
||||
print_char: {
|
||||
ldy #0
|
||||
sta (print_char_cursor),y
|
||||
inc.z print_char_cursor
|
||||
bne !+
|
||||
inc.z print_char_cursor+1
|
||||
!:
|
||||
rts
|
||||
}
|
||||
// Print a zero-terminated string
|
||||
// print_str(byte* zeropage(2) str)
|
||||
print_str: {
|
||||
.label str = 2
|
||||
b1:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
cmp #0
|
||||
bne b2
|
||||
rts
|
||||
b2:
|
||||
ldy #0
|
||||
lda (str),y
|
||||
sta (print_char_cursor),y
|
||||
inc.z print_char_cursor
|
||||
bne !+
|
||||
inc.z print_char_cursor+1
|
||||
!:
|
||||
inc.z str
|
||||
bne !+
|
||||
inc.z str+1
|
||||
!:
|
||||
jmp b1
|
||||
}
|
||||
// Clear the screen. Also resets current line/char cursor.
|
||||
print_cls: {
|
||||
jsr memset
|
||||
rts
|
||||
}
|
||||
// Copies the character c (an unsigned char) to the first num characters of the object pointed to by the argument str.
|
||||
memset: {
|
||||
.const c = ' '
|
||||
.const num = $3e8
|
||||
.label str = $400
|
||||
.label end = str+num
|
||||
.label dst = 4
|
||||
lda #<str
|
||||
sta.z dst
|
||||
lda #>str
|
||||
sta.z dst+1
|
||||
b2:
|
||||
lda #c
|
||||
ldy #0
|
||||
sta (dst),y
|
||||
inc.z dst
|
||||
bne !+
|
||||
inc.z dst+1
|
||||
!:
|
||||
lda.z dst+1
|
||||
cmp #>end
|
||||
bne b2
|
||||
lda.z dst
|
||||
cmp #<end
|
||||
bne b2
|
||||
rts
|
||||
}
|
||||
print_hextab: .text "0123456789abcdef"
|
||||
files: .fill 2*$a, 0
|
115
src/test/ref/struct-ptr-22.cfg
Normal file
115
src/test/ref/struct-ptr-22.cfg
Normal file
@ -0,0 +1,115 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
main: scope:[main] from @1
|
||||
[4] *((byte**)(const struct fileentry[$a]) files#0) ← (byte*) 16384
|
||||
[5] *(*((byte**)(const struct fileentry[$a]) files#0) + (byte) 3) ← (byte) $aa
|
||||
[6] (byte*~) main::$0 ← *((byte**)(const struct fileentry[$a]) files#0)
|
||||
[7] *((byte*~) main::$0 + (byte) 4) ← (byte) $cc
|
||||
[8] call print_cls
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
[9] phi()
|
||||
[10] call print_str
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[11] (byte) print_byte::b#0 ← *((byte*) 0)
|
||||
[12] call print_byte
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2
|
||||
[13] phi()
|
||||
[14] call print_ln
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@3
|
||||
[15] (byte*~) print_char_cursor#48 ← (byte*) print_line_cursor#1
|
||||
[16] call print_str
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@4
|
||||
[17] (byte) print_byte::b#1 ← *((byte*) 16388)
|
||||
[18] call print_byte
|
||||
to:main::@6
|
||||
main::@6: scope:[main] from main::@5
|
||||
[19] phi()
|
||||
[20] call print_ln
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@6
|
||||
[21] return
|
||||
to:@return
|
||||
print_ln: scope:[print_ln] from main::@3 main::@6
|
||||
[22] (byte*) print_line_cursor#19 ← phi( main::@3/(byte*) 1024 main::@6/(byte*) print_line_cursor#1 )
|
||||
to:print_ln::@1
|
||||
print_ln::@1: scope:[print_ln] from print_ln print_ln::@1
|
||||
[23] (byte*) print_line_cursor#10 ← phi( print_ln/(byte*) print_line_cursor#19 print_ln::@1/(byte*) print_line_cursor#1 )
|
||||
[24] (byte*) print_line_cursor#1 ← (byte*) print_line_cursor#10 + (byte) $28
|
||||
[25] if((byte*) print_line_cursor#1<(byte*) print_char_cursor#29) goto print_ln::@1
|
||||
to:print_ln::@return
|
||||
print_ln::@return: scope:[print_ln] from print_ln::@1
|
||||
[26] return
|
||||
to:@return
|
||||
print_byte: scope:[print_byte] from main::@2 main::@5
|
||||
[27] (byte) print_byte::b#2 ← phi( main::@2/(byte) print_byte::b#0 main::@5/(byte) print_byte::b#1 )
|
||||
[28] (byte~) print_byte::$0 ← (byte) print_byte::b#2 >> (byte) 4
|
||||
[29] (byte) print_char::ch#0 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$0)
|
||||
[30] call print_char
|
||||
to:print_byte::@1
|
||||
print_byte::@1: scope:[print_byte] from print_byte
|
||||
[31] (byte~) print_byte::$2 ← (byte) print_byte::b#2 & (byte) $f
|
||||
[32] (byte) print_char::ch#1 ← *((const byte[]) print_hextab#0 + (byte~) print_byte::$2)
|
||||
[33] call print_char
|
||||
to:print_byte::@return
|
||||
print_byte::@return: scope:[print_byte] from print_byte::@1
|
||||
[34] return
|
||||
to:@return
|
||||
print_char: scope:[print_char] from print_byte print_byte::@1
|
||||
[35] (byte*) print_char_cursor#28 ← phi( print_byte/(byte*) print_char_cursor#2 print_byte::@1/(byte*) print_char_cursor#29 )
|
||||
[35] (byte) print_char::ch#2 ← phi( print_byte/(byte) print_char::ch#0 print_byte::@1/(byte) print_char::ch#1 )
|
||||
[36] *((byte*) print_char_cursor#28) ← (byte) print_char::ch#2
|
||||
[37] (byte*) print_char_cursor#29 ← ++ (byte*) print_char_cursor#28
|
||||
to:print_char::@return
|
||||
print_char::@return: scope:[print_char] from print_char
|
||||
[38] return
|
||||
to:@return
|
||||
print_str: scope:[print_str] from main::@1 main::@4
|
||||
[39] (byte*) print_char_cursor#45 ← phi( main::@1/(byte*) 1024 main::@4/(byte*~) print_char_cursor#48 )
|
||||
[39] (byte*) print_str::str#5 ← phi( main::@1/(const string) main::str main::@4/(const string) main::str1 )
|
||||
to:print_str::@1
|
||||
print_str::@1: scope:[print_str] from print_str print_str::@2
|
||||
[40] (byte*) print_char_cursor#2 ← phi( print_str/(byte*) print_char_cursor#45 print_str::@2/(byte*) print_char_cursor#1 )
|
||||
[40] (byte*) print_str::str#3 ← phi( print_str/(byte*) print_str::str#5 print_str::@2/(byte*) print_str::str#0 )
|
||||
[41] if((byte) 0!=*((byte*) print_str::str#3)) goto print_str::@2
|
||||
to:print_str::@return
|
||||
print_str::@return: scope:[print_str] from print_str::@1
|
||||
[42] return
|
||||
to:@return
|
||||
print_str::@2: scope:[print_str] from print_str::@1
|
||||
[43] *((byte*) print_char_cursor#2) ← *((byte*) print_str::str#3)
|
||||
[44] (byte*) print_char_cursor#1 ← ++ (byte*) print_char_cursor#2
|
||||
[45] (byte*) print_str::str#0 ← ++ (byte*) print_str::str#3
|
||||
to:print_str::@1
|
||||
print_cls: scope:[print_cls] from main
|
||||
[46] phi()
|
||||
[47] call memset
|
||||
to:print_cls::@return
|
||||
print_cls::@return: scope:[print_cls] from print_cls
|
||||
[48] return
|
||||
to:@return
|
||||
memset: scope:[memset] from print_cls
|
||||
[49] phi()
|
||||
to:memset::@2
|
||||
memset::@2: scope:[memset] from memset memset::@1
|
||||
[50] (byte*) memset::dst#4 ← phi( memset::@1/(byte*) memset::dst#1 memset/(byte*)(const void*) memset::str#0 )
|
||||
[51] *((byte*) memset::dst#4) ← (const byte) memset::c#0
|
||||
[52] (byte*) memset::dst#1 ← ++ (byte*) memset::dst#4
|
||||
to:memset::@1
|
||||
memset::@1: scope:[memset] from memset::@2
|
||||
[53] if((byte*) memset::dst#1!=(const byte*) memset::end#0) goto memset::@2
|
||||
to:memset::@return
|
||||
memset::@return: scope:[memset] from memset::@1
|
||||
[54] return
|
||||
to:@return
|
2275
src/test/ref/struct-ptr-22.log
Normal file
2275
src/test/ref/struct-ptr-22.log
Normal file
File diff suppressed because it is too large
Load Diff
89
src/test/ref/struct-ptr-22.sym
Normal file
89
src/test/ref/struct-ptr-22.sym
Normal file
@ -0,0 +1,89 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) RADIX::BINARY BINARY = (number) 2
|
||||
(const byte) RADIX::DECIMAL DECIMAL = (number) $a
|
||||
(const byte) RADIX::HEXADECIMAL HEXADECIMAL = (number) $10
|
||||
(const byte) RADIX::OCTAL OCTAL = (number) 8
|
||||
(struct fileentry*) file
|
||||
(byte*) fileentry::bufEdit
|
||||
(struct fileentry[$a]) files
|
||||
(const struct fileentry[$a]) files#0 files = { fill( $a, 0) }
|
||||
(signed word()) main()
|
||||
(byte*~) main::$0 $0 zp ZP_WORD:6 4.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@return
|
||||
(signed word) main::return
|
||||
(const string) main::str str = (string) "$0000="
|
||||
(const string) main::str1 str1 = (string) "$4004="
|
||||
(void*()) memset((void*) memset::str , (byte) memset::c , (word) memset::num)
|
||||
(label) memset::@1
|
||||
(label) memset::@2
|
||||
(label) memset::@return
|
||||
(byte) memset::c
|
||||
(const byte) memset::c#0 c = (byte) ' '
|
||||
(byte*) memset::dst
|
||||
(byte*) memset::dst#1 dst zp ZP_WORD:4 16.5
|
||||
(byte*) memset::dst#4 dst zp ZP_WORD:4 16.5
|
||||
(byte*) memset::end
|
||||
(const byte*) memset::end#0 end = (byte*)(const void*) memset::str#0+(const word) memset::num#0
|
||||
(word) memset::num
|
||||
(const word) memset::num#0 num = (word) $3e8
|
||||
(void*) memset::return
|
||||
(void*) memset::str
|
||||
(const void*) memset::str#0 str = (void*)(byte*) 1024
|
||||
(void()) print_byte((byte) print_byte::b)
|
||||
(byte~) print_byte::$0 reg byte a 4.0
|
||||
(byte~) print_byte::$2 reg byte x 4.0
|
||||
(label) print_byte::@1
|
||||
(label) print_byte::@return
|
||||
(byte) print_byte::b
|
||||
(byte) print_byte::b#0 reg byte x 4.0
|
||||
(byte) print_byte::b#1 reg byte x 4.0
|
||||
(byte) print_byte::b#2 reg byte x 2.0
|
||||
(void()) print_char((byte) print_char::ch)
|
||||
(label) print_char::@return
|
||||
(byte) print_char::ch
|
||||
(byte) print_char::ch#0 reg byte a 4.0
|
||||
(byte) print_char::ch#1 reg byte a 4.0
|
||||
(byte) print_char::ch#2 reg byte a 6.0
|
||||
(byte*) print_char_cursor
|
||||
(byte*) print_char_cursor#1 print_char_cursor zp ZP_WORD:6 11.0
|
||||
(byte*) print_char_cursor#2 print_char_cursor zp ZP_WORD:6 3.3636363636363638
|
||||
(byte*) print_char_cursor#28 print_char_cursor zp ZP_WORD:6 4.0
|
||||
(byte*) print_char_cursor#29 print_char_cursor zp ZP_WORD:6 0.9999999999999999
|
||||
(byte*) print_char_cursor#45 print_char_cursor zp ZP_WORD:6 4.0
|
||||
(byte*~) print_char_cursor#48 print_char_cursor zp ZP_WORD:6 4.0
|
||||
(void()) print_cls()
|
||||
(label) print_cls::@return
|
||||
(byte[]) print_hextab
|
||||
(const byte[]) print_hextab#0 print_hextab = (string) "0123456789abcdef"z
|
||||
(byte*) print_line_cursor
|
||||
(byte*) print_line_cursor#1 print_line_cursor zp ZP_WORD:4 4.111111111111112
|
||||
(byte*) print_line_cursor#10 print_line_cursor zp ZP_WORD:4 24.0
|
||||
(byte*) print_line_cursor#19 print_line_cursor zp ZP_WORD:4 4.0
|
||||
(void()) print_ln()
|
||||
(label) print_ln::@1
|
||||
(label) print_ln::@return
|
||||
(byte*) print_screen
|
||||
(void()) print_str((byte*) print_str::str)
|
||||
(label) print_str::@1
|
||||
(label) print_str::@2
|
||||
(label) print_str::@return
|
||||
(byte*) print_str::str
|
||||
(byte*) print_str::str#0 str zp ZP_WORD:2 22.0
|
||||
(byte*) print_str::str#3 str zp ZP_WORD:2 11.5
|
||||
(byte*) print_str::str#5 str zp ZP_WORD:2 2.0
|
||||
|
||||
reg byte x [ print_byte::b#2 print_byte::b#0 print_byte::b#1 ]
|
||||
reg byte a [ print_char::ch#2 print_char::ch#0 print_char::ch#1 ]
|
||||
zp ZP_WORD:2 [ print_str::str#3 print_str::str#5 print_str::str#0 ]
|
||||
zp ZP_WORD:4 [ memset::dst#4 memset::dst#1 print_line_cursor#10 print_line_cursor#19 print_line_cursor#1 ]
|
||||
zp ZP_WORD:6 [ main::$0 print_char_cursor#28 print_char_cursor#2 print_char_cursor#29 print_char_cursor#45 print_char_cursor#48 print_char_cursor#1 ]
|
||||
reg byte a [ print_byte::$0 ]
|
||||
reg byte x [ print_byte::$2 ]
|
Loading…
x
Reference in New Issue
Block a user