/** * print.c * * First pass at a printer, for bootstrapping. * * * (c) 2017 Simon Brooke * Licensed under GPL version 2.0, or, at your option, any later version. */ #include #include #include /* * wide characters */ #include #include #include "conspage.h" #include "consspaceobject.h" #include "integer.h" #include "print.h" void print_string_contents(FILE * output, struct cons_pointer pointer) { if (stringp(pointer) || symbolp(pointer)) { struct cons_space_object *cell = &pointer2cell(pointer); wint_t c = cell->payload.string.character; if (c != '\0') { fputwc(c, output); } print_string_contents(output, cell->payload.string.cdr); } } void print_string(FILE * output, struct cons_pointer pointer) { fputwc(btowc('"'), output); print_string_contents(output, pointer); fputwc(btowc('"'), output); } /** * Print a single list cell (cons cell). TODO: does not handle dotted pairs. */ void print_list_contents(FILE * output, struct cons_pointer pointer, bool initial_space) { struct cons_space_object *cell = &pointer2cell(pointer); switch (cell->tag.value) { case CONSTV: if (initial_space) { fputwc(btowc(' '), output); } print(output, cell->payload.cons.car); print_list_contents(output, cell->payload.cons.cdr, true); break; case NILTV: break; default: fwprintf(output, L" . "); print(output, pointer); } } void print_list(FILE * output, struct cons_pointer pointer) { fputwc(btowc('('), output); print_list_contents(output, pointer, false); fputwc(btowc(')'), output); } void print(FILE * output, struct cons_pointer pointer) { struct cons_space_object cell = pointer2cell(pointer); /* * Because tags have values as well as bytes, this if ... else if * statement can ultimately be replaced by a switch, which will be neater. */ switch (cell.tag.value) { case CONSTV: print_list(output, pointer); break; case INTEGERTV: fwprintf(output, L"%ld", cell.payload.integer.value); break; case NILTV: fwprintf(output, L"nil"); break; case REALTV: fwprintf(output, L"%lf", cell.payload.real.value); break; case STRINGTV: print_string(output, pointer); break; case SYMBOLTV: print_string_contents(output, pointer); break; case TRUETV: fwprintf(output, L"t"); break; default: fwprintf(stderr, L"Error: Unrecognised tag value %d (%c%c%c%c)\n", cell.tag.value, cell.tag.bytes[0], cell.tag.bytes[1], cell.tag.bytes[2], cell.tag.bytes[3]); break; } }