Mercurial > repo
diff src/ploki/sub.c @ 4223:ac0403686959
<oerjan> rm -rf src/ploki; mv ploki src
author | HackBot |
---|---|
date | Fri, 20 Dec 2013 22:18:50 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ploki/sub.c Fri Dec 20 22:18:50 2013 +0000 @@ -0,0 +1,134 @@ +#include "expr.h" +#include "main_opt.h" +#include "sub.h" +#include "transmogrify.h" +#include "xmalloc.h" + +#include <stddef.h> + +struct sub { + struct expr *expr; + size_t refs; + size_t id; +}; + +static struct expr *dup(const struct expr *e) { + struct expr *p; + + if (!e) { + return NULL; + } + + p = xmalloc(1, sizeof *p); + *p = *e; + + switch (e->type) { + case literE: + p->v.val = v_undef(); + v_set(p->v.val, e->v.val); + break; + + case varE: + break; + + case varhashE: + p->right = dup(e->right); + break; + + case symbolE: + switch (e->op) { + case S_ARGV: + p->right = dup(e->right); + break; + } + break; + + case unopE: + p->right = dup(e->right); + if (e->op == F_MATCH) { + p->left.rx = re_dup(e->left.rx); + } + break; + + case binopE: + case listE: + p->right = dup(e->right); + p->left.expr = dup(e->left.expr); + break; + } + + return p; +} + +static void solid(struct expr *e) { + if (!e) { + return; + } + + switch (e->type) { + case literE: + break; + + case varE: + e->v.val = eval_expr(e); + e->type = literE; + break; + + case varhashE: + break; + + case symbolE: + switch (e->op) { + case S_ARGV: + solid(e->right); + break; + } + break; + + case unopE: + solid(e->right); + break; + + case binopE: + case listE: + solid(e->left.expr); + solid(e->right); + break; + } +} + +struct sub *sub_new(const struct expr *e) { + static size_t idcount; + struct sub *p; + p = xmalloc(1, sizeof *p); + p->expr = dup(e); + solid(p->expr); + if (!Opt.unoptimize) { + trans_fold(&p->expr); + } + p->refs = 0; + p->id = idcount++; + return p; +} + +struct sub *sub_incr(struct sub *p) { + ++p->refs; + return p; +} + +void sub_decr(struct sub *p) { + if (!p->refs) { + free_expr(p->expr); + xfree(p); + return; + } + --p->refs; +} + +struct expr *sub_expr(const struct sub *p) { + return p->expr; +} + +size_t sub_id(const struct sub *p) { + return p->id; +}