txlyre 1 dzień temu
rodzic
commit
10c4172a0c
1 zmienionych plików z 39 dodań i 1 usunięć
  1. 39 1
      qic.c

+ 39 - 1
qic.c

@@ -1091,6 +1091,8 @@ struct _node_t {
     N_LOGOR,
     N_LOGAND,
 
+    N_CATCH,
+
     N_EXPRS_END,
 
     N_STAR,
@@ -1492,7 +1494,11 @@ char *unescape(char *s);
 node_t *parse_primary(list_t *tokens, size_t *pos) {
   if (MATCH(MVAR))
     return NODET(MVAR, tokens->data[(*pos) - 1]);
-  else if (MATCH(FUNC))
+  else if (MATCH(CATCH)) {
+    node_t *a = parse_expr(tokens, pos);
+
+    return NODE1(CATCH, a);
+  } else if (MATCH(FUNC))
     return parse_func(tokens, pos, 1);
   else if (MATCH(LPAR)) {
     if (MATCH(RPAR))
@@ -6141,6 +6147,38 @@ void compile_node(buffer_t *gbuf, buffer_t *buf, list_t *ctx, table_t *ltab,
     }
     break;
 
+  case N_CATCH: {
+    NEWGID();
+
+    buffer_t *tbuf = buffer_new();
+
+    buffer_fmt(tbuf, "qi_value_t *__%s%d(qi_state_t *state) {\n", PREFIX, gid);
+
+    char *varname1 = tempvar();
+    char *varname2 = tempvar();
+
+    buffer_fmt(tbuf, "qi_value_t *%s = state->nil;\n", varname1);
+    buffer_fmt(tbuf, "qi_value_t *%s = state->nil;\n", varname2);
+
+    buffer_fmt(tbuf, "qi_try(state, {\n");
+    buffer_fmt(tbuf, "%s = ", varname1);
+    compile_node(gbuf, tbuf, ctx, ltab, lstk, sstk, lbl, node->a);
+    buffer_fmt(tbuf, ";\n}, {\n");
+    buffer_fmt(tbuf, "%s = trap->value;\n", varname2);
+    buffer_fmt(tbuf, "}, NULL);\n");
+   
+    char *varname3 = tempvar();
+    buffer_fmt(tbuf, "qi_list_t *%s = qi_list_make_n(2);\n", varname3);
+    buffer_fmt(tbuf, "qi_list_data(%s, 0) = %s;\n", varname3, varname1);
+    buffer_fmt(tbuf, "qi_list_data(%s, 1) = %s;\n", varname3, varname2);
+    buffer_fmt(tbuf, "return qi_make_tuple(state, %s);\n", varname3);
+    buffer_fmt(tbuf, "}\n");
+
+    buffer_appendb(gbuf, tbuf);
+
+    EMIT("__%s%d(state)", PREFIX, gid);
+    } break;
+
   case N_LABEL: {
     int_stack_t *pair = table_get(list_index(lbl, -1), node->t->text);