Fix yet another bug in GC, in which the instruction pointer was not
[panda.git] / src / st-generator.c
blob525434b0d96f42933c40458fa58d7aef613511fd
1 /*
2 * st-generator.c
4 * Copyright (C) 2008 Vincent Geddes
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 #include "st-compiler.h"
27 #include "st-types.h"
28 #include "st-object.h"
29 #include "st-symbol.h"
30 #include "st-dictionary.h"
31 #include "st-method.h"
32 #include "st-array.h"
33 #include "st-array.h"
34 #include "st-universe.h"
35 #include "st-behavior.h"
36 #include "st-character.h"
37 #include "st-unicode.h"
39 #include <string.h>
40 #include <stdlib.h>
41 #include <setjmp.h>
43 #define DEFAULT_CODE_SIZE 50
45 #define CSTRING(string) ((char *) st_byte_array_bytes (string))
47 typedef struct
49 bool in_block;
51 st_oop class;
53 jmp_buf jmploc;
55 st_compiler_error *error;
57 st_uint max_stack_depth;
59 bool references_super;
61 /* names of temporaries, in order of appearance */
62 st_list *temporaries;
63 /* names of instvars, in order they were defined */
64 st_list *instvars;
65 /* literal frame for the compiled code */
66 st_list *literals;
68 st_uchar *code;
69 st_uint size;
70 st_uint alloc;
72 } Generator;
74 static st_uint sizes[255] = { 0, };
77 // setup global data for compiler
78 static void
79 check_init (void)
81 static bool initialized = false;
83 if (initialized)
84 return;
85 initialized = true;
87 /* The size (in bytes) of each bytecode instruction
89 sizes[PUSH_TEMP] = 2;
90 sizes[PUSH_INSTVAR] = 2;
91 sizes[PUSH_LITERAL_CONST] = 2;
92 sizes[PUSH_LITERAL_VAR] = 2;
93 sizes[PUSH_SELF] = 1;
94 sizes[PUSH_NIL] = 1;
95 sizes[PUSH_TRUE] = 1;
96 sizes[PUSH_FALSE] = 1;
97 sizes[PUSH_INTEGER] = 2;
98 sizes[STORE_LITERAL_VAR] = 2;
99 sizes[STORE_TEMP] = 2;
100 sizes[STORE_INSTVAR] = 2;
101 sizes[STORE_POP_LITERAL_VAR] = 2;
102 sizes[STORE_POP_TEMP] = 2;
103 sizes[STORE_POP_INSTVAR] = 2;
104 sizes[RETURN_STACK_TOP] = 1;
105 sizes[BLOCK_RETURN] = 1;
106 sizes[POP_STACK_TOP] = 1;
107 sizes[DUPLICATE_STACK_TOP] = 1;
108 sizes[PUSH_ACTIVE_CONTEXT] = 1;
109 sizes[BLOCK_COPY] = 2;
110 sizes[JUMP_TRUE] = 3;
111 sizes[JUMP_FALSE] = 3;
112 sizes[JUMP] = 3;
113 sizes[SEND] = 3;
114 sizes[SEND_SUPER] = 3;
115 sizes[SEND_PLUS] = 1;
116 sizes[SEND_MINUS] = 1;
117 sizes[SEND_LT] = 1;
118 sizes[SEND_GT] = 1;
119 sizes[SEND_LE] = 1;
120 sizes[SEND_GE] = 1;
121 sizes[SEND_EQ] = 1;
122 sizes[SEND_NE] = 1;
123 sizes[SEND_MUL] = 1;
124 sizes[SEND_DIV] = 1;
125 sizes[SEND_MOD] = 1;
126 sizes[SEND_BITSHIFT] = 1;
127 sizes[SEND_BITAND] = 1;
128 sizes[SEND_BITOR] = 1;
129 sizes[SEND_BITXOR] = 1;
130 sizes[SEND_AT] = 1;
131 sizes[SEND_AT_PUT] = 1;
132 sizes[SEND_SIZE] = 1;
133 sizes[SEND_VALUE] = 1;
134 sizes[SEND_VALUE_ARG] = 1;
135 sizes[SEND_IDENTITY_EQ] = 1;
136 sizes[SEND_CLASS] = 1;
137 sizes[SEND_NEW] = 1;
138 sizes[SEND_NEW_ARG] = 1;
141 static int size_message (Generator *gt, st_node *node);
142 static int size_expression (Generator *gt, st_node *node);
143 static int size_statements (Generator *gt, st_node *node);
146 static void generate_expression (Generator *gt, st_node *node);
147 static void generate_statements (Generator *gt, st_node *statements);
149 static void
150 generation_error (Generator *gt, const char *message, st_node *node)
152 if (gt->error) {
153 strncpy (gt->error->message, message, 255);
154 gt->error->line = node->line;
155 gt->error->column = 0;
158 longjmp (gt->jmploc, 0);
161 static st_list *
162 get_temporaries (Generator *gt,
163 st_list *instvars,
164 st_node *arguments,
165 st_node *temporaries)
167 st_list *temps = NULL;
169 for (st_node *n = arguments; n; n = n->next) {
171 for (st_list *l = instvars; l; l = l->next) {
172 if (streq (n->variable.name, (char *) l->data))
173 generation_error (gt, "name is already defined", arguments);
175 temps = st_list_prepend (temps, (st_pointer) n->variable.name);
178 for (st_node *n = temporaries; n; n = n->next) {
180 for (st_list *l = instvars; l; l = l->next) {
181 if (streq (n->variable.name, (char *) l->data))
182 generation_error (gt, "name is already defined", temporaries);
184 temps = st_list_prepend (temps, (st_pointer) n->variable.name);
187 return st_list_reverse (temps);
190 static Generator *
191 generator_new (void)
193 Generator *gt;
195 gt = st_new0 (Generator);
197 gt->class = 0;
198 gt->instvars = NULL;
199 gt->literals = NULL;
200 gt->temporaries = NULL;
202 gt->max_stack_depth = 0;
203 gt->references_super = false;
205 gt->code = st_malloc (DEFAULT_CODE_SIZE);
206 gt->alloc = DEFAULT_CODE_SIZE;
207 gt->size = 0;
209 return gt;
212 static void
213 generator_destroy (Generator *gt)
215 st_list_destroy (gt->instvars);
216 st_list_destroy (gt->temporaries);
217 st_list_destroy (gt->literals);
219 st_free (gt->code);
220 st_free (gt);
223 static st_oop
224 create_literals_array (Generator *gt)
226 int count;
227 st_oop literals = st_nil;
229 if (gt->references_super)
230 gt->literals = st_list_append (gt->literals, (st_pointer) gt->class);
232 count = st_list_length (gt->literals);
234 if (count > 0) {
235 literals = st_object_new_arrayed (st_array_class, count);
237 int i = 1;
238 for (st_list *l = gt->literals; l; l = l->next) {
239 st_array_at_put (literals, i, (st_oop) l->data);
240 i++;
244 return literals;
247 static st_oop
248 create_bytecode_array (Generator *gt)
250 if (gt->size == 0)
251 return st_nil;
253 st_oop bytecode;
254 st_uchar *bytes;
256 bytecode = st_object_new_arrayed (st_byte_array_class, gt->size);
257 bytes = st_byte_array_bytes (bytecode);
258 memcpy (bytes, gt->code, gt->size);
260 return bytecode;
263 static void
264 emit (Generator *gt, st_uchar code)
266 if (++gt->size > gt->alloc) {
267 gt->alloc += gt->alloc;
268 gt->code = st_realloc (gt->code, gt->alloc);
271 gt->code[gt->size - 1] = code;
275 static int
276 find_instvar (Generator *gt, char *name)
278 int i = 0;
279 for (st_list *l = gt->instvars; l; l = l->next) {
281 if (streq (name, (char *) l->data))
282 return i;
283 i++;
285 return -1;
288 static int
289 find_temporary (Generator *gt, char *name)
291 int i = 0;
293 for (st_list *l = gt->temporaries; l; l = l->next) {
295 if (streq (name, (char *) l->data))
296 return i;
297 i++;
299 return -1;
302 static int
303 find_literal_const (Generator *gt, st_oop literal)
305 int i = 0;
306 for (st_list *l = gt->literals; l; l = l->next) {
308 if (st_object_equal (literal, (st_oop) l->data))
309 return i;
310 i++;
312 gt->literals = st_list_append (gt->literals, (void *) literal);
313 return i;
316 static int
317 find_literal_var (Generator *gt, char *name)
319 st_oop assoc;
321 assoc = st_dictionary_association_at (st_globals, st_symbol_new (name));
322 if (assoc == st_nil)
323 return -1;
325 int i = 0;
326 for (st_list *l = gt->literals; l; l = l->next) {
327 if (st_object_equal (assoc, (st_oop) l->data))
328 return i;
329 i++;
331 gt->literals = st_list_append (gt->literals, (st_pointer) assoc);
332 return i;
335 static void
336 jump_offset (Generator *gt, int offset)
338 st_assert (offset <= INT16_MAX);
340 emit (gt, JUMP);
342 /* push low byte */
343 emit (gt, offset & 0xFF);
344 /* push high byte */
345 emit (gt, (offset >> 8) & 0xFF);
349 static void
350 assign_temp (Generator *gt, int index, bool pop)
352 st_assert (index <= 255);
354 if (pop)
355 emit (gt, STORE_POP_TEMP);
356 else
357 emit (gt, STORE_TEMP);
358 emit (gt, (st_uchar) index);
361 static void
362 assign_instvar (Generator *gt, int index, bool pop)
364 st_assert (index <= 255);
366 if (pop)
367 emit (gt, STORE_POP_INSTVAR);
368 else
369 emit (gt, STORE_INSTVAR);
370 emit (gt, (st_uchar) index);
373 static void
374 assign_literal_var (Generator *gt, int index, bool pop)
376 st_assert (index <= 255);
378 if (pop)
379 emit (gt, STORE_POP_LITERAL_VAR);
380 else
381 emit (gt, STORE_LITERAL_VAR);
382 emit (gt, (st_uchar) index);
385 static void
386 push (Generator *gt, st_uchar code, st_uchar index)
388 emit (gt, code);
389 emit (gt, index);
391 gt->max_stack_depth++;
395 static void
396 push_special (Generator *gt, st_uchar code)
398 emit (gt, code);
399 gt->max_stack_depth++;
402 static int
403 size_assign (Generator *gt, st_node *node)
405 return size_expression (gt, node->assign.expression) + 2;
408 static void
409 generate_assign (Generator *gt, st_node *node, bool pop)
411 int index;
413 generate_expression (gt, node->assign.expression);
415 index = find_temporary (gt, node->assign.assignee->variable.name);
416 if (index >= 0) {
417 assign_temp (gt, index, pop);
418 return;
421 index = find_instvar (gt, node->assign.assignee->variable.name);
422 if (index >= 0) {
423 assign_instvar (gt, index, pop);
424 return;
427 index = find_literal_var (gt, node->assign.assignee->variable.name);
428 if (index >= 0) {
429 assign_literal_var (gt, index, pop);
430 return;
433 generation_error (gt, "unknown variable", node);
436 static int
437 size_return (Generator *gt, st_node *node)
439 int size = 0;
441 size += size_expression (gt, node->retrn.expression);
443 size += sizes[RETURN_STACK_TOP];
445 return size;
448 static void
449 generate_return (Generator *gt, st_node *node)
451 generate_expression (gt, node->retrn.expression);
453 emit (gt, RETURN_STACK_TOP);
456 static st_list *
457 get_block_temporaries (Generator *gt, st_node *temporaries)
459 st_list *temps = NULL;
461 for (st_node *node = temporaries; node; node = node->next) {
463 for (st_list *l = gt->instvars; l; l = l->next) {
464 if (streq (node->variable.name, (char *) l->data))
465 generation_error (gt, "name is already defined", node);
468 for (st_list *l = gt->temporaries; l; l = l->next) {
469 if (streq (node->variable.name, (char *) l->data))
470 generation_error (gt, "name already used in method", node);
473 temps = st_list_prepend (temps, (st_pointer) node->variable.name);
477 return st_list_reverse (temps);
481 static int
482 size_block (Generator *gt, st_node *node)
484 int size = 0;
486 size += sizes[BLOCK_COPY];
487 size += sizes[JUMP];
488 size += sizes[STORE_POP_TEMP] * st_node_list_length (node->block.arguments);
489 size += size_statements (gt, node->block.statements);
490 size += sizes[BLOCK_RETURN];
492 return size;
495 static void
496 generate_block (Generator *gt, st_node *node)
498 bool in_block;
499 int index, size = 0;
501 in_block = gt->in_block;
502 gt->in_block = true;
504 emit (gt, BLOCK_COPY);
505 emit (gt, st_node_list_length (node->block.arguments));
507 // get size of block code and then jump around that code
508 size = 2 * st_node_list_length (node->block.arguments);
509 size += size_statements (gt, node->block.statements);
510 size += sizes[BLOCK_RETURN];
511 jump_offset (gt, size);
513 /* Store all block arguments into the temporary frame.
514 Note that upon a block activation, the stack pointer sits
515 above the last argument to to the block */
516 st_node *l;
517 st_uint i = st_node_list_length (node->block.arguments);
518 for (; i > 0; --i) {
519 l = st_node_list_at (node->block.arguments, i - 1);
520 index = find_temporary (gt, l->variable.name);
521 st_assert (index >= 0);
522 assign_temp (gt, index, true);
525 generate_statements (gt, node->block.statements);
527 emit (gt, BLOCK_RETURN);
529 if (in_block == false)
530 gt->in_block = false;
533 static void
534 generation_func_1 (Generator *gt, st_node *node, st_uint subpattern_index)
536 st_node *block;
537 int size;
539 block = node->message.arguments;
540 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
541 generation_error (gt, "argument of ifTrue: message must be a 0-argument block", block);
543 generate_expression (gt, node->message.receiver);
545 size = size_statements (gt, block->block.statements);
547 if (!node->message.is_statement)
548 size += sizes[JUMP];
549 else
550 size += sizes[POP_STACK_TOP];
552 if (subpattern_index == 0)
553 emit (gt, JUMP_FALSE);
554 else
555 emit (gt, JUMP_TRUE);
556 emit (gt, size & 0xFF);
557 emit (gt, (size >> 8) & 0xFF);
559 generate_statements (gt, block->block.statements);
561 if (!node->message.is_statement) {
562 emit (gt, JUMP);
563 emit (gt, 1);
564 emit (gt, 0);
565 emit (gt, PUSH_NIL);
566 } else {
567 emit (gt, POP_STACK_TOP);
572 static int
573 size_func_1 (Generator *gt, st_node *node, st_uint subpattern_index)
575 st_node *block;
576 int size = 0;
578 block = node->message.arguments;
579 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
580 generation_error (gt, "argument of ifTrue: message must be a 0-argument block", block);
583 size += size_expression (gt, node->message.receiver);
584 size += sizes[JUMP_TRUE];
585 size += size_statements (gt, node->message.arguments->block.statements);
587 if (!node->message.is_statement) {
588 size += sizes[JUMP];
589 size += sizes[PUSH_NIL];
590 } else {
591 size += sizes[POP_STACK_TOP];
594 return size;
598 static void
599 generation_func_2 (Generator *gt, st_node *node, st_uint subpattern_index)
601 int size;
603 st_node *true_block, *false_block;
605 true_block = node->message.arguments;
606 if (true_block->type != ST_BLOCK_NODE || true_block->block.arguments != NULL)
607 generation_error (gt, "first argument of ifTrue:ifFalse message must be a 0-argument block", true_block);
608 false_block = node->message.arguments->next;
609 if (false_block->type != ST_BLOCK_NODE || false_block->block.arguments != NULL)
610 generation_error (gt, "second argument of ifTrue:ifFalse message must be a 0-argument block", false_block);
612 generate_expression (gt, node->message.receiver);
614 // add 3 for size of jump instr at end of true block
615 size = size_statements (gt, true_block->block.statements);
616 size += sizes[JUMP];
618 if (subpattern_index == 0)
619 emit (gt, JUMP_FALSE);
620 else
621 emit (gt, JUMP_TRUE);
622 emit (gt, size & 0xFF);
623 emit (gt, (size >> 8) & 0xFF);
626 generate_statements (gt, true_block->block.statements);
628 size = size_statements (gt, false_block->block.statements);
629 emit (gt, JUMP);
630 emit (gt, size & 0xFF);
631 emit (gt, (size >> 8) & 0xFF);
633 generate_statements (gt, false_block->block.statements);
635 if (node->message.is_statement)
636 emit (gt, POP_STACK_TOP);
639 static int
640 size_func_2 (Generator *gt, st_node *node, st_uint subpattern_index)
642 int size= 0;
644 st_node *true_block, *false_block;
646 true_block = node->message.arguments;
647 if (true_block->type != ST_BLOCK_NODE || true_block->block.arguments != NULL)
648 generation_error (gt, "first argument of ifTrue:ifFalse message must be a 0-argument block", true_block);
649 false_block = node->message.arguments->next;
650 if (false_block->type != ST_BLOCK_NODE || false_block->block.arguments != NULL)
651 generation_error (gt, "second argument of ifTrue:ifFalse message must be a 0-argument block", false_block);
653 size += size_expression (gt, node->message.receiver);
654 size += sizes[JUMP_TRUE];
656 // true block
657 size += size_statements (gt, node->message.arguments->block.statements);
658 size += sizes[JUMP];
659 size += size_statements (gt, node->message.arguments->next->block.statements);
661 if (node->message.is_statement)
662 size += sizes[POP_STACK_TOP];
664 return size;
667 static void
668 generation_func_3 (Generator *gt, st_node *node, st_uint subpattern_index)
670 st_node *block;
671 int size;
673 block = node->message.receiver;
674 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
675 generation_error (gt, st_strdup_printf ("receiver of %s message must be a zero argument block",
676 subpattern_index == 0 ? "#whileTrue" : "#whileFalse"), block);
678 generate_statements (gt, block->block.statements);
680 // jump around jump statement
681 if (subpattern_index == 0)
682 emit (gt, JUMP_FALSE);
683 else
684 emit (gt, JUMP_TRUE);
685 emit (gt, 3);
686 emit (gt, 0);
689 size = size_statements (gt, block->block.statements);
690 size += sizes[JUMP_FALSE];
691 // we jump backwards
692 size = - size;
694 emit (gt, JUMP);
695 emit (gt, size & 0xFF);
696 emit (gt, (size >> 8) & 0xFF);
698 if (!node->message.is_statement)
699 emit (gt, PUSH_NIL);
702 static int
703 size_func_3 (Generator *gt, st_node *node, st_uint subpattern_index)
705 st_node *block;
706 int size = 0;
708 block = node->message.receiver;
709 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
710 generation_error (gt, st_strdup_printf ("receiver of %s message must be a zero argument block",
711 subpattern_index == 0 ? "#whileTrue" : "#whileFalse"), block);
713 size += size_statements (gt, node->message.receiver->block.statements);
714 size += sizes[JUMP_TRUE];
715 size += sizes[JUMP];
717 if (!node->message.is_statement)
718 size += sizes[PUSH_NIL];
720 return size;
723 static void
724 generation_func_4 (Generator *gt, st_node *node, st_uint subpattern_index)
726 st_node *block;
727 int size;
729 block = node->message.receiver;
730 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
731 generation_error (gt, st_strdup_printf ("receiver of %s message must be a zero argument block",
732 subpattern_index == 0 ? "#whileTrue:" : "#whileFalse:"), block);
734 block = node->message.arguments;
735 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
736 generation_error (gt, st_strdup_printf ("argument of %s message must be a zero argument block",
737 subpattern_index == 0 ? "#whileTrue:" : "#whileFalse:"), block);
739 generate_statements (gt, node->message.receiver->block.statements);
741 if (subpattern_index == 0)
742 emit (gt, JUMP_FALSE);
743 else
744 emit (gt, JUMP_TRUE);
746 size = size_statements (gt, node->message.arguments->block.statements);
747 // include size of POP and JUMP statement
748 size += sizes[POP_STACK_TOP] + sizes[JUMP];
750 emit (gt, size & 0xFF);
751 emit (gt, (size >> 8) & 0xFF);
754 generate_statements (gt, node->message.arguments->block.statements);
756 size += size_statements (gt, node->message.receiver->block.statements);
757 size = - size;
759 emit (gt, POP_STACK_TOP);
761 emit (gt, JUMP);
762 emit (gt, size & 0xFF);
763 emit (gt, (size >> 8) & 0xFF);
765 if (!node->message.is_statement)
766 emit (gt, PUSH_NIL);
770 static int
771 size_func_4 (Generator *gt, st_node *node, st_uint subpattern_index)
773 st_node *block;
774 int size = 0;
776 block = node->message.receiver;
777 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
778 generation_error (gt, st_strdup_printf ("receiver of %s message must be a zero argument block",
779 subpattern_index == 0 ? "#whileTrue:" : "#whileFalse:"), block);
781 block = node->message.arguments;
782 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
783 generation_error (gt, st_strdup_printf ("argument of %s message must be a zero argument block",
784 subpattern_index == 0 ? "#whileTrue:" : "#whileFalse:"), block);
786 size += size_statements (gt, node->message.receiver->block.statements);
787 size += sizes[JUMP_TRUE];
788 size += size_statements (gt, node->message.arguments->block.statements);
789 size += sizes[POP_STACK_TOP] + sizes[JUMP];
791 if (!node->message.is_statement)
792 size += sizes[PUSH_NIL];
794 return size;
797 static void
798 generation_func_5 (Generator *gt, st_node *node, st_uint subpattern_index)
800 st_node *block;
801 int size;
803 block = node->message.arguments;
804 if (block->type != ST_BLOCK_NODE || block->block.arguments != NULL)
805 generation_error (gt, st_strdup_printf ("argument of %s message must be a zero argument block",
806 subpattern_index == 0 ? "#and:" : "#or:"), block);
808 generate_expression (gt, node->message.receiver);
810 size = size_statements (gt, block->block.statements);
811 // size of JUMP instr after block statements
812 size += 3;
814 if (subpattern_index == 0)
815 emit (gt, JUMP_FALSE);
816 else
817 emit (gt, JUMP_TRUE);
818 emit (gt, size & 0xFF);
819 emit (gt, (size >> 8) & 0xFF);
821 generate_statements (gt, block->block.statements);
823 emit (gt, JUMP);
824 emit (gt, 1);
825 emit (gt, 0);
827 if (subpattern_index == 0)
828 emit (gt, PUSH_FALSE);
829 else
830 emit (gt, PUSH_TRUE);
832 if (node->message.is_statement)
833 emit (gt, POP_STACK_TOP);
837 static int
838 size_func_5 (Generator *gt, st_node *node, st_uint subpattern_index)
840 int size = 0;
842 size += size_expression (gt, node->message.receiver);
843 size += sizes[JUMP_TRUE];
844 size += size_statements (gt, node->message.arguments->block.statements);
845 size += sizes[JUMP];
846 size += sizes[PUSH_TRUE];
848 if (node->message.is_statement)
849 size += sizes[POP_STACK_TOP];
851 return size;
854 typedef void (* CodeGenerationFunc) (Generator *gt, st_node *message, st_uint subpattern_index);
855 typedef int (* CodeSizeFunc) (Generator *gt, st_node *message, st_uint subpattern_index);
857 static const struct generators {
859 const char *const pattern[3];
860 CodeGenerationFunc generation_func;
861 CodeSizeFunc size_func;
863 } generators[] =
865 { { "ifTrue:", "ifFalse", NULL },
866 generation_func_1, size_func_1 },
867 { { "ifTrue:ifFalse:", "ifFalse:ifTrue:", NULL },
868 generation_func_2, size_func_2 },
869 { { "whileTrue", "whileFalse", NULL },
870 generation_func_3, size_func_3 },
871 { { "whileTrue:", "whileFalse:", NULL },
872 generation_func_4, size_func_4 },
873 { { "and:", "or:", NULL },
874 generation_func_5, size_func_5 },
877 static int
878 size_message_send (Generator *gt, st_node *node)
880 st_node *args;
881 int size = 0;
883 args = node->message.arguments;
884 for (; args; args = args->next)
885 size += size_expression (gt, args);
887 /* check if message is a special */
888 for (int i = 0; i < ST_N_ELEMENTS (st_specials); i++) {
889 if (!node->message.super_send && node->message.selector == st_specials[i]) {
890 size += 1;
891 goto out;
895 size += sizes[SEND];
897 out:
899 if (node->message.is_statement)
900 size += sizes[POP_STACK_TOP];
902 return size;
905 static void
906 generate_message_send (Generator *gt, st_node *node)
908 st_node *args;
909 st_uint argcount = 0;
911 /* generate arguments */
912 args = node->message.arguments;
913 for (; args; args = args->next) {
914 generate_expression (gt, args);
915 argcount++;
918 /* check if message is a special */
919 for (int i = 0; i < ST_N_ELEMENTS (st_specials); i++) {
920 if (!node->message.super_send && node->message.selector == st_specials[i]) {
921 emit (gt, SEND_PLUS + i);
922 goto out;
926 if (node->message.super_send)
927 emit (gt, SEND_SUPER);
928 else
929 emit (gt, SEND);
931 emit (gt, (st_uchar) argcount);
933 int index = find_literal_const (gt, node->message.selector);
934 emit (gt, (st_uchar) index);
936 out:
938 if (node->message.is_statement)
939 emit (gt, POP_STACK_TOP);
943 static int
944 size_cascade (Generator *gt, st_node *node)
946 st_uint i, j;
947 st_uint size = 0;
949 size += size_expression (gt, node->cascade.receiver);
950 size += sizes[DUPLICATE_STACK_TOP];
952 for (st_list *l = node->cascade.messages; l; l = l->next) {
954 size += size_message_send (gt, (st_node *) l->data);
956 if (l->next || node->cascade.is_statement)
957 size += sizes[POP_STACK_TOP];
959 if (l->next && l->next->next)
960 size += sizes[DUPLICATE_STACK_TOP];
963 return size;
966 static void
967 generate_cascade (Generator *gt, st_node *node)
969 st_uint i, j;
971 generate_expression (gt, node->cascade.receiver);
972 emit (gt, DUPLICATE_STACK_TOP);
974 for (st_list *l = node->cascade.messages; l; l = l->next) {
976 generate_message_send (gt, (st_node*) l->data);
978 if (l->next || node->cascade.is_statement)
979 emit (gt, POP_STACK_TOP);
981 if (l->next && l->next->next)
982 emit (gt, DUPLICATE_STACK_TOP);
986 static int
987 size_message (Generator *gt, st_node *node)
989 const char *selector;
990 st_uint i, j;
991 st_uint size = 0;
993 selector = CSTRING (node->message.selector);
995 for (i = 0; i < ST_N_ELEMENTS (generators); i++) {
996 for (j = 0; j < ST_N_ELEMENTS (generators[i].pattern); j++) {
997 if (generators[i].pattern[j] && strcmp (generators[i].pattern[j], selector) == 0) {
998 size += generators[i].size_func (gt, node, j);
999 return size;
1004 size += size_expression (gt, node->message.receiver);
1005 size += size_message_send (gt, node);
1007 return size;
1010 static void
1011 generate_message (Generator *gt, st_node *node)
1013 const char *selector;
1014 st_uint i, j;
1016 selector = CSTRING (node->message.selector);
1018 for (i = 0; i < ST_N_ELEMENTS (generators); i++) {
1019 for (j = 0; j < ST_N_ELEMENTS (generators[i].pattern); j++) {
1020 if (generators[i].pattern[j] && strcmp (generators[i].pattern[j], selector) == 0) {
1021 generators[i].generation_func (gt, node, j);
1022 return;
1027 generate_expression (gt, node->message.receiver);
1028 generate_message_send (gt, node);
1031 static int
1032 size_expression (Generator *gt, st_node *node)
1034 int index;
1035 int size = 0;
1037 switch (node->type) {
1038 case ST_VARIABLE_NODE:
1040 const char *name = node->variable.name;
1042 if (streq (name, "self") || streq (name, "super")) {
1043 size += sizes[PUSH_SELF];
1044 break;
1045 } else if (streq (name, "true")) {
1046 size += sizes[PUSH_TRUE];
1047 break;
1048 } else if (streq (name, "false")) {
1049 size += sizes[PUSH_FALSE];
1050 break;
1051 } else if (streq (name, "nil")) {
1052 size += sizes[PUSH_NIL];
1053 break;
1054 } else if (streq (name, "thisContext")) {
1055 size += sizes[PUSH_ACTIVE_CONTEXT];
1056 break;
1059 index = find_temporary (gt, node->variable.name);
1060 if (index >= 0) {
1061 size += 2;
1062 break;
1064 index = find_instvar (gt, node->variable.name);
1065 if (index >= 0) {
1066 size += 2;
1067 break;
1069 index = find_literal_var (gt, node->variable.name);
1070 if (index >= 0) {
1071 size += 2;
1072 break;
1074 generation_error (gt, "unknown variable", node);
1076 case ST_LITERAL_NODE:
1078 /* use optimized PUSH_INTEGER for smis in the range of -127..127 */
1079 if (st_object_is_smi (node->literal.value) &&
1080 ((st_smi_value (node->literal.value) >= -127) &&
1081 (st_smi_value (node->literal.value) <= 127))) {
1082 size += sizes[PUSH_INTEGER];
1083 } else {
1084 size += sizes[PUSH_LITERAL_CONST];
1087 break;
1089 case ST_ASSIGN_NODE:
1090 size += size_assign (gt, node);
1091 break;
1093 case ST_BLOCK_NODE:
1094 size += size_block (gt, node);
1095 break;
1097 case ST_MESSAGE_NODE:
1099 size += size_message (gt, node);
1100 break;
1102 case ST_CASCADE_NODE:
1104 size += size_cascade (gt, node);
1105 break;
1107 default:
1108 st_assert_not_reached ();
1111 return size;
1114 static void
1115 generate_expression (Generator *gt, st_node *node)
1117 int index;
1119 switch (node->type) {
1120 case ST_VARIABLE_NODE:
1122 const char *name = node->variable.name;
1124 if (streq (name, "self")) {
1125 push_special (gt, PUSH_SELF);
1126 break;
1127 } else if (streq (name, "super")) {
1128 gt->references_super = true;
1129 push_special (gt, PUSH_SELF);
1130 break;
1131 } else if (streq (name, "true")) {
1132 push_special (gt, PUSH_TRUE);
1133 break;
1134 } else if (streq (name, "false")) {
1135 push_special (gt, PUSH_FALSE);
1136 break;
1137 } else if (streq (name, "nil")) {
1138 push_special (gt, PUSH_NIL);
1139 break;
1140 } else if (streq (name, "thisContext")) {
1141 push_special (gt, PUSH_ACTIVE_CONTEXT);
1142 break;
1145 index = find_temporary (gt, node->variable.name);
1146 if (index >= 0) {
1147 push (gt, PUSH_TEMP, index);
1148 break;
1150 index = find_instvar (gt, node->variable.name);
1151 if (index >= 0) {
1152 push (gt, PUSH_INSTVAR, index);
1153 break;
1155 index = find_literal_var (gt, node->variable.name);
1156 if (index >= 0) {
1157 push (gt, PUSH_LITERAL_VAR, index);
1158 break;
1160 generation_error (gt, "unknown variable", node);
1163 case ST_LITERAL_NODE:
1165 /* use optimized PUSH_INTEGER for smis in the range of -127..127 */
1166 if (st_object_is_smi (node->literal.value) &&
1167 ((st_smi_value (node->literal.value) >= -127) &&
1168 (st_smi_value (node->literal.value) <= 127))) {
1169 emit (gt, PUSH_INTEGER);
1170 emit (gt, st_smi_value (node->literal.value));
1171 } else {
1172 index = find_literal_const (gt, node->literal.value);
1173 push (gt, PUSH_LITERAL_CONST, index);
1175 break;
1177 case ST_ASSIGN_NODE:
1178 generate_assign (gt, node, false);
1179 break;
1181 case ST_BLOCK_NODE:
1182 generate_block (gt, node);
1183 break;
1185 case ST_MESSAGE_NODE:
1186 generate_message (gt, node);
1187 break;
1189 case ST_CASCADE_NODE:
1190 generate_cascade (gt, node);
1191 break;
1193 default:
1194 st_assert_not_reached ();
1198 static int
1199 size_statements (Generator *gt, st_node *statements)
1201 int size = 0;
1203 if (statements == NULL)
1204 size += sizes[PUSH_NIL];
1206 for (st_node *node = statements; node; node = node->next) {
1208 switch (node->type) {
1210 case ST_VARIABLE_NODE:
1211 case ST_LITERAL_NODE:
1212 case ST_BLOCK_NODE:
1214 * don't generate anything since we would end up with a constant
1215 * expression with no side-effects.
1217 * However, in a block with no explicit return, the value of the last statement is the implicit
1218 * value of the block.
1220 if (node->next == NULL)
1221 size += size_expression (gt, node);
1223 break;
1225 case ST_ASSIGN_NODE:
1227 size += size_assign (gt, node);
1229 break;
1231 case ST_RETURN_NODE:
1233 st_assert (node->next == NULL);
1234 size += size_return (gt, node);
1235 return size;
1237 case ST_MESSAGE_NODE:
1239 size += size_message (gt, node);
1240 break;
1242 case ST_CASCADE_NODE:
1244 size += size_cascade (gt, node);
1245 break;
1247 default:
1248 st_assert_not_reached ();
1252 return size;
1255 static void
1256 generate_statements (Generator *gt, st_node *statements)
1258 if (statements == NULL) {
1259 emit (gt, PUSH_NIL);
1262 for (st_node *node = statements; node; node = node->next) {
1264 switch (node->type) {
1266 case ST_VARIABLE_NODE:
1267 case ST_LITERAL_NODE:
1268 case ST_BLOCK_NODE:
1270 * don't generate anything in this case since we would end up with a constant
1271 * expression with no side-effects.
1273 * However, in a block with no explicit return, the value of the last statement is the implicit
1274 * value of the block.
1276 if (node->next == NULL)
1277 generate_expression (gt, node);
1278 break;
1280 case ST_ASSIGN_NODE:
1282 /* don't use STORE_POP if this is the last statement */
1283 if (node->next == NULL)
1284 generate_assign (gt, node, false);
1285 else
1286 generate_assign (gt, node, true);
1287 break;
1289 case ST_RETURN_NODE:
1291 st_assert (node->next == NULL);
1292 generate_return (gt, node);
1293 return;
1295 case ST_MESSAGE_NODE:
1297 generate_message (gt, node);
1298 break;
1300 case ST_CASCADE_NODE:
1302 generate_cascade (gt, node);
1303 break;
1305 default:
1306 st_assert_not_reached ();
1312 static void
1313 generate_method_statements (Generator *gt, st_node *statements)
1315 for (st_node *node = statements; node; node = node->next) {
1317 switch (node->type) {
1319 case ST_VARIABLE_NODE:
1320 case ST_LITERAL_NODE:
1321 case ST_BLOCK_NODE:
1322 break;
1324 case ST_ASSIGN_NODE:
1326 generate_assign (gt, node, true);
1327 break;
1329 case ST_RETURN_NODE:
1331 st_assert (node->next == NULL);
1332 generate_return (gt, node);
1333 return;
1335 case ST_MESSAGE_NODE:
1337 generate_message (gt, node);
1338 break;
1340 case ST_CASCADE_NODE:
1342 generate_cascade (gt, node);
1343 break;
1345 default:
1346 st_assert_not_reached ();
1350 emit (gt, PUSH_SELF);
1351 emit (gt, RETURN_STACK_TOP);
1354 static st_list *
1355 collect_temporaries (Generator *gt, st_node *node)
1357 st_list *temps = NULL;
1359 if (node == NULL)
1360 return NULL;
1362 if (node->type == ST_BLOCK_NODE)
1363 temps = st_list_concat (get_block_temporaries (gt, node->block.arguments),
1364 get_block_temporaries (gt, node->block.temporaries));
1366 switch (node->type) {
1367 case ST_BLOCK_NODE:
1368 temps = st_list_concat (temps, collect_temporaries (gt, node->block.statements));
1369 break;
1370 case ST_ASSIGN_NODE:
1371 temps = st_list_concat (temps, collect_temporaries (gt, node->assign.expression));
1372 break;
1373 case ST_RETURN_NODE:
1374 temps = st_list_concat (temps, collect_temporaries (gt, node->retrn.expression));
1375 break;
1376 case ST_MESSAGE_NODE:
1377 temps = st_list_concat (temps, collect_temporaries (gt, node->message.receiver));
1378 temps = st_list_concat (temps, collect_temporaries (gt, node->message.arguments));
1379 break;
1380 break;
1381 case ST_CASCADE_NODE:
1382 temps = st_list_concat (temps, collect_temporaries (gt, node->cascade.receiver));
1383 for (st_list *l = node->cascade.messages; l; l = l->next)
1384 temps = st_list_concat (temps, collect_temporaries (gt, (st_node *) l->data));
1386 break;
1388 case ST_METHOD_NODE:
1389 case ST_VARIABLE_NODE:
1390 case ST_LITERAL_NODE:
1391 break;
1394 temps = st_list_concat (temps, collect_temporaries (gt, node->next));
1396 return temps;
1399 st_oop
1400 st_generate_method (st_oop class, st_node *node, st_compiler_error *error)
1402 Generator *gt;
1403 st_oop method;
1405 st_assert (class != st_nil);
1406 st_assert (node != NULL && node->type == ST_METHOD_NODE);
1408 check_init ();
1410 gt = generator_new ();
1411 gt->error = error;
1413 if (setjmp (gt->jmploc))
1414 goto error;
1416 gt->class = class;
1417 gt->instvars = st_behavior_all_instance_variables (class);
1418 gt->temporaries = get_temporaries (gt, gt->instvars, node->method.arguments, node->method.temporaries);
1420 /* collect all block-level temporaries */
1421 gt->temporaries = st_list_concat (gt->temporaries, collect_temporaries (gt, node->method.statements));
1423 // generate bytecode
1424 generate_method_statements (gt, node->method.statements);
1426 method = st_object_new (st_compiled_method_class);
1428 ST_METHOD_HEADER (method) = st_smi_new (0);
1430 st_uint argcount;
1431 st_uint tempcount;
1433 argcount = st_node_list_length (node->method.arguments);
1434 tempcount = st_list_length (gt->temporaries) - st_node_list_length (node->method.arguments);
1436 st_method_set_arg_count (method, argcount);
1437 st_method_set_temp_count (method, tempcount);
1438 st_method_set_large_context (method, (gt->max_stack_depth + argcount + tempcount) > 12);
1440 if (node->method.primitive >= 0) {
1441 st_method_set_flags (method, ST_METHOD_PRIMITIVE);
1442 } else {
1443 st_method_set_flags (method, ST_METHOD_NORMAL);
1446 st_method_set_primitive_index (method, node->method.primitive);
1448 ST_METHOD_LITERALS (method) = create_literals_array (gt);
1449 ST_METHOD_BYTECODE (method) = create_bytecode_array (gt);
1450 ST_METHOD_SELECTOR (method) = node->method.selector;
1452 generator_destroy (gt);
1454 return method;
1456 error:
1458 generator_destroy (gt);
1460 return st_nil;
1463 #define NEXT(ip) \
1464 ip += sizes[*ip]; \
1465 break
1467 #define FORMAT(ip) (formats[sizes[*ip]-1])
1469 static void
1470 print_bytecodes (st_oop literals, st_uchar *codes, int len)
1472 static const char * const formats[] = {
1473 "<%02x> ",
1474 "<%02x %02x> ",
1475 "<%02x %02x %02x> ",
1478 st_uchar *ip = codes;
1480 while (*ip) {
1482 printf ("%3li ", ip - codes);
1484 switch ((Code) *ip) {
1486 case PUSH_TEMP:
1487 printf (FORMAT (ip), ip[0], ip[1]);
1488 printf ("pushTemp: %i", ip[1]);
1490 NEXT (ip);
1492 case PUSH_INSTVAR:
1493 printf (FORMAT (ip), ip[0], ip[1]);
1494 printf ("pushInstvar: %i", ip[1]);
1496 NEXT (ip);
1498 case PUSH_LITERAL_CONST:
1499 printf (FORMAT (ip), ip[0], ip[1]);
1500 printf ("pushConst: %i", ip[1]);
1502 NEXT (ip);
1504 case PUSH_LITERAL_VAR:
1505 printf (FORMAT (ip), ip[0], ip[1]);
1506 printf ("pushLit: %i", ip[1]);
1508 NEXT (ip);
1510 case PUSH_SELF:
1511 printf (FORMAT (ip), ip[0]);
1512 printf ("push: self");
1514 NEXT (ip);
1516 case PUSH_TRUE:
1517 printf (FORMAT (ip), ip[0]);
1518 printf ("pushConst: true");
1520 NEXT (ip);
1522 case PUSH_FALSE:
1523 printf (FORMAT (ip), ip[0]);
1524 printf ("pushConst: false");
1526 NEXT (ip);
1528 case PUSH_NIL:
1529 printf (FORMAT (ip), ip[0]);
1530 printf ("pushConst: nil");
1532 NEXT (ip);
1534 case PUSH_INTEGER:
1535 printf (FORMAT (ip), ip[0], ip[1]);
1536 printf ("pushConst: %i", (signed char) ip[1]);
1538 NEXT (ip);
1540 case PUSH_ACTIVE_CONTEXT:
1541 printf (FORMAT (ip), ip[0]);
1542 printf ("push: thisContext");
1544 NEXT (ip);
1546 case STORE_TEMP:
1547 printf (FORMAT (ip), ip[0], ip[1]);
1548 printf ("storeTemp: %i", ip[1]);
1550 NEXT (ip);
1552 case STORE_INSTVAR:
1553 printf (FORMAT (ip), ip[0], ip[1]);
1554 printf ("storeInstvar: %i", ip[1]);
1556 NEXT (ip);
1558 case STORE_LITERAL_VAR:
1559 printf (FORMAT (ip), ip[0], ip[1]);
1560 printf ("storeLiteral: %i", ip[1]);
1562 NEXT (ip);
1564 case STORE_POP_TEMP:
1565 printf (FORMAT (ip), ip[0], ip[1]);
1566 printf ("popIntoTemp: %i", ip[1]);
1568 NEXT (ip);
1570 case STORE_POP_INSTVAR:
1571 printf (FORMAT (ip), ip[0], ip[1]);
1572 printf ("popIntoInstvar: %i", ip[1]);
1574 NEXT (ip);
1576 case STORE_POP_LITERAL_VAR:
1577 printf (FORMAT (ip), ip[0], ip[1]);
1578 printf ("popIntoLiteral: %i", ip[1]);
1580 NEXT (ip);
1582 case BLOCK_COPY:
1583 printf (FORMAT (ip), ip[0], ip[1]);
1584 printf ("blockCopy: %i", ip[1]);
1586 NEXT (ip);
1588 case JUMP:
1589 printf (FORMAT (ip), ip[0], ip[1], ip[2]);
1591 short offset = ((ip[1] << 8) | ip[2]);
1592 printf ("jump: %li", (offset >= 0 ? 3 : 0) + (ip - codes) + offset);
1594 NEXT (ip);
1596 case JUMP_TRUE:
1597 printf (FORMAT (ip), ip[0], ip[1], ip[2]);
1598 printf ("jumpTrue: %li", 3 + (ip - codes) + ((ip[1] << 8) | ip[2]));
1600 NEXT (ip);
1602 case JUMP_FALSE:
1603 printf (FORMAT (ip), ip[0], ip[1], ip[2]);
1604 printf ("jumpFalse: %li", 3 + (ip - codes) + ((ip[1] << 8) | ip[2]));
1606 NEXT (ip);
1608 case POP_STACK_TOP:
1609 printf (FORMAT (ip), ip[0]);
1610 printf ("pop");
1612 NEXT (ip);
1614 case DUPLICATE_STACK_TOP:
1615 printf (FORMAT (ip), ip[0]);
1616 printf ("dup");
1618 NEXT (ip);
1620 case RETURN_STACK_TOP:
1621 printf (FORMAT (ip), ip[0]);
1622 printf ("returnTop");
1624 ip += 1;
1625 break;
1627 NEXT (ip);
1629 case BLOCK_RETURN:
1630 printf (FORMAT (ip), ip[0]);
1631 printf ("blockReturn");
1633 NEXT (ip);
1635 case SEND:
1637 st_oop selector;
1639 selector = st_array_at (literals, ip[2] + 1);
1641 printf (FORMAT (ip), ip[0], ip[1], ip[2]);
1643 printf ("send: #%s", (char *) st_byte_array_bytes (selector));
1645 NEXT (ip);
1647 case SEND_SUPER:
1649 st_oop selector;
1651 selector = st_array_at (literals, ip[2] + 1);
1653 printf (FORMAT (ip), ip[0], ip[1], ip[2]);
1655 printf ("sendSuper: #%s", (char *) st_byte_array_bytes (selector));
1657 NEXT (ip);
1660 case SEND_PLUS:
1661 case SEND_MINUS:
1662 case SEND_LT:
1663 case SEND_GT:
1664 case SEND_LE:
1665 case SEND_GE:
1666 case SEND_EQ:
1667 case SEND_NE:
1668 case SEND_MUL:
1669 case SEND_DIV:
1670 case SEND_MOD:
1671 case SEND_BITSHIFT:
1672 case SEND_BITAND:
1673 case SEND_BITOR:
1674 case SEND_BITXOR:
1675 case SEND_AT:
1676 case SEND_AT_PUT:
1677 case SEND_SIZE:
1678 case SEND_VALUE:
1679 case SEND_VALUE_ARG:
1680 case SEND_IDENTITY_EQ:
1681 case SEND_CLASS:
1682 case SEND_NEW:
1683 case SEND_NEW_ARG:
1685 printf (FORMAT (ip), ip[0]);
1686 printf ("sendSpecial: #%s", st_byte_array_bytes (st_specials[ip[0] - SEND_PLUS]));
1688 NEXT (ip);
1691 printf ("\n");
1696 static void
1697 print_literal (st_oop lit)
1699 if (st_object_is_smi (lit)) {
1701 printf ("%li", st_smi_value (lit));
1703 } else if (st_object_is_symbol (lit)) {
1705 printf ("#%s", (char *) st_byte_array_bytes (lit));
1707 } else if (st_object_class (lit) == st_string_class) {
1709 printf ("'%s'", (char *) st_byte_array_bytes (lit));
1711 } else if (st_object_class (lit) == st_character_class) {
1713 char outbuf[6] = { 0 };
1714 st_unichar_to_utf8 (st_character_value (lit), outbuf);
1715 printf ("$%s", outbuf);
1720 static void
1721 print_literals (st_oop literals)
1723 if (literals == st_nil)
1724 return;
1726 printf ("literals: ");
1728 for (int i = 1; i <= st_smi_value (ST_ARRAYED_OBJECT (literals)->size); i++) {
1730 st_oop lit = st_array_at (literals, i);
1732 print_literal (lit);
1734 printf (" ");
1737 printf ("\n");
1740 void
1741 st_print_method (st_oop method)
1743 st_oop literals;
1744 st_uchar *bytecodes;
1745 int size;
1747 printf ("flags: %i; ", st_method_get_flags (method));
1748 printf ("arg-count: %i; ", st_method_get_arg_count (method));
1749 printf ("temp-count: %i; ", st_method_get_temp_count (method));
1750 printf ("large-context: %i; ", st_method_get_large_context (method));
1751 printf ("primitive: %i;\n", st_method_get_primitive_index (method));
1753 printf ("\n");
1755 literals = ST_METHOD_LITERALS (method);
1756 bytecodes = st_method_bytecode_bytes (method);
1757 size = ST_ARRAYED_OBJECT (ST_METHOD_BYTECODE (method))->size;
1759 print_bytecodes (literals, bytecodes, size);
1761 print_literals (literals);