Reads, stores and prints numbers correctly. Reads and stores lists and

strings, but they don't print correctly.
This commit is contained in:
Simon Brooke 2017-01-07 02:17:54 +00:00
parent 5920b0d04f
commit 85cc542d74
9 changed files with 226 additions and 125 deletions

View file

@ -29,7 +29,7 @@ bool conspageinitihasbeencalled = false;
/** /**
* the number of cons pages which have thus far been initialised. * the number of cons pages which have thus far been initialised.
*/ */
int initialisedconspages = 0; int initialised_cons_pages = 0;
/** /**
* The (global) pointer to the (global) freelist. Not sure whether this ultimately * The (global) pointer to the (global) freelist. Not sure whether this ultimately
@ -48,49 +48,54 @@ struct cons_page* conspages[NCONSPAGES];
* Initialise all cells and prepend each to the freelist; if pageno is zero, do not prepend * Initialise all cells and prepend each to the freelist; if pageno is zero, do not prepend
* cells 0 and 1 to the freelist but initialise them as NIL and T respectively. * cells 0 and 1 to the freelist but initialise them as NIL and T respectively.
*/ */
void makeconspage() { void make_cons_page() {
struct cons_page* result = malloc( sizeof( struct cons_page)); struct cons_page* result = malloc( sizeof( struct cons_page));
if ( result != NULL) { if ( result != NULL) {
conspages[initialised_cons_pages] = result;
for (int i = 0; i < CONSPAGESIZE; i++) { for (int i = 0; i < CONSPAGESIZE; i++) {
if ( initialisedconspages == 0 && i < 2) { struct cons_space_object * cell = &conspages[initialised_cons_pages]->cell[i];
if ( initialised_cons_pages == 0 && i < 2) {
if ( i == 0) { if ( i == 0) {
/* initialise cell as NIL */ /* initialise cell as NIL */
strncpy( result->cell[i].tag, NILTAG, TAGLENGTH); strncpy( &cell->tag.bytes[0], NILTAG, TAGLENGTH);
result->cell[i].count = MAXREFERENCE; cell->count = MAXREFERENCE;
result->cell[i].payload.free.car = NIL; cell->payload.free.car = NIL;
result->cell[i].payload.free.cdr = NIL; cell->payload.free.cdr = NIL;
fprintf( stderr, "Allocated special cell NIL\n");
} else if ( i == 1) { } else if ( i == 1) {
/* initialise cell as T */ /* initialise cell as T */
strncpy( result->cell[i].tag, TRUETAG, TAGLENGTH); strncpy( &cell->tag.bytes[0], TRUETAG, TAGLENGTH);
result->cell[i].count = MAXREFERENCE; cell->count = MAXREFERENCE;
result->cell[i].payload.free.car = (struct cons_pointer){ 0, 1}; cell->payload.free.car = (struct cons_pointer){ 0, 1};
result->cell[i].payload.free.cdr = (struct cons_pointer){ 0, 1}; cell->payload.free.cdr = (struct cons_pointer){ 0, 1};
fprintf( stderr, "Allocated special cell T\n");
} }
} else {
/* otherwise, standard initialisation */
strncpy( &cell->tag.bytes[0], FREETAG, TAGLENGTH);
cell->payload.free.car = NIL;
cell->payload.free.cdr = freelist;
freelist.page = initialised_cons_pages;
freelist.offset = i;
} }
/* otherwise, standard initialisation */
strncpy( result->cell[i].tag, FREETAG, TAGLENGTH);
result->cell[i].payload.free.car = NIL;
result->cell[i].payload.free.cdr = freelist;
freelist.page = initialisedconspages;
freelist.offset = i;
} }
initialised_cons_pages ++;
} else { } else {
fprintf( stderr, "FATAL: Failed to allocate memory for cons page %d\n", initialisedconspages); fprintf( stderr, "FATAL: Failed to allocate memory for cons page %d\n", initialised_cons_pages);
exit(1); exit(1);
} }
conspages[initialisedconspages] = result;
initialisedconspages++;
} }
/** /**
* dump the allocated pages to this output stream. * dump the allocated pages to this output stream.
*/ */
void dumppages( FILE* output) { void dump_pages( FILE* output) {
for ( int i = 0; i < initialisedconspages; i++) { for ( int i = 0; i < initialised_cons_pages; i++) {
fprintf( output, "\nDUMPING PAGE %d\n", i); fprintf( output, "\nDUMPING PAGE %d\n", i);
for ( int j = 0; j < CONSPAGESIZE; j++) { for ( int j = 0; j < CONSPAGESIZE; j++) {
@ -107,20 +112,22 @@ void dumppages( FILE* output) {
* @pointer the cell to free * @pointer the cell to free
*/ */
void free_cell(struct cons_pointer pointer) { void free_cell(struct cons_pointer pointer) {
struct cons_space_object cell = conspages[pointer.page]->cell[pointer.offset]; struct cons_space_object* cell = &pointer2cell( pointer);
if ( strncmp( cell.tag, FREETAG, 4) != 0) { if ( !check_tag(pointer, FREETAG)) {
if ( cell.count == 0) { if ( cell->count == 0) {
strncpy( cell.tag, FREETAG, 4); strncpy( &cell->tag.bytes[0], FREETAG, 4);
cell.payload.free.car = NIL; cell->payload.free.car = NIL;
cell.payload.free.cdr = freelist; cell->payload.free.cdr = freelist;
freelist = pointer; freelist = pointer;
} else { } else {
fprintf( stderr, "Attempt to free cell with %d dangling references at page %d, offset %d\n", fprintf( stderr,
cell.count, pointer.page, pointer.offset); "Attempt to free cell with %d dangling references at page %d, offset %d\n",
cell->count, pointer.page, pointer.offset);
} }
} else { } else {
fprintf( stderr, "Attempt to free cell which is already FREE at page %d, offset %d\n", fprintf( stderr,
"Attempt to free cell which is already FREE at page %d, offset %d\n",
pointer.page, pointer.offset); pointer.page, pointer.offset);
} }
} }
@ -133,28 +140,36 @@ void free_cell(struct cons_pointer pointer) {
* @param tag the tag of the cell to allocate - must be a valid cons space tag. * @param tag the tag of the cell to allocate - must be a valid cons space tag.
* @return the cons pointer which refers to the cell allocated. * @return the cons pointer which refers to the cell allocated.
*/ */
struct cons_pointer allocatecell( char* tag) { struct cons_pointer allocate_cell( char* tag) {
struct cons_pointer result = freelist; struct cons_pointer result = freelist;
if ( result.page == NIL.page && result.offset == NIL.offset) { if ( result.page == NIL.page && result.offset == NIL.offset) {
makeconspage(); make_cons_page();
result = allocatecell( tag); result = allocate_cell( tag);
} else { } else {
struct cons_space_object cell = conspages[result.page]->cell[result.offset]; struct cons_space_object* cell = &pointer2cell(result);
freelist = cell.payload.free.cdr; if ( strncmp( &cell->tag.bytes[0], FREETAG, TAGLENGTH) == 0) {
freelist = cell->payload.free.cdr;
fprintf( stderr, "Before: %c\n", cell.tag[0]); fprintf( stderr, "Before: %c%c%c%c (%d)\n",
strncpy( cell.tag, tag, 4); cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
fprintf( stderr, "After: %c\n", cell.tag[0]); cell->tag.bytes[3], cell->tag.value);
strncpy( &cell->tag.bytes[0], tag, 4);
fprintf( stderr, "After: %c%c%c%c (%d)\n",
cell->tag.bytes[0], cell->tag.bytes[1], cell->tag.bytes[2],
cell->tag.bytes[3], cell->tag.value);
cell.count = 1; cell->count = 0;
cell.payload.cons.car = NIL; cell->payload.cons.car = NIL;
cell.payload.cons.cdr = NIL; cell->payload.cons.cdr = NIL;
fprintf( stderr, "Allocated cell of type '%s' at %d, %d \n", fprintf( stderr, "Allocated cell of type '%s' at %d, %d \n",
tag, result.page, result.offset); tag, result.page, result.offset);
dump_object( stderr, result); dump_object( stderr, result);
} else {
fprintf( stderr, "WARNING: Allocating non-free cell!");
}
} }
return result; return result;
@ -164,13 +179,13 @@ struct cons_pointer allocatecell( char* tag) {
/** /**
* initialise the cons page system; to be called exactly once during startup. * initialise the cons page system; to be called exactly once during startup.
*/ */
void conspagesinit() { void initialise_cons_pages() {
if ( conspageinitihasbeencalled == false) { if ( conspageinitihasbeencalled == false) {
for (int i = 0; i < NCONSPAGES; i++) { for (int i = 0; i < NCONSPAGES; i++) {
conspages[i] = (struct cons_page *) NULL; conspages[i] = (struct cons_page *) NULL;
} }
makeconspage(); make_cons_page();
conspageinitihasbeencalled = true; conspageinitihasbeencalled = true;
} else { } else {
fprintf( stderr, "WARNING: conspageinit() called a second or subsequent time\n"); fprintf( stderr, "WARNING: conspageinit() called a second or subsequent time\n");

View file

@ -9,14 +9,14 @@
* the size which, by version 1, it will default to) is the maximum value of an unsigned 32 * the size which, by version 1, it will default to) is the maximum value of an unsigned 32
* bit integer, which is to say 4294967296. However, we'll start small. * bit integer, which is to say 4294967296. However, we'll start small.
*/ */
#define CONSPAGESIZE 64 #define CONSPAGESIZE 8
/** /**
* the number of cons pages we will initially allow for. For convenience we'll set up an array * the number of cons pages we will initially allow for. For convenience we'll set up an array
* of cons pages this big; however, later we will want a mechanism for this to be able to grow * of cons pages this big; however, later we will want a mechanism for this to be able to grow
* dynamically to the maximum we can currently allow, which is 4294967296. * dynamically to the maximum we can currently allow, which is 4294967296.
*/ */
#define NCONSPAGES 64 #define NCONSPAGES 8
/** /**
* a cons page is essentially just an array of cons space objects. It might later have a local * a cons page is essentially just an array of cons space objects. It might later have a local
@ -56,17 +56,17 @@ void free_cell(struct cons_pointer pointer);
* @param tag the tag of the cell to allocate - must be a valid cons space tag. * @param tag the tag of the cell to allocate - must be a valid cons space tag.
* @return the cons pointer which refers to the cell allocated. * @return the cons pointer which refers to the cell allocated.
*/ */
struct cons_pointer allocatecell( char* tag); struct cons_pointer allocate_cell( char* tag);
/** /**
* initialise the cons page system; to be called exactly once during startup. * initialise the cons page system; to be called exactly once during startup.
*/ */
void conspagesinit(); void initialise_cons_pages();
/** /**
* dump the allocated pages to this output stream. * dump the allocated pages to this output stream.
*/ */
void dumppages( FILE* output); void dump_pages( FILE* output);
#endif #endif

View file

@ -15,6 +15,14 @@
#include "conspage.h" #include "conspage.h"
#include "consspaceobject.h" #include "consspaceobject.h"
/**
* Check that the tag on the cell at this pointer is this tag
*/
int check_tag( struct cons_pointer pointer, char* tag) {
struct cons_space_object cell = pointer2cell(pointer);
return strncmp( &cell.tag.bytes[0], tag, TAGLENGTH) == 0;
}
/** /**
* increment the reference count of the object at this cons pointer. * increment the reference count of the object at this cons pointer.
@ -22,11 +30,11 @@
* You can't roll over the reference count. Once it hits the maximum * You can't roll over the reference count. Once it hits the maximum
* value you cannot increment further. * value you cannot increment further.
*/ */
void incref( struct cons_pointer pointer) { void inc_ref( struct cons_pointer pointer) {
struct cons_space_object cell = pointer2cell( pointer); struct cons_space_object* cell = &pointer2cell( pointer);
if (cell.count < MAXREFERENCE) { if (cell->count < MAXREFERENCE) {
cell.count ++; cell->count ++;
} }
} }
@ -37,13 +45,13 @@ void incref( struct cons_pointer pointer) {
* If a count has reached MAXREFERENCE it cannot be decremented. * If a count has reached MAXREFERENCE it cannot be decremented.
* If a count is decremented to zero the cell should be freed. * If a count is decremented to zero the cell should be freed.
*/ */
void decref( struct cons_pointer pointer) { void dec_ref( struct cons_pointer pointer) {
struct cons_space_object cell = pointer2cell( pointer); struct cons_space_object* cell = &pointer2cell( pointer);
if (cell.count < MAXREFERENCE) { if (cell->count <= MAXREFERENCE) {
cell.count --; cell->count --;
if (cell.count == 0) { if (cell->count == 0) {
free_cell( pointer); free_cell( pointer);
} }
} }
@ -54,30 +62,73 @@ void decref( struct cons_pointer pointer) {
* dump the object at this cons_pointer to this output stream. * dump the object at this cons_pointer to this output stream.
*/ */
void dump_object( FILE* output, struct cons_pointer pointer) { void dump_object( FILE* output, struct cons_pointer pointer) {
struct cons_space_object cell = conspages[pointer.page]->cell[pointer.offset]; struct cons_space_object cell = pointer2cell(pointer);
char * tag = malloc( TAGLENGTH + 1); fprintf( output,
memset( tag, 0, TAGLENGTH + 1); "\tDumping object at page %d, offset %d with tag %c%c%c%c (%d), count %u\n",
strncpy( tag, cell.tag, TAGLENGTH); pointer.page,
pointer.offset,
cell.tag.bytes[0],
cell.tag.bytes[1],
cell.tag.bytes[2],
cell.tag.bytes[3],
cell.tag.value,
cell.count);
fprintf( output, "\tDumping object at page %d, offset %d with tag %s, count %d\n", if ( check_tag(pointer, CONSTAG)) {
pointer.page, fprintf( output,
pointer.offset, "\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n",
tag, cell.payload.cons.car.page, cell.payload.cons.car.offset,
cell.count); cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset);
} else if ( check_tag(pointer, INTEGERTAG)) {
if ( strncmp( tag, CONSTAG, TAGLENGTH) == 0) { fprintf( output, "\t\tInteger cell: value %ld\n", cell.payload.integer.value);
fprintf( output, "\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n", } else if ( check_tag( pointer, FREETAG)) {
cell.payload.cons.car.page, cell.payload.cons.car.offset, cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset); fprintf( output, "\t\tFree cell: next at page %d offset %d\n",
} else if ( strncmp( tag, INTEGERTAG, TAGLENGTH) == 0) { cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset);
fprintf( output, "\t\tInteger cell: value %ld\n", cell.payload.integer.value); } else if ( check_tag(pointer, REALTAG)) {
} else if ( strncmp( tag, FREETAG, TAGLENGTH) == 0) { fprintf( output, "\t\tReal cell: value %Lf\n", cell.payload.real.value);
fprintf( output, "\t\tFree cell: next at page %d offset %d\n", } else if ( check_tag( pointer, STRINGTAG)) {
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset); fprintf( output, "\t\tString cell: character '%c' next at page %d offset %d\n",
} else if ( strncmp( tag, REALTAG, TAGLENGTH) == 0) { cell.payload.string.character, cell.payload.string.cdr.page,
fprintf( output, "\t\tReal cell: value %Lf\n", cell.payload.real.value); cell.payload.string.cdr.offset);
} else if ( strncmp( tag, STRINGTAG, TAGLENGTH) == 0) { };
fprintf( output, "\t\tString cell: character '%c' next at page %d offset %d\n", }
cell.payload.string.character, cell.payload.string.cdr.page,
cell.payload.string.cdr.offset);
}; /**
* Construct a cons cell from this pair of pointers.
*/
struct cons_pointer make_cons( struct cons_pointer car, struct cons_pointer cdr) {
struct cons_pointer pointer = allocate_cell( CONSTAG);
struct cons_space_object* cell = &conspages[pointer.page]->cell[pointer.offset];
inc_ref(car);
inc_ref(cdr);
cell->payload.cons.car = car;
cell->payload.cons.cdr = cdr;
return pointer;
}
/**
* Construct a string from this character (which later will be UTF) and
* this tail. A string is implemented as a flat list of cells each of which
* has one character and a pointer to the next; in the last cell the
* pointer to next is NIL.
*/
struct cons_pointer make_string( char c, struct cons_pointer tail) {
struct cons_pointer pointer = NIL;
if ( check_tag( tail, STRINGTAG) || check_tag( tail, NILTAG)) {
pointer = allocate_cell( STRINGTAG);
struct cons_space_object* cell = &conspages[pointer.page]->cell[pointer.offset];
inc_ref(tail);
cell->payload.string.character = (uint32_t) c;
cell->payload.string.cdr = tail;
} else {
fprintf( stderr, "Warning: only NIL and STRING can be appended to STRING\n");
}
return pointer;
} }

View file

@ -41,7 +41,7 @@
/** /**
* the maximum possible value of a reference count * the maximum possible value of a reference count
*/ */
#define MAXREFERENCE ((2 ^ 32) - 1) #define MAXREFERENCE 4294967295
/** /**
* a macro to convert a tag into a number * a macro to convert a tag into a number
@ -50,21 +50,20 @@
#define pointer2cell(pointer) ((conspages[pointer.page]->cell[pointer.offset])) #define pointer2cell(pointer) ((conspages[pointer.page]->cell[pointer.offset]))
/** /**
* true if conspointer points to the special cell NIL, else false * true if conspointer points to the special cell NIL, else false
*/ */
#define nilp(conspoint) (strncmp(pointer2cell(conspoint).tag, NILTAG, TAGLENGTH)==0) #define nilp(conspoint) (check_tag(conspoint,NILTAG)==0)
/** /**
* true if conspointer points to a cons cell, else false * true if conspointer points to a cons cell, else false
*/ */
#define consp(conspoint) (strncmp(pointer2cell(conspoint).tag, CONSTAG, TAGLENGTH)==0) #define consp(conspoint) (check_tag(conspoint,CONSTAG)==0)
/** /**
* true if conspointer points to a string cell, else false * true if conspointer points to a string cell, else false
*/ */
#define stringp(conspoint) (strncmp(pointer2cell(conspoint).tag, STRINGTAG, TAGLENGTH)==0) #define stringp(conspoint) (check_tag(conspoint,STRINGTAG)==0)
/** /**
* An indirect pointer to a cons cell * An indirect pointer to a cons cell
@ -123,7 +122,10 @@ struct string_payload {
* an object in cons space. * an object in cons space.
*/ */
struct cons_space_object { struct cons_space_object {
char tag[TAGLENGTH]; /* the tag (type) of this cell */ union {
char bytes[TAGLENGTH]; /* the tag (type) of this cell, considered as bytes */
uint32_t value; /* the tag considered as a number */
} tag;
uint32_t count; /* the count of the number of references to this cell */ uint32_t count; /* the count of the number of references to this cell */
struct cons_pointer access; /* cons pointer to the access control list of this cell */ struct cons_pointer access; /* cons pointer to the access control list of this cell */
union { union {
@ -145,16 +147,22 @@ struct cons_space_object {
}; };
/**
* Check that the tag on the cell at this pointer is this tag
*/
int check_tag( struct cons_pointer pointer, char* tag);
/** /**
* increment the reference count of the object at this cons pointer * increment the reference count of the object at this cons pointer
*/ */
void incref( struct cons_pointer pointer); void inc_ref( struct cons_pointer pointer);
/** /**
* decrement the reference count of the object at this cons pointer * decrement the reference count of the object at this cons pointer
*/ */
void decref( struct cons_pointer pointer); void dec_ref( struct cons_pointer pointer);
/** /**
@ -162,4 +170,14 @@ void decref( struct cons_pointer pointer);
*/ */
void dump_object( FILE* output, struct cons_pointer pointer); void dump_object( FILE* output, struct cons_pointer pointer);
struct cons_pointer make_cons( struct cons_pointer car, struct cons_pointer cdr);
/**
* Construct a string from this character (which later will be UTF) and
* this tail. A string is implemented as a flat list of cells each of which
* has one character and a pointer to the next; in the last cell the
* pointer to next is NIL.
*/
struct cons_pointer make_string( char c, struct cons_pointer tail);
#endif #endif

View file

@ -19,16 +19,16 @@
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
printf( "Post scarcity software environment version %s\n", VERSION); printf( "Post scarcity software environment version %s\n", VERSION);
conspagesinit(); initialise_cons_pages();
printf( "Ready\n>>"); printf( "Ready\n>> ");
struct cons_pointer input = read( stdin); struct cons_pointer input = read( stdin);
incref( input); inc_ref( input);
printf( "\n"); printf( "\n:: ");
print( stdout, input); print( stdout, input);
dumppages(stdout); dump_pages(stdout);
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE")); // printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
return(0); return(0);

View file

@ -14,10 +14,10 @@
/** /**
* Allocate an integer cell representing this value and return a cons pointer to it. * Allocate an integer cell representing this value and return a cons pointer to it.
*/ */
struct cons_pointer makeinteger( int value) { struct cons_pointer make_integer( int value) {
struct cons_pointer result = allocatecell( INTEGERTAG); struct cons_pointer result = allocate_cell( INTEGERTAG);
struct cons_space_object cell = conspages[result.page]->cell[result.offset]; struct cons_space_object* cell = &conspages[result.page]->cell[result.offset];
cell.payload.integer.value = value; cell->payload.integer.value = value;
return result; return result;
} }

View file

@ -14,6 +14,6 @@
/** /**
* Allocate an integer cell representing this value and return a cons pointer to it. * Allocate an integer cell representing this value and return a cons pointer to it.
*/ */
struct cons_pointer makeinteger( int value); struct cons_pointer make_integer( int value);
#endif #endif

View file

@ -20,7 +20,7 @@
void print( FILE* output, struct cons_pointer pointer) { void print( FILE* output, struct cons_pointer pointer) {
struct cons_space_object cell = pointer2cell( pointer); struct cons_space_object cell = pointer2cell( pointer);
if ( strncmp( cell.tag, CONSTAG, TAGLENGTH) == 0) { if ( check_tag( pointer, CONSTAG)) {
fputc( '(', output); fputc( '(', output);
for (struct cons_pointer p = pointer; consp( p); for (struct cons_pointer p = pointer; consp( p);
p = pointer2cell( p).payload.cons.cdr) { p = pointer2cell( p).payload.cons.cdr) {
@ -28,20 +28,21 @@ void print( FILE* output, struct cons_pointer pointer) {
fputc( ' ', output); fputc( ' ', output);
} }
fputc( ')', output); fputc( ')', output);
} else if ( strncmp( cell.tag, INTEGERTAG, TAGLENGTH) == 0) { } else if ( check_tag( pointer, INTEGERTAG)) {
fprintf( output, " %ld", cell.payload.integer.value); fprintf( output, " %ld", cell.payload.integer.value);
} else if ( strncmp( cell.tag, NILTAG, TAGLENGTH) == 0) { } else if ( check_tag( pointer, NILTAG)) {
fprintf( output, "NIL"); fprintf( output, "NIL");
} else if ( strncmp( cell.tag, REALTAG, TAGLENGTH) == 0) { } else if ( check_tag( pointer, REALTAG)) {
fprintf( output, "%Lf", cell.payload.real.value); fprintf( output, "%Lf", cell.payload.real.value);
} else if ( strncmp( cell.tag, STRINGTAG, TAGLENGTH) == 0) { } else if ( check_tag( pointer, STRINGTAG)) {
fputc( '"', output); fputc( '"', output);
for (struct cons_pointer p = pointer; stringp( p); for (struct cons_pointer p = pointer; stringp( p);
p = pointer2cell( p).payload.string.cdr) { p = pointer2cell( p).payload.string.cdr) {
fprintf( output, '%c', (char)pointer2cell( p).payload.string.character); // TODO: That's potentially a UTF character, needs more handling.
fprintf( output, "%c", (char)pointer2cell( p).payload.string.character);
} }
fputc( '"', output); fputc( '"', output);
} else if ( strncmp( cell.tag, TRUETAG, TAGLENGTH) == 0) { } else if ( check_tag( pointer, TRUETAG)) {
fprintf( output, "T"); fprintf( output, "T");
} }
} }

View file

@ -24,7 +24,7 @@
/** /**
* read a number from this input stream, given this initial character. * read a number from this input stream, given this initial character.
*/ */
struct cons_pointer readnumber( FILE* input, char initial) { struct cons_pointer read_number( FILE* input, char initial) {
int accumulator = 0; int accumulator = 0;
char c; char c;
@ -36,17 +36,35 @@ struct cons_pointer readnumber( FILE* input, char initial) {
/* push back the character read which was not a digit */ /* push back the character read which was not a digit */
fputc( c, input); fputc( c, input);
return makeinteger( accumulator); return make_integer( accumulator);
} }
struct cons_pointer readlist( FILE* input) { struct cons_pointer read_list( FILE* input) {
return NIL; struct cons_pointer car = read( input);
struct cons_pointer cdr = NIL;
char c = fgetc( input);
if ( c != ')' ) {
cdr = read_list( input);
}
return make_cons( car, cdr);
} }
struct cons_pointer readstring( FILE* input) { struct cons_pointer read_string( FILE* input) {
return NIL; struct cons_pointer cdr = NIL;
struct cons_pointer result= NIL;
char c = fgetc( input);
if ( c != '"' ) {
result = make_string( c, read_string( input));
}
return result;
} }
@ -56,16 +74,14 @@ struct cons_pointer readstring( FILE* input) {
struct cons_pointer read( FILE* input) { struct cons_pointer read( FILE* input) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
char c = fgetc( input); char c;
while ( isblank( c)) { for (c = fgetc( input); isblank( c); c = fgetc( input));
c = fgetc( input);
}
switch( c) { switch( c) {
case '(' : result = readlist(input); case '(' : result = read_list(input);
break; break;
case '"': result = readstring(input); case '"': result = read_string(input);
break; break;
case '0': case '0':
case '1': case '1':
@ -78,7 +94,7 @@ struct cons_pointer read( FILE* input) {
case '8': case '8':
case '9': case '9':
// case '.': // case '.':
result = readnumber( input, c); result = read_number( input, c);
break; break;
default: default:
fprintf( stderr, "Unrecognised start of input character %c\n", c); fprintf( stderr, "Unrecognised start of input character %c\n", c);