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