-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathconstant.c
More file actions
155 lines (133 loc) · 3.64 KB
/
constant.c
File metadata and controls
155 lines (133 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <stdio.h>
#include <stdlib.h>
#include "agent.h"
#include "code.h"
#include "constant.h"
#include "struct.h"
#include "value.h"
const char *cb_const_type_name(enum cb_const_type ty)
{
switch (ty) {
#define CASE(TY) case TY: return #TY;
CB_CONST_TYPE_LIST(CASE)
#undef CASE
default:
fprintf(stderr, "Unknown const type %d\n", ty);
abort();
}
}
void cb_const_free(struct cb_const *obj)
{
switch (obj->type) {
case CB_CONST_INT:
case CB_CONST_DOUBLE:
case CB_CONST_CHAR:
case CB_CONST_STRING:
case CB_CONST_STRUCT_SPEC: /* struct spec is GCed */
break;
case CB_CONST_ARRAY: {
struct cb_const_array *arr = obj->val.as_array;
for (unsigned i = 0; i < arr->len; i += 1)
cb_const_free(&arr->elements[i]);
free(arr);
break;
}
case CB_CONST_STRUCT: {
struct cb_const_struct *struct_ = obj->val.as_struct;
for (unsigned i = 0; i < struct_->nfields; i += 1)
cb_const_free(&struct_->fields[i].value);
free(struct_);
break;
}
case CB_CONST_FUNCTION:
free(obj->val.as_function);
break;
case CB_CONST_MODULE:
/* modspec is owned by the VM */
break;
default:
fprintf(stderr, "Unknown const type %d\n", obj->type);
abort();
}
}
struct cb_value cb_const_to_value(const struct cb_const *const_)
{
struct cb_value ret;
switch (const_->type) {
case CB_CONST_INT:
ret.type = CB_VALUE_INT;
ret.val.as_int = const_->val.as_int;
break;
case CB_CONST_DOUBLE:
ret.type = CB_VALUE_DOUBLE;
ret.val.as_double = const_->val.as_double;
break;
case CB_CONST_CHAR:
ret.type = CB_VALUE_CHAR;
ret.val.as_char = const_->val.as_char;
break;
case CB_CONST_STRING:
ret.type = CB_VALUE_INTERNED_STRING;
ret.val.as_interned_string = const_->val.as_string;
break;
case CB_CONST_STRUCT_SPEC:
ret.type = CB_VALUE_STRUCT_SPEC;
ret.val.as_struct_spec = const_->val.as_struct_spec;
break;
case CB_CONST_ARRAY: {
struct cb_const_array *const_array = const_->val.as_array;
struct cb_array *array = cb_array_new(const_array->len);
for (unsigned i = 0; i < const_array->len; i += 1)
array->values[i] = cb_const_to_value(
&const_array->elements[i]);
ret.type = CB_VALUE_ARRAY;
ret.val.as_array = array;
break;
}
case CB_CONST_STRUCT: {
struct cb_const_struct *strct = const_->val.as_struct;
struct cb_struct_spec *spec = cb_struct_spec_new(
cb_agent_intern_string("<anonymous>", 11),
strct->nfields, 0);
/* FIXME: add more efficient way to build struct literal */
for (unsigned i = 0; i < strct->nfields; i += 1)
cb_struct_spec_set_field_name(spec, i,
strct->fields[i].name);
struct cb_struct *struct_val = cb_struct_spec_instantiate(spec);
for (unsigned i = 0; i < strct->nfields; i += 1) {
struct cb_value fieldval = cb_const_to_value(
&strct->fields[i].value);
cb_struct_set_field(struct_val, i, fieldval, NULL);
}
ret.type = CB_VALUE_STRUCT;
ret.val.as_struct = struct_val;
break;
}
case CB_CONST_FUNCTION: {
struct cb_const_user_function *const_func = const_->val
.as_function;
struct cb_function *func = cb_function_new();
func->type = CB_FUNCTION_USER;
func->name = const_func->name;
func->arity = const_func->arity;
func->value.as_user.code = const_func->code;
if (const_func->code->nupvalues) {
func->upvalues = malloc(const_func->code->nupvalues
* sizeof(struct cb_upvalue *));
}
for (int i = 0; i < const_func->code->nupvalues; i += 1)
func->upvalues[i] = NULL;
ret.type = CB_VALUE_FUNCTION;
ret.val.as_function = func;
break;
}
case CB_CONST_MODULE:
fprintf(stderr, "Fatal: Converting const module to value\n");
exit(1);
break;
default:
fprintf(stderr, "Unknown const type %d\n", const_->type);
abort();
}
return ret;
}