summaryrefslogtreecommitdiff
path: root/uscript/val.h
diff options
context:
space:
mode:
Diffstat (limited to 'uscript/val.h')
-rw-r--r--uscript/val.h102
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__