mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-06 18:20:17 +00:00
reimpl goto
This commit is contained in:
parent
5e11b9bf53
commit
dd6e8fab9b
@ -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 <identifier>
|
||||
$label <identifier>
|
||||
== <identifier> ==
|
||||
```
|
||||
|
||||
## Goto a label
|
||||
|
||||
```
|
||||
-> <identifier>
|
||||
```
|
||||
|
||||
## Example
|
||||
@ -18,7 +23,8 @@ $label <identifier>
|
||||
for i in range(10):
|
||||
for j in range(10):
|
||||
for k in range(10):
|
||||
$goto exit
|
||||
-> exit
|
||||
|
||||
$label exit
|
||||
== exit ==
|
||||
print('exit')
|
||||
```
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user