ma_obj.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Abstract: Defining objects and values
  3. * License: AGL, see LICENSE file for copyright and license details.
  4. */
  5. #ifndef ma_obj_h
  6. #define ma_obj_h
  7. #include "ma_conf.h"
  8. /*
  9. * Macros defined below are both used to manipulate objects and
  10. * non NAN-TAGGING represented values, reason why they aren't
  11. * specific to `#if` body of the MA_NAN_TAGGING check.
  12. */
  13. /* Vary type 't' with the variant bits 'v', see Value */
  14. #define vary(t, v) ((t) | (v << 5))
  15. #define with_variant(v) ((v)->type & 0x7F)
  16. #define without_variant(v) ((v)->type & 0x1F)
  17. #define check_type(v, t) (without_variant(v) == t)
  18. #define check_vartype(v, t) (with_variant(v) == t)
  19. /* Get top level value type of 'v' */
  20. #define vtype(v) with_variant(v)
  21. /* value 'o' is an object and get its object type */
  22. #define otype(o) with_variant(as_obj(v))
  23. /* Get profound type of 'v': dig into 'v' if it's an object */
  24. #define type(v) (ma_likely(is_obj(v)) ? otype(v) : vtype(v))
  25. #if !defined(MA_NAN_TAGGING)
  26. /*
  27. * $val: the value itself.
  28. * $n: representation of a number (see 'ma_conf.h').
  29. * $obj: pointer to an object, here, $val is an object.
  30. *
  31. * The below attributes are used to extend Maat code with C/C++:
  32. *
  33. * $cdata: pointer to C-class attributes('struct's).
  34. * $f: pointer to a C function, either represent a cdata's
  35. * method or just a standalone function.
  36. *
  37. * $type: determines $val's type, its bits are segmented into three
  38. * parts. This variable already gathers all what is necessary to
  39. * represent booleans and nils values.
  40. *
  41. * Bits distribution:
  42. *
  43. * - bits 0-4:
  44. * to represent the different types of values except for object
  45. * values which is determined by the MSB. If $val is an object
  46. * then bits 0-4 determine its object's type. This gives us a
  47. * maximum of 32 objects which suffices.
  48. *
  49. * - bits 5-6:
  50. * to represent variants of certain (O_)?TYPE_.* types. You can
  51. * have at most 3 variants for each base type which suffices.
  52. *
  53. * - bit 7: Mark bit: if 1 then $val is an object, 0 otherwise.
  54. */
  55. typedef struct {
  56. Ubyte type;
  57. union {
  58. struct Header *obj;
  59. Num n;
  60. CFunc f;
  61. void *cdata;
  62. } val;
  63. } Value;
  64. #define set_type(v, t) ((v)->type = t)
  65. #define set_val(v, val, t) set_type(v, t); ((v)->val = val);
  66. #define set_valo(v, o) set_val(v, o, (o)->type)
  67. /*
  68. * For objects, copy by reference v2 into v1 while
  69. * for non objects (numbers, etc), copy by value.
  70. */
  71. #define copy(v1, v2) set_val(v1, v2->val, v2->type)
  72. /*
  73. * All the possible standard types of a value, look! V_TYPE_OBJ
  74. * is also one. A value 'v' is an object if the MSB of its $type
  75. * is 1.
  76. */
  77. #define V_TYPE_NIL 0
  78. #define V_TYPE_BOOL 1
  79. #define V_TYPE_NUM 2
  80. #define V_TYPE_CFUNC 3
  81. #define V_TYPE_CDATA 4
  82. #define OBJ_BIT (0b1 << 7)
  83. #define is_obj(v) (type(v) & OBJ_BIT)
  84. #define is_num(v) check_type(v, V_TYPE_NUM)
  85. #define is_nil(v) check_type(v, V_TYPE_NIL)
  86. #define is_bool(v) check_type(v, V_TYPE_BOOL)
  87. #define is_cfunc(v) check_type(v, V_TYPE_CFUNC)
  88. #define is_cdata(v) check_type(v, V_TYPE_CDATA)
  89. /* Check if a value is collectable */
  90. #define is_ctb(v) is_obj(v)
  91. #define as_bool(v) (is_true(v))
  92. #define as_num(v) ((v)->val.n)
  93. #define as_obj(v) ((v)->val.obj)
  94. #define as_cfunc(v) ((v)->val.f)
  95. #define as_cdata(v) ((v)->val.cdata)
  96. /*
  97. * Define variants of the 'nil' type and its singleton values.
  98. *
  99. * V_TYPEV_FREE: this nil variant differentiates a key whose
  100. * corresponding value is a user-perceived 'nil' from a free
  101. * position in a hash table.
  102. *
  103. * V_TYPEV_ABSKEY: when indexing a hash table and key isn't
  104. * found, return a dummy value of type V_TYPEV_ABSKEY.
  105. */
  106. #define V_TYPEV_FREE vary(V_TYPE_NIL, 1)
  107. #define V_TYPEV_ABSKEY vary(V_TYPE_NIL, 2)
  108. #define FREE (Value){ V_TYPEV_FREE, { 0 } }
  109. #define ABSKEY (Value){ V_TYPEV_ABSKEY, { 0 } }
  110. #define is_strict_nil(v) check_vartype(v, V_TYPE_NIL)
  111. #define is_free(v) check_vartype(v, V_TYPEV_NILKEY)
  112. #define is_abskey(v) check_vartype(v, V_TYPEV_ABSKEY)
  113. /* Define boolean type variants with its singleton values */
  114. #define V_TYPEV_TRUE vary(V_TYPE_BOOL,1)
  115. #define V_TYPEV_FALSE vary(V_TYPE_BOOL,2)
  116. #define BOOL (Value){ V_TYPE_BOOL, { 0 } }
  117. #define TRUE (Value){ V_TYPEV_TRUE, { 0 } }
  118. #define FALSE (Value){ V_TYPEV_FALSE, { 0 } }
  119. #define is_false(v) check_vartype(to_bool(v), V_TYPEV_FALSE)
  120. #define is_true(v) check_vartype(to_bool(v), V_TYPEV_TRUE)
  121. #define to_bool(v) (ma_likely(is_bool(v)) ? v : coerce_to_bool(v))
  122. #else
  123. /*
  124. * TODO
  125. */
  126. typedef uint64_t Value;
  127. #endif
  128. /*
  129. * What? Header inherited by all the below objects
  130. * $type: type of the object
  131. * $mark: flag to mark the object during collection
  132. * $class: the object's class
  133. * $next: next obj,to keep track of all objects
  134. */
  135. typedef struct Header {
  136. Ubyte type;
  137. Ubyte mark;
  138. struct Class *class;
  139. struct Header *next;
  140. } Header;
  141. /* Test if the value 'v' is an object of type 't' */
  142. #define o_check_type(v, t) is_obj(v) && check_type(v, t)
  143. /* Defining of all base objects */
  144. #define O_TYPE_CLASS 5
  145. #define O_TYPE_STR 6
  146. #define O_TYPE_RANGE 7
  147. #define O_TYPE_ARRAY 8 /* variants: O_TYPEV_SET, O_TYPEV_MSET, O_TYPEV_LIST */
  148. #define O_TYPE_MAP 9 /* variants: O_TYPEV_BAG, O_TYPEV_MBAG */
  149. #define O_TYPE_FUN 10 /* variants: O_TYPEV_CLOSURE */
  150. #define O_TYPE_CO 12 /* variants: O_TYPEV_MA, O_TYPEV_WORK */
  151. #define O_TYPE_RBQ 13 /* variants: O_TYPEV_CHAN, O_TYPEV_SCHEDQ */
  152. #define O_TYPE_REGEX 14
  153. #define O_TYPE_SOCKET 15
  154. #define O_TYPE_PIPE 16
  155. #define O_TYPE_FILE 17
  156. #define O_TYPE_DIR 18
  157. #define O_TYPE_PROC 19
  158. #define O_TYPE_SYS 20
  159. #define O_TYPE_DATE 21
  160. #define O_TYPE_TERM 22
  161. #define O_DEADKEY 31 /* */
  162. /* A Check macro on 'v' for each object type */
  163. #define is_class(v) o_check_type(v, O_TYPE_CLASS)
  164. #define is_str(v) o_check_type(v, O_TYPE_STR)
  165. #define is_range(v) o_check_type(v, O_TYPE_RANGE)
  166. #define is_array(v) o_check_type(v, O_TYPE_ARRAY)
  167. #define is_map(v) o_check_type(v, O_TYPE_MAP)
  168. #define is_fun(v) o_check_type(v, O_TYPE_FUN)
  169. #define is_ma(v) o_check_type(v, O_TYPE_MA)
  170. #define is_rbq(v) o_check_type(v, O_TYPE_RBQ)
  171. #define is_regex(v) o_check_type(v, O_TYPE_REGEX)
  172. #define is_socket(v) o_check_type(v, O_TYPE_SOCKET)
  173. #define is_pipe(v) o_check_type(v, O_TYPE_PIPE)
  174. #define is_file(v) o_check_type(v, O_TYPE_FILE)
  175. #define is_dir(v) o_check_type(v, O_TYPE_DIR)
  176. #define is_proc(v) o_check_type(v, O_TYPE_PROC)
  177. #define is_date(v) o_check_type(v, O_TYPE_DATE)
  178. #define is_term(v) o_check_type(v, O_TYPE_TERM) /* See term.h */
  179. /* Test if the value 'v' is an object variant of variant type 't' */
  180. #define o_check_vartype(v,t) is_obj(v) && check_vartype(v,t)
  181. /* Here are variants of some base objects */
  182. /* Immutable and mutable bags */
  183. #define O_TYPEV_BAG vary(O_TYPE_MAP, 1)
  184. #define O_TYPEV_MBAG vary(O_TYPE_MAP, 2)
  185. #define is_bag(v) o_check_vartype(v, O_TYPEV_BAG)
  186. #define is_mbag(v) o_check_vartype(v, O_TYPEV_MBAG)
  187. /* Comma-separated list of values, immutable and mutable sets */
  188. #define O_TYPEV_LIST vary(O_TYPE_ARRAY, 1)
  189. #define O_TYPEV_SET vary(O_TYPE_ARRAY, 2)
  190. #define O_TYPEV_MSET vary(O_TYPE_ARRAY, 3)
  191. #define is_list(v) o_check_type(v, O_TYPE_LIST)
  192. #define is_set(v) o_check_vartype(v, O_TYPEV_SET)
  193. #define is_mset(v) o_check_vartype(v, O_TYPEV_MSET)
  194. /* A closure, it encapsulates upvalues */
  195. #define O_TYPEV_CLOSURE vary(O_TYPE_FUN, 1)
  196. #define is_closure(v) o_check_vartype(v, O_TYPEV_CLOSURE)
  197. #define O_TYPEV_MA vary(O_TYPE_CMA, 1)
  198. #define O_TYPEV_GFUN vary(O_TYPE_CMA, 1)
  199. #define O_TYPEV_MA vary(O_TYPE_CMA, 1)
  200. /* A threadsafe Channel and Scheduler queue */
  201. #define O_TYPEV_CHAN vary(O_TYPE_RBQ, 1)
  202. #define O_TYPEV_SCHEDQ vary(O_TYPE_RBQ, 2)
  203. #define is_chan(v) o_check_type(v, O_TYPEV_CHAN)
  204. #define is_schedq(v) o_check_type(v, O_TYPEV_SCHEDQ)
  205. /*
  206. * What? utf8 string object
  207. * $str: utf8 encoded string itself
  208. * $hash: hash value of $str
  209. * $rlen: real length of $str
  210. * $len: user-percieved length of $str
  211. */
  212. typedef struct {
  213. Header obj;
  214. Uint hash;
  215. size_t rlen;
  216. size_t len;
  217. Byte str[1];
  218. } Str;
  219. /*
  220. * What? Range object x..y
  221. * $x: the start (inclusive)
  222. * $y: the end (inclusive)
  223. */
  224. typedef struct {
  225. Header obj;
  226. Num x, y;
  227. } Range;
  228. typedef struct {
  229. Header obj;
  230. } Map;
  231. /*
  232. * $super: class' superclasses (C3 mro)
  233. * $name: class name
  234. * $nfields: number of fields
  235. * $methods: a Map for methods
  236. */
  237. typedef struct Class {
  238. Header obj;
  239. struct Class *super[1];
  240. Str *name;
  241. Ubyte nfields;
  242. Map *methods[1];
  243. } Class;
  244. /*
  245. */
  246. typedef struct {
  247. Header obj;
  248. //...
  249. } Fun;
  250. /*
  251. */
  252. typedef struct Upvalue {
  253. Header obj;
  254. Value *to;
  255. union {
  256. struct Upvalue *next;
  257. Value val;
  258. } state;
  259. } Upvalue;
  260. #endif