1/* BEGIN LICENSE BLOCK
2 * Version: CMPL 1.1
3 *
4 * The contents of this file are subject to the Cisco-style Mozilla Public
5 * License Version 1.1 (the "License"); you may not use this file except
6 * in compliance with the License.  You may obtain a copy of the License
7 * at www.eclipse-clp.org/license.
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11 * the License for the specific language governing rights and limitations
12 * under the License.
13 *
14 * The Original Code is  The ECLiPSe Constraint Logic Programming System.
15 * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16 * Portions created by the Initial Developer are
17 * Copyright (C) 1997-2006 Cisco Systems, Inc.  All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * END LICENSE BLOCK */
22
23/*
24 * ECLiPSe LIBRARY MODULE
25 *
26 * $Id: eclipse_cc.cc,v 1.4 2015/01/14 01:31:09 jschimpf Exp $
27 *
28 *
29 * IDENTIFICATION:	eclipse_cc.cc
30 *
31 * AUTHOR:		Joachim Schimpf
32 * AUTHOR:		Stefano Novello
33 *
34 * DESCRIPTION:
35 *	C++ embedding interface classes
36 *
37 *	This file is preprocessed at eclipse-build-time to produce
38 *	eclipse_cc.h. The main reason to do this is to not pollute
39 *	the user's namespace with all the define's in our .h files.
40 */
41
42#define EC_EXTERNAL
43#define EC_EMBED
44
45#include "config.h"
46#include "ec_public.h"
47#include "types.h"
48#include "embed.h"
49
50enum EC_status
51{
52	EC_succeed = PSUCCEED,
53	EC_fail = PFAIL,
54	EC_throw = PTHROW,
55	EC_yield = PYIELD,
56	EC_running = PRUNNING,
57	EC_waitio = PWAITIO,
58	EC_flushio = PFLUSHIO
59};
60
61/*
62 * classes
63 */
64
65class EC_atom;
66class EC_functor;
67class EC_word;
68class EC_ref;
69class EC_refs;
70
71/*----------------------------------------------------------------------*/
72class EC_atom
73{
74    public:
75	dident d;
76
77	EC_atom() {}
78
79	EC_atom(char * s) { d = ec_did(s,0); }
80
81	EC_atom(dident did)
82	{
83	    if (DidArity(did))
84		ec_panic("atom arity != 0", "EC_atom::EC_atom(dident d)");
85	    d = did;
86	}
87
88	char * Name() { return DidName(d); }
89	char * name() { return DidName(d); }
90};
91
92/*----------------------------------------------------------------------*/
93class EC_functor
94{
95    public:
96	dident d;
97
98	EC_functor() {}
99
100	EC_functor(const char * s,int arity)
101	{
102	    if (!arity)
103		ec_panic("functor arity == 0", "EC_functor::EC_functor(char*,int)");
104	    d = ec_did(s, arity);
105	}
106
107	EC_functor(dident did)
108	{
109	    if (!DidArity(did))
110		ec_panic("functor arity == 0", "EC_functor::EC_functor(dident d)");
111	    d = did;
112	}
113
114	char * Name() { return DidName(d); }
115	char * name() { return DidName(d); }
116	int Arity() { return DidArity(d); }
117	int arity() { return DidArity(d); }
118};
119
120
121/*----------------------------------------------------------------------*/
122class EC_word
123{
124	friend class EC_ref;
125	friend class EC_refs;
126
127	pword w;
128
129    public:
130    	EC_word(const pword& pw)
131	{
132	    w = pw;
133	}
134
135
136    	EC_word()
137	{
138	}
139
140    	EC_word&
141	operator=(const EC_word& ew)
142	{
143	    w = ew.w;
144	    return *this;
145	}
146
147    	EC_word(const char *s)
148	{
149	    w = ec_string(s);
150	}
151
152    	EC_word(const int l, const char *s)
153	{
154	    w = ec_length_string(l, s);
155	}
156
157    	EC_word(const EC_atom did)
158	{
159	    w = ec_atom(did.d);
160	}
161
162    	EC_word(const long l)
163	{
164	    w = ec_long(l);
165	}
166
167    	EC_word(const long long l)
168	{
169	    w = ec_long_long(l);
170	}
171
172    	EC_word(const int i)
173	{
174	    w = ec_long((long)i);
175	}
176
177    	EC_word(const double d)
178	{
179	    w = ec_double(d);
180	}
181
182    	EC_word(const EC_ref& ref);
183
184    	friend EC_word
185	term(const EC_functor functor,const EC_word args[]);
186
187	friend EC_word
188	term(const EC_functor functor,	const EC_word arg1,
189					const EC_word arg2,
190					const EC_word arg3,
191					const EC_word arg4);
192	friend EC_word
193	term(const EC_functor functor,	const EC_word arg1,
194					const EC_word arg2,
195					const EC_word arg3,
196					const EC_word arg4,
197					const EC_word arg5,
198					const EC_word arg6,
199					const EC_word arg7,
200					const EC_word arg8,
201					const EC_word arg9,
202					const EC_word arg10);
203
204	friend EC_word
205	list(const EC_word hd, const EC_word tl);
206
207	/*
208    	EC_word&
209	list(const EC_word hd, const EC_word tl)
210	{
211	    w = ec_list(hd.w,tl.w);
212	    return *this;
213	}
214	*/
215
216
217    /* Type testing */
218
219	int
220	is_atom(EC_atom* did)
221	{
222		return ec_get_atom(w,(dident*) did);
223	}
224
225	int
226	is_string(char **s)
227	{
228		return ec_get_string(w,s);
229	}
230
231	int
232	is_string(char **s, long *len)
233	{
234		return ec_get_string_length(w,s,len);
235	}
236
237	int
238	is_long(long * l)
239	{
240		return ec_get_long(w,l);
241	}
242
243	int
244	is_long_long(long long * l)
245	{
246		return ec_get_long_long(w,l);
247	}
248
249	int
250	is_double(double * d)
251	{
252		return ec_get_double(w,d);
253	}
254
255	int
256	is_handle(const t_ext_type *cl, t_ext_ptr *data)
257	{
258		return ec_get_handle(w,cl,data);
259	}
260
261	int
262	free_handle(const t_ext_type *cl)
263	{
264		return ec_free_handle(w,cl);
265	}
266
267	int
268	is_list(EC_word& hd, EC_word& tl)
269	{
270		return ec_get_list(w, &hd.w, &tl.w);
271	}
272
273	int
274	is_nil()
275	{
276		return ec_get_nil(w);
277	}
278
279	int
280	is_var()
281	{
282		return ec_is_var(w);
283	}
284
285	int
286	arity()
287	{
288		return ec_arity(w);
289	}
290
291	int
292	functor(EC_functor* did)
293	{
294		return ec_get_functor(w, (dident*) did);
295	}
296
297	int
298	arg(const int n,EC_word& arg)
299	{
300		return ec_get_arg(n, w, &arg.w);
301	}
302
303	friend int
304	compare(const EC_word& term1, const EC_word& term2);
305
306	friend int
307	operator==(const EC_word& term1, const EC_word& term2);
308
309	friend int
310	unify(EC_word term1, EC_word term2);
311
312	int
313	unify(EC_word term)
314	{
315	    return ec_unify(w, term.w);
316	}
317
318	int
319	schedule_suspensions(int n)
320	{
321	    return ec_schedule_suspensions(w, n);
322	}
323
324	friend void
325	post_goal(const EC_word term);
326
327	friend int
328	EC_resume(EC_word term, EC_ref& chp);
329
330	friend int
331	EC_resume(EC_word term);
332
333	friend int
334	post_event(EC_word term);
335
336};
337
338
339inline int
340compare(const EC_word& term1, const EC_word& term2)
341{
342    return ec_compare(term1.w, term2.w);
343}
344
345inline int
346operator==(const EC_word& term1, const EC_word& term2)
347{
348    return ec_compare(term1.w, term2.w) == 0;
349}
350
351inline int
352unify(EC_word term1, EC_word term2)
353{
354    return ec_unify(term1.w, term2.w);
355}
356
357inline void
358post_goal(const EC_word term)
359{
360	ec_post_goal(term.w);
361}
362
363inline int
364EC_resume(EC_word term)
365{
366    return ec_resume2(term.w,0);
367}
368
369inline int
370post_event(EC_word term)
371{
372    return ec_post_event(term.w);
373}
374
375inline void
376post_goal(const char * s)
377{
378	ec_post_string(s);
379}
380
381
382/*----------------------------------------------------------------------*/
383class EC_refs
384{
385
386    protected:
387	ec_refs r;
388
389    public:
390    	EC_refs(int size)
391	{
392		r = ec_refs_create_newvars(size);
393	}
394
395    	EC_refs(int size,EC_word init)
396	{
397		r = ec_refs_create(size,init.w);
398	}
399
400    	~EC_refs()
401	{
402		ec_refs_destroy(r);
403	}
404
405	int size()
406	{
407		return ec_refs_size(r);
408	}
409
410	EC_word
411	operator[](int index)
412	{
413		return EC_word(ec_refs_get(r,index));
414	}
415
416	friend EC_word
417	list(EC_refs& array);
418
419	void set(int index, EC_word new_value)
420	{
421	    ec_refs_set(r, index, new_value.w);
422	}
423
424};
425
426
427inline EC_word
428list(EC_refs& array)
429{
430	return EC_word(ec_listofrefs(array.r));
431}
432
433
434/*----------------------------------------------------------------------*/
435class EC_ref
436{
437	friend class EC_word;
438
439    protected:
440	ec_refs r;
441
442    public:
443    	EC_ref()
444	{
445		r = ec_refs_create_newvars(1);
446	}
447
448    	EC_ref(EC_word init)
449	{
450		r = ec_refs_create(1,init.w);
451	}
452
453    	~EC_ref()
454	{
455		ec_refs_destroy(r);
456	}
457
458    	EC_ref& operator=(const EC_word word);
459
460
461	void cut_to()
462	{
463	    ec_cut_to_chp(r);
464	}
465
466	friend int
467	EC_resume(EC_ref& chp);
468
469	friend int
470	EC_resume(EC_word term, EC_ref& chp);
471
472};
473
474
475inline int
476EC_resume()
477{
478    return ec_resume1(0);
479}
480
481inline int
482EC_resume(EC_ref& chp)
483{
484    return ec_resume1(chp.r);
485}
486
487inline int
488EC_resume(EC_word term, EC_ref& chp)
489{
490    return ec_resume2(term.w,chp.r);
491}
492
493inline EC_word
494EC_arg(int n)
495{
496    return EC_word(ec_arg(n));
497}
498
499inline EC_word::EC_word(const EC_ref& ref)
500{
501	w = ec_refs_get(ref.r,0);
502}
503
504inline EC_ref&
505EC_ref::operator=(const EC_word word)
506{
507	ec_refs_set(r,0,word.w);
508	return *this;
509}
510
511
512/*----------------------------------------------------------------------
513 * More EC_word constructors
514 *----------------------------------------------------------------------*/
515
516inline EC_word
517term(const EC_functor functor,const EC_word args[])
518{
519    EC_word t(ec_term_array(functor.d,(pword *) args));
520    return t;
521}
522
523inline EC_word
524term(const EC_functor functor,	const EC_word arg1,
525				const EC_word arg2 = 0,
526				const EC_word arg3 = 0,
527				const EC_word arg4 = 0)
528{
529    EC_word the_term(ec_term(functor.d,arg1.w,arg2.w,arg3.w,arg4.w));
530    return the_term;
531}
532
533inline EC_word
534term(const EC_functor functor,	const EC_word arg1,
535				const EC_word arg2,
536				const EC_word arg3,
537				const EC_word arg4,
538				const EC_word arg5,
539				const EC_word arg6 = 0,
540				const EC_word arg7 = 0,
541				const EC_word arg8 = 0,
542				const EC_word arg9 = 0,
543				const EC_word arg10 = 0)
544{
545    EC_word the_term(ec_term(functor.d,arg1.w,arg2.w,arg3.w,arg4.w,
546				arg5.w,arg6.w,arg7.w,arg8.w,arg9.w,arg10.w));
547    return the_term;
548}
549
550inline EC_word
551list(const EC_word hd, const EC_word tl)
552{
553    EC_word t(ec_list(hd.w,tl.w));
554    return t;
555}
556
557inline EC_word
558list(int size, double* array)
559{
560	return EC_word(ec_listofdouble(size, array));
561}
562
563inline EC_word
564list(int size, long* array)
565{
566	return EC_word(ec_listoflong(size, array));
567}
568
569inline EC_word
570list(int size, char* array)
571{
572	return EC_word(ec_listofchar(size, array));
573}
574
575inline EC_word
576array(int size, double* array)
577{
578	return EC_word(ec_arrayofdouble(size, array));
579}
580
581inline EC_word
582matrix(int rows, int cols, double* array)
583{
584	return EC_word(ec_matrixofdouble(rows, cols, array));
585}
586
587
588inline EC_word
589handle(const t_ext_type *cl, const t_ext_ptr data)
590{
591    return ec_handle(cl, data);
592}
593
594inline EC_word
595newvar()
596{
597    EC_word t(ec_newvar());
598    return t;
599}
600
601inline EC_word
602nil()
603{
604    EC_word t(ec_nil());
605    return t;
606}
607
608
609#define OP2(CNAME,DID)					\
610inline EC_word CNAME(const EC_word a,const EC_word b)	\
611{							\
612	return term(EC_functor((DID)),a,b);		\
613}
614
615#define OP1(CNAME,DID)			\
616inline EC_word CNAME(const EC_word a)	\
617{					\
618	return term(EC_functor((DID)),a);	\
619}
620
621OP2(operator+, ec_.d.plus)
622OP1(operator+, ec_.d.plus1)
623OP2(operator-, ec_.d.minus)
624OP1(operator-, ec_.d.minus1)
625OP2(operator*, ec_.d.times)
626OP2(operator/, ec_.d.quotient)
627OP2(operator%, ec_.d.modulo)
628OP2(operator>>, ec_.d.rshift)
629OP2(operator<<, ec_.d.lshift)
630OP2(operator&, ec_.d.and2)
631OP2(operator|, ec_.d.or2)
632OP2(pow, ec_.d.power)
633OP1(operator~, ec_.d.bitnot)
634OP1(abs, ec_.d.abs)
635OP1(sin, ec_.d.sin)
636OP1(cos, ec_.d.cos)
637OP1(tan, ec_.d.tan)
638OP1(asin, ec_.d.asin)
639OP1(acos, ec_.d.acos)
640OP1(atan, ec_.d.atan)
641OP1(sqrt, ec_.d.sqrt)
642OP1(ln, ec_.d.ln)
643OP1(fix, ec_.d.fix)
644OP1(round, ec_.d.round)
645/* The following cause conflict with system-defined macros:
646OP2(min, ec_.d.min)
647OP2(max, ec_.d.max)
648*/
649