clipsruby 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/ext/clipsruby/agenda.c +1373 -0
  3. data/ext/clipsruby/agenda.h +169 -0
  4. data/ext/clipsruby/analysis.c +1142 -0
  5. data/ext/clipsruby/analysis.h +61 -0
  6. data/ext/clipsruby/argacces.c +526 -0
  7. data/ext/clipsruby/argacces.h +77 -0
  8. data/ext/clipsruby/bload.c +884 -0
  9. data/ext/clipsruby/bload.h +94 -0
  10. data/ext/clipsruby/bmathfun.c +557 -0
  11. data/ext/clipsruby/bmathfun.h +66 -0
  12. data/ext/clipsruby/bsave.c +634 -0
  13. data/ext/clipsruby/bsave.h +130 -0
  14. data/ext/clipsruby/classcom.c +976 -0
  15. data/ext/clipsruby/classcom.h +115 -0
  16. data/ext/clipsruby/classexm.c +1376 -0
  17. data/ext/clipsruby/classexm.h +97 -0
  18. data/ext/clipsruby/classfun.c +1392 -0
  19. data/ext/clipsruby/classfun.h +164 -0
  20. data/ext/clipsruby/classinf.c +1245 -0
  21. data/ext/clipsruby/classinf.h +94 -0
  22. data/ext/clipsruby/classini.c +843 -0
  23. data/ext/clipsruby/classini.h +75 -0
  24. data/ext/clipsruby/classpsr.c +957 -0
  25. data/ext/clipsruby/classpsr.h +73 -0
  26. data/ext/clipsruby/clips.h +133 -0
  27. data/ext/clipsruby/clipsruby.c +619 -0
  28. data/ext/clipsruby/clsltpsr.c +931 -0
  29. data/ext/clipsruby/clsltpsr.h +72 -0
  30. data/ext/clipsruby/commline.c +1217 -0
  31. data/ext/clipsruby/commline.h +131 -0
  32. data/ext/clipsruby/conscomp.c +1593 -0
  33. data/ext/clipsruby/conscomp.h +150 -0
  34. data/ext/clipsruby/constant.h +264 -0
  35. data/ext/clipsruby/constrct.c +1090 -0
  36. data/ext/clipsruby/constrct.h +216 -0
  37. data/ext/clipsruby/constrnt.c +554 -0
  38. data/ext/clipsruby/constrnt.h +132 -0
  39. data/ext/clipsruby/crstrtgy.c +1088 -0
  40. data/ext/clipsruby/crstrtgy.h +85 -0
  41. data/ext/clipsruby/cstrcbin.c +185 -0
  42. data/ext/clipsruby/cstrcbin.h +61 -0
  43. data/ext/clipsruby/cstrccmp.h +43 -0
  44. data/ext/clipsruby/cstrccom.c +1791 -0
  45. data/ext/clipsruby/cstrccom.h +115 -0
  46. data/ext/clipsruby/cstrcpsr.c +835 -0
  47. data/ext/clipsruby/cstrcpsr.h +97 -0
  48. data/ext/clipsruby/cstrnbin.c +282 -0
  49. data/ext/clipsruby/cstrnbin.h +55 -0
  50. data/ext/clipsruby/cstrnchk.c +826 -0
  51. data/ext/clipsruby/cstrnchk.h +91 -0
  52. data/ext/clipsruby/cstrncmp.c +238 -0
  53. data/ext/clipsruby/cstrncmp.h +57 -0
  54. data/ext/clipsruby/cstrnops.c +1176 -0
  55. data/ext/clipsruby/cstrnops.h +47 -0
  56. data/ext/clipsruby/cstrnpsr.c +1394 -0
  57. data/ext/clipsruby/cstrnpsr.h +88 -0
  58. data/ext/clipsruby/cstrnutl.c +564 -0
  59. data/ext/clipsruby/cstrnutl.h +54 -0
  60. data/ext/clipsruby/default.c +454 -0
  61. data/ext/clipsruby/default.h +57 -0
  62. data/ext/clipsruby/defins.c +971 -0
  63. data/ext/clipsruby/defins.h +127 -0
  64. data/ext/clipsruby/developr.c +677 -0
  65. data/ext/clipsruby/developr.h +69 -0
  66. data/ext/clipsruby/dffctbin.c +477 -0
  67. data/ext/clipsruby/dffctbin.h +76 -0
  68. data/ext/clipsruby/dffctbsc.c +308 -0
  69. data/ext/clipsruby/dffctbsc.h +72 -0
  70. data/ext/clipsruby/dffctcmp.c +297 -0
  71. data/ext/clipsruby/dffctcmp.h +44 -0
  72. data/ext/clipsruby/dffctdef.c +364 -0
  73. data/ext/clipsruby/dffctdef.h +104 -0
  74. data/ext/clipsruby/dffctpsr.c +179 -0
  75. data/ext/clipsruby/dffctpsr.h +49 -0
  76. data/ext/clipsruby/dffnxbin.c +520 -0
  77. data/ext/clipsruby/dffnxbin.h +67 -0
  78. data/ext/clipsruby/dffnxcmp.c +378 -0
  79. data/ext/clipsruby/dffnxcmp.h +54 -0
  80. data/ext/clipsruby/dffnxexe.c +241 -0
  81. data/ext/clipsruby/dffnxexe.h +58 -0
  82. data/ext/clipsruby/dffnxfun.c +1192 -0
  83. data/ext/clipsruby/dffnxfun.h +155 -0
  84. data/ext/clipsruby/dffnxpsr.c +514 -0
  85. data/ext/clipsruby/dffnxpsr.h +57 -0
  86. data/ext/clipsruby/dfinsbin.c +509 -0
  87. data/ext/clipsruby/dfinsbin.h +66 -0
  88. data/ext/clipsruby/dfinscmp.c +345 -0
  89. data/ext/clipsruby/dfinscmp.h +48 -0
  90. data/ext/clipsruby/drive.c +1191 -0
  91. data/ext/clipsruby/drive.h +65 -0
  92. data/ext/clipsruby/emathfun.c +1213 -0
  93. data/ext/clipsruby/emathfun.h +99 -0
  94. data/ext/clipsruby/engine.c +1568 -0
  95. data/ext/clipsruby/engine.h +203 -0
  96. data/ext/clipsruby/entities.h +276 -0
  97. data/ext/clipsruby/envrnbld.c +514 -0
  98. data/ext/clipsruby/envrnbld.h +40 -0
  99. data/ext/clipsruby/envrnmnt.c +257 -0
  100. data/ext/clipsruby/envrnmnt.h +112 -0
  101. data/ext/clipsruby/evaluatn.c +1736 -0
  102. data/ext/clipsruby/evaluatn.h +211 -0
  103. data/ext/clipsruby/expressn.c +494 -0
  104. data/ext/clipsruby/expressn.h +154 -0
  105. data/ext/clipsruby/exprnbin.c +538 -0
  106. data/ext/clipsruby/exprnbin.h +60 -0
  107. data/ext/clipsruby/exprnops.c +564 -0
  108. data/ext/clipsruby/exprnops.h +67 -0
  109. data/ext/clipsruby/exprnpsr.c +1112 -0
  110. data/ext/clipsruby/exprnpsr.h +98 -0
  111. data/ext/clipsruby/extconf.rb +2 -0
  112. data/ext/clipsruby/extnfunc.c +1015 -0
  113. data/ext/clipsruby/extnfunc.h +157 -0
  114. data/ext/clipsruby/factbin.c +447 -0
  115. data/ext/clipsruby/factbin.h +56 -0
  116. data/ext/clipsruby/factbld.c +1035 -0
  117. data/ext/clipsruby/factbld.h +63 -0
  118. data/ext/clipsruby/factcmp.c +386 -0
  119. data/ext/clipsruby/factcmp.h +46 -0
  120. data/ext/clipsruby/factcom.c +759 -0
  121. data/ext/clipsruby/factcom.h +80 -0
  122. data/ext/clipsruby/factfile.c +1761 -0
  123. data/ext/clipsruby/factfile.h +54 -0
  124. data/ext/clipsruby/factfun.c +682 -0
  125. data/ext/clipsruby/factfun.h +77 -0
  126. data/ext/clipsruby/factgen.c +1305 -0
  127. data/ext/clipsruby/factgen.h +229 -0
  128. data/ext/clipsruby/facthsh.c +438 -0
  129. data/ext/clipsruby/facthsh.h +81 -0
  130. data/ext/clipsruby/factlhs.c +250 -0
  131. data/ext/clipsruby/factlhs.h +54 -0
  132. data/ext/clipsruby/factmch.c +905 -0
  133. data/ext/clipsruby/factmch.h +68 -0
  134. data/ext/clipsruby/factmngr.c +3373 -0
  135. data/ext/clipsruby/factmngr.h +325 -0
  136. data/ext/clipsruby/factprt.c +498 -0
  137. data/ext/clipsruby/factprt.h +60 -0
  138. data/ext/clipsruby/factqpsr.c +796 -0
  139. data/ext/clipsruby/factqpsr.h +61 -0
  140. data/ext/clipsruby/factqury.c +1267 -0
  141. data/ext/clipsruby/factqury.h +112 -0
  142. data/ext/clipsruby/factrete.c +978 -0
  143. data/ext/clipsruby/factrete.h +70 -0
  144. data/ext/clipsruby/factrhs.c +667 -0
  145. data/ext/clipsruby/factrhs.h +55 -0
  146. data/ext/clipsruby/filecom.c +353 -0
  147. data/ext/clipsruby/filecom.h +137 -0
  148. data/ext/clipsruby/filertr.c +481 -0
  149. data/ext/clipsruby/filertr.h +94 -0
  150. data/ext/clipsruby/fileutil.c +1020 -0
  151. data/ext/clipsruby/fileutil.h +50 -0
  152. data/ext/clipsruby/generate.c +1079 -0
  153. data/ext/clipsruby/generate.h +57 -0
  154. data/ext/clipsruby/genrcbin.c +902 -0
  155. data/ext/clipsruby/genrcbin.h +69 -0
  156. data/ext/clipsruby/genrccmp.c +640 -0
  157. data/ext/clipsruby/genrccmp.h +59 -0
  158. data/ext/clipsruby/genrccom.c +2017 -0
  159. data/ext/clipsruby/genrccom.h +119 -0
  160. data/ext/clipsruby/genrcexe.c +737 -0
  161. data/ext/clipsruby/genrcexe.h +73 -0
  162. data/ext/clipsruby/genrcfun.c +890 -0
  163. data/ext/clipsruby/genrcfun.h +185 -0
  164. data/ext/clipsruby/genrcpsr.c +1618 -0
  165. data/ext/clipsruby/genrcpsr.h +80 -0
  166. data/ext/clipsruby/globlbin.c +458 -0
  167. data/ext/clipsruby/globlbin.h +71 -0
  168. data/ext/clipsruby/globlbsc.c +361 -0
  169. data/ext/clipsruby/globlbsc.h +83 -0
  170. data/ext/clipsruby/globlcmp.c +330 -0
  171. data/ext/clipsruby/globlcmp.h +52 -0
  172. data/ext/clipsruby/globlcom.c +289 -0
  173. data/ext/clipsruby/globlcom.h +63 -0
  174. data/ext/clipsruby/globldef.c +1087 -0
  175. data/ext/clipsruby/globldef.h +151 -0
  176. data/ext/clipsruby/globlpsr.c +530 -0
  177. data/ext/clipsruby/globlpsr.h +59 -0
  178. data/ext/clipsruby/immthpsr.c +431 -0
  179. data/ext/clipsruby/immthpsr.h +55 -0
  180. data/ext/clipsruby/incrrset.c +530 -0
  181. data/ext/clipsruby/incrrset.h +73 -0
  182. data/ext/clipsruby/inherpsr.c +850 -0
  183. data/ext/clipsruby/inherpsr.h +52 -0
  184. data/ext/clipsruby/inscom.c +2076 -0
  185. data/ext/clipsruby/inscom.h +182 -0
  186. data/ext/clipsruby/insfile.c +1764 -0
  187. data/ext/clipsruby/insfile.h +96 -0
  188. data/ext/clipsruby/insfun.c +1451 -0
  189. data/ext/clipsruby/insfun.h +134 -0
  190. data/ext/clipsruby/insmngr.c +2550 -0
  191. data/ext/clipsruby/insmngr.h +125 -0
  192. data/ext/clipsruby/insmoddp.c +1041 -0
  193. data/ext/clipsruby/insmoddp.h +91 -0
  194. data/ext/clipsruby/insmult.c +804 -0
  195. data/ext/clipsruby/insmult.h +62 -0
  196. data/ext/clipsruby/inspsr.c +602 -0
  197. data/ext/clipsruby/inspsr.h +60 -0
  198. data/ext/clipsruby/insquery.c +1278 -0
  199. data/ext/clipsruby/insquery.h +115 -0
  200. data/ext/clipsruby/insqypsr.c +729 -0
  201. data/ext/clipsruby/insqypsr.h +63 -0
  202. data/ext/clipsruby/iofun.c +2045 -0
  203. data/ext/clipsruby/iofun.h +116 -0
  204. data/ext/clipsruby/lgcldpnd.c +644 -0
  205. data/ext/clipsruby/lgcldpnd.h +75 -0
  206. data/ext/clipsruby/main.c +112 -0
  207. data/ext/clipsruby/match.h +142 -0
  208. data/ext/clipsruby/memalloc.c +481 -0
  209. data/ext/clipsruby/memalloc.h +197 -0
  210. data/ext/clipsruby/miscfun.c +1801 -0
  211. data/ext/clipsruby/miscfun.h +132 -0
  212. data/ext/clipsruby/modulbin.c +607 -0
  213. data/ext/clipsruby/modulbin.h +84 -0
  214. data/ext/clipsruby/modulbsc.c +347 -0
  215. data/ext/clipsruby/modulbsc.h +67 -0
  216. data/ext/clipsruby/modulcmp.c +499 -0
  217. data/ext/clipsruby/modulcmp.h +54 -0
  218. data/ext/clipsruby/moduldef.c +817 -0
  219. data/ext/clipsruby/moduldef.h +271 -0
  220. data/ext/clipsruby/modulpsr.c +1150 -0
  221. data/ext/clipsruby/modulpsr.h +69 -0
  222. data/ext/clipsruby/modulutl.c +1036 -0
  223. data/ext/clipsruby/modulutl.h +84 -0
  224. data/ext/clipsruby/msgcom.c +1221 -0
  225. data/ext/clipsruby/msgcom.h +125 -0
  226. data/ext/clipsruby/msgfun.c +1076 -0
  227. data/ext/clipsruby/msgfun.h +118 -0
  228. data/ext/clipsruby/msgpass.c +1441 -0
  229. data/ext/clipsruby/msgpass.h +103 -0
  230. data/ext/clipsruby/msgpsr.c +698 -0
  231. data/ext/clipsruby/msgpsr.h +73 -0
  232. data/ext/clipsruby/multifld.c +1404 -0
  233. data/ext/clipsruby/multifld.h +130 -0
  234. data/ext/clipsruby/multifun.c +2182 -0
  235. data/ext/clipsruby/multifun.h +102 -0
  236. data/ext/clipsruby/network.h +142 -0
  237. data/ext/clipsruby/objbin.c +1522 -0
  238. data/ext/clipsruby/objbin.h +79 -0
  239. data/ext/clipsruby/objcmp.c +1507 -0
  240. data/ext/clipsruby/objcmp.h +71 -0
  241. data/ext/clipsruby/object.h +260 -0
  242. data/ext/clipsruby/objrtbin.c +701 -0
  243. data/ext/clipsruby/objrtbin.h +79 -0
  244. data/ext/clipsruby/objrtbld.c +2393 -0
  245. data/ext/clipsruby/objrtbld.h +66 -0
  246. data/ext/clipsruby/objrtcmp.c +734 -0
  247. data/ext/clipsruby/objrtcmp.h +66 -0
  248. data/ext/clipsruby/objrtfnx.c +1330 -0
  249. data/ext/clipsruby/objrtfnx.h +222 -0
  250. data/ext/clipsruby/objrtgen.c +736 -0
  251. data/ext/clipsruby/objrtgen.h +63 -0
  252. data/ext/clipsruby/objrtmch.c +1524 -0
  253. data/ext/clipsruby/objrtmch.h +160 -0
  254. data/ext/clipsruby/parsefun.c +415 -0
  255. data/ext/clipsruby/parsefun.h +67 -0
  256. data/ext/clipsruby/pattern.c +1265 -0
  257. data/ext/clipsruby/pattern.h +163 -0
  258. data/ext/clipsruby/pprint.c +328 -0
  259. data/ext/clipsruby/pprint.h +79 -0
  260. data/ext/clipsruby/prccode.c +1478 -0
  261. data/ext/clipsruby/prccode.h +145 -0
  262. data/ext/clipsruby/prcdrfun.c +640 -0
  263. data/ext/clipsruby/prcdrfun.h +95 -0
  264. data/ext/clipsruby/prcdrpsr.c +1068 -0
  265. data/ext/clipsruby/prcdrpsr.h +79 -0
  266. data/ext/clipsruby/prdctfun.c +869 -0
  267. data/ext/clipsruby/prdctfun.h +77 -0
  268. data/ext/clipsruby/prntutil.c +878 -0
  269. data/ext/clipsruby/prntutil.h +125 -0
  270. data/ext/clipsruby/proflfun.c +827 -0
  271. data/ext/clipsruby/proflfun.h +118 -0
  272. data/ext/clipsruby/reorder.c +2082 -0
  273. data/ext/clipsruby/reorder.h +172 -0
  274. data/ext/clipsruby/reteutil.c +1732 -0
  275. data/ext/clipsruby/reteutil.h +111 -0
  276. data/ext/clipsruby/retract.c +710 -0
  277. data/ext/clipsruby/retract.h +74 -0
  278. data/ext/clipsruby/router.c +737 -0
  279. data/ext/clipsruby/router.h +147 -0
  280. data/ext/clipsruby/rulebin.c +1136 -0
  281. data/ext/clipsruby/rulebin.h +153 -0
  282. data/ext/clipsruby/rulebld.c +1328 -0
  283. data/ext/clipsruby/rulebld.h +62 -0
  284. data/ext/clipsruby/rulebsc.c +517 -0
  285. data/ext/clipsruby/rulebsc.h +91 -0
  286. data/ext/clipsruby/rulecmp.c +733 -0
  287. data/ext/clipsruby/rulecmp.h +63 -0
  288. data/ext/clipsruby/rulecom.c +1583 -0
  289. data/ext/clipsruby/rulecom.h +116 -0
  290. data/ext/clipsruby/rulecstr.c +892 -0
  291. data/ext/clipsruby/rulecstr.h +53 -0
  292. data/ext/clipsruby/ruledef.c +559 -0
  293. data/ext/clipsruby/ruledef.h +179 -0
  294. data/ext/clipsruby/ruledlt.c +599 -0
  295. data/ext/clipsruby/ruledlt.h +58 -0
  296. data/ext/clipsruby/rulelhs.c +1216 -0
  297. data/ext/clipsruby/rulelhs.h +52 -0
  298. data/ext/clipsruby/rulepsr.c +1073 -0
  299. data/ext/clipsruby/rulepsr.h +61 -0
  300. data/ext/clipsruby/scanner.c +856 -0
  301. data/ext/clipsruby/scanner.h +112 -0
  302. data/ext/clipsruby/setup.h +488 -0
  303. data/ext/clipsruby/sortfun.c +433 -0
  304. data/ext/clipsruby/sortfun.h +55 -0
  305. data/ext/clipsruby/strngfun.c +1173 -0
  306. data/ext/clipsruby/strngfun.h +96 -0
  307. data/ext/clipsruby/strngrtr.c +523 -0
  308. data/ext/clipsruby/strngrtr.h +97 -0
  309. data/ext/clipsruby/symblbin.c +648 -0
  310. data/ext/clipsruby/symblbin.h +64 -0
  311. data/ext/clipsruby/symblcmp.c +893 -0
  312. data/ext/clipsruby/symblcmp.h +61 -0
  313. data/ext/clipsruby/symbol.c +1961 -0
  314. data/ext/clipsruby/symbol.h +243 -0
  315. data/ext/clipsruby/sysdep.c +894 -0
  316. data/ext/clipsruby/sysdep.h +164 -0
  317. data/ext/clipsruby/textpro.c +1388 -0
  318. data/ext/clipsruby/textpro.h +77 -0
  319. data/ext/clipsruby/tmpltbin.c +609 -0
  320. data/ext/clipsruby/tmpltbin.h +108 -0
  321. data/ext/clipsruby/tmpltbsc.c +327 -0
  322. data/ext/clipsruby/tmpltbsc.h +87 -0
  323. data/ext/clipsruby/tmpltcmp.c +450 -0
  324. data/ext/clipsruby/tmpltcmp.h +57 -0
  325. data/ext/clipsruby/tmpltdef.c +584 -0
  326. data/ext/clipsruby/tmpltdef.h +155 -0
  327. data/ext/clipsruby/tmpltfun.c +2477 -0
  328. data/ext/clipsruby/tmpltfun.h +122 -0
  329. data/ext/clipsruby/tmpltlhs.c +379 -0
  330. data/ext/clipsruby/tmpltlhs.h +50 -0
  331. data/ext/clipsruby/tmpltpsr.c +819 -0
  332. data/ext/clipsruby/tmpltpsr.h +59 -0
  333. data/ext/clipsruby/tmpltrhs.c +595 -0
  334. data/ext/clipsruby/tmpltrhs.h +55 -0
  335. data/ext/clipsruby/tmpltutl.c +637 -0
  336. data/ext/clipsruby/tmpltutl.h +82 -0
  337. data/ext/clipsruby/userdata.c +156 -0
  338. data/ext/clipsruby/userdata.h +72 -0
  339. data/ext/clipsruby/userfunctions.c +70 -0
  340. data/ext/clipsruby/usrsetup.h +7 -0
  341. data/ext/clipsruby/utility.c +1594 -0
  342. data/ext/clipsruby/utility.h +250 -0
  343. data/ext/clipsruby/watch.c +865 -0
  344. data/ext/clipsruby/watch.h +124 -0
  345. data/lib/clipsruby.rb +1 -0
  346. metadata +388 -0
