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
					
				
					 8 changed files with 398 additions and 0 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue