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

@ -8,10 +8,11 @@ public interface SymbolType extends Serializable {
/** Specifies that the value of the variable may change at any time, so the optimizer must not make assumptions. The variable must always live in memory to be available for any multi-threaded access (eg. in interrupts). (volatile keyword) */
boolean isVolatile();
/** 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.*/
/** 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();
@ -130,7 +133,17 @@ public interface SymbolType extends Serializable {
* @return true if the type is integer
*/
static boolean isInteger(SymbolType type) {
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);
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());
}
}