diff --git a/docs/features/goto.md b/docs/features/goto.md index 5bd346c7..e5c77fd2 100644 --- a/docs/features/goto.md +++ b/docs/features/goto.md @@ -3,13 +3,18 @@ icon: dot title: Goto Statement --- -pkpy supports `goto` and `label` just like C. You are allowed to change the control flow unconditionally. +pkpy supports goto/label just like C. You are allowed to **change the control flow unconditionally**. -## Syntax +## Define a label ``` -$goto -$label +== == +``` + +## Goto a label + +``` +-> ``` ## Example @@ -18,7 +23,8 @@ $label for i in range(10): for j in range(10): for k in range(10): - $goto exit + -> exit -$label exit +== exit == +print('exit') ``` diff --git a/include/pocketpy/lexer.h b/include/pocketpy/lexer.h index 77dcfb04..b2652f79 100644 --- a/include/pocketpy/lexer.h +++ b/include/pocketpy/lexer.h @@ -22,8 +22,6 @@ constexpr const char* kTokens[] = { ".", ",", ":", ";", "#", "(", ")", "[", "]", "{", "}", "**", "=", ">", "<", "..", "...", "->", "?", "@", "==", "!=", ">=", "<=", "++", "--", "~", - /** SPEC_BEGIN **/ - "$goto", "$label", /** KW_BEGIN **/ "class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "yield", "None", "in", "is", "and", "or", "not", "True", "False", "global", "try", "except", "finally", diff --git a/src/compiler.cpp b/src/compiler.cpp index f96ac93b..9f2379a2 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -844,16 +844,17 @@ __EAT_DOTS_END: ctx()->emit(OP_WITH_EXIT, BC_NOARG, prev().line); } break; /*************************************************/ - case TK("$label"): { - if(mode()!=EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE"); + case TK("=="): { consume(TK("@id")); + if(mode()!=EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE"); bool ok = ctx()->add_label(prev().str()); + consume(TK("==")); if(!ok) SyntaxError("label " + prev().str().escape() + " already exists"); consume_end_stmt(); } break; - case TK("$goto"): - if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE"); + case TK("->"): consume(TK("@id")); + if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE"); ctx()->emit(OP_GOTO, StrName(prev().str()).index, prev().line); consume_end_stmt(); break; diff --git a/src/lexer.cpp b/src/lexer.cpp index d4df00a4..a0ff4f01 100644 --- a/src/lexer.cpp +++ b/src/lexer.cpp @@ -325,16 +325,6 @@ static bool is_unicode_Lo_char(uint32_t c) { eat_spaces(); return true; } - case '$': { - for(int i=TK("$goto"); i<=TK("$label"); i++){ - // +1 to skip the '$' - if(match_string(TK_STR(i) + 1)){ - add_token((TokenIndex)i); - return true; - } - } - SyntaxError("invalid special token"); - } return false; case '%': add_token_2('=', TK("%"), TK("%=")); return true; case '&': add_token_2('=', TK("&"), TK("&=")); return true; case '|': add_token_2('=', TK("|"), TK("|=")); return true; diff --git a/tests/27_goto.py b/tests/27_goto.py index e4552755..f884730f 100644 --- a/tests/27_goto.py +++ b/tests/27_goto.py @@ -2,9 +2,9 @@ a = [] for i in range(10): # [0] for j in range(10): # [0-0] - $goto test + -> test print(2) - $label test + == test == a.append(i) for k in range(5): # [0-1] for t in range(7): # [0-1-0] @@ -16,7 +16,7 @@ b = False for i in range(10): # [1] for j in range(10): # [1-0] - $goto out + -> out b = True -$label out +== out == assert not b \ No newline at end of file