1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Rewrote syntax to separate declarations and statements.

This commit is contained in:
jespergravgaard 2017-12-01 23:45:09 +01:00
parent fed99da261
commit 2f0bcfacd7
11 changed files with 1096 additions and 790 deletions

View File

@ -52,7 +52,7 @@ public class Compiler {
int charPositionInLine,
String msg,
RecognitionException e) {
throw new RuntimeException("Error parsing file " + input.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
throw new CompileError("Error parsing file " + input.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
}
});
return parser.file();

View File

@ -2,21 +2,39 @@
grammar KickC;
file :
stmtSeq EOF
declSeq EOF
;
asmFile :
asmLines EOF
;
declSeq
: decl+
;
decl
: typeDecl NAME '(' parameterListDecl? ')' '{' stmtSeq? '}' #declMethod
| declVar #declVariable
;
parameterListDecl
: parameterDecl (',' parameterDecl)* ;
parameterDecl
: typeDecl NAME ;
declVar
: ('const')? typeDecl NAME ('=' initializer)? ';'
;
stmtSeq
: stmt+
;
stmt
: '{' stmtSeq? '}' #stmtBlock
| typeDecl NAME '(' parameterListDecl? ')' '{' stmtSeq? '}' #stmtFunction
| ('const')? typeDecl NAME ('=' initializer)? ';' #stmtDeclaration
: declVar #stmtDeclVar
| '{' stmtSeq? '}' #stmtBlock
| lvalue '=' expr ';' #stmtAssignment
| expr ';' #stmtExpr
| 'if' '(' expr ')' stmt ( 'else' stmt )? #stmtIfElse
@ -36,12 +54,6 @@ forIteration
| ':' expr ( '..' ) expr #forRange
;
parameterListDecl
: parameterDecl (',' parameterDecl)* ;
parameterDecl
: typeDecl NAME ;
typeDecl
: SIMPLETYPE #typeSimple
| 'signed' SIMPLETYPE #typeSignedSimple

View File

@ -63,10 +63,10 @@ ASMREL=62
WS=63
COMMENT_LINE=64
COMMENT_BLOCK=65
'{'=1
'}'=2
'('=3
')'=4
'('=1
')'=2
'{'=3
'}'=4
'const'=5
'='=6
';'=7

View File

