Mercurial > repo
view src/ploki/sub.c @ 8916:0234daffd946
<oerjan> addquote <int-e> I couldn\'t help thinking that maybe if one considers the ramifications in full detail it will turn out that overthinking is often not helpful and therefore, not something to be proud of.
author | HackBot |
---|---|
date | Sun, 14 Aug 2016 02:31:47 +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; }