1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-01 02:29:30 +00:00

Added support for #if reusing the expression parser. Added support for the special defined operator. Now using the base parser for the preprocessor test. #169

This commit is contained in:
Jesper Gravgaard 2020-04-06 14:34:42 +02:00
parent 0a11eefda0
commit 4352874305
28 changed files with 1775 additions and 2789 deletions

View File

@ -4,6 +4,7 @@ import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantBool;
import dk.camelot64.kickc.model.values.ConstantEnumerable;
import dk.camelot64.kickc.model.values.ConstantLiteral;
/** Unary Logic Not operator (!b) */
@ -15,6 +16,9 @@ public class OperatorLogicNot extends OperatorUnary {
@Override
public ConstantLiteral calculateLiteral(ConstantLiteral left, ProgramScope scope) {
if(left instanceof ConstantEnumerable) {
left = new ConstantBool(((ConstantEnumerable) left).getInteger()!=0);
}
if(left instanceof ConstantBool) {
return new ConstantBool(!((ConstantBool) left).getBool() );
}

View File

@ -4,16 +4,12 @@ import dk.camelot64.kickc.SourceLoader;
import dk.camelot64.kickc.preprocessor.CPreprocessor;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.preprocessor.CPreprocessorTokens;
import org.antlr.v4.runtime.*;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Parser for C-language files.
@ -65,8 +61,7 @@ public class CParser {
this.program = program;
this.cFiles = new LinkedHashMap<>();
this.cTokenSource = new CTokenSource();
final CPreprocessorTokens preprocessorTokens = new CPreprocessorTokens(CHANNEL_WHITESPACE, KickCLexer.WS, KickCLexer.DEFINE, KickCLexer.NAME, KickCLexer.DEFINE_CONTINUE, KickCLexer.UNDEF, KickCLexer.IFDEF, KickCLexer.IFNDEF, KickCLexer.IFELSE, KickCLexer.ENDIF, KickCLexer.PAR_BEGIN, KickCLexer.PAR_END, KickCLexer.COMMA);
final CPreprocessor preprocessor = new CPreprocessor(cTokenSource, preprocessorTokens);
final CPreprocessor preprocessor = new CPreprocessor(cTokenSource, new HashMap<>());
this.tokenStream = new CommonTokenStream(preprocessor);
this.parser = new KickCParser(tokenStream, this);
this.typedefs = new ArrayList<>();
@ -115,6 +110,14 @@ public class CParser {
return this.parser.file();
}
/**
* Get the C parser
* @return The C parser
*/
public KickCParser getParser() {
return parser;
}
/**
* Get the path of the folder containing the source file for a token
*
@ -179,25 +182,35 @@ public class CParser {
program.getLog().append("PARSING " + file.getPath().replace("\\", "/"));
program.getLog().append(fileStream.toString());
}
KickCLexer lexer = new KickCLexer(fileStream, this);
lexer.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(
Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
}
});
KickCLexer lexer = addSource(fileStream);
CFile cFile = new CFile(file, lexer);
cFiles.put(file.getAbsolutePath(), cFile);
cTokenSource.addSource(lexer);
} catch(IOException e) {
throw new CompileError("Error parsing file " + fileName, e);
}
}
/**
* Add source code at the start of the token stream being parsed.
* @param charStream The char stream containing the source code to add
* @return The lexer for reading the source tokens of the added source
*/
public KickCLexer addSource(CharStream charStream) {
KickCLexer lexer = new KickCLexer(charStream, this);
lexer.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(
Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
throw new CompileError("Error parsing file " + charStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
}
});
cTokenSource.addSource(lexer);
return lexer;
}
}

View File

@ -106,6 +106,7 @@ STRUCT : 'struct' ;
ENUM : 'enum' ;
SIZEOF : 'sizeof' ;
TYPEID : 'typeid' ;
DEFINED : 'defined' ;
KICKASM : 'kickasm' ;
RESOURCE : 'resource' ;
USES : 'uses' ;
@ -124,10 +125,12 @@ CHAR : '\'' ('\\'['"rfn] | ~'\'' ) '\'';
// Macros
DEFINE: '#define' ;
DEFINE_CONTINUE: '\\\n' ;
DEFINE_CONTINUE: '\\\n' | '\\\r\n';
UNDEF: '#undef' ;
IFDEF: '#ifdef' ;
IFNDEF: '#ifndef' ;
IFIF: '#if' ;
ELIF: '#elif' ;
IFELSE: '#else' ;
ENDIF: '#endif' ;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -220,6 +220,7 @@ expr
| expr PAR_BEGIN parameterList? PAR_END #exprCall
| SIZEOF PAR_BEGIN ( expr | typeSpecifier ) PAR_END #exprSizeOf
| TYPEID PAR_BEGIN ( expr | typeSpecifier ) PAR_END #exprTypeId
| DEFINED PAR_BEGIN? NAME PAR_END? #exprDefined
| expr BRACKET_BEGIN commaExpr BRACKET_END #exprArray
| PAR_BEGIN typeSpecifier PAR_END expr #exprCast
| ('--' | '++' ) expr #exprPreMod

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.7.2
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickCParser.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parser;
@ -1273,6 +1273,18 @@ public class KickCParserBaseListener implements KickCParserListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprId(KickCParser.ExprIdContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprDefined(KickCParser.ExprDefinedContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprDefined(KickCParser.ExprDefinedContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.7.2
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickCParser.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parser;
@ -748,6 +748,13 @@ public class KickCParserBaseVisitor<T> extends AbstractParseTreeVisitor<T> imple
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprId(KickCParser.ExprIdContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprDefined(KickCParser.ExprDefinedContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.7.2
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickCParser.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parser;
@ -1221,6 +1221,18 @@ public interface KickCParserListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitExprId(KickCParser.ExprIdContext ctx);
/**
* Enter a parse tree produced by the {@code exprDefined}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void enterExprDefined(KickCParser.ExprDefinedContext ctx);
/**
* Exit a parse tree produced by the {@code exprDefined}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
*/
void exitExprDefined(KickCParser.ExprDefinedContext ctx);
/**
* Enter a parse tree produced by the {@code exprTernary}
* labeled alternative in {@link KickCParser#expr}.

View File

@ -1,4 +1,4 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/main/java/dk/camelot64/kickc/parser/KickCParser.g4 by ANTLR 4.7.2
// Generated from C:/c64/kickc/src/main/java/dk/camelot64/kickc/parser\KickCParser.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parser;
@ -723,6 +723,13 @@ public interface KickCParserVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitExprId(KickCParser.ExprIdContext ctx);
/**
* Visit a parse tree produced by the {@code exprDefined}
* labeled alternative in {@link KickCParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprDefined(KickCParser.ExprDefinedContext ctx);
/**
* Visit a parse tree produced by the {@code exprTernary}
* labeled alternative in {@link KickCParser#expr}.

View File

@ -1,8 +1,17 @@
package dk.camelot64.kickc.preprocessor;
import dk.camelot64.kickc.NumberParser;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.parser.CTokenSource;
import dk.camelot64.kickc.model.operators.OperatorBinary;
import dk.camelot64.kickc.model.operators.OperatorUnary;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.values.ConstantBool;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.parser.*;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.*;
@ -22,18 +31,14 @@ public class CPreprocessor implements TokenSource {
*/
private Map<String, List<Token>> defines;
/** The token types. */
private CPreprocessorTokens tokenTypes;
public CPreprocessor(TokenSource input, CPreprocessorTokens tokenTypes) {
public CPreprocessor(TokenSource input, Map<String, List<Token>> defines) {
if(input instanceof CTokenSource) {
// If possible use the input directly instead of wrapping it
this.input = (CTokenSource) input;
} else {
this.input = new CTokenSource(input);
}
this.defines = new LinkedHashMap<>();
this.tokenTypes = tokenTypes;
this.defines = defines;
}
@Override
@ -86,29 +91,30 @@ public class CPreprocessor implements TokenSource {
* @return true if the input token was preprocessed (and should not be added to the output). False if the token was not a preprocessor token
*/
private boolean preprocess(Token inputToken, CTokenSource cTokenSource) {
if(inputToken.getType() == tokenTypes.define) {
if(inputToken.getType() == KickCLexer.DEFINE) {
define(cTokenSource);
return true;
} else if(inputToken.getType() == tokenTypes.undef) {
} else if(inputToken.getType() == KickCLexer.UNDEF) {
undef(cTokenSource);
return true;
} else if(inputToken.getType() == tokenTypes.ifndef) {
} else if(inputToken.getType() == KickCLexer.IFNDEF) {
ifndef(cTokenSource);
return true;
} else if(inputToken.getType() == tokenTypes.ifdef) {
} else if(inputToken.getType() == KickCLexer.IFDEF) {
ifdef(cTokenSource);
return true;
} else if(inputToken.getType() == tokenTypes.ifelse) {
} else if(inputToken.getType() == KickCLexer.IFIF) {
ifif(cTokenSource);
return true;
} else if(inputToken.getType() == KickCLexer.IFELSE) {
// #else means we must skip until #endif
ifelse(cTokenSource);
return true;
} else if(inputToken.getType() == tokenTypes.endif) {
} else if(inputToken.getType() == KickCLexer.ENDIF) {
// Skip #endif - they have already been handled by #if / #else
return true;
} else if(inputToken.getType() == tokenTypes.identifier) {
final boolean expanded = expand(inputToken, cTokenSource);
if(expanded)
return true;
} else if(inputToken.getType() == KickCLexer.NAME) {
return expand(inputToken, cTokenSource);
}
return false;
}
@ -162,7 +168,7 @@ public class CPreprocessor implements TokenSource {
private void undef(CTokenSource cTokenSource) {
// #undef a new macro - find the name
skipWhitespace(cTokenSource);
String macroName = nextToken(cTokenSource, tokenTypes.identifier).getText();
String macroName = nextToken(cTokenSource, KickCLexer.NAME).getText();
this.defines.remove(macroName);
}
@ -173,13 +179,151 @@ public class CPreprocessor implements TokenSource {
*/
private void ifdef(CTokenSource cTokenSource) {
skipWhitespace(cTokenSource);
String macroName = nextToken(cTokenSource, tokenTypes.identifier).getText();
String macroName = nextToken(cTokenSource, KickCLexer.NAME).getText();
final boolean defined = this.defines.containsKey(macroName);
if(!defined) {
iffalse(cTokenSource);
}
}
/**
* #if checks if a constant condition expression is non-zero
*
* @param cTokenSource The token source used to get the condition
*/
private void ifif(CTokenSource cTokenSource) {
// Read the condition body
ArrayList<Token> conditionTokens = readBody(cTokenSource);
// Evaluate any uses of the defined operator (to prevent expansion of the named macro)
evaluateDefinedOperator(conditionTokens);
// Expand the condition body before evaluating it
CPreprocessor subPreprocessor = new CPreprocessor(new ListTokenSource(conditionTokens), new HashMap<>(defines));
// Parse the expression
KickCParser.ExprContext conditionExpr = ExprParser.parseExpression(subPreprocessor);
// Evaluate the expression
Long conditionValue = evaluateExpression(conditionExpr);
if(conditionValue == null || conditionValue == 0L) {
iffalse(cTokenSource);
}
}
/**
* Evaluate a constant condition expression from #if. The special defined operator must be evaluated before calling this.
*
* @param conditionExpr The expression
* @return The result of the evaluation.
*/
private Long evaluateExpression(KickCParser.ExprContext conditionExpr) {
KickCParserBaseVisitor<Long> conditionEvaluator = new KickCParserBaseVisitor<Long>() {
@Override
public Long visitExprNumber(KickCParser.ExprNumberContext ctx) {
try {
ConstantInteger constantInteger = NumberParser.parseIntegerLiteral(ctx.getText());
return constantInteger.getInteger();
} catch(NumberFormatException e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx));
}
}
@Override
public Long visitExprId(KickCParser.ExprIdContext ctx) {
return 0L;
}
@Override
public Long visitExprBinary(KickCParser.ExprBinaryContext ctx) {
Long left = this.visit(ctx.expr(0));
Long right = this.visit(ctx.expr(1));
String op = ((TerminalNode) ctx.getChild(1)).getSymbol().getText();
OperatorBinary operator = (OperatorBinary) Operators.getBinary(op);
ConstantLiteral result = operator.calculateLiteral(new ConstantInteger(left), new ConstantInteger(right));
if(result instanceof ConstantInteger) {
return ((ConstantInteger) result).getInteger();
} else if(result instanceof ConstantBool) {
return ((ConstantBool) result).getBool()?1L:0L;
} else
return 0L;
}
@Override
public Long visitExprUnary(KickCParser.ExprUnaryContext ctx) {
Long left = this.visit(ctx.expr());
String op = ((TerminalNode) ctx.getChild(0)).getSymbol().getText();
OperatorUnary operator = (OperatorUnary) Operators.getUnary(op);
ConstantLiteral result = operator.calculateLiteral(new ConstantInteger(left), null);
if(result instanceof ConstantInteger) {
return ((ConstantInteger) result).getInteger();
} else if(result instanceof ConstantBool) {
return ((ConstantBool) result).getBool()?1L:0L;
} else
return 0L;
}
@Override
public Long visitExprPar(KickCParser.ExprParContext ctx) {
return this.visit(ctx.commaExpr());
}
};
return conditionEvaluator.visit(conditionExpr);
}
/**
* Find and evaluate the special defined X operator which evaluates to 1 if a named macro if defined and 0 if it is undefined.
* Works by replacing the defined X tokens with the resulting 0/1 value in the passed token list.
* @param conditionTokens The token list
*/
private void evaluateDefinedOperator(ArrayList<Token> conditionTokens) {
// First evaluate the special defined operators
ListIterator<Token> tokenIt = conditionTokens.listIterator();
while(tokenIt.hasNext()) {
Token token = tokenIt.next();
if(token.getType()== KickCLexer.DEFINED) {
// Remove the token
tokenIt.remove();
// Read the macro name to examine - and skip any parenthesis
token = getNextSkipWhitespace(tokenIt);
boolean hasPar = false;
if(token.getType()==KickCLexer.PAR_BEGIN) {
tokenIt.remove();
token = getNextSkipWhitespace(tokenIt);
hasPar = true;
}
if(token.getType()!=KickCLexer.NAME) {
throw new CompileError("Unexpected token. Was expecting NAME!");
}
tokenIt.remove();
Token macroNameToken = token;
String macroName = macroNameToken.getText();
if(hasPar) {
// Skip closing parenthesis
token = getNextSkipWhitespace(tokenIt);
if(token.getType()!=KickCLexer.PAR_END) {
throw new CompileError("Unexpected token. Was expecting ')'!");
}
tokenIt.remove();
}
final boolean defined = defines.containsKey(macroName);
CommonToken definedToken = new CommonToken(macroNameToken);
definedToken.setType(KickCLexer.NUMBER);
definedToken.setText(defined?"1":"0");
tokenIt.add(definedToken);
}
}
}
/**
* Get the next token from an iterator skipping whitespace (unless it has a newline)
* @param tokenIt The iterator
* @return The next non-whitespace token
*/
private Token getNextSkipWhitespace(ListIterator<Token> tokenIt) {
Token token = tokenIt.next();
while(token.getChannel()==CParser.CHANNEL_WHITESPACE && !token.getText().contains("\n"))
token = tokenIt.next();
return token;
}
/**
* #ifdef checks if a macro is _NOT_ defined.
*
@ -187,16 +331,16 @@ public class CPreprocessor implements TokenSource {
*/
private void ifndef(CTokenSource cTokenSource) {
skipWhitespace(cTokenSource);
String macroName = nextToken(cTokenSource, tokenTypes.identifier).getText();
String macroName = nextToken(cTokenSource, KickCLexer.NAME).getText();
final boolean defined = this.defines.containsKey(macroName);
if(defined) {
iffalse(cTokenSource);
}
}
/**
* Skip tokens based in an #if that is false
*
* @param cTokenSource The token source
*/
private void iffalse(CTokenSource cTokenSource) {
@ -205,14 +349,14 @@ public class CPreprocessor implements TokenSource {
while(true) {
final Token token = cTokenSource.nextToken();
final int tokenType = token.getType();
if(tokenType == tokenTypes.ifdef || tokenType == tokenTypes.ifndef) {
if(tokenType == KickCLexer.IFDEF || tokenType == KickCLexer.IFNDEF || tokenType == KickCLexer.IFIF) {
++nesting;
} else if(tokenType == tokenTypes.ifelse) {
} else if(tokenType == KickCLexer.IFELSE) {
if(nesting == 1) {
// We are at the outer #if - #else means we must generate output from here!
return;
}
} else if(tokenType == tokenTypes.endif) {
} else if(tokenType == KickCLexer.ENDIF) {
if(--nesting == 0) {
// We have passed the matching #endif - restart the output!
return;
@ -231,9 +375,9 @@ public class CPreprocessor implements TokenSource {
while(true) {
final Token token = cTokenSource.nextToken();
final int tokenType = token.getType();
if(tokenType == tokenTypes.ifdef || tokenType == tokenTypes.ifndef) {
if(tokenType == KickCLexer.IFDEF || tokenType == KickCLexer.IFNDEF || tokenType == KickCLexer.IFIF) {
++nesting;
} else if(tokenType == tokenTypes.endif) {
} else if(tokenType == KickCLexer.ENDIF) {
if(--nesting == 0) {
// We have passed the matching #endif
return;
@ -250,34 +394,45 @@ public class CPreprocessor implements TokenSource {
private void define(CTokenSource cTokenSource) {
// #define a new macro - find the name
skipWhitespace(cTokenSource);
String macroName = nextToken(cTokenSource, tokenTypes.identifier).getText();
String macroName = nextToken(cTokenSource, KickCLexer.NAME).getText();
// Examine whether the macro has parameters
skipWhitespace(cTokenSource);
if(cTokenSource.peekToken().getType() == tokenTypes.parBegin) {
if(cTokenSource.peekToken().getType() == KickCLexer.PAR_BEGIN) {
// Macro has parameters - find parameter name list
throw new CompileError("Macros with parameters not supported!");
}
final ArrayList<Token> macroBody = readBody(cTokenSource);
defines.put(macroName, macroBody);
}
/**
* Read a preprocessor body (eg. a macro body) until encountering a newline
*
* @param cTokenSource The token source to read from
* @return The list of body tokens read
*/
private ArrayList<Token> readBody(CTokenSource cTokenSource) {
// Find body by gobbling tokens until the line ends
final ArrayList<Token> macroBody = new ArrayList<>();
while(true) {
final Token bodyToken = cTokenSource.nextToken();
if(bodyToken.getType() == tokenTypes.defineMultiline) {
if(bodyToken.getType() == KickCLexer.DEFINE_CONTINUE) {
// Skip the multi-line token, add a newline token and continue reading body on the next line
final CommonToken newlineToken = new CommonToken(bodyToken);
newlineToken.setType(tokenTypes.whitespace);
newlineToken.setChannel(tokenTypes.channelWhitespace);
newlineToken.setType(KickCLexer.WS);
newlineToken.setChannel(CParser.CHANNEL_WHITESPACE);
newlineToken.setText("\n");
macroBody.add(newlineToken);
continue;
}
if(bodyToken.getChannel() == tokenTypes.channelWhitespace && bodyToken.getText().contains("\n")) {
if(bodyToken.getChannel() == CParser.CHANNEL_WHITESPACE && bodyToken.getText().contains("\n")) {
// Done reading the body
break;
} else {
macroBody.add(bodyToken);
}
}
defines.put(macroName, macroBody);
return macroBody;
}
/**
@ -302,7 +457,7 @@ public class CPreprocessor implements TokenSource {
private void skipWhitespace(CTokenSource cTokenSource) {
while(true) {
final Token token = cTokenSource.peekToken();
if(token.getChannel() != tokenTypes.channelWhitespace)
if(token.getChannel() != CParser.CHANNEL_WHITESPACE)
break;
if(token.getText().contains("\n"))
break;

View File

@ -1,50 +0,0 @@
package dk.camelot64.kickc.preprocessor;
/**
* Tokens used by the preprocessor
*/
public class CPreprocessorTokens {
/** The channel containing whitespaces. */
final int channelWhitespace;
/** The token type for tokens containing whitespace. */
final int whitespace;
/** The token type for #define. */
final int define;
/** The token type for define multi-line. */
final int defineMultiline;
/** The token type for #undef. */
final int undef;
/** The token type for #ifdef. */
final int ifdef;
/** The token type for #ifndef. */
final int ifndef;
/** The token type for #else. */
final int ifelse;
/** The token type for #endif. */
final int endif;
/** The token type for identifiers. */
final int identifier;
/** The token type for parenthesis begin. */
final int parBegin;
/** The token type for parenthesis end. */
final int parEnd;
/** The token type for comma. */
final int comma;
public CPreprocessorTokens(int channelWhitespace, int whitespace, int define, int identifier, int defineMultiline, int undef, int ifdef, int ifndef, int ifelse, int endif, int parBegin, int parEnd, int comma) {
this.channelWhitespace = channelWhitespace;
this.whitespace = whitespace;
this.define = define;
this.identifier = identifier;
this.defineMultiline = defineMultiline;
this.undef = undef;
this.ifdef = ifdef;
this.ifndef = ifndef;
this.ifelse = ifelse;
this.endif = endif;
this.parBegin = parBegin;
this.parEnd = parEnd;
this.comma = comma;
}
}

View File

@ -1,49 +0,0 @@
/**
* Minimal grammar implementing C macros
*/
grammar Macros;
@header {
}
@parser::members {
}
@lexer::members {
}
stmtSeq
: stmt*
;
stmt
: expr ';' #stmtExpr
;
expr
: PAR_BEGIN SIMPLETYPE PAR_END expr #exprCast
| IDENTIFIER #exprName
| NUMBER #exprNumber
| PAR_BEGIN expr PAR_END #exprPar
| expr '*' expr #exprBinary
| expr '/' expr #exprBinary
| expr '+' expr #exprBinary
| expr '-' expr #exprBinary
| expr COMMA expr #exprBinary
;
PAR_BEGIN: '(' ;
PAR_END: ')' ;
COMMA : ',' ;
SIMPLETYPE: 'char' | 'int' ;
IDENTIFIER: [a-zA-Z_][a-zA-Z_0-9]* ;
NUMBER: [0-9]+ ;
DEFINE: '#define' ;
UNDEF: '#undef' ;
IFDEF: '#ifdef' ;
IFNDEF: '#ifndef' ;
IFELSE: '#else' ;
ENDIF: '#endif' ;
DEFINE_CONTINUE: '\\\n' ;
WHITESPACE: [ \t\r\n]+ -> channel(1) ; // Send whitespace to the hidden WS channel

View File

@ -1,52 +0,0 @@
token literal names:
null
';'
'*'
'/'
'+'
'-'
'('
')'
','
null
null
null
'#define'
'#undef'
'#ifdef'
'#ifndef'
'#else'
'#endif'
'\\\n'
null
token symbolic names:
null
null
null
null
null
null
PAR_BEGIN
PAR_END
COMMA
SIMPLETYPE
IDENTIFIER
NUMBER
DEFINE
UNDEF
IFDEF
IFNDEF
IFELSE
ENDIF
DEFINE_CONTINUE
WHITESPACE
rule names:
stmtSeq
stmt
expr
atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 21, 51, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 3, 2, 7, 2, 10, 10, 2, 12, 2, 14, 2, 13, 11, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 5, 4, 29, 10, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 46, 10, 4, 12, 4, 14, 4, 49, 11, 4, 3, 4, 2, 3, 6, 5, 2, 4, 6, 2, 2, 2, 56, 2, 11, 3, 2, 2, 2, 4, 14, 3, 2, 2, 2, 6, 28, 3, 2, 2, 2, 8, 10, 5, 4, 3, 2, 9, 8, 3, 2, 2, 2, 10, 13, 3, 2, 2, 2, 11, 9, 3, 2, 2, 2, 11, 12, 3, 2, 2, 2, 12, 3, 3, 2, 2, 2, 13, 11, 3, 2, 2, 2, 14, 15, 5, 6, 4, 2, 15, 16, 7, 3, 2, 2, 16, 5, 3, 2, 2, 2, 17, 18, 8, 4, 1, 2, 18, 19, 7, 8, 2, 2, 19, 20, 7, 11, 2, 2, 20, 21, 7, 9, 2, 2, 21, 29, 5, 6, 4, 11, 22, 29, 7, 12, 2, 2, 23, 29, 7, 13, 2, 2, 24, 25, 7, 8, 2, 2, 25, 26, 5, 6, 4, 2, 26, 27, 7, 9, 2, 2, 27, 29, 3, 2, 2, 2, 28, 17, 3, 2, 2, 2, 28, 22, 3, 2, 2, 2, 28, 23, 3, 2, 2, 2, 28, 24, 3, 2, 2, 2, 29, 47, 3, 2, 2, 2, 30, 31, 12, 7, 2, 2, 31, 32, 7, 4, 2, 2, 32, 46, 5, 6, 4, 8, 33, 34, 12, 6, 2, 2, 34, 35, 7, 5, 2, 2, 35, 46, 5, 6, 4, 7, 36, 37, 12, 5, 2, 2, 37, 38, 7, 6, 2, 2, 38, 46, 5, 6, 4, 6, 39, 40, 12, 4, 2, 2, 40, 41, 7, 7, 2, 2, 41, 46, 5, 6, 4, 5, 42, 43, 12, 3, 2, 2, 43, 44, 7, 10, 2, 2, 44, 46, 5, 6, 4, 4, 45, 30, 3, 2, 2, 2, 45, 33, 3, 2, 2, 2, 45, 36, 3, 2, 2, 2, 45, 39, 3, 2, 2, 2, 45, 42, 3, 2, 2, 2, 46, 49, 3, 2, 2, 2, 47, 45, 3, 2, 2, 2, 47, 48, 3, 2, 2, 2, 48, 7, 3, 2, 2, 2, 49, 47, 3, 2, 2, 2, 6, 11, 28, 45, 47]

View File

@ -1,34 +0,0 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
PAR_BEGIN=6
PAR_END=7
COMMA=8
SIMPLETYPE=9
IDENTIFIER=10
NUMBER=11
DEFINE=12
UNDEF=13
IFDEF=14
IFNDEF=15
IFELSE=16
ENDIF=17
DEFINE_CONTINUE=18
WHITESPACE=19
';'=1
'*'=2
'/'=3
'+'=4
'-'=5
'('=6
')'=7
','=8
'#define'=12
'#undef'=13
'#ifdef'=14
'#ifndef'=15
'#else'=16
'#endif'=17
'\\\n'=18

View File

@ -1,125 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
/**
* This class provides an empty implementation of {@link MacrosListener},
* which can be extended to create a listener which only needs to handle a subset
* of the available methods.
*/
public class MacrosBaseListener implements MacrosListener {
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterStmtSeq(MacrosParser.StmtSeqContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtSeq(MacrosParser.StmtSeqContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterStmtExpr(MacrosParser.StmtExprContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtExpr(MacrosParser.StmtExprContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprCast(MacrosParser.ExprCastContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprCast(MacrosParser.ExprCastContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprBinary(MacrosParser.ExprBinaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprBinary(MacrosParser.ExprBinaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprPar(MacrosParser.ExprParContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprPar(MacrosParser.ExprParContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprNumber(MacrosParser.ExprNumberContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprNumber(MacrosParser.ExprNumberContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterExprName(MacrosParser.ExprNameContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitExprName(MacrosParser.ExprNameContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void visitTerminal(TerminalNode node) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void visitErrorNode(ErrorNode node) { }
}

View File

@ -1,65 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link MacrosVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class MacrosBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements MacrosVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtSeq(MacrosParser.StmtSeqContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtExpr(MacrosParser.StmtExprContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprCast(MacrosParser.ExprCastContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprBinary(MacrosParser.ExprBinaryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprPar(MacrosParser.ExprParContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprNumber(MacrosParser.ExprNumberContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitExprName(MacrosParser.ExprNameContext ctx) { return visitChildren(ctx); }
}

View File

@ -1,74 +0,0 @@
token literal names:
null
';'
'*'
'/'
'+'
'-'
'('
')'
','
null
null
null
'#define'
'#undef'
'#ifdef'
'#ifndef'
'#else'
'#endif'
'\\\n'
null
token symbolic names:
null
null
null
null
null
null
PAR_BEGIN
PAR_END
COMMA
SIMPLETYPE
IDENTIFIER
NUMBER
DEFINE
UNDEF
IFDEF
IFNDEF
IFELSE
ENDIF
DEFINE_CONTINUE
WHITESPACE
rule names:
T__0
T__1
T__2
T__3
T__4
PAR_BEGIN
PAR_END
COMMA
SIMPLETYPE
IDENTIFIER
NUMBER
DEFINE
UNDEF
IFDEF
IFNDEF
IFELSE
ENDIF
DEFINE_CONTINUE
WHITESPACE
channel names:
DEFAULT_TOKEN_CHANNEL
HIDDEN
mode names:
DEFAULT_MODE
atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 21, 131, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 65, 10, 10, 3, 11, 3, 11, 7, 11, 69, 10, 11, 12, 11, 14, 11, 72, 11, 11, 3, 12, 6, 12, 75, 10, 12, 13, 12, 14, 12, 76, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20, 6, 20, 126, 10, 20, 13, 20, 14, 20, 127, 3, 20, 3, 20, 2, 2, 21, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 3, 2, 6, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59, 5, 2, 11, 12, 15, 15, 34, 34, 2, 134, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 3, 41, 3, 2, 2, 2, 5, 43, 3, 2, 2, 2, 7, 45, 3, 2, 2, 2, 9, 47, 3, 2, 2, 2, 11, 49, 3, 2, 2, 2, 13, 51, 3, 2, 2, 2, 15, 53, 3, 2, 2, 2, 17, 55, 3, 2, 2, 2, 19, 64, 3, 2, 2, 2, 21, 66, 3, 2, 2, 2, 23, 74, 3, 2, 2, 2, 25, 78, 3, 2, 2, 2, 27, 86, 3, 2, 2, 2, 29, 93, 3, 2, 2, 2, 31, 100, 3, 2, 2, 2, 33, 108, 3, 2, 2, 2, 35, 114, 3, 2, 2, 2, 37, 121, 3, 2, 2, 2, 39, 125, 3, 2, 2, 2, 41, 42, 7, 61, 2, 2, 42, 4, 3, 2, 2, 2, 43, 44, 7, 44, 2, 2, 44, 6, 3, 2, 2, 2, 45, 46, 7, 49, 2, 2, 46, 8, 3, 2, 2, 2, 47, 48, 7, 45, 2, 2, 48, 10, 3, 2, 2, 2, 49, 50, 7, 47, 2, 2, 50, 12, 3, 2, 2, 2, 51, 52, 7, 42, 2, 2, 52, 14, 3, 2, 2, 2, 53, 54, 7, 43, 2, 2, 54, 16, 3, 2, 2, 2, 55, 56, 7, 46, 2, 2, 56, 18, 3, 2, 2, 2, 57, 58, 7, 101, 2, 2, 58, 59, 7, 106, 2, 2, 59, 60, 7, 99, 2, 2, 60, 65, 7, 116, 2, 2, 61, 62, 7, 107, 2, 2, 62, 63, 7, 112, 2, 2, 63, 65, 7, 118, 2, 2, 64, 57, 3, 2, 2, 2, 64, 61, 3, 2, 2, 2, 65, 20, 3, 2, 2, 2, 66, 70, 9, 2, 2, 2, 67, 69, 9, 3, 2, 2, 68, 67, 3, 2, 2, 2, 69, 72, 3, 2, 2, 2, 70, 68, 3, 2, 2, 2, 70, 71, 3, 2, 2, 2, 71, 22, 3, 2, 2, 2, 72, 70, 3, 2, 2, 2, 73, 75, 9, 4, 2, 2, 74, 73, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 74, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 24, 3, 2, 2, 2, 78, 79, 7, 37, 2, 2, 79, 80, 7, 102, 2, 2, 80, 81, 7, 103, 2, 2, 81, 82, 7, 104, 2, 2, 82, 83, 7, 107, 2, 2, 83, 84, 7, 112, 2, 2, 84, 85, 7, 103, 2, 2, 85, 26, 3, 2, 2, 2, 86, 87, 7, 37, 2, 2, 87, 88, 7, 119, 2, 2, 88, 89, 7, 112, 2, 2, 89, 90, 7, 102, 2, 2, 90, 91, 7, 103, 2, 2, 91, 92, 7, 104, 2, 2, 92, 28, 3, 2, 2, 2, 93, 94, 7, 37, 2, 2, 94, 95, 7, 107, 2, 2, 95, 96, 7, 104, 2, 2, 96, 97, 7, 102, 2, 2, 97, 98, 7, 103, 2, 2, 98, 99, 7, 104, 2, 2, 99, 30, 3, 2, 2, 2, 100, 101, 7, 37, 2, 2, 101, 102, 7, 107, 2, 2, 102, 103, 7, 104, 2, 2, 103, 104, 7, 112, 2, 2, 104, 105, 7, 102, 2, 2, 105, 106, 7, 103, 2, 2, 106, 107, 7, 104, 2, 2, 107, 32, 3, 2, 2, 2, 108, 109, 7, 37, 2, 2, 109, 110, 7, 103, 2, 2, 110, 111, 7, 110, 2, 2, 111, 112, 7, 117, 2, 2, 112, 113, 7, 103, 2, 2, 113, 34, 3, 2, 2, 2, 114, 115, 7, 37, 2, 2, 115, 116, 7, 103, 2, 2, 116, 117, 7, 112, 2, 2, 117, 118, 7, 102, 2, 2, 118, 119, 7, 107, 2, 2, 119, 120, 7, 104, 2, 2, 120, 36, 3, 2, 2, 2, 121, 122, 7, 94, 2, 2, 122, 123, 7, 12, 2, 2, 123, 38, 3, 2, 2, 2, 124, 126, 9, 5, 2, 2, 125, 124, 3, 2, 2, 2, 126, 127, 3, 2, 2, 2, 127, 125, 3, 2, 2, 2, 127, 128, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 130, 8, 20, 2, 2, 130, 40, 3, 2, 2, 2, 7, 2, 64, 70, 76, 127, 3, 2, 3, 2]

View File

@ -1,159 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class MacrosLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.7.2", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, PAR_BEGIN=6, PAR_END=7, COMMA=8,
SIMPLETYPE=9, IDENTIFIER=10, NUMBER=11, DEFINE=12, UNDEF=13, IFDEF=14,
IFNDEF=15, IFELSE=16, ENDIF=17, DEFINE_CONTINUE=18, WHITESPACE=19;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"T__0", "T__1", "T__2", "T__3", "T__4", "PAR_BEGIN", "PAR_END", "COMMA",
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "UNDEF", "IFDEF", "IFNDEF",
"IFELSE", "ENDIF", "DEFINE_CONTINUE", "WHITESPACE"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, "';'", "'*'", "'/'", "'+'", "'-'", "'('", "')'", "','", null, null,
null, "'#define'", "'#undef'", "'#ifdef'", "'#ifndef'", "'#else'", "'#endif'",
"'\\\n'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, null, null, null, null, null, "PAR_BEGIN", "PAR_END", "COMMA",
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "UNDEF", "IFDEF", "IFNDEF",
"IFELSE", "ENDIF", "DEFINE_CONTINUE", "WHITESPACE"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public MacrosLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "Macros.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\25\u0083\b\1\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\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7"+
"\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n\5\nA\n\n\3\13\3\13\7"+
"\13E\n\13\f\13\16\13H\13\13\3\f\6\fK\n\f\r\f\16\fL\3\r\3\r\3\r\3\r\3\r"+
"\3\r\3\r\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3"+
"\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3"+
"\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\24\6"+
"\24~\n\24\r\24\16\24\177\3\24\3\24\2\2\25\3\3\5\4\7\5\t\6\13\7\r\b\17"+
"\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25\3\2\6"+
"\5\2C\\aac|\6\2\62;C\\aac|\3\2\62;\5\2\13\f\17\17\"\"\2\u0086\2\3\3\2"+
"\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17"+
"\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2"+
"\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3"+
"\2\2\2\2\'\3\2\2\2\3)\3\2\2\2\5+\3\2\2\2\7-\3\2\2\2\t/\3\2\2\2\13\61\3"+
"\2\2\2\r\63\3\2\2\2\17\65\3\2\2\2\21\67\3\2\2\2\23@\3\2\2\2\25B\3\2\2"+
"\2\27J\3\2\2\2\31N\3\2\2\2\33V\3\2\2\2\35]\3\2\2\2\37d\3\2\2\2!l\3\2\2"+
"\2#r\3\2\2\2%y\3\2\2\2\'}\3\2\2\2)*\7=\2\2*\4\3\2\2\2+,\7,\2\2,\6\3\2"+
"\2\2-.\7\61\2\2.\b\3\2\2\2/\60\7-\2\2\60\n\3\2\2\2\61\62\7/\2\2\62\f\3"+
"\2\2\2\63\64\7*\2\2\64\16\3\2\2\2\65\66\7+\2\2\66\20\3\2\2\2\678\7.\2"+
"\28\22\3\2\2\29:\7e\2\2:;\7j\2\2;<\7c\2\2<A\7t\2\2=>\7k\2\2>?\7p\2\2?"+
"A\7v\2\2@9\3\2\2\2@=\3\2\2\2A\24\3\2\2\2BF\t\2\2\2CE\t\3\2\2DC\3\2\2\2"+
"EH\3\2\2\2FD\3\2\2\2FG\3\2\2\2G\26\3\2\2\2HF\3\2\2\2IK\t\4\2\2JI\3\2\2"+
"\2KL\3\2\2\2LJ\3\2\2\2LM\3\2\2\2M\30\3\2\2\2NO\7%\2\2OP\7f\2\2PQ\7g\2"+
"\2QR\7h\2\2RS\7k\2\2ST\7p\2\2TU\7g\2\2U\32\3\2\2\2VW\7%\2\2WX\7w\2\2X"+
"Y\7p\2\2YZ\7f\2\2Z[\7g\2\2[\\\7h\2\2\\\34\3\2\2\2]^\7%\2\2^_\7k\2\2_`"+
"\7h\2\2`a\7f\2\2ab\7g\2\2bc\7h\2\2c\36\3\2\2\2de\7%\2\2ef\7k\2\2fg\7h"+
"\2\2gh\7p\2\2hi\7f\2\2ij\7g\2\2jk\7h\2\2k \3\2\2\2lm\7%\2\2mn\7g\2\2n"+
"o\7n\2\2op\7u\2\2pq\7g\2\2q\"\3\2\2\2rs\7%\2\2st\7g\2\2tu\7p\2\2uv\7f"+
"\2\2vw\7k\2\2wx\7h\2\2x$\3\2\2\2yz\7^\2\2z{\7\f\2\2{&\3\2\2\2|~\t\5\2"+
"\2}|\3\2\2\2~\177\3\2\2\2\177}\3\2\2\2\177\u0080\3\2\2\2\u0080\u0081\3"+
"\2\2\2\u0081\u0082\b\24\2\2\u0082(\3\2\2\2\7\2@FL\177\3\2\3\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@ -1,34 +0,0 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
PAR_BEGIN=6
PAR_END=7
COMMA=8
SIMPLETYPE=9
IDENTIFIER=10
NUMBER=11
DEFINE=12
UNDEF=13
IFDEF=14
IFNDEF=15
IFELSE=16
ENDIF=17
DEFINE_CONTINUE=18
WHITESPACE=19
';'=1
'*'=2
'/'=3
'+'=4
'-'=5
'('=6
')'=7
','=8
'#define'=12
'#undef'=13
'#ifdef'=14
'#ifndef'=15
'#else'=16
'#endif'=17
'\\\n'=18

View File

@ -1,94 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.tree.ParseTreeListener;
/**
* This interface defines a complete listener for a parse tree produced by
* {@link MacrosParser}.
*/
public interface MacrosListener extends ParseTreeListener {
/**
* Enter a parse tree produced by {@link MacrosParser#stmtSeq}.
* @param ctx the parse tree
*/
void enterStmtSeq(MacrosParser.StmtSeqContext ctx);
/**
* Exit a parse tree produced by {@link MacrosParser#stmtSeq}.
* @param ctx the parse tree
*/
void exitStmtSeq(MacrosParser.StmtSeqContext ctx);
/**
* Enter a parse tree produced by the {@code stmtExpr}
* labeled alternative in {@link MacrosParser#stmt}.
* @param ctx the parse tree
*/
void enterStmtExpr(MacrosParser.StmtExprContext ctx);
/**
* Exit a parse tree produced by the {@code stmtExpr}
* labeled alternative in {@link MacrosParser#stmt}.
* @param ctx the parse tree
*/
void exitStmtExpr(MacrosParser.StmtExprContext ctx);
/**
* Enter a parse tree produced by the {@code exprCast}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void enterExprCast(MacrosParser.ExprCastContext ctx);
/**
* Exit a parse tree produced by the {@code exprCast}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void exitExprCast(MacrosParser.ExprCastContext ctx);
/**
* Enter a parse tree produced by the {@code exprBinary}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void enterExprBinary(MacrosParser.ExprBinaryContext ctx);
/**
* Exit a parse tree produced by the {@code exprBinary}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void exitExprBinary(MacrosParser.ExprBinaryContext ctx);
/**
* Enter a parse tree produced by the {@code exprPar}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void enterExprPar(MacrosParser.ExprParContext ctx);
/**
* Exit a parse tree produced by the {@code exprPar}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void exitExprPar(MacrosParser.ExprParContext ctx);
/**
* Enter a parse tree produced by the {@code exprNumber}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void enterExprNumber(MacrosParser.ExprNumberContext ctx);
/**
* Exit a parse tree produced by the {@code exprNumber}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void exitExprNumber(MacrosParser.ExprNumberContext ctx);
/**
* Enter a parse tree produced by the {@code exprName}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void enterExprName(MacrosParser.ExprNameContext ctx);
/**
* Exit a parse tree produced by the {@code exprName}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
*/
void exitExprName(MacrosParser.ExprNameContext ctx);
}

View File

@ -1,533 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class MacrosParser extends Parser {
static { RuntimeMetaData.checkVersion("4.7.2", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, PAR_BEGIN=6, PAR_END=7, COMMA=8,
SIMPLETYPE=9, IDENTIFIER=10, NUMBER=11, DEFINE=12, UNDEF=13, IFDEF=14,
IFNDEF=15, IFELSE=16, ENDIF=17, DEFINE_CONTINUE=18, WHITESPACE=19;
public static final int
RULE_stmtSeq = 0, RULE_stmt = 1, RULE_expr = 2;
private static String[] makeRuleNames() {
return new String[] {
"stmtSeq", "stmt", "expr"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, "';'", "'*'", "'/'", "'+'", "'-'", "'('", "')'", "','", null, null,
null, "'#define'", "'#undef'", "'#ifdef'", "'#ifndef'", "'#else'", "'#endif'",
"'\\\n'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, null, null, null, null, null, "PAR_BEGIN", "PAR_END", "COMMA",
"SIMPLETYPE", "IDENTIFIER", "NUMBER", "DEFINE", "UNDEF", "IFDEF", "IFNDEF",
"IFELSE", "ENDIF", "DEFINE_CONTINUE", "WHITESPACE"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
@Override
public String getGrammarFileName() { return "Macros.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public ATN getATN() { return _ATN; }
public MacrosParser(TokenStream input) {
super(input);
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
public static class StmtSeqContext extends ParserRuleContext {
public List<StmtContext> stmt() {
return getRuleContexts(StmtContext.class);
}
public StmtContext stmt(int i) {
return getRuleContext(StmtContext.class,i);
}
public StmtSeqContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_stmtSeq; }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterStmtSeq(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitStmtSeq(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitStmtSeq(this);
else return visitor.visitChildren(this);
}
}
public final StmtSeqContext stmtSeq() throws RecognitionException {
StmtSeqContext _localctx = new StmtSeqContext(_ctx, getState());
enterRule(_localctx, 0, RULE_stmtSeq);
int _la;
try {
enterOuterAlt(_localctx, 1);
{
setState(9);
_errHandler.sync(this);
_la = _input.LA(1);
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << PAR_BEGIN) | (1L << IDENTIFIER) | (1L << NUMBER))) != 0)) {
{
{
setState(6);
stmt();
}
}
setState(11);
_errHandler.sync(this);
_la = _input.LA(1);
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class StmtContext extends ParserRuleContext {
public StmtContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_stmt; }
public StmtContext() { }
public void copyFrom(StmtContext ctx) {
super.copyFrom(ctx);
}
}
public static class StmtExprContext extends StmtContext {
public ExprContext expr() {
return getRuleContext(ExprContext.class,0);
}
public StmtExprContext(StmtContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterStmtExpr(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitStmtExpr(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitStmtExpr(this);
else return visitor.visitChildren(this);
}
}
public final StmtContext stmt() throws RecognitionException {
StmtContext _localctx = new StmtContext(_ctx, getState());
enterRule(_localctx, 2, RULE_stmt);
try {
_localctx = new StmtExprContext(_localctx);
enterOuterAlt(_localctx, 1);
{
setState(12);
expr(0);
setState(13);
match(T__0);
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
exitRule();
}
return _localctx;
}
public static class ExprContext extends ParserRuleContext {
public ExprContext(ParserRuleContext parent, int invokingState) {
super(parent, invokingState);
}
@Override public int getRuleIndex() { return RULE_expr; }
public ExprContext() { }
public void copyFrom(ExprContext ctx) {
super.copyFrom(ctx);
}
}
public static class ExprCastContext extends ExprContext {
public TerminalNode PAR_BEGIN() { return getToken(MacrosParser.PAR_BEGIN, 0); }
public TerminalNode SIMPLETYPE() { return getToken(MacrosParser.SIMPLETYPE, 0); }
public TerminalNode PAR_END() { return getToken(MacrosParser.PAR_END, 0); }
public ExprContext expr() {
return getRuleContext(ExprContext.class,0);
}
public ExprCastContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterExprCast(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitExprCast(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitExprCast(this);
else return visitor.visitChildren(this);
}
}
public static class ExprBinaryContext extends ExprContext {
public List<ExprContext> expr() {
return getRuleContexts(ExprContext.class);
}
public ExprContext expr(int i) {
return getRuleContext(ExprContext.class,i);
}
public TerminalNode COMMA() { return getToken(MacrosParser.COMMA, 0); }
public ExprBinaryContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterExprBinary(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitExprBinary(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitExprBinary(this);
else return visitor.visitChildren(this);
}
}
public static class ExprParContext extends ExprContext {
public TerminalNode PAR_BEGIN() { return getToken(MacrosParser.PAR_BEGIN, 0); }
public ExprContext expr() {
return getRuleContext(ExprContext.class,0);
}
public TerminalNode PAR_END() { return getToken(MacrosParser.PAR_END, 0); }
public ExprParContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterExprPar(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitExprPar(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitExprPar(this);
else return visitor.visitChildren(this);
}
}
public static class ExprNumberContext extends ExprContext {
public TerminalNode NUMBER() { return getToken(MacrosParser.NUMBER, 0); }
public ExprNumberContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterExprNumber(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitExprNumber(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitExprNumber(this);
else return visitor.visitChildren(this);
}
}
public static class ExprNameContext extends ExprContext {
public TerminalNode IDENTIFIER() { return getToken(MacrosParser.IDENTIFIER, 0); }
public ExprNameContext(ExprContext ctx) { copyFrom(ctx); }
@Override
public void enterRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).enterExprName(this);
}
@Override
public void exitRule(ParseTreeListener listener) {
if ( listener instanceof MacrosListener ) ((MacrosListener)listener).exitExprName(this);
}
@Override
public <T> T accept(ParseTreeVisitor<? extends T> visitor) {
if ( visitor instanceof MacrosVisitor ) return ((MacrosVisitor<? extends T>)visitor).visitExprName(this);
else return visitor.visitChildren(this);
}
}
public final ExprContext expr() throws RecognitionException {
return expr(0);
}
private ExprContext expr(int _p) throws RecognitionException {
ParserRuleContext _parentctx = _ctx;
int _parentState = getState();
ExprContext _localctx = new ExprContext(_ctx, _parentState);
ExprContext _prevctx = _localctx;
int _startState = 4;
enterRecursionRule(_localctx, 4, RULE_expr, _p);
try {
int _alt;
enterOuterAlt(_localctx, 1);
{
setState(26);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) {
case 1:
{
_localctx = new ExprCastContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(16);
match(PAR_BEGIN);
setState(17);
match(SIMPLETYPE);
setState(18);
match(PAR_END);
setState(19);
expr(9);
}
break;
case 2:
{
_localctx = new ExprNameContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(20);
match(IDENTIFIER);
}
break;
case 3:
{
_localctx = new ExprNumberContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(21);
match(NUMBER);
}
break;
case 4:
{
_localctx = new ExprParContext(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
setState(22);
match(PAR_BEGIN);
setState(23);
expr(0);
setState(24);
match(PAR_END);
}
break;
}
_ctx.stop = _input.LT(-1);
setState(45);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,3,_ctx);
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
if ( _alt==1 ) {
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
{
setState(43);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) {
case 1:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(28);
if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)");
setState(29);
match(T__1);
setState(30);
expr(6);
}
break;
case 2:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(31);
if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)");
setState(32);
match(T__2);
setState(33);
expr(5);
}
break;
case 3:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(34);
if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)");
setState(35);
match(T__3);
setState(36);
expr(4);
}
break;
case 4:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(37);
if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)");
setState(38);
match(T__4);
setState(39);
expr(3);
}
break;
case 5:
{
_localctx = new ExprBinaryContext(new ExprContext(_parentctx, _parentState));
pushNewRecursionContext(_localctx, _startState, RULE_expr);
setState(40);
if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)");
setState(41);
match(COMMA);
setState(42);
expr(2);
}
break;
}
}
}
setState(47);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,3,_ctx);
}
}
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.reportError(this, re);
_errHandler.recover(this, re);
}
finally {
unrollRecursionContexts(_parentctx);
}
return _localctx;
}
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
switch (ruleIndex) {
case 2:
return expr_sempred((ExprContext)_localctx, predIndex);
}
return true;
}
private boolean expr_sempred(ExprContext _localctx, int predIndex) {
switch (predIndex) {
case 0:
return precpred(_ctx, 5);
case 1:
return precpred(_ctx, 4);
case 2:
return precpred(_ctx, 3);
case 3:
return precpred(_ctx, 2);
case 4:
return precpred(_ctx, 1);
}
return true;
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\25\63\4\2\t\2\4\3"+
"\t\3\4\4\t\4\3\2\7\2\n\n\2\f\2\16\2\r\13\2\3\3\3\3\3\3\3\4\3\4\3\4\3\4"+
"\3\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\35\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3"+
"\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4.\n\4\f\4\16\4\61\13\4\3\4\2\3\6\5\2"+
"\4\6\2\2\28\2\13\3\2\2\2\4\16\3\2\2\2\6\34\3\2\2\2\b\n\5\4\3\2\t\b\3\2"+
"\2\2\n\r\3\2\2\2\13\t\3\2\2\2\13\f\3\2\2\2\f\3\3\2\2\2\r\13\3\2\2\2\16"+
"\17\5\6\4\2\17\20\7\3\2\2\20\5\3\2\2\2\21\22\b\4\1\2\22\23\7\b\2\2\23"+
"\24\7\13\2\2\24\25\7\t\2\2\25\35\5\6\4\13\26\35\7\f\2\2\27\35\7\r\2\2"+
"\30\31\7\b\2\2\31\32\5\6\4\2\32\33\7\t\2\2\33\35\3\2\2\2\34\21\3\2\2\2"+
"\34\26\3\2\2\2\34\27\3\2\2\2\34\30\3\2\2\2\35/\3\2\2\2\36\37\f\7\2\2\37"+
" \7\4\2\2 .\5\6\4\b!\"\f\6\2\2\"#\7\5\2\2#.\5\6\4\7$%\f\5\2\2%&\7\6\2"+
"\2&.\5\6\4\6\'(\f\4\2\2()\7\7\2\2).\5\6\4\5*+\f\3\2\2+,\7\n\2\2,.\5\6"+
"\4\4-\36\3\2\2\2-!\3\2\2\2-$\3\2\2\2-\'\3\2\2\2-*\3\2\2\2.\61\3\2\2\2"+
"/-\3\2\2\2/\60\3\2\2\2\60\7\3\2\2\2\61/\3\2\2\2\6\13\34-/";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@ -1,63 +0,0 @@
// Generated from /Users/jespergravgaard/c64/kickc/src/test/java/dk/camelot64/kickc/parsing/macros/Macros.g4 by ANTLR 4.7.2
package dk.camelot64.kickc.parsing.macros;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link MacrosParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface MacrosVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link MacrosParser#stmtSeq}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtSeq(MacrosParser.StmtSeqContext ctx);
/**
* Visit a parse tree produced by the {@code stmtExpr}
* labeled alternative in {@link MacrosParser#stmt}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtExpr(MacrosParser.StmtExprContext ctx);
/**
* Visit a parse tree produced by the {@code exprCast}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprCast(MacrosParser.ExprCastContext ctx);
/**
* Visit a parse tree produced by the {@code exprBinary}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprBinary(MacrosParser.ExprBinaryContext ctx);
/**
* Visit a parse tree produced by the {@code exprPar}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprPar(MacrosParser.ExprParContext ctx);
/**
* Visit a parse tree produced by the {@code exprNumber}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprNumber(MacrosParser.ExprNumberContext ctx);
/**
* Visit a parse tree produced by the {@code exprName}
* labeled alternative in {@link MacrosParser#expr}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitExprName(MacrosParser.ExprNameContext ctx);
}

View File

@ -1,16 +1,18 @@
package dk.camelot64.kickc.parsing.macros;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.preprocessor.CPreprocessor;
import dk.camelot64.kickc.preprocessor.CPreprocessorTokens;
import org.antlr.v4.runtime.*;
import dk.camelot64.kickc.parser.CParser;
import dk.camelot64.kickc.parser.KickCParser;
import dk.camelot64.kickc.parser.KickCParserBaseVisitor;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CodePointCharStream;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class TestMacrosParser {
private int CHANNEL_WHITESPACE = 1;
/**
* Test the C preprocessor
*/
public class TestPreprocessor {
/**
* Test some parsing without macros
@ -36,6 +38,8 @@ public class TestMacrosParser {
public void testSimpleDefine() {
// A simple unused define
assertEquals("+(name:b,num:1);*(name:c,num:2);", parse("#define A a\nb+1;\nc*2;\n"));
// A minimal used define
assertEquals("name:a;", parse("#define A a\nA;"));
// A simple used define
assertEquals("+(*(name:axe,num:2),name:axe);", parse("#define A axe\nA*2+A;"));
// A define using a special token class
@ -116,6 +120,47 @@ public class TestMacrosParser {
assertEquals("name:x2;name:y;", parse("#define A a\n#ifndef A\nx1;\n#else\nx2;\n#endif\ny;"));
}
/**
* Test #if
*/
@Test
public void testIf() {
// Output not generated by #if
assertEquals("name:y;", parse("#if 0\nx;\n#endif\ny;"));
// Output generated by #if
assertEquals("name:x;name:y;", parse("#define A 7\n#if 7\nx;\n#endif\ny;"));
// Output generated by #if using a sub-define
assertEquals("name:x;name:y;", parse("#define A 7\n#if A\nx;\n#endif\ny;"));
// Output not generated by #if using an undefined symbol
assertEquals("name:y;", parse("#if A\nx;\n#endif\ny;"));
// Output not generated by #if using an symbol==0
assertEquals("name:y;", parse("#define A 0\n#if A\nx;\n#endif\ny;"));
// Output generated by #if using an expression
assertEquals("name:x;name:y;", parse("#define A 7\n#if A==7\nx;\n#endif\ny;"));
// Output not generated by #if using an expression
assertEquals("name:y;", parse("#define A 7\n#if A==6\nx;\n#endif\ny;"));
// Output generated by #if using an expression
assertEquals("name:x;name:y;", parse("#define A 7\n#define B 8\n#if A<B\nx;\n#endif\ny;"));
// Output not generated by #if using an expression
assertEquals("name:y;", parse("#define A 7\n#define B 8\n#if A>B\nx;\n#endif\ny;"));
// Output generated by #if using an expression with a parenthesis
assertEquals("name:x;name:y;", parse("#define A 7\n#define B 8\n#if (A<B)\nx;\n#endif\ny;"));
// Output generated by #if using an expression with a few parenthesis
assertEquals("name:x;name:y;", parse("#define A 7\n#define B 8\n#if ((A)<(B))\nx;\n#endif\ny;"));
// Output not generated by #if using an expression with a few parenthesis
assertEquals("name:y;", parse("#define A 7\n#define B 8\n#if ((A)>(B))\nx;\n#endif\ny;"));
// Output generated by #if using a unary expression
assertEquals("name:x;name:y;", parse("#define A -10\n#define B 8\n#if A<-B\nx;\n#endif\ny;"));
// Output not generated by #if using a unary expression
assertEquals("name:y;", parse("#define A 7\n#define B 8\n#if !(A<B)\nx;\n#endif\ny;"));
// Output not generated by #if using an expression with an undefined symbol
assertEquals("name:y;", parse("#define A 7\n#if A<B\nx;\n#endif\ny;"));
// Output generated by #if using defined operator
assertEquals("name:x;name:y;", parse("#define A X\n#if defined A\nx;\n#endif\ny;"));
// Output not generated by #if using defined operator
assertEquals("name:y;", parse("#if defined A\nx;\n#endif\ny;"));
}
/**
* Test define with parameters
*/
@ -132,55 +177,27 @@ public class TestMacrosParser {
* @return The parse-tree in string form
*/
private String parse(String program) {
final CharStream fileStream = CharStreams.fromString(program);
// typedefs shared between lexer and parser
MacrosLexer lexer = new MacrosLexer(fileStream);
lexer.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(
Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
}
});
final CPreprocessorTokens preprocessorTokens = new CPreprocessorTokens(CHANNEL_WHITESPACE, MacrosLexer.WHITESPACE, MacrosLexer.DEFINE, MacrosLexer.IDENTIFIER, MacrosLexer.DEFINE_CONTINUE, MacrosLexer.UNDEF, MacrosLexer.IFDEF, MacrosLexer.IFNDEF, MacrosLexer.IFELSE, MacrosLexer.ENDIF, MacrosLexer.PAR_BEGIN, MacrosLexer.PAR_END, MacrosLexer.COMMA);
final CPreprocessor expandedTokenSource = new CPreprocessor(lexer, preprocessorTokens);
MacrosParser parser = new MacrosParser(new CommonTokenStream(expandedTokenSource));
parser.setBuildParseTree(true);
parser.addErrorListener(new BaseErrorListener() {
@Override
public void syntaxError(
Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
}
});
CodePointCharStream charStream = CharStreams.fromString(program);
CParser cParser = new CParser(null);
cParser.addSource(charStream);
KickCParser.StmtSeqContext stmtSeqContext = cParser.getParser().stmtSeq();
MacrosPrinter printVisitor = new MacrosPrinter();
printVisitor.visit(parser.stmtSeq());
printVisitor.visit(stmtSeqContext);
return printVisitor.getOut().toString();
}
private static class MacrosPrinter extends MacrosBaseVisitor<Object> {
private static class MacrosPrinter extends KickCParserBaseVisitor<Object> {
StringBuilder out = new StringBuilder();
public StringBuilder getOut() {
StringBuilder getOut() {
return out;
}
@Override
public Object visitStmtSeq(MacrosParser.StmtSeqContext ctx) {
for(MacrosParser.StmtContext stmtContext : ctx.stmt()) {
public Object visitStmtSeq(KickCParser.StmtSeqContext ctx) {
for(KickCParser.StmtContext stmtContext : ctx.stmt()) {
this.visit(stmtContext);
out.append(";");
}
@ -188,26 +205,20 @@ public class TestMacrosParser {
}
@Override
public Object visitStmtExpr(MacrosParser.StmtExprContext ctx) {
this.visit(ctx.expr());
public Object visitExprId(KickCParser.ExprIdContext ctx) {
out.append("name:").append(ctx.NAME().getText());
return null;
}
@Override
public Object visitExprName(MacrosParser.ExprNameContext ctx) {
out.append("name:").append(ctx.getText());
return null;
public Object visitExprNumber(KickCParser.ExprNumberContext ctx) {
return out.append("num:").append(ctx.NUMBER().getText());
}
@Override
public Object visitExprNumber(MacrosParser.ExprNumberContext ctx) {
return out.append("num:").append(ctx.getText());
}
@Override
public Object visitExprCast(MacrosParser.ExprCastContext ctx) {
public Object visitExprCast(KickCParser.ExprCastContext ctx) {
out.append("cast(");
out.append(ctx.SIMPLETYPE().getText());
out.append(ctx.typeSpecifier().getText());
out.append(",");
this.visit(ctx.expr());
out.append(")");
@ -215,7 +226,7 @@ public class TestMacrosParser {
}
@Override
public Object visitExprBinary(MacrosParser.ExprBinaryContext ctx) {
public Object visitExprBinary(KickCParser.ExprBinaryContext ctx) {
String fct = ctx.getChild(1).getText();
out.append(fct).append("(");
this.visit(ctx.expr(0));
@ -225,11 +236,10 @@ public class TestMacrosParser {
return null;
}
@Override
public Object visitExprPar(MacrosParser.ExprParContext ctx) {
public Object visitExprPar(KickCParser.ExprParContext ctx) {
out.append("(");
this.visit(ctx.expr());
this.visit(ctx.commaExpr());
out.append(")");
return null;
}