diff --git a/ps5/src/emit.h b/ps5/src/emit.h index 2cda337..a9080ff 100644 --- a/ps5/src/emit.h +++ b/ps5/src/emit.h @@ -33,6 +33,7 @@ #define MOVQ_OFFSET(offset, src, dst) EMIT("movq %d(%s), %s", (offset), (src), (dst)) #define PUSHQ(src) EMIT("pushq %s", (src)) #define POPQ(src) EMIT("popq %s", (src)) +#define LEAQ_LABEL(label, dst) EMIT("leaq %s(%%rip), %s", (label), (dst)) #define LEAQ_GLOBAL(name, dst) EMIT("leaq .%s(%%rip), %s", (name), (dst)) #define LEAQ_OFFSET(offset, src, dst) EMIT("leaq %d(%s), %s", (offset), (src), (dst)) #define STASH() MOVQ(RAX, RCX) diff --git a/ps5/src/generator.c b/ps5/src/generator.c index f370e57..0e0050b 100644 --- a/ps5/src/generator.c +++ b/ps5/src/generator.c @@ -72,8 +72,8 @@ static void generate_stringtable(void) // TODO (Task 1): Print all strings in the program here, with labels you can refer to later // You have access to the global variables string_list and string_list_len from symbols.c - for (int i = 0; i < string_list_len; i++) { - DIRECTIVE("string%d:\t.asciz \"%s\"", i, string_list[i]); + for (long int i = 0; i < string_list_len; i++) { + DIRECTIVE("string%ld:\t.asciz \"%s\"", i, string_list[i]); } } @@ -315,6 +315,23 @@ static void generate_print_statement(node_t* statement) { // TODO (Task 4.4): // Remember to call safe_printf instead of printf + node_t *print_list = statement->children[0]; + assert(print_list->n_children >= 1); + for (int i = 0; i < print_list->n_children; i++) { + node_t *item = print_list->children[i]; + if (item->type == STRING_LIST_REFERENCE) { + char label[64]; + snprintf(label, sizeof(label), "string%ld", item->data.string_list_index); + LEAQ_LABEL(label, RSI); + LEAQ_LABEL("strout", RDI); + EMIT("call safe_printf"); + } else { // it's an expression, so + generate_expression(item); + MOVQ(RAX, RSI); + LEAQ_LABEL("intout", RDI); + EMIT("call safe_printf"); + } + } } static void generate_return_statement(node_t* statement)