From 936a46362212401d092de5477149f9a594993da5 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Mon, 29 Aug 2016 11:35:10 +0200 Subject: match EXPR_APP --- interpreter/eval.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/interpreter/eval.c b/interpreter/eval.c index f3d10c3..20330cc 100644 --- a/interpreter/eval.c +++ b/interpreter/eval.c @@ -75,6 +75,30 @@ void free_node(struct node* node, unsigned dont_free_first) { } } +struct node** flatten_app_args(struct node* from) { + struct node** result; + unsigned int i; + unsigned char len = 0; + struct node* _from = from; + + while (_from->kind == EXPR_APP) { + len++; + _from = _from->var1; + } + len++; + + result = my_calloc(1, sizeof(struct node*) * (len + 1)); + i = 1; + while (from->kind == EXPR_APP) { + result[len - i] = from->var2; + from = from->var1; + i++; + } + result[0] = from; + result[len] = NULL; + return result; +} + void cpy_expression_to_node(struct node* dst, expression* src) { if (!dst || !src) return; @@ -169,11 +193,45 @@ unsigned match_expr(fuspel* rules, expression* expr, struct node** node, int match_rule(fuspel* rules, rewrite_rule* rule, struct node* node, replacements** repls, nodes_array** to_free) { + struct node** node_args; + unsigned char i; + switch (node->kind) { case EXPR_NAME: return (strcmp(rule->name, (char*) node->var1)) ? -1 : 0; break; + case EXPR_APP: + node_args = flatten_app_args(node); + i = 0; + if (!strcmp(node_args[0]->var1, rule->name)) { + struct node* node = node_args[++i]; + arg_list* args = rule->args; + unsigned char args_len = len_arg_list(args); + + while (!empty_args_list(args)) { + if (!match_expr(rules, &args->elem, &node, repls, to_free)) { + my_free(node_args); + return -1; + } + + args = args->rest; + node = node_args[++i]; + + if (!empty_args_list(args) && !node) { + my_free(node_args); + return -1; + } + } + + while (node) node = node_args[++i]; + my_free(node_args); + return i - args_len - 1; + } + my_free(node_args); + return -1; + break; + default: return -1; } -- cgit v1.2.3