Added first cut of reader and writer, but nothing working at this stage.
This commit is contained in:
parent
0e693d4360
commit
5920b0d04f
|
@ -27,7 +27,13 @@
|
||||||
bool conspageinitihasbeencalled = false;
|
bool conspageinitihasbeencalled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The (global) pointer to the (global) freelist. Not sure whether this ultimately belongs in this file.
|
* the number of cons pages which have thus far been initialised.
|
||||||
|
*/
|
||||||
|
int initialisedconspages = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The (global) pointer to the (global) freelist. Not sure whether this ultimately
|
||||||
|
* belongs in this file.
|
||||||
*/
|
*/
|
||||||
struct cons_pointer freelist = NIL;
|
struct cons_pointer freelist = NIL;
|
||||||
|
|
||||||
|
@ -36,11 +42,6 @@ struct cons_pointer freelist = NIL;
|
||||||
*/
|
*/
|
||||||
struct cons_page* conspages[NCONSPAGES];
|
struct cons_page* conspages[NCONSPAGES];
|
||||||
|
|
||||||
/**
|
|
||||||
* the number of cons pages which have thus far been initialised.
|
|
||||||
*/
|
|
||||||
int initialisedconspages = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a cons page whose serial number (i.e. index in the conspages directory) is pageno.
|
* Make a cons page whose serial number (i.e. index in the conspages directory) is pageno.
|
||||||
|
@ -55,21 +56,21 @@ void makeconspage() {
|
||||||
if ( initialisedconspages == 0 && i < 2) {
|
if ( initialisedconspages == 0 && i < 2) {
|
||||||
if ( i == 0) {
|
if ( i == 0) {
|
||||||
/* initialise cell as NIL */
|
/* initialise cell as NIL */
|
||||||
strncpy( result->cell[i].tag, NILTAG, 4);
|
strncpy( result->cell[i].tag, NILTAG, TAGLENGTH);
|
||||||
result->cell[i].count = (2 ^ 32) - 1; // should be max value of unsigned 32 bit integer
|
result->cell[i].count = MAXREFERENCE;
|
||||||
result->cell[i].payload.free.car = NIL;
|
result->cell[i].payload.free.car = NIL;
|
||||||
result->cell[i].payload.free.cdr = NIL;
|
result->cell[i].payload.free.cdr = NIL;
|
||||||
} else if ( i == 1) {
|
} else if ( i == 1) {
|
||||||
/* initialise cell as T */
|
/* initialise cell as T */
|
||||||
strncpy( result->cell[i].tag, TRUETAG, 4);
|
strncpy( result->cell[i].tag, TRUETAG, TAGLENGTH);
|
||||||
result->cell[i].count = (2 ^ 32) - 1; // should be max value of unsigned 32 bit integer
|
result->cell[i].count = MAXREFERENCE;
|
||||||
result->cell[i].payload.free.car = (struct cons_pointer){ 0, 1};
|
result->cell[i].payload.free.car = (struct cons_pointer){ 0, 1};
|
||||||
result->cell[i].payload.free.cdr = (struct cons_pointer){ 0, 1};
|
result->cell[i].payload.free.cdr = (struct cons_pointer){ 0, 1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise, standard initialisation */
|
/* otherwise, standard initialisation */
|
||||||
strncpy( result->cell[i].tag, FREETAG, 4);
|
strncpy( result->cell[i].tag, FREETAG, TAGLENGTH);
|
||||||
result->cell[i].payload.free.car = NIL;
|
result->cell[i].payload.free.car = NIL;
|
||||||
result->cell[i].payload.free.cdr = freelist;
|
result->cell[i].payload.free.cdr = freelist;
|
||||||
freelist.page = initialisedconspages;
|
freelist.page = initialisedconspages;
|
||||||
|
@ -85,6 +86,20 @@ void makeconspage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dump the allocated pages to this output stream.
|
||||||
|
*/
|
||||||
|
void dumppages( FILE* output) {
|
||||||
|
for ( int i = 0; i < initialisedconspages; i++) {
|
||||||
|
fprintf( output, "\nDUMPING PAGE %d\n", i);
|
||||||
|
|
||||||
|
for ( int j = 0; j < CONSPAGESIZE; j++) {
|
||||||
|
dump_object( output, (struct cons_pointer){i, j});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees the cell at the specified pointer. Dangerous, primitive, low
|
* Frees the cell at the specified pointer. Dangerous, primitive, low
|
||||||
* level.
|
* level.
|
||||||
|
@ -129,10 +144,17 @@ struct cons_pointer allocatecell( char* tag) {
|
||||||
|
|
||||||
freelist = cell.payload.free.cdr;
|
freelist = cell.payload.free.cdr;
|
||||||
|
|
||||||
|
fprintf( stderr, "Before: %c\n", cell.tag[0]);
|
||||||
strncpy( cell.tag, tag, 4);
|
strncpy( cell.tag, tag, 4);
|
||||||
|
fprintf( stderr, "After: %c\n", cell.tag[0]);
|
||||||
|
|
||||||
cell.count = 1;
|
cell.count = 1;
|
||||||
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",
|
||||||
|
tag, result.page, result.offset);
|
||||||
|
dump_object( stderr, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -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 256
|
#define CONSPAGESIZE 64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 256
|
#define NCONSPAGES 64
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -28,9 +28,45 @@ struct cons_page {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The (global) pointer to the (global) freelist. Not sure whether this ultimately
|
||||||
|
* belongs in this file.
|
||||||
|
*/
|
||||||
|
extern struct cons_pointer freelist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of pointers to cons pages.
|
||||||
|
*/
|
||||||
|
extern struct cons_page* conspages[NCONSPAGES];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frees the cell at the specified pointer. Dangerous, primitive, low
|
||||||
|
* level.
|
||||||
|
*
|
||||||
|
* @pointer the cell to free
|
||||||
|
*/
|
||||||
|
void free_cell(struct cons_pointer pointer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a cell with the specified tag. Dangerous, primitive, low
|
||||||
|
* level.
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 conspagesinit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dump the allocated pages to this output stream.
|
||||||
|
*/
|
||||||
|
void dumppages( FILE* output);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,76 @@
|
||||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "conspage.h"
|
||||||
#include "consspaceobject.h"
|
#include "consspaceobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* increment the reference count of the object at this cons pointer.
|
||||||
|
*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
if (cell.count < MAXREFERENCE) {
|
||||||
|
cell.count ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the reference count of the object at this cons 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);
|
||||||
|
|
||||||
|
if (cell.count < MAXREFERENCE) {
|
||||||
|
cell.count --;
|
||||||
|
|
||||||
|
if (cell.count == 0) {
|
||||||
|
free_cell( 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",
|
||||||
|
pointer.page,
|
||||||
|
pointer.offset,
|
||||||
|
tag,
|
||||||
|
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) {
|
||||||
|
fprintf( output, "\t\tInteger cell: value %ld\n", cell.payload.integer.value);
|
||||||
|
} else if ( strncmp( tag, FREETAG, TAGLENGTH) == 0) {
|
||||||
|
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) {
|
||||||
|
fprintf( output, "\t\tReal cell: value %Lf\n", cell.payload.real.value);
|
||||||
|
} 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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef __consspaceobject_h
|
#ifndef __consspaceobject_h
|
||||||
#define __consspaceobject_h
|
#define __consspaceobject_h
|
||||||
|
@ -38,11 +38,33 @@
|
||||||
*/
|
*/
|
||||||
#define NIL (struct cons_pointer){ 0, 0}
|
#define NIL (struct cons_pointer){ 0, 0}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the maximum possible value of a reference count
|
||||||
|
*/
|
||||||
|
#define MAXREFERENCE ((2 ^ 32) - 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* a macro to convert a tag into a number
|
* a macro to convert a tag into a number
|
||||||
*/
|
*/
|
||||||
#define tag2uint(tag) ((uint32_t)*tag)
|
#define tag2uint(tag) ((uint32_t)*tag)
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if conspointer points to a cons cell, else false
|
||||||
|
*/
|
||||||
|
#define consp(conspoint) (strncmp(pointer2cell(conspoint).tag, CONSTAG, TAGLENGTH)==0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* true if conspointer points to a string cell, else false
|
||||||
|
*/
|
||||||
|
#define stringp(conspoint) (strncmp(pointer2cell(conspoint).tag, STRINGTAG, TAGLENGTH)==0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An indirect pointer to a cons cell
|
* An indirect pointer to a cons cell
|
||||||
|
@ -76,7 +98,7 @@ struct free_payload {
|
||||||
* optional bignum object.
|
* optional bignum object.
|
||||||
*/
|
*/
|
||||||
struct integer_payload {
|
struct integer_payload {
|
||||||
long int integer;
|
long int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,7 +107,7 @@ struct integer_payload {
|
||||||
* precision, but I'm not sure of the detail.
|
* precision, but I'm not sure of the detail.
|
||||||
*/
|
*/
|
||||||
struct real_payload {
|
struct real_payload {
|
||||||
long double real;
|
long double value;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,4 +145,21 @@ struct cons_space_object {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* increment the reference count of the object at this cons pointer
|
||||||
|
*/
|
||||||
|
void incref( struct cons_pointer pointer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decrement the reference count of the object at this cons pointer
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
10
src/init.c
10
src/init.c
|
@ -14,11 +14,21 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "conspage.h"
|
#include "conspage.h"
|
||||||
#include "consspaceobject.h"
|
#include "consspaceobject.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "read.h"
|
||||||
|
|
||||||
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();
|
conspagesinit();
|
||||||
|
|
||||||
|
printf( "Ready\n>>");
|
||||||
|
|
||||||
|
struct cons_pointer input = read( stdin);
|
||||||
|
incref( input);
|
||||||
|
printf( "\n");
|
||||||
|
print( stdout, input);
|
||||||
|
|
||||||
|
dumppages(stdout);
|
||||||
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
// printf( "Tag2uint(\"FREE\") = %d\n", tag2uint("FREE"));
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
|
24
src/integer.c
Normal file
24
src/integer.c
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* integer.c
|
||||||
|
*
|
||||||
|
* functions for integer cells.
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "conspage.h"
|
||||||
|
#include "consspaceobject.h"
|
||||||
|
#include "read.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
19
src/integer.h
Normal file
19
src/integer.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* integer.h
|
||||||
|
*
|
||||||
|
* functions for integer cells.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __integer_h
|
||||||
|
#define __integer_h
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an integer cell representing this value and return a cons pointer to it.
|
||||||
|
*/
|
||||||
|
struct cons_pointer makeinteger( int value);
|
||||||
|
|
||||||
|
#endif
|
47
src/print.c
Normal file
47
src/print.c
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* print.c
|
||||||
|
*
|
||||||
|
* First pass at a printer, for bootstrapping.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "conspage.h"
|
||||||
|
#include "consspaceobject.h"
|
||||||
|
#include "integer.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
void print( FILE* output, struct cons_pointer pointer) {
|
||||||
|
struct cons_space_object cell = pointer2cell( pointer);
|
||||||
|
|
||||||
|
if ( strncmp( cell.tag, CONSTAG, TAGLENGTH) == 0) {
|
||||||
|
fputc( '(', output);
|
||||||
|
for (struct cons_pointer p = pointer; consp( p);
|
||||||
|
p = pointer2cell( p).payload.cons.cdr) {
|
||||||
|
print( output, p);
|
||||||
|
fputc( ' ', output);
|
||||||
|
}
|
||||||
|
fputc( ')', output);
|
||||||
|
} else if ( strncmp( cell.tag, INTEGERTAG, TAGLENGTH) == 0) {
|
||||||
|
fprintf( output, " %ld", cell.payload.integer.value);
|
||||||
|
} else if ( strncmp( cell.tag, NILTAG, TAGLENGTH) == 0) {
|
||||||
|
fprintf( output, "NIL");
|
||||||
|
} else if ( strncmp( cell.tag, REALTAG, TAGLENGTH) == 0) {
|
||||||
|
fprintf( output, "%Lf", cell.payload.real.value);
|
||||||
|
} else if ( strncmp( cell.tag, STRINGTAG, TAGLENGTH) == 0) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
fputc( '"', output);
|
||||||
|
} else if ( strncmp( cell.tag, TRUETAG, TAGLENGTH) == 0) {
|
||||||
|
fprintf( output, "T");
|
||||||
|
}
|
||||||
|
}
|
19
src/print.h
Normal file
19
src/print.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* print.h
|
||||||
|
*
|
||||||
|
* First pass at a printer, for bootstrapping.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef __print_h
|
||||||
|
#define __print_h
|
||||||
|
|
||||||
|
void print( FILE* output, struct cons_pointer pointer);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,19 +0,0 @@
|
||||||
/**
|
|
||||||
* quickbool.h
|
|
||||||
*
|
|
||||||
* Currently, just a macro to test whether a cons_pointer is the
|
|
||||||
* special NIL cons_pointer.
|
|
||||||
*
|
|
||||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
|
||||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "consspaceobject.h"
|
|
||||||
|
|
||||||
#ifndef __quickbool_h
|
|
||||||
#define __quickbool_h
|
|
||||||
|
|
||||||
/* true if conspointer points to the special cell NIL, else false */
|
|
||||||
#define nilp(conspoint) ((((struct cons_pointer)conspoint).page == NIL.page) && ((struct conspoint).offser == NIL.offset))
|
|
||||||
|
|
||||||
#endif
|
|
92
src/read.c
Normal file
92
src/read.c
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* read.c
|
||||||
|
*
|
||||||
|
* First pass at a reader, for bootstrapping.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "consspaceobject.h"
|
||||||
|
#include "integer.h"
|
||||||
|
#include "read.h"
|
||||||
|
|
||||||
|
/* for the time being things which may be read are:
|
||||||
|
strings
|
||||||
|
numbers - either integer or real, but not yet including ratios or bignums
|
||||||
|
lists
|
||||||
|
Can't read atoms because I don't yet know what an atom is or how it's stored. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read a number from this input stream, given this initial character.
|
||||||
|
*/
|
||||||
|
struct cons_pointer readnumber( FILE* input, char initial) {
|
||||||
|
int accumulator = 0;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
for (c = initial; isdigit( c); c = fgetc( input)) {
|
||||||
|
int digitvalue = (int)c - (int)'0';
|
||||||
|
accumulator = accumulator * 10 + digitvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* push back the character read which was not a digit */
|
||||||
|
fputc( c, input);
|
||||||
|
|
||||||
|
return makeinteger( accumulator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct cons_pointer readlist( FILE* input) {
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct cons_pointer readstring( FILE* input) {
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the next object on this input stream and return a cons_pointer to it.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read( FILE* input) {
|
||||||
|
struct cons_pointer result = NIL;
|
||||||
|
|
||||||
|
char c = fgetc( input);
|
||||||
|
|
||||||
|
while ( isblank( c)) {
|
||||||
|
c = fgetc( input);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( c) {
|
||||||
|
case '(' : result = readlist(input);
|
||||||
|
break;
|
||||||
|
case '"': result = readstring(input);
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
// case '.':
|
||||||
|
result = readnumber( input, c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf( stderr, "Unrecognised start of input character %c\n", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
19
src/read.h
Normal file
19
src/read.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* read.c
|
||||||
|
*
|
||||||
|
* First pass at a reader, for bootstrapping.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||||
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __read_h
|
||||||
|
#define __read_h
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read the next object on this input stream and return a cons_pointer to it.
|
||||||
|
*/
|
||||||
|
struct cons_pointer read( FILE* input);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue