Add continue
and break
as aliases for skip
/stop
, also improve
keyword detection using a binary search
This commit is contained in:
parent
1d2e55f53d
commit
6cf980ea71
@ -86,11 +86,12 @@ func main()
|
||||
>> [x*10 for x in my_numbers if x != 20]
|
||||
= [100, 300]
|
||||
|
||||
# Loop control flow uses "skip" and "stop"
|
||||
# Loop control flow uses "skip"/"continue" and "stop"/"break"
|
||||
for x in my_numbers
|
||||
for y in my_numbers
|
||||
if x == y
|
||||
skip
|
||||
continue # This is the same as `skip`
|
||||
|
||||
# For readability, you can also use postfix conditionals:
|
||||
skip if x == y
|
||||
@ -99,6 +100,7 @@ func main()
|
||||
# Skip or stop can specify a loop variable if you want to
|
||||
# affect an enclosing loop:
|
||||
stop x
|
||||
break x # This is the same as `stop x`
|
||||
|
||||
# Tables are efficient hash maps
|
||||
table := {"one"=1, "two"=2}
|
||||
|
@ -1338,7 +1338,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
|
||||
}
|
||||
}
|
||||
if (env->loop_ctx)
|
||||
code_err(ast, "This 'skip' is not inside any loop");
|
||||
code_err(ast, "This is not inside any loop");
|
||||
else if (target)
|
||||
code_err(ast, "No loop target named '", target, "' was found");
|
||||
else
|
||||
@ -1367,7 +1367,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
|
||||
}
|
||||
}
|
||||
if (env->loop_ctx)
|
||||
code_err(ast, "This 'stop' is not inside any loop");
|
||||
code_err(ast, "This is not inside any loop");
|
||||
else if (target)
|
||||
code_err(ast, "No loop target named '", target, "' was found");
|
||||
else
|
||||
|
33
src/parse.c
33
src/parse.c
@ -61,10 +61,10 @@ int op_tightness[] = {
|
||||
};
|
||||
|
||||
static const char *keywords[] = {
|
||||
"yes", "xor", "while", "when", "use", "unless", "then", "struct", "stop", "skip", "return",
|
||||
"or", "not", "none", "no", "mod1", "mod", "pass", "lang", "inline", "in", "if",
|
||||
"func", "for", "extern", "extend", "enum", "else", "do", "deserialize", "defer", "and",
|
||||
"_min_", "_max_", NULL,
|
||||
"_max_", "_min_", "and", "break", "continue", "defer", "deserialize", "do", "else", "enum",
|
||||
"extend", "extern", "for", "func", "if", "in", "inline", "lang", "mod", "mod1", "no", "none",
|
||||
"not", "or", "pass", "return", "skip", "skip", "stop", "struct", "then", "unless", "use", "when",
|
||||
"while", "xor", "yes",
|
||||
};
|
||||
|
||||
enum {NORMAL_FUNCTION=0, EXTERN_FUNCTION=1};
|
||||
@ -379,13 +379,26 @@ const char *get_word(const char **inout) {
|
||||
return GC_strndup(word, (size_t)((const char*)pos - word));
|
||||
}
|
||||
|
||||
static CONSTFUNC bool is_keyword(const char *word) {
|
||||
int64_t lo = 0, hi = sizeof(keywords)/sizeof(keywords[0])-1;
|
||||
while (lo <= hi) {
|
||||
int64_t mid = (lo + hi) / 2;
|
||||
int32_t cmp = strcmp(word, keywords[mid]);
|
||||
if (cmp == 0)
|
||||
return true;
|
||||
else if (cmp > 0)
|
||||
lo = mid + 1;
|
||||
else if (cmp < 0)
|
||||
hi = mid - 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *get_id(const char **inout) {
|
||||
const char *pos = *inout;
|
||||
const char *word = get_word(&pos);
|
||||
if (!word) return word;
|
||||
for (int i = 0; keywords[i]; i++)
|
||||
if (strcmp(word, keywords[i]) == 0)
|
||||
return NULL;
|
||||
if (!word || is_keyword(word))
|
||||
return NULL;
|
||||
*inout = pos;
|
||||
return word;
|
||||
}
|
||||
@ -1346,7 +1359,7 @@ PARSER(parse_defer) {
|
||||
|
||||
PARSER(parse_skip) {
|
||||
const char *start = pos;
|
||||
if (!match_word(&pos, "skip")) return NULL;
|
||||
if (!match_word(&pos, "continue") && !match_word(&pos, "skip")) return NULL;
|
||||
const char *target;
|
||||
if (match_word(&pos, "for")) target = "for";
|
||||
else if (match_word(&pos, "while")) target = "while";
|
||||
@ -1358,7 +1371,7 @@ PARSER(parse_skip) {
|
||||
|
||||
PARSER(parse_stop) {
|
||||
const char *start = pos;
|
||||
if (!match_word(&pos, "stop")) return NULL;
|
||||
if (!match_word(&pos, "stop") && !match_word(&pos, "break")) return NULL;
|
||||
const char *target;
|
||||
if (match_word(&pos, "for")) target = "for";
|
||||
else if (match_word(&pos, "while")) target = "while";
|
||||
|
Loading…
Reference in New Issue
Block a user