|
@@ -820,6 +820,8 @@ struct _node_t {
|
|
N_FOR,
|
|
N_FOR,
|
|
N_FOROF,
|
|
N_FOROF,
|
|
N_FOROFVAR,
|
|
N_FOROFVAR,
|
|
|
|
+ N_FOROFUNPACK,
|
|
|
|
+ N_FOROFVARUNPACK,
|
|
N_BREAK,
|
|
N_BREAK,
|
|
N_CONTINUE,
|
|
N_CONTINUE,
|
|
N_FUNCDEF,
|
|
N_FUNCDEF,
|
|
@@ -1787,6 +1789,25 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
node_t *c = NULL;
|
|
node_t *c = NULL;
|
|
|
|
|
|
if (!AT(LCB) && !AT(COLON) && !CLIFF) {
|
|
if (!AT(LCB) && !AT(COLON) && !CLIFF) {
|
|
|
|
+ if (MATCH(LPAR)) {
|
|
|
|
+ list_t *l = list_new();
|
|
|
|
+
|
|
|
|
+ do {
|
|
|
|
+ if(!AT(NAME))
|
|
|
|
+ PARSE_ERROR("expected identifier");
|
|
|
|
+
|
|
|
|
+ list_push(l, ((token_t *)tokens->data[(*pos)++])->text);
|
|
|
|
+ } while (MATCH(COMMA));
|
|
|
|
+
|
|
|
|
+ EXPECT(RPAR, ")");
|
|
|
|
+ EXPECT(OF, "of");
|
|
|
|
+
|
|
|
|
+ a = parse_expr(tokens, pos);
|
|
|
|
+ b = BLOCK();
|
|
|
|
+
|
|
|
|
+ return NODE2l(FOROFUNPACK, a, b, l);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (AT(NAME) && ATP(OF, 1)) {
|
|
if (AT(NAME) && ATP(OF, 1)) {
|
|
token_t *t = tokens->data[(*pos)++];
|
|
token_t *t = tokens->data[(*pos)++];
|
|
|
|
|
|
@@ -1799,6 +1820,25 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
}
|
|
}
|
|
|
|
|
|
if (MATCH(VAR)) {
|
|
if (MATCH(VAR)) {
|
|
|
|
+ if (MATCH(LPAR)) {
|
|
|
|
+ list_t *l = list_new();
|
|
|
|
+
|
|
|
|
+ do {
|
|
|
|
+ if(!AT(NAME))
|
|
|
|
+ PARSE_ERROR("expected identifier");
|
|
|
|
+
|
|
|
|
+ list_push(l, ((token_t *)tokens->data[(*pos)++])->text);
|
|
|
|
+ } while (MATCH(COMMA));
|
|
|
|
+
|
|
|
|
+ EXPECT(RPAR, ")");
|
|
|
|
+ EXPECT(OF, "of");
|
|
|
|
+
|
|
|
|
+ a = parse_expr(tokens, pos);
|
|
|
|
+ b = BLOCK();
|
|
|
|
+
|
|
|
|
+ return NODE2l(FOROFVARUNPACK, a, b, l);
|
|
|
|
+ }
|
|
|
|
+
|
|
if (AT(NAME) && ATP(OF, 1)) {
|
|
if (AT(NAME) && ATP(OF, 1)) {
|
|
token_t *t = tokens->data[(*pos)++];
|
|
token_t *t = tokens->data[(*pos)++];
|
|
|
|
|
|
@@ -2793,7 +2833,7 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
|
|
EMIT("__break%d:;\n", gid);
|
|
EMIT("__break%d:;\n", gid);
|
|
} break;
|
|
} break;
|
|
|
|
|
|
- case N_FOROF: case N_FOROFVAR: {
|
|
|
|
|
|
+ case N_FOROF: case N_FOROFVAR: case N_FOROFUNPACK: case N_FOROFVARUNPACK: {
|
|
NEWGID();
|
|
NEWGID();
|
|
char *varname = tempvar();
|
|
char *varname = tempvar();
|
|
|
|
|
|
@@ -2801,11 +2841,20 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->a);
|
|
compile_node(gbuf, buf, ctx, lstk, lbl, node->a);
|
|
EMIT(");\n");
|
|
EMIT(");\n");
|
|
|
|
|
|
- if (node->tag == N_FOROFVAR)
|
|
|
|
|
|
+ if (node->tag == N_FOROFVAR) {
|
|
EMIT("qi_decl(state, \"%s\", state->nil);\n", node->t->text);
|
|
EMIT("qi_decl(state, \"%s\", state->nil);\n", node->t->text);
|
|
|
|
+ } else if (node->tag == N_FOROFVARUNPACK) {
|
|
|
|
+ for (size_t i = 0; i < node->l->length; i++)
|
|
|
|
+ EMIT("qi_decl(state, \"%s\", state->nil);\n", node->l->data[i]);
|
|
|
|
+ }
|
|
|
|
|
|
EMIT("for (qi_size_t length = _qi_length(state, %s), i = 0; i < length; i++) {\n", varname);
|
|
EMIT("for (qi_size_t length = _qi_length(state, %s), i = 0; i < length; i++) {\n", varname);
|
|
- EMIT("qi_set(state, false, \"%s\", qi_index(state, %s, qi_make_number(state, i)));\n", node->t->text, varname);
|
|
|
|
|
|
+
|
|
|
|
+ if (node->tag == N_FOROFUNPACK || node->tag == N_FOROFVARUNPACK) {
|
|
|
|
+ for (size_t i = 0; i < node->l->length; i++)
|
|
|
|
+ EMIT("qi_set(state, false, \"%s\", qi_index(state, qi_index(state, %s, qi_make_number(state, i)), qi_make_number(state, %d)));\n", node->l->data[i], varname, i);
|
|
|
|
+ } else
|
|
|
|
+ EMIT("qi_set(state, false, \"%s\", qi_index(state, %s, qi_make_number(state, i)));\n", node->t->text, varname);
|
|
|
|
|
|
LPUSH(gid);
|
|
LPUSH(gid);
|
|
CTXPUSH("for");
|
|
CTXPUSH("for");
|