picell.h
Go to the documentation of this file.
1 
9 #ifndef PICELL_H
10 #define PICELL_H
11 #include "pisettings.h"
12 #include <stdbool.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 /********************************************************************************
17  * CELL DEFINITION
18  ********************************************************************************/
19 
24 enum {
25  TYPE_CONS = 0, // is a cell with a car and a cdr
26  TYPE_SYM, // symbol cell
27  TYPE_NUM, // integer cell
28  TYPE_STR, // string cell
29  TYPE_FREE, // free cell: can be allocated from the memory manager to another
30  // cell
33  TYPE_KEYWORD,
35 };
36 
44 typedef struct cell {
45  unsigned char type;
46  unsigned char marked;
47  unsigned long marks;
48  union {
49  int value;
50  char *str;
51  struct cell *
53  struct {
54  struct cell *car;
55  struct cell *cdr;
56  };
57  struct {
58  char *sym; // symbol for symbol cells
59  union {
60  struct {
61  struct cell *(*bl)(
62  struct cell *args);
63  void (*bs)(
65  size_t stack_base,
66  unsigned char
67  nargs);
68  };
71  struct cell *(*bm)(
72  struct cell *args,
73  struct cell *env);
74  };
75  };
76  };
77 } cell;
78 
79 // unsafe unmark: no checks if cell is empty or a builtin! use only if you are
80 // sure that cell exists and is not a builtin symbol. it's faster
81 #if INLINE_FUNCTIONS
82 inline void unsafe_cell_remove(cell *c) { c->marks--; }
83 #else
84 void unsafe_cell_remove(cell *c);
85 #endif
86 
87 /********************************************************************************
88  * STACK DEFINITION
89  ********************************************************************************/
90 
93 
94 /********************************************************************************
95  * GARBAGE COLLECTOR
96  ********************************************************************************/
97 
98 // cells array
99 typedef struct {
100  size_t block_size;
102 } cell_block;
103 
104 cell_block *cell_block_create(size_t s);
105 void cell_block_free(cell_block *cb);
106 
107 // cells space: array of cell blocks. Just one of this will be instantiated:
108 // the pointer "memory" that represents the allocated cells in the interpreter
109 typedef struct {
112  size_t n_cells;
113  size_t n_free_cells;
117 } cell_space;
118 
120 void init_memory();
121 void free_memory();
122 
126 void cell_space_init(cell_space *cs);
127 void cell_space_grow(cell_space *cs);
130 void cell_space_free(cell_space *cs);
132 
133 /********************************************************************************
134  * CELL BASIC OPERATIONS
135  ********************************************************************************/
136 
137 #if INLINE_FUNCTIONS
138 inline cell *get_cell() { return cell_space_get_cell(memory); }
139 
140 inline cell *mk_num(int n) {
141  cell *c = get_cell();
142  c->type = TYPE_NUM;
143  c->value = n;
144  return c;
145 }
146 
147 inline cell *mk_str(char *s) {
148  cell *c = get_cell();
149  c->type = TYPE_STR;
150  c->str = malloc(strlen(s) + 1);
151  strcpy(c->str, s);
152 
153  return c;
154 }
155 
156 inline cell *mk_cons(cell *car, cell *cdr) {
157  cell *c = get_cell();
158  c->type = TYPE_CONS;
159  c->car = car;
160  c->cdr = cdr;
161  return c;
162 }
163 #else
164 cell *get_cell();
165 cell *mk_num(int n);
166 cell *mk_str(char *s);
167 cell *mk_cons(cell *car, cell *cdr);
168 #endif
169 
170 cell *mk_sym(char *symbol);
171 cell *mk_builtin_lambda(char *symbol, cell *(*function)(cell *),
172  void (*builtin_stack)(size_t, unsigned char));
173 cell *mk_builtin_macro(char *symbol, cell *(*function)(cell *, cell *));
174 
175 cell *copy_cell(cell *c);
177 
178 /********************************************************************************
179  * CELL IDENTIFICATION
180  ********************************************************************************/
181 #if INLINE_FUNCTIONS
182 inline bool is_num(cell *c) { return c->type == TYPE_NUM; }
183 inline bool is_str(cell *c) { return c->type == TYPE_STR; }
184 inline bool is_cons(cell *c) { return c->type == TYPE_CONS; }
185 inline bool is_keyword(cell *c) { return c->type == TYPE_KEYWORD; }
186 inline bool is_sym(cell *c) {
187  return c->type == TYPE_SYM || c->type == TYPE_BUILTINLAMBDA ||
188  c->type == TYPE_BUILTINMACRO || c->type == TYPE_KEYWORD;
189 }
190 inline bool is_builtin(cell *c) {
191  return c->type == TYPE_BUILTINLAMBDA || c->type == TYPE_BUILTINMACRO;
192 }
193 inline bool is_builtin_lambda(cell *c) { return c->type == TYPE_BUILTINLAMBDA; }
194 inline bool is_builtin_macro(cell *c) { return c->type == TYPE_BUILTINMACRO; }
195 #else
196 bool is_num(cell *c);
197 bool is_str(cell *c);
198 bool is_cons(cell *c);
199 bool is_sym(cell *c);
200 bool is_keyword(cell *c);
201 bool is_builtin(cell *c);
202 bool is_builtin_lambda(cell *c);
203 bool is_builtin_macro(cell *c);
204 #endif
205 cell *is_symbol_builtin_lambda(char *symbol);
206 cell *is_symbol_builtin_macro(char *symbol);
207 bool cell_is_in_global_env(cell *global_env, cell *c);
208 
209 /********************************************************************************
210  * CELL PROTECTION
211  ********************************************************************************/
212 
213 #if INLINE_FUNCTIONS
214 inline void cell_push(cell *val) {
215 #if COLLECT_GARBAGE
216  val->marks++;
217 #endif
218 }
219 
220 inline void cell_remove(cell *val) {
221 #if COLLECT_GARBAGE
222  if (!val || is_builtin(val))
223  return;
224  if (val->marks > 0)
225  val->marks--;
226 #endif
227 }
228 #else
229 void cell_push(cell *val);
230 void cell_remove(cell *val);
231 #endif
232 void cell_push_recursive(cell *c); // mark as used
233 void cell_remove_recursive(cell *c);
234 void cell_remove_args(cell *args);
235 void cell_remove_pairlis(cell *new_env, cell *old_env);
236 void cell_remove_cars(cell *list);
237 void cell_remove_pairlis_deep(cell *new_env, cell *old_env);
238 
239 /********************************************************************************
240  * CORE OF THE GC
241  ********************************************************************************/
242 
243 void collect_garbage(cell_space *cs);
245 void mark_memory(cell_space *cs);
246 void mark(cell *root);
247 void sweep(cell_space *cs);
248 void deep_sweep(cell_space *cs);
249 
250 #endif // !PICELL_H
void(* bs)(size_t stack_base, unsigned char nargs)
Definition: picell.h:64
struct cell * cdr
car of the cons cell
Definition: picell.h:55
char * sym
Definition: picell.h:58
size_t n_cells
Definition: picell.h:112
void cell_remove(cell *val)
Definition: picell.c:546
cell_block * blocks
Definition: picell.h:116
void cell_space_double_capacity_if_full(cell_space *cs)
Definition: picell.c:201
void collect_garbage(cell_space *cs)
Definition: picell.c:264
cell * global_env
Definition: picell.h:115
size_t n_free_cells
Definition: picell.h:113
bool is_builtin_macro(cell *c)
Definition: picell.c:538
cell * mk_num(int n)
Definition: picell.c:503
Definition: picell.h:31
void cell_space_init(cell_space *cs)
Definition: picell.c:178
size_t block_size
Definition: picell.h:100
cell * is_symbol_builtin_macro(char *symbol)
Definition: picell.c:38
unsigned long marks
1 if marked in the "mark" phase of the gc
Definition: picell.h:47
cell * mk_builtin_macro(char *symbol, cell *(*function)(cell *, cell *))
Definition: picell.c:100
cell * list(cell *args)
Definition: pibuiltin.c:389
char * str
value of the num cell
Definition: picell.h:50
Definition: picell.h:28
bool is_builtin_lambda(cell *c)
Definition: picell.c:537
void cell_space_mark_cell_as_free(cell_space *cs, cell *c)
Definition: picell.c:358
cell * cell_space_get_cell(cell_space *cs)
Definition: picell.c:238
bool is_sym(cell *c)
Definition: picell.c:530
size_t cell_space_size
Definition: picell.h:110
void cell_remove_recursive(cell *c)
Definition: picell.c:389
Definition: picell.h:109
cell * cdr(cell *c)
Definition: pibuiltin.c:982
size_t stack_pointer
Definition: picell.h:91
void cell_remove_cars(cell *list)
Definition: picell.c:475
cell_space * memory
Definition: picell.h:119
cell * copy_cell(cell *c)
Definition: picell.c:115
cell * mk_str(char *s)
Definition: picell.c:510
void cell_push(cell *val)
Definition: picell.c:540
bool is_num(cell *c)
Definition: picell.c:526
bool is_builtin(cell *c)
Definition: picell.c:534
void init_memory()
Definition: picell.c:262
void cell_remove_pairlis(cell *new_env, cell *old_env)
Definition: picell.c:463
cell * mk_builtin_lambda(char *symbol, cell *(*function)(cell *), void(*builtin_stack)(size_t, unsigned char))
Definition: picell.c:84
void mark(cell *root)
Definition: picell.c:307
void cell_block_free(cell_block *cb)
Definition: picell.c:427
unsigned char type
Definition: picell.h:45
void cell_remove_pairlis_deep(cell *new_env, cell *old_env)
Definition: picell.c:485
cell_space * cell_space_create()
Definition: picell.c:191
cell * car(cell *c)
Definition: pibuiltin.c:972
void cell_push_recursive(cell *c)
Definition: picell.c:372
cell * env(cell *arg)
Definition: pibuiltin.c:907
Basic Lisp entity.
Definition: picell.h:44
void cell_space_grow(cell_space *cs)
Definition: picell.c:211
bool cell_is_in_global_env(cell *global_env, cell *c)
Definition: picell.c:440
cell * is_symbol_builtin_lambda(char *symbol)
Definition: picell.c:26
Definition: picell.h:27
Definition: picell.h:26
Definition: picell.h:29
unsigned char marked
type of the cell referred to the type enum
Definition: picell.h:46
void mark_memory(cell_space *cs)
Definition: picell.c:290
Definition: picell.h:25
cell * first_free
Definition: picell.h:114
cell * get_cell()
Definition: picell.c:501
void cell_remove_args(cell *args)
Definition: picell.c:452
struct cell * next_free_cell
string of the string cell
Definition: picell.h:51
cell * block
Definition: picell.h:101
cell * mk_sym(char *symbol)
Definition: picell.c:50
#define STACK_LIMIT
Max dimension of the stack.
Definition: pisettings.h:109
Definition: picell.h:34
bool cell_space_is_full(cell_space *cs)
Definition: picell.c:197
cell * cell_space_is_symbol_allocated(cell_space *cs, char *symbol)
Definition: picell.c:8
cell * mk_cons(cell *car, cell *cdr)
Definition: picell.c:518
bool is_cons(cell *c)
Definition: picell.c:528
struct cell * car
Definition: picell.h:54
bool is_str(cell *c)
Definition: picell.c:527
struct cell cell
Basic Lisp entity.
cell_block * cell_block_create(size_t s)
Definition: picell.c:155
void unsafe_cell_remove(cell *c)
Definition: picell.c:499
void deep_collect_garbage(cell_space *cs)
Definition: picell.c:283
bool is_keyword(cell *c)
Definition: picell.c:529
void cell_space_free(cell_space *cs)
Definition: picell.c:417
represents a builtin lisp function (e.g. car, cdr...)
Definition: picell.h:32
void deep_sweep(cell_space *cs)
Definition: picell.c:336
size_t cell_space_capacity
Definition: picell.h:111
void free_cell_pointed_memory(cell *c)
Definition: picell.c:142
void sweep(cell_space *cs)
Definition: picell.c:317
Definition: picell.h:99
cell * stack[STACK_LIMIT]
Definition: picell.h:92
int value
Definition: picell.h:49
void free_memory()
Definition: picell.c:438