Added stuff for a lisp stack, but not yet integrated.
This commit is contained in:
		
							parent
							
								
									432ccb2d44
								
							
						
					
					
						commit
						7e53ce2c4f
					
				
					 3 changed files with 125 additions and 8 deletions
				
			
		| 
						 | 
					@ -26,17 +26,17 @@
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * tag values, all of which must be 4 bytes. Must not collide with vector space tag values
 | 
					 * tag values, all of which must be 4 bytes. Must not collide with vector space tag values
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define CONSTAG  "CONS"
 | 
					#define CONSTAG     "CONS"
 | 
				
			||||||
#define FREETAG  "FREE"
 | 
					#define FREETAG     "FREE"
 | 
				
			||||||
#define FUNCTIONTAG "FUNC"
 | 
					#define FUNCTIONTAG "FUNC"
 | 
				
			||||||
#define INTEGERTAG  "INTR"
 | 
					#define INTEGERTAG  "INTR"
 | 
				
			||||||
#define NILTAG  "NIL "
 | 
					#define NILTAG      "NIL "
 | 
				
			||||||
#define READTAG  "READ"
 | 
					#define READTAG     "READ"
 | 
				
			||||||
#define REALTAG  "REAL"
 | 
					#define REALTAG     "REAL"
 | 
				
			||||||
#define STRINGTAG  "STRG"
 | 
					#define STRINGTAG   "STRG"
 | 
				
			||||||
#define TRUETAG  "TRUE"
 | 
					#define TRUETAG     "TRUE"
 | 
				
			||||||
#define VECTORPOINTTAG  "VECP"
 | 
					#define VECTORPOINTTAG  "VECP"
 | 
				
			||||||
#define WRITETAG  "WRIT"
 | 
					#define WRITETAG    "WRIT"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * a cons pointer which points to the special NIL cell
 | 
					 * a cons pointer which points to the special NIL cell
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										75
									
								
								src/stack.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/stack.c
									
										
									
									
									
										Normal 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
									
								
							
							
						
						
									
										42
									
								
								src/stack.h
									
										
									
									
									
										Normal 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
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue