Added stuff for a lisp stack, but not yet integrated.

This commit is contained in:
Simon Brooke 2017-01-13 08:44:56 +00:00
parent 432ccb2d44
commit 7e53ce2c4f
3 changed files with 125 additions and 8 deletions

View file

@ -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

75
src/stack.c Normal file
View file

@ -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;
}

42
src/stack.h Normal file
View file

@ -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