New builtins are added in header.pl and after a "make realclean; make" a new version of BinProlog containing them is generated automatically.
An example of declaration in headers.pl is:
b0(+/3,arith(1),in_body). % arity=3+1 by binarization
+(0,1,Result).
new_builtin()
which looks as follows:
/* New builtins can be called from Prolog as: new_builtin(0,<INPUT_ARG>,<OUTPUT_ARG>) X(1) contains the integer `opcode' of your builtin X(2) contains your input arg regs[I] contains somthing that will be unified with what you return (the precise value of I depends on the register allocator). You are expected to `return' either - a non-null object that will be unified with <OUTPUT_ARG>, or - NULL to signal FAILURE As the returned object will be in a register this can be used for instance to add a garbage collector that moves every data area around... */ term new_builtin(H,regs,A,P,wam) register term H,regs,*A; register instr P; register stack wam; { BP_check_call(); switch(BP_op) { /* for beginners ... */ case 0: /* this just returns your input argument (default behavior) */ break; case 1: BP_result=BP_integer(13); /* this example returns 13 */ break; case 2: BP_result=BP_atom("hello"); /* this example returns 'hello' */ break; /* for experts ... */ case 3: /* iterative list construction */ { cell middle,last,F1,F2; int i; BP_make_float(F1, 77.0/2); BP_make_float(F2, 3.14); BP_begin_put_list(middle); BP_put_list(BP_integer(33)); BP_put_list(F1); BP_put_list(BP_string("hello")); BP_put_list(F2); BP_end_put_list(); BP_begin_put_list(last); for(i=0; i<5; i++) { BP_put_list(BP_integer(i)); } BP_end_put_list(); BP_begin_put_list(BP_result); BP_put_list(BP_string("first")); BP_put_list(middle); BP_put_list(last); BP_put_list(F1); BP_put_list(F2); BP_end_put_list(); } break; case 4: /* cons style list construction */ BP_begin_cons(); BP_result= BP_cons( BP_integer(1), BP_cons( BP_integer(2), BP_nil ) ); BP_end_cons(); break; case 5: /* for hackers only ... */ ; BP_result=(cell)H; H[0]=g.DOT; H[1]=X(2); H[2]=g.DOT; H[3]=BP_integer(99); H[4]=g.DOT; H[5]=(cell)(H+5); /* new var */ H[6]=g.DOT; H[7]=(cell)(H+5); /* same var as previously created */ H[8]=g.DOT; H[9]=BP_atom("that's it"); H[10]=g.NIL; H+=11; break; case 6: BP_fail(); break; case 7: { cell T=BP_input; if(BP_is_integer(T)) {fprintf(g.tellfile,"integer: %d\n",BP_get_single_integer(T)); BP_result=BP_integer(-1); } else BP_fail(); } break; case 8: /* for experts: calling BinProlog from C */ { cell L,R,Goal; BP_begin_put_list(L); BP_put_list(BP_string("one")); BP_put_list(BP_integer(2)); BP_put_list(BP_string("three")); BP_put_list(BP_input); /* whatever comes as input */ BP_end_put_list(); BP_put_functor(Goal,"append",3); BP_put_old_var(L); BP_put_old_var(L); BP_put_new_var(R); BP_prolog_call(Goal); /* this will return NULL on failure !!!*/ BP_put_functor(Goal,"write",1); BP_put_old_var(R); BP_prolog_call(Goal); /* calls write/1 */ BP_put_functor(Goal,"nl",0); BP_prolog_call(Goal); /* calls nl/0 */ BP_result=R; /* returns the appended list to Prolog */ } break; /* EDIT AND ADD YOUR CODE HERE....*/ default: return LOCAL_ERR(X(1),"call to unknown user_defined C function"); } return H; }