|
@@ -281,6 +281,7 @@ typedef struct {
|
|
T_VAR,
|
|
T_VAR,
|
|
T_LET,
|
|
T_LET,
|
|
T_CONST,
|
|
T_CONST,
|
|
|
|
+ T_UNPACK,
|
|
T_IF,
|
|
T_IF,
|
|
T_ELSE,
|
|
T_ELSE,
|
|
T_ELIF,
|
|
T_ELIF,
|
|
@@ -582,6 +583,8 @@ token_t *next_token(char *source, size_t *pos) {
|
|
return TK(LET);
|
|
return TK(LET);
|
|
else if (strcmp(name, "const") == 0)
|
|
else if (strcmp(name, "const") == 0)
|
|
return TK(CONST);
|
|
return TK(CONST);
|
|
|
|
+ else if (strcmp(name, "unpack") == 0)
|
|
|
|
+ return TK(UNPACK);
|
|
else if (strcmp(name, "if") == 0)
|
|
else if (strcmp(name, "if") == 0)
|
|
return TK(IF);
|
|
return TK(IF);
|
|
else if (strcmp(name, "else") == 0)
|
|
else if (strcmp(name, "else") == 0)
|
|
@@ -808,6 +811,9 @@ struct _node_t {
|
|
|
|
|
|
N_VAR,
|
|
N_VAR,
|
|
N_LET,
|
|
N_LET,
|
|
|
|
+ N_VARUNPACK,
|
|
|
|
+ N_LETUNPACK,
|
|
|
|
+ N_UNPACK,
|
|
N_CONST,
|
|
N_CONST,
|
|
N_IF,
|
|
N_IF,
|
|
N_SWITCH,
|
|
N_SWITCH,
|
|
@@ -1566,6 +1572,31 @@ node_t *parse_var(list_t *tokens, size_t *pos, int is_let) {
|
|
return NODEH(VAR, h);
|
|
return NODEH(VAR, h);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+node_t *parse_unpack(list_t *tokens, size_t *pos, int tag) {
|
|
|
|
+ EXPECT(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(ASSIGN, "=");
|
|
|
|
+
|
|
|
|
+ node_t *a = parse_expr(tokens, pos);
|
|
|
|
+
|
|
|
|
+ if (tag == N_VARUNPACK)
|
|
|
|
+ return NODE1l(VARUNPACK, a, l);
|
|
|
|
+ else if (tag == N_LETUNPACK)
|
|
|
|
+ return NODE1l(LETUNPACK, a, l);
|
|
|
|
+
|
|
|
|
+ return NODE1l(UNPACK, a, l);
|
|
|
|
+}
|
|
|
|
+
|
|
node_t *parse_func(list_t *tokens, size_t *pos, int is_expr) {
|
|
node_t *parse_func(list_t *tokens, size_t *pos, int is_expr) {
|
|
token_t *name = NULL;
|
|
token_t *name = NULL;
|
|
|
|
|
|
@@ -1666,10 +1697,18 @@ node_t *parse_stmt(list_t *tokens, size_t *pos) {
|
|
EXPECT(RCB, "}");
|
|
EXPECT(RCB, "}");
|
|
|
|
|
|
return NODEL(BLOCK, stmts);
|
|
return NODEL(BLOCK, stmts);
|
|
- } else if (MATCH(VAR))
|
|
|
|
|
|
+ } else if (MATCH(VAR)) {
|
|
|
|
+ if (AT(LPAR))
|
|
|
|
+ return parse_unpack(tokens, pos, N_VARUNPACK);
|
|
|
|
+
|
|
return parse_var(tokens, pos, 0);
|
|
return parse_var(tokens, pos, 0);
|
|
- else if (MATCH(LET))
|
|
|
|
|
|
+ } else if (MATCH(LET)) {
|
|
|
|
+ if (AT(LPAR))
|
|
|
|
+ return parse_unpack(tokens, pos, N_LETUNPACK);
|
|
|
|
+
|
|
return parse_var(tokens, pos, 1);
|
|
return parse_var(tokens, pos, 1);
|
|
|
|
+ } else if (MATCH(UNPACK))
|
|
|
|
+ return parse_unpack(tokens, pos, N_UNPACK);
|
|
else if (MATCH(CONST)) {
|
|
else if (MATCH(CONST)) {
|
|
table_t *h = table_new();
|
|
table_t *h = table_new();
|
|
|
|
|
|
@@ -2646,6 +2685,21 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, stack_t *lstk, lis
|
|
});
|
|
});
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
+ case N_UNPACK: case N_VARUNPACK: case N_LETUNPACK: {
|
|
|
|
+ NEWGID();
|
|
|
|
+
|
|
|
|
+ EMIT("qi_value_t *__temp%d = ", gid);
|
|
|
|
+ compile_node(gbuf, buf, ctx, lstk, lbl, node->a);
|
|
|
|
+ EMIT(";\n");
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < node->l->length; i++)
|
|
|
|
+ if (node->tag == N_UNPACK) {
|
|
|
|
+ EMIT("qi_set(state, false, \"%s\", qi_index(state, __temp%d, qi_make_number(state, %d)));\n", node->l->data[i], gid, i);
|
|
|
|
+ } else {
|
|
|
|
+ EMIT("%s(state, \"%s\", qi_index(state, __temp%d, qi_make_number(state, %d)));\n", node->tag == N_VARUNPACK? "qi_decl": "qi_decl_const", node->l->data[i], gid, i);
|
|
|
|
+ }
|
|
|
|
+ } break;
|
|
|
|
+
|
|
case N_CONST:break;
|
|
case N_CONST:break;
|
|
|
|
|
|
case N_IF:
|
|
case N_IF:
|