|
@@ -4670,6 +4670,10 @@ int mexpr_greater(node_t *a, node_t *b) {
|
|
|
return TO_DOUBLE(a) > TO_DOUBLE(b);
|
|
return TO_DOUBLE(a) > TO_DOUBLE(b);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+macro_t *find_macro(char *name, size_t argc, int *res);
|
|
|
|
|
+node_t *run_macro(macro_t *macro, list_t *args);
|
|
|
|
|
+node_t *expand_mvars(node_t *node, node_t *_node, int expr);
|
|
|
|
|
+
|
|
|
node_t *mexpr_eval(node_t *n) {
|
|
node_t *mexpr_eval(node_t *n) {
|
|
|
if (n)
|
|
if (n)
|
|
|
switch (n->tag) {
|
|
switch (n->tag) {
|
|
@@ -4770,6 +4774,19 @@ node_t *mexpr_eval(node_t *n) {
|
|
|
case N_COMMA:
|
|
case N_COMMA:
|
|
|
return mexpr_eval(list_index(n->l, -1));
|
|
return mexpr_eval(list_index(n->l, -1));
|
|
|
|
|
|
|
|
|
|
+ case N_MACRO_CALL: {
|
|
|
|
|
+ list_t *args = list_new();
|
|
|
|
|
+
|
|
|
|
|
+ for (size_t i = 0; i < n->l->length; i++)
|
|
|
|
|
+ list_push(args, mexpr_eval(n->l->data[i]));
|
|
|
|
|
+
|
|
|
|
|
+ macro_t *m = find_macro(n->t->text, args->length, NULL);
|
|
|
|
|
+ if (!m)
|
|
|
|
|
+ return n;
|
|
|
|
|
+
|
|
|
|
|
+ return mexpr_eval(expand_mvars(n, run_macro(m, args), 1));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|