#ifndef _val_h #define _val_h #include #include #include typedef struct _val Val; typedef struct _obj Obj; typedef struct _state State; typedef Val (*CFunc)(State *S, int nargs, Val *args); typedef enum { TY_NIL, TY_NUM, TY_BOOL, TY_OBJ, TY_CFUNC, } ValTy; typedef struct _val { ValTy ty; union { double d; bool b; Obj *o; CFunc f; } as; } Val; void print_val(Val v); void println_val(Val v); const char *typename_str(Val v); bool is_truthy(Val v); bool val_equal(Val a, Val b); // ValTy or ObjTy int val_type(Val v); typedef enum { OTY_STRING = 100, OTY_FUNC, OTY_ARR, } ObjTy; typedef struct _obj { ObjTy oty; } Obj; typedef struct { Obj obj; size_t len; uint32_t hash; char *d; } ObjString; #include "chunk.h" // Constructs a new objstring from the given C string, // creating its own fresh copy of the data. ObjString *objstring_copy(State *S, char *src, size_t len); ObjString *objstring_copy_cstr(State *s, char *str); // Constructs a new objstring from the given C string, // taking ownership of the provided data. ObjString *objstring_take(State *S, char *src, size_t len); typedef struct { Obj obj; Chunk ch; uint8_t arity; } ObjFunc; ObjFunc *objfunc_new(State *S, uint8_t arity); typedef struct { Obj obj; size_t len; size_t cap; Val *d; } ObjArr; ObjArr *objarr_new(State *S); Val objarr_get(State *S, ObjArr *arr, size_t ix); void objarr_append(State *S, ObjArr *arr, Val v); void objarr_put(State *S, ObjArr *arr, size_t ix, Val v); void objarr_insert(State *S, ObjArr *arr, size_t ix, Val v); #define IS_NIL(x) (x.ty == TY_NIL) #define IS_NUM(x) (x.ty == TY_NUM) #define IS_BOOL(x) (x.ty == TY_BOOL) #define IS_OBJ(x) (x.ty == TY_OBJ) #define IS_CFUNC(x) (x.ty == TY_CFUNC) #define IS_STRING(x) (is_obj_ty((x), OTY_STRING)) #define IS_FUNC(x) (is_obj_ty((x), OTY_FUNC)) #define IS_ARR(x) (is_obj_ty((x), OTY_ARR)) #define AS_NUM(x) (x.as.d) #define AS_BOOL(x) (x.as.b) #define AS_OBJ(x) (x.as.o) #define AS_CFUNC(x) (x.as.f) #define AS_STRING(x) ((ObjString*)AS_OBJ(x)) #define AS_CSTRING(x) (AS_STRING(x)->d) #define AS_FUNC(x) ((ObjFunc*)AS_OBJ(x)) #define AS_ARR(x) ((ObjArr*)AS_OBJ(x)) #define VAL_NIL ((Val){.ty=TY_NIL}) #define VAL_NUM(x) ((Val){.ty=TY_NUM, .as.d=(x) }) #define VAL_BOOL(x) ((Val){.ty=TY_BOOL, .as.b=(x) }) #define VAL_TRUE VAL_BOOL(1) #define VAL_FALSE VAL_BOOL(0) #define VAL_OBJ(x) ((Val){.ty=TY_OBJ, .as.o=(Obj*)(x) }) #define VAL_CFUNC(x) ((Val){.ty=TY_CFUNC, .as.f=(CFunc)(x)}) static inline bool is_obj_ty(Val v, ObjTy t) { return IS_OBJ(v) && (AS_OBJ(v)->oty == t); } #endif