annotate src/ploki/compile.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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4223
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
1 #include "config.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
2 #include "Str.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
3 #include "compile.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
4 #include "expr.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
5 #include "main_var.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
6 #include "op.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
7 #include "text.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
8 #include "zz.h"
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
9
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
10 #include <assert.h>
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
11
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
12 static struct op *end_if(struct text *code, size_t *n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
13 for (; *n < code->length; ++*n) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
14 struct op *const p = code->start[*n];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
15 switch (p->type) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
16 case OP_IF:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
17 ++*n;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
18 p->arh.op = code->start[*n];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
19 p->next = end_if(code, n);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
20 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
21
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
22 case OP_ELSE: {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
23 size_t tmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
24 tmp = ++*n;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
25 p->next = end_if(code, n);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
26 p->type = OP_NOP;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
27 if (tmp < code->length) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
28 return code->start[tmp];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
29 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
30 return p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
31 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
32
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
33 case OP_FI:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
34 p->type = OP_NOP;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
35 return p;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
36
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
37 default:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
38 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
39 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
40 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
41
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
42 return code->start[0];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
43 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
44
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
45 static void resolve(struct expr *e) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
46 if (!e) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
47 return;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
48 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
49
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
50 switch (e->type) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
51 case literE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
52 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
53
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
54 case varE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
55 e->v.val = vr_data(Var_plain, e->v.tent);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
56 assert(e->v.val != NULL);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
57 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
58
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
59 case varhashE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
60 e->v.hash = vr_data(Var_hash, e->v.tent);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
61 resolve(e->right);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
62 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
63
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
64 case symbolE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
65 if (e->op == S_ARGV) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
66 resolve(e->right);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
67 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
68 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
69
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
70 case unopE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
71 resolve(e->right);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
72 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
73
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
74 case binopE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
75 resolve(e->left.expr);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
76 resolve(e->right);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
77 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
78
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
79 case listE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
80 resolve(e->right);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
81 resolve(e->left.expr);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
82 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
83 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
84 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
85
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
86 static void op_resolve(struct op *o) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
87 switch (o->type) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
88 case OP_NOP:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
89 case OP_GOBACK:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
90 case OP_GOTO:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
91 case OP_HANG:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
92 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
93
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
94 case OP_ASSIGN:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
95 case OP_CALL_BACK:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
96 case OP_MODIFY:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
97 case OP_PRINT:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
98 case OP_PUTC:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
99 case OP_TEMP:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
100 resolve(o->arh.expr);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
101 resolve(o->arg);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
102 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
103
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
104 case OP_CALL:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
105 case OP_CALL_DYN:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
106 case OP_CLOSE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
107 case OP_EXIT:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
108 case OP_IF:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
109 case OP_RETURN:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
110 case OP_SYSTEM:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
111 case OP_THROW:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
112 resolve(o->arg);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
113 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
114
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
115 default:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
116 NOTREACHED;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
117 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
118 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
119 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
120
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
121 void compile(struct text *code) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
122 size_t i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
123
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
124 for (i = 0; i < code->length; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
125 struct op *const p = code->start[i];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
126
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
127 op_getop(p);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
128
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
129 if (!p->next && p->type != OP_EXIT && i + 1 < code->length) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
130 p->next = code->start[i + 1];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
131 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
132 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
133
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
134 if (!i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
135 struct op tmp;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
136 op_init(&tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
137 text_push(code, &tmp);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
138 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
139
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
140 vr_freeze(Var_plain);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
141 vr_freeze(Var_hash);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
142
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
143 for (i = 0; i < code->length; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
144 struct op *const p = code->start[i];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
145
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
146 switch (p->type) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
147 case OP_IF:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
148 ++i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
149 p->arh.op = code->start[i];
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
150 p->next = end_if(code, &i);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
151 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
152
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
153 case OP_ELSE:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
154 ++i;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
155 p->next = end_if(code, &i);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
156 p->type = OP_NOP;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
157 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
158
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
159 case OP_FI:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
160 p->type = OP_NOP;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
161 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
162
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
163 default:
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
164 break;
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
165 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
166 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
167
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
168 for (i = 0; i < code->length; ++i) {
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
169 op_resolve(code->start[i]);
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
170 }
ac0403686959 <oerjan> rm -rf src/ploki; mv ploki src
HackBot
parents:
diff changeset
171 }