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 (',' parameterDecl)* ;
|
||||||
|
|
||||||
parameterDecl
|
parameterDecl
|
||||||
: directive* typeDecl directive* NAME ;
|
: directive* typeDecl directive* NAME #parameterDeclType
|
||||||
|
| SIMPLETYPE #parameterDeclVoid
|
||||||
|
;
|
||||||
|
|
||||||
directive
|
directive
|
||||||
: 'const' #directiveConst
|
: 'const' #directiveConst
|
||||||
|
@ -124,13 +124,25 @@ public class KickCBaseListener implements KickCListener {
|
|||||||
*
|
*
|
||||||
* <p>The default implementation does nothing.</p>
|
* <p>The default implementation does nothing.</p>
|
||||||
*/
|
*/
|
||||||
@Override public void enterParameterDecl(KickCParser.ParameterDeclContext ctx) { }
|
@Override public void enterParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) { }
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
* <p>The default implementation does nothing.</p>
|
* <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}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@ -80,7 +80,14 @@ public class KickCBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
|
|||||||
* <p>The default implementation returns the result of calling
|
* <p>The default implementation returns the result of calling
|
||||||
* {@link #visitChildren} on {@code ctx}.</p>
|
* {@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}
|
* {@inheritDoc}
|
||||||
*
|
*
|
||||||
|
@ -98,15 +98,29 @@ public interface KickCListener extends ParseTreeListener {
|
|||||||
*/
|
*/
|
||||||
void exitParameterListDecl(KickCParser.ParameterListDeclContext ctx);
|
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
|
* @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
|
* @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}
|
* Enter a parse tree produced by the {@code directiveConst}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* 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);
|
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
|
* @param ctx the parse tree
|
||||||
* @return the visitor result
|
* @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}
|
* Visit a parse tree produced by the {@code directiveConst}
|
||||||
* labeled alternative in {@link KickCParser#directive}.
|
* labeled alternative in {@link KickCParser#directive}.
|
||||||
|
@ -150,14 +150,25 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
public List<Variable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
|
public List<Variable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
|
||||||
ArrayList<Variable> parameterDecls = new ArrayList<>();
|
ArrayList<Variable> parameterDecls = new ArrayList<>();
|
||||||
for(KickCParser.ParameterDeclContext parameterDeclCtx : ctx.parameterDecl()) {
|
for(KickCParser.ParameterDeclContext parameterDeclCtx : ctx.parameterDecl()) {
|
||||||
Variable parameterDecl = (Variable) this.visit(parameterDeclCtx);
|
Object parameterDecl = this.visit(parameterDeclCtx);
|
||||||
parameterDecls.add(parameterDecl);
|
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;
|
return parameterDecls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Variable visitParameterDecl(KickCParser.ParameterDeclContext ctx) {
|
public Object visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) {
|
||||||
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
|
SymbolType type = (SymbolType) this.visit(ctx.typeDecl());
|
||||||
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type);
|
VariableUnversioned param = new VariableUnversioned(ctx.NAME().getText(), getCurrentScope(), type);
|
||||||
// Add directives
|
// Add directives
|
||||||
@ -165,6 +176,14 @@ public class Pass0GenerateStatementSequence extends KickCBaseVisitor<Object> {
|
|||||||
return param;
|
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
|
@Override
|
||||||
public Object visitDeclKasm(KickCParser.DeclKasmContext ctx) {
|
public Object visitDeclKasm(KickCParser.DeclKasmContext ctx) {
|
||||||
String kasm = ctx.KICKASM().getText();
|
String kasm = ctx.KICKASM().getText();
|
||||||
|
@ -32,6 +32,16 @@ public class TestPrograms {
|
|||||||
public 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
|
@Test
|
||||||
public void testFire() throws IOException, URISyntaxException {
|
public void testFire() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("examples/fire/fire");
|
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