1/* SICStus Common Foreign Language Interface: definitions. -*- C -*- 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5This file is part of the Parma Polyhedra Library (PPL). 6 7The PPL is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by the 9Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The PPL is distributed in the hope that it will be useful, but WITHOUT 13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with this program; if not, write to the Free Software Foundation, 19Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21For the most up-to-date information see the Parma Polyhedra Library 22site: http://bugseng.com/products/ppl/ . */ 23 24#include <assert.h> 25#include <limits.h> 26 27/*! 28 Return a new term reference. 29*/ 30PCFLI_EXTERN_INLINE Prolog_term_ref 31Prolog_new_term_ref() { 32 return SP_new_term_ref(); 33} 34 35/*! 36 Make \p t be a reference to the same term referenced by \p u, 37 i.e., assign \p u to \p t. 38*/ 39PCFLI_EXTERN_INLINE int 40Prolog_put_term(Prolog_term_ref t, Prolog_term_ref u) { 41 return SP_put_term(t, u); 42} 43 44/*! 45 Assign to \p t a Prolog integer with value \p l. 46*/ 47PCFLI_EXTERN_INLINE int 48Prolog_put_long(Prolog_term_ref t, long l) { 49 return SP_put_integer(t, l); 50} 51 52static int 53Prolog_put_big_ulong(Prolog_term_ref t, unsigned long ul) { 54 static unsigned char uc_buffer[sizeof(unsigned long) + 1]; 55 static unsigned n; 56#if PPL_SIZEOF_LONG_LONG > PPL_SIZEOF_LONG 57 static long long ll_buffer; 58#endif 59 60#if PPL_SIZEOF_LONG_LONG > PPL_SIZEOF_LONG 61 ll_buffer = ul; 62 if (SP_put_integer_bytes(t, &ll_buffer, sizeof(ll_buffer), 1)) 63 return 1; 64#endif 65 n = 0; 66 do { 67 uc_buffer[n++] = ul & 0xff; 68 ul >>= 8; 69 } while (ul); 70 if (uc_buffer[n-1] & 0x80) 71 uc_buffer[n++] = 0; 72 return SP_put_integer_bytes(t, &uc_buffer, n, 0); 73} 74 75/*! 76 Assign to \p t a Prolog integer with value \p ul. 77*/ 78PCFLI_EXTERN_INLINE int 79Prolog_put_ulong(Prolog_term_ref t, unsigned long ul) { 80 return 81 (ul <= LONG_MAX) 82 ? SP_put_integer(t, (long) ul) 83 : Prolog_put_big_ulong(t, ul); 84} 85 86/*! 87 Assign to \p t an atom whose name is given 88 by the null-terminated string \p s. 89*/ 90PCFLI_EXTERN_INLINE int 91Prolog_put_atom_chars(Prolog_term_ref t, const char* s) { 92 return SP_put_string(t, s); 93} 94 95/*! 96 Assign to \p t the Prolog atom \p a. 97*/ 98PCFLI_EXTERN_INLINE int 99Prolog_put_atom(Prolog_term_ref t, Prolog_atom a) { 100 return SP_put_atom(t, a); 101} 102 103/*! 104 Assign to \p t a term representing the address contained in \p p. 105*/ 106PCFLI_EXTERN_INLINE int 107Prolog_put_address(Prolog_term_ref t, void* p) { 108 return SP_put_address(t, p); 109} 110 111/*! 112 Return an atom whose name is given by the null-terminated string \p s. 113*/ 114PCFLI_EXTERN_INLINE Prolog_atom 115Prolog_atom_from_string(const char* s) { 116 return SP_atom_from_string(s); 117} 118 119/*! 120 Assign to \p t a compound term whose principal functor is \p f 121 of arity 1 with argument \p a1. 122*/ 123PCFLI_EXTERN_INLINE int 124Prolog_construct_compound(Prolog_term_ref t, Prolog_atom f, 125 Prolog_term_ref a1) { 126 return SP_cons_functor(t, f, 1, a1); 127} 128 129/*! 130 Assign to \p t a compound term whose principal functor is \p f 131 of arity 2 with arguments \p a1 and \p a2. 132*/ 133PCFLI_EXTERN_INLINE int 134Prolog_construct_compound(Prolog_term_ref t, Prolog_atom f, 135 Prolog_term_ref a1, Prolog_term_ref a2) { 136 return SP_cons_functor(t, f, 2, a1, a2); 137} 138 139/*! 140 Assign to \p t a compound term whose principal functor is \p f 141 of arity 3 with arguments \p a1, \p a2 and \p a3. 142*/ 143PCFLI_EXTERN_INLINE int 144Prolog_construct_compound(Prolog_term_ref t, Prolog_atom f, 145 Prolog_term_ref a1, Prolog_term_ref a2, 146 Prolog_term_ref a3) { 147 return SP_cons_functor(t, f, 3, a1, a2, a3); 148} 149 150/*! 151 Assign to \p t a compound term whose principal functor is \p f 152 of arity 4 with arguments \p a1, \p a2, \p a3 and \p a4. 153*/ 154PCFLI_EXTERN_INLINE int 155Prolog_construct_compound(Prolog_term_ref t, Prolog_atom f, 156 Prolog_term_ref a1, Prolog_term_ref a2, 157 Prolog_term_ref a3, Prolog_term_ref a4) { 158 return SP_cons_functor(t, f, 4, a1, a2, a3, a4); 159} 160 161/*! 162 Assign to \p c a Prolog list whose head is \p h and tail is \p t. 163*/ 164PCFLI_EXTERN_INLINE int 165Prolog_construct_cons(Prolog_term_ref c, 166 Prolog_term_ref h, Prolog_term_ref t) { 167 return SP_cons_list(c, h, t); 168} 169 170/*! 171 Raise a Prolog exception with \p t as the exception term. 172*/ 173PCFLI_EXTERN_INLINE void 174Prolog_raise_exception(Prolog_term_ref t) { 175 SP_raise_exception(t); 176} 177 178/*! 179 Return true if \p t is a Prolog variable, false otherwise. 180*/ 181PCFLI_EXTERN_INLINE int 182Prolog_is_variable(Prolog_term_ref t) { 183 return SP_is_variable(t); 184} 185 186/*! 187 Return true if \p t is a Prolog atom, false otherwise. 188*/ 189PCFLI_EXTERN_INLINE int 190Prolog_is_atom(Prolog_term_ref t) { 191 return SP_is_atom(t); 192} 193 194/*! 195 Return true if \p t is a Prolog integer, false otherwise. 196*/ 197PCFLI_EXTERN_INLINE int 198Prolog_is_integer(Prolog_term_ref t) { 199 return SP_is_integer(t); 200} 201 202/*! 203 Return true if \p t is the representation of an address, false otherwise. 204*/ 205PCFLI_EXTERN_INLINE int 206Prolog_is_address(Prolog_term_ref t) { 207 return SP_is_integer(t); 208} 209 210/*! 211 Return true if \p t is a Prolog compound term, false otherwise. 212*/ 213PCFLI_EXTERN_INLINE int 214Prolog_is_compound(Prolog_term_ref t) { 215 return SP_is_compound(t); 216} 217 218/*! 219 Return true if \p t is a Prolog cons (list constructor), false otherwise. 220*/ 221PCFLI_EXTERN_INLINE int 222Prolog_is_cons(Prolog_term_ref t) { 223 return SP_is_list(t); 224} 225 226/*! 227 Assuming \p t is a Prolog integer, return true if its value fits 228 in a long, in which case the value is assigned to \p v, 229 return false otherwise. The behavior is undefined if \p t is 230 not a Prolog integer. 231*/ 232PCFLI_EXTERN_INLINE int 233Prolog_get_long(Prolog_term_ref t, long* lp) { 234 assert(Prolog_is_integer(t)); 235 return SP_get_integer(t, lp); 236} 237 238/*! 239 If \p t is the Prolog representation for a memory address, return 240 true and store that address into to \p v; return false otherwise. 241 The behavior is undefined if \p t is not an address. 242*/ 243PCFLI_EXTERN_INLINE int 244Prolog_get_address(Prolog_term_ref t, void** vpp) { 245 assert(Prolog_is_address(t)); 246 return SP_get_address(t, vpp); 247} 248 249/*! 250 If \p t is a Prolog atom, return true and store its name into \p name. 251 The behavior is undefined if \p t is not a Prolog atom. 252*/ 253PCFLI_EXTERN_INLINE int 254Prolog_get_atom_name(Prolog_term_ref t, Prolog_atom* ap) { 255 assert(Prolog_is_atom(t)); 256 return SP_get_atom(t, ap); 257} 258 259/*! 260 If \p t is a Prolog compound term, return true and store its name 261 and arity into \p name and \p arity, respectively. 262 The behavior is undefined if \p t is not a Prolog compound term. 263*/ 264PCFLI_EXTERN_INLINE int 265Prolog_get_compound_name_arity(Prolog_term_ref t, Prolog_atom* ap, int* ip) { 266 assert(Prolog_is_compound(t)); 267 return SP_get_functor(t, ap, ip); 268} 269 270/*! 271 If \p t is a Prolog compound term and \p i is a positive integer 272 less than or equal to its arity, return true and assign to \p a the 273 i-th (principal) argument of \p t. 274 The behavior is undefined if \p t is not a Prolog compound term. 275*/ 276PCFLI_EXTERN_INLINE int 277Prolog_get_arg(int i, Prolog_term_ref t, Prolog_term_ref a) { 278 assert(Prolog_is_compound(t)); 279 return SP_get_arg(i, t, a); 280} 281 282/*! 283 If \p c is a Prolog cons (list constructor), assign its head and 284 tail to \p h and \p t, respectively. 285 The behavior is undefined if \p c is not a Prolog cons. 286*/ 287PCFLI_EXTERN_INLINE int 288Prolog_get_cons(Prolog_term_ref c, Prolog_term_ref h, Prolog_term_ref t) { 289 assert(Prolog_is_cons(c)); 290 return SP_get_list(c, h, t); 291} 292 293/*! 294 Unify the terms referenced by \p t and \p u and return true 295 if the unification is successful; return false otherwise. 296*/ 297PCFLI_EXTERN_INLINE int 298Prolog_unify(Prolog_term_ref t, Prolog_term_ref u) { 299 return SP_unify(t, u); 300} 301