From 7e53ce2c4fb4f2032fda8b87832920e8cd919fad Mon Sep 17 00:00:00 2001
From: Simon Brooke <simon@journeyman.cc>
Date: Fri, 13 Jan 2017 08:44:56 +0000
Subject: [PATCH] Added stuff for a lisp stack, but not yet integrated.

---
 src/consspaceobject.h | 16 ++++-----
 src/stack.c           | 75 +++++++++++++++++++++++++++++++++++++++++++
 src/stack.h           | 42 ++++++++++++++++++++++++
 3 files changed, 125 insertions(+), 8 deletions(-)
 create mode 100644 src/stack.c
 create mode 100644 src/stack.h

diff --git a/src/consspaceobject.h b/src/consspaceobject.h
index bc7d6be..fb696e6 100644
--- a/src/consspaceobject.h
+++ b/src/consspaceobject.h
@@ -26,17 +26,17 @@
 /**
  * tag values, all of which must be 4 bytes. Must not collide with vector space tag values
  */
-#define CONSTAG  "CONS"
-#define FREETAG  "FREE"
+#define CONSTAG     "CONS"
+#define FREETAG     "FREE"
 #define FUNCTIONTAG "FUNC"
 #define INTEGERTAG  "INTR"
-#define NILTAG  "NIL "
-#define READTAG  "READ"
-#define REALTAG  "REAL"
-#define STRINGTAG  "STRG"
-#define TRUETAG  "TRUE"
+#define NILTAG      "NIL "
+#define READTAG     "READ"
+#define REALTAG     "REAL"
+#define STRINGTAG   "STRG"
+#define TRUETAG     "TRUE"
 #define VECTORPOINTTAG  "VECP"
-#define WRITETAG  "WRIT"
+#define WRITETAG    "WRIT"
 
 /**
  * a cons pointer which points to the special NIL cell
diff --git a/src/stack.c b/src/stack.c
new file mode 100644
index 0000000..7e24574
--- /dev/null
+++ b/src/stack.c
@@ -0,0 +1,75 @@
+/**
+ * stack.c
+ *
+ * The Lisp evaluation stack.
+ *
+ * Stack frames could be implemented in cons space; indeed, the stack
+ * could simply be an assoc list consed onto the front of the environment. 
+ * But such a stack would be costly to search. The design sketched here, 
+ * with stack frames as special objects, SHOULD be substantially more 
+ * efficient, but does imply we need to generalise the idea of cons pages
+ * with freelists to a more general 'equal sized object pages', so that
+ * allocating/freeing stack frames can be more efficient.
+ * 
+ * Stack frames are not yet a first class object; they have no VECP pointer
+ * in cons space.
+ *
+ * (c) 2017 Simon Brooke <simon@journeyman.cc>
+ * Licensed under GPL version 2.0, or, at your option, any later version.
+ */
+
+#include <stdlib.h>
+
+#include "consspaceobject.h"
+#include "conspage.h"
+#include "stack.h"
+
+/**
+ * Allocate a new stack frame with its previous pointer set to this value
+ */
+struct stack_frame* make_stack_frame(struct stack_frame* previous) {
+  /* TODO: later, pop a frame off a free-list of stack frames */
+  struct stack_frame* result = malloc( sizeof( struct stack_frame));
+
+  result->previous = previous;
+
+  /* clearing the frame with memset would probably be slightly quicker, but
+   * this is clear. */
+  result->more = NIL;
+  result->function = NIL;
+
+  for ( int i = 0; i < locals_in_frame; i++) {
+    result->local[i] = NIL;
+  }
+
+  return result;
+}
+
+/**
+ * Free this stack frame.
+ */
+void free_stack_frame( struct stack_frame* frame) {
+  /* TODO: later, push it back on the stack-frame freelist */
+  free( frame);
+}
+
+/**
+ * Fetch a pointer to the value of the local variable at this index.
+ */
+struct cons_pointer fetch_local( struct stack_frame* frame, unsigned int index) {
+  struct cons_pointer result = NIL;
+  
+  if ( index < locals_in_frame) {
+    result = frame->local[ index];
+  } else {
+    struct cons_pointer p = frame->more;
+    
+    for ( int i = locals_in_frame; i < index; i++) {
+      p = pointer2cell( p).payload.cons.cdr;
+    }
+
+    result = pointer2cell( p).payload.cons.car;
+  }
+
+  return result;
+}
diff --git a/src/stack.h b/src/stack.h
new file mode 100644
index 0000000..ec3d956
--- /dev/null
+++ b/src/stack.h
@@ -0,0 +1,42 @@
+/**
+ * stack.h
+ *
+ * The Lisp evaluation stack.
+ *
+ * Stack frames could be implemented in cons space; indeed, the stack
+ * could simply be an assoc list consed onto the front of the environment. 
+ * But such a stack would be costly to search. The design sketched here, 
+ * with stack frames as special objects, SHOULD be substantially more 
+ * efficient, but does imply we need to generalise the idea of cons pages
+ * with freelists to a more general 'equal sized object pages', so that
+ * allocating/freeing stack frames can be more efficient.
+ * 
+ * Stack frames are not yet a first class object; they have no VECP pointer
+ * in cons space.
+ *
+ * (c) 2017 Simon Brooke <simon@journeyman.cc>
+ * Licensed under GPL version 2.0, or, at your option, any later version.
+ */
+
+#include "consspaceobject.h"
+
+#ifndef __stack_h
+#define __stack_h
+
+/* number of local variables stored in a stack frame */
+#define locals_in_frame 8
+
+struct stack_frame* make_stack_frame(struct stack_frame* previous);
+void free_stack_frame( struct stack_frame* frame);
+struct cons_pointer fetch_local( struct stack_frame* frame, unsigned int n);
+
+struct stack_frame {
+  struct stack_frame* previous;         /* the previous frame */
+  struct cons_pointer local[locals_in_frame];
+                                        /* first 8 local variable bindings */
+  struct cons_pointer more;             /* list of any further local 
+					 * variable bindings */
+  struct cons_pointer function;         /* the function to be called */
+};
+
+#endif