1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-30 09:57:11 +00:00

Added toCDecl() that cn print variables and types in standard C declaration format.

This commit is contained in:
jespergravgaard 2021-08-10 00:54:20 +02:00
parent dfa0109613
commit ac9dbc88a8
16 changed files with 533 additions and 309 deletions

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT vbuzz=vbuc1
ldz #{c1}
//FRAGMENT vbuzz_lt_vbuc1_then_la1

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT _deref_pbuc1=vbuc2
lda #{c2}
sta {c1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT vbuz1=vbuc1
lda #{c1}
sta {z1}
@ -1866,8 +1866,39 @@ lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT call__deref_pprz1
jsr {la1}
{la1}: @outside_flow
jmp ({z1}) @outside_flow
//FRAGMENT pprz1=pprz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT call_vprc1
jsr {c1}
//FRAGMENT pprz1=qprc1_derefidx_vbuz2
ldy {z2}
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuaa
tay
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuxx
lda {c1},x
sta {z1}
lda {c1}+1,x
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuyy
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT pbuz1_lt_vwuc1_then_la1
lda {z1}+1
cmp #>{c1}
@ -2403,6 +2434,42 @@ tay
sta {c1},x
//FRAGMENT vbsyy=vbsc1
ldy #{c1}
//FRAGMENT vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {z1}
//FRAGMENT _stackpushbyte_=vbuz1
lda {z1}
pha
//FRAGMENT _stackpullbyte_1
pla
//FRAGMENT vbuz1_eq_vbuc1_then_la1
lda #{c1}
cmp {z1}
beq {la1}
//FRAGMENT vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
//FRAGMENT vbuxx=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tax
//FRAGMENT vbuyy=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tay
//FRAGMENT _stackpushbyte_=vbuyy
tya
pha
//FRAGMENT vbuaa_eq_vbuc1_then_la1
cmp #{c1}
beq {la1}
//FRAGMENT vbuxx_eq_vbuc1_then_la1
cpx #{c1}
beq {la1}
//FRAGMENT vbuyy_eq_vbuc1_then_la1
cpy #{c1}
beq {la1}
//FRAGMENT vbuxx=vbuxx_plus_vbuc1
txa
axs #-[{c1}]
@ -3533,6 +3600,26 @@ sta {z1}+1
//FRAGMENT vwuz1=vwuz1_rol_1
asl {z1}
rol {z1}+1
//FRAGMENT pssz1=pssc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT pbuz1=qbuz2_derefidx_vbuc1
ldy #{c1}
lda ({z2}),y
sta {z1}
iny
lda ({z2}),y
sta {z1}+1
//FRAGMENT pssz1=pssz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT vwuz1=_deref_pwuc1_minus_vwuc2
sec
lda {c1}
@ -3688,10 +3775,6 @@ sta {z1}
lda {z1}+1
sbc {c1}+1,y
sta {z1}+1
//FRAGMENT vbuz1_eq_vbuc1_then_la1
lda #{c1}
cmp {z1}
beq {la1}
//FRAGMENT vwuz1=vwuz1_plus_pwuc1_derefidx_vbuz2
ldy {z2}
clc
@ -3954,9 +4037,6 @@ sta {z1}
lda {z1}+1
sbc {c1}+1,y
sta {z1}+1
//FRAGMENT vbuxx_eq_vbuc1_then_la1
cpx #{c1}
beq {la1}
//FRAGMENT vwuz1=vwuz1_plus_pwuc1_derefidx_vbuaa
tay
clc
@ -3988,9 +4068,6 @@ dex
//FRAGMENT vbuyy=vbuyy_minus_2
dey
dey
//FRAGMENT vbuyy_eq_vbuc1_then_la1
cpy #{c1}
beq {la1}
//FRAGMENT vbuz1=vbuz2_bor_vbuyy
tya
ora {z2}
@ -4050,9 +4127,6 @@ sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT vbuaa_eq_vbuc1_then_la1
cmp #{c1}
beq {la1}
//FRAGMENT vbuaa_eq_vbuz1_then_la1
cmp {z1}
beq {la1}
@ -4908,18 +4982,20 @@ sta {c1}
tya
ora {c1}
sta {c1}
//FRAGMENT vbuz1_le_vbuc1_then_la1
lda #{c1}
cmp {z1}
bcs {la1}
//FRAGMENT vbuaa_le_vbuc1_then_la1
cmp #{c1}
bcc {la1}
beq {la1}
//FRAGMENT _stackpushbyte_=vbuc1
lda #{c1}
pha
//FRAGMENT _stackpullbyte_1
pla
//FRAGMENT vbuz1=_stackpullbyte_
pla
sta {z1}
//FRAGMENT vbuz1=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
sta {z1}
//FRAGMENT _stackidxbyte_vbuc1=vbuz1
lda {z1}
tsx
@ -4932,17 +5008,6 @@ tax
//FRAGMENT vbuyy=_stackpullbyte_
pla
tay
//FRAGMENT vbuaa=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
//FRAGMENT vbuxx=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tax
//FRAGMENT vbuyy=_stackidxbyte_vbuc1
tsx
lda STACK_BASE+{c1},x
tay
//FRAGMENT _stackidxbyte_vbuc1=vbuaa
tsx
sta STACK_BASE+{c1},x
@ -5100,9 +5165,6 @@ lda {z1}
sta STACK_BASE+{c1},x
lda {z1}+1
sta STACK_BASE+{c1}+1,x
//FRAGMENT _stackpushbyte_=vbuz1
lda {z1}
pha
//FRAGMENT _stackpushbyte_1
pha
//FRAGMENT vssz1=_stackpullstruct_2_
@ -5286,9 +5348,6 @@ pha
lda {z1}
tay
dey
//FRAGMENT _stackpushbyte_=vbuyy
tya
pha
//FRAGMENT vbuz1=vbuaa_minus_1
sec
sbc #1
@ -6571,10 +6630,6 @@ lda {z2}
clc
adc #2
sta {z1}
//FRAGMENT vbuz1_le_vbuc1_then_la1
lda #{c1}
cmp {z1}
bcs {la1}
//FRAGMENT vbuz1=vbuaa_plus_2
clc
adc #2
@ -6583,10 +6638,6 @@ sta {z1}
inx
inx
stx {z1}
//FRAGMENT vbuaa_le_vbuc1_then_la1
cmp #{c1}
bcc {la1}
beq {la1}
//FRAGMENT vbuxx_le_vbuc1_then_la1
cpx #{c1}
bcc {la1}
@ -8665,18 +8716,6 @@ tax
lda {c1}
eor #$ff
tay
//FRAGMENT pssz1=pssc1
lda #<{c1}
sta {z1}
lda #>{c1}
sta {z1}+1
//FRAGMENT pbuz1=qbuz2_derefidx_vbuc1
ldy #{c1}
lda ({z2}),y
sta {z1}
iny
lda ({z2}),y
sta {z1}+1
//FRAGMENT vwuz1=pwuz2_derefidx_vbuc1
ldy #{c1}
lda ({z2}),y
@ -8684,14 +8723,6 @@ sta {z1}
iny
lda ({z2}),y
sta {z1}+1
//FRAGMENT pssz1=pssz1_plus_vbuc1
lda #{c1}
clc
adc {z1}
sta {z1}
bcc !+
inc {z1}+1
!:
//FRAGMENT _deref_pwsc1=vwsc2
lda #<{c2}
sta {c1}
@ -11616,6 +11647,153 @@ ldy {c1}+1
sty $ff
ldy #0
sta ($fe),y
//FRAGMENT vbuz1=vbuz2_bxor_vbuz3
lda {z2}
eor {z3}
sta {z1}
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuz1
ldy {z1}
lda {c1},y
pha
//FRAGMENT vbuz1=vbuz2_bxor_vbuaa
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bxor_vbuxx
txa
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bxor_vbuyy
tya
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuz2
tya
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuaa
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
//FRAGMENT vbuaa=vbuz1_bxor_vbuaa
eor {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuxx
txa
eor {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuyy
tya
eor {z1}
//FRAGMENT vbuaa=vbuyy_bxor_vbuz1
tya
eor {z1}
//FRAGMENT vbuaa=vbuyy_bxor_vbuaa
sty $ff
eor $ff
//FRAGMENT vbuaa=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
//FRAGMENT vbuaa=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
//FRAGMENT vbuxx=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuaa
eor {z1}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuxx
txa
eor {z1}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuyy
tya
eor {z1}
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuz1
tya
eor {z1}
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuaa
sty $ff
eor $ff
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuxx
sty $ff
txa
eor $ff
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
tax
//FRAGMENT vbuyy=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuaa
eor {z1}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuxx
txa
eor {z1}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuyy
tya
eor {z1}
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuz1
tya
eor {z1}
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuaa
sty $ff
eor $ff
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
tay
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuaa
tay
lda {c1},y
pha
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuxx
lda {c1},x
pha
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuyy
lda {c1},y
pha
//FRAGMENT vbuyy_gt_vbuaa_then_la1
tax
sty $ff
cpx $ff
bcc {la1}
//FRAGMENT vbuyy_lt_vbuaa_then_la1
sta $ff
cpy $ff
bcc {la1}
//FRAGMENT _deref_pbuc1_eq__deref_pbuc2_then_la1
lda {c1}
cmp {c2}
@ -12104,6 +12282,28 @@ sta ({z1}),y
lda #{c2}
ldy {m1}
sta {c1},y
//FRAGMENT qbuc1_derefidx_vbuz1=pbuc2
ldy {z1}
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT qbuc1_derefidx_vbuaa=pbuc2
tay
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT qbuc1_derefidx_vbuxx=pbuc2
lda #<{c2}
sta {c1},x
lda #>{c2}
sta {c1}+1,x
//FRAGMENT qbuc1_derefidx_vbuyy=pbuc2
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT pbuz1_ge_pbuc1_then_la1
lda {z1}+1
cmp #>{c1}
@ -12748,6 +12948,15 @@ sta {z1}
lda #0
adc {z2}+1
sta {z1}+1
//FRAGMENT pssz1_lt_pssc1_then_la1
lda {z1}+1
cmp #>{c1}
bcc {la1}
bne !+
lda {z1}
cmp #<{c1}
bcc {la1}
!:
//FRAGMENT vbuz1_lt__deref_pbuc1_then_la1
lda {z1}
cmp {c1}
@ -13111,6 +13320,19 @@ sta ({z1}),y
//FRAGMENT _deref_pbuc1=_byte_pprz1
lda {z1}
sta {c1}
//FRAGMENT _stackidxbyte_vbuc1=vbuc2
lda #{c2}
tsx
sta STACK_BASE+{c1},x
//FRAGMENT call__deref_(qprz1_derefidx_vbuc1)
ldy #{c1}
lda ({z1}),y
sta !+ +1
iny
lda ({z1}),y
sta !+ +2
!:
jsr $0000
//FRAGMENT vbuz1=vbuz2_band_pbuz3_derefidx_vbuc1
lda {z2}
ldy #{c1}
@ -15510,6 +15732,11 @@ adc ({z1}),y
sta {z1}+1
pla
sta {z1}
//FRAGMENT pprz1=_deref_qprc1
lda {c1}
sta {z1}
lda {c1}+1
sta {z1}+1
//FRAGMENT vbuz1_ge_vbuaa_then_la1
ldy {z1}
sta $ff
@ -16142,230 +16369,3 @@ sta {c1},x
lda #{c2}
ora {c1},y
sta {c1},y
//FRAGMENT call__deref_pprz1
jsr {la1}
{la1}: @outside_flow
jmp ({z1}) @outside_flow
//FRAGMENT pprz1=pprz2
lda {z2}
sta {z1}
lda {z2}+1
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuz2
ldy {z2}
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuaa
tay
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuxx
lda {c1},x
sta {z1}
lda {c1}+1,x
sta {z1}+1
//FRAGMENT pprz1=qprc1_derefidx_vbuyy
lda {c1},y
sta {z1}
lda {c1}+1,y
sta {z1}+1
//FRAGMENT vbuz1=vbuz2_bxor_vbuz3
lda {z2}
eor {z3}
sta {z1}
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuz1
ldy {z1}
lda {c1},y
pha
//FRAGMENT vbuz1=vbuz2_bxor_vbuaa
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bxor_vbuxx
txa
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuz2_bxor_vbuyy
tya
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuz2
tya
eor {z2}
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuaa
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuz1=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
sta {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
//FRAGMENT vbuaa=vbuz1_bxor_vbuaa
eor {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuxx
txa
eor {z1}
//FRAGMENT vbuaa=vbuz1_bxor_vbuyy
tya
eor {z1}
//FRAGMENT vbuaa=vbuyy_bxor_vbuz1
tya
eor {z1}
//FRAGMENT vbuaa=vbuyy_bxor_vbuaa
sty $ff
eor $ff
//FRAGMENT vbuaa=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
//FRAGMENT vbuaa=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
//FRAGMENT vbuxx=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuaa
eor {z1}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuxx
txa
eor {z1}
tax
//FRAGMENT vbuxx=vbuz1_bxor_vbuyy
tya
eor {z1}
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuz1
tya
eor {z1}
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuaa
sty $ff
eor $ff
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuxx
sty $ff
txa
eor $ff
tax
//FRAGMENT vbuxx=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
tax
//FRAGMENT vbuyy=vbuz1_bxor_vbuz2
lda {z1}
eor {z2}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuaa
eor {z1}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuxx
txa
eor {z1}
tay
//FRAGMENT vbuyy=vbuz1_bxor_vbuyy
tya
eor {z1}
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuz1
tya
eor {z1}
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuaa
sty $ff
eor $ff
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuxx
txa
sty $ff
eor $ff
tay
//FRAGMENT vbuyy=vbuyy_bxor_vbuyy
tya
sty $ff
eor $ff
tay
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuaa
tay
lda {c1},y
pha
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuxx
lda {c1},x
pha
//FRAGMENT _stackpushbyte_=pbuc1_derefidx_vbuyy
lda {c1},y
pha
//FRAGMENT vbuyy_gt_vbuaa_then_la1
tax
sty $ff
cpx $ff
bcc {la1}
//FRAGMENT vbuyy_lt_vbuaa_then_la1
sta $ff
cpy $ff
bcc {la1}
//FRAGMENT _stackidxbyte_vbuc1=vbuc2
lda #{c2}
tsx
sta STACK_BASE+{c1},x
//FRAGMENT pprz1=_deref_qprc1
lda {c1}
sta {z1}
lda {c1}+1
sta {z1}+1
//FRAGMENT qbuc1_derefidx_vbuz1=pbuc2
ldy {z1}
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT qbuc1_derefidx_vbuaa=pbuc2
tay
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT qbuc1_derefidx_vbuxx=pbuc2
lda #<{c2}
sta {c1},x
lda #>{c2}
sta {c1}+1,x
//FRAGMENT qbuc1_derefidx_vbuyy=pbuc2
lda #<{c2}
sta {c1},y
lda #>{c2}
sta {c1}+1,y
//FRAGMENT pssz1_lt_pssc1_then_la1
lda {z1}+1
cmp #>{c1}
bcc {la1}
bne !+
lda {z1}
cmp #<{c1}
bcc {la1}
!:
//FRAGMENT call__deref_(qprz1_derefidx_vbuc1)
ldy #{c1}
lda ({z1}),y
sta !+ +1
iny
lda ({z1}),y
sta !+ +2
!:
jsr $0000

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT _deref_pbuc1=_inc__deref_pbuc1
inc {c1}
//FRAGMENT isr_hardware_all_entry

View File

@ -1,4 +1,4 @@
//KICKC FRAGMENT CACHE 8d94f4f71 8d94f7000
//KICKC FRAGMENT CACHE 85a010c65 85a012cfb
//FRAGMENT vbuz1=_deref_pbuc1
lda {c1}
sta {z1}

View File

@ -572,6 +572,12 @@ public class Variable implements Symbol {
return print.toString();
}
public String toCDecl() {
StringBuilder cdecl = new StringBuilder();
cdecl.append(getType().toCDecl(getLocalName()));
return cdecl.toString();
}
@Override
public boolean equals(Object o) {
if(this == o) return true;

View File

@ -11,7 +11,8 @@ public interface SymbolType extends Serializable {
/** Specifies that the variable is not allowed to be modified (const keyword). The compiler should try to detect modifications and generate compile-time errors if they occur. */
boolean isNomodify();
/** Get the type with different type qualifiers.
/**
* Get the type with different type qualifiers.
*
* @param isVolatile Should the type be marked as volatile
* @param isNomodify Should the type be marked as nomodify (keyword const)
@ -20,17 +21,17 @@ public interface SymbolType extends Serializable {
SymbolType getQualified(boolean isVolatile, boolean isNomodify);
/** Unsigned byte (8 bits)). */
SymbolTypeIntegerFixed BYTE = new SymbolTypeIntegerFixed("byte", 0, 255, false, 8, false, false);
SymbolTypeIntegerFixed BYTE = new SymbolTypeIntegerFixed("byte", "char", 0, 255, false, 8, false, false);
/** Signed byte (8 bits). */
SymbolTypeIntegerFixed SBYTE = new SymbolTypeIntegerFixed("signed byte", -128, 127, true, 8, false, false);
SymbolTypeIntegerFixed SBYTE = new SymbolTypeIntegerFixed("signed byte", "signed char", -128, 127, true, 8, false, false);
/** Unsigned word (2 bytes, 16 bits). */
SymbolTypeIntegerFixed WORD = new SymbolTypeIntegerFixed("word", 0, 65_535, false, 16, false, false);
SymbolTypeIntegerFixed WORD = new SymbolTypeIntegerFixed("word", "unsigned int", 0, 65_535, false, 16, false, false);
/** Signed word (2 bytes, 16 bits). */
SymbolTypeIntegerFixed SWORD = new SymbolTypeIntegerFixed("signed word", -32_768, 32_767, true, 16, false, false);
SymbolTypeIntegerFixed SWORD = new SymbolTypeIntegerFixed("signed word", "int", -32_768, 32_767, true, 16, false, false);
/** Unsigned double word (4 bytes, 32 bits). */
SymbolTypeIntegerFixed DWORD = new SymbolTypeIntegerFixed("dword", 0, 4_294_967_296L, false, 32, false, false);
SymbolTypeIntegerFixed DWORD = new SymbolTypeIntegerFixed("dword", "unsigned long", 0, 4_294_967_296L, false, 32, false, false);
/** Signed double word (4 bytes, 32 bits). */
SymbolTypeIntegerFixed SDWORD = new SymbolTypeIntegerFixed("signed dword", -2_147_483_648, 2_147_483_647, true, 32, false, false);
SymbolTypeIntegerFixed SDWORD = new SymbolTypeIntegerFixed("signed dword", "long", -2_147_483_648, 2_147_483_647, true, 32, false, false);
/** Integer with unknown size and unknown signedness (used for constant expressions). */
SymbolTypeIntegerAuto NUMBER = new SymbolTypeIntegerAuto("number");
/** Unsigned integer with unknown size (used for constant expressions). */
@ -113,12 +114,14 @@ public interface SymbolType extends Serializable {
/**
* Get the type base name (without const/volatile)
*
* @return type base name
*/
String getTypeBaseName();
/**
* Get the size of the type (in bytes).
*
* @return The size. -1 if the type is compile-time only.
*/
int getSizeBytes();
@ -133,4 +136,14 @@ public interface SymbolType extends Serializable {
return SDWORD.equals(type) || DWORD.equals(type) || SWORD.equals(type) || WORD.equals(type) || SBYTE.equals(type) || BYTE.equals(type) || NUMBER.equals(type) || UNUMBER.equals(type) || SNUMBER.equals(type);
}
/**
* Get the C declaration formatted type.
*
* @return The C declaration string
* @param parentCDecl
*/
default public String toCDecl(String parentCDecl) {
return "";
}
}

View File

@ -23,6 +23,12 @@ public class SymbolTypeEnum implements SymbolType {
this.isNomodify = isNomodify;
}
public SymbolTypeEnum(String enumName, boolean isVolatile, boolean isNomodify) {
this.enumName = enumName;
this.isVolatile = isVolatile;
this.isNomodify = isNomodify;
}
@Override
public SymbolType getQualified(boolean isVolatile, boolean isNomodify) {
return new SymbolTypeEnum(this.definition, isVolatile, isNomodify);
@ -70,4 +76,18 @@ public class SymbolTypeEnum implements SymbolType {
return Objects.hash(enumName);
}
@Override
public String toCDecl(String parentCDecl) {
StringBuilder cdecl = new StringBuilder();
if(isVolatile())
cdecl.append("volatile ");
if(isNomodify())
cdecl.append("const ");
cdecl.append("enum ");
cdecl.append(this.enumName);
cdecl.append(" ");
cdecl.append(parentCDecl);
return cdecl.toString();
}
}

View File

@ -53,4 +53,17 @@ public class SymbolTypeIntegerAuto implements SymbolTypeInteger {
public int hashCode() {
return Objects.hash(typeName);
}
@Override
public String toCDecl(String parentCDecl) {
StringBuilder cdecl = new StringBuilder();
if(isVolatile())
cdecl.append("volatile ");
if(isNomodify())
cdecl.append("const ");
cdecl.append(this.getTypeBaseName());
cdecl.append(" ");
cdecl.append(parentCDecl);
return cdecl.toString();
}
}

View File

@ -9,6 +9,8 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
/** The basename of the the type (without any qualifiers). */
private final String typeBaseName;
/** The basename of the the C type (without any qualifiers). */
private final String cTypeBaseName;
private final long minValue;
private final long maxValue;
@ -18,8 +20,9 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
private final boolean isVolatile;
private final boolean isNomodify;
SymbolTypeIntegerFixed(String typeBaseName, long minValue, long maxValue, boolean signed, int bits, boolean isVolatile, boolean isNomodify) {
SymbolTypeIntegerFixed(String typeBaseName, String cTypeBaseName, long minValue, long maxValue, boolean signed, int bits, boolean isVolatile, boolean isNomodify) {
this.typeBaseName = typeBaseName;
this.cTypeBaseName = cTypeBaseName;
this.minValue = minValue;
this.maxValue = maxValue;
this.signed = signed;
@ -30,7 +33,7 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
@Override
public SymbolType getQualified(boolean isVolatile, boolean isNomodify) {
return new SymbolTypeIntegerFixed(this.typeBaseName, this.minValue, this.maxValue, this.signed, this.bits, isVolatile, isNomodify);
return new SymbolTypeIntegerFixed(this.typeBaseName, this.cTypeBaseName, this.minValue, this.maxValue, this.signed, this.bits, isVolatile, isNomodify);
}
/**
@ -87,7 +90,7 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
/**
* Determines if a value can be represented by the type without loss of information
*
* @param value The value to examine
* @param number The value to examine
* @return true if the type contains the value
*/
public boolean contains(Long number) {
@ -99,6 +102,10 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
return typeBaseName;
}
public String getCTypeBaseName() {
return cTypeBaseName;
}
public long getMinValue() {
return minValue;
}
@ -125,6 +132,20 @@ public class SymbolTypeIntegerFixed implements SymbolTypeInteger {
return getTypeName();
}
@Override
public String toCDecl(String parentCDecl) {
StringBuilder cdecl = new StringBuilder();
if(isVolatile())
cdecl.append("volatile ");
if(isNomodify())
cdecl.append("const ");
cdecl.append(this.getCTypeBaseName());
if(parentCDecl.length()>0)
cdecl.append(" ");
cdecl.append(parentCDecl);
return cdecl.toString();
}
@Override
public boolean equals(Object o) {
if(this == o) return true;

View File

@ -63,5 +63,18 @@ public class SymbolTypeNamed implements SymbolType {
return getTypeName();
}
@Override
public String toCDecl(String parentCDecl) {
StringBuilder cdecl = new StringBuilder();
if(isVolatile())
cdecl.append("volatile ");
if(isNomodify())
cdecl.append("const ");
cdecl.append(this.getTypeBaseName());
if(parentCDecl.length()>0)
cdecl.append(" ");
cdecl.append(parentCDecl);
return cdecl.toString();
}
}

View File

@ -94,4 +94,32 @@ public class SymbolTypePointer implements SymbolType {
return getTypeName();
}
@Override
public String toCDecl(String parentCDecl) {
if(getArraySpec() != null) {
// Array
StringBuilder cdecl = new StringBuilder();
if(parentCDecl.contains("*"))
cdecl.append("(");
cdecl.append(parentCDecl);
if(parentCDecl.contains("*"))
cdecl.append(")");
cdecl.append("[");
cdecl.append(getArraySpec().getArraySize().toString());
cdecl.append("]");
return this.getElementType().toCDecl(cdecl.toString());
} else {
// Normal pointer
StringBuilder cdecl = new StringBuilder();
cdecl.append("*");
if(isVolatile())
cdecl.append(" volatile");
if(isNomodify())
cdecl.append(" const");
if(isVolatile() || isNomodify())
cdecl.append(" ");
cdecl.append(parentCDecl);
return this.getElementType().toCDecl(cdecl.toString());
}
}
}

View File

@ -2,6 +2,7 @@ package dk.camelot64.kickc.model.types;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
/** A function returning another type */
public class SymbolTypeProcedure implements SymbolType {
@ -81,4 +82,19 @@ public class SymbolTypeProcedure implements SymbolType {
return Objects.hash(returnType, paramTypes);
}
@Override
public String toCDecl(String parentCDecl) {
final StringBuilder cdecl = new StringBuilder();
if(parentCDecl.contains("*") || parentCDecl.contains("["))
cdecl.append("(");
cdecl.append(parentCDecl);
if(parentCDecl.contains("*") || parentCDecl.contains("["))
cdecl.append(")");
cdecl.append("(");
StringJoiner joiner = new StringJoiner(", ");
paramTypes.stream().forEach(symbolType -> joiner.add(symbolType.toCDecl("")));
cdecl.append(joiner);
cdecl.append(")");
return getReturnType().toCDecl(cdecl.toString());
}
}

View File

@ -147,4 +147,21 @@ public class SymbolTypeStruct implements SymbolType {
return getTypeName();
}
@Override
public String toCDecl(String parentCDecl) {
StringBuilder cdecl = new StringBuilder();
if(isVolatile())
cdecl.append("volatile ");
if(isNomodify())
cdecl.append("const ");
if(isUnion) {
cdecl.append("union ");
} else {
cdecl.append("struct ");
}
cdecl.append(this.structName);
cdecl.append(" ");
cdecl.append(parentCDecl);
return cdecl.toString();
}
}

View File

@ -0,0 +1,77 @@
package dk.camelot64.kickc.test;
import dk.camelot64.kickc.model.symbols.ArraySpec;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.*;
import dk.camelot64.kickc.model.values.ConstantInteger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
/// Test correct printing of types in legal C declaration format
/// https://cdecl.org
public class testTypeCDecl {
@Test
void testSimple() {
assertCDecl("char x", "x", SymbolType.BYTE);
assertCDecl("signed char x", "x", SymbolType.SBYTE);
assertCDecl("volatile char x", "x", SymbolType.BYTE.getQualified(true, false));
assertCDecl("const int x", "x", SymbolType.SWORD.getQualified(false, true));
assertCDecl("volatile const unsigned long qwe", "qwe", SymbolType.DWORD.getQualified(true, true));
}
@Test
void testSpecial() {
assertCDecl("number x", "x", SymbolType.NUMBER);
assertCDecl("snumber x", "x", SymbolType.SNUMBER);
assertCDecl("bool x", "x", SymbolType.BOOLEAN);
assertCDecl("var x", "x", SymbolType.VAR);
assertCDecl("void x", "x", SymbolType.VOID);
}
@Test
void testPointerVar() {
assertCDecl("char *ptr", "ptr", new SymbolTypePointer(SymbolType.BYTE));
assertCDecl("void *ptr", "ptr", new SymbolTypePointer(SymbolType.VOID));
assertCDecl("volatile unsigned int * const ptr", "ptr", new SymbolTypePointer(SymbolType.WORD.getQualified(true, false)).getQualified(false, true));
assertCDecl("volatile char * volatile * volatile ptr", "ptr", new SymbolTypePointer(new SymbolTypePointer(SymbolType.BYTE.getQualified(true, false)).getQualified(true, false)).getQualified(true, false));
}
@Test
void testArray() {
assertCDecl("char NUM[5]", "NUM", new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(new ConstantInteger(5L)), false, false));
assertCDecl("int BOARD[8][8]", "BOARD", new SymbolTypePointer(new SymbolTypePointer(SymbolType.SWORD, new ArraySpec(new ConstantInteger(8L)), false, false), new ArraySpec(new ConstantInteger(8L)), false, false));
assertCDecl("long * const ls[7]", "ls", new SymbolTypePointer(new SymbolTypePointer(SymbolType.SDWORD, null, false, true), new ArraySpec(new ConstantInteger(7L)), false, false));
assertCDecl("char (* volatile x[2])[3]", "x", new SymbolTypePointer(new SymbolTypePointer(new SymbolTypePointer(SymbolType.BYTE, new ArraySpec(new ConstantInteger(3L)), false, false), null, true, false), new ArraySpec(new ConstantInteger(2L)), false, false));
}
@Test
void testStructUnionEnum() {
assertCDecl("struct Point p", "p", new SymbolTypeStruct("Point", false, 4, false, false));
assertCDecl("struct Point *ptr", "ptr", new SymbolTypePointer(new SymbolTypeStruct("Point", false, 4, false, false)));
assertCDecl("const union IPV4 ip", "ip", new SymbolTypeStruct("IPV4", true, 4, false, true));
assertCDecl("struct Point * const ptr", "ptr", new SymbolTypePointer(new SymbolTypeStruct("Point", false, 4, false, false)).getQualified(false, true));
assertCDecl("struct Point points[9]", "points", new SymbolTypePointer(new SymbolTypeStruct("Point", false, 4, false, false), new ArraySpec(new ConstantInteger(9l)), false, false) );
assertCDecl("enum SUIT suit", "suit", new SymbolTypeEnum("SUIT", false, false));
}
@Test
void testProcedure() {
assertCDecl("char fn(char)", "fn", new SymbolTypeProcedure(SymbolType.BYTE, Arrays.asList(SymbolType.BYTE)));
assertCDecl("void (*fn)(void)", "fn", new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.VOID, Arrays.asList(SymbolType.VOID))));
assertCDecl("char (*fn)(long, int)", "fn", new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.BYTE, Arrays.asList(SymbolType.SDWORD, SymbolType.SWORD))));
assertCDecl("char (FUNCS[3])(void)", "FUNCS", new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.BYTE, Arrays.asList(SymbolType.VOID)), new ArraySpec(new ConstantInteger(3l)), false, false));
assertCDecl("void (*transform)(char (*)(char))", "transform", new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.VOID, Arrays.asList(new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.BYTE, Arrays.asList(SymbolType.BYTE)))))));
assertCDecl("void (*(*getfn)(char))(void)", "getfn", new SymbolTypePointer(new SymbolTypeProcedure(new SymbolTypePointer(new SymbolTypeProcedure(SymbolType.VOID, Arrays.asList(SymbolType.VOID))), Arrays.asList(SymbolType.BYTE))));
}
private void assertCDecl(String cdecl, String name, SymbolType type) {
ProgramScope scope = new ProgramScope();
Variable var = scope.add(new Variable(name, Variable.Kind.LOAD_STORE, type, scope, Variable.MemoryArea.MAIN_MEMORY, "Data", null));
Assertions.assertEquals(cdecl, var.toCDecl());
}
}