From 2d9f4b0439f6945e79eaec1af5ba12cbc347ad5d Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Sat, 7 Jan 2017 12:24:54 +0000 Subject: [PATCH] All unit tests passing! This is slightly a fix because there is a bug with the character read after reading a number not being correctly pushed back onto the input stream, but... --- src/consspaceobject.c | 5 +-- src/consspaceobject.h | 6 ++-- src/init.c | 9 +++-- src/integer.c | 2 +- src/print.c | 60 ++++++++++++++++++++++---------- unit-tests/complex-list.sh | 13 +++++++ unit-tests/fred.sh | 4 +-- unit-tests/simple-list.sh | 2 +- unit-tests/string-allocation.sh | 14 ++++++++ unit-tests/string-with-spaces.sh | 4 +-- 10 files changed, 85 insertions(+), 34 deletions(-) create mode 100644 unit-tests/complex-list.sh create mode 100644 unit-tests/string-allocation.sh diff --git a/src/consspaceobject.c b/src/consspaceobject.c index a390cdb..0ef8ab1 100644 --- a/src/consspaceobject.c +++ b/src/consspaceobject.c @@ -121,11 +121,12 @@ struct cons_pointer make_string( char c, struct cons_pointer tail) { if ( check_tag( tail, STRINGTAG) || check_tag( tail, NILTAG)) { pointer = allocate_cell( STRINGTAG); - struct cons_space_object* cell = &conspages[pointer.page]->cell[pointer.offset]; + struct cons_space_object* cell = &pointer2cell(pointer); inc_ref(tail); cell->payload.string.character = (uint32_t) c; - cell->payload.string.cdr = tail; + cell->payload.string.cdr.page = tail.page; + cell->payload.string.cdr.offset = tail.offset; } else { fprintf( stderr, "Warning: only NIL and STRING can be appended to STRING\n"); } diff --git a/src/consspaceobject.h b/src/consspaceobject.h index fdce9a4..5526e8c 100644 --- a/src/consspaceobject.h +++ b/src/consspaceobject.h @@ -53,17 +53,17 @@ /** * true if conspointer points to the special cell NIL, else false */ -#define nilp(conspoint) (check_tag(conspoint,NILTAG)==0) +#define nilp(conspoint) (check_tag(conspoint,NILTAG)) /** * true if conspointer points to a cons cell, else false */ -#define consp(conspoint) (check_tag(conspoint,CONSTAG)==0) +#define consp(conspoint) (check_tag(conspoint,CONSTAG)) /** * true if conspointer points to a string cell, else false */ -#define stringp(conspoint) (check_tag(conspoint,STRINGTAG)==0) +#define stringp(conspoint) (check_tag(conspoint,STRINGTAG)) /** * An indirect pointer to a cons cell diff --git a/src/init.c b/src/init.c index 98ece93..63b8558 100644 --- a/src/init.c +++ b/src/init.c @@ -18,16 +18,15 @@ #include "read.h" int main (int argc, char *argv[]) { - // printf( "Post scarcity software environment version %s\n", VERSION); + fprintf( stderr, "Post scarcity software environment version %s\n", VERSION); initialise_cons_pages(); + fprintf( stderr, "\n:: "); struct cons_pointer input = read( stdin); - //inc_ref( input); - //printf( "\n:: "); + fprintf( stderr, "\n{%d,%d}=> ", input.page, input.offset); print( stdout, input); - // dump_pages(stdout); - // printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE")); + dump_pages(stderr); return(0); } diff --git a/src/integer.c b/src/integer.c index e9a5d43..1493c9d 100644 --- a/src/integer.c +++ b/src/integer.c @@ -16,7 +16,7 @@ */ struct cons_pointer make_integer( int value) { struct cons_pointer result = allocate_cell( INTEGERTAG); - struct cons_space_object* cell = &conspages[result.page]->cell[result.offset]; + struct cons_space_object* cell = &pointer2cell(result); cell->payload.integer.value = value; return result; diff --git a/src/print.c b/src/print.c index 0390516..be6cac8 100644 --- a/src/print.c +++ b/src/print.c @@ -17,17 +17,51 @@ #include "integer.h" #include "print.h" +void print_string_contents( FILE* output, struct cons_pointer pointer) { + if ( check_tag( pointer, STRINGTAG)) { + struct cons_space_object* cell = &pointer2cell(pointer); + char c = cell->payload.string.character; + + if ( c != '\0') { + fputc( 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); +} + + +void print_list_contents( FILE* output, struct cons_pointer pointer) { + if ( check_tag( pointer, CONSTAG)) { + struct cons_space_object* cell = &pointer2cell(pointer); + + print( output, cell->payload.cons.car); + + if ( !nilp( cell->payload.cons.cdr)) { + fputc( ' ', output); + } + print_list_contents( output, cell->payload.cons.cdr); + } +} + + +void print_list( FILE* output, struct cons_pointer pointer) { + fputc( '(', output); + print_list_contents( output, pointer); + fputc( ')', output); +} + void print( FILE* output, struct cons_pointer pointer) { struct cons_space_object cell = pointer2cell( pointer); if ( check_tag( pointer, CONSTAG)) { - fputc( '(', output); - for (struct cons_pointer p = pointer; consp( p); - p = pointer2cell( p).payload.cons.cdr) { - print( output, p); - fputc( ' ', output); - } - fputc( ')', output); + print_list( output, pointer); } else if ( check_tag( pointer, INTEGERTAG)) { fprintf( output, "%ld", cell.payload.integer.value); } else if ( check_tag( pointer, NILTAG)) { @@ -35,17 +69,7 @@ void print( FILE* output, struct cons_pointer pointer) { } else if ( check_tag( pointer, REALTAG)) { fprintf( output, "%Lf", cell.payload.real.value); } else if ( check_tag( pointer, STRINGTAG)) { - fputc( '"', output); - for (struct cons_pointer p = pointer; stringp( p); - p = pointer2cell( p).payload.string.cdr) { - // TODO: That's potentially a UTF character, needs more handling. - char c = (char)pointer2cell( p).payload.string.character; - - if ( c != '\0') { - fprintf( output, "%c", c); - } - } - fputc( '"', output); + print_string( output, pointer); } else if ( check_tag( pointer, TRUETAG)) { fprintf( output, "T"); } diff --git a/unit-tests/complex-list.sh b/unit-tests/complex-list.sh new file mode 100644 index 0000000..dd9c7e1 --- /dev/null +++ b/unit-tests/complex-list.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +expected='(1 2 3 ("Fred") NIL 77354)' +actual=`echo '(1 2 3 ("Fred") () 77354 )' | target/psse 2> /dev/null` + +if [ "${expected}" = "${actual}" ] +then + echo "OK" + exit 0 +else + echo "Fail: expected '${expected}', got '${actual}'" + exit 1 +fi diff --git a/unit-tests/fred.sh b/unit-tests/fred.sh index 5b3048c..ebb03ac 100644 --- a/unit-tests/fred.sh +++ b/unit-tests/fred.sh @@ -1,9 +1,9 @@ #!/bin/bash -expected=\"Fred\" +expected='"Fred"' actual=`echo ${expected} | target/psse 2> /dev/null` -if [ "${expected}" = "{$actual}" ] +if [ "${expected}" = "${actual}" ] then echo "OK" exit 0 diff --git a/unit-tests/simple-list.sh b/unit-tests/simple-list.sh index 9ee9719..9ea89a9 100644 --- a/unit-tests/simple-list.sh +++ b/unit-tests/simple-list.sh @@ -1,7 +1,7 @@ #!/bin/bash expected="(1 2 3)" -actual=`echo '(1 2 3)' | target/psse 2> /dev/null` +actual=`echo '(1 2 3 )' | target/psse 2> /dev/null` if [ "${expected}" = "${actual}" ] then diff --git a/unit-tests/string-allocation.sh b/unit-tests/string-allocation.sh new file mode 100644 index 0000000..5f503fc --- /dev/null +++ b/unit-tests/string-allocation.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +value='"Fred"' +expected="String cell: character 'F'" +echo ${value} | target/psse 2>&1 | grep "${expected}" > /dev/null + +if [ $? -eq 0 ] +then + echo "OK" + exit 0 +else + echo "Expected '${expected}', not found" + exit 1 +fi diff --git a/unit-tests/string-with-spaces.sh b/unit-tests/string-with-spaces.sh index ee5612f..fb78b81 100644 --- a/unit-tests/string-with-spaces.sh +++ b/unit-tests/string-with-spaces.sh @@ -1,9 +1,9 @@ #!/bin/bash -expected="\"Strings should be able to include spaces (and other stuff)!\"" +expected='"Strings should be able to include spaces (and other stuff)!"' actual=`echo ${expected} | target/psse 2> /dev/null` -if [ "${expected}" = "{$actual}" ] +if [ "${expected}" = "${actual}" ] then echo "OK" exit 0