int prolog_call0(CTXTdeclc Cell term) { Psc psc; if (isconstr(term)) { int disp; char *addr; psc = get_str_psc(term); addr = (char *)(clref_val(term)); for (disp = 1; disp <= (int)get_arity(psc); ++disp) { bld_copy(reg+disp, cell((CPtr)(addr)+disp)); } } else if (isstring(term)) { int value; Pair sym; if (string_val(term) == true_string) return TRUE; /* short-circuit if calling "true" */ sym = insert(string_val(term),0,(Psc)flags[CURRENT_MODULE],&value); psc = pair_psc(sym); } else { if (isnonvar(term)) xsb_type_error(CTXTc "callable",term,"call/1",1); else xsb_instantiation_error(CTXTc "call/1",1); return FALSE; } #ifdef CP_DEBUG pscreg = psc; #endif pcreg = get_ep(psc); if (asynint_val) intercept(CTXTc psc); return TRUE; }
void add_interrupt(CTXTdeclc Cell op1, Cell op2) { Cell head, tail, temp; CPtr addr_head, addr_tail; addr_head = (CPtr)glstack.low; head = cell(addr_head); // addr of interrupt list addr_tail = (CPtr)glstack.low+1; tail = cell(addr_tail); // addr of last cons cell of interrupt list // Build the new list cons pair and the new op-pair cons // This record is 4 words long and so INT_REC_SIZE=4 bld_list(&temp,hreg); // temp -> new cons pair 1 bld_list(hreg,hreg+2); // 1.car -> 2nd new cons pair 2 hreg++; bld_free(hreg); // 1.cdr is free var hreg++; bld_copy(hreg,op1); // 2.car is op1 hreg++; bld_copy(hreg,op2); // 2.cdr is op2 hreg++; if (isnonvar(head)) { // nonempty CPtr addr_cdr; addr_cdr = clref_val(tail)+1; bind_copy(addr_cdr,temp); push_pre_image_trail(addr_tail,temp); bld_copy(addr_tail,temp); } else { // first bind_copy(addr_head,temp); bind_copy(addr_tail,temp); } }
int compare(CTXTdeclc const void * v1, const void * v2) { int comp; CPtr cptr1, cptr2; Cell val1 = (Cell) v1 ; Cell val2 = (Cell) v2 ; XSB_Deref(val2); /* val2 is not in register! */ XSB_Deref(val1); /* val1 is not in register! */ if (val1 == val2) return 0; switch(cell_tag(val1)) { case XSB_FREE: case XSB_REF1: if (isattv(val2)) return vptr(val1) - (CPtr)dec_addr(val2); else if (isnonvar(val2)) return -1; else { /* in case there exist local stack variables in the */ /* comparison, globalize them to guarantee that their */ /* order is retained as long as nobody "touches" them */ /* in the future -- without copying garbage collection */ if ((top_of_localstk <= vptr(val1)) && (vptr(val1) <= (CPtr)glstack.high-1)) { bld_free(hreg); bind_ref(vptr(val1), hreg); hreg++; val1 = follow(val1); /* deref again */ } if ((top_of_localstk <= vptr(val2)) && (vptr(val2) <= (CPtr)glstack.high-1)) { bld_free(hreg); bind_ref(vptr(val2), hreg); hreg++; val2 = follow(val2); /* deref again */ } return vptr(val1) - vptr(val2); } case XSB_FLOAT: if (isref(val2) || isattv(val2)) return 1; else if (isofloat(val2)) return sign(float_val(val1) - ofloat_val(val2)); else return -1; case XSB_INT: if (isref(val2) || isofloat(val2) || isattv(val2)) return 1; else if (isinteger(val2)) return int_val(val1) - int_val(val2); else if (isboxedinteger(val2)) return int_val(val1) - boxedint_val(val2); else return -1; case XSB_STRING: if (isref(val2) || isofloat(val2) || isinteger(val2) || isattv(val2)) return 1; else if (isstring(val2)) { return strcmp(string_val(val1), string_val(val2)); } else return -1; case XSB_STRUCT: // below, first 2 if-checks test to see if this struct is actually a number representation, // (boxed float or boxed int) and if so, does what the number case would do, only with boxed_val // macros. if (isboxedinteger(val1)) { if (isref(val2) || isofloat(val2) || isattv(val2)) return 1; else if (isinteger(val2)) return boxedint_val(val1) - int_val(val2); else if (isboxedinteger(val2)) return boxedint_val(val1) - boxedint_val(val2); else return -1; } else if (isboxedfloat(val1)) { if (isref(val2) || isattv(val2)) return 1; else if (isofloat(val2)) return sign(boxedfloat_val(val1) - ofloat_val(val2)); else return -1; } else if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1; else { int arity1, arity2; Psc ptr1 = get_str_psc(val1); Psc ptr2 = get_str_psc(val2); arity1 = get_arity(ptr1); if (islist(val2)) arity2 = 2; else arity2 = get_arity(ptr2); if (arity1 != arity2) return arity1-arity2; if (islist(val2)) comp = strcmp(get_name(ptr1), "."); else comp = strcmp(get_name(ptr1), get_name(ptr2)); if (comp || (arity1 == 0)) return comp; cptr1 = clref_val(val1); cptr2 = clref_val(val2); for (arity2 = 1; arity2 <= arity1; arity2++) { if (islist(val2)) comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2-1)); else comp = compare(CTXTc (void*)cell(cptr1+arity2), (void*)cell(cptr2+arity2)); if (comp) break; } return comp; } break; case XSB_LIST: if (cell_tag(val2) != XSB_STRUCT && cell_tag(val2) != XSB_LIST) return 1; else if (isconstr(val2)) return -(compare(CTXTc (void*)val2, (void*)val1)); else { /* Here we are comparing two list structures. */ cptr1 = clref_val(val1); cptr2 = clref_val(val2); comp = compare(CTXTc (void*)cell(cptr1), (void*)cell(cptr2)); if (comp) return comp; return compare(CTXTc (void*)cell(cptr1+1), (void*)cell(cptr2+1)); } break; case XSB_ATTV: if (isattv(val2)) return (CPtr)dec_addr(val1) - (CPtr)dec_addr(val2); else if (isref(val2)) return (CPtr)dec_addr(val1) - vptr(val2); else return -1; default: xsb_abort("Compare (unknown tag %ld); returning 0", cell_tag(val1)); return 0; } }