Reads, stores and prints numbers correctly. Reads and stores lists and
strings, but they don't print correctly.
This commit is contained in:
parent
5920b0d04f
commit
85cc542d74
105
src/conspage.c
105
src/conspage.c
|
@ -29,7 +29,7 @@ bool conspageinitihasbeencalled = false;
|
|||
/**
|
||||
* 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
|
||||
|
@ -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
|
||||
* 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));
|
||||
|
||||
if ( result != NULL) {
|
||||
conspages[initialised_cons_pages] = result;
|
||||
|
||||
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) {
|
||||
/* initialise cell as NIL */
|
||||
strncpy( result->cell[i].tag, NILTAG, TAGLENGTH);
|
||||
result->cell[i].count = MAXREFERENCE;
|
||||
result->cell[i].payload.free.car = NIL;
|
||||
result->cell[i].payload.free.cdr = NIL;
|
||||
strncpy( &cell->tag.bytes[0], NILTAG, TAGLENGTH);
|
||||
cell->count = MAXREFERENCE;
|
||||
cell->payload.free.car = NIL;
|
||||
cell->payload.free.cdr = NIL;
|
||||
fprintf( stderr, "Allocated special cell NIL\n");
|
||||
} else if ( i == 1) {
|
||||
/* initialise cell as T */
|
||||
strncpy( result->cell[i].tag, TRUETAG, TAGLENGTH);
|
||||
result->cell[i].count = MAXREFERENCE;
|
||||
result->cell[i].payload.free.car = (struct cons_pointer){ 0, 1};
|
||||
result->cell[i].payload.free.cdr = (struct cons_pointer){ 0, 1};
|
||||
strncpy( &cell->tag.bytes[0], TRUETAG, TAGLENGTH);
|
||||
cell->count = MAXREFERENCE;
|
||||
cell->payload.free.car = (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 {
|
||||
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);
|
||||
}
|
||||
|
||||
conspages[initialisedconspages] = result;
|
||||
initialisedconspages++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dump the allocated pages to this output stream.
|
||||
*/
|
||||
void dumppages( FILE* output) {
|
||||
for ( int i = 0; i < initialisedconspages; i++) {
|
||||
void dump_pages( FILE* output) {
|
||||
for ( int i = 0; i < initialised_cons_pages; i++) {
|
||||
fprintf( output, "\nDUMPING PAGE %d\n", i);
|
||||
|
||||
for ( int j = 0; j < CONSPAGESIZE; j++) {
|
||||
|
@ -107,20 +112,22 @@ void dumppages( FILE* output) {
|
|||
* @pointer the cell to free
|
||||
*/
|
||||
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 ( cell.count == 0) {
|
||||
strncpy( cell.tag, FREETAG, 4);
|
||||
cell.payload.free.car = NIL;
|
||||
cell.payload.free.cdr = freelist;
|
||||
if ( !check_tag(pointer, FREETAG)) {
|
||||
if ( cell->count == 0) {
|
||||
strncpy( &cell->tag.bytes[0], FREETAG, 4);
|
||||
cell->payload.free.car = NIL;
|
||||
cell->payload.free.cdr = freelist;
|
||||
freelist = pointer;
|
||||
} else {
|
||||
fprintf( stderr, "Attempt to free cell with %d dangling references at page %d, offset %d\n",
|
||||
cell.count, pointer.page, pointer.offset);
|
||||
fprintf( stderr,
|
||||
"Attempt to free cell with %d dangling references at page %d, offset %d\n",
|
||||
cell->count, pointer.page, pointer.offset);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* @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;
|
||||
|
||||
if ( result.page == NIL.page && result.offset == NIL.offset) {
|
||||
makeconspage();
|
||||
result = allocatecell( tag);
|
||||
make_cons_page();
|
||||
result = allocate_cell( tag);
|
||||
} 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]);
|
||||
strncpy( cell.tag, tag, 4);
|
||||
fprintf( stderr, "After: %c\n", cell.tag[0]);
|
||||
fprintf( stderr, "Before: %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);
|
||||
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.payload.cons.car = NIL;
|
||||
cell.payload.cons.cdr = NIL;
|
||||
cell->count = 0;
|
||||
cell->payload.cons.car = NIL;
|
||||
cell->payload.cons.cdr = NIL;
|
||||
|
||||
fprintf( stderr, "Allocated cell of type '%s' at %d, %d \n",
|
||||
tag, result.page, result.offset);
|
||||
dump_object( stderr, result);
|
||||
} else {
|
||||
fprintf( stderr, "WARNING: Allocating non-free cell!");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -164,13 +179,13 @@ struct cons_pointer allocatecell( char* tag) {
|
|||
/**
|
||||
* initialise the cons page system; to be called exactly once during startup.
|
||||
*/
|
||||
void conspagesinit() {
|
||||
void initialise_cons_pages() {
|
||||
if ( conspageinitihasbeencalled == false) {
|
||||
for (int i = 0; i < NCONSPAGES; i++) {
|
||||
conspages[i] = (struct cons_page *) NULL;
|
||||
}
|
||||
|
||||
makeconspage();
|
||||
make_cons_page();
|
||||
conspageinitihasbeencalled = true;
|
||||
} else {
|
||||
fprintf( stderr, "WARNING: conspageinit() called a second or subsequent time\n");
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
* 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.
|
||||
*/
|
||||
#define CONSPAGESIZE 64
|
||||
#define CONSPAGESIZE 8
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
|
@ -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.
|
||||
* @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.
|
||||
*/
|
||||
void conspagesinit();
|
||||
void initialise_cons_pages();
|
||||
|
||||
/**
|
||||
* dump the allocated pages to this output stream.
|
||||
*/
|
||||
void dumppages( FILE* output);
|
||||
void dump_pages( FILE* output);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,14 @@
|
|||
#include "conspage.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.
|
||||
|
@ -22,11 +30,11 @@
|
|||
* You can't roll over the reference count. Once it hits the maximum
|
||||
* value you cannot increment further.
|
||||
*/
|
||||
void incref( struct cons_pointer pointer) {
|
||||
struct cons_space_object cell = pointer2cell( pointer);
|
||||
void inc_ref( struct cons_pointer pointer) {
|
||||
struct cons_space_object* cell = &pointer2cell( pointer);
|
||||
|
||||
if (cell.count < MAXREFERENCE) {
|
||||
cell.count ++;
|
||||
if (cell->count < MAXREFERENCE) {
|
||||
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 is decremented to zero the cell should be freed.
|
||||
*/
|
||||
void decref( struct cons_pointer pointer) {
|
||||
struct cons_space_object cell = pointer2cell( pointer);
|
||||
void dec_ref( struct cons_pointer pointer) {
|
||||
struct cons_space_object* cell = &pointer2cell( pointer);
|
||||
|
||||
if (cell.count < MAXREFERENCE) {
|
||||
cell.count --;
|
||||
if (cell->count <= MAXREFERENCE) {
|
||||
cell->count --;
|
||||
|
||||
if (cell.count == 0) {
|
||||
if (cell->count == 0) {
|
||||
free_cell( pointer);
|
||||
}
|
||||
}
|
||||
|
@ -54,30 +62,73 @@ void decref( struct cons_pointer pointer) {
|
|||
* dump the object at this cons_pointer to this output stream.
|
||||
*/
|
||||
void dump_object( FILE* output, struct cons_pointer pointer) {
|
||||
struct cons_space_object cell = conspages[pointer.page]->cell[pointer.offset];
|
||||
char * tag = malloc( TAGLENGTH + 1);
|
||||
memset( tag, 0, TAGLENGTH + 1);
|
||||
strncpy( tag, cell.tag, TAGLENGTH);
|
||||
|
||||
fprintf( output, "\tDumping object at page %d, offset %d with tag %s, count %d\n",
|
||||
struct cons_space_object cell = pointer2cell(pointer);
|
||||
fprintf( output,
|
||||
"\tDumping object at page %d, offset %d with tag %c%c%c%c (%d), count %u\n",
|
||||
pointer.page,
|
||||
pointer.offset,
|
||||
tag,
|
||||
cell.tag.bytes[0],
|
||||
cell.tag.bytes[1],
|
||||
cell.tag.bytes[2],
|
||||
cell.tag.bytes[3],
|
||||
cell.tag.value,
|
||||
cell.count);
|
||||
|
||||
if ( strncmp( tag, CONSTAG, TAGLENGTH) == 0) {
|
||||
fprintf( output, "\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n",
|
||||
cell.payload.cons.car.page, cell.payload.cons.car.offset, cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset);
|
||||
} else if ( strncmp( tag, INTEGERTAG, TAGLENGTH) == 0) {
|
||||
if ( check_tag(pointer, CONSTAG)) {
|
||||
fprintf( output,
|
||||
"\tCons cell: car at page %d offset %d, cdr at page %d offset %d\n",
|
||||
cell.payload.cons.car.page, cell.payload.cons.car.offset,
|
||||
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset);
|
||||
} else if ( check_tag(pointer, INTEGERTAG)) {
|
||||
fprintf( output, "\t\tInteger cell: value %ld\n", cell.payload.integer.value);
|
||||
} else if ( strncmp( tag, FREETAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, FREETAG)) {
|
||||
fprintf( output, "\t\tFree cell: next at page %d offset %d\n",
|
||||
cell.payload.cons.cdr.page, cell.payload.cons.cdr.offset);
|
||||
} else if ( strncmp( tag, REALTAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag(pointer, REALTAG)) {
|
||||
fprintf( output, "\t\tReal cell: value %Lf\n", cell.payload.real.value);
|
||||
} else if ( strncmp( tag, STRINGTAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, STRINGTAG)) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
/**
|
||||
* 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
|
||||
|
@ -50,21 +50,20 @@
|
|||
|
||||
#define pointer2cell(pointer) ((conspages[pointer.page]->cell[pointer.offset]))
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
#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
|
||||
*/
|
||||
#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
|
||||
|
@ -123,7 +122,10 @@ struct string_payload {
|
|||
* an object in cons space.
|
||||
*/
|
||||
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 */
|
||||
struct cons_pointer access; /* cons pointer to the access control list of this cell */
|
||||
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
|
||||
*/
|
||||
void incref( struct cons_pointer pointer);
|
||||
void inc_ref( struct cons_pointer 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);
|
||||
|
||||
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
|
||||
|
|
10
src/init.c
10
src/init.c
|
@ -19,16 +19,16 @@
|
|||
|
||||
int main (int argc, char *argv[]) {
|
||||
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);
|
||||
incref( input);
|
||||
printf( "\n");
|
||||
inc_ref( input);
|
||||
printf( "\n:: ");
|
||||
print( stdout, input);
|
||||
|
||||
dumppages(stdout);
|
||||
dump_pages(stdout);
|
||||
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
||||
|
||||
return(0);
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
/**
|
||||
* Allocate an integer cell representing this value and return a cons pointer to it.
|
||||
*/
|
||||
struct cons_pointer makeinteger( int value) {
|
||||
struct cons_pointer result = allocatecell( INTEGERTAG);
|
||||
struct cons_space_object cell = conspages[result.page]->cell[result.offset];
|
||||
cell.payload.integer.value = value;
|
||||
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];
|
||||
cell->payload.integer.value = value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
/**
|
||||
* 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
|
||||
|
|
15
src/print.c
15
src/print.c
|
@ -20,7 +20,7 @@
|
|||
void print( FILE* output, struct cons_pointer pointer) {
|
||||
struct cons_space_object cell = pointer2cell( pointer);
|
||||
|
||||
if ( strncmp( cell.tag, CONSTAG, TAGLENGTH) == 0) {
|
||||
if ( check_tag( pointer, CONSTAG)) {
|
||||
fputc( '(', output);
|
||||
for (struct cons_pointer p = pointer; consp( p);
|
||||
p = pointer2cell( p).payload.cons.cdr) {
|
||||
|
@ -28,20 +28,21 @@ void print( FILE* output, struct cons_pointer pointer) {
|
|||
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);
|
||||
} else if ( strncmp( cell.tag, NILTAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, NILTAG)) {
|
||||
fprintf( output, "NIL");
|
||||
} else if ( strncmp( cell.tag, REALTAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, REALTAG)) {
|
||||
fprintf( output, "%Lf", cell.payload.real.value);
|
||||
} else if ( strncmp( cell.tag, STRINGTAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, STRINGTAG)) {
|
||||
fputc( '"', output);
|
||||
for (struct cons_pointer p = pointer; stringp( p);
|
||||
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);
|
||||
} else if ( strncmp( cell.tag, TRUETAG, TAGLENGTH) == 0) {
|
||||
} else if ( check_tag( pointer, TRUETAG)) {
|
||||
fprintf( output, "T");
|
||||
}
|
||||
}
|
||||
|
|
42
src/read.c
42
src/read.c
|
@ -24,7 +24,7 @@
|
|||
/**
|
||||
* 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;
|
||||
char c;
|
||||
|
||||
|
@ -36,17 +36,35 @@ struct cons_pointer readnumber( FILE* input, char initial) {
|
|||
/* push back the character read which was not a digit */
|
||||
fputc( c, input);
|
||||
|
||||
return makeinteger( accumulator);
|
||||
return make_integer( accumulator);
|
||||
}
|
||||
|
||||
|
||||
struct cons_pointer readlist( FILE* input) {
|
||||
return NIL;
|
||||
struct cons_pointer read_list( FILE* input) {
|
||||
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) {
|
||||
return NIL;
|
||||
struct cons_pointer read_string( FILE* input) {
|
||||
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 result = NIL;
|
||||
|
||||
char c = fgetc( input);
|
||||
char c;
|
||||
|
||||
while ( isblank( c)) {
|
||||
c = fgetc( input);
|
||||
}
|
||||
for (c = fgetc( input); isblank( c); c = fgetc( input));
|
||||
|
||||
switch( c) {
|
||||
case '(' : result = readlist(input);
|
||||
case '(' : result = read_list(input);
|
||||
break;
|
||||
case '"': result = readstring(input);
|
||||
case '"': result = read_string(input);
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
|
@ -78,7 +94,7 @@ struct cons_pointer read( FILE* input) {
|
|||
case '8':
|
||||
case '9':
|
||||
// case '.':
|
||||
result = readnumber( input, c);
|
||||
result = read_number( input, c);
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "Unrecognised start of input character %c\n", c);
|
||||
|
|
Loading…
Reference in a new issue