the hito embeddable programming language
at main 80 lines 2.0 kB view raw
1#include "env.h" 2 3#include "bitset.h" 4#include "util.h" 5#include "value.h" 6#include <stdlib.h> 7#include <string.h> 8#include <assert.h> 9#include <stdio.h> 10 11struct env { 12 value_t **vals; // array of captured values 13 size_t offset; // first index in De Bruijn space 14 size_t length; // number of slots (offset .. last set bit) 15}; 16 17void env_free(env_t *caps) { 18 if (caps) 19 free(caps->vals); 20 free(caps); 21} 22 23void env_mark_values(env_t *caps) { 24 if (caps == NULL) return; 25 for (size_t i = 0; i < caps->length; i++) { 26 if (caps->vals[i] != NULL) value_mark_gc(caps->vals[i]); 27 } 28} 29 30value_t *env_lookup(env_t *env, de_bruijn_t index) { 31 if (env != NULL && index < env->length) 32 return env->vals[index]; 33 else 34 return NULL; 35} 36 37/* ---------------- Capturing variables ---------------- */ 38 39env_t *env_capture(env_t *env, value_t **locals, size_t as_frame, size_t as_top, bitset_t *used) { 40 //printf("BITS:"); 41 //bitset_dump(used); 42 size_t start = 0; 43 size_t first = bitset_next(used, &start); 44 if (first == (size_t)-1) return NULL; // empty capture 45 46 size_t last = bitset_max(used); 47 size_t length = last - first + 1; 48 //printf("first: %zu, last: %zu, length: %zu\n", first,last,length); 49 env_t *caps = malloc(sizeof(env_t)); 50 if (caps == NULL) 51 die("Out of memory: can't allocate captures"); 52 caps->offset = first; 53 caps->length = length; 54 caps->vals = calloc(length, sizeof(value_t*)); // NULL slots by default 55 if (caps->vals == NULL) 56 die("Out of memory: can't allocate captures array"); 57 58 start = first; 59 size_t bit; 60 while ((bit = bitset_next(used, &start)) != (size_t)-1 && bit <= last) { 61 value_t *val = (bit >= as_frame) ? 62 env_lookup(env, bit - as_frame) : 63 locals[as_top - 1 - bit]; 64 caps->vals[bit - first] = val; 65 } 66 67 return caps; 68} 69 70 71void env_debug_dump(env_t *env) { 72 if (!env) 73 return; 74 for (int i = 0; i < env->length; i++) { 75 if (env->vals[i]) { 76 value_debug_dump(env->vals[i]); 77 printf("%zu:", i + env->offset); 78 } 79 } 80}