1 /* Copyright (c) 2003, David Leonard. All rights reserved. */
2 
3 #ifndef _SEE_h_value_
4 #define _SEE_h_value_
5 
6 /*
7  * Values are small units of short-life, typed memory
8  * that contain primitive information, object
9  * references or string references.
10  */
11 
12 #include <math.h>
13 
14 #include <see/type.h>
15 
16 /* if not defined, define NULL as a pointer, not as ANSI C's (0) */
17 #ifndef NULL
18 #define NULL	((void *)0)
19 #endif
20 
21 struct SEE_object;
22 struct SEE_string;
23 struct SEE_value;
24 struct SEE_interpreter;
25 
26 /* Value types */
27 enum SEE_type {
28 	SEE_UNDEFINED,
29 	SEE_NULL,
30 	SEE_BOOLEAN,
31 	SEE_NUMBER,
32 	SEE_STRING,
33 	SEE_OBJECT,
34 	SEE_REFERENCE,			/* internal type (8.7) */
35 	SEE_COMPLETION			/* internal type (8.9) */
36 };
37 
38 /* This structure is not part of the public API and may change */
39 struct _SEE_reference {
40 	struct SEE_object *base;
41 	struct SEE_string *property;
42 };
43 
44 /* This structure is not part of the public API and may change */
45 struct _SEE_completion {
46 	struct SEE_value *value;	/* Return value */
47 	unsigned int target;		/* Throw context or break target */
48 	enum { SEE_COMPLETION_NORMAL,
49 	       SEE_COMPLETION_BREAK,
50 	       SEE_COMPLETION_CONTINUE,
51 	       SEE_COMPLETION_RETURN,
52 	       SEE_COMPLETION_THROW } type;
53 };
54 
55 /* Value storage */
56 struct SEE_value {
57 	enum SEE_type		      _type;
58 	union {
59 		SEE_number_t	      number;
60 		SEE_boolean_t	      boolean;
61 		struct SEE_object    *object;
62 		struct SEE_string    *string;
63 		/* The following members are not part of the public API */
64 		struct _SEE_reference  reference;
65 		struct _SEE_completion completion;
66 		void *_padding[4];
67 	} u;
68 };
69 
70 /* Copy between value storages */
71 #define SEE_VALUE_COPY(dst, src)		\
72 	*(dst) = *(src)
73 
74 /* Obtain the value's type */
75 #define SEE_VALUE_GET_TYPE(v)			\
76 	((v)->_type)
77 
78 /* This macro is not part of the public API and may change */
79 #define _SEE_VALUE_SET_TYPE(v, t)		\
80 	(v)->_type = t
81 
82 /* Fill a value storage with the undefined value */
83 #define SEE_SET_UNDEFINED(v)			\
84 	_SEE_VALUE_SET_TYPE(v, SEE_UNDEFINED)
85 
86 /* Fill a value storage with the null value */
87 #define SEE_SET_NULL(v)				\
88 	_SEE_VALUE_SET_TYPE(v, SEE_NULL)
89 
90 /* Fill a value storage with a boolean value */
91 #define SEE_SET_BOOLEAN(v, b) 			\
92     do {					\
93 	_SEE_VALUE_SET_TYPE(v, SEE_BOOLEAN);	\
94 	(v)->u.boolean = (b);			\
95     } while (0)
96 
97 /* Fill a value storage with a numeric value */
98 #define SEE_SET_NUMBER(v, n) 			\
99     do {					\
100 	_SEE_VALUE_SET_TYPE(v, SEE_NUMBER);	\
101 	(v)->u.number = (n);			\
102     } while (0)
103 
104 /* Fill a value storage with a pointer to a string */
105 #define SEE_SET_STRING(v, s)			\
106     do {					\
107 	_SEE_VALUE_SET_TYPE(v, SEE_STRING);	\
108 	(v)->u.string = (s);			\
109     } while (0)
110 
111 /* Fill a value storage with a pointer to an object */
112 #define SEE_SET_OBJECT(v, o)			\
113     do {					\
114 	_SEE_VALUE_SET_TYPE(v, SEE_OBJECT);	\
115 	(v)->u.object = (o);			\
116     } while (0)
117 
118 /* This macro is not part of the public API and may change */
119 #define _SEE_SET_REFERENCE(v, b, p)		\
120     do {					\
121 	_SEE_VALUE_SET_TYPE(v, SEE_REFERENCE);	\
122 	(v)->u.reference.base = (b);		\
123 	(v)->u.reference.property = (p);	\
124     } while (0)
125 
126 /* This macro is not part of the public API and may change */
127 /* NB: 'val' must NOT be on the stack */
128 #define _SEE_SET_COMPLETION(v, typ, val, tgt)	\
129     do {					\
130 	_SEE_VALUE_SET_TYPE(v, SEE_COMPLETION);	\
131 	(v)->u.completion.type = (typ);		\
132 	(v)->u.completion.value = (val);	\
133 	(v)->u.completion.target = (tgt);	\
134     } while (0)
135 
136 int _SEE_isnan(SEE_number_t n);
137 int _SEE_isfinite(SEE_number_t n);
138 SEE_number_t _SEE_copysign(SEE_number_t x, SEE_number_t y);
139 int _SEE_ispinf(SEE_number_t n);
140 int _SEE_isninf(SEE_number_t n);
141 #define SEE_ISNAN(n)	        _SEE_isnan(n)
142 #define SEE_ISFINITE(n)	        _SEE_isfinite(n)
143 #define SEE_COPYSIGN(x, y)	_SEE_copysign(x, y)
144 #define SEE_ISPINF(n)	        _SEE_ispinf(n)
145 #define SEE_ISNINF(n)	        _SEE_isninf(n)
146 
147 /* Convenience macros for numbers */
148 #define SEE_NUMBER_ISNAN(v)     SEE_ISNAN((v)->u.number)
149 #define SEE_NUMBER_ISFINITE(v)  SEE_ISFINITE((v)->u.number)
150 #define SEE_NUMBER_ISPINF(v)    SEE_ISPINF((v)->u.number)
151 #define SEE_NUMBER_ISNINF(v)    SEE_ISNINF((v)->u.number)
152 
153 /* SEE_ISINF() and SEE_NUMBER_ISINF() are deprecated */
154 #define SEE_ISINF(n)	        (SEE_ISPINF(n) || SEE_ISNINF(n))
155 #define SEE_NUMBER_ISINF(n)	SEE_ISINF((v)->u.number)
156 
157 /* Converters */
158 void SEE_ToPrimitive(struct SEE_interpreter *i,
159 			struct SEE_value *val, struct SEE_value *type,
160 			struct SEE_value *res);
161 void SEE_ToBoolean(struct SEE_interpreter *i, struct SEE_value *val,
162 			struct SEE_value *res);
163 void SEE_ToNumber(struct SEE_interpreter *i, struct SEE_value *val,
164 			struct SEE_value *res);
165 void SEE_ToInteger(struct SEE_interpreter *i, struct SEE_value *val,
166 			struct SEE_value *res);
167 void SEE_ToString(struct SEE_interpreter *i, struct SEE_value *val,
168 			struct SEE_value *res);
169 void SEE_ToObject(struct SEE_interpreter *i, struct SEE_value *val,
170 			struct SEE_value *res);
171 
172 /* Integer converters */
173 SEE_int32_t  SEE_ToInt32(struct SEE_interpreter *i, struct SEE_value *val);
174 SEE_uint32_t SEE_ToUint32(struct SEE_interpreter *i, struct SEE_value *val);
175 SEE_uint16_t SEE_ToUint16(struct SEE_interpreter *i, struct SEE_value *val);
176 
177 /* "0123456789abcdef" */
178 extern char SEE_hexstr_lowercase[16], SEE_hexstr_uppercase[16];
179 
180 #endif /* _SEE_h_value_ */
181