mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-01 13:30:50 +00:00
Recoded #pragma parsing to allow unknown pragmas (as long as they follow the parenthesized syntax). Closes #324
This commit is contained in:
parent
825b277888
commit
56e3553c56
@ -28,6 +28,21 @@ public class CParser {
|
||||
/** The hidden lexer channel containing comments. */
|
||||
public static final int CHANNEL_COMMENTS = 2;
|
||||
|
||||
/** Pragma Names. */
|
||||
public static final String PRAGMA_TARGET = "target";
|
||||
public static final String PRAGMA_CPU = "cpu";
|
||||
public static final String PRAGMA_VAR_MODEL = "var_model";
|
||||
public static final String PRAGMA_LINKSCRIPT = "link";
|
||||
public static final String PRAGMA_EXTENSION = "extension";
|
||||
public static final String PRAGMA_EMULATOR = "emulator";
|
||||
public static final String PRAGMA_ENCODING = "encoding";
|
||||
public static final String PRAGMA_CODE_SEG = "code_seg";
|
||||
public static final String PRAGMA_DATA_SEG = "data_seg";
|
||||
public static final String PRAGMA_PC = "pc";
|
||||
public static final String PRAGMA_CALLING = "calling";
|
||||
public static final String PRAGMA_ZP_RESERVE = "zp_reserve";
|
||||
public static final String PRAGMA_CONSTRUCTOR_FOR = "constructor_for";
|
||||
|
||||
/** The Program. */
|
||||
private Program program;
|
||||
|
||||
|
@ -62,16 +62,6 @@ ASSIGN_COMPOUND : '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '&=' | '|='
|
||||
|
||||
// Keywords
|
||||
TYPEDEF: 'typedef' ;
|
||||
RESERVE: 'zp_reserve' ;
|
||||
PC:'pc';
|
||||
TARGET:'target';
|
||||
LINK:'link';
|
||||
EXTENSION:'extension';
|
||||
EMULATOR:'emulator';
|
||||
CPU:'cpu';
|
||||
CODESEG:'code_seg';
|
||||
DATASEG:'data_seg';
|
||||
ENCODING:'encoding';
|
||||
CONST: 'const' ;
|
||||
EXTERN: 'extern' ;
|
||||
EXPORT: 'export' ;
|
||||
@ -88,10 +78,7 @@ ADDRESS_MAINMEM: '__mem' ;
|
||||
FORM_SSA: '__ssa' ;
|
||||
FORM_MA: '__ma' ;
|
||||
INTRINSIC: '__intrinsic' ;
|
||||
CALLING: 'calling';
|
||||
CALLINGCONVENTION: '__stackcall' | '__phicall' ;
|
||||
VARMODEL: 'var_model';
|
||||
CONSTRUCTORFOR: 'constructor_for';
|
||||
IF: 'if' ;
|
||||
ELSE: 'else' ;
|
||||
WHILE: 'while' ;
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -37,133 +37,120 @@ LOGIC_OR=36
|
||||
ASSIGN=37
|
||||
ASSIGN_COMPOUND=38
|
||||
TYPEDEF=39
|
||||
RESERVE=40
|
||||
PC=41
|
||||
TARGET=42
|
||||
LINK=43
|
||||
EXTENSION=44
|
||||
EMULATOR=45
|
||||
CPU=46
|
||||
CODESEG=47
|
||||
DATASEG=48
|
||||
ENCODING=49
|
||||
CONST=50
|
||||
EXTERN=51
|
||||
EXPORT=52
|
||||
ALIGN=53
|
||||
INLINE=54
|
||||
VOLATILE=55
|
||||
STATIC=56
|
||||
INTERRUPT=57
|
||||
REGISTER=58
|
||||
LOCAL_RESERVE=59
|
||||
ADDRESS=60
|
||||
ADDRESS_ZEROPAGE=61
|
||||
ADDRESS_MAINMEM=62
|
||||
FORM_SSA=63
|
||||
FORM_MA=64
|
||||
INTRINSIC=65
|
||||
CALLING=66
|
||||
CALLINGCONVENTION=67
|
||||
VARMODEL=68
|
||||
CONSTRUCTORFOR=69
|
||||
IF=70
|
||||
ELSE=71
|
||||
WHILE=72
|
||||
DO=73
|
||||
FOR=74
|
||||
SWITCH=75
|
||||
RETURN=76
|
||||
BREAK=77
|
||||
CONTINUE=78
|
||||
ASM=79
|
||||
DEFAULT=80
|
||||
CASE=81
|
||||
STRUCT=82
|
||||
ENUM=83
|
||||
SIZEOF=84
|
||||
TYPEID=85
|
||||
DEFINED=86
|
||||
KICKASM=87
|
||||
RESOURCE=88
|
||||
USES=89
|
||||
CLOBBERS=90
|
||||
BYTES=91
|
||||
CYCLES=92
|
||||
LOGIC_NOT=93
|
||||
SIGNEDNESS=94
|
||||
SIMPLETYPE=95
|
||||
BOOLEAN=96
|
||||
KICKASM_BODY=97
|
||||
IMPORT=98
|
||||
INCLUDE=99
|
||||
PRAGMA=100
|
||||
DEFINE=101
|
||||
DEFINE_CONTINUE=102
|
||||
UNDEF=103
|
||||
IFDEF=104
|
||||
IFNDEF=105
|
||||
IFIF=106
|
||||
ELIF=107
|
||||
IFELSE=108
|
||||
ENDIF=109
|
||||
ERROR=110
|
||||
NUMBER=111
|
||||
NUMFLOAT=112
|
||||
BINFLOAT=113
|
||||
DECFLOAT=114
|
||||
HEXFLOAT=115
|
||||
NUMINT=116
|
||||
BININTEGER=117
|
||||
DECINTEGER=118
|
||||
HEXINTEGER=119
|
||||
NAME=120
|
||||
STRING=121
|
||||
CHAR=122
|
||||
WS=123
|
||||
COMMENT_LINE=124
|
||||
COMMENT_BLOCK=125
|
||||
ASM_BYTE=126
|
||||
ASM_MNEMONIC=127
|
||||
ASM_IMM=128
|
||||
ASM_COLON=129
|
||||
ASM_COMMA=130
|
||||
ASM_PAR_BEGIN=131
|
||||
ASM_PAR_END=132
|
||||
ASM_BRACKET_BEGIN=133
|
||||
ASM_BRACKET_END=134
|
||||
ASM_DOT=135
|
||||
ASM_SHIFT_LEFT=136
|
||||
ASM_SHIFT_RIGHT=137
|
||||
ASM_PLUS=138
|
||||
ASM_MINUS=139
|
||||
ASM_LESS_THAN=140
|
||||
ASM_GREATER_THAN=141
|
||||
ASM_MULTIPLY=142
|
||||
ASM_DIVIDE=143
|
||||
ASM_CURLY_BEGIN=144
|
||||
ASM_CURLY_END=145
|
||||
ASM_NUMBER=146
|
||||
ASM_NUMFLOAT=147
|
||||
ASM_BINFLOAT=148
|
||||
ASM_DECFLOAT=149
|
||||
ASM_HEXFLOAT=150
|
||||
ASM_NUMINT=151
|
||||
ASM_BININTEGER=152
|
||||
ASM_DECINTEGER=153
|
||||
ASM_HEXINTEGER=154
|
||||
ASM_CHAR=155
|
||||
ASM_MULTI_REL=156
|
||||
ASM_MULTI_NAME=157
|
||||
ASM_NAME=158
|
||||
ASM_WS=159
|
||||
ASM_COMMENT_LINE=160
|
||||
ASM_COMMENT_BLOCK=161
|
||||
IMPORT_SYSTEMFILE=162
|
||||
IMPORT_LOCALFILE=163
|
||||
IMPORT_WS=164
|
||||
IMPORT_COMMENT_LINE=165
|
||||
IMPORT_COMMENT_BLOCK=166
|
||||
CONST=40
|
||||
EXTERN=41
|
||||
EXPORT=42
|
||||
ALIGN=43
|
||||
INLINE=44
|
||||
VOLATILE=45
|
||||
STATIC=46
|
||||
INTERRUPT=47
|
||||
REGISTER=48
|
||||
LOCAL_RESERVE=49
|
||||
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_WS=146
|
||||
ASM_COMMENT_LINE=147
|
||||
ASM_COMMENT_BLOCK=148
|
||||
IMPORT_SYSTEMFILE=149
|
||||
IMPORT_LOCALFILE=150
|
||||
IMPORT_WS=151
|
||||
IMPORT_COMMENT_LINE=152
|
||||
IMPORT_COMMENT_BLOCK=153
|
||||
';'=8
|
||||
'..'=11
|
||||
'...'=12
|
||||
@ -184,70 +171,57 @@ IMPORT_COMMENT_BLOCK=166
|
||||
'||'=36
|
||||
'='=37
|
||||
'typedef'=39
|
||||
'zp_reserve'=40
|
||||
'pc'=41
|
||||
'target'=42
|
||||
'link'=43
|
||||
'extension'=44
|
||||
'emulator'=45
|
||||
'cpu'=46
|
||||
'code_seg'=47
|
||||
'data_seg'=48
|
||||
'encoding'=49
|
||||
'const'=50
|
||||
'extern'=51
|
||||
'export'=52
|
||||
'align'=53
|
||||
'inline'=54
|
||||
'volatile'=55
|
||||
'static'=56
|
||||
'interrupt'=57
|
||||
'register'=58
|
||||
'__zp_reserve'=59
|
||||
'__address'=60
|
||||
'__zp'=61
|
||||
'__mem'=62
|
||||
'__ssa'=63
|
||||
'__ma'=64
|
||||
'__intrinsic'=65
|
||||
'calling'=66
|
||||
'var_model'=68
|
||||
'constructor_for'=69
|
||||
'if'=70
|
||||
'else'=71
|
||||
'while'=72
|
||||
'do'=73
|
||||
'for'=74
|
||||
'switch'=75
|
||||
'return'=76
|
||||
'break'=77
|
||||
'continue'=78
|
||||
'asm'=79
|
||||
'default'=80
|
||||
'case'=81
|
||||
'struct'=82
|
||||
'enum'=83
|
||||
'sizeof'=84
|
||||
'typeid'=85
|
||||
'defined'=86
|
||||
'kickasm'=87
|
||||
'resource'=88
|
||||
'uses'=89
|
||||
'clobbers'=90
|
||||
'bytes'=91
|
||||
'cycles'=92
|
||||
'!'=93
|
||||
'#import'=98
|
||||
'#include'=99
|
||||
'#pragma'=100
|
||||
'#define'=101
|
||||
'#undef'=103
|
||||
'#ifdef'=104
|
||||
'#ifndef'=105
|
||||
'#if'=106
|
||||
'#elif'=107
|
||||
'#else'=108
|
||||
'#endif'=109
|
||||
'#error'=110
|
||||
'.byte'=126
|
||||
'#'=128
|
||||
'const'=40
|
||||
'extern'=41
|
||||
'export'=42
|
||||
'align'=43
|
||||
'inline'=44
|
||||
'volatile'=45
|
||||
'static'=46
|
||||
'interrupt'=47
|
||||
'register'=48
|
||||
'__zp_reserve'=49
|
||||
'__address'=50
|
||||
'__zp'=51
|
||||
'__mem'=52
|
||||
'__ssa'=53
|
||||
'__ma'=54
|
||||
'__intrinsic'=55
|
||||
'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
|
||||
'!'=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
|
||||
|
@ -34,7 +34,7 @@ decl
|
||||
| structDef ';'
|
||||
| enumDef ';'
|
||||
| declFunction
|
||||
| globalDirective
|
||||
| pragma
|
||||
| typeDef ';'
|
||||
;
|
||||
|
||||
@ -133,24 +133,16 @@ parameterDecl
|
||||
| PARAM_LIST #parameterDeclList
|
||||
;
|
||||
|
||||
globalDirective
|
||||
: (PRAGMA TARGET) PAR_BEGIN NAME PAR_END #globalDirectivePlatform
|
||||
| (PRAGMA CPU) PAR_BEGIN NAME PAR_END #globalDirectiveCpu
|
||||
| (PRAGMA LINK) PAR_BEGIN STRING PAR_END #globalDirectiveLinkScript
|
||||
| (PRAGMA EXTENSION) PAR_BEGIN STRING PAR_END #globalDirectiveExtension
|
||||
| (PRAGMA EMULATOR) PAR_BEGIN STRING PAR_END #globalDirectiveEmulator
|
||||
| (PRAGMA RESERVE) PAR_BEGIN directiveReserveParam ( COMMA directiveReserveParam )* PAR_END #globalDirectiveReserve
|
||||
| (PRAGMA PC) PAR_BEGIN NUMBER PAR_END #globalDirectivePc
|
||||
| (PRAGMA CODESEG) PAR_BEGIN NAME PAR_END #globalDirectiveCodeSeg
|
||||
| (PRAGMA DATASEG) PAR_BEGIN NAME PAR_END #globalDirectiveDataSeg
|
||||
| (PRAGMA ENCODING) PAR_BEGIN NAME PAR_END #globalDirectiveEncoding
|
||||
| (PRAGMA CALLING) PAR_BEGIN CALLINGCONVENTION PAR_END #globalDirectiveCalling
|
||||
| (PRAGMA VARMODEL) PAR_BEGIN NAME ( COMMA NAME )* PAR_END #globalDirectiveVarModel
|
||||
| (PRAGMA CONSTRUCTORFOR) PAR_BEGIN NAME ( COMMA NAME )* PAR_END #globalDirectiveConstructorFor
|
||||
pragma
|
||||
: PRAGMA NAME PAR_BEGIN pragmaParam (COMMA pragmaParam)* PAR_END
|
||||
;
|
||||
|
||||
directiveReserveParam
|
||||
: NUMBER (RANGE NUMBER)?
|
||||
pragmaParam
|
||||
: NUMBER #pragmaParamNumber
|
||||
| NUMBER RANGE NUMBER #pragmaParamRange
|
||||
| NAME #pragmaParamName
|
||||
| STRING #pragmaParamString
|
||||
| CALLINGCONVENTION #pragmaParamCallingConvention
|
||||
;
|
||||
|
||||
directive
|
||||
@ -169,7 +161,7 @@ directive
|
||||
| INLINE #directiveInline
|
||||
| INTRINSIC #directiveIntrinsic
|
||||
| INTERRUPT ( PAR_BEGIN NAME PAR_END )? #directiveInterrupt
|
||||
| LOCAL_RESERVE PAR_BEGIN directiveReserveParam ( COMMA directiveReserveParam )* PAR_END #directiveReserveZp
|
||||
| LOCAL_RESERVE PAR_BEGIN pragmaParam ( COMMA pragmaParam )* PAR_END #directiveReserveZp
|
||||
| CALLINGCONVENTION #directiveCallingConvention
|
||||
;
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -37,133 +37,120 @@ LOGIC_OR=36
|
||||
ASSIGN=37
|
||||
ASSIGN_COMPOUND=38
|
||||
TYPEDEF=39
|
||||
RESERVE=40
|
||||
PC=41
|
||||
TARGET=42
|
||||
LINK=43
|
||||
EXTENSION=44
|
||||
EMULATOR=45
|
||||
CPU=46
|
||||
CODESEG=47
|
||||
DATASEG=48
|
||||
ENCODING=49
|
||||
CONST=50
|
||||
EXTERN=51
|
||||
EXPORT=52
|
||||
ALIGN=53
|
||||
INLINE=54
|
||||
VOLATILE=55
|
||||
STATIC=56
|
||||
INTERRUPT=57
|
||||
REGISTER=58
|
||||
LOCAL_RESERVE=59
|
||||
ADDRESS=60
|
||||
ADDRESS_ZEROPAGE=61
|
||||
ADDRESS_MAINMEM=62
|
||||
FORM_SSA=63
|
||||
FORM_MA=64
|
||||
INTRINSIC=65
|
||||
CALLING=66
|
||||
CALLINGCONVENTION=67
|
||||
VARMODEL=68
|
||||
CONSTRUCTORFOR=69
|
||||
IF=70
|
||||
ELSE=71
|
||||
WHILE=72
|
||||
DO=73
|
||||
FOR=74
|
||||
SWITCH=75
|
||||
RETURN=76
|
||||
BREAK=77
|
||||
CONTINUE=78
|
||||
ASM=79
|
||||
DEFAULT=80
|
||||
CASE=81
|
||||
STRUCT=82
|
||||
ENUM=83
|
||||
SIZEOF=84
|
||||
TYPEID=85
|
||||
DEFINED=86
|
||||
KICKASM=87
|
||||
RESOURCE=88
|
||||
USES=89
|
||||
CLOBBERS=90
|
||||
BYTES=91
|
||||
CYCLES=92
|
||||
LOGIC_NOT=93
|
||||
SIGNEDNESS=94
|
||||
SIMPLETYPE=95
|
||||
BOOLEAN=96
|
||||
KICKASM_BODY=97
|
||||
IMPORT=98
|
||||
INCLUDE=99
|
||||
PRAGMA=100
|
||||
DEFINE=101
|
||||
DEFINE_CONTINUE=102
|
||||
UNDEF=103
|
||||
IFDEF=104
|
||||
IFNDEF=105
|
||||
IFIF=106
|
||||
ELIF=107
|
||||
IFELSE=108
|
||||
ENDIF=109
|
||||
ERROR=110
|
||||
NUMBER=111
|
||||
NUMFLOAT=112
|
||||
BINFLOAT=113
|
||||
DECFLOAT=114
|
||||
HEXFLOAT=115
|
||||
NUMINT=116
|
||||
BININTEGER=117
|
||||
DECINTEGER=118
|
||||
HEXINTEGER=119
|
||||
NAME=120
|
||||
STRING=121
|
||||
CHAR=122
|
||||
WS=123
|
||||
COMMENT_LINE=124
|
||||
COMMENT_BLOCK=125
|
||||
ASM_BYTE=126
|
||||
ASM_MNEMONIC=127
|
||||
ASM_IMM=128
|
||||
ASM_COLON=129
|
||||
ASM_COMMA=130
|
||||
ASM_PAR_BEGIN=131
|
||||
ASM_PAR_END=132
|
||||
ASM_BRACKET_BEGIN=133
|
||||
ASM_BRACKET_END=134
|
||||
ASM_DOT=135
|
||||
ASM_SHIFT_LEFT=136
|
||||
ASM_SHIFT_RIGHT=137
|
||||
ASM_PLUS=138
|
||||
ASM_MINUS=139
|
||||
ASM_LESS_THAN=140
|
||||
ASM_GREATER_THAN=141
|
||||
ASM_MULTIPLY=142
|
||||
ASM_DIVIDE=143
|
||||
ASM_CURLY_BEGIN=144
|
||||
ASM_CURLY_END=145
|
||||
ASM_NUMBER=146
|
||||
ASM_NUMFLOAT=147
|
||||
ASM_BINFLOAT=148
|
||||
ASM_DECFLOAT=149
|
||||
ASM_HEXFLOAT=150
|
||||
ASM_NUMINT=151
|
||||
ASM_BININTEGER=152
|
||||
ASM_DECINTEGER=153
|
||||
ASM_HEXINTEGER=154
|
||||
ASM_CHAR=155
|
||||
ASM_MULTI_REL=156
|
||||
ASM_MULTI_NAME=157
|
||||
ASM_NAME=158
|
||||
ASM_WS=159
|
||||
ASM_COMMENT_LINE=160
|
||||
ASM_COMMENT_BLOCK=161
|
||||
IMPORT_SYSTEMFILE=162
|
||||
IMPORT_LOCALFILE=163
|
||||
IMPORT_WS=164
|
||||
IMPORT_COMMENT_LINE=165
|
||||
IMPORT_COMMENT_BLOCK=166
|
||||
CONST=40
|
||||
EXTERN=41
|
||||
EXPORT=42
|
||||
ALIGN=43
|
||||
INLINE=44
|
||||
VOLATILE=45
|
||||
STATIC=46
|
||||
INTERRUPT=47
|
||||
REGISTER=48
|
||||
LOCAL_RESERVE=49
|
||||
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_WS=146
|
||||
ASM_COMMENT_LINE=147
|
||||
ASM_COMMENT_BLOCK=148
|
||||
IMPORT_SYSTEMFILE=149
|
||||
IMPORT_LOCALFILE=150
|
||||
IMPORT_WS=151
|
||||
IMPORT_COMMENT_LINE=152
|
||||
IMPORT_COMMENT_BLOCK=153
|
||||
';'=8
|
||||
'..'=11
|
||||
'...'=12
|
||||
@ -184,70 +171,57 @@ IMPORT_COMMENT_BLOCK=166
|
||||
'||'=36
|
||||
'='=37
|
||||
'typedef'=39
|
||||
'zp_reserve'=40
|
||||
'pc'=41
|
||||
'target'=42
|
||||
'link'=43
|
||||
'extension'=44
|
||||
'emulator'=45
|
||||
'cpu'=46
|
||||
'code_seg'=47
|
||||
'data_seg'=48
|
||||
'encoding'=49
|
||||
'const'=50
|
||||
'extern'=51
|
||||
'export'=52
|
||||
'align'=53
|
||||
'inline'=54
|
||||
'volatile'=55
|
||||
'static'=56
|
||||
'interrupt'=57
|
||||
'register'=58
|
||||
'__zp_reserve'=59
|
||||
'__address'=60
|
||||
'__zp'=61
|
||||
'__mem'=62
|
||||
'__ssa'=63
|
||||
'__ma'=64
|
||||
'__intrinsic'=65
|
||||
'calling'=66
|
||||
'var_model'=68
|
||||
'constructor_for'=69
|
||||
'if'=70
|
||||
'else'=71
|
||||
'while'=72
|
||||
'do'=73
|
||||
'for'=74
|
||||
'switch'=75
|
||||
'return'=76
|
||||
'break'=77
|
||||
'continue'=78
|
||||
'asm'=79
|
||||
'default'=80
|
||||
'case'=81
|
||||
'struct'=82
|
||||
'enum'=83
|
||||
'sizeof'=84
|
||||
'typeid'=85
|
||||
'defined'=86
|
||||
'kickasm'=87
|
||||
'resource'=88
|
||||
'uses'=89
|
||||
'clobbers'=90
|
||||
'bytes'=91
|
||||
'cycles'=92
|
||||
'!'=93
|
||||
'#import'=98
|
||||
'#include'=99
|
||||
'#pragma'=100
|
||||
'#define'=101
|
||||
'#undef'=103
|
||||
'#ifdef'=104
|
||||
'#ifndef'=105
|
||||
'#if'=106
|
||||
'#elif'=107
|
||||
'#else'=108
|
||||
'#endif'=109
|
||||
'#error'=110
|
||||
'.byte'=126
|
||||
'#'=128
|
||||
'const'=40
|
||||
'extern'=41
|
||||
'export'=42
|
||||
'align'=43
|
||||
'inline'=44
|
||||
'volatile'=45
|
||||
'static'=46
|
||||
'interrupt'=47
|
||||
'register'=48
|
||||
'__zp_reserve'=49
|
||||
'__address'=50
|
||||
'__zp'=51
|
||||
'__mem'=52
|
||||
'__ssa'=53
|
||||
'__ma'=54
|
||||
'__intrinsic'=55
|
||||
'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
|
||||
'!'=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
|
||||
|
@ -474,169 +474,73 @@ public class KickCParserBaseListener implements KickCParserListener {
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx) { }
|
||||
@Override public void enterPragma(KickCParser.PragmaContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx) { }
|
||||
@Override public void exitPragma(KickCParser.PragmaContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx) { }
|
||||
@Override public void enterPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx) { }
|
||||
@Override public void exitPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) { }
|
||||
@Override public void enterPragmaParamRange(KickCParser.PragmaParamRangeContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) { }
|
||||
@Override public void exitPragmaParamRange(KickCParser.PragmaParamRangeContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx) { }
|
||||
@Override public void enterPragmaParamName(KickCParser.PragmaParamNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx) { }
|
||||
@Override public void exitPragmaParamName(KickCParser.PragmaParamNameContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx) { }
|
||||
@Override public void enterPragmaParamString(KickCParser.PragmaParamStringContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx) { }
|
||||
@Override public void exitPragmaParamString(KickCParser.PragmaParamStringContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) { }
|
||||
@Override public void enterPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void enterDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation does nothing.</p>
|
||||
*/
|
||||
@Override public void exitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { }
|
||||
@Override public void exitPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx) { }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -285,98 +285,42 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragma(KickCParser.PragmaContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragmaParamRange(KickCParser.PragmaParamRangeContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragmaParamName(KickCParser.PragmaParamNameContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragmaParamString(KickCParser.PragmaParamStringContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx) { return visitChildren(ctx); }
|
||||
@Override public T visitPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
|
@ -426,171 +426,75 @@ public interface KickCParserListener extends ParseTreeListener {
|
||||
*/
|
||||
void exitParameterDeclList(KickCParser.ParameterDeclListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectivePlatform}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by {@link KickCParser#pragma}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx);
|
||||
void enterPragma(KickCParser.PragmaContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectivePlatform}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by {@link KickCParser#pragma}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx);
|
||||
void exitPragma(KickCParser.PragmaContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveCpu}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by the {@code pragmaParamNumber}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx);
|
||||
void enterPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveCpu}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by the {@code pragmaParamNumber}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx);
|
||||
void exitPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveLinkScript}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by the {@code pragmaParamRange}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx);
|
||||
void enterPragmaParamRange(KickCParser.PragmaParamRangeContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveLinkScript}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by the {@code pragmaParamRange}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx);
|
||||
void exitPragmaParamRange(KickCParser.PragmaParamRangeContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveExtension}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by the {@code pragmaParamName}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx);
|
||||
void enterPragmaParamName(KickCParser.PragmaParamNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveExtension}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by the {@code pragmaParamName}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx);
|
||||
void exitPragmaParamName(KickCParser.PragmaParamNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveEmulator}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by the {@code pragmaParamString}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx);
|
||||
void enterPragmaParamString(KickCParser.PragmaParamStringContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveEmulator}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by the {@code pragmaParamString}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx);
|
||||
void exitPragmaParamString(KickCParser.PragmaParamStringContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveReserve}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Enter a parse tree produced by the {@code pragmaParamCallingConvention}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx);
|
||||
void enterPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveReserve}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Exit a parse tree produced by the {@code pragmaParamCallingConvention}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectivePc}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectivePc}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveCodeSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveCodeSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveDataSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveDataSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveEncoding}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveEncoding}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveCalling}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveCalling}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveVarModel}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveVarModel}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code globalDirectiveConstructorFor}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by the {@code globalDirectiveConstructorFor}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link KickCParser#directiveReserveParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link KickCParser#directiveReserveParam}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
|
||||
void exitPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by the {@code directiveConst}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -259,102 +259,46 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
|
||||
*/
|
||||
T visitParameterDeclList(KickCParser.ParameterDeclListContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectivePlatform}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by {@link KickCParser#pragma}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx);
|
||||
T visitPragma(KickCParser.PragmaContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveCpu}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by the {@code pragmaParamNumber}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx);
|
||||
T visitPragmaParamNumber(KickCParser.PragmaParamNumberContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveLinkScript}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by the {@code pragmaParamRange}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx);
|
||||
T visitPragmaParamRange(KickCParser.PragmaParamRangeContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveExtension}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by the {@code pragmaParamName}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx);
|
||||
T visitPragmaParamName(KickCParser.PragmaParamNameContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveEmulator}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by the {@code pragmaParamString}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx);
|
||||
T visitPragmaParamString(KickCParser.PragmaParamStringContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveReserve}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* Visit a parse tree produced by the {@code pragmaParamCallingConvention}
|
||||
* labeled alternative in {@link KickCParser#pragmaParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectivePc}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveCodeSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveDataSeg}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveEncoding}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveCalling}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveVarModel}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code globalDirectiveConstructorFor}
|
||||
* labeled alternative in {@link KickCParser#globalDirective}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link KickCParser#directiveReserveParam}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDirectiveReserveParam(KickCParser.DirectiveReserveParamContext ctx);
|
||||
T visitPragmaParamCallingConvention(KickCParser.PragmaParamCallingConventionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code directiveConst}
|
||||
* labeled alternative in {@link KickCParser#directive}.
|
||||
|
@ -44,7 +44,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
/** The memory area used by default for variables. */
|
||||
private Variable.MemoryArea defaultMemoryArea;
|
||||
/** All #pragma constructor_for() statements. Collected during parsing and handled by {@link #generate()} before returning. */
|
||||
private List<KickCParser.GlobalDirectiveConstructorForContext> pragmaConstructorFors;
|
||||
private List<KickCParser.PragmaContext> pragmaConstructorFors;
|
||||
|
||||
public Pass0GenerateStatementSequence(CParser cParser, KickCParser.FileContext fileCtx, Program program, Procedure.CallingConvention initialCallingConvention, StringEncoding defaultEncoding) {
|
||||
this.cParser = cParser;
|
||||
@ -130,16 +130,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
// Handle #pragma constructor_for()
|
||||
List<ProcedureRef> constructorProcs = new ArrayList<>();
|
||||
for(KickCParser.GlobalDirectiveConstructorForContext pragmaConstructorFor : pragmaConstructorFors) {
|
||||
final List<TerminalNode> names = pragmaConstructorFor.NAME();
|
||||
for(KickCParser.PragmaContext pragmaConstructorFor : pragmaConstructorFors) {
|
||||
final List<KickCParser.PragmaParamContext> names = pragmaConstructorFor.pragmaParam();
|
||||
if(names.size() < 2)
|
||||
throw new CompileError("Error! #pragma constructor_for requires at least 2 parameters.", new StatementSource(pragmaConstructorFor));
|
||||
final String constructorProcName = names.get(0).getText();
|
||||
final String constructorProcName = pragmaParamName(names.get(0));
|
||||
final Procedure constructorProc = program.getScope().getLocalProcedure(constructorProcName);
|
||||
if(constructorProc == null)
|
||||
throw new CompileError("Error! Constructor procedure not found " + constructorProcName, new StatementSource(pragmaConstructorFor));
|
||||
for(int i = 1; i < names.size(); i++) {
|
||||
final String procName = names.get(i).getText();
|
||||
final String procName = pragmaParamName(names.get(i));
|
||||
final Procedure proc = program.getScope().getLocalProcedure(procName);
|
||||
if(proc == null)
|
||||
throw new CompileError("Error! Procedure not found " + procName, new StatementSource(pragmaConstructorFor));
|
||||
@ -198,71 +198,162 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveConstructorFor(KickCParser.GlobalDirectiveConstructorForContext ctx) {
|
||||
this.pragmaConstructorFors.add(ctx);
|
||||
return null;
|
||||
}
|
||||
public Object visitPragma(KickCParser.PragmaContext ctx) {
|
||||
final String pragmaName = ctx.NAME().getText();
|
||||
switch(pragmaName) {
|
||||
case CParser.PRAGMA_TARGET:
|
||||
throw new InternalError("Error! #pragma target() should be handled in preprocessor!");
|
||||
case CParser.PRAGMA_CPU:
|
||||
final String cpuName = pragmaParamName(pragmaParamSingle(ctx));
|
||||
TargetCpu cpu = TargetCpu.getTargetCpu(cpuName, false);
|
||||
program.getTargetPlatform().setCpu(cpu);
|
||||
break;
|
||||
case CParser.PRAGMA_VAR_MODEL:
|
||||
final List<KickCParser.PragmaParamContext> pragmaParams = ctx.pragmaParam();
|
||||
List<String> settings = pragmaParams.stream().map(Pass0GenerateStatementSequence::pragmaParamName).collect(Collectors.toList());
|
||||
final VariableBuilderConfig variableBuilderConfig = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx));
|
||||
program.getTargetPlatform().setVariableBuilderConfig(variableBuilderConfig);
|
||||
break;
|
||||
case CParser.PRAGMA_LINKSCRIPT:
|
||||
final String linkScriptName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getLog().append("Loading link script \"" + linkScriptName + "\"");
|
||||
Path currentPath = cParser.getSourceFolderPath(ctx);
|
||||
final File linkScriptFile = SourceLoader.loadFile(linkScriptName, currentPath, program.getTargetPlatformPaths());
|
||||
program.getTargetPlatform().setLinkScriptFile(linkScriptFile);
|
||||
break;
|
||||
case CParser.PRAGMA_EXTENSION:
|
||||
String extension = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getTargetPlatform().setOutFileExtension(extension);
|
||||
break;
|
||||
case CParser.PRAGMA_EMULATOR:
|
||||
String emuName = pragmaParamString(pragmaParamSingle(ctx));
|
||||
program.getTargetPlatform().setEmulatorCommand(emuName);
|
||||
break;
|
||||
case CParser.PRAGMA_ENCODING:
|
||||
final String encodingName = pragmaParamName(pragmaParamSingle(ctx));
|
||||
try {
|
||||
this.currentEncoding = StringEncoding.fromName(encodingName.toUpperCase(Locale.ENGLISH));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new CompileError("Unknown string encoding " + encodingName, new StatementSource(ctx));
|
||||
}
|
||||
break;
|
||||
case CParser.PRAGMA_CODE_SEG:
|
||||
this.currentCodeSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_DATA_SEG:
|
||||
this.currentDataSegment = pragmaParamName(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_PC:
|
||||
Number programPc = pragmaParamNumber(pragmaParamSingle(ctx));
|
||||
program.setProgramPc(programPc);
|
||||
break;
|
||||
case CParser.PRAGMA_CALLING:
|
||||
currentCallingConvention = pragmaParamCallingConvention(pragmaParamSingle(ctx));
|
||||
break;
|
||||
case CParser.PRAGMA_ZP_RESERVE:
|
||||
List<Integer> reservedZps = pragmaParamRanges(ctx.pragmaParam());
|
||||
program.addReservedZps(reservedZps);
|
||||
break;
|
||||
case CParser.PRAGMA_CONSTRUCTOR_FOR:
|
||||
this.pragmaConstructorFors.add(ctx);
|
||||
return null;
|
||||
default:
|
||||
program.getLog().append("Warning! Unknown #pragma " + pragmaName + "\n" + new StatementSource(ctx).toString());
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveVarModel(KickCParser.GlobalDirectiveVarModelContext ctx) {
|
||||
List<TerminalNode> settingNodes = new ArrayList<>(ctx.NAME());
|
||||
List<String> settings = settingNodes.stream().map(ParseTree::getText).collect(Collectors.toList());
|
||||
final VariableBuilderConfig variableBuilderConfig = VariableBuilderConfig.fromSettings(settings, new StatementSource(ctx));
|
||||
program.getTargetPlatform().setVariableBuilderConfig(variableBuilderConfig);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveLinkScript(KickCParser.GlobalDirectiveLinkScriptContext ctx) {
|
||||
String linkName = ctx.STRING().getText();
|
||||
String linkScriptName = linkName.substring(1, linkName.length() - 1);
|
||||
program.getLog().append("Loading link script " + linkName);
|
||||
Path currentPath = cParser.getSourceFolderPath(ctx);
|
||||
final File linkScriptFile = SourceLoader.loadFile(linkScriptName, currentPath, program.getTargetPlatformPaths());
|
||||
program.getTargetPlatform().setLinkScriptFile(linkScriptFile);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveExtension(KickCParser.GlobalDirectiveExtensionContext ctx) {
|
||||
String extension = ctx.STRING().getText();
|
||||
extension = extension.substring(1, extension.length() - 1);
|
||||
program.getTargetPlatform().setOutFileExtension(extension);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveEmulator(KickCParser.GlobalDirectiveEmulatorContext ctx) {
|
||||
String emuName = ctx.STRING().getText();
|
||||
emuName = emuName.substring(1, emuName.length() - 1);
|
||||
program.getTargetPlatform().setEmulatorCommand(emuName);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveReserve(KickCParser.GlobalDirectiveReserveContext ctx) {
|
||||
final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
|
||||
List<Integer> reservedZps = getReservedZps(reserveParams);
|
||||
program.addReservedZps(reservedZps);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the list of all reserved ZP-addresses from a list of reserve parameters (potentially including ranges)
|
||||
* Check that a #pragma has a single parameter - and return that parameter
|
||||
*
|
||||
* @param ctx The #pragma
|
||||
* @return The single parameter
|
||||
*/
|
||||
private static KickCParser.PragmaParamContext pragmaParamSingle(KickCParser.PragmaContext ctx) {
|
||||
if(ctx.pragmaParam().size() != 1)
|
||||
throw new CompileError("Error! #pragma expects a single parameter!", new StatementSource(ctx));
|
||||
return ctx.pragmaParam().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single NUMBER parameter of a #pragma
|
||||
* If the parameter is not a NUMBER the compiler will fail out
|
||||
*
|
||||
* @param paramCtx The parameter to parse
|
||||
* @return The number
|
||||
*/
|
||||
private static Number pragmaParamNumber(KickCParser.PragmaParamContext paramCtx) {
|
||||
if(!(paramCtx instanceof KickCParser.PragmaParamNumberContext))
|
||||
throw new CompileError("Error! Expected a NUMBER parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
final Number number = NumberParser.parseLiteral(((KickCParser.PragmaParamNumberContext) paramCtx).NUMBER().getText());
|
||||
if(number == null)
|
||||
throw new CompileError("Error! Expected a NUMBER parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single CALLINGCONVENTION parameter of a #pragma
|
||||
* If the parameter is not a CALLINGCONVENTION the compiler will fail out
|
||||
*
|
||||
* @param paramCtx The parameter to parse
|
||||
* @return The name
|
||||
*/
|
||||
private static Procedure.CallingConvention pragmaParamCallingConvention(KickCParser.PragmaParamContext paramCtx) {
|
||||
if(!(paramCtx instanceof KickCParser.PragmaParamCallingConventionContext))
|
||||
throw new CompileError("Error! Expected a CALLINGCONVENTION parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
final String callingConventionName = ((KickCParser.PragmaParamCallingConventionContext) paramCtx).CALLINGCONVENTION().getText();
|
||||
final Procedure.CallingConvention callingConvention = Procedure.CallingConvention.getCallingConvension(callingConventionName);
|
||||
if(callingConvention == null)
|
||||
throw new CompileError("Error! Expected a CALLINGCONVENTION parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
return callingConvention;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a single NAME parameter of a #pragma
|
||||
* If the parameter is not a NAME the compiler will fail out
|
||||
*
|
||||
* @param paramCtx The parameter to parse
|
||||
* @return The name
|
||||
*/
|
||||
private static String pragmaParamName(KickCParser.PragmaParamContext paramCtx) {
|
||||
if(!(paramCtx instanceof KickCParser.PragmaParamNameContext))
|
||||
throw new CompileError("Error! Expected a NAME parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
return ((KickCParser.PragmaParamNameContext) paramCtx).NAME().getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single STRING parameter of a #pragma
|
||||
* If the parameter is not a STRING the compiler will fail out
|
||||
*
|
||||
* @param paramCtx The parameter to parse
|
||||
* @return The string
|
||||
*/
|
||||
private static String pragmaParamString(KickCParser.PragmaParamContext paramCtx) {
|
||||
if(!(paramCtx instanceof KickCParser.PragmaParamStringContext))
|
||||
throw new CompileError("Error! Expected a STRING parameter. Found '" + paramCtx.getText() + "'.", new StatementSource(paramCtx.getParent()));
|
||||
final String stringLiteral = ((KickCParser.PragmaParamStringContext) paramCtx).STRING().getText();
|
||||
return stringLiteral.substring(1, stringLiteral.length() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a reserved ZP-addresses from a list of pragma parameters (consisting of numbers and number ranges).
|
||||
*
|
||||
* @param reserveParams The params
|
||||
* @return The list of reserved zeropage addresses
|
||||
*/
|
||||
private List<Integer> getReservedZps(List<KickCParser.DirectiveReserveParamContext> reserveParams) {
|
||||
private List<Integer> pragmaParamRanges(List<KickCParser.PragmaParamContext> reserveParams) {
|
||||
List<Integer> reservedZps = new ArrayList<>();
|
||||
for(KickCParser.DirectiveReserveParamContext reserveCtx : reserveParams) {
|
||||
final TerminalNode rangeStart = reserveCtx.NUMBER(0);
|
||||
final TerminalNode rangeEnd = reserveCtx.NUMBER(1);
|
||||
if(rangeEnd == null) {
|
||||
for(KickCParser.PragmaParamContext reserveCtx : reserveParams) {
|
||||
if(reserveCtx instanceof KickCParser.PragmaParamNumberContext) {
|
||||
final TerminalNode number = ((KickCParser.PragmaParamNumberContext) reserveCtx).NUMBER();
|
||||
// Only a single reserved address
|
||||
Number reservedZp = NumberParser.parseLiteral(rangeStart.getText());
|
||||
Number reservedZp = NumberParser.parseLiteral(number.getText());
|
||||
reservedZps.add(reservedZp.intValue());
|
||||
} else {
|
||||
} else if(reserveCtx instanceof KickCParser.PragmaParamRangeContext) {
|
||||
final TerminalNode rangeStart = ((KickCParser.PragmaParamRangeContext) reserveCtx).NUMBER(0);
|
||||
final TerminalNode rangeEnd = ((KickCParser.PragmaParamRangeContext) reserveCtx).NUMBER(1);
|
||||
// A range of reserved addresses
|
||||
Number startZp = NumberParser.parseLiteral(rangeStart.getText());
|
||||
Number endZp = NumberParser.parseLiteral(rangeEnd.getText());
|
||||
@ -271,75 +362,22 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
reservedZps.add(zp);
|
||||
zp++;
|
||||
}
|
||||
} else {
|
||||
throw new CompileError("Error! Expected a NUMBER or RANGE parameter. Found '" + reserveCtx.getText() + "'.", new StatementSource(reserveCtx.getParent()));
|
||||
}
|
||||
}
|
||||
return reservedZps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveEncoding(KickCParser.GlobalDirectiveEncodingContext ctx) {
|
||||
try {
|
||||
this.currentEncoding = StringEncoding.fromName(ctx.NAME().getText().toUpperCase(Locale.ENGLISH));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new CompileError("Unknown string encoding " + ctx.NAME().getText(), new StatementSource(ctx));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectivePc(KickCParser.GlobalDirectivePcContext ctx) {
|
||||
Number programPc = NumberParser.parseLiteral(ctx.NUMBER().getText());
|
||||
if(programPc != null) {
|
||||
program.setProgramPc(programPc);
|
||||
} else {
|
||||
throw new CompileError("Cannot parse #pc directive", new StatementSource(ctx));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectivePlatform(KickCParser.GlobalDirectivePlatformContext ctx) {
|
||||
throw new InternalError("Error! #pragma target() should be handled in preprocessor!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveCpu(KickCParser.GlobalDirectiveCpuContext ctx) {
|
||||
final String cpuName = ctx.NAME().getText();
|
||||
TargetCpu cpu = TargetCpu.getTargetCpu(cpuName, false);
|
||||
program.getTargetPlatform().setCpu(cpu);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The current calling convention for procedures. */
|
||||
private Procedure.CallingConvention currentCallingConvention;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveCalling(KickCParser.GlobalDirectiveCallingContext ctx) {
|
||||
Procedure.CallingConvention callingConvention = Procedure.CallingConvention.getCallingConvension(ctx.CALLINGCONVENTION().getText());
|
||||
if(callingConvention != null) {
|
||||
currentCallingConvention = callingConvention;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The current code segment - if null the default segment is used. */
|
||||
private String currentCodeSegment = Scope.SEGMENT_CODE_DEFAULT;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveCodeSeg(KickCParser.GlobalDirectiveCodeSegContext ctx) {
|
||||
this.currentCodeSegment = ctx.NAME().getText();
|
||||
return null;
|
||||
}
|
||||
|
||||
/** The current data segment - if null the default segment is used. */
|
||||
private String currentDataSegment = Scope.SEGMENT_DATA_DEFAULT;
|
||||
|
||||
@Override
|
||||
public Object visitGlobalDirectiveDataSeg(KickCParser.GlobalDirectiveDataSegContext ctx) {
|
||||
this.currentDataSegment = ctx.NAME().getText();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitDeclFunction(KickCParser.DeclFunctionContext ctx) {
|
||||
this.visit(ctx.declType());
|
||||
@ -1260,8 +1298,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
@Override
|
||||
public Directive visitDirectiveReserveZp(KickCParser.DirectiveReserveZpContext ctx) {
|
||||
final List<KickCParser.DirectiveReserveParamContext> reserveParams = ctx.directiveReserveParam();
|
||||
final List<Integer> reservedZps = getReservedZps(reserveParams);
|
||||
final List<KickCParser.PragmaParamContext> reserveParams = ctx.pragmaParam();
|
||||
final List<Integer> reservedZps = pragmaParamRanges(reserveParams);
|
||||
return new Directive.ReserveZp(reservedZps);
|
||||
}
|
||||
|
||||
|
@ -169,8 +169,8 @@ public class CPreprocessor implements TokenSource {
|
||||
// Already examined by the preprocessor - and determined to be for the parser
|
||||
return false;
|
||||
final List<Token> ws = skipWhitespace(cTokenSource);
|
||||
final Token pragmaType = cTokenSource.nextToken();
|
||||
if(KickCLexer.TARGET == pragmaType.getType()) {
|
||||
final Token pragmaType = nextToken(cTokenSource, KickCLexer.NAME);
|
||||
if(pragmaType.getText().equals(CParser.PRAGMA_TARGET)) {
|
||||
skipWhitespace(cTokenSource);
|
||||
nextToken(cTokenSource, KickCLexer.PAR_BEGIN);
|
||||
skipWhitespace(cTokenSource);
|
||||
|
@ -42,6 +42,11 @@ public class TestPrograms {
|
||||
public TestPrograms() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPragmaUnknown() throws IOException, URISyntaxException {
|
||||
compileAndCompare("pragma-unknown.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLibraryConstructorError2() throws IOException, URISyntaxException {
|
||||
assertError("library-constructor-error-2.c", "Error! Procedure not found print");
|
||||
|
9
src/test/kc/pragma-unknown.c
Normal file
9
src/test/kc/pragma-unknown.c
Normal file
@ -0,0 +1,9 @@
|
||||
// Test an unknown pragma
|
||||
|
||||
#pragma unknown(x)
|
||||
|
||||
char * const SCREEN = 0x0400;
|
||||
|
||||
void main() {
|
||||
*SCREEN = 'a';
|
||||
}
|
12
src/test/ref/pragma-unknown.asm
Normal file
12
src/test/ref/pragma-unknown.asm
Normal file
@ -0,0 +1,12 @@
|
||||
// Test an unknown pragma
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
main: {
|
||||
// *SCREEN = 'a'
|
||||
lda #'a'
|
||||
sta SCREEN
|
||||
// }
|
||||
rts
|
||||
}
|
8
src/test/ref/pragma-unknown.cfg
Normal file
8
src/test/ref/pragma-unknown.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from
|
||||
[0] *((const nomodify byte*) SCREEN) ← (byte) 'a'
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
154
src/test/ref/pragma-unknown.log
Normal file
154
src/test/ref/pragma-unknown.log
Normal file
@ -0,0 +1,154 @@
|
||||
Warning! Unknown #pragma unknown
|
||||
File /Users/jespergravgaard/c64/kickc/src/test/kc/pragma-unknown.c
|
||||
Line 3
|
||||
#pragma unknown(x)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from __start
|
||||
*((const nomodify byte*) SCREEN) ← (byte) 'a'
|
||||
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
|
||||
(const nomodify byte*) SCREEN = (byte*)(number) $400
|
||||
(void()) __start()
|
||||
(label) __start::@1
|
||||
(label) __start::@return
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
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] *((const nomodify byte*) SCREEN) ← (byte) 'a'
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[1] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
// File Comments
|
||||
// Test an unknown pragma
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
// main
|
||||
main: {
|
||||
// [0] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2
|
||||
lda #'a'
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] *((const nomodify byte*) SCREEN) ← (byte) 'a' [ ] ( [ ] { } ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 15 combination
|
||||
Uplifting [] best 15 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// Test an unknown pragma
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
// main
|
||||
main: {
|
||||
// [0] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2
|
||||
lda #'a'
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 12
|
||||
|
||||
// File Comments
|
||||
// Test an unknown pragma
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
// main
|
||||
main: {
|
||||
// *SCREEN = 'a'
|
||||
// [0] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2
|
||||
lda #'a'
|
||||
sta SCREEN
|
||||
// main::@return
|
||||
// }
|
||||
// [1] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
4
src/test/ref/pragma-unknown.sym
Normal file
4
src/test/ref/pragma-unknown.sym
Normal file
@ -0,0 +1,4 @@
|
||||
(const nomodify byte*) SCREEN = (byte*) 1024
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
@ -12,7 +12,8 @@
|
||||
"print.h": "c",
|
||||
"printf.h": "c",
|
||||
"c64.h": "c",
|
||||
"sstream": "c"
|
||||
"sstream": "c",
|
||||
"functional": "c"
|
||||
},
|
||||
"kickassembler.assemblerJar": "/Applications/KickAssembler/KickAss.jar"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user