Browse Source

wip macros

txlyre 3 days ago
parent
commit
c3ac0df634
1 changed files with 66 additions and 7 deletions
  1. 66 7
      qic.c

+ 66 - 7
qic.c

@@ -2539,6 +2539,12 @@ node_t *parse_mexpr(list_t *tokens, size_t *pos) {
 
       a = NODE2(MUL, a, b);
 
+      continue;
+    } else if (MATCH(SLASH)) {
+      node_t *b = parse_mprimary(tokens, pos);
+
+      a = NODE2(DIV, a, b);
+
       continue;
     } else if (MATCH(ASSIGN)) {
       node_t *b = parse_mprimary(tokens, pos);
@@ -3622,6 +3628,20 @@ node_t *mexpr_mul(node_t *a, node_t *b) {
   return make_number(TO_DOUBLE(a) * TO_DOUBLE(b));
 }
 
+node_t *mexpr_div(node_t *a, node_t *b) {
+  if (!IS_NUMBER(a))
+    return NULL;
+
+  if (!IS_NUMBER(b))
+    return NULL;
+
+  double x = TO_DOUBLE(b);
+  if (x == 0)
+    return make_number(0);
+
+  return make_number(TO_DOUBLE(a) * x);
+}
+
 int mexpr_equals(node_t *a, node_t *b) {
   if (!a && !b) return 1;
   if (!a && b) return 0;
@@ -3683,6 +3703,29 @@ node_t *mexpr_eval(node_t *n) {
         return mexpr_sub(a, b);
       }
 
+      case N_MUL: {
+        node_t *a = mexpr_eval(n->a);
+        node_t *b = mexpr_eval(n->b);
+
+        return mexpr_mul(a, b);
+      }
+
+      case N_DIV: {
+        node_t *a = mexpr_eval(n->a);
+        node_t *b = mexpr_eval(n->b);
+
+        return mexpr_div(a, b);
+      }
+
+      case N_IFEXPR: {
+        node_t *a = mexpr_eval(n->a);
+
+        if (a)
+          return mexpr_eval(n->b);
+
+        return mexpr_eval(n->c);
+      }
+
       default: break;
     }
 
@@ -3693,11 +3736,7 @@ node_t *mf_isExpr(list_t *t) {
   if (t->length != 1)
     return NULL;
 
-  node_t *a = t->data[0];
-  if (!a)
-    return NULL;
-
-  return a->tag > N_EXPRS_BEGIN && a->tag < N_EXPRS_END? YES: NULL;
+  return IS_EXPR(t->data[0])? YES: NULL;
 }
 
 node_t *mf_isList(list_t *t) {
@@ -3801,6 +3840,17 @@ node_t *mf_E(list_t *t) {
   return mexpr_eval(a);
 }
 
+node_t *mf_C(list_t *t) {
+  if (t->length != 1)
+    return NULL;
+
+  node_t *a = t->data[0];
+  if (!IS_STRING(a))
+    return NULL;
+
+  return const_get(a->t->text);
+}
+
 struct {
   char *name;
   node_t *(*handler)(list_t *);
@@ -3816,6 +3866,7 @@ struct {
   { "nth", mf_nth },
 
   { "E", mf_E },
+  { "C", mf_C },
 
   { NULL, NULL }
 };
@@ -3938,6 +3989,13 @@ node_t *run_mexpr(node_t *node) {
       return mexpr_mul(a, b);
     }
 
+    case N_DIV: {
+      node_t *a = run_mexpr(node->a);
+      node_t *b = run_mexpr(node->b);
+
+      return mexpr_div(a, b);
+    }
+
     case N_EQUALS: {
       node_t *a = run_mexpr(node->a);
       node_t *b = run_mexpr(node->b);
@@ -4080,7 +4138,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
     node->a = n;
 
     return node;
-  } else if (node->tag >= N_ADD && node->tag <= N_BAND) {
+  } else if ((node->tag >= N_ADD && node->tag <= N_BAND) || (node->tag >= N_ASSIGN && node->tag <= N_ASSIGN_SHR)) {
     node = node_copy(node);
 
     node->a = _expand_mvars(node->a, 1, err);
@@ -4090,7 +4148,7 @@ node_t *_expand_mvars(node_t *node, int expr, mvar_expand_err_t *err) {
     if (err->code != 0) return NULL;
 
     return node;
-  } else if (node->tag == N_PROGRAM || node->tag == N_LIST || node->tag == N_TUPLE) {
+  } else if (node->tag == N_PROGRAM || node->tag == N_BLOCK || node->tag == N_LIST || node->tag == N_TUPLE) {
     node = node_copy(node);
     node->l = list_copy(node->l);
 
@@ -5148,6 +5206,7 @@ char *compile(char *source, list_t *required) {
   buffer_t *buf = buffer_new();
 
   compile_into("const __QIC = \"" QIC_VERSION "\"", gbuf, buf, ctx, ltab, lstk, sstk, lbl);
+  compile_into("macro E(x)$:E(x)", gbuf, buf, ctx, ltab, lstk, sstk, lbl);
 
   if (required && required->length)
     for (size_t i = 0; i < required->length; i++)