1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added examples of 2 problems

This commit is contained in:
jespergravgaard 2019-08-19 08:42:48 +02:00
parent 0185370732
commit e3427796d3
7 changed files with 2717 additions and 0 deletions

View File

@ -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");

View 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;
}

View 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++] = ' ';
}

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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 ]