1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-28 16:31:36 +00:00

Added union syntax and support for very simple unions. Still need some work to support passing as parameters and more. #197

This commit is contained in:
jespergravgaard 2021-07-22 21:05:48 +02:00
parent eee018847c
commit 16234fefa0
35 changed files with 2668 additions and 1150 deletions

View File

@ -15206,3 +15206,31 @@ sta {c1},x
lda #{c2}
ora {c1},y
sta {c1},y
//FRAGMENT vduz1=vduc1_minus__deref_pduc2
lda #<{c1}
sec
sbc {c2}
sta {z1}
lda #>{c1}
sbc {c2}+1
sta {z1}+1
lda #<{c1}>>$10
sbc {c2}+2
sta {z1}+2
lda #>{c1}>>$10
sbc {c2}+3
sta {z1}+3
//FRAGMENT vduz1=vduz2_minus_vduc1
lda {z2}
sec
sbc #<{c1}
sta {z1}
lda {z2}+1
sbc #>{c1}
sta {z1}+1
lda {z2}+2
sbc #<{c1}>>$10
sta {z1}+2
lda {z2}+3
sbc #>{c1}>>$10
sta {z1}+3

View File

@ -1,6 +1,5 @@
package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.LiveRangeEquivalenceClass;
import dk.camelot64.kickc.model.LiveRangeEquivalenceClassSet;
import dk.camelot64.kickc.model.Program;
@ -55,7 +54,7 @@ public class ProgramScope extends Scope {
}
public Symbol getSymbol(SymbolRef symbolRef) {
return getProgramScope().getGlobalSymbol(symbolRef.getFullName());
return this.getGlobalSymbol(symbolRef.getFullName());
}
public Variable getVar(SymbolVariableRef variableRef) {
@ -92,6 +91,16 @@ public class ProgramScope extends Scope {
return (Procedure) symbol;
}
/**
* Add a struct definition.
* The name can be either defined in the program or an intermediate name.
*
* @param name The name of the struct definition
*/
public StructDefinition addStructDefinition(String name, boolean isUnion) {
return add(new StructDefinition(name, isUnion, this));
}
public Scope getScope(ScopeRef scopeRef) {
if(scopeRef.getFullName().equals("")) {
// Special case for the outer program scope

View File

@ -126,16 +126,6 @@ public abstract class Scope implements Symbol, Serializable {
return add(new BlockScope(name, this));
}
/**
* Add a struct definition.
* The name can be either defined in the program or an intermediate name.
*
* @param name The name of the struct definition
*/
public StructDefinition addStructDefinition(String name) {
return add(new StructDefinition(name, this));
}
public String allocateIntermediateVariableName() {
return "$" + intermediateVarCount++;
}

View File

@ -6,11 +6,15 @@ import dk.camelot64.kickc.model.types.SymbolTypeStruct;
/**
* A struct definition containing a set of variables.
* The struct definition can either represent a struct (linear consecutive memory layout) or a union (same memory address)
*/
public class StructDefinition extends Scope {
public StructDefinition(String name, Scope parentScope) {
private boolean isUnion;
public StructDefinition(String name, boolean isUnion, Scope parentScope) {
super(name, parentScope, SEGMENT_DATA_DEFAULT);
this.isUnion = isUnion;
}
@Override
@ -18,8 +22,13 @@ public class StructDefinition extends Scope {
return new SymbolTypeStruct(this, false, false);
}
public boolean isUnion() {
return isUnion;
}
/**
* Get a struct member variable
*
* @param name The name of the member
* @return The member variable
*/
@ -34,10 +43,13 @@ public class StructDefinition extends Scope {
/**
* Get the number of bytes that the member data is offset from the start of the struct
*
* @param member The member to find offset for
* @return The byte offset of the start of the member data
*/
public long getMemberByteOffset(Variable member, ProgramScope programScope) {
if(isUnion)
return 0;
long byteOffset = 0;
for(Variable structMember : getAllVars(false)) {
if(structMember.equals(member)) {
@ -51,6 +63,10 @@ public class StructDefinition extends Scope {
@Override
public String toString(Program program) {
if(isUnion) {
return "union-" + getFullName();
} else {
return "struct-" + getFullName();
}
}
}

View File

@ -9,20 +9,26 @@ import dk.camelot64.kickc.model.values.ConstantValue;
import java.util.Objects;
/** A struct */
/** A struct/union */
public class SymbolTypeStruct implements SymbolType {
/** Name of the struct type. */
/** Name of the struct/union type. */
private String structName;
/** Size of the struct in bytes. */
/** Size of the struct/union in bytes. */
private int sizeBytes;
/** Is this a union */
private final boolean isUnion;
/** Volatile type qualifier. */
private final boolean isVolatile;
/** Const type qualifier. */
private final boolean isNomodify;
public SymbolTypeStruct(String structName, int sizeBytes, boolean isVolatile, boolean isNomodify) {
public SymbolTypeStruct(String structName, boolean isUnion, int sizeBytes, boolean isVolatile, boolean isNomodify) {
this.structName = structName;
this.isUnion = isUnion;
this.sizeBytes = sizeBytes;
this.isVolatile = isVolatile;
this.isNomodify = isNomodify;
@ -30,6 +36,7 @@ public class SymbolTypeStruct implements SymbolType {
public SymbolTypeStruct(StructDefinition structDefinition, boolean isVolatile, boolean isNomodify) {
this.structName = structDefinition.getLocalName();
this.isUnion = structDefinition.isUnion();
this.sizeBytes = calculateSizeBytes(structDefinition, null);
this.isVolatile = isVolatile;
this.isNomodify = isNomodify;
@ -37,7 +44,11 @@ public class SymbolTypeStruct implements SymbolType {
@Override
public SymbolType getQualified(boolean isVolatile, boolean isNomodify) {
return new SymbolTypeStruct(this.structName, this.sizeBytes, isVolatile, isNomodify);
return new SymbolTypeStruct(this.structName, isUnion, this.sizeBytes, isVolatile, isNomodify);
}
public boolean isUnion() {
return isUnion;
}
@Override
@ -52,8 +63,12 @@ public class SymbolTypeStruct implements SymbolType {
@Override
public String getTypeBaseName() {
if(isUnion) {
return "union " + this.structName;
} else {
return "struct " + this.structName;
}
}
public String getStructTypeName() {
return structName;
@ -80,11 +95,19 @@ public class SymbolTypeStruct implements SymbolType {
*/
public int calculateSizeBytes(StructDefinition structDefinition, ProgramScope programScope) {
int sizeBytes = 0;
if(isUnion) {
for(Variable member : structDefinition.getAllVars(false)) {
SymbolType memberType = member.getType();
int memberSize = getMemberSizeBytes(memberType, member.getArraySize(), programScope);
sizeBytes = Math.max(sizeBytes, memberSize);
}
} else {
for(Variable member : structDefinition.getAllVars(false)) {
SymbolType memberType = member.getType();
int memberSize = getMemberSizeBytes(memberType, member.getArraySize(), programScope);
sizeBytes += memberSize;
}
}
return sizeBytes;
}
@ -110,12 +133,13 @@ public class SymbolTypeStruct implements SymbolType {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
SymbolTypeStruct that = (SymbolTypeStruct) o;
return Objects.equals(structName, that.structName);
return isUnion == that.isUnion &&
structName.equals(that.structName);
}
@Override
public int hashCode() {
return Objects.hash(structName, sizeBytes);
return Objects.hash(structName, isUnion);
}
@Override

View File

@ -92,6 +92,7 @@ ASM: 'asm' { asmEnter=true; };
DEFAULT : 'default' ;
CASE : 'case' ;
STRUCT : 'struct' ;
UNION : 'union' ;
ENUM : 'enum' ;
SIZEOF : 'sizeof' ;
TYPEID : 'typeid' ;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -67,91 +67,92 @@ ASM=66
DEFAULT=67
CASE=68
STRUCT=69
ENUM=70
SIZEOF=71
TYPEID=72
DEFINED=73
KICKASM=74
RESOURCE=75
USES=76
CLOBBERS=77
BYTES=78
CYCLES=79
LOGIC_NOT=80
SIGNEDNESS=81
SIMPLETYPE=82
BOOLEAN=83
KICKASM_BODY=84
IMPORT=85
INCLUDE=86
PRAGMA=87
DEFINE=88
DEFINE_CONTINUE=89
UNDEF=90
IFDEF=91
IFNDEF=92
IFIF=93
ELIF=94
IFELSE=95
ENDIF=96
ERROR=97
NUMBER=98
NUMFLOAT=99
BINFLOAT=100
DECFLOAT=101
HEXFLOAT=102
NUMINT=103
BININTEGER=104
DECINTEGER=105
HEXINTEGER=106
NAME=107
STRING=108
CHAR=109
WS=110
COMMENT_LINE=111
COMMENT_BLOCK=112
ASM_BYTE=113
ASM_MNEMONIC=114
ASM_IMM=115
ASM_COLON=116
ASM_COMMA=117
ASM_PAR_BEGIN=118
ASM_PAR_END=119
ASM_BRACKET_BEGIN=120
ASM_BRACKET_END=121
ASM_DOT=122
ASM_SHIFT_LEFT=123
ASM_SHIFT_RIGHT=124
ASM_PLUS=125
ASM_MINUS=126
ASM_LESS_THAN=127
ASM_GREATER_THAN=128
ASM_MULTIPLY=129
ASM_DIVIDE=130
ASM_CURLY_BEGIN=131
ASM_CURLY_END=132
ASM_NUMBER=133
ASM_NUMFLOAT=134
ASM_BINFLOAT=135
ASM_DECFLOAT=136
ASM_HEXFLOAT=137
ASM_NUMINT=138
ASM_BININTEGER=139
ASM_DECINTEGER=140
ASM_HEXINTEGER=141
ASM_CHAR=142
ASM_MULTI_REL=143
ASM_MULTI_NAME=144
ASM_NAME=145
ASM_TAG=146
ASM_WS=147
ASM_COMMENT_LINE=148
ASM_COMMENT_BLOCK=149
IMPORT_SYSTEMFILE=150
IMPORT_LOCALFILE=151
IMPORT_WS=152
IMPORT_COMMENT_LINE=153
IMPORT_COMMENT_BLOCK=154
UNION=70
ENUM=71
SIZEOF=72
TYPEID=73
DEFINED=74
KICKASM=75
RESOURCE=76
USES=77
CLOBBERS=78
BYTES=79
CYCLES=80
LOGIC_NOT=81
SIGNEDNESS=82
SIMPLETYPE=83
BOOLEAN=84
KICKASM_BODY=85
IMPORT=86
INCLUDE=87
PRAGMA=88
DEFINE=89
DEFINE_CONTINUE=90
UNDEF=91
IFDEF=92
IFNDEF=93
IFIF=94
ELIF=95
IFELSE=96
ENDIF=97
ERROR=98
NUMBER=99
NUMFLOAT=100
BINFLOAT=101
DECFLOAT=102
HEXFLOAT=103
NUMINT=104
BININTEGER=105
DECINTEGER=106
HEXINTEGER=107
NAME=108
STRING=109
CHAR=110
WS=111
COMMENT_LINE=112
COMMENT_BLOCK=113
ASM_BYTE=114
ASM_MNEMONIC=115
ASM_IMM=116
ASM_COLON=117
ASM_COMMA=118
ASM_PAR_BEGIN=119
ASM_PAR_END=120
ASM_BRACKET_BEGIN=121
ASM_BRACKET_END=122
ASM_DOT=123
ASM_SHIFT_LEFT=124
ASM_SHIFT_RIGHT=125
ASM_PLUS=126
ASM_MINUS=127
ASM_LESS_THAN=128
ASM_GREATER_THAN=129
ASM_MULTIPLY=130
ASM_DIVIDE=131
ASM_CURLY_BEGIN=132
ASM_CURLY_END=133
ASM_NUMBER=134
ASM_NUMFLOAT=135
ASM_BINFLOAT=136
ASM_DECFLOAT=137
ASM_HEXFLOAT=138
ASM_NUMINT=139
ASM_BININTEGER=140
ASM_DECINTEGER=141
ASM_HEXINTEGER=142
ASM_CHAR=143
ASM_MULTI_REL=144
ASM_MULTI_NAME=145
ASM_NAME=146
ASM_TAG=147
ASM_WS=148
ASM_COMMENT_LINE=149
ASM_COMMENT_BLOCK=150
IMPORT_SYSTEMFILE=151
IMPORT_LOCALFILE=152
IMPORT_WS=153
IMPORT_COMMENT_LINE=154
IMPORT_COMMENT_BLOCK=155
';'=8
'..'=11
'...'=12
@ -201,28 +202,29 @@ IMPORT_COMMENT_BLOCK=154
'default'=67
'case'=68
'struct'=69
'enum'=70
'sizeof'=71
'typeid'=72
'defined'=73
'kickasm'=74
'resource'=75
'uses'=76
'clobbers'=77
'bytes'=78
'cycles'=79
'!'=80
'#import'=85
'#include'=86
'#pragma'=87
'#define'=88
'#undef'=90
'#ifdef'=91
'#ifndef'=92
'#if'=93
'#elif'=94
'#else'=95
'#endif'=96
'#error'=97
'.byte'=113
'#'=115
'union'=70
'enum'=71
'sizeof'=72
'typeid'=73
'defined'=74
'kickasm'=75
'resource'=76
'uses'=77
'clobbers'=78
'bytes'=79
'cycles'=80
'!'=81
'#import'=86
'#include'=87
'#pragma'=88
'#define'=89
'#undef'=91
'#ifdef'=92
'#ifndef'=93
'#if'=94
'#elif'=95
'#else'=96
'#endif'=97
'#error'=98
'.byte'=114
'#'=116

View File

@ -95,11 +95,11 @@ type
;
structRef
: STRUCT NAME
: (STRUCT|UNION) NAME
;
structDef
: STRUCT NAME? CURLY_BEGIN structMembers+ CURLY_END
: (STRUCT|UNION) NAME? CURLY_BEGIN structMembers+ CURLY_END
;
structMembers

File diff suppressed because one or more lines are too long

View File

@ -30,24 +30,24 @@ public class KickCParser extends Parser {
ADDRESS=50, ADDRESS_ZEROPAGE=51, ADDRESS_MAINMEM=52, FORM_SSA=53, FORM_MA=54,
INTRINSIC=55, CALLINGCONVENTION=56, IF=57, ELSE=58, WHILE=59, DO=60, FOR=61,
SWITCH=62, RETURN=63, BREAK=64, CONTINUE=65, ASM=66, DEFAULT=67, CASE=68,
STRUCT=69, ENUM=70, SIZEOF=71, TYPEID=72, DEFINED=73, KICKASM=74, RESOURCE=75,
USES=76, CLOBBERS=77, BYTES=78, CYCLES=79, LOGIC_NOT=80, SIGNEDNESS=81,
SIMPLETYPE=82, BOOLEAN=83, KICKASM_BODY=84, IMPORT=85, INCLUDE=86, PRAGMA=87,
DEFINE=88, DEFINE_CONTINUE=89, UNDEF=90, IFDEF=91, IFNDEF=92, IFIF=93,
ELIF=94, IFELSE=95, ENDIF=96, ERROR=97, NUMBER=98, NUMFLOAT=99, BINFLOAT=100,
DECFLOAT=101, HEXFLOAT=102, NUMINT=103, BININTEGER=104, DECINTEGER=105,
HEXINTEGER=106, NAME=107, STRING=108, CHAR=109, WS=110, COMMENT_LINE=111,
COMMENT_BLOCK=112, ASM_BYTE=113, ASM_MNEMONIC=114, ASM_IMM=115, ASM_COLON=116,
ASM_COMMA=117, ASM_PAR_BEGIN=118, ASM_PAR_END=119, ASM_BRACKET_BEGIN=120,
ASM_BRACKET_END=121, ASM_DOT=122, ASM_SHIFT_LEFT=123, ASM_SHIFT_RIGHT=124,
ASM_PLUS=125, ASM_MINUS=126, ASM_LESS_THAN=127, ASM_GREATER_THAN=128,
ASM_MULTIPLY=129, ASM_DIVIDE=130, ASM_CURLY_BEGIN=131, ASM_CURLY_END=132,
ASM_NUMBER=133, ASM_NUMFLOAT=134, ASM_BINFLOAT=135, ASM_DECFLOAT=136,
ASM_HEXFLOAT=137, ASM_NUMINT=138, ASM_BININTEGER=139, ASM_DECINTEGER=140,
ASM_HEXINTEGER=141, ASM_CHAR=142, ASM_MULTI_REL=143, ASM_MULTI_NAME=144,
ASM_NAME=145, ASM_TAG=146, ASM_WS=147, ASM_COMMENT_LINE=148, ASM_COMMENT_BLOCK=149,
IMPORT_SYSTEMFILE=150, IMPORT_LOCALFILE=151, IMPORT_WS=152, IMPORT_COMMENT_LINE=153,
IMPORT_COMMENT_BLOCK=154;
STRUCT=69, UNION=70, ENUM=71, SIZEOF=72, TYPEID=73, DEFINED=74, KICKASM=75,
RESOURCE=76, USES=77, CLOBBERS=78, BYTES=79, CYCLES=80, LOGIC_NOT=81,
SIGNEDNESS=82, SIMPLETYPE=83, BOOLEAN=84, KICKASM_BODY=85, IMPORT=86,
INCLUDE=87, PRAGMA=88, DEFINE=89, DEFINE_CONTINUE=90, UNDEF=91, IFDEF=92,
IFNDEF=93, IFIF=94, ELIF=95, IFELSE=96, ENDIF=97, ERROR=98, NUMBER=99,
NUMFLOAT=100, BINFLOAT=101, DECFLOAT=102, HEXFLOAT=103, NUMINT=104, BININTEGER=105,
DECINTEGER=106, HEXINTEGER=107, NAME=108, STRING=109, CHAR=110, WS=111,
COMMENT_LINE=112, COMMENT_BLOCK=113, ASM_BYTE=114, ASM_MNEMONIC=115, ASM_IMM=116,
ASM_COLON=117, ASM_COMMA=118, ASM_PAR_BEGIN=119, ASM_PAR_END=120, ASM_BRACKET_BEGIN=121,
ASM_BRACKET_END=122, ASM_DOT=123, ASM_SHIFT_LEFT=124, ASM_SHIFT_RIGHT=125,
ASM_PLUS=126, ASM_MINUS=127, ASM_LESS_THAN=128, ASM_GREATER_THAN=129,
ASM_MULTIPLY=130, ASM_DIVIDE=131, ASM_CURLY_BEGIN=132, ASM_CURLY_END=133,
ASM_NUMBER=134, ASM_NUMFLOAT=135, ASM_BINFLOAT=136, ASM_DECFLOAT=137,
ASM_HEXFLOAT=138, ASM_NUMINT=139, ASM_BININTEGER=140, ASM_DECINTEGER=141,
ASM_HEXINTEGER=142, ASM_CHAR=143, ASM_MULTI_REL=144, ASM_MULTI_NAME=145,
ASM_NAME=146, ASM_TAG=147, ASM_WS=148, ASM_COMMENT_LINE=149, ASM_COMMENT_BLOCK=150,
IMPORT_SYSTEMFILE=151, IMPORT_LOCALFILE=152, IMPORT_WS=153, IMPORT_COMMENT_LINE=154,
IMPORT_COMMENT_BLOCK=155;
public static final int
RULE_file = 0, RULE_asmFile = 1, RULE_declSeq = 2, RULE_decl = 3, RULE_declVariables = 4,
RULE_declaratorInitList = 5, RULE_declaratorInit = 6, RULE_typeDef = 7,
@ -87,9 +87,9 @@ public class KickCParser extends Parser {
"'__interrupt'", "'register'", "'__zp_reserve'", "'__address'", "'__zp'",
"'__mem'", "'__ssa'", "'__ma'", "'__intrinsic'", null, "'if'", "'else'",
"'while'", "'do'", "'for'", "'switch'", "'return'", "'break'", "'continue'",
"'asm'", "'default'", "'case'", "'struct'", "'enum'", "'sizeof'", "'typeid'",
"'defined'", "'kickasm'", "'resource'", "'uses'", "'clobbers'", "'bytes'",
"'cycles'", "'!'", null, null, null, null, "'#import'", "'#include'",
"'asm'", "'default'", "'case'", "'struct'", "'union'", "'enum'", "'sizeof'",
"'typeid'", "'defined'", "'kickasm'", "'resource'", "'uses'", "'clobbers'",
"'bytes'", "'cycles'", "'!'", null, null, null, null, "'#import'", "'#include'",
"'#pragma'", "'#define'", null, "'#undef'", "'#ifdef'", "'#ifndef'",
"'#if'", "'#elif'", "'#else'", "'#endif'", "'#error'", null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
@ -109,11 +109,11 @@ public class KickCParser extends Parser {
"STATIC", "INTERRUPT", "REGISTER", "LOCAL_RESERVE", "ADDRESS", "ADDRESS_ZEROPAGE",
"ADDRESS_MAINMEM", "FORM_SSA", "FORM_MA", "INTRINSIC", "CALLINGCONVENTION",
"IF", "ELSE", "WHILE", "DO", "FOR", "SWITCH", "RETURN", "BREAK", "CONTINUE",
"ASM", "DEFAULT", "CASE", "STRUCT", "ENUM", "SIZEOF", "TYPEID", "DEFINED",
"KICKASM", "RESOURCE", "USES", "CLOBBERS", "BYTES", "CYCLES", "LOGIC_NOT",
"SIGNEDNESS", "SIMPLETYPE", "BOOLEAN", "KICKASM_BODY", "IMPORT", "INCLUDE",
"PRAGMA", "DEFINE", "DEFINE_CONTINUE", "UNDEF", "IFDEF", "IFNDEF", "IFIF",
"ELIF", "IFELSE", "ENDIF", "ERROR", "NUMBER", "NUMFLOAT", "BINFLOAT",
"ASM", "DEFAULT", "CASE", "STRUCT", "UNION", "ENUM", "SIZEOF", "TYPEID",
"DEFINED", "KICKASM", "RESOURCE", "USES", "CLOBBERS", "BYTES", "CYCLES",
"LOGIC_NOT", "SIGNEDNESS", "SIMPLETYPE", "BOOLEAN", "KICKASM_BODY", "IMPORT",
"INCLUDE", "PRAGMA", "DEFINE", "DEFINE_CONTINUE", "UNDEF", "IFDEF", "IFNDEF",
"IFIF", "ELIF", "IFELSE", "ENDIF", "ERROR", "NUMBER", "NUMFLOAT", "BINFLOAT",
"DECFLOAT", "HEXFLOAT", "NUMINT", "BININTEGER", "DECINTEGER", "HEXINTEGER",
"NAME", "STRING", "CHAR", "WS", "COMMENT_LINE", "COMMENT_BLOCK", "ASM_BYTE",
"ASM_MNEMONIC", "ASM_IMM", "ASM_COLON", "ASM_COMMA", "ASM_PAR_BEGIN",
@ -321,7 +321,7 @@ public class KickCParser extends Parser {
setState(101);
_errHandler.sync(this);
_la = _input.LA(1);
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << TYPEDEF) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)) | (1L << (PRAGMA - 69)))) != 0)) {
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << TYPEDEF) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (UNION - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)) | (1L << (PRAGMA - 69)))) != 0)) {
{
{
setState(98);
@ -1092,7 +1092,7 @@ public class KickCParser extends Parser {
setState(184);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << PARAM_LIST) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << PARAM_LIST) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (UNION - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
{
setState(183);
parameterListDecl();
@ -1114,7 +1114,7 @@ public class KickCParser extends Parser {
setState(190);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(189);
expr(0);
@ -1364,7 +1364,7 @@ public class KickCParser extends Parser {
setState(218);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << PARAM_LIST) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << PARAM_LIST) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (UNION - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
{
setState(217);
parameterListDecl();
@ -1386,7 +1386,7 @@ public class KickCParser extends Parser {
setState(224);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(223);
expr(0);
@ -1644,8 +1644,9 @@ public class KickCParser extends Parser {
}
public static class StructRefContext extends ParserRuleContext {
public TerminalNode STRUCT() { return getToken(KickCParser.STRUCT, 0); }
public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); }
public TerminalNode STRUCT() { return getToken(KickCParser.STRUCT, 0); }
public TerminalNode UNION() { return getToken(KickCParser.UNION, 0); }
public StructRefContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@ -1668,11 +1669,20 @@ public class KickCParser extends Parser {
public final StructRefContext structRef() throws RecognitionException {
StructRefContext _localctx = new StructRefContext(_ctx, getState());
enterRule(_localctx, 26, RULE_structRef);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(244);
match(STRUCT);
_la = _input.LA(1);
if ( !(_la==STRUCT || _la==UNION) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(245);
match(NAME);
}
@ -1689,9 +1699,10 @@ public class KickCParser extends Parser {
}
public static class StructDefContext extends ParserRuleContext {
public TerminalNode STRUCT() { return getToken(KickCParser.STRUCT, 0); }
public TerminalNode CURLY_BEGIN() { return getToken(KickCParser.CURLY_BEGIN, 0); }
public TerminalNode CURLY_END() { return getToken(KickCParser.CURLY_END, 0); }
public TerminalNode STRUCT() { return getToken(KickCParser.STRUCT, 0); }
public TerminalNode UNION() { return getToken(KickCParser.UNION, 0); }
public TerminalNode NAME() { return getToken(KickCParser.NAME, 0); }
public List<StructMembersContext> structMembers() {
return getRuleContexts(StructMembersContext.class);
@ -1726,7 +1737,15 @@ public class KickCParser extends Parser {
enterOuterAlt(_localctx, 1);
{
setState(247);
match(STRUCT);
_la = _input.LA(1);
if ( !(_la==STRUCT || _la==UNION) ) {
_errHandler.recoverInline(this);
}
else {
if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
_errHandler.reportMatch(this);
consume();
}
setState(249);
_errHandler.sync(this);
_la = _input.LA(1);
@ -1752,7 +1771,7 @@ public class KickCParser extends Parser {
setState(255);
_errHandler.sync(this);
_la = _input.LA(1);
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0) );
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (UNION - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0) );
setState(257);
match(CURLY_END);
}
@ -2114,7 +2133,7 @@ public class KickCParser extends Parser {
setState(293);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (UNION - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
{
setState(292);
stmtSeq();
@ -3163,7 +3182,7 @@ public class KickCParser extends Parser {
setState(384);
_errHandler.sync(this);
_la = _input.LA(1);
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0) );
} while ( (((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (UNION - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0) );
}
}
catch (RecognitionException re) {
@ -3546,7 +3565,7 @@ public class KickCParser extends Parser {
setState(391);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (UNION - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
{
setState(390);
stmtSeq();
@ -3718,7 +3737,7 @@ public class KickCParser extends Parser {
setState(454);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(453);
commaExpr(0);
@ -3866,7 +3885,7 @@ public class KickCParser extends Parser {
setState(481);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (UNION - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
{
setState(480);
stmtSeq();
@ -3933,7 +3952,7 @@ public class KickCParser extends Parser {
setState(489);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << SEMICOLON) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION) | (1L << IF) | (1L << WHILE) | (1L << DO) | (1L << FOR) | (1L << SWITCH) | (1L << RETURN))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (BREAK - 64)) | (1L << (CONTINUE - 64)) | (1L << (ASM - 64)) | (1L << (STRUCT - 64)) | (1L << (UNION - 64)) | (1L << (ENUM - 64)) | (1L << (SIZEOF - 64)) | (1L << (TYPEID - 64)) | (1L << (DEFINED - 64)) | (1L << (KICKASM - 64)) | (1L << (LOGIC_NOT - 64)) | (1L << (SIGNEDNESS - 64)) | (1L << (SIMPLETYPE - 64)) | (1L << (BOOLEAN - 64)) | (1L << (NUMBER - 64)) | (1L << (NAME - 64)) | (1L << (STRING - 64)) | (1L << (CHAR - 64)))) != 0)) {
{
setState(488);
stmtSeq();
@ -4043,7 +4062,7 @@ public class KickCParser extends Parser {
setState(494);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(493);
forClassicCondition();
@ -4055,7 +4074,7 @@ public class KickCParser extends Parser {
setState(498);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(497);
commaExpr(0);
@ -4173,6 +4192,7 @@ public class KickCParser extends Parser {
case INTRINSIC:
case CALLINGCONVENTION:
case STRUCT:
case UNION:
case ENUM:
case SIGNEDNESS:
case SIMPLETYPE:
@ -4182,7 +4202,7 @@ public class KickCParser extends Parser {
setState(510);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << TYPEDEFNAME) | (1L << CONST) | (1L << EXTERN) | (1L << EXPORT) | (1L << ALIGN) | (1L << INLINE) | (1L << VOLATILE) | (1L << STATIC) | (1L << INTERRUPT) | (1L << REGISTER) | (1L << LOCAL_RESERVE) | (1L << ADDRESS) | (1L << ADDRESS_ZEROPAGE) | (1L << ADDRESS_MAINMEM) | (1L << FORM_SSA) | (1L << FORM_MA) | (1L << INTRINSIC) | (1L << CALLINGCONVENTION))) != 0) || ((((_la - 69)) & ~0x3f) == 0 && ((1L << (_la - 69)) & ((1L << (STRUCT - 69)) | (1L << (UNION - 69)) | (1L << (ENUM - 69)) | (1L << (SIGNEDNESS - 69)) | (1L << (SIMPLETYPE - 69)))) != 0)) {
{
setState(509);
declVariables();
@ -4989,6 +5009,7 @@ public class KickCParser extends Parser {
break;
case TYPEDEFNAME:
case STRUCT:
case UNION:
case ENUM:
case SIGNEDNESS:
case SIMPLETYPE:
@ -5041,6 +5062,7 @@ public class KickCParser extends Parser {
break;
case TYPEDEFNAME:
case STRUCT:
case UNION:
case ENUM:
case SIGNEDNESS:
case SIMPLETYPE:
@ -5493,7 +5515,7 @@ public class KickCParser extends Parser {
setState(641);
_errHandler.sync(this);
_la = _input.LA(1);
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 71)) & ~0x3f) == 0 && ((1L << (_la - 71)) & ((1L << (SIZEOF - 71)) | (1L << (TYPEID - 71)) | (1L << (DEFINED - 71)) | (1L << (LOGIC_NOT - 71)) | (1L << (BOOLEAN - 71)) | (1L << (NUMBER - 71)) | (1L << (NAME - 71)) | (1L << (STRING - 71)) | (1L << (CHAR - 71)))) != 0)) {
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << CURLY_BEGIN) | (1L << PAR_BEGIN) | (1L << PLUS) | (1L << MINUS) | (1L << ASTERISK) | (1L << INC) | (1L << DEC) | (1L << AND) | (1L << BIT_NOT))) != 0) || ((((_la - 72)) & ~0x3f) == 0 && ((1L << (_la - 72)) & ((1L << (SIZEOF - 72)) | (1L << (TYPEID - 72)) | (1L << (DEFINED - 72)) | (1L << (LOGIC_NOT - 72)) | (1L << (BOOLEAN - 72)) | (1L << (NUMBER - 72)) | (1L << (NAME - 72)) | (1L << (STRING - 72)) | (1L << (CHAR - 72)))) != 0)) {
{
setState(640);
parameterList();
@ -5971,7 +5993,7 @@ public class KickCParser extends Parser {
setState(696);
_errHandler.sync(this);
_la = _input.LA(1);
while (((((_la - 113)) & ~0x3f) == 0 && ((1L << (_la - 113)) & ((1L << (ASM_BYTE - 113)) | (1L << (ASM_MNEMONIC - 113)) | (1L << (ASM_MULTI_NAME - 113)) | (1L << (ASM_NAME - 113)))) != 0)) {
while (((((_la - 114)) & ~0x3f) == 0 && ((1L << (_la - 114)) & ((1L << (ASM_BYTE - 114)) | (1L << (ASM_MNEMONIC - 114)) | (1L << (ASM_MULTI_NAME - 114)) | (1L << (ASM_NAME - 114)))) != 0)) {
{
{
setState(693);
@ -6949,7 +6971,7 @@ public class KickCParser extends Parser {
_prevctx = _localctx;
setState(799);
_la = _input.LA(1);
if ( !(((((_la - 125)) & ~0x3f) == 0 && ((1L << (_la - 125)) & ((1L << (ASM_PLUS - 125)) | (1L << (ASM_MINUS - 125)) | (1L << (ASM_LESS_THAN - 125)) | (1L << (ASM_GREATER_THAN - 125)))) != 0)) ) {
if ( !(((((_la - 126)) & ~0x3f) == 0 && ((1L << (_la - 126)) & ((1L << (ASM_PLUS - 126)) | (1L << (ASM_MINUS - 126)) | (1L << (ASM_LESS_THAN - 126)) | (1L << (ASM_GREATER_THAN - 126)))) != 0)) ) {
_errHandler.recoverInline(this);
}
else {
@ -7231,7 +7253,7 @@ public class KickCParser extends Parser {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\u009c\u033e\4\2\t"+
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\u009d\u033e\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
@ -7290,48 +7312,48 @@ public class KickCParser extends Parser {
"/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\5/\u032b\n/\3/\3/\3/\3/\3/\3/\3/\3"+
"/\3/\3/\3/\3/\7/\u0339\n/\f/\16/\u033c\13/\3/\2\t\f\26\30&DF\\\60\2\4"+
"\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNP"+
"RTVXZ\\\2\f\3\2\27\30\5\2\22\23\31\32RR\3\2\35\36\3\2\24\26\3\2\22\23"+
"\3\2\37$\3\2\177\u0082\3\2}~\3\2\u0083\u0084\3\2\177\u0080\2\u03b8\2^"+
"\3\2\2\2\4a\3\2\2\2\6g\3\2\2\2\bx\3\2\2\2\nz\3\2\2\2\f}\3\2\2\2\16\u0091"+
"\3\2\2\2\20\u0093\3\2\2\2\22\u009b\3\2\2\2\24\u00a5\3\2\2\2\26\u00b5\3"+
"\2\2\2\30\u00d7\3\2\2\2\32\u00f4\3\2\2\2\34\u00f6\3\2\2\2\36\u00f9\3\2"+
"\2\2 \u0105\3\2\2\2\"\u0108\3\2\2\2$\u010b\3\2\2\2&\u0113\3\2\2\2(\u011e"+
"\3\2\2\2*\u0123\3\2\2\2,\u012b\3\2\2\2.\u0138\3\2\2\2\60\u013a\3\2\2\2"+
"\62\u014e\3\2\2\2\64\u017d\3\2\2\2\66\u0180\3\2\2\28\u01d9\3\2\2\2:\u01dc"+
"\3\2\2\2<\u01e7\3\2\2\2>\u01fd\3\2\2\2@\u0203\3\2\2\2B\u0205\3\2\2\2D"+
"\u0207\3\2\2\2F\u0251\3\2\2\2H\u0292\3\2\2\2J\u029a\3\2\2\2L\u02a0\3\2"+
"\2\2N\u02b5\3\2\2\2P\u02ba\3\2\2\2R\u02c0\3\2\2\2T\u02d2\3\2\2\2V\u02d4"+
"\3\2\2\2X\u02de\3\2\2\2Z\u031a\3\2\2\2\\\u032a\3\2\2\2^_\5\6\4\2_`\7\2"+
"\2\3`\3\3\2\2\2ab\5P)\2bc\7\2\2\3c\5\3\2\2\2df\5\b\5\2ed\3\2\2\2fi\3\2"+
"\2\2ge\3\2\2\2gh\3\2\2\2h\7\3\2\2\2ig\3\2\2\2jk\5\n\6\2kl\7\n\2\2ly\3"+
"\2\2\2my\5*\26\2no\5\36\20\2op\7\n\2\2py\3\2\2\2qr\5$\23\2rs\7\n\2\2s"+
"y\3\2\2\2ty\5\60\31\2uv\5\20\t\2vw\7\n\2\2wy\3\2\2\2xj\3\2\2\2xm\3\2\2"+
"\2xn\3\2\2\2xq\3\2\2\2xt\3\2\2\2xu\3\2\2\2y\t\3\2\2\2z{\5\22\n\2{|\5\f"+
"\7\2|\13\3\2\2\2}~\b\7\1\2~\177\5\16\b\2\177\u0085\3\2\2\2\u0080\u0081"+
"\f\3\2\2\u0081\u0082\7\f\2\2\u0082\u0084\5\16\b\2\u0083\u0080\3\2\2\2"+
"\u0084\u0087\3\2\2\2\u0085\u0083\3\2\2\2\u0085\u0086\3\2\2\2\u0086\r\3"+
"\2\2\2\u0087\u0085\3\2\2\2\u0088\u008b\5\30\r\2\u0089\u008a\7\'\2\2\u008a"+
"\u008c\5F$\2\u008b\u0089\3\2\2\2\u008b\u008c\3\2\2\2\u008c\u0092\3\2\2"+
"\2\u008d\u008e\5\30\r\2\u008e\u008f\7\'\2\2\u008f\u0090\5J&\2\u0090\u0092"+
"\3\2\2\2\u0091\u0088\3\2\2\2\u0091\u008d\3\2\2\2\u0092\17\3\2\2\2\u0093"+
"\u0094\7)\2\2\u0094\u0095\5\22\n\2\u0095\u0096\b\t\1\2\u0096\u0097\5\30"+
"\r\2\u0097\21\3\2\2\2\u0098\u009a\5\64\33\2\u0099\u0098\3\2\2\2\u009a"+
"\u009d\3\2\2\2\u009b\u0099\3\2\2\2\u009b\u009c\3\2\2\2\u009c\u009e\3\2"+
"\2\2\u009d\u009b\3\2\2\2\u009e\u00a2\5\32\16\2\u009f\u00a1\5\64\33\2\u00a0"+
"\u009f\3\2\2\2\u00a1\u00a4\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a2\u00a3\3\2"+
"\2\2\u00a3\23\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a5\u00a6\5\32\16\2\u00a6"+
"\u00a7\5\26\f\2\u00a7\25\3\2\2\2\u00a8\u00b6\b\f\1\2\u00a9\u00ad\7\24"+
"\2\2\u00aa\u00ac\5\64\33\2\u00ab\u00aa\3\2\2\2\u00ac\u00af\3\2\2\2\u00ad"+
"\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\u00b0\3\2\2\2\u00af\u00ad\3\2"+
"\2\2\u00b0\u00b6\5\26\f\4\u00b1\u00b2\7\b\2\2\u00b2\u00b3\5\26\f\2\u00b3"+
"\u00b4\7\t\2\2\u00b4\u00b6\3\2\2\2\u00b5\u00a8\3\2\2\2\u00b5\u00a9\3\2"+
"\2\2\u00b5\u00b1\3\2\2\2\u00b6\u00c5\3\2\2\2\u00b7\u00b8\f\6\2\2\u00b8"+
"RTVXZ\\\2\r\3\2GH\3\2\27\30\5\2\22\23\31\32SS\3\2\35\36\3\2\24\26\3\2"+
"\22\23\3\2\37$\3\2\u0080\u0083\3\2~\177\3\2\u0084\u0085\3\2\u0080\u0081"+
"\2\u03b8\2^\3\2\2\2\4a\3\2\2\2\6g\3\2\2\2\bx\3\2\2\2\nz\3\2\2\2\f}\3\2"+
"\2\2\16\u0091\3\2\2\2\20\u0093\3\2\2\2\22\u009b\3\2\2\2\24\u00a5\3\2\2"+
"\2\26\u00b5\3\2\2\2\30\u00d7\3\2\2\2\32\u00f4\3\2\2\2\34\u00f6\3\2\2\2"+
"\36\u00f9\3\2\2\2 \u0105\3\2\2\2\"\u0108\3\2\2\2$\u010b\3\2\2\2&\u0113"+
"\3\2\2\2(\u011e\3\2\2\2*\u0123\3\2\2\2,\u012b\3\2\2\2.\u0138\3\2\2\2\60"+
"\u013a\3\2\2\2\62\u014e\3\2\2\2\64\u017d\3\2\2\2\66\u0180\3\2\2\28\u01d9"+
"\3\2\2\2:\u01dc\3\2\2\2<\u01e7\3\2\2\2>\u01fd\3\2\2\2@\u0203\3\2\2\2B"+
"\u0205\3\2\2\2D\u0207\3\2\2\2F\u0251\3\2\2\2H\u0292\3\2\2\2J\u029a\3\2"+
"\2\2L\u02a0\3\2\2\2N\u02b5\3\2\2\2P\u02ba\3\2\2\2R\u02c0\3\2\2\2T\u02d2"+
"\3\2\2\2V\u02d4\3\2\2\2X\u02de\3\2\2\2Z\u031a\3\2\2\2\\\u032a\3\2\2\2"+
"^_\5\6\4\2_`\7\2\2\3`\3\3\2\2\2ab\5P)\2bc\7\2\2\3c\5\3\2\2\2df\5\b\5\2"+
"ed\3\2\2\2fi\3\2\2\2ge\3\2\2\2gh\3\2\2\2h\7\3\2\2\2ig\3\2\2\2jk\5\n\6"+
"\2kl\7\n\2\2ly\3\2\2\2my\5*\26\2no\5\36\20\2op\7\n\2\2py\3\2\2\2qr\5$"+
"\23\2rs\7\n\2\2sy\3\2\2\2ty\5\60\31\2uv\5\20\t\2vw\7\n\2\2wy\3\2\2\2x"+
"j\3\2\2\2xm\3\2\2\2xn\3\2\2\2xq\3\2\2\2xt\3\2\2\2xu\3\2\2\2y\t\3\2\2\2"+
"z{\5\22\n\2{|\5\f\7\2|\13\3\2\2\2}~\b\7\1\2~\177\5\16\b\2\177\u0085\3"+
"\2\2\2\u0080\u0081\f\3\2\2\u0081\u0082\7\f\2\2\u0082\u0084\5\16\b\2\u0083"+
"\u0080\3\2\2\2\u0084\u0087\3\2\2\2\u0085\u0083\3\2\2\2\u0085\u0086\3\2"+
"\2\2\u0086\r\3\2\2\2\u0087\u0085\3\2\2\2\u0088\u008b\5\30\r\2\u0089\u008a"+
"\7\'\2\2\u008a\u008c\5F$\2\u008b\u0089\3\2\2\2\u008b\u008c\3\2\2\2\u008c"+
"\u0092\3\2\2\2\u008d\u008e\5\30\r\2\u008e\u008f\7\'\2\2\u008f\u0090\5"+
"J&\2\u0090\u0092\3\2\2\2\u0091\u0088\3\2\2\2\u0091\u008d\3\2\2\2\u0092"+
"\17\3\2\2\2\u0093\u0094\7)\2\2\u0094\u0095\5\22\n\2\u0095\u0096\b\t\1"+
"\2\u0096\u0097\5\30\r\2\u0097\21\3\2\2\2\u0098\u009a\5\64\33\2\u0099\u0098"+
"\3\2\2\2\u009a\u009d\3\2\2\2\u009b\u0099\3\2\2\2\u009b\u009c\3\2\2\2\u009c"+
"\u009e\3\2\2\2\u009d\u009b\3\2\2\2\u009e\u00a2\5\32\16\2\u009f\u00a1\5"+
"\64\33\2\u00a0\u009f\3\2\2\2\u00a1\u00a4\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a2"+
"\u00a3\3\2\2\2\u00a3\23\3\2\2\2\u00a4\u00a2\3\2\2\2\u00a5\u00a6\5\32\16"+
"\2\u00a6\u00a7\5\26\f\2\u00a7\25\3\2\2\2\u00a8\u00b6\b\f\1\2\u00a9\u00ad"+
"\7\24\2\2\u00aa\u00ac\5\64\33\2\u00ab\u00aa\3\2\2\2\u00ac\u00af\3\2\2"+
"\2\u00ad\u00ab\3\2\2\2\u00ad\u00ae\3\2\2\2\u00ae\u00b0\3\2\2\2\u00af\u00ad"+
"\3\2\2\2\u00b0\u00b6\5\26\f\4\u00b1\u00b2\7\b\2\2\u00b2\u00b3\5\26\f\2"+
"\u00b3\u00b4\7\t\2\2\u00b4\u00b6\3\2\2\2\u00b5\u00a8\3\2\2\2\u00b5\u00a9"+
"\3\2\2\2\u00b5\u00b1\3\2\2\2\u00b6\u00c5\3\2\2\2\u00b7\u00b8\f\6\2\2\u00b8"+
"\u00ba\7\b\2\2\u00b9\u00bb\5,\27\2\u00ba\u00b9\3\2\2\2\u00ba\u00bb\3\2"+
"\2\2\u00bb\u00bc\3\2\2\2\u00bc\u00c4\7\t\2\2\u00bd\u00be\f\5\2\2\u00be"+
"\u00c0\7\6\2\2\u00bf\u00c1\5F$\2\u00c0\u00bf\3\2\2\2\u00c0\u00c1\3\2\2"+
"\2\u00c1\u00c2\3\2\2\2\u00c2\u00c4\7\7\2\2\u00c3\u00b7\3\2\2\2\u00c3\u00bd"+
"\3\2\2\2\u00c4\u00c7\3\2\2\2\u00c5\u00c3\3\2\2\2\u00c5\u00c6\3\2\2\2\u00c6"+
"\27\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00c9\b\r\1\2\u00c9\u00ca\7m\2\2"+
"\27\3\2\2\2\u00c7\u00c5\3\2\2\2\u00c8\u00c9\b\r\1\2\u00c9\u00ca\7n\2\2"+
"\u00ca\u00d8\b\r\1\2\u00cb\u00cf\7\24\2\2\u00cc\u00ce\5\64\33\2\u00cd"+
"\u00cc\3\2\2\2\u00ce\u00d1\3\2\2\2\u00cf\u00cd\3\2\2\2\u00cf\u00d0\3\2"+
"\2\2\u00d0\u00d2\3\2\2\2\u00d1\u00cf\3\2\2\2\u00d2\u00d8\5\30\r\4\u00d3"+
@ -7343,24 +7365,24 @@ public class KickCParser extends Parser {
"$\2\u00e2\u00e1\3\2\2\2\u00e2\u00e3\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4"+
"\u00e6\7\7\2\2\u00e5\u00d9\3\2\2\2\u00e5\u00df\3\2\2\2\u00e6\u00e9\3\2"+
"\2\2\u00e7\u00e5\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\31\3\2\2\2\u00e9\u00e7"+
"\3\2\2\2\u00ea\u00f5\7T\2\2\u00eb\u00ed\7S\2\2\u00ec\u00ee\7T\2\2\u00ed"+
"\3\2\2\2\u00ea\u00f5\7U\2\2\u00eb\u00ed\7T\2\2\u00ec\u00ee\7U\2\2\u00ed"+
"\u00ec\3\2\2\2\u00ed\u00ee\3\2\2\2\u00ee\u00f5\3\2\2\2\u00ef\u00f5\5\36"+
"\20\2\u00f0\u00f5\5\34\17\2\u00f1\u00f5\5$\23\2\u00f2\u00f5\5\"\22\2\u00f3"+
"\u00f5\7\3\2\2\u00f4\u00ea\3\2\2\2\u00f4\u00eb\3\2\2\2\u00f4\u00ef\3\2"+
"\2\2\u00f4\u00f0\3\2\2\2\u00f4\u00f1\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f4"+
"\u00f3\3\2\2\2\u00f5\33\3\2\2\2\u00f6\u00f7\7G\2\2\u00f7\u00f8\7m\2\2"+
"\u00f8\35\3\2\2\2\u00f9\u00fb\7G\2\2\u00fa\u00fc\7m\2\2\u00fb\u00fa\3"+
"\u00f3\3\2\2\2\u00f5\33\3\2\2\2\u00f6\u00f7\t\2\2\2\u00f7\u00f8\7n\2\2"+
"\u00f8\35\3\2\2\2\u00f9\u00fb\t\2\2\2\u00fa\u00fc\7n\2\2\u00fb\u00fa\3"+
"\2\2\2\u00fb\u00fc\3\2\2\2\u00fc\u00fd\3\2\2\2\u00fd\u00ff\7\4\2\2\u00fe"+
"\u0100\5 \21\2\u00ff\u00fe\3\2\2\2\u0100\u0101\3\2\2\2\u0101\u00ff\3\2"+
"\2\2\u0101\u0102\3\2\2\2\u0102\u0103\3\2\2\2\u0103\u0104\7\5\2\2\u0104"+
"\37\3\2\2\2\u0105\u0106\5\n\6\2\u0106\u0107\7\n\2\2\u0107!\3\2\2\2\u0108"+
"\u0109\7H\2\2\u0109\u010a\7m\2\2\u010a#\3\2\2\2\u010b\u010d\7H\2\2\u010c"+
"\u010e\7m\2\2\u010d\u010c\3\2\2\2\u010d\u010e\3\2\2\2\u010e\u010f\3\2"+
"\u0109\7I\2\2\u0109\u010a\7n\2\2\u010a#\3\2\2\2\u010b\u010d\7I\2\2\u010c"+
"\u010e\7n\2\2\u010d\u010c\3\2\2\2\u010d\u010e\3\2\2\2\u010e\u010f\3\2"+
"\2\2\u010f\u0110\7\4\2\2\u0110\u0111\5&\24\2\u0111\u0112\7\5\2\2\u0112"+
"%\3\2\2\2\u0113\u0114\b\24\1\2\u0114\u0115\5(\25\2\u0115\u011b\3\2\2\2"+
"\u0116\u0117\f\3\2\2\u0117\u0118\7\f\2\2\u0118\u011a\5(\25\2\u0119\u0116"+
"\3\2\2\2\u011a\u011d\3\2\2\2\u011b\u0119\3\2\2\2\u011b\u011c\3\2\2\2\u011c"+
"\'\3\2\2\2\u011d\u011b\3\2\2\2\u011e\u0121\7m\2\2\u011f\u0120\7\'\2\2"+
"\'\3\2\2\2\u011d\u011b\3\2\2\2\u011e\u0121\7n\2\2\u011f\u0120\7\'\2\2"+
"\u0120\u0122\5F$\2\u0121\u011f\3\2\2\2\u0121\u0122\3\2\2\2\u0122)\3\2"+
"\2\2\u0123\u0124\5\22\n\2\u0124\u0125\5\30\r\2\u0125\u0127\7\4\2\2\u0126"+
"\u0128\5\66\34\2\u0127\u0126\3\2\2\2\u0127\u0128\3\2\2\2\u0128\u0129\3"+
@ -7369,23 +7391,23 @@ public class KickCParser extends Parser {
"\u012e\3\2\2\2\u0130\u0131\3\2\2\2\u0131-\3\2\2\2\u0132\u0130\3\2\2\2"+
"\u0133\u0134\5\22\n\2\u0134\u0135\5\30\r\2\u0135\u0139\3\2\2\2\u0136\u0139"+
"\5\24\13\2\u0137\u0139\7\16\2\2\u0138\u0133\3\2\2\2\u0138\u0136\3\2\2"+
"\2\u0138\u0137\3\2\2\2\u0139/\3\2\2\2\u013a\u013b\7Y\2\2\u013b\u013c\7"+
"m\2\2\u013c\u013d\7\b\2\2\u013d\u0142\5\62\32\2\u013e\u013f\7\f\2\2\u013f"+
"\2\u0138\u0137\3\2\2\2\u0139/\3\2\2\2\u013a\u013b\7Z\2\2\u013b\u013c\7"+
"n\2\2\u013c\u013d\7\b\2\2\u013d\u0142\5\62\32\2\u013e\u013f\7\f\2\2\u013f"+
"\u0141\5\62\32\2\u0140\u013e\3\2\2\2\u0141\u0144\3\2\2\2\u0142\u0140\3"+
"\2\2\2\u0142\u0143\3\2\2\2\u0143\u0145\3\2\2\2\u0144\u0142\3\2\2\2\u0145"+
"\u0146\7\t\2\2\u0146\61\3\2\2\2\u0147\u014f\7d\2\2\u0148\u0149\7d\2\2"+
"\u0149\u014a\7\r\2\2\u014a\u014f\7d\2\2\u014b\u014f\7m\2\2\u014c\u014f"+
"\7n\2\2\u014d\u014f\7:\2\2\u014e\u0147\3\2\2\2\u014e\u0148\3\2\2\2\u014e"+
"\u0146\7\t\2\2\u0146\61\3\2\2\2\u0147\u014f\7e\2\2\u0148\u0149\7e\2\2"+
"\u0149\u014a\7\r\2\2\u014a\u014f\7e\2\2\u014b\u014f\7n\2\2\u014c\u014f"+
"\7o\2\2\u014d\u014f\7:\2\2\u014e\u0147\3\2\2\2\u014e\u0148\3\2\2\2\u014e"+
"\u014b\3\2\2\2\u014e\u014c\3\2\2\2\u014e\u014d\3\2\2\2\u014f\63\3\2\2"+
"\2\u0150\u017e\7*\2\2\u0151\u0152\7-\2\2\u0152\u0153\7\b\2\2\u0153\u0154"+
"\7d\2\2\u0154\u017e\7\t\2\2\u0155\u0159\7\62\2\2\u0156\u0157\7\b\2\2\u0157"+
"\u0158\7m\2\2\u0158\u015a\7\t\2\2\u0159\u0156\3\2\2\2\u0159\u015a\3\2"+
"\7e\2\2\u0154\u017e\7\t\2\2\u0155\u0159\7\62\2\2\u0156\u0157\7\b\2\2\u0157"+
"\u0158\7n\2\2\u0158\u015a\7\t\2\2\u0159\u0156\3\2\2\2\u0159\u015a\3\2"+
"\2\2\u015a\u017e\3\2\2\2\u015b\u017e\7\65\2\2\u015c\u017e\7\66\2\2\u015d"+
"\u015e\7\64\2\2\u015e\u015f\7\b\2\2\u015f\u0160\5F$\2\u0160\u0161\7\t"+
"\2\2\u0161\u017e\3\2\2\2\u0162\u017e\7/\2\2\u0163\u017e\7\60\2\2\u0164"+
"\u017e\7\67\2\2\u0165\u017e\78\2\2\u0166\u017e\7+\2\2\u0167\u017e\7,\2"+
"\2\u0168\u017e\7.\2\2\u0169\u017e\79\2\2\u016a\u016e\7\61\2\2\u016b\u016c"+
"\7\b\2\2\u016c\u016d\7m\2\2\u016d\u016f\7\t\2\2\u016e\u016b\3\2\2\2\u016e"+
"\7\b\2\2\u016c\u016d\7n\2\2\u016d\u016f\7\t\2\2\u016e\u016b\3\2\2\2\u016e"+
"\u016f\3\2\2\2\u016f\u017e\3\2\2\2\u0170\u0171\7\63\2\2\u0171\u0172\7"+
"\b\2\2\u0172\u0177\5\62\32\2\u0173\u0174\7\f\2\2\u0174\u0176\5\62\32\2"+
"\u0175\u0173\3\2\2\2\u0176\u0179\3\2\2\2\u0177\u0175\3\2\2\2\u0177\u0178"+
@ -7421,7 +7443,7 @@ public class KickCParser extends Parser {
"\3\2\2\2\u01c9\u01ca\3\2\2\2\u01ca\u01da\7\n\2\2\u01cb\u01cc\7B\2\2\u01cc"+
"\u01da\7\n\2\2\u01cd\u01ce\7C\2\2\u01ce\u01da\7\n\2\2\u01cf\u01d1\7D\2"+
"\2\u01d0\u01d2\5L\'\2\u01d1\u01d0\3\2\2\2\u01d1\u01d2\3\2\2\2\u01d2\u01d3"+
"\3\2\2\2\u01d3\u01d4\7\4\2\2\u01d4\u01d5\5P)\2\u01d5\u01d6\7\u0086\2\2"+
"\3\2\2\2\u01d3\u01d4\7\4\2\2\u01d4\u01d5\5P)\2\u01d5\u01d6\7\u0087\2\2"+
"\u01d6\u01da\3\2\2\2\u01d7\u01da\5J&\2\u01d8\u01da\7\n\2\2\u01d9\u0184"+
"\3\2\2\2\u01d9\u0187\3\2\2\2\u01d9\u018c\3\2\2\2\u01d9\u018f\3\2\2\2\u01d9"+
"\u019b\3\2\2\2\u01d9\u01a7\3\2\2\2\u01d9\u01b5\3\2\2\2\u01d9\u01be\3\2"+
@ -7446,32 +7468,32 @@ public class KickCParser extends Parser {
"$\2\u020d\u020a\3\2\2\2\u020e\u0211\3\2\2\2\u020f\u020d\3\2\2\2\u020f"+
"\u0210\3\2\2\2\u0210E\3\2\2\2\u0211\u020f\3\2\2\2\u0212\u0213\b$\1\2\u0213"+
"\u0214\7\b\2\2\u0214\u0215\5D#\2\u0215\u0216\7\t\2\2\u0216\u0252\3\2\2"+
"\2\u0217\u0218\7I\2\2\u0218\u021b\7\b\2\2\u0219\u021c\5F$\2\u021a\u021c"+
"\2\u0217\u0218\7J\2\2\u0218\u021b\7\b\2\2\u0219\u021c\5F$\2\u021a\u021c"+
"\5\24\13\2\u021b\u0219\3\2\2\2\u021b\u021a\3\2\2\2\u021c\u021d\3\2\2\2"+
"\u021d\u021e\7\t\2\2\u021e\u0252\3\2\2\2\u021f\u0220\7J\2\2\u0220\u0223"+
"\u021d\u021e\7\t\2\2\u021e\u0252\3\2\2\2\u021f\u0220\7K\2\2\u0220\u0223"+
"\7\b\2\2\u0221\u0224\5F$\2\u0222\u0224\5\24\13\2\u0223\u0221\3\2\2\2\u0223"+
"\u0222\3\2\2\2\u0224\u0225\3\2\2\2\u0225\u0226\7\t\2\2\u0226\u0252\3\2"+
"\2\2\u0227\u0229\7K\2\2\u0228\u022a\7\b\2\2\u0229\u0228\3\2\2\2\u0229"+
"\u022a\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u022d\7m\2\2\u022c\u022e\7\t"+
"\2\2\u0227\u0229\7L\2\2\u0228\u022a\7\b\2\2\u0229\u0228\3\2\2\2\u0229"+
"\u022a\3\2\2\2\u022a\u022b\3\2\2\2\u022b\u022d\7n\2\2\u022c\u022e\7\t"+
"\2\2\u022d\u022c\3\2\2\2\u022d\u022e\3\2\2\2\u022e\u0252\3\2\2\2\u022f"+
"\u0230\7\b\2\2\u0230\u0231\5\24\13\2\u0231\u0232\7\t\2\2\u0232\u0233\5"+
"F$\31\u0233\u0252\3\2\2\2\u0234\u0235\t\2\2\2\u0235\u0252\5F$\30\u0236"+
"\u0237\7\24\2\2\u0237\u0252\5F$\26\u0238\u0239\t\3\2\2\u0239\u0252\5F"+
"F$\31\u0233\u0252\3\2\2\2\u0234\u0235\t\3\2\2\u0235\u0252\5F$\30\u0236"+
"\u0237\7\24\2\2\u0237\u0252\5F$\26\u0238\u0239\t\4\2\2\u0239\u0252\5F"+
"$\25\u023a\u023b\7\4\2\2\u023b\u0240\5F$\2\u023c\u023d\7\f\2\2\u023d\u023f"+
"\5F$\2\u023e\u023c\3\2\2\2\u023f\u0242\3\2\2\2\u0240\u023e\3\2\2\2\u0240"+
"\u0241\3\2\2\2\u0241\u0244\3\2\2\2\u0242\u0240\3\2\2\2\u0243\u0245\7\f"+
"\2\2\u0244\u0243\3\2\2\2\u0244\u0245\3\2\2\2\u0245\u0246\3\2\2\2\u0246"+
"\u0247\7\5\2\2\u0247\u0252\3\2\2\2\u0248\u0252\7m\2\2\u0249\u0252\7d\2"+
"\2\u024a\u024c\7n\2\2\u024b\u024a\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u024b"+
"\3\2\2\2\u024d\u024e\3\2\2\2\u024e\u0252\3\2\2\2\u024f\u0252\7o\2\2\u0250"+
"\u0252\7U\2\2\u0251\u0212\3\2\2\2\u0251\u0217\3\2\2\2\u0251\u021f\3\2"+
"\u0247\7\5\2\2\u0247\u0252\3\2\2\2\u0248\u0252\7n\2\2\u0249\u0252\7e\2"+
"\2\u024a\u024c\7o\2\2\u024b\u024a\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u024b"+
"\3\2\2\2\u024d\u024e\3\2\2\2\u024e\u0252\3\2\2\2\u024f\u0252\7p\2\2\u0250"+
"\u0252\7V\2\2\u0251\u0212\3\2\2\2\u0251\u0217\3\2\2\2\u0251\u021f\3\2"+
"\2\2\u0251\u0227\3\2\2\2\u0251\u022f\3\2\2\2\u0251\u0234\3\2\2\2\u0251"+
"\u0236\3\2\2\2\u0251\u0238\3\2\2\2\u0251\u023a\3\2\2\2\u0251\u0248\3\2"+
"\2\2\u0251\u0249\3\2\2\2\u0251\u024b\3\2\2\2\u0251\u024f\3\2\2\2\u0251"+
"\u0250\3\2\2\2\u0252\u028f\3\2\2\2\u0253\u0254\f\24\2\2\u0254\u0255\t"+
"\4\2\2\u0255\u028e\5F$\25\u0256\u0257\f\23\2\2\u0257\u0258\t\5\2\2\u0258"+
"\u028e\5F$\24\u0259\u025a\f\22\2\2\u025a\u025b\t\6\2\2\u025b\u028e\5F"+
"$\23\u025c\u025d\f\21\2\2\u025d\u025e\t\7\2\2\u025e\u028e\5F$\22\u025f"+
"\5\2\2\u0255\u028e\5F$\25\u0256\u0257\f\23\2\2\u0257\u0258\t\6\2\2\u0258"+
"\u028e\5F$\24\u0259\u025a\f\22\2\2\u025a\u025b\t\7\2\2\u025b\u028e\5F"+
"$\23\u025c\u025d\f\21\2\2\u025d\u025e\t\b\2\2\u025e\u028e\5F$\22\u025f"+
"\u0260\f\20\2\2\u0260\u0261\7\31\2\2\u0261\u028e\5F$\21\u0262\u0263\f"+
"\17\2\2\u0263\u0264\7\33\2\2\u0264\u028e\5F$\20\u0265\u0266\f\16\2\2\u0266"+
"\u0267\7\34\2\2\u0267\u028e\5F$\17\u0268\u0269\f\r\2\2\u0269\u026a\7%"+
@ -7480,12 +7502,12 @@ public class KickCParser extends Parser {
"\u0272\7\13\2\2\u0272\u0273\5F$\f\u0273\u028e\3\2\2\2\u0274\u0275\f\n"+
"\2\2\u0275\u0276\7\'\2\2\u0276\u028e\5F$\n\u0277\u0278\f\t\2\2\u0278\u0279"+
"\7(\2\2\u0279\u028e\5F$\t\u027a\u027b\f \2\2\u027b\u027c\7\20\2\2\u027c"+
"\u028e\7m\2\2\u027d\u027e\f\37\2\2\u027e\u027f\7\21\2\2\u027f\u028e\7"+
"m\2\2\u0280\u0281\f\36\2\2\u0281\u0283\7\b\2\2\u0282\u0284\5H%\2\u0283"+
"\u028e\7n\2\2\u027d\u027e\f\37\2\2\u027e\u027f\7\21\2\2\u027f\u028e\7"+
"n\2\2\u0280\u0281\f\36\2\2\u0281\u0283\7\b\2\2\u0282\u0284\5H%\2\u0283"+
"\u0282\3\2\2\2\u0283\u0284\3\2\2\2\u0284\u0285\3\2\2\2\u0285\u028e\7\t"+
"\2\2\u0286\u0287\f\32\2\2\u0287\u0288\7\6\2\2\u0288\u0289\5D#\2\u0289"+
"\u028a\7\7\2\2\u028a\u028e\3\2\2\2\u028b\u028c\f\27\2\2\u028c\u028e\t"+
"\2\2\2\u028d\u0253\3\2\2\2\u028d\u0256\3\2\2\2\u028d\u0259\3\2\2\2\u028d"+
"\3\2\2\u028d\u0253\3\2\2\2\u028d\u0256\3\2\2\2\u028d\u0259\3\2\2\2\u028d"+
"\u025c\3\2\2\2\u028d\u025f\3\2\2\2\u028d\u0262\3\2\2\2\u028d\u0265\3\2"+
"\2\2\u028d\u0268\3\2\2\2\u028d\u026b\3\2\2\2\u028d\u026e\3\2\2\2\u028d"+
"\u0274\3\2\2\2\u028d\u0277\3\2\2\2\u028d\u027a\3\2\2\2\u028d\u027d\3\2"+
@ -7493,59 +7515,59 @@ public class KickCParser extends Parser {
"\u0291\3\2\2\2\u028f\u028d\3\2\2\2\u028f\u0290\3\2\2\2\u0290G\3\2\2\2"+
"\u0291\u028f\3\2\2\2\u0292\u0297\5F$\2\u0293\u0294\7\f\2\2\u0294\u0296"+
"\5F$\2\u0295\u0293\3\2\2\2\u0296\u0299\3\2\2\2\u0297\u0295\3\2\2\2\u0297"+
"\u0298\3\2\2\2\u0298I\3\2\2\2\u0299\u0297\3\2\2\2\u029a\u029c\7L\2\2\u029b"+
"\u0298\3\2\2\2\u0298I\3\2\2\2\u0299\u0297\3\2\2\2\u029a\u029c\7M\2\2\u029b"+
"\u029d\5L\'\2\u029c\u029b\3\2\2\2\u029c\u029d\3\2\2\2\u029d\u029e\3\2"+
"\2\2\u029e\u029f\7V\2\2\u029fK\3\2\2\2\u02a0\u02a1\7\b\2\2\u02a1\u02a6"+
"\2\2\u029e\u029f\7W\2\2\u029fK\3\2\2\2\u02a0\u02a1\7\b\2\2\u02a1\u02a6"+
"\5N(\2\u02a2\u02a3\7\f\2\2\u02a3\u02a5\5N(\2\u02a4\u02a2\3\2\2\2\u02a5"+
"\u02a8\3\2\2\2\u02a6\u02a4\3\2\2\2\u02a6\u02a7\3\2\2\2\u02a7\u02a9\3\2"+
"\2\2\u02a8\u02a6\3\2\2\2\u02a9\u02aa\7\t\2\2\u02aaM\3\2\2\2\u02ab\u02ac"+
"\7M\2\2\u02ac\u02b6\7n\2\2\u02ad\u02ae\7N\2\2\u02ae\u02b6\7m\2\2\u02af"+
"\u02b0\7O\2\2\u02b0\u02b6\7n\2\2\u02b1\u02b2\7P\2\2\u02b2\u02b6\5F$\2"+
"\u02b3\u02b4\7Q\2\2\u02b4\u02b6\5F$\2\u02b5\u02ab\3\2\2\2\u02b5\u02ad"+
"\7N\2\2\u02ac\u02b6\7o\2\2\u02ad\u02ae\7O\2\2\u02ae\u02b6\7n\2\2\u02af"+
"\u02b0\7P\2\2\u02b0\u02b6\7o\2\2\u02b1\u02b2\7Q\2\2\u02b2\u02b6\5F$\2"+
"\u02b3\u02b4\7R\2\2\u02b4\u02b6\5F$\2\u02b5\u02ab\3\2\2\2\u02b5\u02ad"+
"\3\2\2\2\u02b5\u02af\3\2\2\2\u02b5\u02b1\3\2\2\2\u02b5\u02b3\3\2\2\2\u02b6"+
"O\3\2\2\2\u02b7\u02b9\5R*\2\u02b8\u02b7\3\2\2\2\u02b9\u02bc\3\2\2\2\u02ba"+
"\u02b8\3\2\2\2\u02ba\u02bb\3\2\2\2\u02bbQ\3\2\2\2\u02bc\u02ba\3\2\2\2"+
"\u02bd\u02c1\5T+\2\u02be\u02c1\5V,\2\u02bf\u02c1\5X-\2\u02c0\u02bd\3\2"+
"\2\2\u02c0\u02be\3\2\2\2\u02c0\u02bf\3\2\2\2\u02c1S\3\2\2\2\u02c2\u02c3"+
"\7\u0093\2\2\u02c3\u02c7\7v\2\2\u02c4\u02c6\7\u0094\2\2\u02c5\u02c4\3"+
"\7\u0094\2\2\u02c3\u02c7\7w\2\2\u02c4\u02c6\7\u0095\2\2\u02c5\u02c4\3"+
"\2\2\2\u02c6\u02c9\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c7\u02c8\3\2\2\2\u02c8"+
"\u02d3\3\2\2\2\u02c9\u02c7\3\2\2\2\u02ca\u02cb\7\u0092\2\2\u02cb\u02cf"+
"\7v\2\2\u02cc\u02ce\7\u0094\2\2\u02cd\u02cc\3\2\2\2\u02ce\u02d1\3\2\2"+
"\u02d3\3\2\2\2\u02c9\u02c7\3\2\2\2\u02ca\u02cb\7\u0093\2\2\u02cb\u02cf"+
"\7w\2\2\u02cc\u02ce\7\u0095\2\2\u02cd\u02cc\3\2\2\2\u02ce\u02d1\3\2\2"+
"\2\u02cf\u02cd\3\2\2\2\u02cf\u02d0\3\2\2\2\u02d0\u02d3\3\2\2\2\u02d1\u02cf"+
"\3\2\2\2\u02d2\u02c2\3\2\2\2\u02d2\u02ca\3\2\2\2\u02d3U\3\2\2\2\u02d4"+
"\u02d6\7t\2\2\u02d5\u02d7\5Z.\2\u02d6\u02d5\3\2\2\2\u02d6\u02d7\3\2\2"+
"\2\u02d7\u02db\3\2\2\2\u02d8\u02da\7\u0094\2\2\u02d9\u02d8\3\2\2\2\u02da"+
"\u02d6\7u\2\2\u02d5\u02d7\5Z.\2\u02d6\u02d5\3\2\2\2\u02d6\u02d7\3\2\2"+
"\2\u02d7\u02db\3\2\2\2\u02d8\u02da\7\u0095\2\2\u02d9\u02d8\3\2\2\2\u02da"+
"\u02dd\3\2\2\2\u02db\u02d9\3\2\2\2\u02db\u02dc\3\2\2\2\u02dcW\3\2\2\2"+
"\u02dd\u02db\3\2\2\2\u02de\u02df\7s\2\2\u02df\u02e4\5\\/\2\u02e0\u02e1"+
"\7w\2\2\u02e1\u02e3\5\\/\2\u02e2\u02e0\3\2\2\2\u02e3\u02e6\3\2\2\2\u02e4"+
"\u02dd\u02db\3\2\2\2\u02de\u02df\7t\2\2\u02df\u02e4\5\\/\2\u02e0\u02e1"+
"\7x\2\2\u02e1\u02e3\5\\/\2\u02e2\u02e0\3\2\2\2\u02e3\u02e6\3\2\2\2\u02e4"+
"\u02e2\3\2\2\2\u02e4\u02e5\3\2\2\2\u02e5\u02ea\3\2\2\2\u02e6\u02e4\3\2"+
"\2\2\u02e7\u02e9\7\u0094\2\2\u02e8\u02e7\3\2\2\2\u02e9\u02ec\3\2\2\2\u02ea"+
"\2\2\u02e7\u02e9\7\u0095\2\2\u02e8\u02e7\3\2\2\2\u02e9\u02ec\3\2\2\2\u02ea"+
"\u02e8\3\2\2\2\u02ea\u02eb\3\2\2\2\u02ebY\3\2\2\2\u02ec\u02ea\3\2\2\2"+
"\u02ed\u031b\5\\/\2\u02ee\u02ef\7u\2\2\u02ef\u031b\5\\/\2\u02f0\u02f1"+
"\5\\/\2\u02f1\u02f2\7w\2\2\u02f2\u02f3\5\\/\2\u02f3\u031b\3\2\2\2\u02f4"+
"\u02f5\7x\2\2\u02f5\u02f6\5\\/\2\u02f6\u02f7\7y\2\2\u02f7\u02f8\7w\2\2"+
"\u02f8\u02f9\7\u0093\2\2\u02f9\u031b\3\2\2\2\u02fa\u02fb\7x\2\2\u02fb"+
"\u02fc\7x\2\2\u02fc\u02fd\5\\/\2\u02fd\u02fe\7y\2\2\u02fe\u02ff\7y\2\2"+
"\u02ff\u0300\7w\2\2\u0300\u0301\7\u0093\2\2\u0301\u031b\3\2\2\2\u0302"+
"\u0303\7x\2\2\u0303\u0304\5\\/\2\u0304\u0305\7w\2\2\u0305\u0306\7\u0093"+
"\2\2\u0306\u0307\7y\2\2\u0307\u0308\7w\2\2\u0308\u0309\7\u0093\2\2\u0309"+
"\u031b\3\2\2\2\u030a\u030b\7x\2\2\u030b\u030c\5\\/\2\u030c\u030d\7w\2"+
"\2\u030d\u030e\7\u0093\2\2\u030e\u030f\7y\2\2\u030f\u031b\3\2\2\2\u0310"+
"\u0311\7x\2\2\u0311\u0312\5\\/\2\u0312\u0313\7y\2\2\u0313\u031b\3\2\2"+
"\2\u0314\u0315\7x\2\2\u0315\u0316\7x\2\2\u0316\u0317\5\\/\2\u0317\u0318"+
"\7y\2\2\u0318\u0319\7y\2\2\u0319\u031b\3\2\2\2\u031a\u02ed\3\2\2\2\u031a"+
"\u02ed\u031b\5\\/\2\u02ee\u02ef\7v\2\2\u02ef\u031b\5\\/\2\u02f0\u02f1"+
"\5\\/\2\u02f1\u02f2\7x\2\2\u02f2\u02f3\5\\/\2\u02f3\u031b\3\2\2\2\u02f4"+
"\u02f5\7y\2\2\u02f5\u02f6\5\\/\2\u02f6\u02f7\7z\2\2\u02f7\u02f8\7x\2\2"+
"\u02f8\u02f9\7\u0094\2\2\u02f9\u031b\3\2\2\2\u02fa\u02fb\7y\2\2\u02fb"+
"\u02fc\7y\2\2\u02fc\u02fd\5\\/\2\u02fd\u02fe\7z\2\2\u02fe\u02ff\7z\2\2"+
"\u02ff\u0300\7x\2\2\u0300\u0301\7\u0094\2\2\u0301\u031b\3\2\2\2\u0302"+
"\u0303\7y\2\2\u0303\u0304\5\\/\2\u0304\u0305\7x\2\2\u0305\u0306\7\u0094"+
"\2\2\u0306\u0307\7z\2\2\u0307\u0308\7x\2\2\u0308\u0309\7\u0094\2\2\u0309"+
"\u031b\3\2\2\2\u030a\u030b\7y\2\2\u030b\u030c\5\\/\2\u030c\u030d\7x\2"+
"\2\u030d\u030e\7\u0094\2\2\u030e\u030f\7z\2\2\u030f\u031b\3\2\2\2\u0310"+
"\u0311\7y\2\2\u0311\u0312\5\\/\2\u0312\u0313\7z\2\2\u0313\u031b\3\2\2"+
"\2\u0314\u0315\7y\2\2\u0315\u0316\7y\2\2\u0316\u0317\5\\/\2\u0317\u0318"+
"\7z\2\2\u0318\u0319\7z\2\2\u0319\u031b\3\2\2\2\u031a\u02ed\3\2\2\2\u031a"+
"\u02ee\3\2\2\2\u031a\u02f0\3\2\2\2\u031a\u02f4\3\2\2\2\u031a\u02fa\3\2"+
"\2\2\u031a\u0302\3\2\2\2\u031a\u030a\3\2\2\2\u031a\u0310\3\2\2\2\u031a"+
"\u0314\3\2\2\2\u031b[\3\2\2\2\u031c\u031d\b/\1\2\u031d\u031e\7z\2\2\u031e"+
"\u031f\5\\/\2\u031f\u0320\7{\2\2\u0320\u032b\3\2\2\2\u0321\u0322\t\b\2"+
"\2\u0322\u032b\5\\/\n\u0323\u032b\7\u0093\2\2\u0324\u032b\7\u0091\2\2"+
"\u0325\u0326\7\u0085\2\2\u0326\u0327\7\u0093\2\2\u0327\u032b\7\u0086\2"+
"\2\u0328\u032b\7\u0087\2\2\u0329\u032b\7\u0090\2\2\u032a\u031c\3\2\2\2"+
"\u0314\3\2\2\2\u031b[\3\2\2\2\u031c\u031d\b/\1\2\u031d\u031e\7{\2\2\u031e"+
"\u031f\5\\/\2\u031f\u0320\7|\2\2\u0320\u032b\3\2\2\2\u0321\u0322\t\t\2"+
"\2\u0322\u032b\5\\/\n\u0323\u032b\7\u0094\2\2\u0324\u032b\7\u0092\2\2"+
"\u0325\u0326\7\u0086\2\2\u0326\u0327\7\u0094\2\2\u0327\u032b\7\u0087\2"+
"\2\u0328\u032b\7\u0088\2\2\u0329\u032b\7\u0091\2\2\u032a\u031c\3\2\2\2"+
"\u032a\u0321\3\2\2\2\u032a\u0323\3\2\2\2\u032a\u0324\3\2\2\2\u032a\u0325"+
"\3\2\2\2\u032a\u0328\3\2\2\2\u032a\u0329\3\2\2\2\u032b\u033a\3\2\2\2\u032c"+
"\u032d\f\f\2\2\u032d\u032e\7|\2\2\u032e\u0339\5\\/\r\u032f\u0330\f\13"+
"\2\2\u0330\u0331\t\t\2\2\u0331\u0339\5\\/\f\u0332\u0333\f\t\2\2\u0333"+
"\u0334\t\n\2\2\u0334\u0339\5\\/\n\u0335\u0336\f\b\2\2\u0336\u0337\t\13"+
"\u032d\f\f\2\2\u032d\u032e\7}\2\2\u032e\u0339\5\\/\r\u032f\u0330\f\13"+
"\2\2\u0330\u0331\t\n\2\2\u0331\u0339\5\\/\f\u0332\u0333\f\t\2\2\u0333"+
"\u0334\t\13\2\2\u0334\u0339\5\\/\n\u0335\u0336\f\b\2\2\u0336\u0337\t\f"+
"\2\2\u0337\u0339\5\\/\t\u0338\u032c\3\2\2\2\u0338\u032f\3\2\2\2\u0338"+
"\u0332\3\2\2\2\u0338\u0335\3\2\2\2\u0339\u033c\3\2\2\2\u033a\u0338\3\2"+
"\2\2\u033a\u033b\3\2\2\2\u033b]\3\2\2\2\u033c\u033a\3\2\2\2Tgx\u0085\u008b"+

View File

@ -67,91 +67,92 @@ ASM=66
DEFAULT=67
CASE=68
STRUCT=69
ENUM=70
SIZEOF=71
TYPEID=72
DEFINED=73
KICKASM=74
RESOURCE=75
USES=76
CLOBBERS=77
BYTES=78
CYCLES=79
LOGIC_NOT=80
SIGNEDNESS=81
SIMPLETYPE=82
BOOLEAN=83
KICKASM_BODY=84
IMPORT=85
INCLUDE=86
PRAGMA=87
DEFINE=88
DEFINE_CONTINUE=89
UNDEF=90
IFDEF=91
IFNDEF=92
IFIF=93
ELIF=94
IFELSE=95
ENDIF=96
ERROR=97
NUMBER=98
NUMFLOAT=99
BINFLOAT=100
DECFLOAT=101
HEXFLOAT=102
NUMINT=103
BININTEGER=104
DECINTEGER=105
HEXINTEGER=106
NAME=107
STRING=108
CHAR=109
WS=110
COMMENT_LINE=111
COMMENT_BLOCK=112
ASM_BYTE=113
ASM_MNEMONIC=114
ASM_IMM=115
ASM_COLON=116
ASM_COMMA=117
ASM_PAR_BEGIN=118
ASM_PAR_END=119
ASM_BRACKET_BEGIN=120
ASM_BRACKET_END=121
ASM_DOT=122
ASM_SHIFT_LEFT=123
ASM_SHIFT_RIGHT=124
ASM_PLUS=125
ASM_MINUS=126
ASM_LESS_THAN=127
ASM_GREATER_THAN=128
ASM_MULTIPLY=129
ASM_DIVIDE=130
ASM_CURLY_BEGIN=131
ASM_CURLY_END=132
ASM_NUMBER=133
ASM_NUMFLOAT=134
ASM_BINFLOAT=135
ASM_DECFLOAT=136
ASM_HEXFLOAT=137
ASM_NUMINT=138
ASM_BININTEGER=139
ASM_DECINTEGER=140
ASM_HEXINTEGER=141
ASM_CHAR=142
ASM_MULTI_REL=143
ASM_MULTI_NAME=144
ASM_NAME=145
ASM_TAG=146
ASM_WS=147
ASM_COMMENT_LINE=148
ASM_COMMENT_BLOCK=149
IMPORT_SYSTEMFILE=150
IMPORT_LOCALFILE=151
IMPORT_WS=152
IMPORT_COMMENT_LINE=153
IMPORT_COMMENT_BLOCK=154
UNION=70
ENUM=71
SIZEOF=72
TYPEID=73
DEFINED=74
KICKASM=75
RESOURCE=76
USES=77
CLOBBERS=78
BYTES=79
CYCLES=80
LOGIC_NOT=81
SIGNEDNESS=82
SIMPLETYPE=83
BOOLEAN=84
KICKASM_BODY=85
IMPORT=86
INCLUDE=87
PRAGMA=88
DEFINE=89
DEFINE_CONTINUE=90
UNDEF=91
IFDEF=92
IFNDEF=93
IFIF=94
ELIF=95
IFELSE=96
ENDIF=97
ERROR=98
NUMBER=99
NUMFLOAT=100
BINFLOAT=101
DECFLOAT=102
HEXFLOAT=103
NUMINT=104
BININTEGER=105
DECINTEGER=106
HEXINTEGER=107
NAME=108
STRING=109
CHAR=110
WS=111
COMMENT_LINE=112
COMMENT_BLOCK=113
ASM_BYTE=114
ASM_MNEMONIC=115
ASM_IMM=116
ASM_COLON=117
ASM_COMMA=118
ASM_PAR_BEGIN=119
ASM_PAR_END=120
ASM_BRACKET_BEGIN=121
ASM_BRACKET_END=122
ASM_DOT=123
ASM_SHIFT_LEFT=124
ASM_SHIFT_RIGHT=125
ASM_PLUS=126
ASM_MINUS=127
ASM_LESS_THAN=128
ASM_GREATER_THAN=129
ASM_MULTIPLY=130
ASM_DIVIDE=131
ASM_CURLY_BEGIN=132
ASM_CURLY_END=133
ASM_NUMBER=134
ASM_NUMFLOAT=135
ASM_BINFLOAT=136
ASM_DECFLOAT=137
ASM_HEXFLOAT=138
ASM_NUMINT=139
ASM_BININTEGER=140
ASM_DECINTEGER=141
ASM_HEXINTEGER=142
ASM_CHAR=143
ASM_MULTI_REL=144
ASM_MULTI_NAME=145
ASM_NAME=146
ASM_TAG=147
ASM_WS=148
ASM_COMMENT_LINE=149
ASM_COMMENT_BLOCK=150
IMPORT_SYSTEMFILE=151
IMPORT_LOCALFILE=152
IMPORT_WS=153
IMPORT_COMMENT_LINE=154
IMPORT_COMMENT_BLOCK=155
';'=8
'..'=11
'...'=12
@ -201,28 +202,29 @@ IMPORT_COMMENT_BLOCK=154
'default'=67
'case'=68
'struct'=69
'enum'=70
'sizeof'=71
'typeid'=72
'defined'=73
'kickasm'=74
'resource'=75
'uses'=76
'clobbers'=77
'bytes'=78
'cycles'=79
'!'=80
'#import'=85
'#include'=86
'#pragma'=87
'#define'=88
'#undef'=90
'#ifdef'=91
'#ifndef'=92
'#if'=93
'#elif'=94
'#else'=95
'#endif'=96
'#error'=97
'.byte'=113
'#'=115
'union'=70
'enum'=71
'sizeof'=72
'typeid'=73
'defined'=74
'kickasm'=75
'resource'=76
'uses'=77
'clobbers'=78
'bytes'=79
'cycles'=80
'!'=81
'#import'=86
'#include'=87
'#pragma'=88
'#define'=89
'#undef'=91
'#ifdef'=92
'#ifndef'=93
'#if'=94
'#elif'=95
'#else'=96
'#endif'=97
'#error'=98
'.byte'=114
'#'=116

View File

@ -1829,13 +1829,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
@Override
public Object visitStructDef(KickCParser.StructDefContext ctx) {
boolean isUnion = ctx.UNION()!=null;
String structDefName;
if(ctx.NAME() != null) {
structDefName = ctx.NAME().getText();
} else {
structDefName = program.getScope().allocateIntermediateVariableName();
}
StructDefinition structDefinition = program.getScope().addStructDefinition(structDefName);
StructDefinition structDefinition = program.getScope().addStructDefinition(structDefName, isUnion);
scopeStack.push(structDefinition);
for(KickCParser.StructMembersContext memberCtx : ctx.structMembers()) {
varDeclPush();

View File

@ -2223,6 +2223,27 @@ public class TestProgramsFast extends TestPrograms {
compileAndCompare("struct-directives.c");
}
@Test
public void testUnion3() throws IOException {
compileAndCompare("union-3.c");
}
@Test
public void testUnion2() throws IOException {
compileAndCompare("union-2.c");
}
@Test
public void testUnion1() throws IOException {
compileAndCompare("union-1.c");
}
@Test
public void testUnion0() throws IOException {
compileAndCompare("union-0.c");
}
@Test
public void testStruct44() throws IOException {
compileAndCompare("struct-44.c");

15
src/test/kc/union-0.c Normal file
View File

@ -0,0 +1,15 @@
// Minimal union with C-Standard behavior
union Data {
char b;
unsigned w;
};
union Data data;
char* const SCREEN = (char*)0x0400;
void main() {
data.w = 1234;
SCREEN[0] = data.b;
}

22
src/test/kc/union-1.c Normal file
View File

@ -0,0 +1,22 @@
// Minimal union with C-Standard behavior - union nested inside struct
union Data {
char b;
unsigned w;
};
struct Jig {
enum Type { BYTE , WORD } type;
union Data data;
};
struct Jig jig;
char* const SCREEN = (char*)0x0400;
void main() {
jig.type = WORD;
jig.data.w = 1234;
SCREEN[0] = jig.type;
SCREEN[0] = jig.data.b;
}

20
src/test/kc/union-2.c Normal file
View File

@ -0,0 +1,20 @@
// Minimal union with C-Standard behavior - union nested inside struct
struct Jig {
enum Type { BYTE , WORD } type;
union Data {
char b;
unsigned w;
} data;
};
struct Jig jig;
char* const SCREEN = (char*)0x0400;
void main() {
jig.type = WORD;
jig.data.w = 0x1234;
SCREEN[0] = jig.type;
SCREEN[1] = jig.data.b;
}

21
src/test/kc/union-3.c Normal file
View File

@ -0,0 +1,21 @@
// Minimal union with C-Standard behavior - array of union
union Data {
char b;
unsigned w;
};
struct Data datas[10];
char* const SCREEN = (char*)0x0400;
void main() {
for(char i=0;i<10;i++) {
datas[i].w = 0x1230+i;
}
for(char i=0;i<10;i++) {
SCREEN[i] = datas[i].b;
}
}

26
src/test/ref/union-0.asm Normal file
View File

@ -0,0 +1,26 @@
// Minimal union with C-Standard behavior
// Commodore 64 PRG executable file
.file [name="union-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const SIZEOF_UNION_DATA = 2
.label SCREEN = $400
.segment Code
main: {
// data.w = 1234
lda #<$4d2
sta data
lda #>$4d2
sta data+1
// SCREEN[0] = data.b
lda data
sta SCREEN
// }
rts
}
.segment Data
data: .fill SIZEOF_UNION_DATA, 0

9
src/test/ref/union-0.cfg Normal file
View File

@ -0,0 +1,9 @@
void main()
main: scope:[main] from
[0] *((word*)&data) = $4d2
[1] *SCREEN = *((byte*)&data)
to:main::@return
main::@return: scope:[main] from main
[2] return
to:@return

184
src/test/ref/union-0.log Normal file
View File

@ -0,0 +1,184 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
*((word*)&data+OFFSET_UNION_DATA_W) = $4d2
SCREEN[0] = *((byte*)&data+OFFSET_UNION_DATA_B)
to:main::@return
main::@return: scope:[main] from main
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
constant byte OFFSET_UNION_DATA_B = 0
constant byte OFFSET_UNION_DATA_W = 0
constant byte* const SCREEN = (byte*)$400
void __start()
union Data data loadstore = {}
void main()
Adding number conversion cast (unumber) $4d2 in *((word*)&data+OFFSET_UNION_DATA_W) = $4d2
Adding number conversion cast (unumber) 0 in SCREEN[0] = *((byte*)&data+OFFSET_UNION_DATA_B)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((word*)&data+OFFSET_UNION_DATA_W) = (unumber)$4d2
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $4d2
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (word) $4d2
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero (word*)&data in [0] *((word*)&data+OFFSET_UNION_DATA_W) = $4d2
Simplifying expression containing zero (byte*)&data in [1] SCREEN[0] = *((byte*)&data+OFFSET_UNION_DATA_B)
Simplifying expression containing zero SCREEN in [1] SCREEN[0] = *((byte*)&data)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant OFFSET_UNION_DATA_W
Eliminating unused constant OFFSET_UNION_DATA_B
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *((word*)&data) = $4d2
[1] *SCREEN = *((byte*)&data)
to:main::@return
main::@return: scope:[main] from main
[2] return
to:@return
VARIABLE REGISTER WEIGHTS
union Data data loadstore = {}
void main()
Initial phi equivalence classes
Added variable data to live range equivalence class [ data ]
Complete equivalence classes
[ data ]
Allocated mem[2] [ data ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((word*)&data) = $4d2 [ data ] ( [ data ] { } ) always clobbers reg byte a
Statement [1] *SCREEN = *((byte*)&data) [ ] ( [ ] { } ) always clobbers reg byte a
Potential registers mem[2] [ data ] : mem[2] ,
REGISTER UPLIFT SCOPES
Uplift Scope [Data]
Uplift Scope [main]
Uplift Scope [] 0: mem[2] [ data ]
Uplifting [Data] best 29 combination
Uplifting [main] best 29 combination
Uplifting [] best 29 combination mem[2] [ data ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Minimal union with C-Standard behavior
// Upstart
// Commodore 64 PRG executable file
.file [name="union-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const SIZEOF_UNION_DATA = 2
.label SCREEN = $400
.segment Code
// main
main: {
// [0] *((word*)&data) = $4d2 -- _deref_pwuc1=vwuc2
lda #<$4d2
sta data
lda #>$4d2
sta data+1
// [1] *SCREEN = *((byte*)&data) -- _deref_pbuc1=_deref_pbuc2
lda data
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [2] return
rts
}
// File Data
.segment Data
data: .fill SIZEOF_UNION_DATA, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_UNION_DATA = 2
union Data data loadstore mem[2] = {}
void main()
mem[2] [ data ]
FINAL ASSEMBLER
Score: 26
// File Comments
// Minimal union with C-Standard behavior
// Upstart
// Commodore 64 PRG executable file
.file [name="union-0.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const SIZEOF_UNION_DATA = 2
.label SCREEN = $400
.segment Code
// main
main: {
// data.w = 1234
// [0] *((word*)&data) = $4d2 -- _deref_pwuc1=vwuc2
lda #<$4d2
sta data
lda #>$4d2
sta data+1
// SCREEN[0] = data.b
// [1] *SCREEN = *((byte*)&data) -- _deref_pbuc1=_deref_pbuc2
lda data
sta SCREEN
// main::@return
// }
// [2] return
rts
}
// File Data
.segment Data
data: .fill SIZEOF_UNION_DATA, 0

6
src/test/ref/union-0.sym Normal file
View File

@ -0,0 +1,6 @@
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_UNION_DATA = 2
union Data data loadstore mem[2] = {}
void main()
mem[2] [ data ]

34
src/test/ref/union-1.asm Normal file
View File

@ -0,0 +1,34 @@
// Minimal union with C-Standard behavior - union nested inside struct
// Commodore 64 PRG executable file
.file [name="union-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
main: {
// jig.type = WORD
lda #WORD
sta jig
// jig.data.w = 1234
lda #<$4d2
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$4d2
sta jig+OFFSET_STRUCT_JIG_DATA+1
// SCREEN[0] = jig.type
lda jig
sta SCREEN
// SCREEN[0] = jig.data.b
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN
// }
rts
}
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0

11
src/test/ref/union-1.cfg Normal file
View File

@ -0,0 +1,11 @@
void main()
main: scope:[main] from
[0] *((byte*)&jig) = WORD
[1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $4d2
[2] *SCREEN = *((byte*)&jig)
[3] *SCREEN = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA)
to:main::@return
main::@return: scope:[main] from main
[4] return
to:@return

224
src/test/ref/union-1.log Normal file
View File

@ -0,0 +1,224 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
*((byte*)&jig+OFFSET_STRUCT_JIG_TYPE) = WORD
*((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $4d2
SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
SCREEN[0] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
to:main::@return
main::@return: scope:[main] from main
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte OFFSET_STRUCT_JIG_TYPE = 0
constant byte OFFSET_UNION_DATA_B = 0
constant byte OFFSET_UNION_DATA_W = 0
constant byte* const SCREEN = (byte*)$400
constant byte WORD = 1
void __start()
struct Jig jig loadstore = {}
void main()
Adding number conversion cast (unumber) $4d2 in *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $4d2
Adding number conversion cast (unumber) 0 in SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
Adding number conversion cast (unumber) 0 in SCREEN[0] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = (unumber)$4d2
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $4d2
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (word) $4d2
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero (byte*)&jig in [0] *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE) = WORD
Simplifying expression containing zero (word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA in [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $4d2
Simplifying expression containing zero (byte*)&jig in [2] SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
Simplifying expression containing zero SCREEN in [2] SCREEN[0] = *((byte*)&jig)
Simplifying expression containing zero (byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA in [3] SCREEN[0] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
Simplifying expression containing zero SCREEN in [3] SCREEN[0] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant OFFSET_STRUCT_JIG_TYPE
Eliminating unused constant OFFSET_UNION_DATA_W
Eliminating unused constant OFFSET_UNION_DATA_B
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *((byte*)&jig) = WORD
[1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $4d2
[2] *SCREEN = *((byte*)&jig)
[3] *SCREEN = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA)
to:main::@return
main::@return: scope:[main] from main
[4] return
to:@return
VARIABLE REGISTER WEIGHTS
struct Jig jig loadstore = {}
void main()
Initial phi equivalence classes
Added variable jig to live range equivalence class [ jig ]
Complete equivalence classes
[ jig ]
Allocated mem[3] [ jig ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&jig) = WORD [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $4d2 [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = *((byte*)&jig) [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [3] *SCREEN = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) [ ] ( [ ] { } ) always clobbers reg byte a
Potential registers mem[3] [ jig ] : mem[3] ,
REGISTER UPLIFT SCOPES
Uplift Scope [Data]
Uplift Scope [Jig]
Uplift Scope [Jig::Type]
Uplift Scope [main]
Uplift Scope [] 0: mem[3] [ jig ]
Uplifting [Data] best 43 combination
Uplifting [Jig] best 43 combination
Uplifting [Jig::Type] best 43 combination
Uplifting [main] best 43 combination
Uplifting [] best 43 combination mem[3] [ jig ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Minimal union with C-Standard behavior - union nested inside struct
// Upstart
// Commodore 64 PRG executable file
.file [name="union-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
// main
main: {
// [0] *((byte*)&jig) = WORD -- _deref_pbuc1=vbuc2
lda #WORD
sta jig
// [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $4d2 -- _deref_pwuc1=vwuc2
lda #<$4d2
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$4d2
sta jig+OFFSET_STRUCT_JIG_DATA+1
// [2] *SCREEN = *((byte*)&jig) -- _deref_pbuc1=_deref_pbuc2
lda jig
sta SCREEN
// [3] *SCREEN = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) -- _deref_pbuc1=_deref_pbuc2
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [4] return
rts
}
// File Data
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_STRUCT_JIG = 3
constant byte WORD = 1
struct Jig jig loadstore mem[3] = {}
void main()
mem[3] [ jig ]
FINAL ASSEMBLER
Score: 40
// File Comments
// Minimal union with C-Standard behavior - union nested inside struct
// Upstart
// Commodore 64 PRG executable file
.file [name="union-1.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
// main
main: {
// jig.type = WORD
// [0] *((byte*)&jig) = WORD -- _deref_pbuc1=vbuc2
lda #WORD
sta jig
// jig.data.w = 1234
// [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $4d2 -- _deref_pwuc1=vwuc2
lda #<$4d2
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$4d2
sta jig+OFFSET_STRUCT_JIG_DATA+1
// SCREEN[0] = jig.type
// [2] *SCREEN = *((byte*)&jig) -- _deref_pbuc1=_deref_pbuc2
lda jig
sta SCREEN
// SCREEN[0] = jig.data.b
// [3] *SCREEN = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) -- _deref_pbuc1=_deref_pbuc2
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN
// main::@return
// }
// [4] return
rts
}
// File Data
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0

8
src/test/ref/union-1.sym Normal file
View File

@ -0,0 +1,8 @@
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_STRUCT_JIG = 3
constant byte WORD = 1
struct Jig jig loadstore mem[3] = {}
void main()
mem[3] [ jig ]

34
src/test/ref/union-2.asm Normal file
View File

@ -0,0 +1,34 @@
// Minimal union with C-Standard behavior - union nested inside struct
// Commodore 64 PRG executable file
.file [name="union-2.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
main: {
// jig.type = WORD
lda #WORD
sta jig
// jig.data.w = 0x1234
lda #<$1234
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$1234
sta jig+OFFSET_STRUCT_JIG_DATA+1
// SCREEN[0] = jig.type
lda jig
sta SCREEN
// SCREEN[1] = jig.data.b
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN+1
// }
rts
}
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0

11
src/test/ref/union-2.cfg Normal file
View File

@ -0,0 +1,11 @@
void main()
main: scope:[main] from
[0] *((byte*)&jig) = WORD
[1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $1234
[2] *SCREEN = *((byte*)&jig)
[3] *(SCREEN+1) = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA)
to:main::@return
main::@return: scope:[main] from main
[4] return
to:@return

225
src/test/ref/union-2.log Normal file
View File

@ -0,0 +1,225 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
*((byte*)&jig+OFFSET_STRUCT_JIG_TYPE) = WORD
*((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $1234
SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
SCREEN[1] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
to:main::@return
main::@return: scope:[main] from main
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte OFFSET_STRUCT_JIG_TYPE = 0
constant byte OFFSET_UNION_DATA_B = 0
constant byte OFFSET_UNION_DATA_W = 0
constant byte* const SCREEN = (byte*)$400
constant byte WORD = 1
void __start()
struct Jig jig loadstore = {}
void main()
Adding number conversion cast (unumber) $1234 in *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $1234
Adding number conversion cast (unumber) 0 in SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
Adding number conversion cast (unumber) 1 in SCREEN[1] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = (unumber)$1234
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $1234
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (word) $1234
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero (byte*)&jig in [0] *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE) = WORD
Simplifying expression containing zero (word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA in [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_W) = $1234
Simplifying expression containing zero (byte*)&jig in [2] SCREEN[0] = *((byte*)&jig+OFFSET_STRUCT_JIG_TYPE)
Simplifying expression containing zero SCREEN in [2] SCREEN[0] = *((byte*)&jig)
Simplifying expression containing zero (byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA in [3] SCREEN[1] = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA+OFFSET_UNION_DATA_B)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant OFFSET_STRUCT_JIG_TYPE
Eliminating unused constant OFFSET_UNION_DATA_W
Eliminating unused constant OFFSET_UNION_DATA_B
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *((byte*)&jig) = WORD
[1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $1234
[2] *SCREEN = *((byte*)&jig)
[3] *(SCREEN+1) = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA)
to:main::@return
main::@return: scope:[main] from main
[4] return
to:@return
VARIABLE REGISTER WEIGHTS
struct Jig jig loadstore = {}
void main()
Initial phi equivalence classes
Added variable jig to live range equivalence class [ jig ]
Complete equivalence classes
[ jig ]
Allocated mem[3] [ jig ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&jig) = WORD [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $1234 [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [2] *SCREEN = *((byte*)&jig) [ jig ] ( [ jig ] { } ) always clobbers reg byte a
Statement [3] *(SCREEN+1) = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) [ ] ( [ ] { } ) always clobbers reg byte a
Potential registers mem[3] [ jig ] : mem[3] ,
REGISTER UPLIFT SCOPES
Uplift Scope [Jig]
Uplift Scope [Jig::Type]
Uplift Scope [Data]
Uplift Scope [main]
Uplift Scope [] 0: mem[3] [ jig ]
Uplifting [Jig] best 43 combination
Uplifting [Jig::Type] best 43 combination
Uplifting [Data] best 43 combination
Uplifting [main] best 43 combination
Uplifting [] best 43 combination mem[3] [ jig ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Minimal union with C-Standard behavior - union nested inside struct
// Upstart
// Commodore 64 PRG executable file
.file [name="union-2.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
// main
main: {
// [0] *((byte*)&jig) = WORD -- _deref_pbuc1=vbuc2
lda #WORD
sta jig
// [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $1234 -- _deref_pwuc1=vwuc2
lda #<$1234
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$1234
sta jig+OFFSET_STRUCT_JIG_DATA+1
// [2] *SCREEN = *((byte*)&jig) -- _deref_pbuc1=_deref_pbuc2
lda jig
sta SCREEN
// [3] *(SCREEN+1) = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) -- _deref_pbuc1=_deref_pbuc2
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [4] return
rts
}
// File Data
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_STRUCT_JIG = 3
constant byte WORD = 1
struct Jig jig loadstore mem[3] = {}
void main()
mem[3] [ jig ]
FINAL ASSEMBLER
Score: 40
// File Comments
// Minimal union with C-Standard behavior - union nested inside struct
// Upstart
// Commodore 64 PRG executable file
.file [name="union-2.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.const WORD = 1
.const OFFSET_STRUCT_JIG_DATA = 1
.const SIZEOF_STRUCT_JIG = 3
.label SCREEN = $400
.segment Code
// main
main: {
// jig.type = WORD
// [0] *((byte*)&jig) = WORD -- _deref_pbuc1=vbuc2
lda #WORD
sta jig
// jig.data.w = 0x1234
// [1] *((word*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) = $1234 -- _deref_pwuc1=vwuc2
lda #<$1234
sta jig+OFFSET_STRUCT_JIG_DATA
lda #>$1234
sta jig+OFFSET_STRUCT_JIG_DATA+1
// SCREEN[0] = jig.type
// [2] *SCREEN = *((byte*)&jig) -- _deref_pbuc1=_deref_pbuc2
lda jig
sta SCREEN
// SCREEN[1] = jig.data.b
// [3] *(SCREEN+1) = *((byte*)(union Data*)&jig+OFFSET_STRUCT_JIG_DATA) -- _deref_pbuc1=_deref_pbuc2
lda jig+OFFSET_STRUCT_JIG_DATA
sta SCREEN+1
// main::@return
// }
// [4] return
rts
}
// File Data
.segment Data
jig: .fill SIZEOF_STRUCT_JIG, 0

8
src/test/ref/union-2.sym Normal file
View File

@ -0,0 +1,8 @@
constant byte OFFSET_STRUCT_JIG_DATA = 1
constant byte* const SCREEN = (byte*) 1024
constant byte SIZEOF_STRUCT_JIG = 3
constant byte WORD = 1
struct Jig jig loadstore mem[3] = {}
void main()
mem[3] [ jig ]

58
src/test/ref/union-3.asm Normal file
View File

@ -0,0 +1,58 @@
// Minimal union with C-Standard behavior - array of union
// Commodore 64 PRG executable file
.file [name="union-3.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
.label SCREEN = $400
.segment Code
main: {
.label __1 = 2
ldx #0
__b1:
// for(char i=0;i<10;i++)
cpx #$a
bcc __b2
ldx #0
__b3:
// for(char i=0;i<10;i++)
cpx #$a
bcc __b4
// }
rts
__b4:
// SCREEN[i] = datas[i].b
txa
asl
tay
lda datas,y
sta SCREEN,x
// for(char i=0;i<10;i++)
inx
jmp __b3
__b2:
// 0x1230+i
txa
clc
adc #<$1230
sta.z __1
lda #>$1230
adc #0
sta.z __1+1
// datas[i].w = 0x1230+i
txa
asl
tay
lda.z __1
sta datas,y
lda.z __1+1
sta datas+1,y
// for(char i=0;i<10;i++)
inx
jmp __b1
}
.segment Data
datas: .fill 2*$a, 0

27
src/test/ref/union-3.cfg Normal file
View File

@ -0,0 +1,27 @@
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[1] main::i#2 = phi( main/0, main::@2/main::i#1 )
[2] if(main::i#2<$a) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1 main::@4
[3] main::i1#2 = phi( main::@1/0, main::@4/main::i1#1 )
[4] if(main::i1#2<$a) goto main::@4
to:main::@return
main::@return: scope:[main] from main::@3
[5] return
to:@return
main::@4: scope:[main] from main::@3
[6] main::$4 = main::i1#2 << 1
[7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4]
[8] main::i1#1 = ++ main::i1#2
to:main::@3
main::@2: scope:[main] from main::@1
[9] main::$1 = $1230 + main::i#2
[10] main::$3 = main::i#2 << 1
[11] ((word*)datas)[main::$3] = main::$1
[12] main::i#1 = ++ main::i#2
to:main::@1

432
src/test/ref/union-3.log Normal file
View File

@ -0,0 +1,432 @@
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start
main::i#0 = 0
to:main::@1
main::@1: scope:[main] from main main::@2
main::i#2 = phi( main/main::i#0, main::@2/main::i#1 )
main::$0 = main::i#2 < $a
if(main::$0) goto main::@2
to:main::@3
main::@2: scope:[main] from main::@1
main::i#3 = phi( main::@1/main::i#2 )
main::$1 = $1230 + main::i#3
main::$3 = main::i#3 * SIZEOF_UNION_DATA
((word*)datas+OFFSET_UNION_DATA_W)[main::$3] = main::$1
main::i#1 = ++ main::i#3
to:main::@1
main::@3: scope:[main] from main::@1
main::i1#0 = 0
to:main::@4
main::@4: scope:[main] from main::@3 main::@5
main::i1#2 = phi( main::@3/main::i1#0, main::@5/main::i1#1 )
main::$2 = main::i1#2 < $a
if(main::$2) goto main::@5
to:main::@return
main::@5: scope:[main] from main::@4
main::i1#3 = phi( main::@4/main::i1#2 )
main::$4 = main::i1#3 * SIZEOF_UNION_DATA
SCREEN[main::i1#3] = ((byte*)datas+OFFSET_UNION_DATA_B)[main::$4]
main::i1#1 = ++ main::i1#3
to:main::@4
main::@return: scope:[main] from main::@4
return
to:@return
void __start()
__start: scope:[__start] from
call main
to:__start::@1
__start::@1: scope:[__start] from __start
to:__start::@return
__start::@return: scope:[__start] from __start::@1
return
to:@return
SYMBOL TABLE SSA
constant byte OFFSET_UNION_DATA_B = 0
constant byte OFFSET_UNION_DATA_W = 0
constant byte* const SCREEN = (byte*)$400
constant byte SIZEOF_UNION_DATA = 2
void __start()
constant union Data* datas[$a] = { fill( $a, 0) }
void main()
bool~ main::$0
number~ main::$1
bool~ main::$2
byte~ main::$3
byte~ main::$4
byte main::i
byte main::i#0
byte main::i#1
byte main::i#2
byte main::i#3
byte main::i1
byte main::i1#0
byte main::i1#1
byte main::i1#2
byte main::i1#3
Adding number conversion cast (unumber) $a in main::$0 = main::i#2 < $a
Adding number conversion cast (unumber) $1230 in main::$1 = $1230 + main::i#3
Adding number conversion cast (unumber) main::$1 in main::$1 = (unumber)$1230 + main::i#3
Adding number conversion cast (unumber) $a in main::$2 = main::i1#2 < $a
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $a
Simplifying constant integer cast $1230
Simplifying constant integer cast $a
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $a
Finalized unsigned number type (word) $1230
Finalized unsigned number type (byte) $a
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to word in main::$1 = $1230 + main::i#3
Alias main::i#2 = main::i#3
Alias main::i1#2 = main::i1#3
Successful SSA optimization Pass2AliasElimination
Simple Condition main::$0 [3] if(main::i#2<$a) goto main::@2
Simple Condition main::$2 [11] if(main::i1#2<$a) goto main::@5
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::i#0 = 0
Constant main::i1#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (word*)datas in [6] ((word*)datas+OFFSET_UNION_DATA_W)[main::$3] = main::$1
Simplifying expression containing zero (byte*)datas in [13] SCREEN[main::i1#2] = ((byte*)datas+OFFSET_UNION_DATA_B)[main::$4]
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant OFFSET_UNION_DATA_W
Eliminating unused constant OFFSET_UNION_DATA_B
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Rewriting multiplication to use shift [3] main::$3 = main::i#2 * SIZEOF_UNION_DATA
Rewriting multiplication to use shift [8] main::$4 = main::i1#2 * SIZEOF_UNION_DATA
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings main::i#0
Inlining constant with var siblings main::i1#0
Constant inlined main::i#0 = 0
Constant inlined main::i1#0 = 0
Successful SSA optimization Pass2ConstantInlining
Eliminating unused constant SIZEOF_UNION_DATA
Successful SSA optimization PassNEliminateUnusedVars
Finalized unsigned number type (byte) $a
Finalized unsigned number type (byte) $a
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@3
CALL GRAPH
Created 2 initial phi equivalence classes
Coalesced [10] main::i1#4 = main::i1#1
Coalesced [15] main::i#4 = main::i#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@3
Renumbering block main::@4 to main::@3
Renumbering block main::@5 to main::@4
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
to:main::@1
main::@1: scope:[main] from main main::@2
[1] main::i#2 = phi( main/0, main::@2/main::i#1 )
[2] if(main::i#2<$a) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@1 main::@4
[3] main::i1#2 = phi( main::@1/0, main::@4/main::i1#1 )
[4] if(main::i1#2<$a) goto main::@4
to:main::@return
main::@return: scope:[main] from main::@3
[5] return
to:@return
main::@4: scope:[main] from main::@3
[6] main::$4 = main::i1#2 << 1
[7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4]
[8] main::i1#1 = ++ main::i1#2
to:main::@3
main::@2: scope:[main] from main::@1
[9] main::$1 = $1230 + main::i#2
[10] main::$3 = main::i#2 << 1
[11] ((word*)datas)[main::$3] = main::$1
[12] main::i#1 = ++ main::i#2
to:main::@1
VARIABLE REGISTER WEIGHTS
void main()
word~ main::$1 11.0
byte~ main::$3 22.0
byte~ main::$4 22.0
byte main::i
byte main::i#1 22.0
byte main::i#2 11.0
byte main::i1
byte main::i1#1 22.0
byte main::i1#2 13.75
Initial phi equivalence classes
[ main::i#2 main::i#1 ]
[ main::i1#2 main::i1#1 ]
Added variable main::$4 to live range equivalence class [ main::$4 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable main::$3 to live range equivalence class [ main::$3 ]
Complete equivalence classes
[ main::i#2 main::i#1 ]
[ main::i1#2 main::i1#1 ]
[ main::$4 ]
[ main::$1 ]
[ main::$3 ]
Allocated zp[1]:2 [ main::i#2 main::i#1 ]
Allocated zp[1]:3 [ main::i1#2 main::i1#1 ]
Allocated zp[1]:4 [ main::$4 ]
Allocated zp[2]:5 [ main::$1 ]
Allocated zp[1]:7 [ main::$3 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] main::$4 = main::i1#2 << 1 [ main::i1#2 main::$4 ] ( [ main::i1#2 main::$4 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i1#2 main::i1#1 ]
Statement [7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4] [ main::i1#2 ] ( [ main::i1#2 ] { } ) always clobbers reg byte a
Statement [9] main::$1 = $1230 + main::i#2 [ main::i#2 main::$1 ] ( [ main::i#2 main::$1 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Statement [10] main::$3 = main::i#2 << 1 [ main::i#2 main::$1 main::$3 ] ( [ main::i#2 main::$1 main::$3 ] { } ) always clobbers reg byte a
Statement [11] ((word*)datas)[main::$3] = main::$1 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a
Statement [6] main::$4 = main::i1#2 << 1 [ main::i1#2 main::$4 ] ( [ main::i1#2 main::$4 ] { } ) always clobbers reg byte a
Statement [7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4] [ main::i1#2 ] ( [ main::i1#2 ] { } ) always clobbers reg byte a
Statement [9] main::$1 = $1230 + main::i#2 [ main::i#2 main::$1 ] ( [ main::i#2 main::$1 ] { } ) always clobbers reg byte a
Statement [10] main::$3 = main::i#2 << 1 [ main::i#2 main::$1 main::$3 ] ( [ main::i#2 main::$1 main::$3 ] { } ) always clobbers reg byte a
Statement [11] ((word*)datas)[main::$3] = main::$1 [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ main::i1#2 main::i1#1 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ main::$4 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[2]:5 [ main::$1 ] : zp[2]:5 ,
Potential registers zp[1]:7 [ main::$3 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [main] 35.75: zp[1]:3 [ main::i1#2 main::i1#1 ] 33: zp[1]:2 [ main::i#2 main::i#1 ] 22: zp[1]:4 [ main::$4 ] 22: zp[1]:7 [ main::$3 ] 11: zp[2]:5 [ main::$1 ]
Uplift Scope [Data]
Uplift Scope []
Uplifting [main] best 861 combination reg byte x [ main::i1#2 main::i1#1 ] reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$4 ] reg byte a [ main::$3 ] zp[2]:5 [ main::$1 ]
Limited combination testing to 100 combinations of 144 possible.
Uplifting [Data] best 861 combination
Uplifting [] best 861 combination
Allocated (was zp[2]:5) zp[2]:2 [ main::$1 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Minimal union with C-Standard behavior - array of union
// Upstart
// Commodore 64 PRG executable file
.file [name="union-3.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
.label __1 = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
jmp __b1
// main::@1
__b1:
// [2] if(main::i#2<$a) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #$a
bcc __b2
// [3] phi from main::@1 to main::@3 [phi:main::@1->main::@3]
__b3_from___b1:
// [3] phi main::i1#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1
ldx #0
jmp __b3
// main::@3
__b3:
// [4] if(main::i1#2<$a) goto main::@4 -- vbuxx_lt_vbuc1_then_la1
cpx #$a
bcc __b4
jmp __breturn
// main::@return
__breturn:
// [5] return
rts
// main::@4
__b4:
// [6] main::$4 = main::i1#2 << 1 -- vbuaa=vbuxx_rol_1
txa
asl
// [7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuaa
tay
lda datas,y
sta SCREEN,x
// [8] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx
inx
// [3] phi from main::@4 to main::@3 [phi:main::@4->main::@3]
__b3_from___b4:
// [3] phi main::i1#2 = main::i1#1 [phi:main::@4->main::@3#0] -- register_copy
jmp __b3
// main::@2
__b2:
// [9] main::$1 = $1230 + main::i#2 -- vwuz1=vwuc1_plus_vbuxx
txa
clc
adc #<$1230
sta.z __1
lda #>$1230
adc #0
sta.z __1+1
// [10] main::$3 = main::i#2 << 1 -- vbuaa=vbuxx_rol_1
txa
asl
// [11] ((word*)datas)[main::$3] = main::$1 -- pwuc1_derefidx_vbuaa=vwuz1
tay
lda.z __1
sta datas,y
lda.z __1+1
sta datas+1,y
// [12] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx
inx
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
__b1_from___b2:
// [1] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
}
// File Data
.segment Data
datas: .fill 2*$a, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b3
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from_main:
Removing instruction __b3_from___b1:
Removing instruction __breturn:
Removing instruction __b3_from___b4:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
constant byte* const SCREEN = (byte*) 1024
constant union Data* datas[$a] = { fill( $a, 0) }
void main()
word~ main::$1 zp[2]:2 11.0
byte~ main::$3 reg byte a 22.0
byte~ main::$4 reg byte a 22.0
byte main::i
byte main::i#1 reg byte x 22.0
byte main::i#2 reg byte x 11.0
byte main::i1
byte main::i1#1 reg byte x 22.0
byte main::i1#2 reg byte x 13.75
reg byte x [ main::i#2 main::i#1 ]
reg byte x [ main::i1#2 main::i1#1 ]
reg byte a [ main::$4 ]
zp[2]:2 [ main::$1 ]
reg byte a [ main::$3 ]
FINAL ASSEMBLER
Score: 771
// File Comments
// Minimal union with C-Standard behavior - array of union
// Upstart
// Commodore 64 PRG executable file
.file [name="union-3.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
.label __1 = 2
// [1] phi from main to main::@1 [phi:main->main::@1]
// [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #0
// main::@1
__b1:
// for(char i=0;i<10;i++)
// [2] if(main::i#2<$a) goto main::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #$a
bcc __b2
// [3] phi from main::@1 to main::@3 [phi:main::@1->main::@3]
// [3] phi main::i1#2 = 0 [phi:main::@1->main::@3#0] -- vbuxx=vbuc1
ldx #0
// main::@3
__b3:
// for(char i=0;i<10;i++)
// [4] if(main::i1#2<$a) goto main::@4 -- vbuxx_lt_vbuc1_then_la1
cpx #$a
bcc __b4
// main::@return
// }
// [5] return
rts
// main::@4
__b4:
// SCREEN[i] = datas[i].b
// [6] main::$4 = main::i1#2 << 1 -- vbuaa=vbuxx_rol_1
txa
asl
// [7] SCREEN[main::i1#2] = ((byte*)datas)[main::$4] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuaa
tay
lda datas,y
sta SCREEN,x
// for(char i=0;i<10;i++)
// [8] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx
inx
// [3] phi from main::@4 to main::@3 [phi:main::@4->main::@3]
// [3] phi main::i1#2 = main::i1#1 [phi:main::@4->main::@3#0] -- register_copy
jmp __b3
// main::@2
__b2:
// 0x1230+i
// [9] main::$1 = $1230 + main::i#2 -- vwuz1=vwuc1_plus_vbuxx
txa
clc
adc #<$1230
sta.z __1
lda #>$1230
adc #0
sta.z __1+1
// datas[i].w = 0x1230+i
// [10] main::$3 = main::i#2 << 1 -- vbuaa=vbuxx_rol_1
txa
asl
// [11] ((word*)datas)[main::$3] = main::$1 -- pwuc1_derefidx_vbuaa=vwuz1
tay
lda.z __1
sta datas,y
lda.z __1+1
sta datas+1,y
// for(char i=0;i<10;i++)
// [12] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx
inx
// [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
// [1] phi main::i#2 = main::i#1 [phi:main::@2->main::@1#0] -- register_copy
jmp __b1
}
// File Data
.segment Data
datas: .fill 2*$a, 0

18
src/test/ref/union-3.sym Normal file
View File

@ -0,0 +1,18 @@
constant byte* const SCREEN = (byte*) 1024
constant union Data* datas[$a] = { fill( $a, 0) }
void main()
word~ main::$1 zp[2]:2 11.0
byte~ main::$3 reg byte a 22.0
byte~ main::$4 reg byte a 22.0
byte main::i
byte main::i#1 reg byte x 22.0
byte main::i#2 reg byte x 11.0
byte main::i1
byte main::i1#1 reg byte x 22.0
byte main::i1#2 reg byte x 13.75
reg byte x [ main::i#2 main::i#1 ]
reg byte x [ main::i1#2 main::i1#1 ]
reg byte a [ main::$4 ]
zp[2]:2 [ main::$1 ]
reg byte a [ main::$3 ]