YAP 7.1.0
YapTags.h
1/*************************************************************************
2* *
3* YAP Prolog %W% %G% *
4* Yap Prolog was developed at NCCUP - Universidade do Porto *
5* *
6* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
7* *
8**************************************************************************
9* *
10* File: YapTags.h *
11* mods: *
12* comments: Term Operations for YAP *
13* version: $Id: Yap.h,v 1.38 2008-06-18 10:02:27 vsc Exp $ *
14*************************************************************************/
15
16#ifndef YAPTAGS_H
17
18#define YAPTAGS_H 1
19
20#ifndef EXTERN
21#define EXTERN extern
22#endif
23
24#include "inline-only.h"
25
26#ifndef SHORT_ADDRESSES
27#define LONG_ADDRESSES 1
28#else
29#define LONG_ADDRESSES 0
30#endif
31
32/***********************************************************************/
33
34/*
35 absrectype Term = Int + Float + Atom + Pair + Appl + Ref + Var
36
37 with AbsAppl(t) : *CELL -> Term
38 and RepAppl(t) : Term -> *CELL
39
40 and AbsPair(t) : *CELL -> Term
41 and RepPair(t) : Term -> *CELL
42
43 and IsIntTerm(t) = ...
44 and IsAtomTerm(t) = ...
45 and IsVarTerm(t) = ...
46 and IsPairTerm(t) = ...
47 and IsApplTerm(t) = ...
48 and IsFloatTerm(t) = ...
49 and IsRefTerm(t) = ...
50 and IsNonVarTerm(t) = ! IsVar(t)
51 and IsNumterm(t) = IsIntTerm(t) || IsFloatTerm(t)
52 and IsAtomicTerm(t) = IsNumTerm(t) || IsAtomTerm(t)
53 and IsPrimitiveTerm(t) = IsAtomicTerm(t) || IsRefTerm(t)
54
55 and MkIntTerm(n) = ...
56 and MkFloatTerm(f) = ...
57 and MkAtomTerm(a) = ...
58 and MkVarTerm(r) = ...
59 and MkApplTerm(f,n,args) = ...
60 and MkPairTerm(hd,tl) = ...
61 and MkRefTerm(R) = ...
62
63 and PtrOfTerm(t) : Term -> CELL * = ...
64 and IntOfTerm(t) : Term -> int = ...
65 and FloatOfTerm(t) : Term -> flt = ...
66 and AtomOfTerm(t) : Term -> Atom = ...
67 and VarOfTerm(t) : Term -> *Term = ....
68 and HeadOfTerm(t) : Term -> Term = ...
69 and TailOfTerm(t) : Term -> Term = ...
70 and FunctorOfTerm(t) : Term -> Functor = ...
71 and ArgOfTerm(i,t) : Term -> Term= ...
72 and RefOfTerm(t) : Term -> DBRef = ...
73
74 */
75
76/*
77 YAP can use several different tag schemes, according to the kind of
78 machine we are experimenting with.
79*/
80
81#include "Regs.h"
82
83#if LONG_ADDRESSES && defined(OLD_TAG_SCHEME)
84
85#include "Tags_32bits.h"
86
87#endif /* LONG_ADDRESSES && defined(OLD_TAG_SCHEME) */
88
89/* AIX will by default place mmaped segments at 0x30000000. This is
90 incompatible with the high tag scheme. Linux-ELF also does not like
91 if you place things in the lower addresses (power to the libc people).
92*/
93
94#if defined(__APPLE__)
95/* mmap on __APPLE__ is not the greatest idea. It overwrites memory allocated by
96 * malloc */
97#undef USE_DL_MALLOC
98#ifndef USE_SYSTEM_MALLOC
99#define USE_SYSTEM_MALLOC 1
100#endif
101#endif
102
103#if SIZEOF_INT_P == 4
104#define USE_LOW32_TAGS 1
105#endif
106
107#if SIZEOF_INT_P == 4 && !defined(OLD_TAG_SCHEME) && !defined(USE_LOW32_TAGS)
108
109#include "Tags_32Ops.h"
110
111#elif LONG_ADDRESSES && SIZEOF_INT_P == 4 && !defined(OLD_TAG_SCHEME) && \
112 defined(USE_LOW32_TAGS)
113
114#include "Tags_32LowTag.h"
115
116#elif SIZEOF_INT_P == 8 && !defined(OLD_TAG_SCHEME)
117
118#include "Tags_64bits.h"
119
120// #elif !LONG_ADDRESSES
121//
122// #include "Tags_24bits.h"
123
124#endif
125
126#ifdef TAG_LOW_BITS_32
127
128#if !GC_NO_TAGS
129#define MBIT 0x80000000
130#define RBIT 0x40000000
131
132#if IN_SECOND_QUADRANT
133#define INVERT_RBIT 1 /* RBIT is 1 by default */
134#endif
135#endif /* !GC_NO_TAGS */
136
137#else
138
139#if !GC_NO_TAGS
140#if defined(YAPOR_SBA) && defined(__linux__)
141#define MBIT /* 0x20000000 */ MKTAG(0x1, 0) /* mark bit */
142#else
143#define RBIT /* 0x20000000 */ MKTAG(0x1, 0) /* relocation chain bit */
144#define MBIT /* 0x40000000 */ MKTAG(0x2, 0) /* mark bit */
145#endif
146#endif /* !GC_NO_TAGS */
147
148#endif
149
150/*************************************************************************************************
151 ???
152*************************************************************************************************/
153
154#define MkVarTerm() MkVarTerm__(PASS_REGS1)
155#define MkPairTerm(A, B) MkPairTerm__(A, B PASS_REGS)
156
157/*************************************************************************************************
158 applies to unbound variables
159*************************************************************************************************/
160
161INLINE_ONLY Term *VarOfTerm(Term t);
162
163INLINE_ONLY Term *VarOfTerm(Term t) { return (Term *)(t); }
164
165#ifdef YAPOR_SBA
166
167#define RESET_VARIABLE(V) (*(CELL *)(V) = 0)
168
169INLINE_ONLY Term MkVarTerm__(USES_REGS1);
170
171INLINE_ONLY Term MkVarTerm__(USES_REGS1) {
172 return (Term)((*HR = 0, HR++));
173}
174
175INLINE_ONLY bool IsUnboundVar(Term *t) { return (int)(*(t) ==
1760); }
177
178#else
179
180#define RESET_VARIABLE(V) (*(CELL *)(V) = Unsigned(V))
181
182
183INLINE_ONLY Term MkVarTerm__(USES_REGS1) {
184 return (Term)((*HR = (CELL)HR, HR++));
185}
186
187
188INLINE_ONLY bool IsUnboundVar(Term *t) {
189 return *(t) == (Term)(t);
190}
191
192#endif
193
194
195INLINE_ONLY CELL *PtrOfTerm(Term t) {
196 return (CELL *)(*(CELL *)(t));
197}
198
199INLINE_ONLY Functor FunctorOfTerm(Term);
200
201INLINE_ONLY Functor FunctorOfTerm(Term t) {
202 return (Functor)(*RepAppl(t));
203}
204
205#if USE_LOW32_TAGS
206
207INLINE_ONLY Term MkAtomTerm(Atom);
208
209INLINE_ONLY Term MkAtomTerm(Atom a) {
210 return (Term)(AtomTag | (CELL)(a));
211}
212
213INLINE_ONLY Atom AtomOfTerm(Term t);
214
215INLINE_ONLY Atom AtomOfTerm(Term t) {
216 return (Atom)((~AtomTag & (CELL)(t)));
217}
218
219#else
220
221INLINE_ONLY Term MkAtomTerm(Atom);
222
223INLINE_ONLY Term MkAtomTerm(Atom at) {
224 return (Term)(TAGGEDA((CELL)AtomTag, (CELL)(at)));
225}
226
227INLINE_ONLY Atom AtomOfTerm(Term t);
228
229INLINE_ONLY Atom AtomOfTerm(Term t) {
230 return (Atom)(NonTagPart(t));
231}
232
233#endif
234
235INLINE_ONLY bool IsAtomTerm(Term);
236
237INLINE_ONLY bool IsAtomTerm(Term t) {
238 return CHKTAG((t), AtomTag);
239}
240
241INLINE_ONLY Term MkIntTerm(Int);
242
243INLINE_ONLY Term MkIntTerm(Int n) {
244 return (Term)(TAGGED(NumberTag, (n)));
245}
246
247/*
248 A constant to subtract or add to a well-known term, we assume no
249 overflow problems are possible
250*/
251
252INLINE_ONLY Term MkIntConstant(Int);
253
254INLINE_ONLY Term MkIntConstant(Int n) {
255 return (Term)(NONTAGGED(NumberTag, (n)));
256}
257
258INLINE_ONLY bool IsIntTerm(Term);
259
260INLINE_ONLY bool IsIntTerm(Term t) {
261 return CHKTAG((t), NumberTag);
262}
263
264INLINE_ONLY Term MkPairTerm__(Term head, Term tail USES_REGS);
265
266INLINE_ONLY Term MkPairTerm__(Term head, Term tail USES_REGS) {
267 CELL *p = HR;
268
269 HR[0] = head;
270 HR[1] = tail;
271 HR += 2;
272 return (AbsPair(p));
273}
274
275/* Needed to handle numbers:
276 these two macros are fundamental in the integer/float conversions */
277
278#ifdef M_WILLIAMS
279#define IntInBnd(X) (TRUE)
280#else
281#ifdef TAGS_FAST_OPS
282#define IntInBnd(X) (Unsigned(((Int)(X) >> (32 - 7)) + 1) <= 1)
283#else
284#define IntInBnd(X) ((X) < MAX_ABS_INT && (X) > -MAX_ABS_INT - 1L)
285#endif
286#endif
287
288/*
289 There are two types of functors:
290
291 o Special functors mark special terms
292 on the heap that should be seen as constants.
293
294 o Standard functors mark normal applications.
295
296*/
297
298#include "TermExt.h"
299
300#define IsAccessFunc(func) ((func) == FunctorAccess)
301
302#ifdef YAP_H
303
304#define MkIntegerTerm(i) __MkIntegerTerm(i PASS_REGS)
305
306INLINE_ONLY Term __MkIntegerTerm(Int USES_REGS);
307
308INLINE_ONLY Term __MkIntegerTerm(Int n USES_REGS) {
309 return (Term)(IntInBnd(n) ? MkIntTerm(n) : MkLongIntTerm(n));
310}
311#endif
312
313INLINE_ONLY bool IsIntegerTerm(Term);
314
315INLINE_ONLY bool IsIntegerTerm(Term t) {
316 return (int)(IsIntTerm(t) || IsLongIntTerm(t));
317}
318
319INLINE_ONLY Int IntegerOfTerm(Term);
320
321INLINE_ONLY Int IntegerOfTerm(Term t) {
322
323 return (Int)(IsIntTerm(t) ? IntOfTerm(t) : LongIntOfTerm(t));
324}
325
326#ifdef YAP_H
327
328#define MkAddressTerm(i) __MkAddressTerm(i PASS_REGS)
329
330INLINE_ONLY Term __MkAddressTerm(void *USES_REGS);
331
332INLINE_ONLY Term __MkAddressTerm(void *n USES_REGS) {
333 return __MkIntegerTerm((Int)n PASS_REGS);
334}
335
336#endif
337
338INLINE_ONLY bool IsAddressTerm(Term);
339
340INLINE_ONLY bool IsAddressTerm(Term t) {
341 return (bool)IsIntegerTerm(t);
342}
343
344INLINE_ONLY void *AddressOfTerm(Term);
345
346INLINE_ONLY void *AddressOfTerm(Term t) {
347 return (void *)(IsIntTerm(t) ? IntOfTerm(t) : LongIntOfTerm(t));
348}
349
350
351INLINE_ONLY Int IsPairTermOrNil (Term);
352
353INLINE_ONLY Int
354IsPairOrNilTerm (Term t)
355{
356 return IsPairTerm(t) || t == TermNil;
357}
358
359
360#endif