Dumps the function so parsed.
Chris Pressey
6 years ago
82 | 82 | |
83 | 83 | /**** Function Utilities ****/ |
84 | 84 | |
85 | /* | |
86 | * This function takes ownership of the lhs and rhs passed to it. | |
87 | */ | |
85 | 88 | struct function *make_function(enum fntype fntype, struct function *lhs, struct function *rhs) { |
86 | 89 | struct function *fn; |
87 | 90 | |
99 | 102 | } |
100 | 103 | |
101 | 104 | |
105 | struct function *copy_function(struct function *src) { | |
106 | return make_function(src->fntype, src->lhs, src->rhs); | |
107 | } | |
108 | ||
109 | ||
110 | void dump_function(struct function *fn) { | |
111 | switch (fn->fntype) { | |
112 | case APPLY: | |
113 | printf("apply"); | |
114 | break; | |
115 | case COMPOSE: | |
116 | printf("compose"); | |
117 | break; | |
118 | case POP: | |
119 | printf("pop"); | |
120 | break; | |
121 | case SWAP: | |
122 | printf("swap"); | |
123 | break; | |
124 | case ADD: | |
125 | printf("add"); | |
126 | break; | |
127 | case SUB: | |
128 | printf("sub"); | |
129 | break; | |
130 | case SIGN: | |
131 | printf("sign"); | |
132 | break; | |
133 | case PICK: | |
134 | printf("pick"); | |
135 | break; | |
136 | case ONE: | |
137 | printf("one"); | |
138 | break; | |
139 | case NOP: | |
140 | printf("nop"); | |
141 | break; | |
142 | ||
143 | case PUSH: | |
144 | printf("(push "); | |
145 | dump_function(fn->lhs); | |
146 | printf(")"); | |
147 | break; | |
148 | case CONCAT: | |
149 | printf("(concat "); | |
150 | dump_function(fn->lhs); | |
151 | printf(" "); | |
152 | dump_function(fn->rhs); | |
153 | printf(")"); | |
154 | break; | |
155 | } | |
156 | } | |
157 | ||
158 | ||
102 | 159 | /**** Evaluation ****/ |
103 | 160 | |
104 | 161 | void apply_(struct function *fn, struct stack *stack) { |
112 | 169 | case COMPOSE: |
113 | 170 | pop(stack, &a); |
114 | 171 | pop(stack, &b); |
115 | // FIXME no - will need to make copies of a and b | |
116 | 172 | c.num = 0; |
173 | /* Even though a and b are local variables, the functions they point to, aren't. So this is OK. */ | |
174 | /* (I think.) */ | |
117 | 175 | c.fn = make_function(CONCAT, a.fn, b.fn); |
118 | 176 | push(stack, &c); |
119 | 177 | break; |
205 | 263 | } |
206 | 264 | |
207 | 265 | |
208 | struct function *parse(char *text) { | |
266 | struct function *parse_stream(FILE *stream) { | |
267 | char c; | |
209 | 268 | struct function *fn; |
210 | 269 | |
211 | 270 | fn = make_function(NOP, NULL, NULL); |
212 | 271 | |
213 | for (int i = 0; text[i]; i++) { | |
214 | fn = make_function(CONCAT, semantics(text[i]), fn); | |
272 | c = fgetc(stream); | |
273 | while (!feof(stream)) { | |
274 | fn = make_function(CONCAT, semantics(c), fn); | |
275 | c = fgetc(stream); | |
215 | 276 | } |
216 | 277 | |
217 | 278 | return fn; |
219 | 280 | |
220 | 281 | |
221 | 282 | int main(int argc, char **argv) { |
222 | }⏎ | |
283 | FILE *f; | |
284 | struct function *program; | |
285 | ||
286 | f = fopen(argv[1], "r"); | |
287 | if (!f) { | |
288 | fprintf(stderr, "Couldn't open '%s' for reading\n", argv[1]); | |
289 | exit(1); | |
290 | } | |
291 | ||
292 | program = parse_stream(f); | |
293 | fclose(f); | |
294 | ||
295 | dump_function(program); | |
296 | ||
297 | return 0; | |
298 | } |