#ifndef _val_h #define _val_h #include typedef struct _val Val; typedef struct _obj Obj; typedef enum { TY_NIL, TY_NUM, TY_BOOL, TY_OBJ, } ValTy; typedef struct _val { ValTy ty; union { double d; bool b; Obj *o; } as; } Val; void print_val(Val v); void println_val(Val v); const char *valty_str(Val v); typedef enum { OTY_STRING, } ObjTy; typedef struct _obj { ObjTy oty; } Obj; typedef struct { Obj obj; size_t len; char *b; } ObjString; // copies data ObjString *objstring_new(char *src, size_t len); #define IS_NIL(x) (x.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_STRING(x) (is_obj_ty((x), OTY_STRING)) #define AS_NUM(x) (x.as.d) #define AS_BOOL(x) (x.as.b) #define AS_OBJ(x) (x.as.o) #define AS_STRING(x) ((ObjString*)AS_OBJ(x)) #define AS_CSTRING(x) (AS_STRING(x)->b) #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_OBJ(x) ((Val){.ty=TY_OBJ, .as.o=(Obj*)(x) }) static inline bool is_obj_ty(Val v, ObjTy t) { return IS_OBJ(v) && (AS_OBJ(v)->oty == t); } #endif