First NIT release and new clean mercurial repository
[nit.git] / lib / nit_common.h
1 #ifndef NIT_COMMON_H
2 #define NIT_COMMON_H
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 /* *** Types *** */
9 typedef int (*fun_t)(int); /* generic function pointer */
10 typedef unsigned int cid_t; /* class identifier */
11 typedef unsigned long int val_t; /* value (everything is a val_t) */
12 typedef union obj_tu {union classtable_elt_tu * vft; val_t attr;} *obj_t; /* standard object */
13 typedef union classtable_elt_tu { int i; fun_t f; cid_t cid;} classtable_elt_t; /* classtable element */
14
15 typedef classtable_elt_t * classtable_t; /* classtable */
16
17 /*****************************************************************************
18 * Types macros (primitive and less primitives) ******************************
19 *****************************************************************************
20 *
21 * ** types are: **
22 *
23 * OBJ (obj_t) : standard object representation (including boxes + NIL)
24 * Int (int) : integers
25 * Char (car) : characters
26 * Bool (int) : booleans (true or false)
27 *
28 * X (x_t) : generic representatio of the previous four types
29 *
30 * ** macros are: **
31 *
32 * int ISX(val_t v) : true if v is a X
33 * x_t VAL2X(val_t v) : convert a val_t to a primitive type (you should check ISX before)
34 * val_t X2VAL(x_t x) : convert a type to a val_t
35 * int XTAG : numeric identifier of a type
36 * int TAG(val_t v) : return the XTAG (ie TAG(Char2VAL('e')) == CharTag)
37 *
38 * classtable_t VAL2VFT(val_t v): the virtual function table of a value
39 *
40 * val_t NIT_NULL : the instance of the None class
41 *****************************************************************************/
42
43 #define TAG(x) ((int)(x) & 3)
44 #ifndef IntTAG
45 # define IntTAG 1
46 #endif
47 #define TAG_Int(x) ((val_t)(((x)<<2)|IntTAG))
48 #define UNTAG_Int(x) ((int)(x)>>2)
49 #ifndef CharTAG
50 # define CharTAG 2
51 #endif
52 #define TAG_Char(x) ((val_t)((((int)(x))<<2)|CharTAG))
53 #define UNTAG_Char(x) ((char)((int)(x)>>2))
54 #ifndef BoolTAG
55 # define BoolTAG 3
56 #endif
57 #define TAG_Bool(x) ((val_t)(((x)<<2)|BoolTAG))
58 #define UNTAG_Bool(x) ((int)(x)>>2)
59 #ifndef OBJTAG
60 # define OBJTAG 0
61 #endif
62
63 #define ISOBJ(x) (TAG((x)) == OBJTAG)
64 #define VAL2OBJ(x) ((obj_t)(x))
65 #define OBJ2VAL(o) ((val_t)(o))
66 #define VAL2VFT(x) (ISOBJ(x) ? VAL2OBJ(x)->vft : TAG2VFT[TAG(x)])
67 /*#define VAL2CID(x) (ISOBJ(x) ? (VAL2OBJ(x)->vft->cid) : (-TAG(x)))*/
68 #define VAL2CID(x) (VAL2OBJ(x)->vft->cid)
69
70 #define NIT_NULL ((val_t)0)
71 #define ISNULL(x) ((x)==NIT_NULL)
72
73 /* Equal comparaison */
74 /* O = Non nil object ; N = Object or nil ; P = Primitive */
75 #define OBJ_IS_BOX(x) ((VAL2OBJ(x)->vft->i) < 0)
76 #define IS_BOX(x) (ISOBJ(x) && OBJ_IS_BOX(x))
77 #define IS_EQUAL_BOX(x, y) (ISOBJ(y) && (VAL2OBJ(x)[1].vft==VAL2OBJ(y)[1].vft) && (VAL2OBJ(x)->vft==VAL2OBJ(y)->vft))
78 #define IS_EQUAL_OO(x, y) ((x)==(y) || (IS_BOX(x) && IS_EQUAL_BOX((x), (y))))
79 #define IS_EQUAL_ON(x, y) ((x)==(y) || (IS_BOX(x) && !ISNULL(y) && IS_EQUAL_BOX((x), (y))))
80 #define IS_EQUAL_NN(x, y) ((x)==(y) || (!ISNULL(x) && IS_BOX(x) && !ISNULL(y) && IS_EQUAL_BOX((x), (y))))
81
82 /* Subclass comparaison */
83 /* check is e is a subtype of c2 */
84 /* Warning, only subclasse comparaison is performed, not subtype */
85 /* e is a val (not nil) */
86 /* c a class name (eg: Int) */
87 #define VALISA(e, c) (VAL2VFT(e)[COLOR_ ## c].cid == (cid_t) ID_ ## c)
88 #define OBJISA(e, c) (VAL2OBJ(e)->vft[COLOR_ ## c].cid == (cid_t) ID_ ## c)
89
90 #define VAL_ISA(e, c, i) (VAL2VFT((e))[(c)].cid == (cid_t)(i))
91
92 void * alloc(size_t);
93 extern val_t G_args;
94 extern val_t G_stdin;
95 extern val_t G_stdout;
96 extern val_t G_stderr;
97 extern val_t G_sys;
98
99 extern int glob_argc;
100 extern char ** glob_argv;
101
102 struct trace_t {
103 struct trace_t *prev;
104 const char *text;
105 };
106 extern struct trace_t *tracehead;
107 typedef enum {true = (1==1),false = (0==1)} bool;
108
109 void nit_exit(int);
110
111 #define CALL(r,c) ((VAL2VFT(r)[c].f))
112 #define ATTR(r,c) (*(val_t*)(VAL2OBJ(r)+c))
113 #define ATTRS(r,c,o) ((VAL2OBJ(r)+VAL2VFT(r)[c].i)[o].attr)
114
115 void prepare_signals(void);
116 extern classtable_t TAG2VFT[4];
117 #endif