@@ -0,0 +1,1736 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.41 12/04/22 */
5
+ /* */
6
+ /* EVALUATION MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Provides routines for evaluating expressions. */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Gary D. Riley */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* Brian L. Dantes */
17
+ /* */
18
+ /* Revision History: */
19
+ /* */
20
+ /* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
21
+ /* */
22
+ /* 6.24: Renamed BOOLEAN macro type to intBool. */
23
+ /* */
24
+ /* Added EvaluateAndStoreInDataObject function. */
25
+ /* */
26
+ /* 6.30: Added support for passing context information */
27
+ /* to user defined functions. */
28
+ /* */
29
+ /* Added support for external address hash table */
30
+ /* and subtyping. */
31
+ /* */
32
+ /* Changed integer type/precision. */
33
+ /* */
34
+ /* Support for long long integers. */
35
+ /* */
36
+ /* Changed garbage collection algorithm. */
37
+ /* */
38
+ /* Support for DATA_OBJECT_ARRAY primitive. */
39
+ /* */
40
+ /* Added const qualifiers to remove C++ */
41
+ /* deprecation warnings. */
42
+ /* */
43
+ /* Converted API macros to function calls. */
44
+ /* */
45
+ /* 6.40: Added Env prefix to GetEvaluationError and */
46
+ /* SetEvaluationError functions. */
47
+ /* */
48
+ /* Added Env prefix to GetHaltExecution and */
49
+ /* SetHaltExecution functions. */
50
+ /* */
51
+ /* Pragma once and other inclusion changes. */
52
+ /* */
53
+ /* Added support for booleans with <stdbool.h>. */
54
+ /* */
55
+ /* Removed use of void pointers for specific */
56
+ /* data structures. */
57
+ /* */
58
+ /* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
59
+ /* */
60
+ /* Callbacks must be environment aware. */
61
+ /* */
62
+ /* UDF redesign. */
63
+ /* */
64
+ /* Removed DATA_OBJECT_ARRAY primitive type. */
65
+ /* */
66
+ /* Modified GetFunctionReference to handle module */
67
+ /* specifier for funcall. */
68
+ /* */
69
+ /* 6.41: Added FCBPopArgument function. */
70
+ /* */
71
+ /* Used gensnprintf in place of gensprintf and. */
72
+ /* sprintf. */
73
+ /* */
74
+ /*************************************************************/
75
+
76
+ #include <stdio.h>
77
+ #include <stdint.h>
78
+ #include <stdlib.h>
79
+ #include <string.h>
80
+ #include <ctype.h>
81
+
82
+ #include "setup.h"
83
+
84
+ #include "argacces.h"
85
+ #include "commline.h"
86
+ #include "constant.h"
87
+ #include "envrnmnt.h"
88
+ #include "factmngr.h"
89
+ #include "memalloc.h"
90
+ #include "modulutl.h"
91
+ #include "router.h"
92
+ #include "prcdrfun.h"
93
+ #include "multifld.h"
94
+ #include "prntutil.h"
95
+ #include "exprnpsr.h"
96
+ #include "utility.h"
97
+ #include "proflfun.h"
98
+ #include "sysdep.h"
99
+
100
+ #if DEFFUNCTION_CONSTRUCT
101
+ #include "dffnxfun.h"
102
+ #endif
103
+
104
+ #if DEFGENERIC_CONSTRUCT
105
+ #include "genrccom.h"
106
+ #endif
107
+
108
+ #if OBJECT_SYSTEM
109
+ #include "object.h"
110
+ #include "inscom.h"
111
+ #endif
112
+
113
+ #include "evaluatn.h"
114
+
115
+ /***************************************/
116
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
117
+ /***************************************/
118
+
119
+ static void DeallocateEvaluationData(Environment *);
120
+ static void PrintCAddress(Environment *,const char *,void *);
121
+ static void NewCAddress(UDFContext *,UDFValue *);
122
+ /*
123
+ static bool DiscardCAddress(void *,void *);
124
+ */
125
+
126
+ /**************************************************/
127
+ /* InitializeEvaluationData: Allocates environment */
128
+ /* data for expression evaluation. */
129
+ /**************************************************/
130
+ void InitializeEvaluationData(
131
+ Environment *theEnv)
132
+ {
133
+ struct externalAddressType cPointer = { "C", PrintCAddress, PrintCAddress, NULL, NewCAddress, NULL };
134
+
135
+ AllocateEnvironmentData(theEnv,EVALUATION_DATA,sizeof(struct evaluationData),DeallocateEvaluationData);
136
+
137
+ InstallExternalAddressType(theEnv,&cPointer);
138
+ }
139
+
140
+ /*****************************************************/
141
+ /* DeallocateEvaluationData: Deallocates environment */
142
+ /* data for evaluation data. */
143
+ /*****************************************************/
144
+ static void DeallocateEvaluationData(
145
+ Environment *theEnv)
146
+ {
147
+ int i;
148
+
149
+ for (i = 0; i < EvaluationData(theEnv)->numberOfAddressTypes; i++)
150
+ { rtn_struct(theEnv,externalAddressType,EvaluationData(theEnv)->ExternalAddressTypes[i]); }
151
+ }
152
+
153
+ /**************************************************************/
154
+ /* EvaluateExpression: Evaluates an expression. Returns false */
155
+ /* if no errors occurred during evaluation, otherwise true. */
156
+ /**************************************************************/
157
+ bool EvaluateExpression(
158
+ Environment *theEnv,
159
+ struct expr *problem,
160
+ UDFValue *returnValue)
161
+ {
162
+ struct expr *oldArgument;
163
+ struct functionDefinition *fptr;
164
+ UDFContext theUDFContext;
165
+ #if PROFILING_FUNCTIONS
166
+ struct profileFrameInfo profileFrame;
167
+ #endif
168
+
169
+ returnValue->voidValue = VoidConstant(theEnv);
170
+ returnValue->begin = 0;
171
+ returnValue->range = SIZE_MAX;
172
+
173
+ if (problem == NULL)
174
+ {
175
+ returnValue->value = FalseSymbol(theEnv);
176
+ return(EvaluationData(theEnv)->EvaluationError);
177
+ }
178
+
179
+ switch (problem->type)
180
+ {
181
+ case STRING_TYPE:
182
+ case SYMBOL_TYPE:
183
+ case FLOAT_TYPE:
184
+ case INTEGER_TYPE:
185
+ #if OBJECT_SYSTEM
186
+ case INSTANCE_NAME_TYPE:
187
+ case INSTANCE_ADDRESS_TYPE:
188
+ #endif
189
+ case FACT_ADDRESS_TYPE:
190
+ case EXTERNAL_ADDRESS_TYPE:
191
+ returnValue->value = problem->value;
192
+ break;
193
+
194
+ case FCALL:
195
+ {
196
+ fptr = problem->functionValue;
197
+
198
+ #if PROFILING_FUNCTIONS
199
+ StartProfile(theEnv,&profileFrame,
200
+ &fptr->usrData,
201
+ ProfileFunctionData(theEnv)->ProfileUserFunctions);
202
+ #endif
203
+
204
+ oldArgument = EvaluationData(theEnv)->CurrentExpression;
205
+ EvaluationData(theEnv)->CurrentExpression = problem;
206
+
207
+ theUDFContext.environment = theEnv;
208
+ theUDFContext.context = fptr->context;
209
+ theUDFContext.theFunction = fptr;
210
+ theUDFContext.lastArg = problem->argList;
211
+ theUDFContext.lastPosition = 1;
212
+ theUDFContext.returnValue = returnValue;
213
+ fptr->functionPointer(theEnv,&theUDFContext,returnValue);
214
+ if ((returnValue->header->type == MULTIFIELD_TYPE) &&
215
+ (returnValue->range == SIZE_MAX))
216
+ { returnValue->range = returnValue->multifieldValue->length; }
217
+
218
+ #if PROFILING_FUNCTIONS
219
+ EndProfile(theEnv,&profileFrame);
220
+ #endif
221
+
222
+ EvaluationData(theEnv)->CurrentExpression = oldArgument;
223
+ break;
224
+ }
225
+
226
+ case MULTIFIELD_TYPE:
227
+ returnValue->value = ((UDFValue *) (problem->value))->value;
228
+ returnValue->begin = ((UDFValue *) (problem->value))->begin;
229
+ returnValue->range = ((UDFValue *) (problem->value))->range;
230
+ break;
231
+
232
+ case MF_VARIABLE:
233
+ case SF_VARIABLE:
234
+ if (GetBoundVariable(theEnv,returnValue,problem->lexemeValue) == false)
235
+ {
236
+ PrintErrorID(theEnv,"EVALUATN",1,false);
237
+ WriteString(theEnv,STDERR,"Variable ");
238
+ if (problem->type == MF_VARIABLE)
239
+ { WriteString(theEnv,STDERR,"$?"); }
240
+ else
241
+ { WriteString(theEnv,STDERR,"?"); }
242
+ WriteString(theEnv,STDERR,problem->lexemeValue->contents);
243
+ WriteString(theEnv,STDERR," is unbound.\n");
244
+ returnValue->value = FalseSymbol(theEnv);
245
+ SetEvaluationError(theEnv,true);
246
+ }
247
+ break;
248
+
249
+ default:
250
+ if (EvaluationData(theEnv)->PrimitivesArray[problem->type] == NULL)
251
+ {
252
+ SystemError(theEnv,"EVALUATN",3);
253
+ ExitRouter(theEnv,EXIT_FAILURE);
254
+ }
255
+
256
+ if (EvaluationData(theEnv)->PrimitivesArray[problem->type]->copyToEvaluate)
257
+ {
258
+ returnValue->value = problem->value;
259
+ break;
260
+ }
261
+
262
+ if (EvaluationData(theEnv)->PrimitivesArray[problem->type]->evaluateFunction == NULL)
263
+ {
264
+ SystemError(theEnv,"EVALUATN",4);
265
+ ExitRouter(theEnv,EXIT_FAILURE);
266
+ }
267
+
268
+ oldArgument = EvaluationData(theEnv)->CurrentExpression;
269
+ EvaluationData(theEnv)->CurrentExpression = problem;
270
+
271
+ #if PROFILING_FUNCTIONS
272
+ StartProfile(theEnv,&profileFrame,
273
+ &EvaluationData(theEnv)->PrimitivesArray[problem->type]->usrData,
274
+ ProfileFunctionData(theEnv)->ProfileUserFunctions);
275
+ #endif
276
+
277
+ (*EvaluationData(theEnv)->PrimitivesArray[problem->type]->evaluateFunction)(theEnv,problem->value,returnValue);
278
+
279
+ #if PROFILING_FUNCTIONS
280
+ EndProfile(theEnv,&profileFrame);
281
+ #endif
282
+
283
+ EvaluationData(theEnv)->CurrentExpression = oldArgument;
284
+ break;
285
+ }
286
+
287
+ return EvaluationData(theEnv)->EvaluationError;
288
+ }
289
+
290
+ /******************************************/
291
+ /* InstallPrimitive: Installs a primitive */
292
+ /* data type in the primitives array. */
293
+ /******************************************/
294
+ void InstallPrimitive(
295
+ Environment *theEnv,
296
+ struct entityRecord *thePrimitive,
297
+ int whichPosition)
298
+ {
299
+ if (EvaluationData(theEnv)->PrimitivesArray[whichPosition] != NULL)
300
+ {
301
+ SystemError(theEnv,"EVALUATN",5);
302
+ ExitRouter(theEnv,EXIT_FAILURE);
303
+ }
304
+
305
+ EvaluationData(theEnv)->PrimitivesArray[whichPosition] = thePrimitive;
306
+ }
307
+
308
+ /******************************************************/
309
+ /* InstallExternalAddressType: Installs an external */
310
+ /* address type in the external address type array. */
311
+ /******************************************************/
312
+ int InstallExternalAddressType(
313
+ Environment *theEnv,
314
+ struct externalAddressType *theAddressType)
315
+ {
316
+ struct externalAddressType *copyEAT;
317
+
318
+ int rv = EvaluationData(theEnv)->numberOfAddressTypes;
319
+
320
+ if (EvaluationData(theEnv)->numberOfAddressTypes == MAXIMUM_EXTERNAL_ADDRESS_TYPES)
321
+ {
322
+ SystemError(theEnv,"EVALUATN",6);
323
+ ExitRouter(theEnv,EXIT_FAILURE);
324
+ }
325
+
326
+ copyEAT = (struct externalAddressType *) genalloc(theEnv,sizeof(struct externalAddressType));
327
+ memcpy(copyEAT,theAddressType,sizeof(struct externalAddressType));
328
+ EvaluationData(theEnv)->ExternalAddressTypes[EvaluationData(theEnv)->numberOfAddressTypes++] = copyEAT;
329
+
330
+ return rv;
331
+ }
332
+
333
+ /*******************/
334
+ /* ResetErrorFlags */
335
+ /*******************/
336
+ void ResetErrorFlags(
337
+ Environment *theEnv)
338
+ {
339
+ EvaluationData(theEnv)->EvaluationError = false;
340
+ EvaluationData(theEnv)->HaltExecution = false;
341
+ }
342
+
343
+ /******************************************************/
344
+ /* SetEvaluationError: Sets the EvaluationError flag. */
345
+ /******************************************************/
346
+ void SetEvaluationError(
347
+ Environment *theEnv,
348
+ bool value)
349
+ {
350
+ EvaluationData(theEnv)->EvaluationError = value;
351
+ if (value == true)
352
+ { EvaluationData(theEnv)->HaltExecution = true; }
353
+ }
354
+
355
+ /*********************************************************/
356
+ /* GetEvaluationError: Returns the EvaluationError flag. */
357
+ /*********************************************************/
358
+ bool GetEvaluationError(
359
+ Environment *theEnv)
360
+ {
361
+ return(EvaluationData(theEnv)->EvaluationError);
362
+ }
363
+
364
+ /**************************************************/
365
+ /* SetHaltExecution: Sets the HaltExecution flag. */
366
+ /**************************************************/
367
+ void SetHaltExecution(
368
+ Environment *theEnv,
369
+ bool value)
370
+ {
371
+ EvaluationData(theEnv)->HaltExecution = value;
372
+ }
373
+
374
+ /*****************************************************/
375
+ /* GetHaltExecution: Returns the HaltExecution flag. */
376
+ /*****************************************************/
377
+ bool GetHaltExecution(
378
+ Environment *theEnv)
379
+ {
380
+ return(EvaluationData(theEnv)->HaltExecution);
381
+ }
382
+
383
+ /*****************************************************/
384
+ /* ReturnValues: Returns a linked list of UDFValue */
385
+ /* structures to the pool of free memory. */
386
+ /*****************************************************/
387
+ void ReturnValues(
388
+ Environment *theEnv,
389
+ UDFValue *garbagePtr,
390
+ bool decrementSupplementalInfo)
391
+ {
392
+ UDFValue *nextPtr;
393
+
394
+ while (garbagePtr != NULL)
395
+ {
396
+ nextPtr = garbagePtr->next;
397
+ ReleaseUDFV(theEnv,garbagePtr);
398
+ if ((garbagePtr->supplementalInfo != NULL) && decrementSupplementalInfo)
399
+ { ReleaseLexeme(theEnv,(CLIPSLexeme *) garbagePtr->supplementalInfo); }
400
+ rtn_struct(theEnv,udfValue,garbagePtr);
401
+ garbagePtr = nextPtr;
402
+ }
403
+ }
404
+
405
+ /**************************************************/
406
+ /* WriteCLIPSValue: Prints a CLIPSValue structure */
407
+ /* to the specified logical name. */
408
+ /**************************************************/
409
+ void WriteCLIPSValue(
410
+ Environment *theEnv,
411
+ const char *fileid,
412
+ CLIPSValue *argPtr)
413
+ {
414
+ switch(argPtr->header->type)
415
+ {
416
+ case VOID_TYPE:
417
+ case SYMBOL_TYPE:
418
+ case STRING_TYPE:
419
+ case INTEGER_TYPE:
420
+ case FLOAT_TYPE:
421
+ case EXTERNAL_ADDRESS_TYPE:
422
+ case FACT_ADDRESS_TYPE:
423
+ #if OBJECT_SYSTEM
424
+ case INSTANCE_NAME_TYPE:
425
+ case INSTANCE_ADDRESS_TYPE:
426
+ #endif
427
+ PrintAtom(theEnv,fileid,argPtr->header->type,argPtr->value);
428
+ break;
429
+
430
+ case MULTIFIELD_TYPE:
431
+ PrintMultifieldDriver(theEnv,fileid,argPtr->multifieldValue,
432
+ 0,argPtr->multifieldValue->length,true);
433
+ break;
434
+
435
+ default:
436
+ WriteString(theEnv,fileid,"<UnknownPrintType");
437
+ WriteInteger(theEnv,fileid,argPtr->header->type);
438
+ WriteString(theEnv,fileid,">");
439
+ SetHaltExecution(theEnv,true);
440
+ SetEvaluationError(theEnv,true);
441
+ break;
442
+ }
443
+ }
444
+
445
+ /**********************************************/
446
+ /* WriteUDFValue: Prints a UDFValue structure */
447
+ /* to the specified logical name. */
448
+ /**********************************************/
449
+ void WriteUDFValue(
450
+ Environment *theEnv,
451
+ const char *fileid,
452
+ UDFValue *argPtr)
453
+ {
454
+ switch(argPtr->header->type)
455
+ {
456
+ case VOID_TYPE:
457
+ case SYMBOL_TYPE:
458
+ case STRING_TYPE:
459
+ case INTEGER_TYPE:
460
+ case FLOAT_TYPE:
461
+ case EXTERNAL_ADDRESS_TYPE:
462
+ case FACT_ADDRESS_TYPE:
463
+ #if OBJECT_SYSTEM
464
+ case INSTANCE_NAME_TYPE:
465
+ case INSTANCE_ADDRESS_TYPE:
466
+ #endif
467
+ PrintAtom(theEnv,fileid,argPtr->header->type,argPtr->value);
468
+ break;
469
+
470
+ case MULTIFIELD_TYPE:
471
+ PrintMultifieldDriver(theEnv,fileid,argPtr->multifieldValue,
472
+ argPtr->begin,argPtr->range,true);
473
+ break;
474
+
475
+ default:
476
+ WriteString(theEnv,fileid,"<UnknownPrintType");
477
+ WriteInteger(theEnv,fileid,argPtr->header->type);
478
+ WriteString(theEnv,fileid,">");
479
+ SetHaltExecution(theEnv,true);
480
+ SetEvaluationError(theEnv,true);
481
+ break;
482
+ }
483
+ }
484
+
485
+ /*************************************************/
486
+ /* SetMultifieldErrorValue: Creates a multifield */
487
+ /* value of length zero for error returns. */
488
+ /*************************************************/
489
+ void SetMultifieldErrorValue(
490
+ Environment *theEnv,
491
+ UDFValue *returnValue)
492
+ {
493
+ returnValue->value = CreateMultifield(theEnv,0L);
494
+ returnValue->begin = 0;
495
+ returnValue->range = 0;
496
+ }
497
+
498
+ /***********************************************/
499
+ /* RetainUDFV: Increments the appropriate count */
500
+ /* (in use) values for a UDFValue structure. */
501
+ /***********************************************/
502
+ void RetainUDFV(
503
+ Environment *theEnv,
504
+ UDFValue *vPtr)
505
+ {
506
+ if (vPtr->header->type == MULTIFIELD_TYPE)
507
+ { IncrementCLIPSValueMultifieldReferenceCount(theEnv,vPtr->multifieldValue); }
508
+ else
509
+ { Retain(theEnv,vPtr->header); }
510
+ }
511
+
512
+ /***********************************************/
513
+ /* RetainUDFV: Decrements the appropriate count */
514
+ /* (in use) values for a UDFValue structure. */
515
+ /***********************************************/
516
+ void ReleaseUDFV(
517
+ Environment *theEnv,
518
+ UDFValue *vPtr)
519
+ {
520
+ if (vPtr->header->type == MULTIFIELD_TYPE)
521
+ { DecrementCLIPSValueMultifieldReferenceCount(theEnv,vPtr->multifieldValue); }
522
+ else
523
+ { Release(theEnv,vPtr->header); }
524
+ }
525
+
526
+ /*************************************************/
527
+ /* RetainCV: Increments the appropriate count */
528
+ /* (in use) values for a CLIPSValue structure. */
529
+ /*************************************************/
530
+ void RetainCV(
531
+ Environment *theEnv,
532
+ CLIPSValue *vPtr)
533
+ {
534
+ if (vPtr->header->type == MULTIFIELD_TYPE)
535
+ { IncrementCLIPSValueMultifieldReferenceCount(theEnv,vPtr->multifieldValue); }
536
+ else
537
+ { Retain(theEnv,vPtr->header); }
538
+ }
539
+
540
+ /*************************************************/
541
+ /* ReleaseCV: Decrements the appropriate count */
542
+ /* (in use) values for a CLIPSValue structure. */
543
+ /*************************************************/
544
+ void ReleaseCV(
545
+ Environment *theEnv,
546
+ CLIPSValue *vPtr)
547
+ {
548
+ if (vPtr->header->type == MULTIFIELD_TYPE)
549
+ { DecrementCLIPSValueMultifieldReferenceCount(theEnv,vPtr->multifieldValue); }
550
+ else
551
+ { Release(theEnv,vPtr->header); }
552
+ }
553
+
554
+ /******************************************/
555
+ /* Retain: Increments the reference count */
556
+ /* of an atomic data type. */
557
+ /******************************************/
558
+ void Retain(
559
+ Environment *theEnv,
560
+ TypeHeader *th)
561
+ {
562
+ switch (th->type)
563
+ {
564
+ case SYMBOL_TYPE:
565
+ case STRING_TYPE:
566
+ #if OBJECT_SYSTEM
567
+ case INSTANCE_NAME_TYPE:
568
+ #endif
569
+ IncrementLexemeCount(th);
570
+ break;
571
+
572
+ case FLOAT_TYPE:
573
+ IncrementFloatCount(th);
574
+ break;
575
+
576
+ case INTEGER_TYPE:
577
+ IncrementIntegerCount(th);
578
+ break;
579
+
580
+ case EXTERNAL_ADDRESS_TYPE:
581
+ IncrementExternalAddressCount(th);
582
+ break;
583
+
584
+ case MULTIFIELD_TYPE:
585
+ RetainMultifield(theEnv,(Multifield *) th);
586
+ break;
587
+
588
+ #if OBJECT_SYSTEM
589
+ case INSTANCE_ADDRESS_TYPE:
590
+ RetainInstance((Instance *) th);
591
+ break;
592
+ #endif
593
+
594
+ #if DEFTEMPLATE_CONSTRUCT
595
+ case FACT_ADDRESS_TYPE:
596
+ RetainFact((Fact *) th);
597
+ break;
598
+ #endif
599
+
600
+ case VOID_TYPE:
601
+ break;
602
+
603
+ default:
604
+ SystemError(theEnv,"EVALUATN",7);
605
+ ExitRouter(theEnv,EXIT_FAILURE);
606
+ break;
607
+ }
608
+ }
609
+
610
+ /*************************************/
611
+ /* Release: Decrements the reference */
612
+ /* count of an atomic data type. */
613
+ /*************************************/
614
+ void Release(
615
+ Environment *theEnv,
616
+ TypeHeader *th)
617
+ {
618
+ switch (th->type)
619
+ {
620
+ case SYMBOL_TYPE:
621
+ case STRING_TYPE:
622
+ #if OBJECT_SYSTEM
623
+ case INSTANCE_NAME_TYPE:
624
+ #endif
625
+ ReleaseLexeme(theEnv,(CLIPSLexeme *) th);
626
+ break;
627
+
628
+ case FLOAT_TYPE:
629
+ ReleaseFloat(theEnv,(CLIPSFloat *) th);
630
+ break;
631
+
632
+ case INTEGER_TYPE:
633
+ ReleaseInteger(theEnv,(CLIPSInteger *) th);
634
+ break;
635
+
636
+ case EXTERNAL_ADDRESS_TYPE:
637
+ ReleaseExternalAddress(theEnv,(CLIPSExternalAddress *) th);
638
+ break;
639
+
640
+ case MULTIFIELD_TYPE:
641
+ ReleaseMultifield(theEnv,(Multifield *) th);
642
+ break;
643
+
644
+ #if OBJECT_SYSTEM
645
+ case INSTANCE_ADDRESS_TYPE:
646
+ ReleaseInstance((Instance *) th);
647
+ break;
648
+ #endif
649
+
650
+ #if DEFTEMPLATE_CONSTRUCT
651
+ case FACT_ADDRESS_TYPE:
652
+ ReleaseFact((Fact *) th);
653
+ break;
654
+ #endif
655
+
656
+ case VOID_TYPE:
657
+ break;
658
+
659
+ default:
660
+ SystemError(theEnv,"EVALUATN",8);
661
+ ExitRouter(theEnv,EXIT_FAILURE);
662
+ break;
663
+ }
664
+ }
665
+
666
+ /*****************************************/
667
+ /* AtomInstall: Increments the reference */
668
+ /* count of an atomic data type. */
669
+ /*****************************************/
670
+ void AtomInstall(
671
+ Environment *theEnv,
672
+ unsigned short type,
673
+ void *vPtr)
674
+ {
675
+ switch (type)
676
+ {
677
+ case SYMBOL_TYPE:
678
+ case STRING_TYPE:
679
+ #if DEFGLOBAL_CONSTRUCT
680
+ case GBL_VARIABLE:
681
+ #endif
682
+ #if OBJECT_SYSTEM
683
+ case INSTANCE_NAME_TYPE:
684
+ #endif
685
+ IncrementLexemeCount(vPtr);
686
+ break;
687
+
688
+ case FLOAT_TYPE:
689
+ IncrementFloatCount(vPtr);
690
+ break;
691
+
692
+ case INTEGER_TYPE:
693
+ IncrementIntegerCount(vPtr);
694
+ break;
695
+
696
+ case EXTERNAL_ADDRESS_TYPE:
697
+ IncrementExternalAddressCount(vPtr);
698
+ break;
699
+
700
+ case MULTIFIELD_TYPE:
701
+ RetainMultifield(theEnv,(Multifield *) vPtr);
702
+ break;
703
+
704
+ case VOID_TYPE:
705
+ break;
706
+
707
+ default:
708
+ if (EvaluationData(theEnv)->PrimitivesArray[type] == NULL) break;
709
+ if (EvaluationData(theEnv)->PrimitivesArray[type]->bitMap) IncrementBitMapCount(vPtr);
710
+ else if (EvaluationData(theEnv)->PrimitivesArray[type]->incrementBusyCount)
711
+ { (*EvaluationData(theEnv)->PrimitivesArray[type]->incrementBusyCount)(theEnv,vPtr); }
712
+ break;
713
+ }
714
+ }
715
+
716
+ /*******************************************/
717
+ /* AtomDeinstall: Decrements the reference */
718
+ /* count of an atomic data type. */
719
+ /*******************************************/
720
+ void AtomDeinstall(
721
+ Environment *theEnv,
722
+ unsigned short type,
723
+ void *vPtr)
724
+ {
725
+ switch (type)
726
+ {
727
+ case SYMBOL_TYPE:
728
+ case STRING_TYPE:
729
+ #if DEFGLOBAL_CONSTRUCT
730
+ case GBL_VARIABLE:
731
+ #endif
732
+ #if OBJECT_SYSTEM
733
+ case INSTANCE_NAME_TYPE:
734
+ #endif
735
+ ReleaseLexeme(theEnv,(CLIPSLexeme *) vPtr);
736
+ break;
737
+
738
+ case FLOAT_TYPE:
739
+ ReleaseFloat(theEnv,(CLIPSFloat *) vPtr);
740
+ break;
741
+
742
+ case INTEGER_TYPE:
743
+ ReleaseInteger(theEnv,(CLIPSInteger *) vPtr);
744
+ break;
745
+
746
+ case EXTERNAL_ADDRESS_TYPE:
747
+ ReleaseExternalAddress(theEnv,(CLIPSExternalAddress *) vPtr);
748
+ break;
749
+
750
+ case MULTIFIELD_TYPE:
751
+ ReleaseMultifield(theEnv,(Multifield *) vPtr);
752
+ break;
753
+
754
+ case VOID_TYPE:
755
+ break;
756
+
757
+ default:
758
+ if (EvaluationData(theEnv)->PrimitivesArray[type] == NULL) break;
759
+ if (EvaluationData(theEnv)->PrimitivesArray[type]->bitMap) DecrementBitMapReferenceCount(theEnv,(CLIPSBitMap *) vPtr);
760
+ else if (EvaluationData(theEnv)->PrimitivesArray[type]->decrementBusyCount)
761
+ { (*EvaluationData(theEnv)->PrimitivesArray[type]->decrementBusyCount)(theEnv,vPtr); }
762
+ }
763
+ }
764
+
765
+ /***************************************************/
766
+ /* CopyDataObject: Copies the values from a source */
767
+ /* UDFValue to a destination UDFValue. */
768
+ /***************************************************/
769
+ void CopyDataObject(
770
+ Environment *theEnv,
771
+ UDFValue *dst,
772
+ UDFValue *src,
773
+ int garbageMultifield)
774
+ {
775
+ if (src->header->type != MULTIFIELD_TYPE)
776
+ {
777
+ dst->value = src->value;
778
+ }
779
+ else
780
+ {
781
+ DuplicateMultifield(theEnv,dst,src);
782
+ if (garbageMultifield)
783
+ { AddToMultifieldList(theEnv,dst->multifieldValue); }
784
+ }
785
+ }
786
+
787
+ /***********************************************/
788
+ /* TransferDataObjectValues: Copies the values */
789
+ /* directly from a source UDFValue to a */
790
+ /* destination UDFValue. */
791
+ /***********************************************/
792
+ void TransferDataObjectValues(
793
+ UDFValue *dst,
794
+ UDFValue *src)
795
+ {
796
+ dst->value = src->value;
797
+ dst->begin = src->begin;
798
+ dst->range = src->range;
799
+ dst->supplementalInfo = src->supplementalInfo;
800
+ dst->next = src->next;
801
+ }
802
+
803
+ /************************************************************************/
804
+ /* ConvertValueToExpression: Converts the value stored in a data object */
805
+ /* into an expression. For multifield values, a chain of expressions */
806
+ /* is generated and the chain is linked by the nextArg field. For a */
807
+ /* single field value, a single expression is created. */
808
+ /************************************************************************/
809
+ struct expr *ConvertValueToExpression(
810
+ Environment *theEnv,
811
+ UDFValue *theValue)
812
+ {
813
+ size_t i;
814
+ struct expr *head = NULL, *last = NULL, *newItem;
815
+
816
+ if (theValue->header->type != MULTIFIELD_TYPE)
817
+ { return(GenConstant(theEnv,theValue->header->type,theValue->value)); }
818
+
819
+ for (i = theValue->begin; i < (theValue->begin + theValue->range); i++)
820
+ {
821
+ newItem = GenConstant(theEnv,theValue->multifieldValue->contents[i].header->type,
822
+ theValue->multifieldValue->contents[i].value);
823
+ if (last == NULL) head = newItem;
824
+ else last->nextArg = newItem;
825
+ last = newItem;
826
+ }
827
+
828
+ if (head == NULL)
829
+ return(GenConstant(theEnv,FCALL,FindFunction(theEnv,"create$")));
830
+
831
+ return(head);
832
+ }
833
+
834
+ /****************************************/
835
+ /* GetAtomicHashValue: Returns the hash */
836
+ /* value for an atomic data type. */
837
+ /****************************************/
838
+ unsigned long GetAtomicHashValue(
839
+ unsigned short type,
840
+ void *value,
841
+ unsigned short position)
842
+ {
843
+ unsigned long tvalue;
844
+ union
845
+ {
846
+ double fv;
847
+ void *vv;
848
+ unsigned long liv;
849
+ } fis;
850
+
851
+ switch (type)
852
+ {
853
+ case FLOAT_TYPE:
854
+ fis.liv = 0;
855
+ fis.fv = ((CLIPSFloat *) value)->contents;
856
+ tvalue = fis.liv;
857
+ break;
858
+
859
+ case INTEGER_TYPE:
860
+ tvalue = (unsigned long) ((CLIPSInteger *) value)->contents;
861
+ break;
862
+
863
+ case EXTERNAL_ADDRESS_TYPE:
864
+ fis.liv = 0;
865
+ fis.vv = ((CLIPSExternalAddress *) value)->contents;
866
+ tvalue = fis.liv;
867
+ break;
868
+
869
+ case FACT_ADDRESS_TYPE:
870
+ #if OBJECT_SYSTEM
871
+ case INSTANCE_ADDRESS_TYPE:
872
+ #endif
873
+ fis.liv = 0;
874
+ fis.vv = value;
875
+ tvalue = fis.liv;
876
+ break;
877
+
878
+ case STRING_TYPE:
879
+ #if OBJECT_SYSTEM
880
+ case INSTANCE_NAME_TYPE:
881
+ #endif
882
+ case SYMBOL_TYPE:
883
+ tvalue = ((CLIPSLexeme *) value)->bucket;
884
+ break;
885
+
886
+ default:
887
+ tvalue = type;
888
+ }
889
+
890
+ return tvalue * (position + 29);
891
+ }
892
+
893
+ /***********************************************************/
894
+ /* FunctionReferenceExpression: Returns an expression with */
895
+ /* an appropriate expression reference to the specified */
896
+ /* name if it is the name of a deffunction, defgeneric, */
897
+ /* or user/system defined function. */
898
+ /***********************************************************/
899
+ struct expr *FunctionReferenceExpression(
900
+ Environment *theEnv,
901
+ const char *name)
902
+ {
903
+ #if DEFGENERIC_CONSTRUCT
904
+ Defgeneric *gfunc;
905
+ #endif
906
+ #if DEFFUNCTION_CONSTRUCT
907
+ Deffunction *dptr;
908
+ #endif
909
+ struct functionDefinition *fptr;
910
+
911
+ /*=====================================================*/
912
+ /* Check to see if the function call is a deffunction. */
913
+ /*=====================================================*/
914
+
915
+ #if DEFFUNCTION_CONSTRUCT
916
+ if ((dptr = LookupDeffunctionInScope(theEnv,name)) != NULL)
917
+ { return(GenConstant(theEnv,PCALL,dptr)); }
918
+ #endif
919
+
920
+ /*====================================================*/
921
+ /* Check to see if the function call is a defgeneric. */
922
+ /*====================================================*/
923
+
924
+ #if DEFGENERIC_CONSTRUCT
925
+ if ((gfunc = LookupDefgenericInScope(theEnv,name)) != NULL)
926
+ { return(GenConstant(theEnv,GCALL,gfunc)); }
927
+ #endif
928
+
929
+ /*======================================*/
930
+ /* Check to see if the function call is */
931
+ /* a system or user defined function. */
932
+ /*======================================*/
933
+
934
+ if ((fptr = FindFunction(theEnv,name)) != NULL)
935
+ { return(GenConstant(theEnv,FCALL,fptr)); }
936
+
937
+ /*===================================================*/
938
+ /* The specified function name is not a deffunction, */
939
+ /* defgeneric, or user/system defined function. */
940
+ /*===================================================*/
941
+
942
+ return NULL;
943
+ }
944
+
945
+ /******************************************************************/
946
+ /* GetFunctionReference: Fills an expression with an appropriate */
947
+ /* expression reference to the specified name if it is the */
948
+ /* name of a deffunction, defgeneric, or user/system defined */
949
+ /* function. */
950
+ /******************************************************************/
951
+ bool GetFunctionReference(
952
+ Environment *theEnv,
953
+ const char *name,
954
+ Expression *theReference)
955
+ {
956
+ #if DEFGENERIC_CONSTRUCT
957
+ Defgeneric *gfunc;
958
+ #endif
959
+ #if DEFFUNCTION_CONSTRUCT
960
+ Deffunction *dptr;
961
+ #endif
962
+ struct functionDefinition *fptr;
963
+ bool moduleSpecified = false;
964
+ unsigned position;
965
+ CLIPSLexeme *moduleName = NULL, *constructName = NULL;
966
+
967
+ theReference->nextArg = NULL;
968
+ theReference->argList = NULL;
969
+ theReference->type = VOID_TYPE;
970
+ theReference->value = NULL;
971
+
972
+ /*==============================*/
973
+ /* Look for a module specifier. */
974
+ /*==============================*/
975
+
976
+ if ((position = FindModuleSeparator(name)) != 0)
977
+ {
978
+ moduleName = ExtractModuleName(theEnv,position,name);
979
+ constructName = ExtractConstructName(theEnv,position,name,SYMBOL_TYPE);
980
+ moduleSpecified = true;
981
+ }
982
+
983
+ /*====================================================*/
984
+ /* Check to see if the function call is a defgeneric. */
985
+ /*====================================================*/
986
+
987
+ #if DEFGENERIC_CONSTRUCT
988
+ if (moduleSpecified)
989
+ {
990
+ if (ConstructExported(theEnv,"defgeneric",moduleName,constructName) ||
991
+ GetCurrentModule(theEnv) == FindDefmodule(theEnv,moduleName->contents))
992
+ {
993
+ if ((gfunc = FindDefgenericInModule(theEnv,name)) != NULL)
994
+ {
995
+ theReference->type = GCALL;
996
+ theReference->value = gfunc;
997
+ return true;
998
+ }
999
+ }
1000
+ }
1001
+ else
1002
+ {
1003
+ if ((gfunc = LookupDefgenericInScope(theEnv,name)) != NULL)
1004
+ {
1005
+ theReference->type = GCALL;
1006
+ theReference->value = gfunc;
1007
+ return true;
1008
+ }
1009
+ }
1010
+ #endif
1011
+
1012
+ /*=====================================================*/
1013
+ /* Check to see if the function call is a deffunction. */
1014
+ /*=====================================================*/
1015
+
1016
+ #if DEFFUNCTION_CONSTRUCT
1017
+ if (moduleSpecified)
1018
+ {
1019
+ if (ConstructExported(theEnv,"deffunction",moduleName,constructName) ||
1020
+ GetCurrentModule(theEnv) == FindDefmodule(theEnv,moduleName->contents))
1021
+ {
1022
+ if ((dptr = FindDeffunctionInModule(theEnv,name)) != NULL)
1023
+ {
1024
+ theReference->type = PCALL;
1025
+ theReference->value = dptr;
1026
+ return true;
1027
+ }
1028
+ }
1029
+ }
1030
+ else
1031
+ {
1032
+ if ((dptr = LookupDeffunctionInScope(theEnv,name)) != NULL)
1033
+ {
1034
+ theReference->type = PCALL;
1035
+ theReference->value = dptr;
1036
+ return true;
1037
+ }
1038
+ }
1039
+ #endif
1040
+
1041
+ /*======================================*/
1042
+ /* Check to see if the function call is */
1043
+ /* a system or user defined function. */
1044
+ /*======================================*/
1045
+
1046
+ if ((fptr = FindFunction(theEnv,name)) != NULL)
1047
+ {
1048
+ theReference->type = FCALL;
1049
+ theReference->value = fptr;
1050
+ return true;
1051
+ }
1052
+
1053
+ /*===================================================*/
1054
+ /* The specified function name is not a deffunction, */
1055
+ /* defgeneric, or user/system defined function. */
1056
+ /*===================================================*/
1057
+
1058
+ return false;
1059
+ }
1060
+
1061
+ /*******************************************************/
1062
+ /* DOsEqual: Determines if two DATA_OBJECTS are equal. */
1063
+ /*******************************************************/
1064
+ bool DOsEqual(
1065
+ UDFValue *dobj1,
1066
+ UDFValue *dobj2)
1067
+ {
1068
+ if (dobj1->header->type != dobj2->header->type)
1069
+ { return false; }
1070
+
1071
+ if (dobj1->header->type == MULTIFIELD_TYPE)
1072
+ {
1073
+ if (MultifieldDOsEqual(dobj1,dobj2) == false)
1074
+ { return false; }
1075
+ }
1076
+ else if (dobj1->value != dobj2->value)
1077
+ { return false; }
1078
+
1079
+ return true;
1080
+ }
1081
+
1082
+ /***********************************************************
1083
+ NAME : EvaluateAndStoreInDataObject
1084
+ DESCRIPTION : Evaluates slot-value expressions
1085
+ and stores the result in a
1086
+ Kernel data object
1087
+ INPUTS : 1) Flag indicating if multifields are OK
1088
+ 2) The value-expression
1089
+ 3) The data object structure
1090
+ 4) Flag indicating if a multifield value
1091
+ should be placed on the garbage list.
1092
+ RETURNS : False on errors, true otherwise
1093
+ SIDE EFFECTS : Segment allocated for storing
1094
+ multifield values
1095
+ NOTES : None
1096
+ ***********************************************************/
1097
+ bool EvaluateAndStoreInDataObject(
1098
+ Environment *theEnv,
1099
+ bool mfp,
1100
+ Expression *theExp,
1101
+ UDFValue *val,
1102
+ bool garbageSegment)
1103
+ {
1104
+ val->begin = 0;
1105
+ val->range = 0;
1106
+
1107
+ if (theExp == NULL)
1108
+ {
1109
+ if (garbageSegment) val->value = CreateMultifield(theEnv,0L);
1110
+ else val->value = CreateUnmanagedMultifield(theEnv,0L);
1111
+
1112
+ return true;
1113
+ }
1114
+
1115
+ if ((mfp == false) && (theExp->nextArg == NULL))
1116
+ EvaluateExpression(theEnv,theExp,val);
1117
+ else
1118
+ StoreInMultifield(theEnv,val,theExp,garbageSegment);
1119
+
1120
+ return(EvaluationData(theEnv)->EvaluationError ? false : true);
1121
+ }
1122
+
1123
+ /******************/
1124
+ /* PrintCAddress: */
1125
+ /******************/
1126
+ static void PrintCAddress(
1127
+ Environment *theEnv,
1128
+ const char *logicalName,
1129
+ void *theValue)
1130
+ {
1131
+ char buffer[20];
1132
+
1133
+ WriteString(theEnv,logicalName,"<Pointer-C-");
1134
+
1135
+ gensnprintf(buffer,sizeof(buffer),"%p",((CLIPSExternalAddress *) theValue)->contents);
1136
+ WriteString(theEnv,logicalName,buffer);
1137
+ WriteString(theEnv,logicalName,">");
1138
+ }
1139
+
1140
+ /****************/
1141
+ /* NewCAddress: */
1142
+ /****************/
1143
+ static void NewCAddress(
1144
+ UDFContext *context,
1145
+ UDFValue *rv)
1146
+ {
1147
+ unsigned int numberOfArguments;
1148
+ Environment *theEnv = context->environment;
1149
+
1150
+ numberOfArguments = UDFArgumentCount(context);
1151
+
1152
+ if (numberOfArguments != 1)
1153
+ {
1154
+ PrintErrorID(theEnv,"NEW",1,false);
1155
+ WriteString(theEnv,STDERR,"Function new expected no additional arguments for the C external language type.\n");
1156
+ SetEvaluationError(theEnv,true);
1157
+ return;
1158
+ }
1159
+
1160
+ rv->value = CreateExternalAddress(theEnv,NULL,0);
1161
+ }
1162
+
1163
+ /******************************/
1164
+ /* CreateFunctionCallBuilder: */
1165
+ /******************************/
1166
+ FunctionCallBuilder *CreateFunctionCallBuilder(
1167
+ Environment *theEnv,
1168
+ size_t theSize)
1169
+ {
1170
+ FunctionCallBuilder *theFC;
1171
+
1172
+ if (theEnv == NULL) return NULL;
1173
+
1174
+ theFC = get_struct(theEnv,functionCallBuilder);
1175
+
1176
+ theFC->fcbEnv = theEnv;
1177
+ theFC->bufferReset = theSize;
1178
+ theFC->bufferMaximum = theSize;
1179
+ theFC->length = 0;
1180
+
1181
+ if (theSize == 0)
1182
+ { theFC->contents = NULL; }
1183
+ else
1184
+ { theFC->contents = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theSize); }
1185
+
1186
+ return theFC;
1187
+ }
1188
+
1189
+ /**********************/
1190
+ /* FCBAppendUDFValue: */
1191
+ /**********************/
1192
+ void FCBAppendUDFValue(
1193
+ FunctionCallBuilder *theFCB,
1194
+ UDFValue *theValue)
1195
+ {
1196
+ Environment *theEnv = theFCB->fcbEnv;
1197
+ size_t i, neededSize, newSize;
1198
+ CLIPSValue *newArray;
1199
+
1200
+ /*==============================================*/
1201
+ /* A void value can't be added to a multifield. */
1202
+ /*==============================================*/
1203
+
1204
+ if (theValue->header->type == VOID_TYPE)
1205
+ { return; }
1206
+
1207
+ /*=======================================*/
1208
+ /* Determine the amount of space needed. */
1209
+ /*=======================================*/
1210
+
1211
+ neededSize = theFCB->length + 1;
1212
+
1213
+ /*============================================*/
1214
+ /* Increase the size of the buffer if needed. */
1215
+ /*============================================*/
1216
+
1217
+ if (neededSize > theFCB->bufferMaximum)
1218
+ {
1219
+ newSize = neededSize * 2;
1220
+
1221
+ newArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSize);
1222
+
1223
+ for (i = 0; i < theFCB->length; i++)
1224
+ { newArray[i] = theFCB->contents[i]; }
1225
+
1226
+ if (theFCB->bufferMaximum != 0)
1227
+ { rm(theFCB->fcbEnv,theFCB->contents,sizeof(CLIPSValue) * theFCB->bufferMaximum); }
1228
+
1229
+ theFCB->bufferMaximum = newSize;
1230
+ theFCB->contents = newArray;
1231
+ }
1232
+
1233
+ /*==================================*/
1234
+ /* Copy the new value to the array. */
1235
+ /*==================================*/
1236
+
1237
+ if (theValue->header->type == MULTIFIELD_TYPE)
1238
+ {
1239
+ CLIPSValue newValue;
1240
+
1241
+ UDFToCLIPSValue(theEnv,theValue,&newValue);
1242
+ theFCB->contents[theFCB->length].value = newValue.value;
1243
+ }
1244
+ else
1245
+ { theFCB->contents[theFCB->length].value = theValue->value; }
1246
+
1247
+ Retain(theEnv,theFCB->contents[theFCB->length].header);
1248
+ theFCB->length++;
1249
+ }
1250
+
1251
+ /**************/
1252
+ /* FCBAppend: */
1253
+ /**************/
1254
+ void FCBAppend(
1255
+ FunctionCallBuilder *theFCB,
1256
+ CLIPSValue *theValue)
1257
+ {
1258
+ Environment *theEnv = theFCB->fcbEnv;
1259
+ size_t i, neededSize, newSize;
1260
+ CLIPSValue *newArray;
1261
+
1262
+ /*==============================================*/
1263
+ /* A void value can't be added to a multifield. */
1264
+ /*==============================================*/
1265
+
1266
+ if (theValue->header->type == VOID_TYPE)
1267
+ { return; }
1268
+
1269
+ /*=======================================*/
1270
+ /* Determine the amount of space needed. */
1271
+ /*=======================================*/
1272
+
1273
+ neededSize = theFCB->length + 1;
1274
+
1275
+ /*============================================*/
1276
+ /* Increase the size of the buffer if needed. */
1277
+ /*============================================*/
1278
+
1279
+ if (neededSize > theFCB->bufferMaximum)
1280
+ {
1281
+ newSize = neededSize * 2;
1282
+
1283
+ newArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSize);
1284
+
1285
+ for (i = 0; i < theFCB->length; i++)
1286
+ { newArray[i] = theFCB->contents[i]; }
1287
+
1288
+ if (theFCB->bufferMaximum != 0)
1289
+ { rm(theFCB->fcbEnv,theFCB->contents,sizeof(CLIPSValue) * theFCB->bufferMaximum); }
1290
+
1291
+ theFCB->bufferMaximum = newSize;
1292
+ theFCB->contents = newArray;
1293
+ }
1294
+
1295
+ /*===================================*/
1296
+ /* Copy the new values to the array. */
1297
+ /*===================================*/
1298
+
1299
+ theFCB->contents[theFCB->length].value = theValue->value;
1300
+ Retain(theEnv,theFCB->contents[theFCB->length].header);
1301
+ theFCB->length++;
1302
+ }
1303
+
1304
+ /**************************/
1305
+ /* FCBAppendCLIPSInteger: */
1306
+ /**************************/
1307
+ void FCBAppendCLIPSInteger(
1308
+ FunctionCallBuilder *theFCB,
1309
+ CLIPSInteger *pv)
1310
+ {
1311
+ CLIPSValue theValue;
1312
+
1313
+ theValue.integerValue = pv;
1314
+ FCBAppend(theFCB,&theValue);
1315
+ }
1316
+
1317
+ /*********************/
1318
+ /* FCBAppendInteger: */
1319
+ /*********************/
1320
+ void FCBAppendInteger(
1321
+ FunctionCallBuilder *theFCB,
1322
+ long long intValue)
1323
+ {
1324
+ CLIPSValue theValue;
1325
+ CLIPSInteger *pv = CreateInteger(theFCB->fcbEnv,intValue);
1326
+
1327
+ theValue.integerValue = pv;
1328
+ FCBAppend(theFCB,&theValue);
1329
+ }
1330
+
1331
+ /************************/
1332
+ /* FCBAppendCLIPSFloat: */
1333
+ /************************/
1334
+ void FCBAppendCLIPSFloat(
1335
+ FunctionCallBuilder *theFCB,
1336
+ CLIPSFloat *pv)
1337
+ {
1338
+ CLIPSValue theValue;
1339
+
1340
+ theValue.floatValue = pv;
1341
+ FCBAppend(theFCB,&theValue);
1342
+ }
1343
+
1344
+ /*******************/
1345
+ /* FCBAppendFloat: */
1346
+ /*******************/
1347
+ void FCBAppendFloat(
1348
+ FunctionCallBuilder *theFCB,
1349
+ double floatValue)
1350
+ {
1351
+ CLIPSValue theValue;
1352
+ CLIPSFloat *pv = CreateFloat(theFCB->fcbEnv,floatValue);
1353
+
1354
+ theValue.floatValue = pv;
1355
+ FCBAppend(theFCB,&theValue);
1356
+ }
1357
+
1358
+ /*************************/
1359
+ /* FCBAppendCLIPSLexeme: */
1360
+ /*************************/
1361
+ void FCBAppendCLIPSLexeme(
1362
+ FunctionCallBuilder *theFCB,
1363
+ CLIPSLexeme *pv)
1364
+ {
1365
+ CLIPSValue theValue;
1366
+
1367
+ theValue.lexemeValue = pv;
1368
+ FCBAppend(theFCB,&theValue);
1369
+ }
1370
+
1371
+ /********************/
1372
+ /* FCBAppendSymbol: */
1373
+ /********************/
1374
+ void FCBAppendSymbol(
1375
+ FunctionCallBuilder *theFCB,
1376
+ const char *strValue)
1377
+ {
1378
+ CLIPSValue theValue;
1379
+ CLIPSLexeme *pv = CreateSymbol(theFCB->fcbEnv,strValue);
1380
+
1381
+ theValue.lexemeValue = pv;
1382
+ FCBAppend(theFCB,&theValue);
1383
+ }
1384
+
1385
+ /********************/
1386
+ /* FCBAppendString: */
1387
+ /********************/
1388
+ void FCBAppendString(
1389
+ FunctionCallBuilder *theFCB,
1390
+ const char *strValue)
1391
+ {
1392
+ CLIPSValue theValue;
1393
+ CLIPSLexeme *pv = CreateString(theFCB->fcbEnv,strValue);
1394
+
1395
+ theValue.lexemeValue = pv;
1396
+ FCBAppend(theFCB,&theValue);
1397
+ }
1398
+
1399
+ /**************************/
1400
+ /* FCBAppendInstanceName: */
1401
+ /**************************/
1402
+ void FCBAppendInstanceName(
1403
+ FunctionCallBuilder *theFCB,
1404
+ const char *strValue)
1405
+ {
1406
+ CLIPSValue theValue;
1407
+ CLIPSLexeme *pv = CreateInstanceName(theFCB->fcbEnv,strValue);
1408
+
1409
+ theValue.lexemeValue = pv;
1410
+ FCBAppend(theFCB,&theValue);
1411
+ }
1412
+
1413
+ /**********************************/
1414
+ /* FCBAppendCLIPSExternalAddress: */
1415
+ /**********************************/
1416
+ void FCBAppendCLIPSExternalAddress(
1417
+ FunctionCallBuilder *theFCB,
1418
+ CLIPSExternalAddress *pv)
1419
+ {
1420
+ CLIPSValue theValue;
1421
+
1422
+ theValue.externalAddressValue = pv;
1423
+ FCBAppend(theFCB,&theValue);
1424
+ }
1425
+
1426
+ /******************/
1427
+ /* FCBAppendFact: */
1428
+ /******************/
1429
+ void FCBAppendFact(
1430
+ FunctionCallBuilder *theFCB,
1431
+ Fact *pv)
1432
+ {
1433
+ CLIPSValue theValue;
1434
+
1435
+ theValue.factValue = pv;
1436
+ FCBAppend(theFCB,&theValue);
1437
+ }
1438
+
1439
+ /**********************/
1440
+ /* FCBAppendInstance: */
1441
+ /**********************/
1442
+ void FCBAppendInstance(
1443
+ FunctionCallBuilder *theFCB,
1444
+ Instance *pv)
1445
+ {
1446
+ CLIPSValue theValue;
1447
+
1448
+ theValue.instanceValue = pv;
1449
+ FCBAppend(theFCB,&theValue);
1450
+ }
1451
+
1452
+ /************************/
1453
+ /* FCBAppendMultifield: */
1454
+ /************************/
1455
+ void FCBAppendMultifield(
1456
+ FunctionCallBuilder *theFCB,
1457
+ Multifield *pv)
1458
+ {
1459
+ CLIPSValue theValue;
1460
+
1461
+ theValue.multifieldValue = pv;
1462
+ FCBAppend(theFCB,&theValue);
1463
+ }
1464
+
1465
+ /*******************/
1466
+ /* FCBPopArgument: */
1467
+ /*******************/
1468
+ void FCBPopArgument(
1469
+ FunctionCallBuilder *theFCB)
1470
+ {
1471
+ if (theFCB->length > 0)
1472
+ {
1473
+ Release(theFCB->fcbEnv,theFCB->contents[theFCB->length-1].header);
1474
+ theFCB->length--;
1475
+ }
1476
+ }
1477
+
1478
+ /***********/
1479
+ /* FCBCall */
1480
+ /***********/
1481
+ FunctionCallBuilderError FCBCall(
1482
+ FunctionCallBuilder *theFCB,
1483
+ const char *functionName,
1484
+ CLIPSValue *returnValue)
1485
+ {
1486
+ Environment *theEnv;
1487
+ Expression theReference, *lastAdd = NULL, *nextAdd, *multiAdd;
1488
+ struct functionDefinition *theFunction = NULL;
1489
+ size_t i, j;
1490
+ UDFValue udfReturnValue;
1491
+ GCBlock gcb;
1492
+
1493
+ /*==========================*/
1494
+ /* Check for NULL pointers. */
1495
+ /*==========================*/
1496
+
1497
+ if ((theFCB == NULL) || (functionName == NULL))
1498
+ { return FCBE_NULL_POINTER_ERROR; }
1499
+
1500
+ /*======================================*/
1501
+ /* Check to see if the function exists. */
1502
+ /*======================================*/
1503
+
1504
+ if (! GetFunctionReference(theFCB->fcbEnv,functionName,&theReference))
1505
+ { return FCBE_FUNCTION_NOT_FOUND_ERROR; }
1506
+
1507
+ /*============================================*/
1508
+ /* Functions with specialized parsers cannot */
1509
+ /* be used with a FunctionCallBuilder. */
1510
+ /*============================================*/
1511
+
1512
+ if (theReference.type == FCALL)
1513
+ {
1514
+ theFunction = FindFunction(theFCB->fcbEnv,functionName);
1515
+ if (theFunction->parser != NULL)
1516
+ { return FCBE_INVALID_FUNCTION_ERROR; }
1517
+ }
1518
+
1519
+ /*=======================================*/
1520
+ /* Append the arguments for the function */
1521
+ /* call to the expression. */
1522
+ /*=======================================*/
1523
+
1524
+ theEnv = theFCB->fcbEnv;
1525
+
1526
+ for (i = 0; i < theFCB->length; i++)
1527
+ {
1528
+ /*====================================================*/
1529
+ /* Multifield values have to be dynamically recreated */
1530
+ /* through a create$ expression call. */
1531
+ /*====================================================*/
1532
+
1533
+ if (theFCB->contents[i].header->type == MULTIFIELD_TYPE)
1534
+ {
1535
+ nextAdd = GenConstant(theEnv,FCALL,FindFunction(theEnv,"create$"));
1536
+
1537
+ if (lastAdd == NULL)
1538
+ { theReference.argList = nextAdd; }
1539
+ else
1540
+ { lastAdd->nextArg = nextAdd; }
1541
+
1542
+ lastAdd = nextAdd;
1543
+
1544
+ multiAdd = NULL;
1545
+ for (j = 0; j < theFCB->contents[i].multifieldValue->length; j++)
1546
+ {
1547
+ nextAdd = GenConstant(theEnv,theFCB->contents[i].multifieldValue->contents[j].header->type,
1548
+ theFCB->contents[i].multifieldValue->contents[j].value);
1549
+
1550
+ if (multiAdd == NULL)
1551
+ { lastAdd->argList = nextAdd; }
1552
+ else
1553
+ { multiAdd->nextArg = nextAdd; }
1554
+ multiAdd = nextAdd;
1555
+ }
1556
+ }
1557
+
1558
+ /*================================================================*/
1559
+ /* Single field values can just be appended to the argument list. */
1560
+ /*================================================================*/
1561
+
1562
+ else
1563
+ {
1564
+ nextAdd = GenConstant(theEnv,theFCB->contents[i].header->type,theFCB->contents[i].value);
1565
+
1566
+ if (lastAdd == NULL)
1567
+ { theReference.argList = nextAdd; }
1568
+ else
1569
+ { lastAdd->nextArg = nextAdd; }
1570
+ lastAdd = nextAdd;
1571
+ }
1572
+ }
1573
+
1574
+ ExpressionInstall(theEnv,&theReference);
1575
+
1576
+ /*===========================================================*/
1577
+ /* Verify a deffunction has the correct number of arguments. */
1578
+ /*===========================================================*/
1579
+
1580
+ #if DEFFUNCTION_CONSTRUCT
1581
+ if (theReference.type == PCALL)
1582
+ {
1583
+ if (CheckDeffunctionCall(theEnv,(Deffunction *) theReference.value,CountArguments(theReference.argList)) == false)
1584
+ {
1585
+ ExpressionDeinstall(theEnv,&theReference);
1586
+ ReturnExpression(theEnv,theReference.argList);
1587
+ return FCBE_ARGUMENT_COUNT_ERROR;
1588
+ }
1589
+ }
1590
+ #endif
1591
+
1592
+ /*=========================================*/
1593
+ /* Verify the correct number of arguments. */
1594
+ /*=========================================*/
1595
+
1596
+ // TBD Support run time check of arguments
1597
+ #if ! RUN_TIME
1598
+ if (theReference.type == FCALL)
1599
+ {
1600
+ FunctionArgumentsError theError;
1601
+ if ((theError = CheckExpressionAgainstRestrictions(theEnv,&theReference,theFunction,functionName)) != FAE_NO_ERROR)
1602
+ {
1603
+ ExpressionDeinstall(theEnv,&theReference);
1604
+ ReturnExpression(theEnv,theReference.argList);
1605
+ if (theError == FAE_TYPE_ERROR) return FCBE_ARGUMENT_TYPE_ERROR;
1606
+ else if (theError == FAE_COUNT_ERROR) return FCBE_ARGUMENT_COUNT_ERROR;
1607
+ else
1608
+ {
1609
+ SystemError(theEnv,"EVALUATN",9);
1610
+ ExitRouter(theEnv,EXIT_FAILURE);
1611
+ }
1612
+ }
1613
+ }
1614
+ #endif
1615
+ /*========================================*/
1616
+ /* Set up the frame for tracking garbage. */
1617
+ /*========================================*/
1618
+
1619
+ GCBlockStart(theEnv,&gcb);
1620
+
1621
+ /*=====================================*/
1622
+ /* If embedded, clear the error flags. */
1623
+ /*=====================================*/
1624
+
1625
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1626
+ { ResetErrorFlags(theEnv); }
1627
+
1628
+ /*======================*/
1629
+ /* Call the expression. */
1630
+ /*======================*/
1631
+
1632
+ EvaluateExpression(theEnv,&theReference,&udfReturnValue);
1633
+
1634
+ /*====================================================*/
1635
+ /* Convert a partial multifield to a full multifield. */
1636
+ /*====================================================*/
1637
+
1638
+ NormalizeMultifield(theEnv,&udfReturnValue);
1639
+
1640
+ /*========================================*/
1641
+ /* Return the expression data structures. */
1642
+ /*========================================*/
1643
+
1644
+ ExpressionDeinstall(theEnv,&theReference);
1645
+ ReturnExpression(theEnv,theReference.argList);
1646
+
1647
+ /*================================*/
1648
+ /* Restore the old garbage frame. */
1649
+ /*================================*/
1650
+
1651
+ if (returnValue != NULL)
1652
+ { GCBlockEndUDF(theEnv,&gcb,&udfReturnValue); }
1653
+ else
1654
+ { GCBlockEnd(theEnv,&gcb); }
1655
+
1656
+ /*==========================================*/
1657
+ /* Perform periodic cleanup if the eval was */
1658
+ /* issued from an embedded controller. */
1659
+ /*==========================================*/
1660
+
1661
+ if (EvaluationData(theEnv)->CurrentExpression == NULL)
1662
+ {
1663
+ if (returnValue != NULL)
1664
+ { CleanCurrentGarbageFrame(theEnv,&udfReturnValue); }
1665
+ else
1666
+ { CleanCurrentGarbageFrame(theEnv,NULL); }
1667
+ CallPeriodicTasks(theEnv);
1668
+ }
1669
+
1670
+ if (returnValue != NULL)
1671
+ { returnValue->value = udfReturnValue.value; }
1672
+
1673
+ if (GetEvaluationError(theEnv)) return FCBE_PROCESSING_ERROR;
1674
+
1675
+ return FCBE_NO_ERROR;
1676
+ }
1677
+
1678
+ /*************/
1679
+ /* FCBReset: */
1680
+ /*************/
1681
+ void FCBReset(
1682
+ FunctionCallBuilder *theFCB)
1683
+ {
1684
+ size_t i;
1685
+
1686
+ for (i = 0; i < theFCB->length; i++)
1687
+ { Release(theFCB->fcbEnv,theFCB->contents[i].header); }
1688
+
1689
+ if (theFCB->bufferReset != theFCB->bufferMaximum)
1690
+ {
1691
+ if (theFCB->bufferMaximum != 0)
1692
+ { rm(theFCB->fcbEnv,theFCB->contents,sizeof(CLIPSValue) * theFCB->bufferMaximum); }
1693
+
1694
+ if (theFCB->bufferReset == 0)
1695
+ { theFCB->contents = NULL; }
1696
+ else
1697
+ { theFCB->contents = (CLIPSValue *) gm2(theFCB->fcbEnv,sizeof(CLIPSValue) * theFCB->bufferReset); }
1698
+
1699
+ theFCB->bufferMaximum = theFCB->bufferReset;
1700
+ }
1701
+
1702
+ theFCB->length = 0;
1703
+ }
1704
+
1705
+ /***************/
1706
+ /* FCBDispose: */
1707
+ /***************/
1708
+ void FCBDispose(
1709
+ FunctionCallBuilder *theFCB)
1710
+ {
1711
+ Environment *theEnv = theFCB->fcbEnv;
1712
+ size_t i;
1713
+
1714
+ for (i = 0; i < theFCB->length; i++)
1715
+ { Release(theFCB->fcbEnv,theFCB->contents[i].header); }
1716
+
1717
+ if (theFCB->bufferMaximum != 0)
1718
+ { rm(theFCB->fcbEnv,theFCB->contents,sizeof(CLIPSValue) * theFCB->bufferMaximum); }
1719
+
1720
+ rtn_struct(theEnv,multifieldBuilder,theFCB);
1721
+ }
1722
+
1723
+ /*******************************/
1724
+ /* DiscardCAddress: TBD Remove */
1725
+ /*******************************/
1726
+ /*
1727
+ static bool DiscardCAddress(
1728
+ Environment *theEnv,
1729
+ void *theValue)
1730
+ {
1731
+ WriteString(theEnv,STDOUT,"Discarding C Address\n");
1732
+
1733
+ return true;
1734
+ }
1735
+ */
1736
+