Shave 100 lines off of the compiler.
Cat's Eye Technologies
10 years ago
91 | 91 | emit(X) = $:emit(X). |
92 | 92 | indent = 'ok'. |
93 | 93 | outdent = 'ok'. |
94 | ||
94 | ||
95 | emitln_fmt(S, L) = emit_fmt(S, L) & $:emit('\n'). | |
96 | emit_fmt(S, L) = emit_fmt_r(L) @ S. | |
97 | emit_fmt_r([H|T]) = "%" & "s" & emit(H) & emit_fmt_r(T) | |
98 | | any → C & emit(C) & emit_fmt_r([H|T]) | |
99 | | eof & 'ok'. | |
100 | emit_fmt_r([]) = any → C & emit(C) & emit_fmt_r([]) | |
101 | | eof & 'ok'. | |
102 | ||
95 | 103 | compile(program(Ms)) = |
96 | 104 | prelude & |
97 | 105 | emit_prototypes(nil, Ms) & |
133 | 141 | compile_all(P,B,N, Ps). |
134 | 142 | |
135 | 143 | compile_r(P,B,Mod, production(N, Bs)) = |
136 | emit('void prod_') & | |
137 | emit(Mod) & | |
138 | emit('_') & | |
139 | emit(N) & | |
140 | emit('(') & | |
144 | emit_fmt('void prod_%s_%s(', [Mod, N]) & | |
141 | 145 | make_formals_names(Bs) → FmlNms & |
142 | 146 | emit_formals(FmlNms) & |
143 | 147 | emitln(') {') & |
152 | 156 | |
153 | 157 | compile_r(P,B,Mod, call(prodref('$', 'expect'), list(T, nil))) = |
154 | 158 | compile_r(P,B,Mod, T) → TNm & |
155 | emit('tamsin_expect(scanner, ') & | |
156 | emit(TNm) & | |
157 | emitln(');'). | |
159 | emitln_fmt('tamsin_expect(scanner, %s);', [TNm]). | |
158 | 160 | |
159 | 161 | compile_r(P,B,Mod, call(prodref('$', 'return'), list(T, nil))) = |
160 | 162 | compile_r(P,B,Mod, T) → TNm & |
161 | emit('result = ') & | |
162 | emit(TNm) & | |
163 | emitln(';') & | |
163 | emitln_fmt('result = %s;', [TNm]) & | |
164 | 164 | emitln('ok = 1;'). |
165 | 165 | |
166 | 166 | compile_r(P,B,Mod, call(prodref('$', 'fail'), list(T, nil))) = |
167 | 167 | compile_r(P,B,Mod, T) → TNm & |
168 | emit('result = ') & | |
169 | emit(TNm) & | |
170 | emitln(';') & | |
168 | emitln_fmt('result = %s;', [TNm]) & | |
171 | 169 | emitln('ok = 0;'). |
172 | 170 | |
173 | 171 | compile_r(P,B,Mod, call(prodref('$', 'print'), list(T, nil))) = |
174 | 172 | compile_r(P,B,Mod, T) → TNm & |
175 | emit('result = ') & | |
176 | emit(TNm) & | |
177 | emitln(';') & | |
173 | emitln_fmt('result = %s;', [TNm]) & | |
178 | 174 | emitln('term_fput(result, stdout);') & |
179 | 175 | emitln('fprintf(stdout, "\\n");') & |
180 | 176 | emitln('ok = 1;'). |
181 | 177 | |
182 | 178 | compile_r(P,B,Mod, call(prodref('$', 'emit'), list(T, nil))) = |
183 | 179 | compile_r(P,B,Mod, T) → TNm & |
184 | emit('result = ') & | |
185 | emit(TNm) & | |
186 | emitln(';') & | |
180 | emitln_fmt('result = %s;', [TNm]) & | |
187 | 181 | emitln('term_fput(result, stdout);') & |
188 | 182 | emitln('ok = 1;'). |
189 | 183 | |
190 | 184 | compile_r(P,B,Mod, call(prodref('$', 'gensym'), list(T, nil))) = |
191 | 185 | compile_r(P,B,Mod, T) → TNm & |
192 | emit('result = tamsin_gensym(') & | |
193 | emit(TNm) & | |
194 | emitln(');') & | |
186 | emitln_fmt('result = tamsin_gensym(%s);', [TNm]) & | |
195 | 187 | emitln('ok = 1;'). |
196 | 188 | |
197 | 189 | compile_r(P,B,Mod, call(prodref('$', 'repr'), list(T, nil))) = |
198 | 190 | compile_r(P,B,Mod, T) → TNm & |
199 | emit('result = term_repr(') & | |
200 | emit(TNm) & | |
201 | emitln(');') & | |
191 | emitln_fmt('result = term_repr(%s);', [TNm]) & | |
202 | 192 | emitln('ok = 1;'). |
203 | 193 | |
204 | 194 | compile_r(P,B,Mod, call(prodref('$', 'eof'), nil)) = |
211 | 201 | emitln('tamsin_upper(scanner);'). |
212 | 202 | compile_r(P,B,Mod, call(prodref('$', 'startswith'), list(T, nil))) = |
213 | 203 | compile_r(P,B,Mod, T) → TNm & |
214 | emit('tamsin_startswith(scanner, ') & | |
215 | emit(TNm) & | |
216 | emitln('->atom);'). | |
204 | emitln_fmt('tamsin_startswith(scanner, %s->atom);', [TNm]). | |
217 | 205 | compile_r(P,B,Mod, call(prodref('$', 'mkterm'), list(T, list(L, nil)))) = |
218 | 206 | compile_r(P,B,Mod, T) → TNm & |
219 | 207 | compile_r(P,B,Mod, L) → LNm & |
220 | emit('result = tamsin_mkterm(') & | |
221 | emit(TNm) & | |
222 | emit(', ') & | |
223 | emit(LNm) & | |
224 | emitln(');') & | |
208 | emitln_fmt('result = tamsin_mkterm(%s, %s);', [TNm, LNm]) & | |
225 | 209 | emitln('ok = 1;'). |
226 | 210 | compile_r(P,B,Mod, call(prodref('$', 'unquote'), list(T, list(L, list(R, nil))))) = |
227 | 211 | compile_r(P,B,Mod, T) → TNm & |
228 | 212 | compile_r(P,B,Mod, L) → LNm & |
229 | 213 | compile_r(P,B,Mod, R) → RNm & |
230 | emit('result = tamsin_unquote(') & | |
231 | emit(TNm) & | |
232 | emit(', ') & | |
233 | emit(LNm) & | |
234 | emit(', ') & | |
235 | emit(RNm) & | |
236 | emitln(');'). | |
214 | emitln_fmt('result = tamsin_unquote(%s, %s, %s);', [TNm, LNm, RNm]). | |
237 | 215 | |
238 | 216 | compile_r(P,B,Mod, call(prodref('$', 'equal'), list(L, list(R, nil)))) = |
239 | 217 | compile_r(P,B,Mod, L) → LNm & |
240 | 218 | compile_r(P,B,Mod, R) → RNm & |
241 | emit('result = tamsin_equal(') & | |
242 | emit(LNm) & | |
243 | emit(', ') & | |
244 | emit(RNm) & | |
245 | emitln(');'). | |
219 | emitln_fmt('result = tamsin_equal(%s, %s);', [LNm, RNm]). | |
246 | 220 | |
247 | 221 | compile_r(P,B,Mod, call(prodref('$', 'reverse'), list(L, list(R, nil)))) = |
248 | 222 | compile_r(P,B,Mod, L) → LNm & |
249 | 223 | compile_r(P,B,Mod, R) → RNm & |
250 | emit('result = tamsin_reverse(') & | |
251 | emit(LNm) & | |
252 | emit(', ') & | |
253 | emit(RNm) & | |
254 | emitln(');'). | |
224 | emitln_fmt('result = tamsin_reverse(%s, %s);', [LNm, RNm]). | |
255 | 225 | |
256 | 226 | compile_r(P,B,Mod, call(prodref('$', 'hexbyte'), list(L, list(R, nil)))) = |
257 | 227 | compile_r(P,B,Mod, L) → LNm & |
258 | 228 | compile_r(P,B,Mod, R) → RNm & |
259 | emit('result = tamsin_hexbyte(') & | |
260 | emit(LNm) & | |
261 | emit(', ') & | |
262 | emit(RNm) & | |
263 | emitln(');') & | |
229 | emitln_fmt('result = tamsin_hexbyte(%s, %s);', [LNm, RNm]) & | |
264 | 230 | emitln('ok = 1;'). |
265 | 231 | |
266 | 232 | compile_r(P,B,Mod, call(prodref('$', 'format_octal'), list(T, nil))) = |
267 | 233 | compile_r(P,B,Mod, T) → TNm & |
268 | emit('result = tamsin_format_octal(') & | |
269 | emit(TNm) & | |
270 | emitln(');') & | |
234 | emitln_fmt('result = tamsin_format_octal(%s);', [TNm]) & | |
271 | 235 | emitln('ok = 1;'). |
272 | 236 | |
273 | 237 | compile_r(P,B,Mod, call(prodref('$', 'length'), list(T, nil))) = |
274 | 238 | compile_r(P,B,Mod, T) → TNm & |
275 | emit('result = tamsin_length(') & | |
276 | emit(TNm) & | |
277 | emitln(');') & | |
239 | emitln_fmt('result = tamsin_length(%s);', [TNm]) & | |
278 | 240 | emitln('ok = 1;'). |
279 | 241 | |
280 | 242 | compile_r(P,B,Mod, call(prodref(M, N), A)) = |
281 | 243 | emit_arguments(P,B,Mod, A, nil) → ArgNms & |
282 | emit('prod_') & | |
283 | emit(M) & | |
284 | emit('_') & | |
285 | emit(N) & | |
286 | emit('(') & | |
244 | emit_fmt('prod_%s_%s(', [M,N]) & | |
287 | 245 | emit_arguments_call(ArgNms) & |
288 | 246 | emitln(');'). |
289 | 247 | |
333 | 291 | |
334 | 292 | compile_r(P,B,Mod, send(R, variable(VN))) = |
335 | 293 | compile_r(P,B,Mod, R) & |
336 | emit(VN) & | |
337 | emitln(' = result;'). | |
294 | emitln_fmt('%s = result;', [VN]). | |
338 | 295 | |
339 | 296 | compile_r(P,B,Mod, set(variable(VN), T)) = |
340 | 297 | compile_r(P,B,Mod, T) → Nm & |
341 | emit('result = ') & | |
342 | emit(Nm) & | |
343 | emitln(';') & | |
344 | emit(VN) & | |
345 | emitln(' = result;') & | |
298 | emitln_fmt('result = %s;', [Nm]) & | |
299 | emitln_fmt('%s = result;', [VN]) & | |
346 | 300 | emitln('ok = 1;'). |
347 | 301 | |
348 | 302 | compile_r(P,B,Mod, while(R)) = |
376 | 330 | indent & |
377 | 331 | compile_r(P,B,Mod, T) → Nm & |
378 | 332 | $:gensym('flat') → FlatNm & |
379 | emit('struct term *') & | |
380 | emit(FlatNm) & | |
381 | emit(' = term_flatten(') & | |
382 | emit(Nm) & | |
383 | emitln(');') & | |
333 | emitln_fmt('struct term *%s = term_flatten(%s);', [FlatNm, Nm]) & | |
384 | 334 | emit_decl_state(B) & |
385 | 335 | emit_save_state(B) & |
386 | emit('scanner->buffer = ') & | |
387 | emit(FlatNm) & | |
388 | emitln('->atom;') & | |
389 | emit('scanner->size = ') & | |
390 | emit(FlatNm) & | |
391 | emitln('->size;') & | |
336 | emitln_fmt('scanner->buffer = %s->atom;', [FlatNm]) & | |
337 | emitln_fmt('scanner->size = %s->size;', [FlatNm]) & | |
392 | 338 | emitln('scanner->position = 0;') & |
393 | 339 | emitln('scanner->reset_position = 0;') & |
394 | 340 | compile_r(P,B,Mod, R) & |
405 | 351 | compile_r(P,B,Mod, R) & |
406 | 352 | emitln('scanner_pop_engine(scanner);'). |
407 | 353 | compile_r(P,B,Mod, using(R, prodref(SMNm, SPNm))) = |
408 | emit('scanner_push_engine(scanner, &prod_') & | |
409 | emit(SMNm) & | |
410 | emit('_') & | |
411 | emit(SPNm) & | |
412 | emitln(');') & | |
354 | emitln_fmt('scanner_push_engine(scanner, &prod_%s_%s);', [SMNm, SPNm]) & | |
413 | 355 | compile_r(P,B,Mod, R) & |
414 | 356 | emitln('scanner_pop_engine(scanner);'). |
415 | 357 | |
417 | 359 | compile_r(P,B,Mod, L) → NmL & |
418 | 360 | compile_r(P,B,Mod, R) → NmR & |
419 | 361 | $:gensym('temp') → Nm & |
420 | emit('struct term *') & | |
421 | emit(Nm) & | |
422 | emit(' = term_concat(term_flatten(') & | |
423 | emit(NmL) & | |
424 | emit('), term_flatten(') & | |
425 | emit(NmR) & | |
426 | emitln('));') & | |
362 | emitln_fmt('struct term *%s = term_concat(term_flatten(%s), ' + | |
363 | 'term_flatten(%s));', [Nm, NmL, NmR]) & | |
427 | 364 | Nm. |
428 | 365 | |
429 | 366 | compile_r(P,B,Mod, atom(T)) = |
441 | 378 | |
442 | 379 | # TODO: this is only one way to compile a variable; there are others |
443 | 380 | compile_r(P,B,Mod, variable(VN)) = |
444 | emit('struct term *') & | |
445 | 381 | $:gensym('temp') → Nm & |
446 | emit(Nm) & | |
447 | emit(' = ') & | |
448 | emit(VN) & | |
449 | emitln(';') & | |
382 | emitln_fmt('struct term *%s = %s;', [Nm, VN]) & | |
450 | 383 | Nm. |
451 | 384 | |
452 | 385 | compile_r(P,B,Mod, constructor(T,Ts)) = |
464 | 397 | emit_subterms(P,B,Mod, ON, nil) = 'ok'. |
465 | 398 | emit_subterms(P,B,Mod, ON, list(H,T)) = |
466 | 399 | compile_r(P,B,Mod, H) → Nm & |
467 | emit('term_add_subterm(') & | |
468 | emit(ON) & | |
469 | emit(', ') & | |
470 | emit(Nm) & | |
471 | emitln(');') & | |
400 | emitln_fmt('term_add_subterm(%s, %s);', [ON, Nm]) & | |
472 | 401 | emit_subterms(P,B,Mod, ON, T). |
473 | 402 | |
474 | 403 | ############### emitting pattern terms ############### |
511 | 440 | emit_pattern_subterms(ON, nil) = 'ok'. |
512 | 441 | emit_pattern_subterms(ON, list(H,T)) = |
513 | 442 | emit_pattern(H) → Nm & |
514 | emit('term_add_subterm(') & | |
515 | emit(ON) & | |
516 | emit(', ') & | |
517 | emit(Nm) & | |
518 | emitln(');') & | |
443 | emitln_fmt('term_add_subterm(%s, %s);', [ON, Nm]) & | |
519 | 444 | emit_pattern_subterms(ON, T). |
520 | 445 | |
521 | 446 | ########### finding variables in patterns ########### |
570 | 495 | PatNms ← list(PatNm, PatNms) & |
571 | 496 | emit_formal_match_patterns(Nms, Fs, PatNms). |
572 | 497 | |
573 | emit_pattern_match_expression(nil, nil) = 'ok'. | |
574 | emit_pattern_match_expression(list(PatNm, PatNms), list(FmlNm, FmlNms)) = | |
575 | emit(' term_match(') & | |
576 | emit(PatNm) & | |
577 | emit(', ') & | |
578 | emit(FmlNm) & | |
579 | emitln(') &&') & | |
498 | emit_pattern_match_expression([], []) = 'ok'. | |
499 | emit_pattern_match_expression([PatNm | PatNms], [FmlNm | FmlNms]) = | |
500 | emitln_fmt(' term_match(%s, %s) &&', [PatNm, FmlNm]) & | |
580 | 501 | emit_pattern_match_expression(PatNms, FmlNms). |
581 | 502 | |
582 | 503 | # declare and get variables which are found in patterns for this branch |
590 | 511 | |
591 | 512 | emit_assign_matched_variables(PatNm, nil) = 'ok'. |
592 | 513 | emit_assign_matched_variables(PatNm, list(VN, T)) = |
593 | emit('struct term *') & | |
594 | emit(VN) & | |
595 | emit(' = term_find_variable(') & | |
596 | emit(PatNm) & | |
597 | emit(', "') & | |
598 | emit(VN) & | |
599 | emitln('");') & | |
514 | emitln_fmt('struct term *%s = term_find_variable(%s, "%s");', | |
515 | [VN, PatNm, VN]) & | |
600 | 516 | emit_assign_matched_variables(PatNm, T). |
601 | 517 | |
602 | 518 | emit_locals(nil, Dont) = 'ok'. |
603 | 519 | emit_locals(list(H,T), Dont) = |
604 | 520 | (list:member(H, Dont) | |
605 | emit('struct term *') & | |
606 | emit(H) & | |
607 | emitln(';')) & | |
521 | emitln_fmt('struct term *%s;', [H])) & | |
608 | 522 | emit_locals(T, Dont). |
609 | 523 | |
610 | 524 | ### for calls... |
615 | 529 | Nms ← list(Nm, Nms) & |
616 | 530 | emit_arguments(P,B,Mod, Tail, Nms). |
617 | 531 | |
618 | emit_arguments_call(nil) = 'ok'. | |
619 | emit_arguments_call(list(H, nil)) = | |
532 | emit_arguments_call([]) = 'ok'. | |
533 | emit_arguments_call([H]) = | |
620 | 534 | emit(H). |
621 | emit_arguments_call(list(H, T)) = | |
535 | emit_arguments_call([H|T]) = | |
622 | 536 | emit(H) & |
623 | 537 | emit(', ') & |
624 | 538 | emit_arguments_call(T). |
652 | 566 | emitln('const char *buffer;') & |
653 | 567 | emitln('int buffer_size;'). |
654 | 568 | |
655 | emit_decl_state_locals(nil) = 'ok'. | |
656 | emit_decl_state_locals(list(H,T)) = | |
657 | emit('struct term *save_') & | |
658 | emit(H) & | |
659 | emitln(';') & | |
569 | emit_decl_state_locals([]) = 'ok'. | |
570 | emit_decl_state_locals([H|T]) = | |
571 | emitln_fmt('struct term *save_%s;', [H]) & | |
660 | 572 | emit_decl_state_locals(T). |
661 | 573 | |
662 | 574 | emit_save_state(prodbranch(Fs, Ls, E)) = |
666 | 578 | emitln('buffer = scanner->buffer;') & |
667 | 579 | emitln('buffer_size = scanner->size;'). |
668 | 580 | |
669 | emit_save_state_locals(nil) = 'ok'. | |
670 | emit_save_state_locals(list(H,T)) = | |
671 | emit('save_') & | |
672 | emit(H) & | |
673 | emit(' = ') & | |
674 | emit(H) & | |
675 | emitln(';') & | |
581 | emit_save_state_locals([]) = 'ok'. | |
582 | emit_save_state_locals([H|T]) = | |
583 | emitln_fmt('save_%s = %s;', [H, H]) & | |
676 | 584 | emit_save_state_locals(T). |
677 | 585 | |
678 | 586 | emit_restore_state(prodbranch(Fs, Ls, E)) = |
682 | 590 | emitln('scanner->size = buffer_size;') & |
683 | 591 | emit_restore_state_locals(Ls). |
684 | 592 | |
685 | emit_restore_state_locals(nil) = 'ok'. | |
686 | emit_restore_state_locals(list(H,T)) = | |
687 | emit(H) & | |
688 | emit(' = ') & | |
689 | emit('save_') & | |
690 | emit(H) & | |
691 | emitln(';') & | |
593 | emit_restore_state_locals([]) = 'ok'. | |
594 | emit_restore_state_locals([H|T]) = | |
595 | emitln_fmt('%s = save_%s;', [H, H]) & | |
692 | 596 | emit_restore_state_locals(T). |
693 | ||
694 | 597 | } |