diff options
Diffstat (limited to 'uscript/val.h')
| -rw-r--r-- | uscript/val.h | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/uscript/val.h b/uscript/val.h new file mode 100644 index 0000000..1c314e4 --- /dev/null +++ b/uscript/val.h @@ -0,0 +1,102 @@ +#ifndef __USCRIPT_VAL_H__ +#define __USCRIPT_VAL_H__ + +#include "common.h" + +#define get_num(v) (v.dat.number) +#define get_bool(v) (v.dat.boolean) +#define get_obj(v) (v.dat.obj) +#define get_str(v) (v.dat.str) +#define get_proto(v) (v.dat.proto) +#define get_func(v) (v.dat.func) +#define get_upval(v) (v.dat.upval) + +#define create_num(n) ((struct us_val){.type=VAL_NUM, .dat={.number=(n)}}) +#define create_bool(b) ((struct us_val){.type=VAL_BOOL, .dat={.boolean=(b)}}) +#define create_zilch() ((struct us_val){.type=VAL_ZILCH, .dat={.number=0}}) +#define wrap_str(o) ((struct us_val){.type=VAL_STR, .dat={.str=(o)}}) +#define wrap_proto(o) ((struct us_val){.type=VAL_PROTO, .dat={.proto=(o)}}) +#define wrap_func(o) ((struct us_val){.type=VAL_FUNC, .dat={.func=(o)}}) +#define wrap_upval(o) ((struct us_val){.type=VAL_UPVAL, .dat={.upval=(o)}}) + +#define val_is_obj(v) (v.type >= VAL_STR) + +#define proto_add_byte(func, op) da_append(u8, &(func)->bytecode, op) + +enum val_type { + VAL_NUM, + VAL_BOOL, + VAL_ZILCH, + // Do not place any new object types before VAL_STR. Object types are + // detected by doing a comparison with VAL_STR. See val_is_obj(). + VAL_STR, + VAL_PROTO, + VAL_FUNC, + VAL_UPVAL, +}; + +struct us_val { + enum val_type type; + union { + double number; + bool boolean; + struct us_obj *obj; + struct us_str *str; + struct us_proto *proto; + struct us_func *func; + struct us_upval *upval; + } dat; +}; + +struct us_obj { + // We don't need the object header for now; it will be useful in the + // future, though. + u8 _placeholder; +}; + +struct us_str { + struct us_obj header; + char *chars; + size_t len; +}; + +struct us_proto { + struct us_obj header; + const struct us_str *name; + struct us_val constants[UINT8_MAX]; + u8 *bytecode; // dyn_arr + int* upval_locs; + int upvalc; + int argc; + bool is_variadic; + u8 nconstants; +}; + +struct us_func { + struct us_obj header; + struct us_proto *proto; + struct us_upval **upvals; +}; + +struct us_upval { + struct us_obj header; + struct us_val *loc; + struct us_val closed; + struct us_upval *next; +}; + +struct us_str *take_str(char *chars, int len); +struct us_str *copy_str(const char *chars, int len); +struct us_proto *create_proto(struct us_str *name); +struct us_func *create_func(struct us_proto *proto); +struct us_upval *create_upval(struct us_val *val); + +void free_val(struct us_val v); + +void proto_add_const(struct us_proto *func, struct us_val v); + +bool vals_eql(struct us_val a, struct us_val b); + +char *val_to_str(struct us_val v, int *len_out); + +#endif // __USCRIPT_VAL_H__ |
