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
|
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>
|
== <identifier> ==
|
||||||
$label <identifier>
|
```
|
||||||
|
|
||||||
|
## Goto a label
|
||||||
|
|
||||||
|
```
|
||||||
|
-> <identifier>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
@ -18,7 +23,8 @@ $label <identifier>
|
|||||||
for i in range(10):
|
for i in range(10):
|
||||||
for j in range(10):
|
for j in range(10):
|
||||||
for k 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 **/
|
/** KW_BEGIN **/
|
||||||
"class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "yield",
|
"class", "import", "as", "def", "lambda", "pass", "del", "from", "with", "yield",
|
||||||
"None", "in", "is", "and", "or", "not", "True", "False", "global", "try", "except", "finally",
|
"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);
|
ctx()->emit(OP_WITH_EXIT, BC_NOARG, prev().line);
|
||||||
} break;
|
} break;
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
case TK("$label"): {
|
case TK("=="): {
|
||||||
if(mode()!=EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE");
|
|
||||||
consume(TK("@id"));
|
consume(TK("@id"));
|
||||||
|
if(mode()!=EXEC_MODE) SyntaxError("'label' is only available in EXEC_MODE");
|
||||||
bool ok = ctx()->add_label(prev().str());
|
bool ok = ctx()->add_label(prev().str());
|
||||||
|
consume(TK("=="));
|
||||||
if(!ok) SyntaxError("label " + prev().str().escape() + " already exists");
|
if(!ok) SyntaxError("label " + prev().str().escape() + " already exists");
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
} break;
|
} break;
|
||||||
case TK("$goto"):
|
case TK("->"):
|
||||||
if(mode()!=EXEC_MODE) SyntaxError("'goto' is only available in EXEC_MODE");
|
|
||||||
consume(TK("@id"));
|
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);
|
ctx()->emit(OP_GOTO, StrName(prev().str()).index, prev().line);
|
||||||
consume_end_stmt();
|
consume_end_stmt();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -325,16 +325,6 @@ static bool is_unicode_Lo_char(uint32_t c) {
|
|||||||
eat_spaces();
|
eat_spaces();
|
||||||
return true;
|
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;
|
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 i in range(10): # [0]
|
||||||
for j in range(10): # [0-0]
|
for j in range(10): # [0-0]
|
||||||
$goto test
|
-> test
|
||||||
print(2)
|
print(2)
|
||||||
$label test
|
== test ==
|
||||||
a.append(i)
|
a.append(i)
|
||||||
for k in range(5): # [0-1]
|
for k in range(5): # [0-1]
|
||||||
for t in range(7): # [0-1-0]
|
for t in range(7): # [0-1-0]
|
||||||
@ -16,7 +16,7 @@ b = False
|
|||||||
|
|
||||||
for i in range(10): # [1]
|
for i in range(10): # [1]
|
||||||
for j in range(10): # [1-0]
|
for j in range(10): # [1-0]
|
||||||
$goto out
|
-> out
|
||||||
b = True
|
b = True
|
||||||
$label out
|
== out ==
|
||||||
assert not b
|
assert not b
|
||||||
Loading…
x
Reference in New Issue
Block a user