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,1618 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 11/01/16 */
5
+ /* */
6
+ /* */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Generic Functions Parsing Routines */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Brian L. Dantes */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* */
17
+ /* Revision History: */
18
+ /* */
19
+ /* 6.24: Renamed BOOLEAN macro type to intBool. */
20
+ /* */
21
+ /* If the last construct in a loaded file is a */
22
+ /* deffunction or defmethod with no closing right */
23
+ /* parenthesis, an error should be issued, but is */
24
+ /* not. DR0872 */
25
+ /* */
26
+ /* 6.30: Changed integer type/precision. */
27
+ /* */
28
+ /* GetConstructNameAndComment API change. */
29
+ /* */
30
+ /* Support for long long integers. */
31
+ /* */
32
+ /* Used gensprintf instead of sprintf. */
33
+ /* */
34
+ /* Added const qualifiers to remove C++ */
35
+ /* deprecation warnings. */
36
+ /* */
37
+ /* Converted API macros to function calls. */
38
+ /* */
39
+ /* Fixed linkage issue when BLOAD_AND_SAVE */
40
+ /* compiler flag is set to 0. */
41
+ /* */
42
+ /* Fixed typing issue when OBJECT_SYSTEM */
43
+ /* compiler flag is set to 0. */
44
+ /* */
45
+ /* Changed find construct functionality so that */
46
+ /* imported modules are search when locating a */
47
+ /* named construct. */
48
+ /* */
49
+ /* 6.40: Pragma once and other inclusion changes. */
50
+ /* */
51
+ /* Added support for booleans with <stdbool.h>. */
52
+ /* */
53
+ /* Removed use of void pointers for specific */
54
+ /* data structures. */
55
+ /* */
56
+ /*************************************************************/
57
+
58
+ /* =========================================
59
+ *****************************************
60
+ EXTERNAL DEFINITIONS
61
+ =========================================
62
+ ***************************************** */
63
+
64
+ #include "setup.h"
65
+
66
+ #if DEFGENERIC_CONSTRUCT && (! BLOAD_ONLY) && (! RUN_TIME)
67
+
68
+ #if BLOAD || BLOAD_AND_BSAVE
69
+ #include "bload.h"
70
+ #endif
71
+
72
+ #if DEFFUNCTION_CONSTRUCT
73
+ #include "dffnxfun.h"
74
+ #endif
75
+
76
+ #if OBJECT_SYSTEM
77
+ #include "classfun.h"
78
+ #include "classcom.h"
79
+ #endif
80
+
81
+ #include "cstrccom.h"
82
+ #include "cstrcpsr.h"
83
+ #include "envrnmnt.h"
84
+ #include "exprnpsr.h"
85
+ #include "genrccom.h"
86
+ #include "immthpsr.h"
87
+ #include "memalloc.h"
88
+ #include "modulutl.h"
89
+ #include "pprint.h"
90
+ #include "prcdrpsr.h"
91
+ #include "prccode.h"
92
+ #include "prntutil.h"
93
+ #include "router.h"
94
+ #include "scanner.h"
95
+ #include "sysdep.h"
96
+
97
+ #include "genrcpsr.h"
98
+
99
+ /* =========================================
100
+ *****************************************
101
+ CONSTANTS
102
+ =========================================
103
+ ***************************************** */
104
+ #define HIGHER_PRECEDENCE -1
105
+ #define IDENTICAL 0
106
+ #define LOWER_PRECEDENCE 1
107
+
108
+ #define CURR_ARG_VAR "current-argument"
109
+
110
+ #define PARAMETER_ERROR USHRT_MAX
111
+
112
+ /* =========================================
113
+ *****************************************
114
+ INTERNALLY VISIBLE FUNCTION HEADERS
115
+ =========================================
116
+ ***************************************** */
117
+
118
+ static bool ValidGenericName(Environment *,const char *);
119
+ static CLIPSLexeme *ParseMethodNameAndIndex(Environment *,const char *,unsigned short *,struct token *);
120
+
121
+ #if DEBUGGING_FUNCTIONS
122
+ static void CreateDefaultGenericPPForm(Environment *,Defgeneric *);
123
+ #endif
124
+
125
+ static unsigned short ParseMethodParameters(Environment *,const char *,Expression **,CLIPSLexeme **,struct token *);
126
+ static RESTRICTION *ParseRestriction(Environment *,const char *);
127
+ static void ReplaceCurrentArgRefs(Environment *,Expression *);
128
+ static bool DuplicateParameters(Environment *,Expression *,Expression **,CLIPSLexeme *);
129
+ static Expression *AddParameter(Environment *,Expression *,Expression *,CLIPSLexeme *,RESTRICTION *);
130
+ static Expression *ValidType(Environment *,CLIPSLexeme *);
131
+ static bool RedundantClasses(Environment *,void *,void *);
132
+ static Defgeneric *AddGeneric(Environment *,CLIPSLexeme *,bool *);
133
+ static Defmethod *AddGenericMethod(Environment *,Defgeneric *,int,unsigned short);
134
+ static int RestrictionsCompare(Expression *,int,int,int,Defmethod *);
135
+ static int TypeListCompare(RESTRICTION *,RESTRICTION *);
136
+ static Defgeneric *NewGeneric(Environment *,CLIPSLexeme *);
137
+
138
+ /* =========================================
139
+ *****************************************
140
+ EXTERNALLY VISIBLE FUNCTIONS
141
+ =========================================
142
+ ***************************************** */
143
+
144
+ /***************************************************************************
145
+ NAME : ParseDefgeneric
146
+ DESCRIPTION : Parses the defgeneric construct
147
+ INPUTS : The input logical name
148
+ RETURNS : False if successful parse, true otherwise
149
+ SIDE EFFECTS : Inserts valid generic function defn into generic entry
150
+ NOTES : H/L Syntax :
151
+ (defgeneric <name> [<comment>])
152
+ ***************************************************************************/
153
+ bool ParseDefgeneric(
154
+ Environment *theEnv,
155
+ const char *readSource)
156
+ {
157
+ CLIPSLexeme *gname;
158
+ Defgeneric *gfunc;
159
+ bool newGeneric;
160
+ struct token genericInputToken;
161
+
162
+ SetPPBufferStatus(theEnv,true);
163
+ FlushPPBuffer(theEnv);
164
+ SavePPBuffer(theEnv,"(defgeneric ");
165
+ SetIndentDepth(theEnv,3);
166
+
167
+ #if BLOAD || BLOAD_AND_BSAVE
168
+ if ((Bloaded(theEnv) == true) && (! ConstructData(theEnv)->CheckSyntaxMode))
169
+ {
170
+ CannotLoadWithBloadMessage(theEnv,"defgeneric");
171
+ return true;
172
+ }
173
+ #endif
174
+
175
+ gname = GetConstructNameAndComment(theEnv,readSource,&genericInputToken,"defgeneric",
176
+ (FindConstructFunction *) FindDefgenericInModule,
177
+ NULL,"^",true,true,true,false);
178
+ if (gname == NULL)
179
+ return true;
180
+
181
+ if (ValidGenericName(theEnv,gname->contents) == false)
182
+ return true;
183
+
184
+ if (genericInputToken.tknType != RIGHT_PARENTHESIS_TOKEN)
185
+ {
186
+ PrintErrorID(theEnv,"GENRCPSR",1,false);
187
+ WriteString(theEnv,STDERR,"Expected ')' to complete defgeneric.\n");
188
+ return true;
189
+ }
190
+ SavePPBuffer(theEnv,"\n");
191
+
192
+ /* ========================================================
193
+ If we're only checking syntax, don't add the
194
+ successfully parsed deffacts to the KB.
195
+ ======================================================== */
196
+
197
+ if (ConstructData(theEnv)->CheckSyntaxMode)
198
+ { return false; }
199
+
200
+ gfunc = AddGeneric(theEnv,gname,&newGeneric);
201
+
202
+ #if DEBUGGING_FUNCTIONS
203
+ SetDefgenericPPForm(theEnv,gfunc,GetConserveMemory(theEnv) ? NULL : CopyPPBuffer(theEnv));
204
+ #endif
205
+ return false;
206
+ }
207
+
208
+ /***************************************************************************
209
+ NAME : ParseDefmethod
210
+ DESCRIPTION : Parses the defmethod construct
211
+ INPUTS : The input logical name
212
+ RETURNS : False if successful parse, true otherwise
213
+ SIDE EFFECTS : Inserts valid method definition into generic entry
214
+ NOTES : H/L Syntax :
215
+ (defmethod <name> [<index>] [<comment>]
216
+ (<restriction>* [<wildcard>])
217
+ <action>*)
218
+ <restriction> :== ?<name> |
219
+ (?<name> <type>* [<restriction-query>])
220
+ <wildcard> :== $?<name> |
221
+ ($?<name> <type>* [<restriction-query>])
222
+ ***************************************************************************/
223
+ bool ParseDefmethod(
224
+ Environment *theEnv,
225
+ const char *readSource)
226
+ {
227
+ CLIPSLexeme *gname;
228
+ unsigned short rcnt;
229
+ int mposn;
230
+ unsigned short mi;
231
+ unsigned short lvars;
232
+ bool newMethod;
233
+ bool mnew = false;
234
+ bool error;
235
+ Expression *params,*actions,*tmp;
236
+ CLIPSLexeme *wildcard;
237
+ Defmethod *meth;
238
+ Defgeneric *gfunc;
239
+ unsigned short theIndex;
240
+ struct token genericInputToken;
241
+
242
+ SetPPBufferStatus(theEnv,true);
243
+ FlushPPBuffer(theEnv);
244
+ SetIndentDepth(theEnv,3);
245
+ SavePPBuffer(theEnv,"(defmethod ");
246
+
247
+ #if BLOAD || BLOAD_AND_BSAVE
248
+ if ((Bloaded(theEnv) == true) && (! ConstructData(theEnv)->CheckSyntaxMode))
249
+ {
250
+ CannotLoadWithBloadMessage(theEnv,"defmethod");
251
+ return true;
252
+ }
253
+ #endif
254
+
255
+ gname = ParseMethodNameAndIndex(theEnv,readSource,&theIndex,&genericInputToken);
256
+ if (gname == NULL)
257
+ return true;
258
+
259
+ if (ValidGenericName(theEnv,gname->contents) == false)
260
+ return true;
261
+
262
+ /* ========================================================
263
+ Go ahead and add the header so that the generic function
264
+ can be called recursively
265
+ ======================================================== */
266
+ gfunc = AddGeneric(theEnv,gname,&newMethod);
267
+
268
+ #if DEBUGGING_FUNCTIONS
269
+ if (newMethod && (! ConstructData(theEnv)->CheckSyntaxMode))
270
+ CreateDefaultGenericPPForm(theEnv,gfunc);
271
+ #endif
272
+
273
+ IncrementIndentDepth(theEnv,1);
274
+ rcnt = ParseMethodParameters(theEnv,readSource,&params,&wildcard,&genericInputToken);
275
+ DecrementIndentDepth(theEnv,1);
276
+ if (rcnt == PARAMETER_ERROR)
277
+ goto DefmethodParseError;
278
+ PPCRAndIndent(theEnv);
279
+ for (tmp = params ; tmp != NULL ; tmp = tmp->nextArg)
280
+ {
281
+ ReplaceCurrentArgRefs(theEnv,((RESTRICTION *) tmp->argList)->query);
282
+ if (ReplaceProcVars(theEnv,"method",((RESTRICTION *) tmp->argList)->query,
283
+ params,wildcard,NULL,NULL))
284
+ {
285
+ DeleteTempRestricts(theEnv,params);
286
+ goto DefmethodParseError;
287
+ }
288
+ }
289
+ meth = FindMethodByRestrictions(gfunc,params,rcnt,wildcard,&mposn);
290
+ error = false;
291
+ if (meth != NULL)
292
+ {
293
+ if (meth->system)
294
+ {
295
+ PrintErrorID(theEnv,"GENRCPSR",17,false);
296
+ WriteString(theEnv,STDERR,"Cannot replace the implicit system method #");
297
+ PrintUnsignedInteger(theEnv,STDERR,meth->index);
298
+ WriteString(theEnv,STDERR,".\n");
299
+ error = true;
300
+ }
301
+ else if ((theIndex != 0) && (theIndex != meth->index))
302
+ {
303
+ PrintErrorID(theEnv,"GENRCPSR",2,false);
304
+ WriteString(theEnv,STDERR,"New method #");
305
+ PrintUnsignedInteger(theEnv,STDERR,theIndex);
306
+ WriteString(theEnv,STDERR," would be indistinguishable from method #");
307
+ PrintUnsignedInteger(theEnv,STDERR,meth->index);
308
+ WriteString(theEnv,STDERR,".\n");
309
+ error = true;
310
+ }
311
+ }
312
+ else if (theIndex != 0)
313
+ {
314
+ mi = FindMethodByIndex(gfunc,theIndex);
315
+ if (mi == METHOD_NOT_FOUND)
316
+ mnew = true;
317
+ else if (gfunc->methods[mi].system)
318
+ {
319
+ PrintErrorID(theEnv,"GENRCPSR",17,false);
320
+ WriteString(theEnv,STDERR,"Cannot replace the implicit system method #");
321
+ PrintUnsignedInteger(theEnv,STDERR,theIndex);
322
+ WriteString(theEnv,STDERR,".\n");
323
+ error = true;
324
+ }
325
+ }
326
+ else
327
+ mnew = true;
328
+ if (error)
329
+ {
330
+ DeleteTempRestricts(theEnv,params);
331
+ goto DefmethodParseError;
332
+ }
333
+ ExpressionData(theEnv)->ReturnContext = true;
334
+ actions = ParseProcActions(theEnv,"method",readSource,
335
+ &genericInputToken,params,wildcard,
336
+ NULL,NULL,&lvars,NULL);
337
+
338
+ /*===========================================================*/
339
+ /* Check for the closing right parenthesis of the defmethod. */
340
+ /*===========================================================*/
341
+
342
+ if ((genericInputToken.tknType != RIGHT_PARENTHESIS_TOKEN) && /* DR0872 */
343
+ (actions != NULL))
344
+ {
345
+ SyntaxErrorMessage(theEnv,"defmethod");
346
+ DeleteTempRestricts(theEnv,params);
347
+ ReturnPackedExpression(theEnv,actions);
348
+ goto DefmethodParseError;
349
+ }
350
+
351
+ if (actions == NULL)
352
+ {
353
+ DeleteTempRestricts(theEnv,params);
354
+ goto DefmethodParseError;
355
+ }
356
+
357
+ /*==============================================*/
358
+ /* If we're only checking syntax, don't add the */
359
+ /* successfully parsed deffunction to the KB. */
360
+ /*==============================================*/
361
+
362
+ if (ConstructData(theEnv)->CheckSyntaxMode)
363
+ {
364
+ DeleteTempRestricts(theEnv,params);
365
+ ReturnPackedExpression(theEnv,actions);
366
+ if (newMethod)
367
+ {
368
+ RemoveConstructFromModule(theEnv,&gfunc->header);
369
+ RemoveDefgeneric(theEnv,gfunc);
370
+ }
371
+ return false;
372
+ }
373
+
374
+ PPBackup(theEnv);
375
+ PPBackup(theEnv);
376
+ SavePPBuffer(theEnv,genericInputToken.printForm);
377
+ SavePPBuffer(theEnv,"\n");
378
+
379
+ #if DEBUGGING_FUNCTIONS
380
+ meth = AddMethod(theEnv,gfunc,meth,mposn,theIndex,params,rcnt,lvars,wildcard,actions,
381
+ GetConserveMemory(theEnv) ? NULL : CopyPPBuffer(theEnv),false);
382
+ #else
383
+ meth = AddMethod(theEnv,gfunc,meth,mposn,theIndex,params,rcnt,lvars,wildcard,actions,NULL,false);
384
+ #endif
385
+ DeleteTempRestricts(theEnv,params);
386
+ if (GetPrintWhileLoading(theEnv) && GetCompilationsWatch(theEnv) &&
387
+ (! ConstructData(theEnv)->CheckSyntaxMode))
388
+ {
389
+ const char *outRouter = STDOUT;
390
+
391
+ if (mnew)
392
+ {
393
+ WriteString(theEnv,outRouter," Method #");
394
+ PrintUnsignedInteger(theEnv,outRouter,meth->index);
395
+ WriteString(theEnv,outRouter," defined.\n");
396
+ }
397
+ else
398
+ {
399
+ outRouter = STDWRN;
400
+ PrintWarningID(theEnv,"CSTRCPSR",1,true);
401
+ WriteString(theEnv,outRouter,"Method #");
402
+ PrintUnsignedInteger(theEnv,outRouter,meth->index);
403
+ WriteString(theEnv,outRouter," redefined.\n");
404
+ }
405
+ }
406
+ return false;
407
+
408
+ DefmethodParseError:
409
+ if (newMethod)
410
+ {
411
+ RemoveConstructFromModule(theEnv,&gfunc->header);
412
+ RemoveDefgeneric(theEnv,gfunc);
413
+ }
414
+ return true;
415
+ }
416
+
417
+ /************************************************************************
418
+ NAME : AddMethod
419
+ DESCRIPTION : (Re)defines a new method for a generic
420
+ If method already exists, deletes old information
421
+ before proceeding.
422
+ INPUTS : 1) The generic address
423
+ 2) The old method address (can be NULL)
424
+ 3) The old method array position (can be -1)
425
+ 4) The method index to assign (0 if don't care)
426
+ 5) The parameter expression-list
427
+ (restrictions attached to argList pointers)
428
+ 6) The number of restrictions
429
+ 7) The number of locals vars reqd
430
+ 8) The wildcard symbol (NULL if none)
431
+ 9) Method actions
432
+ 10) Method pretty-print form
433
+ 11) A flag indicating whether to copy the
434
+ restriction types or just use the pointers
435
+ RETURNS : The new (old) method address
436
+ SIDE EFFECTS : Method added to (or changed in) method array for generic
437
+ Restrictions repacked into new method
438
+ Actions and pretty-print form attached
439
+ NOTES : Assumes if a method is being redefined, its busy
440
+ count is 0!!
441
+ IMPORTANT: Expects that FindMethodByRestrictions() has
442
+ previously been called to determine if this method
443
+ is already present or not. Arguments #1 and #2
444
+ should be the values obtained from FindMethod...().
445
+ ************************************************************************/
446
+ Defmethod *AddMethod(
447
+ Environment *theEnv,
448
+ Defgeneric *gfunc,
449
+ Defmethod *meth,
450
+ int mposn,
451
+ unsigned short mi,
452
+ Expression *params,
453
+ unsigned short rcnt,
454
+ unsigned short lvars,
455
+ CLIPSLexeme *wildcard,
456
+ Expression *actions,
457
+ char *ppForm,
458
+ bool copyRestricts)
459
+ {
460
+ RESTRICTION *rptr, *rtmp;
461
+ int i,j;
462
+ unsigned short mai;
463
+
464
+ SaveBusyCount(gfunc);
465
+ if (meth == NULL)
466
+ {
467
+ mai = (mi != 0) ? FindMethodByIndex(gfunc,mi) : METHOD_NOT_FOUND;
468
+ if (mai == METHOD_NOT_FOUND)
469
+ meth = AddGenericMethod(theEnv,gfunc,mposn,mi);
470
+ else
471
+ {
472
+ DeleteMethodInfo(theEnv,gfunc,&gfunc->methods[mai]);
473
+ if (mai < mposn)
474
+ {
475
+ mposn--;
476
+ for (i = mai+1 ; i <= mposn ; i++)
477
+ GenCopyMemory(Defmethod,1,&gfunc->methods[i-1],&gfunc->methods[i]);
478
+ }
479
+ else
480
+ {
481
+ for (i = mai-1 ; i >= mposn ; i--)
482
+ GenCopyMemory(Defmethod,1,&gfunc->methods[i+1],&gfunc->methods[i]);
483
+ }
484
+ meth = &gfunc->methods[mposn];
485
+ meth->index = mi;
486
+ }
487
+ }
488
+ else
489
+ {
490
+ /* ================================
491
+ The old trace state is preserved
492
+ ================================ */
493
+ ExpressionDeinstall(theEnv,meth->actions);
494
+ ReturnPackedExpression(theEnv,meth->actions);
495
+ if (meth->header.ppForm != NULL)
496
+ rm(theEnv,(void *) meth->header.ppForm,(sizeof(char) * (strlen(meth->header.ppForm)+1)));
497
+ }
498
+ meth->system = 0;
499
+ meth->actions = actions;
500
+ ExpressionInstall(theEnv,meth->actions);
501
+ meth->header.ppForm = ppForm;
502
+ if (mposn == -1)
503
+ {
504
+ RestoreBusyCount(gfunc);
505
+ return(meth);
506
+ }
507
+
508
+ meth->localVarCount = lvars;
509
+ meth->restrictionCount = rcnt;
510
+
511
+ if (wildcard != NULL)
512
+ {
513
+ if (rcnt == 0)
514
+ { meth->minRestrictions = RESTRICTIONS_UNBOUNDED; }
515
+ else
516
+ { meth->minRestrictions = rcnt - 1; }
517
+ meth->maxRestrictions = RESTRICTIONS_UNBOUNDED;
518
+ }
519
+ else
520
+ meth->minRestrictions = meth->maxRestrictions = rcnt;
521
+ if (rcnt != 0)
522
+ meth->restrictions = (RESTRICTION *)
523
+ gm2(theEnv,(sizeof(RESTRICTION) * rcnt));
524
+ else
525
+ meth->restrictions = NULL;
526
+ for (i = 0 ; i < rcnt ; i++)
527
+ {
528
+ rptr = &meth->restrictions[i];
529
+ rtmp = (RESTRICTION *) params->argList;
530
+ rptr->query = PackExpression(theEnv,rtmp->query);
531
+ rptr->tcnt = rtmp->tcnt;
532
+ if (copyRestricts)
533
+ {
534
+ if (rtmp->types != NULL)
535
+ {
536
+ rptr->types = (void **) gm2(theEnv,(rptr->tcnt * sizeof(void *)));
537
+ GenCopyMemory(void *,rptr->tcnt,rptr->types,rtmp->types);
538
+ }
539
+ else
540
+ rptr->types = NULL;
541
+ }
542
+ else
543
+ {
544
+ rptr->types = rtmp->types;
545
+
546
+ /* =====================================================
547
+ Make sure the types-array is not deallocated when the
548
+ temporary restriction nodes are
549
+ ===================================================== */
550
+ rtmp->tcnt = 0;
551
+ rtmp->types = NULL;
552
+ }
553
+ ExpressionInstall(theEnv,rptr->query);
554
+ for (j = 0 ; j < rptr->tcnt ; j++)
555
+ #if OBJECT_SYSTEM
556
+ IncrementDefclassBusyCount(theEnv,(Defclass *) rptr->types[j]);
557
+ #else
558
+ IncrementIntegerCount((CLIPSInteger *) rptr->types[j]);
559
+ #endif
560
+ params = params->nextArg;
561
+ }
562
+ RestoreBusyCount(gfunc);
563
+ return(meth);
564
+ }
565
+
566
+ /*****************************************************
567
+ NAME : PackRestrictionTypes
568
+ DESCRIPTION : Takes the restriction type list
569
+ and packs it into a contiguous
570
+ array of void *.
571
+ INPUTS : 1) The restriction structure
572
+ 2) The types expression list
573
+ RETURNS : Nothing useful
574
+ SIDE EFFECTS : Array allocated & expressions freed
575
+ NOTES : None
576
+ *****************************************************/
577
+ void PackRestrictionTypes(
578
+ Environment *theEnv,
579
+ RESTRICTION *rptr,
580
+ Expression *types)
581
+ {
582
+ Expression *tmp;
583
+ long i;
584
+
585
+ rptr->tcnt = 0;
586
+ for (tmp = types ; tmp != NULL ; tmp = tmp->nextArg)
587
+ rptr->tcnt++;
588
+ if (rptr->tcnt != 0)
589
+ rptr->types = (void **) gm2(theEnv,(sizeof(void *) * rptr->tcnt));
590
+ else
591
+ rptr->types = NULL;
592
+ for (i = 0 , tmp = types ; i < rptr->tcnt ; i++ , tmp = tmp->nextArg)
593
+ rptr->types[i] = tmp->value;
594
+ ReturnExpression(theEnv,types);
595
+ }
596
+
597
+ /***************************************************
598
+ NAME : DeleteTempRestricts
599
+ DESCRIPTION : Deallocates the method
600
+ temporary parameter list
601
+ INPUTS : The head of the list
602
+ RETURNS : Nothing useful
603
+ SIDE EFFECTS : List deallocated
604
+ NOTES : None
605
+ ***************************************************/
606
+ void DeleteTempRestricts(
607
+ Environment *theEnv,
608
+ Expression *phead)
609
+ {
610
+ Expression *ptmp;
611
+ RESTRICTION *rtmp;
612
+
613
+ while (phead != NULL)
614
+ {
615
+ ptmp = phead;
616
+ phead = phead->nextArg;
617
+ rtmp = (RESTRICTION *) ptmp->argList;
618
+ rtn_struct(theEnv,expr,ptmp);
619
+ ReturnExpression(theEnv,rtmp->query);
620
+ if (rtmp->tcnt != 0)
621
+ rm(theEnv,rtmp->types,(sizeof(void *) * rtmp->tcnt));
622
+ rtn_struct(theEnv,restriction,rtmp);
623
+ }
624
+ }
625
+
626
+ /**********************************************************
627
+ NAME : FindMethodByRestrictions
628
+ DESCRIPTION : See if a method for the specified
629
+ generic satsifies the given restrictions
630
+ INPUTS : 1) Generic function
631
+ 2) Parameter/restriction expression list
632
+ 3) Number of restrictions
633
+ 4) Wildcard symbol (can be NULL)
634
+ 5) Caller's buffer for holding array posn
635
+ of where to add new generic method
636
+ (-1 if method already present)
637
+ RETURNS : The address of the found method, NULL if
638
+ not found
639
+ SIDE EFFECTS : Sets the caller's buffer to the index of
640
+ where to place the new method, -1 if
641
+ already present
642
+ NOTES : None
643
+ **********************************************************/
644
+ Defmethod *FindMethodByRestrictions(
645
+ Defgeneric *gfunc,
646
+ Expression *params,
647
+ int rcnt,
648
+ CLIPSLexeme *wildcard,
649
+ int *posn)
650
+ {
651
+ int i,cmp;
652
+ int min,max;
653
+
654
+ if (wildcard != NULL)
655
+ {
656
+ min = rcnt-1;
657
+ max = -1;
658
+ }
659
+ else
660
+ min = max = rcnt;
661
+ for (i = 0 ; i < gfunc->mcnt ; i++)
662
+ {
663
+ cmp = RestrictionsCompare(params,rcnt,min,max,&gfunc->methods[i]);
664
+ if (cmp == IDENTICAL)
665
+ {
666
+ *posn = -1;
667
+ return(&gfunc->methods[i]);
668
+ }
669
+ else if (cmp == HIGHER_PRECEDENCE)
670
+ {
671
+ *posn = i;
672
+ return NULL;
673
+ }
674
+ }
675
+ *posn = i;
676
+ return NULL;
677
+ }
678
+
679
+ /* =========================================
680
+ *****************************************
681
+ INTERNALLY VISIBLE FUNCTIONS
682
+ =========================================
683
+ ***************************************** */
684
+
685
+ /***********************************************************
686
+ NAME : ValidGenericName
687
+ DESCRIPTION : Determines if a particular function name
688
+ can be overloaded
689
+ INPUTS : The name
690
+ RETURNS : True if OK, false otherwise
691
+ SIDE EFFECTS : Error message printed
692
+ NOTES : GetConstructNameAndComment() (called before
693
+ this function) ensures that the defgeneric
694
+ name does not conflict with one from
695
+ another module
696
+ ***********************************************************/
697
+ static bool ValidGenericName(
698
+ Environment *theEnv,
699
+ const char *theDefgenericName)
700
+ {
701
+ Defgeneric *theDefgeneric;
702
+ #if DEFFUNCTION_CONSTRUCT
703
+ Defmodule *theModule;
704
+ Deffunction *theDeffunction;
705
+ #endif
706
+ struct functionDefinition *systemFunction;
707
+
708
+ /*==============================================*/
709
+ /* A defgeneric cannot be named the same as a */
710
+ /* construct type, e.g, defclass, defrule, etc. */
711
+ /*==============================================*/
712
+
713
+ if (FindConstruct(theEnv,theDefgenericName) != NULL)
714
+ {
715
+ PrintErrorID(theEnv,"GENRCPSR",3,false);
716
+ WriteString(theEnv,STDERR,"Defgenerics are not allowed to replace constructs.\n");
717
+ return false;
718
+ }
719
+
720
+ #if DEFFUNCTION_CONSTRUCT
721
+ /* ========================================
722
+ A defgeneric cannot be named the same as
723
+ a defffunction (either in this module or
724
+ imported from another)
725
+ ======================================== */
726
+ theDeffunction = LookupDeffunctionInScope(theEnv,theDefgenericName);
727
+ if (theDeffunction != NULL)
728
+ {
729
+ theModule = GetConstructModuleItem(&theDeffunction->header)->theModule;
730
+ if (theModule != GetCurrentModule(theEnv))
731
+ {
732
+ PrintErrorID(theEnv,"GENRCPSR",4,false);
733
+ WriteString(theEnv,STDERR,"Deffunction '");
734
+ WriteString(theEnv,STDERR,DeffunctionName(theDeffunction));
735
+ WriteString(theEnv,STDERR,"' imported from module '");
736
+ WriteString(theEnv,STDERR,DefmoduleName(theModule));
737
+ WriteString(theEnv,STDERR,"' conflicts with this defgeneric.\n");
738
+ return false;
739
+ }
740
+ else
741
+ {
742
+ PrintErrorID(theEnv,"GENRCPSR",5,false);
743
+ WriteString(theEnv,STDERR,"Defgenerics are not allowed to replace deffunctions.\n");
744
+ }
745
+ return false;
746
+ }
747
+ #endif
748
+
749
+ /*===========================================*/
750
+ /* See if the defgeneric already exists in */
751
+ /* this module (or is imported from another) */
752
+ /*===========================================*/
753
+
754
+ theDefgeneric = FindDefgenericInModule(theEnv,theDefgenericName);
755
+ if (theDefgeneric != NULL)
756
+ {
757
+ /* ===========================================
758
+ And the redefinition of a defgeneric in
759
+ the current module is only valid if none
760
+ of its methods are executing
761
+ =========================================== */
762
+ if (MethodsExecuting(theDefgeneric))
763
+ {
764
+ MethodAlterError(theEnv,theDefgeneric);
765
+ return false;
766
+ }
767
+ }
768
+
769
+ /* =======================================
770
+ Only certain specific system functions
771
+ may be overloaded by generic functions
772
+ ======================================= */
773
+ systemFunction = FindFunction(theEnv,theDefgenericName);
774
+ if ((systemFunction != NULL) ?
775
+ (systemFunction->overloadable == false) : false)
776
+ {
777
+ PrintErrorID(theEnv,"GENRCPSR",16,false);
778
+ WriteString(theEnv,STDERR,"The system function '");
779
+ WriteString(theEnv,STDERR,theDefgenericName);
780
+ WriteString(theEnv,STDERR,"' cannot be overloaded.\n");
781
+ return false;
782
+ }
783
+ return true;
784
+ }
785
+
786
+ #if DEBUGGING_FUNCTIONS
787
+
788
+ /***************************************************
789
+ NAME : CreateDefaultGenericPPForm
790
+ DESCRIPTION : Adds a default pretty-print form
791
+ for a gneric function when it is
792
+ impliciylt created by the defn
793
+ of its first method
794
+ INPUTS : The generic function
795
+ RETURNS : Nothing useful
796
+ SIDE EFFECTS : Pretty-print form created and
797
+ attached.
798
+ NOTES : None
799
+ ***************************************************/
800
+ static void CreateDefaultGenericPPForm(
801
+ Environment *theEnv,
802
+ Defgeneric *gfunc)
803
+ {
804
+ const char *moduleName, *genericName;
805
+ char *buf;
806
+
807
+ moduleName = DefmoduleName(GetCurrentModule(theEnv));
808
+ genericName = DefgenericName(gfunc);
809
+ buf = (char *) gm2(theEnv,(sizeof(char) * (strlen(moduleName) + strlen(genericName) + 17)));
810
+ gensprintf(buf,"(defgeneric %s::%s)\n",moduleName,genericName);
811
+ SetDefgenericPPForm(theEnv,gfunc,buf);
812
+ }
813
+
814
+ #endif
815
+
816
+ /*******************************************************
817
+ NAME : ParseMethodNameAndIndex
818
+ DESCRIPTION : Parses the name of the method and
819
+ optional method index
820
+ INPUTS : 1) The logical name of the input source
821
+ 2) Caller's buffer for method index
822
+ (0 if not specified)
823
+ RETURNS : The symbolic name of the method
824
+ SIDE EFFECTS : None
825
+ NOTES : Assumes "(defmethod " already parsed
826
+ *******************************************************/
827
+ static CLIPSLexeme *ParseMethodNameAndIndex(
828
+ Environment *theEnv,
829
+ const char *readSource,
830
+ unsigned short *theIndex,
831
+ struct token *genericInputToken)
832
+ {
833
+ CLIPSLexeme *gname;
834
+
835
+ *theIndex = 0;
836
+ gname = GetConstructNameAndComment(theEnv,readSource,genericInputToken,"defgeneric",
837
+ (FindConstructFunction *) FindDefgenericInModule,
838
+ NULL,"&",true,false,true,true);
839
+ if (gname == NULL)
840
+ return NULL;
841
+ if (genericInputToken->tknType == INTEGER_TOKEN)
842
+ {
843
+ unsigned short tmp;
844
+
845
+ PPBackup(theEnv);
846
+ PPBackup(theEnv);
847
+ SavePPBuffer(theEnv," ");
848
+ SavePPBuffer(theEnv,genericInputToken->printForm);
849
+ tmp = (unsigned short) genericInputToken->integerValue->contents;
850
+ if (tmp < 1)
851
+ {
852
+ PrintErrorID(theEnv,"GENRCPSR",6,false);
853
+ WriteString(theEnv,STDERR,"Method index out of range.\n");
854
+ return NULL;
855
+ }
856
+ *theIndex = tmp;
857
+ PPCRAndIndent(theEnv);
858
+ GetToken(theEnv,readSource,genericInputToken);
859
+ }
860
+ if (genericInputToken->tknType == STRING_TOKEN)
861
+ {
862
+ PPBackup(theEnv);
863
+ PPBackup(theEnv);
864
+ SavePPBuffer(theEnv," ");
865
+ SavePPBuffer(theEnv,genericInputToken->printForm);
866
+ PPCRAndIndent(theEnv);
867
+ GetToken(theEnv,readSource,genericInputToken);
868
+ }
869
+ return(gname);
870
+ }
871
+
872
+ /************************************************************************
873
+ NAME : ParseMethodParameters
874
+ DESCRIPTION : Parses method restrictions
875
+ (parameter names with class and expression specifiers)
876
+ INPUTS : 1) The logical name of the input source
877
+ 2) Caller's buffer for the parameter name list
878
+ (Restriction structures are attached to
879
+ argList pointers of parameter nodes)
880
+ 3) Caller's buffer for wildcard symbol (if any)
881
+ RETURNS : The number of parameters, or -1 on errors
882
+ SIDE EFFECTS : Memory allocated for parameters and restrictions
883
+ Parameter names stored in expression list
884
+ Parameter restrictions stored in contiguous array
885
+ NOTES : Any memory allocated is freed on errors
886
+ Assumes first opening parenthesis has been scanned
887
+ ************************************************************************/
888
+ static unsigned short ParseMethodParameters(
889
+ Environment *theEnv,
890
+ const char *readSource,
891
+ Expression **params,
892
+ CLIPSLexeme **wildcard,
893
+ struct token *genericInputToken)
894
+ {
895
+ Expression *phead = NULL,*pprv;
896
+ CLIPSLexeme *pname;
897
+ RESTRICTION *rtmp;
898
+ unsigned short rcnt = 0;
899
+
900
+ *wildcard = NULL;
901
+ *params = NULL;
902
+ if (genericInputToken->tknType != LEFT_PARENTHESIS_TOKEN)
903
+ {
904
+ PrintErrorID(theEnv,"GENRCPSR",7,false);
905
+ WriteString(theEnv,STDERR,"Expected a '(' to begin method parameter restrictions.\n");
906
+ return PARAMETER_ERROR;
907
+ }
908
+ GetToken(theEnv,readSource,genericInputToken);
909
+ while (genericInputToken->tknType != RIGHT_PARENTHESIS_TOKEN)
910
+ {
911
+ if (*wildcard != NULL)
912
+ {
913
+ DeleteTempRestricts(theEnv,phead);
914
+ PrintErrorID(theEnv,"PRCCODE",8,false);
915
+ WriteString(theEnv,STDERR,"No parameters allowed after wildcard parameter.\n");
916
+ return PARAMETER_ERROR;
917
+ }
918
+ if ((genericInputToken->tknType == SF_VARIABLE_TOKEN) ||
919
+ (genericInputToken->tknType == MF_VARIABLE_TOKEN))
920
+ {
921
+ pname = genericInputToken->lexemeValue;
922
+ if (DuplicateParameters(theEnv,phead,&pprv,pname))
923
+ {
924
+ DeleteTempRestricts(theEnv,phead);
925
+ return PARAMETER_ERROR;
926
+ }
927
+ if (genericInputToken->tknType == MF_VARIABLE_TOKEN)
928
+ *wildcard = pname;
929
+ rtmp = get_struct(theEnv,restriction);
930
+ PackRestrictionTypes(theEnv,rtmp,NULL);
931
+ rtmp->query = NULL;
932
+ phead = AddParameter(theEnv,phead,pprv,pname,rtmp);
933
+ rcnt++;
934
+ }
935
+ else if (genericInputToken->tknType == LEFT_PARENTHESIS_TOKEN)
936
+ {
937
+ GetToken(theEnv,readSource,genericInputToken);
938
+ if ((genericInputToken->tknType != SF_VARIABLE_TOKEN) &&
939
+ (genericInputToken->tknType != MF_VARIABLE_TOKEN))
940
+ {
941
+ DeleteTempRestricts(theEnv,phead);
942
+ PrintErrorID(theEnv,"GENRCPSR",8,false);
943
+ WriteString(theEnv,STDERR,"Expected a variable for parameter specification.\n");
944
+ return PARAMETER_ERROR;
945
+ }
946
+ pname = genericInputToken->lexemeValue;
947
+ if (DuplicateParameters(theEnv,phead,&pprv,pname))
948
+ {
949
+ DeleteTempRestricts(theEnv,phead);
950
+ return PARAMETER_ERROR;
951
+ }
952
+ if (genericInputToken->tknType == MF_VARIABLE_TOKEN)
953
+ *wildcard = pname;
954
+ SavePPBuffer(theEnv," ");
955
+ rtmp = ParseRestriction(theEnv,readSource);
956
+ if (rtmp == NULL)
957
+ {
958
+ DeleteTempRestricts(theEnv,phead);
959
+ return PARAMETER_ERROR;
960
+ }
961
+ phead = AddParameter(theEnv,phead,pprv,pname,rtmp);
962
+ rcnt++;
963
+ }
964
+ else
965
+ {
966
+ DeleteTempRestricts(theEnv,phead);
967
+ PrintErrorID(theEnv,"GENRCPSR",9,false);
968
+ WriteString(theEnv,STDERR,"Expected a variable or '(' for parameter specification.\n");
969
+ return PARAMETER_ERROR;
970
+ }
971
+ PPCRAndIndent(theEnv);
972
+ GetToken(theEnv,readSource,genericInputToken);
973
+ }
974
+ if (rcnt != 0)
975
+ {
976
+ PPBackup(theEnv);
977
+ PPBackup(theEnv);
978
+ SavePPBuffer(theEnv,")");
979
+ }
980
+ *params = phead;
981
+ return(rcnt);
982
+ }
983
+
984
+ /************************************************************
985
+ NAME : ParseRestriction
986
+ DESCRIPTION : Parses the restriction for a parameter of a
987
+ method
988
+ This restriction is comprised of:
989
+ 1) A list of classes (or types) that are
990
+ allowed for the parameter (None
991
+ if no type restriction)
992
+ 2) And an optional restriction-query
993
+ expression
994
+ INPUTS : The logical name of the input source
995
+ RETURNS : The address of a RESTRICTION node, NULL on
996
+ errors
997
+ SIDE EFFECTS : RESTRICTION node allocated
998
+ Types are in a contiguous array of void *
999
+ Query is an expression
1000
+ NOTES : Assumes "(?<var> " has already been parsed
1001
+ H/L Syntax: <type>* [<query>])
1002
+ ************************************************************/
1003
+ static RESTRICTION *ParseRestriction(
1004
+ Environment *theEnv,
1005
+ const char *readSource)
1006
+ {
1007
+ Expression *types = NULL,*new_types,
1008
+ *typesbot,*tmp,*tmp2,
1009
+ *query = NULL;
1010
+ RESTRICTION *rptr;
1011
+ struct token genericInputToken;
1012
+
1013
+ GetToken(theEnv,readSource,&genericInputToken);
1014
+ while (genericInputToken.tknType != RIGHT_PARENTHESIS_TOKEN)
1015
+ {
1016
+ if (query != NULL)
1017
+ {
1018
+ PrintErrorID(theEnv,"GENRCPSR",10,false);
1019
+ WriteString(theEnv,STDERR,"Query must be last in parameter restriction.\n");
1020
+ ReturnExpression(theEnv,query);
1021
+ ReturnExpression(theEnv,types);
1022
+ return NULL;
1023
+ }
1024
+ if (genericInputToken.tknType == SYMBOL_TOKEN)
1025
+ {
1026
+ new_types = ValidType(theEnv,genericInputToken.lexemeValue);
1027
+ if (new_types == NULL)
1028
+ {
1029
+ ReturnExpression(theEnv,types);
1030
+ ReturnExpression(theEnv,query);
1031
+ return NULL;
1032
+ }
1033
+ if (types == NULL)
1034
+ types = new_types;
1035
+ else
1036
+ {
1037
+ for (typesbot = tmp = types ; tmp != NULL ; tmp = tmp->nextArg)
1038
+ {
1039
+ for (tmp2 = new_types ; tmp2 != NULL ; tmp2 = tmp2->nextArg)
1040
+ {
1041
+ if (tmp->value == tmp2->value)
1042
+ {
1043
+ PrintErrorID(theEnv,"GENRCPSR",11,false);
1044
+ #if OBJECT_SYSTEM
1045
+ WriteString(theEnv,STDERR,"Duplicate classes not allowed in parameter restriction.\n");
1046
+ #else
1047
+ WriteString(theEnv,STDERR,"Duplicate types not allowed in parameter restriction.\n");
1048
+ #endif
1049
+ ReturnExpression(theEnv,query);
1050
+ ReturnExpression(theEnv,types);
1051
+ ReturnExpression(theEnv,new_types);
1052
+ return NULL;
1053
+ }
1054
+ if (RedundantClasses(theEnv,tmp->value,tmp2->value))
1055
+ {
1056
+ ReturnExpression(theEnv,query);
1057
+ ReturnExpression(theEnv,types);
1058
+ ReturnExpression(theEnv,new_types);
1059
+ return NULL;
1060
+ }
1061
+ }
1062
+ typesbot = tmp;
1063
+ }
1064
+ typesbot->nextArg = new_types;
1065
+ }
1066
+ }
1067
+ else if (genericInputToken.tknType == LEFT_PARENTHESIS_TOKEN)
1068
+ {
1069
+ query = Function1Parse(theEnv,readSource);
1070
+ if (query == NULL)
1071
+ {
1072
+ ReturnExpression(theEnv,types);
1073
+ return NULL;
1074
+ }
1075
+ if (GetParsedBindNames(theEnv) != NULL)
1076
+ {
1077
+ PrintErrorID(theEnv,"GENRCPSR",12,false);
1078
+ WriteString(theEnv,STDERR,"Binds are not allowed in query expressions.\n");
1079
+ ReturnExpression(theEnv,query);
1080
+ ReturnExpression(theEnv,types);
1081
+ return NULL;
1082
+ }
1083
+ }
1084
+ #if DEFGLOBAL_CONSTRUCT
1085
+ else if (genericInputToken.tknType == GBL_VARIABLE_TOKEN)
1086
+ query = GenConstant(theEnv,GBL_VARIABLE,genericInputToken.value);
1087
+ #endif
1088
+ else
1089
+ {
1090
+ PrintErrorID(theEnv,"GENRCPSR",13,false);
1091
+ #if OBJECT_SYSTEM
1092
+ WriteString(theEnv,STDERR,"Expected a valid class name or query.\n");
1093
+ #else
1094
+ WriteString(theEnv,STDERR,"Expected a valid type name or query.\n");
1095
+ #endif
1096
+ ReturnExpression(theEnv,query);
1097
+ ReturnExpression(theEnv,types);
1098
+ return NULL;
1099
+ }
1100
+ SavePPBuffer(theEnv," ");
1101
+ GetToken(theEnv,readSource,&genericInputToken);
1102
+ }
1103
+ PPBackup(theEnv);
1104
+ PPBackup(theEnv);
1105
+ SavePPBuffer(theEnv,")");
1106
+ if ((types == NULL) && (query == NULL))
1107
+ {
1108
+ PrintErrorID(theEnv,"GENRCPSR",13,false);
1109
+ #if OBJECT_SYSTEM
1110
+ WriteString(theEnv,STDERR,"Expected a valid class name or query.\n");
1111
+ #else
1112
+ WriteString(theEnv,STDERR,"Expected a valid type name or query.\n");
1113
+ #endif
1114
+ return NULL;
1115
+ }
1116
+ rptr = get_struct(theEnv,restriction);
1117
+ rptr->query = query;
1118
+ PackRestrictionTypes(theEnv,rptr,types);
1119
+ return(rptr);
1120
+ }
1121
+
1122
+ /*****************************************************************
1123
+ NAME : ReplaceCurrentArgRefs
1124
+ DESCRIPTION : Replaces all references to ?current-argument in
1125
+ method parameter queries with special calls
1126
+ to (gnrc-current-arg)
1127
+ INPUTS : The query expression
1128
+ RETURNS : Nothing useful
1129
+ SIDE EFFECTS : Variable references to ?current-argument replaced
1130
+ NOTES : None
1131
+ *****************************************************************/
1132
+ static void ReplaceCurrentArgRefs(
1133
+ Environment *theEnv,
1134
+ Expression *query)
1135
+ {
1136
+ while (query != NULL)
1137
+ {
1138
+ if ((query->type != SF_VARIABLE) ? false :
1139
+ (strcmp(query->lexemeValue->contents,CURR_ARG_VAR) == 0))
1140
+ {
1141
+ query->type = FCALL;
1142
+ query->value = FindFunction(theEnv,"(gnrc-current-arg)");
1143
+ }
1144
+ if (query->argList != NULL)
1145
+ ReplaceCurrentArgRefs(theEnv,query->argList);
1146
+ query = query->nextArg;
1147
+ }
1148
+ }
1149
+
1150
+ /**********************************************************
1151
+ NAME : DuplicateParameters
1152
+ DESCRIPTION : Examines the parameter expression
1153
+ chain for a method looking duplicates.
1154
+ INPUTS : 1) The parameter chain (can be NULL)
1155
+ 2) Caller's buffer for address of
1156
+ last node searched (can be used to
1157
+ later attach new parameter)
1158
+ 3) The name of the parameter being checked
1159
+ RETURNS : True if duplicates found, false otherwise
1160
+ SIDE EFFECTS : Caller's prv address set
1161
+ NOTES : Assumes all parameter list nodes are WORDS
1162
+ **********************************************************/
1163
+ static bool DuplicateParameters(
1164
+ Environment *theEnv,
1165
+ Expression *head,
1166
+ Expression **prv,
1167
+ CLIPSLexeme *name)
1168
+ {
1169
+ *prv = NULL;
1170
+ while (head != NULL)
1171
+ {
1172
+ if (head->value == (void *) name)
1173
+ {
1174
+ PrintErrorID(theEnv,"PRCCODE",7,false);
1175
+ WriteString(theEnv,STDERR,"Duplicate parameter names not allowed.\n");
1176
+ return true;
1177
+ }
1178
+ *prv = head;
1179
+ head = head->nextArg;
1180
+ }
1181
+ return false;
1182
+ }
1183
+
1184
+ /*****************************************************************
1185
+ NAME : AddParameter
1186
+ DESCRIPTION : Shoves a new paramter with its restriction
1187
+ onto the list for a method
1188
+ The parameter list is a list of expressions
1189
+ linked by neext_arg pointers, and the
1190
+ argList pointers are used for the restrictions
1191
+ INPUTS : 1) The head of the list
1192
+ 2) The bottom of the list
1193
+ 3) The parameter name
1194
+ 4) The parameter restriction
1195
+ RETURNS : The (new) head of the list
1196
+ SIDE EFFECTS : New parameter expression node allocated, set,
1197
+ and attached
1198
+ NOTES : None
1199
+ *****************************************************************/
1200
+ static Expression *AddParameter(
1201
+ Environment *theEnv,
1202
+ Expression *phead,
1203
+ Expression *pprv,
1204
+ CLIPSLexeme *pname,
1205
+ RESTRICTION *rptr)
1206
+ {
1207
+ Expression *ptmp;
1208
+
1209
+ ptmp = GenConstant(theEnv,SYMBOL_TYPE,pname);
1210
+ if (phead == NULL)
1211
+ phead = ptmp;
1212
+ else
1213
+ pprv->nextArg = ptmp;
1214
+ ptmp->argList = (Expression *) rptr;
1215
+ return(phead);
1216
+ }
1217
+
1218
+ /**************************************************************
1219
+ NAME : ValidType
1220
+ DESCRIPTION : Examines the name of a restriction type and
1221
+ forms a list of integer-code expressions
1222
+ corresponding to the primitive types
1223
+ (or a Class address if COOL is installed)
1224
+ INPUTS : The type name
1225
+ RETURNS : The expression chain (NULL on errors)
1226
+ SIDE EFFECTS : Expression type chain allocated
1227
+ one or more nodes holding codes for types
1228
+ (or class addresses)
1229
+ NOTES : None
1230
+ *************************************************************/
1231
+ static Expression *ValidType(
1232
+ Environment *theEnv,
1233
+ CLIPSLexeme *tname)
1234
+ {
1235
+ #if OBJECT_SYSTEM
1236
+ Defclass *cls;
1237
+
1238
+ if (FindModuleSeparator(tname->contents))
1239
+ IllegalModuleSpecifierMessage(theEnv);
1240
+ else
1241
+ {
1242
+ cls = LookupDefclassInScope(theEnv,tname->contents);
1243
+ if (cls == NULL)
1244
+ {
1245
+ PrintErrorID(theEnv,"GENRCPSR",14,false);
1246
+ WriteString(theEnv,STDERR,"Unknown class in method.\n");
1247
+ return NULL;
1248
+ }
1249
+ return(GenConstant(theEnv,DEFCLASS_PTR,cls));
1250
+ }
1251
+ #else
1252
+ if (strcmp(tname->contents,INTEGER_TYPE_NAME) == 0)
1253
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,INTEGER_TYPE)));
1254
+ if (strcmp(tname->contents,FLOAT_TYPE_NAME) == 0)
1255
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,FLOAT_TYPE)));
1256
+ if (strcmp(tname->contents,SYMBOL_TYPE_NAME) == 0)
1257
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,SYMBOL_TYPE)));
1258
+ if (strcmp(tname->contents,STRING_TYPE_NAME) == 0)
1259
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,STRING_TYPE)));
1260
+ if (strcmp(tname->contents,MULTIFIELD_TYPE_NAME) == 0)
1261
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,MULTIFIELD_TYPE)));
1262
+ if (strcmp(tname->contents,EXTERNAL_ADDRESS_TYPE_NAME) == 0)
1263
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,EXTERNAL_ADDRESS_TYPE)));
1264
+ if (strcmp(tname->contents,FACT_ADDRESS_TYPE_NAME) == 0)
1265
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,FACT_ADDRESS_TYPE)));
1266
+ if (strcmp(tname->contents,NUMBER_TYPE_NAME) == 0)
1267
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,NUMBER_TYPE_CODE)));
1268
+ if (strcmp(tname->contents,LEXEME_TYPE_NAME) == 0)
1269
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,LEXEME_TYPE_CODE)));
1270
+ if (strcmp(tname->contents,ADDRESS_TYPE_NAME) == 0)
1271
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,ADDRESS_TYPE_CODE)));
1272
+ if (strcmp(tname->contents,PRIMITIVE_TYPE_NAME) == 0)
1273
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,PRIMITIVE_TYPE_CODE)));
1274
+ if (strcmp(tname->contents,OBJECT_TYPE_NAME) == 0)
1275
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,OBJECT_TYPE_CODE)));
1276
+ if (strcmp(tname->contents,INSTANCE_TYPE_NAME) == 0)
1277
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,INSTANCE_TYPE_CODE)));
1278
+ if (strcmp(tname->contents,INSTANCE_NAME_TYPE_NAME) == 0)
1279
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,INSTANCE_NAME_TYPE)));
1280
+ if (strcmp(tname->contents,INSTANCE_ADDRESS_TYPE_NAME) == 0)
1281
+ return(GenConstant(theEnv,INTEGER_TYPE,CreateInteger(theEnv,INSTANCE_ADDRESS_TYPE)));
1282
+
1283
+ PrintErrorID(theEnv,"GENRCPSR",14,false);
1284
+ WriteString(theEnv,STDERR,"Unknown type in method.\n");
1285
+ #endif
1286
+ return NULL;
1287
+ }
1288
+
1289
+ /*************************************************************
1290
+ NAME : RedundantClasses
1291
+ DESCRIPTION : Determines if one class (type) is
1292
+ subsumes (or is subsumed by) another.
1293
+ INPUTS : Two void pointers which are class pointers
1294
+ if COOL is installed or integer hash nodes
1295
+ for type codes otherwise.
1296
+ RETURNS : True if there is subsumption, false otherwise
1297
+ SIDE EFFECTS : An error message is printed, if appropriate.
1298
+ NOTES : None
1299
+ *************************************************************/
1300
+ static bool RedundantClasses(
1301
+ Environment *theEnv,
1302
+ void *c1,
1303
+ void *c2)
1304
+ {
1305
+ const char *tname;
1306
+
1307
+ #if OBJECT_SYSTEM
1308
+ if (HasSuperclass((Defclass *) c1,(Defclass *) c2))
1309
+ tname = DefclassName((Defclass *) c1);
1310
+ else if (HasSuperclass((Defclass *) c2,(Defclass *) c1))
1311
+ tname = DefclassName((Defclass *) c2);
1312
+ #else
1313
+ if (SubsumeType(((CLIPSInteger *) c1)->contents,((CLIPSInteger *) c2)->contents))
1314
+ tname = TypeName(theEnv,((CLIPSInteger *) c1)->contents);
1315
+ else if (SubsumeType(((CLIPSInteger *) c2)->contents,((CLIPSInteger *) c1)->contents))
1316
+ tname = TypeName(theEnv,((CLIPSInteger *) c2)->contents);
1317
+ #endif
1318
+ else
1319
+ return false;
1320
+ PrintErrorID(theEnv,"GENRCPSR",15,false);
1321
+ WriteString(theEnv,STDERR,"Class '");
1322
+ WriteString(theEnv,STDERR,tname);
1323
+ WriteString(theEnv,STDERR,"' is redundant.\n");
1324
+ return true;
1325
+ }
1326
+
1327
+ /*********************************************************
1328
+ NAME : AddGeneric
1329
+ DESCRIPTION : Inserts a new generic function
1330
+ header into the generic list
1331
+ INPUTS : 1) Symbolic name of the new generic
1332
+ 2) Caller's input buffer for flag
1333
+ if added generic is new or not
1334
+ RETURNS : The address of the new node, or
1335
+ address of old node if already present
1336
+ SIDE EFFECTS : Generic header inserted
1337
+ If the node is already present, it is
1338
+ moved to the end of the list, otherwise
1339
+ the new node is inserted at the end
1340
+ NOTES : None
1341
+ *********************************************************/
1342
+ static Defgeneric *AddGeneric(
1343
+ Environment *theEnv,
1344
+ CLIPSLexeme *name,
1345
+ bool *newGeneric)
1346
+ {
1347
+ Defgeneric *gfunc;
1348
+
1349
+ gfunc = FindDefgenericInModule(theEnv,name->contents);
1350
+ if (gfunc != NULL)
1351
+ {
1352
+ *newGeneric = false;
1353
+
1354
+ if (ConstructData(theEnv)->CheckSyntaxMode)
1355
+ { return(gfunc); }
1356
+
1357
+ /* ================================
1358
+ The old trace state is preserved
1359
+ ================================ */
1360
+ RemoveConstructFromModule(theEnv,&gfunc->header);
1361
+ }
1362
+ else
1363
+ {
1364
+ *newGeneric = true;
1365
+ gfunc = NewGeneric(theEnv,name);
1366
+ IncrementLexemeCount(name);
1367
+ AddImplicitMethods(theEnv,gfunc);
1368
+ }
1369
+ AddConstructToModule(&gfunc->header);
1370
+ return(gfunc);
1371
+ }
1372
+
1373
+ /**********************************************************************
1374
+ NAME : AddGenericMethod
1375
+ DESCRIPTION : Inserts a blank method (with the method-index set)
1376
+ into the specified position of the generic
1377
+ method array
1378
+ INPUTS : 1) The generic function
1379
+ 2) The index where to add the method in the array
1380
+ 3) The method user-index (0 if don't care)
1381
+ RETURNS : The address of the new method
1382
+ SIDE EFFECTS : Fields initialized (index set) and new method inserted
1383
+ Generic function new method-index set to specified
1384
+ by user-index if > current new method-index
1385
+ NOTES : None
1386
+ **********************************************************************/
1387
+ static Defmethod *AddGenericMethod(
1388
+ Environment *theEnv,
1389
+ Defgeneric *gfunc,
1390
+ int mposn,
1391
+ unsigned short mi)
1392
+ {
1393
+ Defmethod *narr;
1394
+ long b, e;
1395
+
1396
+ narr = (Defmethod *) gm2(theEnv,(sizeof(Defmethod) * (gfunc->mcnt+1)));
1397
+ for (b = e = 0 ; b < gfunc->mcnt ; b++ , e++)
1398
+ {
1399
+ if (b == mposn)
1400
+ e++;
1401
+ GenCopyMemory(Defmethod,1,&narr[e],&gfunc->methods[b]);
1402
+ }
1403
+ if (mi == 0)
1404
+ narr[mposn].index = gfunc->new_index++;
1405
+ else
1406
+ {
1407
+ narr[mposn].index = mi;
1408
+ if (mi >= gfunc->new_index)
1409
+ gfunc->new_index = mi + 1;
1410
+ }
1411
+ narr[mposn].busy = 0;
1412
+ #if DEBUGGING_FUNCTIONS
1413
+ narr[mposn].trace = DefgenericData(theEnv)->WatchMethods;
1414
+ #endif
1415
+ narr[mposn].minRestrictions = 0;
1416
+ narr[mposn].maxRestrictions = 0;
1417
+ narr[mposn].restrictionCount = 0;
1418
+ narr[mposn].localVarCount = 0;
1419
+ narr[mposn].system = 0;
1420
+ narr[mposn].restrictions = NULL;
1421
+ narr[mposn].actions = NULL;
1422
+ narr[mposn].header.name = NULL;
1423
+ narr[mposn].header.next = NULL;
1424
+ narr[mposn].header.constructType = DEFMETHOD;
1425
+ narr[mposn].header.env = theEnv;
1426
+ narr[mposn].header.whichModule = gfunc->header.whichModule;
1427
+ narr[mposn].header.ppForm = NULL;
1428
+ narr[mposn].header.usrData = NULL;
1429
+
1430
+ if (gfunc->mcnt != 0)
1431
+ rm(theEnv,gfunc->methods,(sizeof(Defmethod) * gfunc->mcnt));
1432
+ gfunc->mcnt++;
1433
+ gfunc->methods = narr;
1434
+ return(&narr[mposn]);
1435
+ }
1436
+
1437
+ /****************************************************************
1438
+ NAME : RestrictionsCompare
1439
+ DESCRIPTION : Compares the restriction-expression list
1440
+ with an existing methods restrictions to
1441
+ determine an ordering
1442
+ INPUTS : 1) The parameter/restriction expression list
1443
+ 2) The total number of restrictions
1444
+ 3) The number of minimum restrictions
1445
+ 4) The number of maximum restrictions (-1
1446
+ if unlimited)
1447
+ 5) The method with which to compare restrictions
1448
+ RETURNS : A code representing how the method restrictions
1449
+ -1 : New restrictions have higher precedence
1450
+ 0 : New restrictions are identical
1451
+ 1 : New restrictions have lower precedence
1452
+ SIDE EFFECTS : None
1453
+ NOTES : The new restrictions are stored in the argList
1454
+ pointers of the parameter expressions
1455
+ ****************************************************************/
1456
+ static int RestrictionsCompare(
1457
+ Expression *params,
1458
+ int rcnt,
1459
+ int min,
1460
+ int max,
1461
+ Defmethod *meth)
1462
+ {
1463
+ int i;
1464
+ RESTRICTION *r1,*r2;
1465
+ bool diff = false;
1466
+ int rtn;
1467
+
1468
+ for (i = 0 ; (i < rcnt) && (i < meth->restrictionCount) ; i++)
1469
+ {
1470
+ /* =============================================================
1471
+ A wildcard parameter always has lower precedence than
1472
+ a regular parameter, regardless of the class restriction list
1473
+ ============================================================= */
1474
+ if ((i == rcnt-1) && (max == -1) &&
1475
+ (meth->maxRestrictions != RESTRICTIONS_UNBOUNDED))
1476
+ return LOWER_PRECEDENCE;
1477
+ if ((i == meth->restrictionCount-1) && (max != -1) &&
1478
+ (meth->maxRestrictions == RESTRICTIONS_UNBOUNDED))
1479
+ return HIGHER_PRECEDENCE;
1480
+
1481
+ /* =============================================================
1482
+ The parameter with the most specific type list has precedence
1483
+ ============================================================= */
1484
+ r1 = (RESTRICTION *) params->argList;
1485
+ r2 = &meth->restrictions[i];
1486
+ rtn = TypeListCompare(r1,r2);
1487
+ if (rtn != IDENTICAL)
1488
+ return rtn;
1489
+
1490
+ /* =====================================================
1491
+ The parameter with a query restriction has precedence
1492
+ ===================================================== */
1493
+ if ((r1->query == NULL) && (r2->query != NULL))
1494
+ return LOWER_PRECEDENCE;
1495
+ if ((r1->query != NULL) && (r2->query == NULL))
1496
+ return HIGHER_PRECEDENCE;
1497
+
1498
+ /* ==========================================================
1499
+ Remember if the method restrictions differ at all - query
1500
+ expressions must be identical as well for the restrictions
1501
+ to be the same
1502
+ ========================================================== */
1503
+ if (IdenticalExpression(r1->query,r2->query) == false)
1504
+ diff = true;
1505
+ params = params->nextArg;
1506
+ }
1507
+
1508
+ /* =============================================================
1509
+ If the methods have the same number of parameters here, they
1510
+ are either the same restrictions, or they differ only in
1511
+ the query restrictions
1512
+ ============================================================= */
1513
+ if (rcnt == meth->restrictionCount)
1514
+ return(diff ? LOWER_PRECEDENCE : IDENTICAL);
1515
+
1516
+ /* =============================================
1517
+ The method with the greater number of regular
1518
+ parameters has precedence
1519
+
1520
+ If they require the smae # of reg params,
1521
+ then one without a wildcard has precedence
1522
+ ============================================= */
1523
+ if (min > meth->minRestrictions)
1524
+ return HIGHER_PRECEDENCE;
1525
+ if (meth->minRestrictions < min)
1526
+ return LOWER_PRECEDENCE;
1527
+ return((max == - 1) ? LOWER_PRECEDENCE : HIGHER_PRECEDENCE);
1528
+ }
1529
+
1530
+ /*****************************************************
1531
+ NAME : TypeListCompare
1532
+ DESCRIPTION : Determines the precedence between
1533
+ the class lists on two restrictions
1534
+ INPUTS : 1) Restriction address #1
1535
+ 2) Restriction address #2
1536
+ RETURNS : -1 : r1 precedes r2
1537
+ 0 : Identical classes
1538
+ 1 : r2 precedes r1
1539
+ SIDE EFFECTS : None
1540
+ NOTES : None
1541
+ *****************************************************/
1542
+ static int TypeListCompare(
1543
+ RESTRICTION *r1,
1544
+ RESTRICTION *r2)
1545
+ {
1546
+ long i;
1547
+ bool diff = false;
1548
+
1549
+ if ((r1->tcnt == 0) && (r2->tcnt == 0))
1550
+ return(IDENTICAL);
1551
+ if (r1->tcnt == 0)
1552
+ return(LOWER_PRECEDENCE);
1553
+ if (r2->tcnt == 0)
1554
+ return(HIGHER_PRECEDENCE);
1555
+ for (i = 0 ; (i < r1->tcnt) && (i < r2->tcnt) ; i++)
1556
+ {
1557
+ if (r1->types[i] != r2->types[i])
1558
+ {
1559
+ diff = true;
1560
+ #if OBJECT_SYSTEM
1561
+ if (HasSuperclass((Defclass *) r1->types[i],(Defclass *) r2->types[i]))
1562
+ return(HIGHER_PRECEDENCE);
1563
+ if (HasSuperclass((Defclass *) r2->types[i],(Defclass *) r1->types[i]))
1564
+ return(LOWER_PRECEDENCE);
1565
+ #else
1566
+ if (SubsumeType(((CLIPSInteger *) r1->types[i])->contents,((CLIPSInteger *) r2->types[i])->contents))
1567
+ return(HIGHER_PRECEDENCE);
1568
+ if (SubsumeType(((CLIPSInteger *) r2->types[i])->contents,((CLIPSInteger *) r1->types[i])->contents))
1569
+ return(LOWER_PRECEDENCE);
1570
+ #endif
1571
+ }
1572
+ }
1573
+ if (r1->tcnt < r2->tcnt)
1574
+ return(HIGHER_PRECEDENCE);
1575
+ if (r1->tcnt > r2->tcnt)
1576
+ return(LOWER_PRECEDENCE);
1577
+ if (diff)
1578
+ return(LOWER_PRECEDENCE);
1579
+ return(IDENTICAL);
1580
+ }
1581
+
1582
+ /***************************************************
1583
+ NAME : NewGeneric
1584
+ DESCRIPTION : Allocates and initializes a new
1585
+ generic function header
1586
+ INPUTS : The name of the new generic
1587
+ RETURNS : The address of the new generic
1588
+ SIDE EFFECTS : Generic function header created
1589
+ NOTES : None
1590
+ ***************************************************/
1591
+ static Defgeneric *NewGeneric(
1592
+ Environment *theEnv,
1593
+ CLIPSLexeme *gname)
1594
+ {
1595
+ Defgeneric *ngen;
1596
+
1597
+ ngen = get_struct(theEnv,defgeneric);
1598
+ InitializeConstructHeader(theEnv,"defgeneric",DEFGENERIC,&ngen->header,gname);
1599
+ ngen->busy = 0;
1600
+ ngen->new_index = 1;
1601
+ ngen->methods = NULL;
1602
+ ngen->mcnt = 0;
1603
+ #if DEBUGGING_FUNCTIONS
1604
+ ngen->trace = DefgenericData(theEnv)->WatchGenerics;
1605
+ #endif
1606
+ return(ngen);
1607
+ }
1608
+
1609
+ #endif /* DEFGENERIC_CONSTRUCT && (! BLOAD_ONLY) && (! RUN_TIME) */
1610
+
1611
+ /***************************************************
1612
+ NAME :
1613
+ DESCRIPTION :
1614
+ INPUTS :
1615
+ RETURNS :
1616
+ SIDE EFFECTS :
1617
+ NOTES :
1618
+ ***************************************************/