ma_obj.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  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 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 *p;
  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 for other type
  69. * of values like numbers, booleans, and function/void pointers, do a
  70. * copy by value.
  71. */
  72. #define copy(v1, v2) set_val(v1, v2->val, v2->type)
  73. /*
  74. * Defines all the possible standard types of a value, V_TYPE_OBJ is
  75. * also a value. A value 'v' is an object if the MSB of its $type 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 value 'v' 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 /* variant: O_TYPEV_CCLASS */
  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 /* variant: O_TYPEV_CLOSURE */
  150. #define O_TYPE_MA 11 /* variants: O_TYPEV_CO, O_TYPEV_WORK */
  151. #define O_TYPE_RBQ 12 /* variants: O_TYPEV_CHAN, O_TYPEV_SCHEDQ */
  152. #define O_TYPE_REGEX 13
  153. #define O_TYPE_SOCKET 14
  154. #define O_TYPE_PIPE 15
  155. #define O_TYPE_FILE 16
  156. #define O_TYPE_DIR 17
  157. #define O_TYPE_PROC 18
  158. #define O_TYPE_SYS 19
  159. #define O_TYPE_DATE 20
  160. #define O_TYPE_PKG 21
  161. #define O_TYPE_TERM 22
  162. #define O_DEADKEY 31 /* */
  163. /* A Check macro on 'v' for each object type */
  164. #define is_class(v) o_check_type(v, O_TYPE_CLASS)
  165. #define is_str(v) o_check_type(v, O_TYPE_STR)
  166. #define is_range(v) o_check_type(v, O_TYPE_RANGE)
  167. #define is_array(v) o_check_type(v, O_TYPE_ARRAY)
  168. #define is_map(v) o_check_type(v, O_TYPE_MAP)
  169. #define is_fun(v) o_check_type(v, O_TYPE_FUN)
  170. #define is_ma(v) o_check_type(v, O_TYPE_MA)
  171. #define is_rbq(v) o_check_type(v, O_TYPE_RBQ)
  172. #define is_regex(v) o_check_type(v, O_TYPE_REGEX)
  173. #define is_socket(v) o_check_type(v, O_TYPE_SOCKET)
  174. #define is_pipe(v) o_check_type(v, O_TYPE_PIPE)
  175. #define is_file(v) o_check_type(v, O_TYPE_FILE)
  176. #define is_dir(v) o_check_type(v, O_TYPE_DIR)
  177. #define is_proc(v) o_check_type(v, O_TYPE_PROC)
  178. #define is_date(v) o_check_type(v, O_TYPE_DATE)
  179. #define is_term(v) o_check_type(v, O_TYPE_TERM) /* See term.h */
  180. /* Test if the value 'v' is an object variant of variant type 't' */
  181. #define o_check_vartype(v,t) is_obj(v) && check_vartype(v,t)
  182. /* Here are variants of some standard objects */
  183. /*
  184. * Cclass--a special way of extending Maat code with C/C++, here
  185. * we store references to C/C++ functions as methods and structs
  186. * as attributes.
  187. */
  188. #define O_TYPEV_CCLASS vary(O_TYPE_CLASS, 1)
  189. #define is_cclass(v) o_check_vartype(v, O_TYPEV_CCLASS)
  190. /* Immutable and mutable bags */
  191. #define O_TYPEV_BAG vary(O_TYPE_MAP, 1)
  192. #define O_TYPEV_MBAG vary(O_TYPE_MAP, 2)
  193. #define is_bag(v) o_check_vartype(v, O_TYPEV_BAG)
  194. #define is_mbag(v) o_check_vartype(v, O_TYPEV_MBAG)
  195. /* Comma-separated list of values, immutable and mutable sets */
  196. #define O_TYPEV_LIST vary(O_TYPE_ARRAY, 1)
  197. #define O_TYPEV_SET vary(O_TYPE_ARRAY, 2)
  198. #define O_TYPEV_MSET vary(O_TYPE_ARRAY, 3)
  199. #define is_list(v) o_check_type(v, O_TYPE_LIST)
  200. #define is_set(v) o_check_vartype(v, O_TYPEV_SET)
  201. #define is_mset(v) o_check_vartype(v, O_TYPEV_MSET)
  202. /* A closure, it encapsulates upvalues */
  203. #define O_TYPEV_CLOSURE vary(O_TYPE_FUN, 1)
  204. #define is_closure(v) o_check_vartype(v, O_TYPEV_CLOSURE)
  205. /* Two other concurrency models: Coroutine, Work */
  206. #define O_TYPEV_CO vary(O_TYPE_CMA, 1)
  207. #define O_TYPEV_WORK vary(O_TYPE_CMA, 2)
  208. /* A threadsafe Channel and Scheduler queue */
  209. #define O_TYPEV_CHAN vary(O_TYPE_RBQ, 1)
  210. #define O_TYPEV_SCHEDQ vary(O_TYPE_RBQ, 2)
  211. #define is_chan(v) o_check_type(v, O_TYPEV_CHAN)
  212. #define is_schedq(v) o_check_type(v, O_TYPEV_SCHEDQ)
  213. /*
  214. * What? string object
  215. * $str: utf-8 encoded string itself
  216. * $hash: hash value of $str
  217. * $rlen: real length of $str
  218. * $len: user-percieved length of $str
  219. */
  220. typedef struct {
  221. Header obj;
  222. unsigned int hash;
  223. size_t rlen;
  224. size_t len;
  225. Byte str[1];
  226. } Str;
  227. /*
  228. * What? Range object [x..y] (inclusive)
  229. * $x: the start
  230. * $y: and the end
  231. */
  232. typedef struct {
  233. Header obj;
  234. Num x;
  235. Num y;
  236. } Range;
  237. /*
  238. */
  239. typedef struct {
  240. Header obj;
  241. } Map;
  242. /*
  243. * $is: class' superclasses (Maat implements C3 mro)
  244. * $name: class name
  245. * $n: number of fields(Class)/cdatas(Cclass)
  246. * $methods: a Map for methods
  247. */
  248. #define x ...
  249. typedef struct Class {
  250. Header obj;
  251. Str *name;
  252. union {
  253. struct Class *c3_list;
  254. Value *cdatas;
  255. } sc;
  256. Ubyte n;
  257. Map *methods;
  258. } Class;
  259. /*
  260. * What? Instance of a class
  261. * $fields: (C)?class' attributes/cdata
  262. */
  263. typedef struct {
  264. Header obj;
  265. Value *fields;
  266. } Instance;
  267. typedef struct Ma {
  268. } Ma;
  269. typedef struct {
  270. Ma ma;
  271. } Work;
  272. /*
  273. */
  274. typedef struct {
  275. Header obj;
  276. //...
  277. } Fun;
  278. /*
  279. */
  280. typedef struct Upvalue {
  281. Header obj;
  282. Value *to;
  283. union {
  284. struct Upvalue *next;
  285. Value val;
  286. } state;
  287. } Upvalue;
  288. #endif