-
Notifications
You must be signed in to change notification settings - Fork 2
/
value.h
144 lines (123 loc) · 3.52 KB
/
value.h
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
#ifndef cb_value_h
#define cb_value_h
#include <stdint.h>
#include "gc.h"
#include "str.h"
#include "userdata.h"
#define CB_VALUE_IS_USER_FN(V) ((V)->type == CB_VALUE_FUNCTION \
&& (V)->val.as_function->type == CB_FUNCTION_USER)
#define CB_MAX_PARAMS 32
/* It's important that CB_VALUE_NULL is first (i.e. 0). In DO_OP_ALLOCATE_LOCALS
* we memset the stack to 0, which is enabled by this. */
#define CB_VALUE_TYPE_LIST(X) \
X(CB_VALUE_NULL) \
X(CB_VALUE_INT) \
X(CB_VALUE_DOUBLE) \
X(CB_VALUE_BOOL) \
X(CB_VALUE_CHAR) \
X(CB_VALUE_INTERNED_STRING) \
X(CB_VALUE_STRING) \
X(CB_VALUE_BYTES) \
X(CB_VALUE_ARRAY) \
X(CB_VALUE_FUNCTION) \
X(CB_VALUE_STRUCT_SPEC) \
X(CB_VALUE_STRUCT) \
X(CB_VALUE_USERDATA)
enum cb_value_type {
#define COMMA(V) V,
CB_VALUE_TYPE_LIST(COMMA)
#undef COMMA
};
struct cb_upvalue;
struct cb_value;
struct cb_string {
cb_gc_header gc_header;
cb_str string;
};
struct cb_bytes {
cb_gc_header gc_header;
uint8_t data[];
};
enum cb_function_type {
CB_FUNCTION_NATIVE,
CB_FUNCTION_USER,
};
/* FIXME: argv should be const since it points to the stack */
typedef int (cb_native_function)(size_t argc, struct cb_value *argv,
struct cb_value *retval);
struct cb_function_optargs {
size_t count;
size_t addrs[CB_MAX_PARAMS];
};
struct cb_user_function {
size_t address;
struct cb_upvalue **upvalues;
size_t upvalues_size, upvalues_len;
size_t module_id;
size_t nlocals;
size_t stack_required;
struct cb_function_optargs optargs;
};
struct cb_function {
cb_gc_header gc_header;
enum cb_function_type type;
size_t name, arity;
union {
cb_native_function *as_native;
struct cb_user_function as_user;
} value;
};
struct cb_array;
struct cb_value {
enum cb_value_type type;
union {
intptr_t as_int;
double as_double;
int as_bool;
uint32_t as_char;
size_t as_interned_string;
/* heap allocated */
struct cb_string *as_string;
struct cb_array *as_array;
struct cb_function *as_function;
struct cb_struct *as_struct;
struct cb_struct_spec *as_struct_spec;
struct cb_userdata *as_userdata;
struct cb_bytes *as_bytes;
} val;
};
struct cb_array {
cb_gc_header gc_header;
size_t len;
struct cb_value values[];
};
int cb_value_eq(struct cb_value *a, struct cb_value *b);
double cb_value_cmp(struct cb_value *a, struct cb_value *b, int *ok);
cb_str cb_value_to_string(struct cb_value *val);
int cb_value_is_truthy(struct cb_value *val);
void cb_function_add_upvalue(struct cb_user_function *fn,
struct cb_upvalue *uv);
int cb_value_call(struct cb_value fn, struct cb_value *args, size_t args_len,
struct cb_value *result);
int cb_value_is_marked(const struct cb_value *val);
void cb_value_mark(struct cb_value *val);
void cb_value_incref(struct cb_value *val);
void cb_value_decref(struct cb_value *val);
struct cb_function *cb_function_new(void);
struct cb_string *cb_string_new(void);
struct cb_array *cb_array_new(size_t len);
struct cb_value cb_cfunc_new(size_t name, size_t arity,
cb_native_function *func);
size_t cb_ufunc_entry(const struct cb_function *func, size_t num_args);
struct cb_value cb_int(int64_t);
struct cb_value cb_double(double);
struct cb_value cb_bool(int);
struct cb_value cb_char(uint32_t);
struct cb_value cb_value_from_string(const char *str);
struct cb_value cb_value_from_fmt(const char *fmt, ...);
struct cb_bytes *cb_bytes_new(size_t size);
struct cb_value cb_bytes_new_value(size_t size);
const char *cb_value_type_name(enum cb_value_type type);
const char *cb_value_type_of(struct cb_value *val);
const char *cb_value_type_friendly_name(enum cb_value_type typ);
#endif