00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "xsb_config.h"
00027 #include "xsb_debug.h"
00028
00029 #include <math.h>
00030
00031 #include "auxlry.h"
00032 #include "cell_xsb.h"
00033 #include "register.h"
00034 #include "memory_xsb.h"
00035 #include "deref.h"
00036 #include "heap_xsb.h"
00037 #include "binding.h"
00038 #include "context.h"
00039
00040 #define FUN_PLUS 1
00041 #define FUN_MINUS 2
00042 #define FUN_TIMES 3
00043 #define FUN_DIVIDE 4
00044 #define FUN_AND 5
00045 #define FUN_OR 6
00046 #define FUN_sin 9
00047 #define FUN_cos 10
00048 #define FUN_tan 11
00049
00050 #define FUN_float 13
00051 #define FUN_floor 14
00052 #define FUN_exp 15
00053 #define FUN_log 16
00054 #define FUN_log10 17
00055 #define FUN_sqrt 18
00056 #define FUN_asin 19
00057 #define FUN_acos 20
00058 #define FUN_atan 21
00059 #define FUN_abs 22
00060 #define FUN_truncate 23
00061 #define FUN_round 24
00062 #define FUN_ceiling 25
00063 #define FUN_max 26
00064 #define FUN_min 27
00065
00066
00067
00068 #define set_fvalue_from_value \
00069 if (isinteger(value)) fvalue = (Float) int_val(value); \
00070 else if (isofloat(value)) fvalue = ofloat_val(value); \
00071 else if (isboxedinteger(value)) fvalue = (Float) boxedint_val(value); \
00072 else return 0
00073
00074 extern inline void bld_boxedfloat(CTXTdeclc CPtr, Float);
00075
00076 int unifunc_call(CTXTdeclc int funcnum, CPtr regaddr)
00077 {
00078 Cell value;
00079 Float fvalue;
00080 prolog_int ivalue;
00081
00082 value = cell(regaddr);
00083 XSB_Deref(value);
00084 switch (funcnum) {
00085 case FUN_float:
00086 set_fvalue_from_value;
00087 bld_boxedfloat(CTXTc regaddr, fvalue);
00088 break;
00089 case FUN_floor:
00090 set_fvalue_from_value;
00091 ivalue = (prolog_int) floor(fvalue);
00092 bld_oint(regaddr, ivalue);
00093 break;
00094 case FUN_PLUS:
00095 case FUN_MINUS:
00096 case FUN_TIMES:
00097 case FUN_DIVIDE:
00098 case FUN_AND:
00099 case FUN_OR:
00100 return 0;
00101 case FUN_sin:
00102 set_fvalue_from_value;
00103 fvalue = sin(fvalue);
00104 bld_boxedfloat(CTXTc regaddr, fvalue);
00105 break;
00106 case FUN_cos:
00107 set_fvalue_from_value;
00108 fvalue = cos(fvalue);
00109 bld_boxedfloat(CTXTc regaddr, fvalue);
00110 break;
00111 case FUN_tan:
00112 set_fvalue_from_value;
00113 fvalue = tan(fvalue);
00114 bld_boxedfloat(CTXTc regaddr, fvalue);
00115 break;
00116 case FUN_exp:
00117 set_fvalue_from_value;
00118 fvalue = exp(fvalue);
00119 bld_boxedfloat(CTXTc regaddr, fvalue);
00120 break;
00121 case FUN_log:
00122 set_fvalue_from_value;
00123 fvalue = log(fvalue);
00124 bld_boxedfloat(CTXTc regaddr, fvalue);
00125 break;
00126 case FUN_log10:
00127 set_fvalue_from_value;
00128 fvalue = log10(fvalue);
00129 bld_boxedfloat(CTXTc regaddr, fvalue);
00130 break;
00131 case FUN_sqrt:
00132 set_fvalue_from_value;
00133 fvalue = sqrt(fvalue);
00134 bld_boxedfloat(CTXTc regaddr, fvalue);
00135 break;
00136 case FUN_asin:
00137 set_fvalue_from_value;
00138 fvalue = asin(fvalue);
00139 bld_boxedfloat(CTXTc regaddr, fvalue);
00140 break;
00141 case FUN_acos:
00142 set_fvalue_from_value;
00143 fvalue = acos(fvalue);
00144 bld_boxedfloat(CTXTc regaddr, fvalue);
00145 break;
00146 case FUN_atan:
00147 set_fvalue_from_value;
00148 fvalue = atan(fvalue);
00149 bld_boxedfloat(CTXTc regaddr, fvalue);
00150 break;
00151 case FUN_abs:
00152 if (isinteger(value)) {
00153 ivalue = int_val(value);
00154 if (ivalue > 0)
00155 bld_int(regaddr,ivalue);
00156 else bld_int(regaddr,-ivalue);
00157 }
00158 else if (isboxedinteger(value)) {
00159 ivalue = boxedint_val(value);
00160 if (ivalue > 0)
00161 {bld_oint(regaddr,ivalue)}
00162 else bld_oint(regaddr,-ivalue);
00163 }
00164 else if (isofloat(value) ) {
00165 fvalue = ofloat_val(value);
00166 if (fvalue > 0)
00167 {
00168 bld_boxedfloat(CTXTc regaddr,fvalue);
00169 }
00170 else
00171 {
00172 fvalue = -fvalue;
00173 bld_boxedfloat(CTXTc regaddr,fvalue);
00174 }
00175 } else return 0;
00176 break;
00177 case FUN_truncate:
00178 if (isinteger(value)) {
00179 ivalue = int_val(value);
00180 bld_int(regaddr,ivalue);
00181 }
00182 else if (isboxedinteger(value)) {
00183 ivalue = boxedint_val(value);
00184 bld_oint(regaddr,ivalue);
00185 }
00186 else if (isofloat(value)) {
00187 fvalue = ofloat_val(value);
00188 if (fvalue > 0)
00189 {
00190 ivalue = (prolog_int) floor(fvalue);
00191 bld_oint(regaddr,ivalue);
00192 }
00193 else
00194 {
00195 ivalue = (prolog_int) -floor(-fvalue);
00196 bld_oint(regaddr,ivalue);
00197 }
00198 } else return 0;
00199 break;
00200 case FUN_round:
00201 if (isinteger(value)) {
00202 ivalue = int_val(value);
00203 bld_int(regaddr,ivalue);
00204 }
00205 else if (isboxedinteger(value)) {
00206 ivalue = boxedint_val(value);
00207 bld_oint(regaddr,ivalue);
00208 }
00209 else if (isofloat(value)) {
00210 fvalue = ofloat_val(value);
00211 ivalue = (prolog_int) floor(fvalue+0.5);
00212 bld_oint(regaddr, ivalue);
00213 } else return 0;
00214 break;
00215 case FUN_ceiling:
00216 if (isinteger(value)) {
00217 ivalue = int_val(value);
00218 bld_int(regaddr,ivalue);
00219 }
00220 else if (isboxedinteger(value)) {
00221 ivalue = boxedint_val(value);
00222 bld_oint(regaddr,ivalue);
00223 }
00224 else if (isofloat(value)) {
00225 fvalue = ofloat_val(value);
00226 ivalue = (prolog_int) -floor(-fvalue);
00227 bld_oint(regaddr,ivalue);
00228 } else return 0;
00229 break;
00230 default: return 0;
00231 }
00232 return 1;
00233 }