Having found rust wasn't going to work, I've hacked up a rough core of the
cons space in C. None of this is tested.
This commit is contained in:
parent
655526afac
commit
2e77d2beb6
23
Makefile
Normal file
23
Makefile
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
TARGET ?= target/psse
|
||||
SRC_DIRS ?= ./src
|
||||
|
||||
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c -or -name *.s)
|
||||
OBJS := $(addsuffix .o,$(basename $(SRCS)))
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
INC_DIRS := $(shell find $(SRC_DIRS) -type d)
|
||||
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
||||
|
||||
VERSION := "0.0.0"
|
||||
|
||||
CPPFLAGS ?= $(INC_FLAGS) -MMD -MP
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) -DVERSION=$(VERSION) -o $@ $(LOADLIBES) $(LDLIBS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) $(TARGET) $(OBJS) $(DEPS)
|
||||
|
||||
-include $(DEPS)
|
156
src/conspage.c
Normal file
156
src/conspage.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* conspage.c
|
||||
*
|
||||
* Setup and tear down cons pages, and (FOR NOW) do primitive
|
||||
* allocation/deallocation of cells.
|
||||
* NOTE THAT before we go multi-threaded, these functions must be
|
||||
* aggressively
|
||||
* thread safe.
|
||||
*
|
||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "consspaceobject.h"
|
||||
#include "conspage.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Flag indicating whether conspage initialisation has been done.
|
||||
*/
|
||||
bool conspageinitihasbeencalled = false;
|
||||
|
||||
/**
|
||||
* The (global) pointer to the (global) freelist. Not sure whether this ultimately belongs in this file.
|
||||
*/
|
||||
struct cons_pointer freelist = NIL;
|
||||
|
||||
/**
|
||||
* An array of pointers to cons pages.
|
||||
*/
|
||||
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.
|
||||
* 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() {
|
||||
struct cons_page* result = malloc( sizeof( struct cons_page));
|
||||
|
||||
if ( result != NULL) {
|
||||
for (int i = 0; i < CONSPAGESIZE; i++) {
|
||||
if ( initialisedconspages == 0 && i < 2) {
|
||||
if ( i == 0) {
|
||||
/* initialise cell as NIL */
|
||||
strncpy( result->cell[i].tag, NILTAG, 4);
|
||||
result->cell[i].count = (2 ^ 32) - 1; // should be max value of unsigned 32 bit integer
|
||||
result->cell[i].payload.free.car = NIL;
|
||||
result->cell[i].payload.free.cdr = NIL;
|
||||
} else if ( i == 1) {
|
||||
/* initialise cell as T */
|
||||
strncpy( result->cell[i].tag, TRUETAG, 4);
|
||||
result->cell[i].count = (2 ^ 32) - 1; // should be max value of unsigned 32 bit integer
|
||||
result->cell[i].payload.free.car = (struct cons_pointer){ 0, 1};
|
||||
result->cell[i].payload.free.cdr = (struct cons_pointer){ 0, 1};
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, standard initialisation */
|
||||
strncpy( result->cell[i].tag, FREETAG, 4);
|
||||
result->cell[i].payload.free.car = NIL;
|
||||
result->cell[i].payload.free.cdr = freelist;
|
||||
freelist.page = initialisedconspages;
|
||||
freelist.offset = i;
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr, "FATAL: Failed to allocate memory for cons page %d\n", initialisedconspages);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
conspages[initialisedconspages] = result;
|
||||
initialisedconspages++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Frees the cell at the specified pointer. Dangerous, primitive, low
|
||||
* level.
|
||||
*
|
||||
* @pointer the cell to free
|
||||
*/
|
||||
void free_cell(struct cons_pointer pointer) {
|
||||
struct cons_space_object cell = conspages[pointer.page]->cell[pointer.offset];
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
fprintf( stderr, "Attempt to free cell which is already FREE at page %d, offset %d\n",
|
||||
pointer.page, pointer.offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
struct cons_pointer result = freelist;
|
||||
|
||||
if ( result.page == NIL.page && result.offset == NIL.offset) {
|
||||
makeconspage();
|
||||
result = allocatecell( tag);
|
||||
} else {
|
||||
struct cons_space_object cell = conspages[result.page]->cell[result.offset];
|
||||
|
||||
freelist = cell.payload.free.cdr;
|
||||
|
||||
strncpy( cell.tag, tag, 4);
|
||||
cell.count = 1;
|
||||
cell.payload.cons.car = NIL;
|
||||
cell.payload.cons.cdr = NIL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initialise the cons page system; to be called exactly once during startup.
|
||||
*/
|
||||
void conspagesinit() {
|
||||
if ( conspageinitihasbeencalled == false) {
|
||||
for (int i = 0; i < NCONSPAGES; i++) {
|
||||
conspages[i] = (struct cons_page *) NULL;
|
||||
}
|
||||
|
||||
makeconspage();
|
||||
conspageinitihasbeencalled = true;
|
||||
} else {
|
||||
fprintf( stderr, "WARNING: conspageinit() called a second or subsequent time\n");
|
||||
}
|
||||
}
|
36
src/conspage.h
Normal file
36
src/conspage.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "consspaceobject.h"
|
||||
|
||||
#ifndef __conspage_h
|
||||
#define __conspage_h
|
||||
|
||||
|
||||
/**
|
||||
* the number of cons cells on a cons page. The maximum value this can be (and consequently,
|
||||
* 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 256
|
||||
|
||||
/**
|
||||
* 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 256
|
||||
|
||||
/**
|
||||
* a cons page is essentially just an array of cons space objects. It might later have a local
|
||||
* free list (i.e. list of free cells on this page) and a pointer to the next cons page, but
|
||||
* my current view is that that's probably unneccessary.
|
||||
*/
|
||||
struct cons_page {
|
||||
struct cons_space_object cell[CONSPAGESIZE];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* initialise the cons page system; to be called exactly once during startup.
|
||||
*/
|
||||
void conspagesinit();
|
||||
|
||||
#endif
|
14
src/consspaceobject.c
Normal file
14
src/consspaceobject.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* consspaceobject.c
|
||||
*
|
||||
* Structures common to all cons space objects.
|
||||
*
|
||||
*
|
||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "consspaceobject.h"
|
116
src/consspaceobject.h
Normal file
116
src/consspaceobject.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* consspaceobject.h
|
||||
*
|
||||
* Declarations common to all cons space objects.
|
||||
*
|
||||
*
|
||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef __consspaceobject_h
|
||||
#define __consspaceobject_h
|
||||
|
||||
/**
|
||||
* The length of a tag, in bytes.
|
||||
*/
|
||||
#define TAGLENGTH 4
|
||||
|
||||
/**
|
||||
* tag values, all of which must be 4 bytes. Must not collide with vector space tag values
|
||||
*/
|
||||
#define CONSTAG "CONS"
|
||||
#define FREETAG "FREE"
|
||||
#define INTEGERTAG "INTR"
|
||||
#define NILTAG "NIL "
|
||||
#define READTAG "READ"
|
||||
#define REALTAG "REAL"
|
||||
#define STRINGTAG "STRG"
|
||||
#define TRUETAG "TRUE"
|
||||
#define VECTORPOINTTAG "VECP"
|
||||
#define WRITETAG "WRIT"
|
||||
|
||||
/**
|
||||
* a cons pointer which points to the special NIL cell
|
||||
*/
|
||||
#define NIL (struct cons_pointer){ 0, 0}
|
||||
|
||||
|
||||
/**
|
||||
* An indirect pointer to a cons cell
|
||||
*/
|
||||
struct cons_pointer {
|
||||
uint32_t page; /* the index of the page on which this cell resides */
|
||||
uint32_t offset; /* the index of the cell within the page */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* payload of a cons cell.
|
||||
*/
|
||||
struct cons_payload {
|
||||
struct cons_pointer car;
|
||||
struct cons_pointer cdr;
|
||||
};
|
||||
|
||||
/**
|
||||
* payload of a free cell. For the time being identical to a cons cell,
|
||||
* but it may not be so in future.
|
||||
*/
|
||||
struct free_payload {
|
||||
struct cons_pointer car;
|
||||
struct cons_pointer cdr;
|
||||
};
|
||||
|
||||
/**
|
||||
* payload of an integer cell. For the time being just a signed integer;
|
||||
* later might be a signed 128 bit integer, or might have some flag to point to an
|
||||
* optional bignum object.
|
||||
*/
|
||||
struct integer_payload {
|
||||
long int integer;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* payload for a real number cell. Internals of this liable to change to give 128 bits
|
||||
* precision, but I'm not sure of the detail.
|
||||
*/
|
||||
struct real_payload {
|
||||
long double real;
|
||||
};
|
||||
|
||||
/**
|
||||
* payload of a string cell. At least at first, only one UTF character will be stored in each cell.
|
||||
*/
|
||||
struct string_payload {
|
||||
uint32_t character; /* the actual character stored in this cell */
|
||||
uint32_t padding; /* unused padding to word-align the cdr */
|
||||
struct cons_pointer cdr;
|
||||
};
|
||||
|
||||
/**
|
||||
* an object in cons space.
|
||||
*/
|
||||
struct cons_space_object {
|
||||
char tag[TAGLENGTH]; /* the tag (type) of this cons 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 */
|
||||
union {
|
||||
/* if tag == CONSTAG */
|
||||
struct cons_payload cons;
|
||||
/* if tag == FREETAG */
|
||||
struct free_payload free;
|
||||
struct integer_payload integer;
|
||||
struct cons_payload nil;
|
||||
struct real_payload real;
|
||||
struct string_payload string;
|
||||
struct cons_payload t;
|
||||
} payload;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
22
src/init.c
Normal file
22
src/init.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* init.c
|
||||
*
|
||||
* Start up and initialise the environement - just enough to get working and (ultimately)
|
||||
* hand off to the executive.
|
||||
*
|
||||
*
|
||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "conspage.h"
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
printf( "Post scarcity software environment version %s\n", VERSION);
|
||||
conspagesinit();
|
||||
|
||||
return(0);
|
||||
}
|
19
src/quickbool.h
Normal file
19
src/quickbool.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* 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
|
12
src/version.h
Normal file
12
src/version.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* version.h
|
||||
*
|
||||
* Just the version number. There's DEFINITELY a better way to do this!
|
||||
*
|
||||
*
|
||||
* (c) 2017 Simon Brooke <simon@journeyman.cc>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
*/
|
||||
|
||||
|
||||
#define VERSION "0.0.0"
|
Loading…
Reference in a new issue