comparison 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
comparison
equal deleted inserted replaced
4222:b0f3e267bb1e 4223:ac0403686959
1 #include "expr.h"
2 #include "main_opt.h"
3 #include "sub.h"
4 #include "transmogrify.h"
5 #include "xmalloc.h"
6
7 #include <stddef.h>
8
9 struct sub {
10 struct expr *expr;
11 size_t refs;
12 size_t id;
13 };
14
15 static struct expr *dup(const struct expr *e) {
16 struct expr *p;
17
18 if (!e) {
19 return NULL;
20 }
21
22 p = xmalloc(1, sizeof *p);
23 *p = *e;
24
25 switch (e->type) {
26 case literE:
27 p->v.val = v_undef();
28 v_set(p->v.val, e->v.val);
29 break;
30
31 case varE:
32 break;
33
34 case varhashE:
35 p->right = dup(e->right);
36 break;
37
38 case symbolE:
39 switch (e->op) {
40 case S_ARGV:
41 p->right = dup(e->right);
42 break;
43 }
44 break;
45
46 case unopE:
47 p->right = dup(e->right);
48 if (e->op == F_MATCH) {
49 p->left.rx = re_dup(e->left.rx);
50 }
51 break;
52
53 case binopE:
54 case listE:
55 p->right = dup(e->right);
56 p->left.expr = dup(e->left.expr);
57 break;
58 }
59
60 return p;
61 }
62
63 static void solid(struct expr *e) {
64 if (!e) {
65 return;
66 }
67
68 switch (e->type) {
69 case literE:
70 break;
71
72 case varE:
73 e->v.val = eval_expr(e);
74 e->type = literE;
75 break;
76
77 case varhashE:
78 break;
79
80 case symbolE:
81 switch (e->op) {
82 case S_ARGV:
83 solid(e->right);
84 break;
85 }
86 break;
87
88 case unopE:
89 solid(e->right);
90 break;
91
92 case binopE:
93 case listE:
94 solid(e->left.expr);
95 solid(e->right);
96 break;
97 }
98 }
99
100 struct sub *sub_new(const struct expr *e) {
101 static size_t idcount;
102 struct sub *p;
103 p = xmalloc(1, sizeof *p);
104 p->expr = dup(e);
105 solid(p->expr);
106 if (!Opt.unoptimize) {
107 trans_fold(&p->expr);
108 }
109 p->refs = 0;
110 p->id = idcount++;
111 return p;
112 }
113
114 struct sub *sub_incr(struct sub *p) {
115 ++p->refs;
116 return p;
117 }
118
119 void sub_decr(struct sub *p) {
120 if (!p->refs) {
121 free_expr(p->expr);
122 xfree(p);
123 return;
124 }
125 --p->refs;
126 }
127
128 struct expr *sub_expr(const struct sub *p) {
129 return p->expr;
130 }
131
132 size_t sub_id(const struct sub *p) {
133 return p->id;
134 }