mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-11 04:49:47 +00:00
Better error when encountering continue in switch that is not inside loop. Closes #282
This commit is contained in:
parent
0fb90dc8b7
commit
bfe90bdf04
@ -855,8 +855,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
/** The label that a continue will jump to. Null if no continue has been encountered. */
|
/** The label that a continue will jump to. Null if no continue has been encountered. */
|
||||||
Label continueLabel;
|
Label continueLabel;
|
||||||
|
|
||||||
public Loop(Scope loopScope) {
|
/** true if the loop is a switch-statement. */
|
||||||
|
boolean isSwitch;
|
||||||
|
|
||||||
|
public Loop(Scope loopScope, boolean isSwitch) {
|
||||||
this.loopScope = loopScope;
|
this.loopScope = loopScope;
|
||||||
|
this.isSwitch = isSwitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
Label getBreakLabel() {
|
Label getBreakLabel() {
|
||||||
@ -895,7 +899,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
// Create the block scope early - to keep all statements of the loop inside it
|
// Create the block scope early - to keep all statements of the loop inside it
|
||||||
BlockScope blockScope = getCurrentScope().addBlockScope();
|
BlockScope blockScope = getCurrentScope().addBlockScope();
|
||||||
scopeStack.push(blockScope);
|
scopeStack.push(blockScope);
|
||||||
loopStack.push(new Loop(blockScope));
|
loopStack.push(new Loop(blockScope, false));
|
||||||
Label beginJumpLabel = getCurrentScope().addLabelIntermediate();
|
Label beginJumpLabel = getCurrentScope().addLabelIntermediate();
|
||||||
Label doJumpLabel = getCurrentScope().addLabelIntermediate();
|
Label doJumpLabel = getCurrentScope().addLabelIntermediate();
|
||||||
Label endJumpLabel = getCurrentScope().addLabelIntermediate();
|
Label endJumpLabel = getCurrentScope().addLabelIntermediate();
|
||||||
@ -930,7 +934,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
// Create the block scope early - to keep all statements of the loop inside it
|
// Create the block scope early - to keep all statements of the loop inside it
|
||||||
BlockScope blockScope = getCurrentScope().addBlockScope();
|
BlockScope blockScope = getCurrentScope().addBlockScope();
|
||||||
scopeStack.push(blockScope);
|
scopeStack.push(blockScope);
|
||||||
loopStack.push(new Loop(blockScope));
|
loopStack.push(new Loop(blockScope, false));
|
||||||
List<Comment> comments = ensureUnusedComments(getCommentsSymbol(ctx));
|
List<Comment> comments = ensureUnusedComments(getCommentsSymbol(ctx));
|
||||||
Label beginJumpLabel = getCurrentScope().addLabelIntermediate();
|
Label beginJumpLabel = getCurrentScope().addLabelIntermediate();
|
||||||
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), StatementSource.doWhile(ctx), comments);
|
StatementLabel beginJumpTarget = new StatementLabel(beginJumpLabel.getRef(), StatementSource.doWhile(ctx), comments);
|
||||||
@ -957,7 +961,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
// Create a block scope - to keep all statements of the loop inside it
|
// Create a block scope - to keep all statements of the loop inside it
|
||||||
BlockScope blockScope = getCurrentScope().addBlockScope();
|
BlockScope blockScope = getCurrentScope().addBlockScope();
|
||||||
scopeStack.push(blockScope);
|
scopeStack.push(blockScope);
|
||||||
Loop switchLoop = new Loop(blockScope);
|
Loop switchLoop = new Loop(blockScope, true);
|
||||||
if(containingLoop != null) {
|
if(containingLoop != null) {
|
||||||
switchLoop.setContinueLabel(containingLoop.getOrCreateContinueLabel());
|
switchLoop.setContinueLabel(containingLoop.getOrCreateContinueLabel());
|
||||||
}
|
}
|
||||||
@ -1030,7 +1034,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
public Object visitForClassic(KickCParser.ForClassicContext ctx) {
|
public Object visitForClassic(KickCParser.ForClassicContext ctx) {
|
||||||
BlockScope blockScope = getCurrentScope().addBlockScope();
|
BlockScope blockScope = getCurrentScope().addBlockScope();
|
||||||
scopeStack.push(blockScope);
|
scopeStack.push(blockScope);
|
||||||
loopStack.push(new Loop(blockScope));
|
loopStack.push(new Loop(blockScope, false));
|
||||||
// Add initialization
|
// Add initialization
|
||||||
this.visit(ctx.forClassicInit());
|
this.visit(ctx.forClassicInit());
|
||||||
KickCParser.StmtForContext stmtForCtx = (KickCParser.StmtForContext) ctx.getParent();
|
KickCParser.StmtForContext stmtForCtx = (KickCParser.StmtForContext) ctx.getParent();
|
||||||
@ -1086,7 +1090,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
public Object visitForRange(KickCParser.ForRangeContext ctx) {
|
public Object visitForRange(KickCParser.ForRangeContext ctx) {
|
||||||
BlockScope blockScope = getCurrentScope().addBlockScope();
|
BlockScope blockScope = getCurrentScope().addBlockScope();
|
||||||
scopeStack.push(blockScope);
|
scopeStack.push(blockScope);
|
||||||
loopStack.push(new Loop(blockScope));
|
loopStack.push(new Loop(blockScope, false));
|
||||||
|
|
||||||
StatementSource statementSource = StatementSource.forRanged(ctx);
|
StatementSource statementSource = StatementSource.forRanged(ctx);
|
||||||
|
|
||||||
@ -1194,7 +1198,15 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
throw new CompileError("Continue not inside a loop! ", new StatementSource(ctx));
|
throw new CompileError("Continue not inside a loop! ", new StatementSource(ctx));
|
||||||
}
|
}
|
||||||
Loop currentLoop = loopStack.peek();
|
Loop currentLoop = loopStack.peek();
|
||||||
Label continueLabel = currentLoop.getOrCreateContinueLabel();
|
Label continueLabel;
|
||||||
|
if(currentLoop.isSwitch) {
|
||||||
|
continueLabel = currentLoop.getContinueLabel();
|
||||||
|
if(continueLabel==null) {
|
||||||
|
throw new CompileError("Continue not inside a loop! ", new StatementSource(ctx));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
continueLabel = currentLoop.getOrCreateContinueLabel();
|
||||||
|
}
|
||||||
Statement continueJmpStmt = new StatementJump(continueLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS);
|
Statement continueJmpStmt = new StatementJump(continueLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS);
|
||||||
sequence.addStatement(continueJmpStmt);
|
sequence.addStatement(continueJmpStmt);
|
||||||
return null;
|
return null;
|
||||||
|
@ -36,7 +36,6 @@ public class TestPrograms {
|
|||||||
public TestPrograms() {
|
public TestPrograms() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAsmMnemonicNames() throws IOException, URISyntaxException {
|
public void testAsmMnemonicNames() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("asm-mnemonic-names");
|
compileAndCompare("asm-mnemonic-names");
|
||||||
@ -47,7 +46,6 @@ public class TestPrograms {
|
|||||||
compileAndCompare("parse-negated-struct-ref");
|
compileAndCompare("parse-negated-struct-ref");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongPointer1() throws IOException, URISyntaxException {
|
public void testLongPointer1() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("long-pointer-1");
|
compileAndCompare("long-pointer-1");
|
||||||
@ -124,13 +122,10 @@ public class TestPrograms {
|
|||||||
// compileAndCompare("loophead-problem");
|
// compileAndCompare("loophead-problem");
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// TODO: Fail with proper error when continue is encountered without a loop https://gitlab.com/camelot/kickc/issues/282
|
|
||||||
/*
|
|
||||||
@Test
|
@Test
|
||||||
public void testSwitch3Err() throws IOException, URISyntaxException {
|
public void testSwitch3Err() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("switch-3-err");
|
assertError("switch-3-err", "Continue not inside a loop!");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSwitch4() throws IOException, URISyntaxException {
|
public void testSwitch4() throws IOException, URISyntaxException {
|
||||||
|
Loading…
Reference in New Issue
Block a user