Mercurial > repo
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 } |