From 2f18ecbaa15f50459ecfd864495b953a23191732 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Fri, 29 Jul 2022 19:33:31 +0900 Subject: [PATCH] Support 'else' block on 'try' --- src/compiler.c | 15 ++++++++++++--- test/testTryElse.krk | 26 ++++++++++++++++++++++++++ test/testTryElse.krk.expect | 8 ++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 test/testTryElse.krk create mode 100644 test/testTryElse.krk.expect diff --git a/src/compiler.c b/src/compiler.c index 46054357..cfa3e94a 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -2205,6 +2205,7 @@ static void tryStatement(struct GlobalState * state) { exitJumpOffsets[0] = emitJump(OP_JUMP); patchJump(tryJump); + int firstJump = 0; int nextJump = -1; _anotherExcept: @@ -2215,7 +2216,7 @@ static void tryStatement(struct GlobalState * state) { previous = state->parser.previous; advance(); } - if (match(TOKEN_EXCEPT)) { + if (exitJumps && !firstJump && match(TOKEN_EXCEPT)) { if (nextJump != -1) { patchJump(nextJump); emitByte(OP_POP); @@ -2254,10 +2255,18 @@ static void tryStatement(struct GlobalState * state) { return; } + goto _anotherExcept; + } else if (firstJump != 1 && match(TOKEN_ELSE)) { + consume(TOKEN_COLON, "Expected ':' after 'else'."); + patchJump(exitJumpOffsets[0]); + firstJump = 1; + beginScope(state); + block(state, blockWidth, "else"); + endScope(state); goto _anotherExcept; } else if (match(TOKEN_FINALLY)) { consume(TOKEN_COLON, "Expected ':' after 'finally'."); - for (int i = 0; i < exitJumps; ++i) { + for (int i = firstJump; i < exitJumps; ++i) { patchJump(exitJumpOffsets[i]); } size_t nameInd = renameLocal(state, exceptionObject, syntheticToken("__tmp")); @@ -2285,7 +2294,7 @@ static void tryStatement(struct GlobalState * state) { } } - for (int i = 0; i < exitJumps; ++i) { + for (int i = firstJump; i < exitJumps; ++i) { patchJump(exitJumpOffsets[i]); } diff --git a/test/testTryElse.krk b/test/testTryElse.krk new file mode 100644 index 00000000..bc618a28 --- /dev/null +++ b/test/testTryElse.krk @@ -0,0 +1,26 @@ +try: + print('totally fine') +except: + print('impossible!') +else: + print('good to go') +finally: + print('then the finally') + +try: + print('totally fine') +except: + print('impossible!') +else: + print('good to go') + +try: + print('in the try') + raise ValueError() + print('oh no, fail') +except: + print('does the except') +else: + print('should not happen, fail') +finally: + print('does the finally') diff --git a/test/testTryElse.krk.expect b/test/testTryElse.krk.expect new file mode 100644 index 00000000..5063ceec --- /dev/null +++ b/test/testTryElse.krk.expect @@ -0,0 +1,8 @@ +totally fine +good to go +then the finally +totally fine +good to go +in the try +does the except +does the finally