1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-20 02:32:36 +00:00

Added support for void parameter lists. Closes #161

This commit is contained in:
jespergravgaard 2019-04-08 23:27:05 +02:00
parent 9a9e4f456e
commit c3849c78b0
10 changed files with 714 additions and 593 deletions

View File

@ -39,7 +39,9 @@ parameterListDecl
: parameterDecl (',' parameterDecl)* ;
parameterDecl
: directive* typeDecl directive* NAME ;
: directive* typeDecl directive* NAME #parameterDeclType
| SIMPLETYPE #parameterDeclVoid
;
directive
: 'const' #directiveConst

View File

@ -124,13 +124,25 @@ public class KickCBaseListener implements KickCListener {
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterParameterDecl(KickCParser.ParameterDeclContext ctx) { }
@Override public void enterParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitParameterDecl(KickCParser.ParameterDeclContext ctx) { }
@Override public void exitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { }
/**
* {@inheritDoc}
*

View File

@ -80,7 +80,14 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParameterDecl(KickCParser.ParameterDeclContext ctx) { return visitChildren(ctx); }
@Override public T visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*

View File

@ -98,15 +98,29 @@ public interface KickCListener extends ParseTreeListener {
*/
void exitParameterListDecl(KickCParser.ParameterListDeclContext ctx);
/**
* Enter a parse tree produced by {@link KickCParser#parameterDecl}.
* Enter a parse tree produced by the {@code parameterDeclType}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
*/
void enterParameterDecl(KickCParser.ParameterDeclContext ctx);
void enterParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
/**
* Exit a parse tree produced by {@link KickCParser#parameterDecl}.
* Exit a parse tree produced by the {@code parameterDeclType}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
*/
void exitParameterDecl(KickCParser.ParameterDeclContext ctx);
void exitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
/**
* Enter a parse tree produced by the {@code parameterDeclVoid}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
*/
void enterParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
/**
* Exit a parse tree produced by the {@code parameterDeclVoid}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
*/
void exitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
/**
* Enter a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}.

File diff suppressed because it is too large Load Diff

View File

@ -65,11 +65,19 @@ public interface KickCVisitor<T> extends ParseTreeVisitor<T> {
*/
T visitParameterListDecl(KickCParser.ParameterListDeclContext ctx);
/**
* Visit a parse tree produced by {@link KickCParser#parameterDecl}.
* Visit a parse tree produced by the {@code parameterDeclType}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParameterDecl(KickCParser.ParameterDeclContext ctx);
T visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx);
/**
* Visit a parse tree produced by the {@code parameterDeclVoid}
* labeled alternative in {@link KickCParser#parameterDecl}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx);
/**
* Visit a parse tree produced by the {@code directiveConst}
* labeled alternative in {@link KickCParser#directive}.

View File

@ -150,14 +150,25 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
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);
Object parameterDecl = this.visit(parameterDeclCtx);
if(parameterDecl.equals(SymbolType.VOID)) {
if(ctx.parameterDecl().size() == 1) {
// A single void parameter decl - equals zero parameters
return new ArrayList<>();
} else {
throw new CompileError("Illegal void parameter." , new StatementSource(ctx));
}
} else if(parameterDecl instanceof Variable) {
parameterDecls.add((Variable) parameterDecl);
} else {
throw new CompileError("Unknown parameter " + ctx.getText(), new StatementSource(ctx));
}
}
return parameterDecls;
}
@Override
public Variable visitParameterDecl(KickCParser.ParameterDeclContext ctx) {
public Object visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) {
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type);
// Add directives
@ -165,6 +176,14 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
return param;
}
@Override
public Object visitParameterDeclVoid(KickCParser.ParameterDeclVoidContext ctx) {
if(!SymbolType.VOID.getTypeName().equals(ctx.SIMPLETYPE().getText())) {
throw new CompileError("Illegal unnamed parameter " + ctx.SIMPLETYPE().getText(), new StatementSource(ctx));
}
return SymbolType.VOID;
}
@Override
public Object visitDeclKasm(KickCParser.DeclKasmContext ctx) {
String kasm = ctx.KICKASM().getText();

View File

@ -32,6 +32,16 @@ public class TestPrograms {
public TestPrograms() {
}
@Test
public void testIllegalVoidParameter() throws IOException, URISyntaxException {
assertError("illegal-void-parameter", "Illegal void parameter");
}
@Test
public void testIllegalUnnamedParameter() throws IOException, URISyntaxException {
assertError("illegal-unnamed-parameter", "Illegal unnamed parameter");
}
@Test
public void testFire() throws IOException, URISyntaxException {
compileAndCompare("examples/fire/fire");

View File

@ -0,0 +1,4 @@
// Tests that the compiler complains if a non-void parameter has no name
void main(char) {
}

View File

@ -0,0 +1,4 @@
// Tests that the compiler complains if a non-void parameter has no name
void main(char c, void) {
}