the hito embeddable programming language
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}