Mercurial > repo
view src/ploki/sub.c @ 4335:c3083517f99c
<int-e> revert
author | HackBot |
---|---|
date | Thu, 16 Jan 2014 23:12:02 +0000 |
parents | ac0403686959 |
children |
line wrap: on
line source
#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; }