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:
parent
9a9e4f456e
commit
c3849c78b0
@ -39,7 +39,9 @@ parameterListDecl
|
||||
: parameterDecl (',' parameterDecl)* ;
|
||||
|
||||
parameterDecl
|
||||
: directive* typeDecl directive* NAME ;
|
||||
: directive* typeDecl directive* NAME #parameterDeclType
|
||||
| SIMPLETYPE #parameterDeclVoid
|
||||
;
|
||||
|
||||
directive
|
||||
: 'const' #directiveConst
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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
@ -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}.
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
4
src/test/kc/illegal-unnamed-parameter.kc
Normal file
4
src/test/kc/illegal-unnamed-parameter.kc
Normal file
@ -0,0 +1,4 @@
|
||||
// Tests that the compiler complains if a non-void parameter has no name
|
||||
|
||||
void main(char) {
|
||||
}
|
4
src/test/kc/illegal-void-parameter.kc
Normal file
4
src/test/kc/illegal-void-parameter.kc
Normal file
@ -0,0 +1,4 @@
|
||||
// Tests that the compiler complains if a non-void parameter has no name
|
||||
|
||||
void main(char c, void) {
|
||||
}
|
Loading…
Reference in New Issue
Block a user