/** * 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) { fputc( '"', output); print_string_contents( output, pointer); fputc( '"', 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) { fputc( ' ', output); } print( output, cell->payload.cons.car); print_list_contents( output, cell->payload.cons.cdr, true); break; case NILTV: break; default: fprintf( output, " . "); print( output, pointer); } } void print_list( FILE* output, struct cons_pointer pointer) { fputc( '(', output); print_list_contents( output, pointer, false); fputc( ')', 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 : fprintf( output, "%ld", cell.payload.integer.value); break; case NILTV : fprintf( output, "nil"); break; case STRINGTV : print_string( output, pointer); break; case SYMBOLTV : print_string_contents( output, pointer); break; case TRUETV : fprintf( output, "t"); break; default : fprintf( stderr, "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]); } }