1 /* Copyright(C) 2004-2007 Brazil
2 
3   This library is free software; you can redistribute it and/or
4   modify it under the terms of the GNU Lesser General Public
5   License as published by the Free Software Foundation; either
6   version 2.1 of the License, or (at your option) any later version.
7 
8   This library is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   Lesser General Public License for more details.
12 
13   You should have received a copy of the GNU Lesser General Public
14   License along with this library; if not, write to the Free Software
15   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 */
17 #ifndef SEN_QL_H
18 #define SEN_QL_H
19 
20 #ifndef SEN_STORE_H
21 #include "store.h"
22 #endif /* SEN_STORE_H */
23 
24 #ifndef SEN_COM_H
25 #include "com.h"
26 #endif /* SEN_COM_H */
27 
28 #ifndef SEN_CTX_H
29 #include "ctx.h"
30 #endif /* SEN_CTX_H */
31 
32 #ifndef __USE_ISOC99
33 #define __USE_ISOC99
34 #endif /*  __USE_ISOC99 */
35 #include <math.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**** query language ****/
42 
43 #define sen_ql_void          0x10
44 #define sen_ql_object        0x11
45 #define sen_ql_records       0x12
46 #define sen_ql_bulk          0x13
47 #define sen_ql_int           0x14
48 #define sen_ql_time          0x15
49 #define sen_ql_symsnip       0x16
50 #define sen_ql_float         0x17
51 #define sen_ql_snip          0x18
52 #define sen_ql_query         0x19
53 #define sen_ql_op            0x1a
54 #define sen_ql_syntax        0x1b
55 #define sen_ql_proc          0x1c
56 #define sen_ql_promise       0x1d
57 #define sen_ql_closure       0x1e
58 #define sen_ql_continuation  0x1f
59 #define sen_ql_macro         0x20
60 #define sen_ql_index         0x30  /* only used in inv.c */
61 #define sen_ql_list          0x40
62 
63 #define SEN_QL_CO_BEGIN(c) if (c) { switch((c)->last) { case 0:
64 #define SEN_QL_CO_WAIT(c,d) \
65   (c)->last = __LINE__; (c)->data = (d); return NULL;\
66   case __LINE__: (d) = (c)->data;
67 #define SEN_QL_CO_END(c) (c)->last = 0; }}
68 
69 #define SEN_QL_PLACEHOLDER_CHAR '?'
70 
71 #define SEN_QL_SET_MODE(c,m) ((c)->feed_mode = (m))
72 #define SEN_QL_GET_MODE(c) ((c)->feed_mode)
73 #define SEN_QL_GET_STAT(c) ((c)->stat)
74 
75 enum {
76   sen_ql_atonce = 0,
77   sen_ql_step
78 };
79 
80 #define SEN_QL_TOPLEVEL  0x00
81 #define SEN_QL_QUITTING  0x0f
82 #define SEN_QL_EVAL      0x40
83 #define SEN_QL_NATIVE    0x41
84 #define SEN_QL_WAIT_EXPR 0xc0
85 #define SEN_QL_WAIT_ARG  0xc1
86 #define SEN_QL_WAIT_DATA 0xc2
87 
88 #define SEN_QL_WAITINGP(c) ((c)->stat & 0x80)
89 
90 extern sen_obj *sen_ql_nil;  /* special cell representing empty cell */
91 extern sen_obj *sen_ql_t;    /* special cell representing #t */
92 extern sen_obj *sen_ql_f;    /* special cell representing #f */
93 
94 #define NIL sen_ql_nil
95 #define T sen_ql_t
96 #define F sen_ql_f
97 
98 // FIXME : should be private
99 #define SEN_OBJ_ALLOCATED 1
100 #define SEN_OBJ_MARKED 2
101 #define SEN_OBJ_SYMBOL 4
102 #define SEN_OBJ_MARK2  8
103 #define SEN_OBJ_PROMISE 16
104 #define SEN_OBJ_REFERER 32
105 #define SEN_OBJ_NATIVE 64
106 #define SEN_OBJ_FROMJA 128
107 #define SEN_OBJ_FREE 256
108 
109 void sen_ql_init_globals(sen_ctx *c);
110 
111 sen_obj *sen_ql_at(sen_ctx *c, const char *key);
112 void sen_ql_def_db_funcs(sen_ctx *c);
113 
114 #define SEN_OBJ_INSPECT_ESC 1
115 #define SEN_OBJ_INSPECT_SYM_AS_STR 2
116 
117 void sen_obj_inspect(sen_ctx *c, sen_obj *obj, sen_rbuf *buf, int flags);
118 void sen_ql_def_native_func(sen_ctx *c, const char *name,
119                                   sen_ql_native_func *func);
120 const char *_sen_obj_key(sen_ctx *c, sen_obj *obj);
121 sen_obj *sen_ql_feed(sen_ctx *c, char *str, uint32_t str_size, int mode);
122 sen_obj *sen_ql_eval(sen_ctx *c, sen_obj *code, sen_obj *objs);
123 sen_rc sen_obj2int(sen_ctx *c, sen_obj *o);
124 
125 sen_obj *sen_ql_mk_symbol(sen_ctx *c, const char *name);
126 sen_obj *sen_ql_mk_obj(sen_ctx *c, sen_id cls, sen_id self);
127 void sen_ql_bind_symbol(sen_db_store *dbs, sen_obj *symbol);
128 sen_obj *sen_ql_mk_string(sen_ctx *c, const char *str, unsigned int len);
129 
130 sen_obj *sen_obj_new(sen_ctx *c);
131 sen_obj *sen_obj_alloc(sen_ctx *c, uint32_t size);
132 void sen_obj_clear(sen_ctx *c, sen_obj *o);
133 sen_obj *sen_obj_cons(sen_ctx *ctx, sen_obj *a, sen_obj *b);
134 char *sen_obj_copy_bulk_value(sen_ctx *ctx, sen_obj *o);
135 void sen_ql_init_const(void);
136 
137 sen_rc sen_ql_obj_mark(sen_ctx *ctx, sen_obj *o);
138 sen_rc sen_ql_obj_unmark(sen_ctx *ctx, sen_obj *o);
139 
140 typedef struct _symsnip_spec symsnip_spec;
141 void sen_ql_symsnip_spec_close(sen_ctx *ctx, symsnip_spec *ss);
142 
143 #define SEN_OBJ2VALUE(o,v,s) ((v) = (o)->u.b.value, (s) = (o)->u.b.size)
144 #define SEN_VALUE2OBJ(o,v,s) ((o)->u.b.value = (v), (o)->u.b.size = (s))
145 
146 #define VOIDP(c) ((c) == NIL || !(c) || (c)->type == sen_ql_void)
147 #define OBJECTP(c) ((c)->type == sen_ql_object)
148 #define RECORDSP(c) ((c)->type == sen_ql_records)
149 #define SNIPP(c) ((c)->type == sen_ql_snip)
150 #define BULKP(c) ((c)->type == sen_ql_bulk)
151 #define PAIRP(c) (((c)->type & sen_ql_list))
152 #define LISTP(c) (PAIRP(c) || (c) == NIL)
153 #define INTP(c) ((c)->type == sen_ql_int)
154 #define CLASSP(c) ((c)->type == sen_db_class)
155 #define RAW_CLASSP(c) ((c)->type == sen_db_raw_class)
156 #define NATIVE_FUNCP(c) ((c)->flags & SEN_OBJ_NATIVE)
157 #define QUERYP(c) ((c)->type == sen_ql_query)
158 #define OBJ_SLOTP(c) ((c)->type == sen_db_obj_slot)
159 #define RA_SLOTP(c) ((c)->type == sen_db_ra_slot)
160 #define JA_SLOTP(c) ((c)->type == sen_db_ja_slot)
161 #define IDX_SLOTP(c) ((c)->type == sen_db_idx_slot)
162 #define SLOTP(c) (sen_db_obj_slot <= (c)->type && (c)->type <= sen_db_pslot)
163 #define OPP(c) ((c)->type == sen_ql_op)
164 #define STRVALUE(c) ((c)->u.b.value)
165 #define STRSIZE(c) ((c)->u.b.size)
166 #define NUMBERP(c) ((c)->type == sen_ql_int || (c)->type == sen_ql_float)
167 #define SYMBOLP(c) ((c)->flags & SEN_OBJ_SYMBOL)
168 #define SYMNAME(c) (SEN_SET_STRKEY_BY_VAL(c))
169 #define KEYWORDP(c) (*SYMNAME(c) == ':')
170 #define CONTINUATIONP(p) ((p)->type == sen_ql_continuation)
171 #define CLOSUREP(p) ((p)->type == sen_ql_closure || (p)->type == sen_ql_macro)
172 #define PROCP(p) ((p)->type == sen_ql_proc)
173 #define PROCEDUREP(p) (PROCP(p) || CLOSUREP(p) || CONTINUATIONP(p) || NATIVE_FUNCP(p))
174 
175 #define SETINT(c,v) ((c)->type = sen_ql_int, (c)->u.i.i = (v))
176 #define SETFLOAT(c,v) ((c)->type = sen_ql_float, (c)->u.d.d = (v))
177 #define SETBULK(c,v,s) ((c)->type = sen_ql_bulk, (c)->u.b.value = (v), (c)->u.b.size = (s))
178 #define SETTIME(c,v) ((c)->type = sen_ql_time, memcpy(&(c)->u.tv, v, sizeof(sen_timeval)))
179 
180 #define CAR(c)          ((c)->u.l.car)
181 #define CDR(c)          ((c)->u.l.cdr)
182 #define CAAR(c)         CAR(CAR(c))
183 #define CADR(c)         CAR(CDR(c))
184 #define CDAR(c)         CDR(CAR(c))
185 #define CDDR(c)         CDR(CDR(c))
186 #define CADDR(c)        CAR(CDDR(c))
187 #define CADAR(p)        CAR(CDAR(p))
188 #define CADAAR(p)       CAR(CDR(CAAR(p)))
189 #define CADDDR(p)       CAR(CDR(CDDR(p)))
190 #define CDDDDR(p)       CDR(CDR(CDDR(p)))
191 
192 #define IVALUE(p)       ((p)->u.i.i)
193 #define FVALUE(p)       ((p)->u.d.d)
194 
195 #define SEN_OBJ_NEW(ctx,o) do {\
196   if (!((o) = sen_obj_new(ctx))) { QLERR("obj_new failed"); }\
197 } while(0)
198 
199 #define SEN_RBUF2OBJ(ctx,rbuf,o) do {\
200   SEN_RBUF_PUTC((rbuf), '\0');\
201   SEN_OBJ_NEW(ctx, (o));\
202   (o)->flags = SEN_OBJ_ALLOCATED;\
203   (o)->type = sen_ql_bulk;\
204   (o)->u.b.value = (rbuf)->head;\
205   (o)->u.b.size = SEN_RBUF_VSIZE(rbuf) - 1;\
206 } while(0)
207 
208 #define CONS(a,b) (sen_obj_cons(ctx, a, b))
209 
210 #define INTERN(s) (sen_ql_mk_symbol(ctx, s))
211 
212 #define POP(x,c) (PAIRP(c) ? ((x) = CAR(c), (c) = CDR(c), (x)) : (x = NIL))
213 
214 #define SKIPSPACE(c) do {\
215   unsigned int len;\
216   while ((c)->cur < (c)->str_end && sen_isspace((c)->cur, (c)->encoding)) {\
217     if (!(len = sen_str_charlen_nonnull((c)->cur, (c)->str_end, (c)->encoding))) {\
218       (c)->cur = (c)->str_end;\
219       break;\
220     }\
221     (c)->cur += len;\
222   }\
223 } while (0)
224 
225 #ifdef __cplusplus
226 }
227 #endif
228 
229 #endif /* SEN_QL_H */
230