@ -35,6 +35,54 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitAsmFile(KickCParser.AsmFileContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDeclSeq(KickCParser.DeclSeqContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDeclSeq(KickCParser.DeclSeqContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDeclMethod(KickCParser.DeclMethodContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDeclMethod(KickCParser.DeclMethodContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDeclVariable(KickCParser.DeclVariableContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDeclVariable(KickCParser.DeclVariableContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDeclVar(KickCParser.DeclVarContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDeclVar(KickCParser.DeclVarContext ctx) { }
/**
* {@inheritDoc}
*
@ -47,6 +95,18 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtSeq(KickCParser.StmtSeqContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterStmtDeclVar(KickCParser.StmtDeclVarContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtDeclVar(KickCParser.StmtDeclVarContext ctx) { }
/**
* {@inheritDoc}
*
@ -59,30 +119,6 @@ public class KickCBaseListener implements KickCListener {
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtBlock(KickCParser.StmtBlockContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterStmtFunction(KickCParser.StmtFunctionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtFunction(KickCParser.StmtFunctionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterStmtDeclaration(KickCParser.StmtDeclarationContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitStmtDeclaration(KickCParser.StmtDeclarationContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -25,6 +25,34 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAsmFile(KickCParser.AsmFileContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDeclSeq(KickCParser.DeclSeqContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDeclMethod(KickCParser.DeclMethodContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDeclVariable(KickCParser.DeclVariableContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDeclVar(KickCParser.DeclVarContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@ -32,6 +60,13 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtSeq(KickCParser.StmtSeqContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtDeclVar(KickCParser.StmtDeclVarContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
@ -39,20 +74,6 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtBlock(KickCParser.StmtBlockContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtFunction(KickCParser.StmtFunctionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitStmtDeclaration(KickCParser.StmtDeclarationContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -49,7 +49,7 @@ public class KickCLexer extends Lexer {
};
private static final String[] _LITERAL_NAMES = {
null, "'{'", "'}'", "'('", "')'", "'const'", "'='", "';'", "'if'", "'else'",
null, "'('", "')'", "'{'", "'}'", "'const'", "'='", "';'", "'if'", "'else'",
"'while'", "'do'", "'for'", "'return'", "'asm'", "':'", "'..'", "','",
"'signed'", "'*'", "'['", "']'", "'<'", "'>'", "'--'", "'++'", "'+'",
"'-'", "'!'", "'&'", "'~'", "'>>'", "'<<'", "'/'", "'%'", "'=='", "'!='",
@ -204,8 +204,8 @@ public class KickCLexer extends Lexer {
"\2\2y\u027d\3\2\2\2{\u0284\3\2\2\2}\u0286\3\2\2\2\177\u0288\3\2\2\2\u0081"+
"\u028a\3\2\2\2\u0083\u0291\3\2\2\2\u0085\u0293\3\2\2\2\u0087\u0295\3\2"+
"\2\2\u0089\u029d\3\2\2\2\u008b\u02a3\3\2\2\2\u008d\u02ae\3\2\2\2\u008f"+
"\u0090\7}\2\2\u0090\4\3\2\2\2\u0091\u0092\7\177\2\2\u0092\6\3\2\2\2\u0093"+
"\u0094\7*\2\2\u0094\b\3\2\2\2\u0095\u0096\7+\2\2\u0096\n\3\2\2\2\u0097"+
"\u0090\7*\2\2\u0090\4\3\2\2\2\u0091\u0092\7+\2\2\u0092\6\3\2\2\2\u0093"+
"\u0094\7}\2\2\u0094\b\3\2\2\2\u0095\u0096\7\177\2\2\u0096\n\3\2\2\2\u0097"+
"\u0098\7e\2\2\u0098\u0099\7q\2\2\u0099\u009a\7p\2\2\u009a\u009b\7u\2\2"+
"\u009b\u009c\7v\2\2\u009c\f\3\2\2\2\u009d\u009e\7?\2\2\u009e\16\3\2\2"+
"\2\u009f\u00a0\7=\2\2\u00a0\20\3\2\2\2\u00a1\u00a2\7k\2\2\u00a2\u00a3"+

View File

@ -63,10 +63,10 @@ ASMREL=62
WS=63
COMMENT_LINE=64
COMMENT_BLOCK=65
'{'=1
'}'=2
'('=3
')'=4
'('=1
')'=2
'{'=3
'}'=4
'const'=5
'='=6
';'=7

View File

@ -27,6 +27,50 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitAsmFile(KickCParser.AsmFileContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#declSeq}.
* @param ctx the parse tree
*/
void enterDeclSeq(KickCParser.DeclSeqContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#declSeq}.
* @param ctx the parse tree
*/
void exitDeclSeq(KickCParser.DeclSeqContext ctx);
/**
* Enter a parse tree produced by the {@code declMethod}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
*/
void enterDeclMethod(KickCParser.DeclMethodContext ctx);
/**
* Exit a parse tree produced by the {@code declMethod}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
*/
void exitDeclMethod(KickCParser.DeclMethodContext ctx);
/**
* Enter a parse tree produced by the {@code declVariable}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
*/
void enterDeclVariable(KickCParser.DeclVariableContext ctx);
/**
* Exit a parse tree produced by the {@code declVariable}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
*/
void exitDeclVariable(KickCParser.DeclVariableContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#declVar}.
* @param ctx the parse tree
*/
void enterDeclVar(KickCParser.DeclVarContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#declVar}.
* @param ctx the parse tree
*/
void exitDeclVar(KickCParser.DeclVarContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#stmtSeq}.
* @param ctx the parse tree
@ -37,6 +81,18 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitStmtSeq(KickCParser.StmtSeqContext ctx);
/**
* Enter a parse tree produced by the {@code stmtDeclVar}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void enterStmtDeclVar(KickCParser.StmtDeclVarContext ctx);
/**
* Exit a parse tree produced by the {@code stmtDeclVar}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void exitStmtDeclVar(KickCParser.StmtDeclVarContext ctx);
/**
* Enter a parse tree produced by the {@code stmtBlock}
* labeled alternative in {@link KickCParser#stmt}.
@ -49,30 +105,6 @@ public interface KickCListener extends ParseTreeListener {
* @param ctx the parse tree
*/
void exitStmtBlock(KickCParser.StmtBlockContext ctx);
/**
* Enter a parse tree produced by the {@code stmtFunction}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void enterStmtFunction(KickCParser.StmtFunctionContext ctx);
/**
* Exit a parse tree produced by the {@code stmtFunction}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void exitStmtFunction(KickCParser.StmtFunctionContext ctx);
/**
* Enter a parse tree produced by the {@code stmtDeclaration}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void enterStmtDeclaration(KickCParser.StmtDeclarationContext ctx);
/**
* Exit a parse tree produced by the {@code stmtDeclaration}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
*/
void exitStmtDeclaration(KickCParser.StmtDeclarationContext ctx);
/**
* Enter a parse tree produced by the {@code stmtAssignment}
* labeled alternative in {@link KickCParser#stmt}.

File diff suppressed because it is too large Load Diff

View File

@ -22,12 +22,45 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitAsmFile(KickCParser.AsmFileContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#declSeq}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDeclSeq(KickCParser.DeclSeqContext ctx);
/**
* Visit a parse tree produced by the {@code declMethod}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDeclMethod(KickCParser.DeclMethodContext ctx);
/**
* Visit a parse tree produced by the {@code declVariable}
* labeled alternative in {@link KickCParser#decl}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDeclVariable(KickCParser.DeclVariableContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#declVar}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDeclVar(KickCParser.DeclVarContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#stmtSeq}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtSeq(KickCParser.StmtSeqContext ctx);
/**
* Visit a parse tree produced by the {@code stmtDeclVar}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtDeclVar(KickCParser.StmtDeclVarContext ctx);
/**
* Visit a parse tree produced by the {@code stmtBlock}
* labeled alternative in {@link KickCParser#stmt}.
@ -35,20 +68,6 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result
*/
T visitStmtBlock(KickCParser.StmtBlockContext ctx);
/**
* Visit a parse tree produced by the {@code stmtFunction}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtFunction(KickCParser.StmtFunctionContext ctx);
/**
* Visit a parse tree produced by the {@code stmtDeclaration}
* labeled alternative in {@link KickCParser#stmt}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitStmtDeclaration(KickCParser.StmtDeclarationContext ctx);
/**
* Visit a parse tree produced by the {@code stmtAssignment}
* labeled alternative in {@link KickCParser#stmt}.

View File

@ -52,15 +52,86 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
@Override
public Void visitFile(KickCParser.FileContext ctx) {
List<KickCParser.StmtContext> stmts = ctx.stmtSeq().stmt();
for (KickCParser.StmtContext stmt : stmts) {
if (stmt instanceof KickCParser.StmtDeclarationContext || stmt instanceof KickCParser.StmtFunctionContext) {
this.visit(stmt);
} else {
program.getLog().append("Statement not allowed outside method. " + stmt.getText());
throw new CompileError("Statement not allowed outside method. " + stmt.getText());
}
this.visit(ctx.declSeq());
return null;
}
@Override
public Object visitDeclSeq(KickCParser.DeclSeqContext ctx) {
for (KickCParser.DeclContext declContext : ctx.decl()) {
this.visit(declContext);
}
return null;
}
@Override
public Object visitDeclMethod(KickCParser.DeclMethodContext ctx) {
SymbolType type = (SymbolType) visit(ctx.typeDecl());
String name = ctx.NAME().getText();
Procedure procedure = getCurrentSymbols().addProcedure(name, type);
scopeStack.push(procedure);
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
VariableUnversioned returnVar = null;
if (!SymbolType.VOID.equals(type)) {
returnVar = procedure.addVariable("return", type);
}
List<Variable> parameterList = new ArrayList<>();
if (ctx.parameterListDecl() != null) {
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
}
procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedureBegin(procedure.getRef()));
if (ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq());
}
sequence.addStatement(new StatementLabel(procExit.getRef()));
if (returnVar != null) {
sequence.addStatement(new StatementAssignment(returnVar, returnVar));
}
VariableRef returnVarRef = null;
if (returnVar != null) {
returnVarRef = returnVar.getRef();
}
sequence.addStatement(new StatementReturn(returnVarRef));
scopeStack.pop();
sequence.addStatement(new StatementProcedureEnd(procedure.getRef()));
return null;
}
@Override
public List<Variable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
ArrayList<Variable> parameterDecls = new ArrayList<>();
for (KickCParser.ParameterDeclContext parameterDeclCtx : ctx.parameterDecl()) {
Variable parameterDecl = (Variable) this.visit(parameterDeclCtx);
parameterDecls.add(parameterDecl);
}
return parameterDecls;
}
@Override
public Variable visitParameterDecl(KickCParser.ParameterDeclContext ctx) {
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentSymbols(), type);
return param;
}
@Override
public Object visitDeclVariable(KickCParser.DeclVariableContext ctx) {
this.visit(ctx.declVar());
return null;
}
@Override
public Object visitDeclVar(KickCParser.DeclVarContext ctx) {
SymbolType type = (SymbolType) visit(ctx.typeDecl());
String varName = ctx.NAME().getText();
KickCParser.InitializerContext initializer = ctx.initializer();
VariableUnversioned lValue = getCurrentSymbols().addVariable(varName, type);
if (ctx.getChild(0).getText().equals("const")) {
lValue.setDeclaredConstant(true);
}
if (initializer != null) {
addInitialAssignment(initializer, lValue);
}
return null;
}
@ -274,39 +345,6 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
return null;
}
@Override
public Void visitStmtFunction(KickCParser.StmtFunctionContext ctx) {
SymbolType type = (SymbolType) visit(ctx.typeDecl());
String name = ctx.NAME().getText();
Procedure procedure = getCurrentSymbols().addProcedure(name, type);
scopeStack.push(procedure);
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
VariableUnversioned returnVar = null;
if (!SymbolType.VOID.equals(type)) {
returnVar = procedure.addVariable("return", type);
}
List<Variable> parameterList = new ArrayList<>();
if (ctx.parameterListDecl() != null) {
parameterList = (List<Variable>) this.visit(ctx.parameterListDecl());
}
procedure.setParameters(parameterList);
sequence.addStatement(new StatementProcedureBegin(procedure.getRef()));
if (ctx.stmtSeq() != null) {
this.visit(ctx.stmtSeq());
}
sequence.addStatement(new StatementLabel(procExit.getRef()));
if (returnVar != null) {
sequence.addStatement(new StatementAssignment(returnVar, returnVar));
}
VariableRef returnVarRef = null;
if (returnVar != null) {
returnVarRef = returnVar.getRef();
}
sequence.addStatement(new StatementReturn(returnVarRef));
scopeStack.pop();
sequence.addStatement(new StatementProcedureEnd(procedure.getRef()));
return null;
}
@Override
public Object visitStmtAsm(KickCParser.StmtAsmContext ctx) {
@ -314,28 +352,11 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
return null;
}
@Override
public List<Variable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
ArrayList<Variable> parameterDecls = new ArrayList<>();
for (KickCParser.ParameterDeclContext parameterDeclCtx : ctx.parameterDecl()) {
Variable parameterDecl = (Variable) this.visit(parameterDeclCtx);
parameterDecls.add(parameterDecl);
}
return parameterDecls;
}
@Override
public Variable visitParameterDecl(KickCParser.ParameterDeclContext ctx) {
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentSymbols(), type);
return param;
}
@Override
public Void visitStmtReturn(KickCParser.StmtReturnContext ctx) {
Procedure procedure = getCurrentProcedure();
KickCParser.ExprContext exprCtx = ctx.expr();
RValue rValue = null;
RValue rValue;
if (exprCtx != null) {
PrePostModifierHandler.addPreModifiers(this, exprCtx);
rValue = (RValue) this.visit(exprCtx);
@ -349,17 +370,8 @@ public class Pass1GenerateStatementSequence extends KickCBaseVisitor<Object> {
}
@Override
public Void visitStmtDeclaration(KickCParser.StmtDeclarationContext ctx) {
SymbolType type = (SymbolType) visit(ctx.typeDecl());
String varName = ctx.NAME().getText();
KickCParser.InitializerContext initializer = ctx.initializer();
VariableUnversioned lValue = getCurrentSymbols().addVariable(varName, type);
if (ctx.getChild(0).getText().equals("const")) {
lValue.setDeclaredConstant(true);
}
if (initializer != null) {
addInitialAssignment(initializer, lValue);
}
public Object visitStmtDeclVar(KickCParser.StmtDeclVarContext ctx) {
this.visit(ctx.declVar());
return null;
}