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,957 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.41 05/28/21 */
5
+ /* */
6
+ /* CLASS PARSER MODULE */
7
+ /*******************************************************/
8
+
9
+ /**************************************************************/
10
+ /* Purpose: Parsing Routines for Defclass Construct */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Brian L. Dantes */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* */
17
+ /* Revision History: */
18
+ /* */
19
+ /* 6.24: Added allowed-classes slot facet. */
20
+ /* */
21
+ /* Converted INSTANCE_PATTERN_MATCHING to */
22
+ /* DEFRULE_CONSTRUCT. */
23
+ /* */
24
+ /* Renamed BOOLEAN macro type to intBool. */
25
+ /* */
26
+ /* 6.30: Added support to allow CreateClassScopeMap to */
27
+ /* be used by other functions. */
28
+ /* */
29
+ /* Changed integer type/precision. */
30
+ /* */
31
+ /* GetConstructNameAndComment API change. */
32
+ /* */
33
+ /* Added const qualifiers to remove C++ */
34
+ /* deprecation warnings. */
35
+ /* */
36
+ /* Converted API macros to function calls. */
37
+ /* */
38
+ /* Changed find construct functionality so that */
39
+ /* imported modules are search when locating a */
40
+ /* named construct. */
41
+ /* */
42
+ /* 6.40: Pragma once and other inclusion changes. */
43
+ /* */
44
+ /* Added support for booleans with <stdbool.h>. */
45
+ /* */
46
+ /* Removed use of void pointers for specific */
47
+ /* data structures. */
48
+ /* */
49
+ /* Eval support for run time and bload only. */
50
+ /* */
51
+ /* Removed use of single-slot in class */
52
+ /* definitions. */
53
+ /* */
54
+ /* 6.41: Disallowed creation of instances when their */
55
+ /* class is being redefined. */
56
+ /* */
57
+ /**************************************************************/
58
+
59
+ /* =========================================
60
+ *****************************************
61
+ EXTERNAL DEFINITIONS
62
+ =========================================
63
+ ***************************************** */
64
+ #include "setup.h"
65
+
66
+ #if BLOAD || BLOAD_AND_BSAVE
67
+ #include "bload.h"
68
+ #endif
69
+
70
+ #include "classcom.h"
71
+ #include "classfun.h"
72
+ #include "clsltpsr.h"
73
+ #include "cstrcpsr.h"
74
+ #include "envrnmnt.h"
75
+ #include "inherpsr.h"
76
+ #include "memalloc.h"
77
+ #include "modulpsr.h"
78
+ #include "modulutl.h"
79
+ #include "msgpsr.h"
80
+ #include "pprint.h"
81
+ #include "prntutil.h"
82
+ #include "router.h"
83
+ #include "scanner.h"
84
+
85
+ #include "classpsr.h"
86
+
87
+ /* =========================================
88
+ *****************************************
89
+ CONSTANTS
90
+ =========================================
91
+ ***************************************** */
92
+ #define ROLE_RLN "role"
93
+ #define ABSTRACT_RLN "abstract"
94
+ #define CONCRETE_RLN "concrete"
95
+
96
+ #define HANDLER_DECL "message-handler"
97
+
98
+ #define SLOT_RLN "slot"
99
+ #define MLT_SLOT_RLN "multislot"
100
+
101
+ #define DIRECT 0
102
+ #define INHERIT 1
103
+
104
+ #if OBJECT_SYSTEM && (! BLOAD_ONLY) && (! RUN_TIME)
105
+
106
+ /***************************************/
107
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
108
+ /***************************************/
109
+
110
+ static bool ValidClassName(Environment *,const char *,Defclass **);
111
+ static bool ParseSimpleQualifier(Environment *,const char *,const char *,const char *,const char *,bool *,bool *);
112
+ static bool ReadUntilClosingParen(Environment *,const char *,struct token *);
113
+ static void AddClass(Environment *,Defclass *);
114
+ static void BuildSubclassLinks(Environment *,Defclass *);
115
+ static void FormInstanceTemplate(Environment *,Defclass *);
116
+ static void FormSlotNameMap(Environment *,Defclass *);
117
+ static TEMP_SLOT_LINK *MergeSlots(Environment *,TEMP_SLOT_LINK *,Defclass *,unsigned short *,unsigned short);
118
+ static void PackSlots(Environment *,Defclass *,TEMP_SLOT_LINK *);
119
+ static void CreatePublicSlotMessageHandlers(Environment *,Defclass *);
120
+
121
+
122
+ /* =========================================
123
+ *****************************************
124
+ EXTERNALLY VISIBLE FUNCTIONS
125
+ =========================================
126
+ ***************************************** */
127
+
128
+ /***************************************************************************************
129
+ NAME : ParseDefclass
130
+ DESCRIPTION : (defclass ...) is a construct (as
131
+ opposed to a function), thus no variables
132
+ may be used. This means classes may only
133
+ be STATICALLY defined (like rules).
134
+ INPUTS : The logical name of the router
135
+ for the parser input
136
+ RETURNS : False if successful parse, true otherwise
137
+ SIDE EFFECTS : Inserts valid class definition into
138
+ Class Table.
139
+ NOTES : H/L Syntax :
140
+ (defclass <name> [<comment>]
141
+ (is-a <superclass-name>+)
142
+ <class-descriptor>*)
143
+
144
+ <class-descriptor> :== (slot <name> <slot-descriptor>*) |
145
+ (role abstract|concrete) |
146
+ (pattern-match reactive|non-reactive)
147
+
148
+ These are for documentation only:
149
+ (message-handler <name> [<type>])
150
+
151
+ <slot-descriptor> :== (default <default-expression>) |
152
+ (default-dynamic <default-expression>) |
153
+ (storage shared|local) |
154
+ (access read-only|read-write|initialize-only) |
155
+ (propagation no-inherit|inherit) |
156
+ (source composite|exclusive)
157
+ (pattern-match reactive|non-reactive)
158
+ (visibility public|private)
159
+ (override-message <message-name>)
160
+ (type ...) |
161
+ (cardinality ...) |
162
+ (allowed-symbols ...) |
163
+ (allowed-strings ...) |
164
+ (allowed-numbers ...) |
165
+ (allowed-integers ...) |
166
+ (allowed-floats ...) |
167
+ (allowed-values ...) |
168
+ (allowed-instance-names ...) |
169
+ (allowed-classes ...) |
170
+ (range ...)
171
+
172
+ <default-expression> ::= ?NONE | ?VARIABLE | <expression>*
173
+ ***************************************************************************************/
174
+ bool ParseDefclass(
175
+ Environment *theEnv,
176
+ const char *readSource)
177
+ {
178
+ CLIPSLexeme *cname;
179
+ Defclass *cls;
180
+ PACKED_CLASS_LINKS *sclasses,*preclist;
181
+ TEMP_SLOT_LINK *slots = NULL;
182
+ bool parseError;
183
+ bool roleSpecified = false, abstract = false;
184
+ #if DEFRULE_CONSTRUCT
185
+ bool patternMatchSpecified = false;
186
+ bool reactive = true;
187
+ #endif
188
+
189
+ SetPPBufferStatus(theEnv,true);
190
+ FlushPPBuffer(theEnv);
191
+ SetIndentDepth(theEnv,3);
192
+ SavePPBuffer(theEnv,"(defclass ");
193
+
194
+ #if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE
195
+ if ((Bloaded(theEnv)) && (! ConstructData(theEnv)->CheckSyntaxMode))
196
+ {
197
+ CannotLoadWithBloadMessage(theEnv,"defclass");
198
+ return true;
199
+ }
200
+ #endif
201
+
202
+ cname = GetConstructNameAndComment(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken,"defclass",
203
+ (FindConstructFunction *) FindDefclassInModule,NULL,"#",true,
204
+ true,true,false);
205
+ if (cname == NULL)
206
+ return true;
207
+
208
+ if (ValidClassName(theEnv,cname->contents,&cls) == false)
209
+ return true;
210
+
211
+ sclasses = ParseSuperclasses(theEnv,readSource,cname);
212
+ if (sclasses == NULL)
213
+ return true;
214
+ preclist = FindPrecedenceList(theEnv,cls,sclasses);
215
+ if (preclist == NULL)
216
+ {
217
+ DeletePackedClassLinks(theEnv,sclasses,true);
218
+ return true;
219
+ }
220
+
221
+ DefclassData(theEnv)->RedefiningClass = cls;
222
+ parseError = false;
223
+ GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
224
+ while (DefclassData(theEnv)->ObjectParseToken.tknType != RIGHT_PARENTHESIS_TOKEN)
225
+ {
226
+ if (DefclassData(theEnv)->ObjectParseToken.tknType != LEFT_PARENTHESIS_TOKEN)
227
+ {
228
+ SyntaxErrorMessage(theEnv,"defclass");
229
+ parseError = true;
230
+ break;
231
+ }
232
+ PPBackup(theEnv);
233
+ PPCRAndIndent(theEnv);
234
+ SavePPBuffer(theEnv,"(");
235
+ GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
236
+ if (DefclassData(theEnv)->ObjectParseToken.tknType != SYMBOL_TOKEN)
237
+ {
238
+ SyntaxErrorMessage(theEnv,"defclass");
239
+ parseError = true;
240
+ break;
241
+ }
242
+ if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,ROLE_RLN) == 0)
243
+ {
244
+ if (ParseSimpleQualifier(theEnv,readSource,ROLE_RLN,CONCRETE_RLN,ABSTRACT_RLN,
245
+ &roleSpecified,&abstract) == false)
246
+ {
247
+ parseError = true;
248
+ break;
249
+ }
250
+ }
251
+ #if DEFRULE_CONSTRUCT
252
+ else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,MATCH_RLN) == 0)
253
+ {
254
+ if (ParseSimpleQualifier(theEnv,readSource,MATCH_RLN,NONREACTIVE_RLN,REACTIVE_RLN,
255
+ &patternMatchSpecified,&reactive) == false)
256
+ {
257
+ parseError = true;
258
+ break;
259
+ }
260
+ }
261
+ #endif
262
+ else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,SLOT_RLN) == 0)
263
+ {
264
+ slots = ParseSlot(theEnv,readSource,cname->contents,slots,preclist,false);
265
+ if (slots == NULL)
266
+ {
267
+ parseError = true;
268
+ break;
269
+ }
270
+ }
271
+ else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,MLT_SLOT_RLN) == 0)
272
+ {
273
+ slots = ParseSlot(theEnv,readSource,cname->contents,slots,preclist,true);
274
+ if (slots == NULL)
275
+ {
276
+ parseError = true;
277
+ break;
278
+ }
279
+ }
280
+ else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,HANDLER_DECL) == 0)
281
+ {
282
+ if (ReadUntilClosingParen(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken) == false)
283
+ {
284
+ parseError = true;
285
+ break;
286
+ }
287
+ }
288
+ else
289
+ {
290
+ SyntaxErrorMessage(theEnv,"defclass");
291
+ parseError = true;
292
+ break;
293
+ }
294
+ GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
295
+ }
296
+
297
+ DefclassData(theEnv)->RedefiningClass = NULL;
298
+
299
+ if ((DefclassData(theEnv)->ObjectParseToken.tknType != RIGHT_PARENTHESIS_TOKEN) ||
300
+ (parseError == true))
301
+ {
302
+ DeletePackedClassLinks(theEnv,sclasses,true);
303
+ DeletePackedClassLinks(theEnv,preclist,true);
304
+ DeleteSlots(theEnv,slots);
305
+ return true;
306
+ }
307
+ SavePPBuffer(theEnv,"\n");
308
+
309
+ /* =========================================================================
310
+ The abstract/reactive qualities of a class are inherited if not specified
311
+ ========================================================================= */
312
+ if (roleSpecified == false)
313
+ {
314
+ if (preclist->classArray[1]->system && /* Change to cause */
315
+ (DefclassData(theEnv)->ClassDefaultsModeValue == CONVENIENCE_MODE)) /* default role of */
316
+ { abstract = false; } /* classes to be concrete. */
317
+ else
318
+ { abstract = preclist->classArray[1]->abstract; }
319
+ }
320
+ #if DEFRULE_CONSTRUCT
321
+ if (patternMatchSpecified == false)
322
+ {
323
+ if ((preclist->classArray[1]->system) && /* Change to cause */
324
+ (! abstract) && /* default pattern-match */
325
+ (DefclassData(theEnv)->ClassDefaultsModeValue == CONVENIENCE_MODE)) /* of classes to be */
326
+ { reactive = true; } /* reactive. */
327
+ else
328
+ { reactive = preclist->classArray[1]->reactive; }
329
+ }
330
+
331
+ /* ================================================================
332
+ An abstract class cannot have direct instances, thus it makes no
333
+ sense for it to be reactive since it will have no objects to
334
+ respond to pattern-matching
335
+ ================================================================ */
336
+ if (abstract && reactive)
337
+ {
338
+ PrintErrorID(theEnv,"CLASSPSR",1,false);
339
+ WriteString(theEnv,STDERR,"An abstract class cannot be reactive.\n");
340
+ DeletePackedClassLinks(theEnv,sclasses,true);
341
+ DeletePackedClassLinks(theEnv,preclist,true);
342
+ DeleteSlots(theEnv,slots);
343
+ return true;
344
+ }
345
+
346
+ #endif
347
+
348
+ /* =======================================================
349
+ If we're only checking syntax, don't add the
350
+ successfully parsed defclass to the KB.
351
+ ======================================================= */
352
+
353
+ if (ConstructData(theEnv)->CheckSyntaxMode)
354
+ {
355
+ DeletePackedClassLinks(theEnv,sclasses,true);
356
+ DeletePackedClassLinks(theEnv,preclist,true);
357
+ DeleteSlots(theEnv,slots);
358
+ return false;
359
+ }
360
+
361
+ cls = NewClass(theEnv,cname);
362
+ cls->abstract = abstract;
363
+ #if DEFRULE_CONSTRUCT
364
+ cls->reactive = reactive;
365
+ #endif
366
+ cls->directSuperclasses.classCount = sclasses->classCount;
367
+ cls->directSuperclasses.classArray = sclasses->classArray;
368
+
369
+ /* =======================================================
370
+ This is a hack to let functions which need to iterate
371
+ over a class AND its superclasses to conveniently do so
372
+
373
+ The real precedence list starts in position 1
374
+ ======================================================= */
375
+ preclist->classArray[0] = cls;
376
+ cls->allSuperclasses.classCount = preclist->classCount;
377
+ cls->allSuperclasses.classArray = preclist->classArray;
378
+ rtn_struct(theEnv,packedClassLinks,sclasses);
379
+ rtn_struct(theEnv,packedClassLinks,preclist);
380
+
381
+ /* =================================
382
+ Shove slots into contiguous array
383
+ ================================= */
384
+ if (slots != NULL)
385
+ PackSlots(theEnv,cls,slots);
386
+ AddClass(theEnv,cls);
387
+
388
+ return false;
389
+ }
390
+
391
+ /* =========================================
392
+ *****************************************
393
+ INTERNALLY VISIBLE FUNCTIONS
394
+ =========================================
395
+ ***************************************** */
396
+
397
+ /***********************************************************
398
+ NAME : ValidClassName
399
+ DESCRIPTION : Determines if a new class of the given
400
+ name can be defined in the current module
401
+ INPUTS : 1) The new class name
402
+ 2) Buffer to hold class address
403
+ RETURNS : True if OK, false otherwise
404
+ SIDE EFFECTS : Error message printed if not OK
405
+ NOTES : GetConstructNameAndComment() (called before
406
+ this function) ensures that the defclass
407
+ name does not conflict with one from
408
+ another module
409
+ ***********************************************************/
410
+ static bool ValidClassName(
411
+ Environment *theEnv,
412
+ const char *theClassName,
413
+ Defclass **theDefclass)
414
+ {
415
+ *theDefclass = FindDefclassInModule(theEnv,theClassName);
416
+ if (*theDefclass != NULL)
417
+ {
418
+ /* ===================================
419
+ System classes (which are visible
420
+ in all modules) cannot be redefined
421
+ =================================== */
422
+ if ((*theDefclass)->system)
423
+ {
424
+ PrintErrorID(theEnv,"CLASSPSR",2,false);
425
+ WriteString(theEnv,STDERR,"Cannot redefine a predefined system class.\n");
426
+ return false;
427
+ }
428
+
429
+ /* ===============================================
430
+ A class in the current module can only be
431
+ redefined if it is not in use, e.g., instances,
432
+ generic function method restrictions, etc.
433
+ =============================================== */
434
+ if ((DefclassIsDeletable(*theDefclass) == false) &&
435
+ (! ConstructData(theEnv)->CheckSyntaxMode))
436
+ {
437
+ PrintErrorID(theEnv,"CLASSPSR",3,false);
438
+ WriteString(theEnv,STDERR,"Class '");
439
+ WriteString(theEnv,STDERR,DefclassName(*theDefclass));
440
+ WriteString(theEnv,STDERR,"' cannot be redefined while ");
441
+ WriteString(theEnv,STDERR,"outstanding references to it still exist.\n");
442
+ return false;
443
+ }
444
+ }
445
+ return true;
446
+ }
447
+
448
+ /***************************************************************
449
+ NAME : ParseSimpleQualifier
450
+ DESCRIPTION : Parses abstract/concrete role and
451
+ pattern-matching reactivity for class
452
+ INPUTS : 1) The input logical name
453
+ 2) The name of the qualifier being parsed
454
+ 3) The qualifier value indicating that the
455
+ qualifier should be false
456
+ 4) The qualifier value indicating that the
457
+ qualifier should be true
458
+ 5) A pointer to a bitmap indicating
459
+ if the qualifier has already been parsed
460
+ 6) A buffer to store the value of the qualifier
461
+ RETURNS : True if all OK, false otherwise
462
+ SIDE EFFECTS : Bitmap and qualifier buffers set
463
+ Messages printed on errors
464
+ NOTES : None
465
+ ***************************************************************/
466
+ static bool ParseSimpleQualifier(
467
+ Environment *theEnv,
468
+ const char *readSource,
469
+ const char *classQualifier,
470
+ const char *clearRelation,
471
+ const char *setRelation,
472
+ bool *alreadyTestedFlag,
473
+ bool *binaryFlag)
474
+ {
475
+ if (*alreadyTestedFlag)
476
+ {
477
+ PrintErrorID(theEnv,"CLASSPSR",4,false);
478
+ WriteString(theEnv,STDERR,"The '");
479
+ WriteString(theEnv,STDERR,classQualifier);
480
+ WriteString(theEnv,STDERR,"' class attribute is already specified.\n");
481
+ return false;
482
+ }
483
+ SavePPBuffer(theEnv," ");
484
+ GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
485
+ if (DefclassData(theEnv)->ObjectParseToken.tknType != SYMBOL_TOKEN)
486
+ goto ParseSimpleQualifierError;
487
+ if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,setRelation) == 0)
488
+ *binaryFlag = true;
489
+ else if (strcmp(DefclassData(theEnv)->ObjectParseToken.lexemeValue->contents,clearRelation) == 0)
490
+ *binaryFlag = false;
491
+ else
492
+ goto ParseSimpleQualifierError;
493
+ GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
494
+ if (DefclassData(theEnv)->ObjectParseToken.tknType != RIGHT_PARENTHESIS_TOKEN)
495
+ goto ParseSimpleQualifierError;
496
+ *alreadyTestedFlag = true;
497
+ return true;
498
+
499
+ ParseSimpleQualifierError:
500
+ SyntaxErrorMessage(theEnv,"defclass");
501
+ return false;
502
+ }
503
+
504
+ /***************************************************
505
+ NAME : ReadUntilClosingParen
506
+ DESCRIPTION : Skips over tokens until a ')' is
507
+ encountered.
508
+ INPUTS : 1) The logical input source
509
+ 2) A buffer for scanned tokens
510
+ RETURNS : True if ')' read, otherwise false
511
+ otherwise
512
+ SIDE EFFECTS : Tokens read
513
+ NOTES : Expects first token after opening
514
+ paren has already been scanned
515
+ ***************************************************/
516
+ static bool ReadUntilClosingParen(
517
+ Environment *theEnv,
518
+ const char *readSource,
519
+ struct token *inputToken)
520
+ {
521
+ int cnt = 1;
522
+ bool lparen_read = false;
523
+
524
+ do
525
+ {
526
+ if (lparen_read == false)
527
+ SavePPBuffer(theEnv," ");
528
+ GetToken(theEnv,readSource,inputToken);
529
+ if (inputToken->tknType == STOP_TOKEN)
530
+ {
531
+ SyntaxErrorMessage(theEnv,"message-handler declaration");
532
+ return false;
533
+ }
534
+ else if (inputToken->tknType == LEFT_PARENTHESIS_TOKEN)
535
+ {
536
+ lparen_read = true;
537
+ cnt++;
538
+ }
539
+ else if (inputToken->tknType == RIGHT_PARENTHESIS_TOKEN)
540
+ {
541
+ cnt--;
542
+ if (lparen_read == false)
543
+ {
544
+ PPBackup(theEnv);
545
+ PPBackup(theEnv);
546
+ SavePPBuffer(theEnv,")");
547
+ }
548
+ lparen_read = false;
549
+ }
550
+ else
551
+ lparen_read = false;
552
+ }
553
+ while (cnt > 0);
554
+
555
+ return true;
556
+ }
557
+
558
+ /*****************************************************************************
559
+ NAME : AddClass
560
+ DESCRIPTION : Determines the precedence list of the new class.
561
+ If it is valid, the routine checks to see if the class
562
+ already exists. If it does not, all the subclass
563
+ links are made from the class's direct superclasses,
564
+ and the class is inserted in the hash table. If it
565
+ does, all sublclasses are deleted. An error will occur
566
+ if any instances of the class (direct or indirect) exist.
567
+ If all checks out, the old definition is replaced by the new.
568
+ INPUTS : The new class description
569
+ RETURNS : Nothing useful
570
+ SIDE EFFECTS : The class is deleted if there is an error.
571
+ NOTES : No change in the class graph state will occur
572
+ if there were any errors.
573
+ Assumes class is not busy!!!
574
+ *****************************************************************************/
575
+ static void AddClass(
576
+ Environment *theEnv,
577
+ Defclass *cls)
578
+ {
579
+ Defclass *ctmp;
580
+ #if DEBUGGING_FUNCTIONS
581
+ bool oldTraceInstances = false,
582
+ oldTraceSlots = false;
583
+ #endif
584
+
585
+ /* ===============================================
586
+ If class does not already exist, insert and
587
+ form progeny links with all direct superclasses
588
+ =============================================== */
589
+ cls->hashTableIndex = HashClass(GetDefclassNamePointer(cls));
590
+ ctmp = FindDefclassInModule(theEnv,DefclassName(cls));
591
+
592
+ if (ctmp != NULL)
593
+ {
594
+ #if DEBUGGING_FUNCTIONS
595
+ oldTraceInstances = ctmp->traceInstances;
596
+ oldTraceSlots = ctmp->traceSlots;
597
+ #endif
598
+ DeleteClassUAG(theEnv,ctmp);
599
+ }
600
+ PutClassInTable(theEnv,cls);
601
+
602
+ BuildSubclassLinks(theEnv,cls);
603
+ InstallClass(theEnv,cls,true);
604
+ AddConstructToModule(&cls->header);
605
+
606
+ FormInstanceTemplate(theEnv,cls);
607
+ FormSlotNameMap(theEnv,cls);
608
+
609
+ AssignClassID(theEnv,cls);
610
+
611
+ #if DEBUGGING_FUNCTIONS
612
+ if (cls->abstract)
613
+ {
614
+ cls->traceInstances = false;
615
+ cls->traceSlots = false;
616
+ }
617
+ else
618
+ {
619
+ if (oldTraceInstances)
620
+ cls->traceInstances = true;
621
+ if (oldTraceSlots)
622
+ cls->traceSlots = true;
623
+ }
624
+ #endif
625
+
626
+ #if DEBUGGING_FUNCTIONS
627
+ if (GetConserveMemory(theEnv) == false)
628
+ SetDefclassPPForm(theEnv,cls,CopyPPBuffer(theEnv));
629
+ #endif
630
+
631
+ #if DEFMODULE_CONSTRUCT
632
+
633
+ /* =========================================
634
+ Create a bitmap indicating whether this
635
+ class is in scope or not for every module
636
+ ========================================= */
637
+ cls->scopeMap = (CLIPSBitMap *) CreateClassScopeMap(theEnv,cls);
638
+
639
+ #endif
640
+
641
+ /* ==============================================
642
+ Define get- and put- handlers for public slots
643
+ ============================================== */
644
+ CreatePublicSlotMessageHandlers(theEnv,cls);
645
+ }
646
+
647
+ /*******************************************************
648
+ NAME : BuildSubclassLinks
649
+ DESCRIPTION : Follows the list of superclasses
650
+ for a class and puts the class in
651
+ each of the superclasses' subclass
652
+ list.
653
+ INPUTS : The address of the class
654
+ RETURNS : Nothing useful
655
+ SIDE EFFECTS : The subclass lists for every superclass
656
+ are modified.
657
+ NOTES : Assumes the superclass list is formed.
658
+ *******************************************************/
659
+ static void BuildSubclassLinks(
660
+ Environment *theEnv,
661
+ Defclass *cls)
662
+ {
663
+ unsigned long i;
664
+
665
+ for (i = 0 ; i < cls->directSuperclasses.classCount ; i++)
666
+ AddClassLink(theEnv,&cls->directSuperclasses.classArray[i]->directSubclasses,cls,true,0);
667
+ }
668
+
669
+ /**********************************************************
670
+ NAME : FormInstanceTemplate
671
+ DESCRIPTION : Forms a contiguous array of instance
672
+ slots for use in creating instances later
673
+ Also used in determining instance slot
674
+ indices a priori during handler defns
675
+ INPUTS : The class
676
+ RETURNS : Nothing useful
677
+ SIDE EFFECTS : Contiguous array of instance slots formed
678
+ NOTES : None
679
+ **********************************************************/
680
+ static void FormInstanceTemplate(
681
+ Environment *theEnv,
682
+ Defclass *cls)
683
+ {
684
+ TEMP_SLOT_LINK *islots = NULL,*stmp;
685
+ unsigned short scnt = 0;
686
+ unsigned long i;
687
+
688
+ /* ========================
689
+ Get direct class's slots
690
+ ======================== */
691
+ islots = MergeSlots(theEnv,islots,cls,&scnt,DIRECT);
692
+
693
+ /* ===================================================================
694
+ Get all inherited slots - a more specific slot takes precedence
695
+ over more general, i.e. the first class in the precedence list with
696
+ a particular slot gets to specify its default value
697
+ =================================================================== */
698
+ for (i = 1 ; i < cls->allSuperclasses.classCount ; i++)
699
+ islots = MergeSlots(theEnv,islots,cls->allSuperclasses.classArray[i],&scnt,INHERIT);
700
+
701
+ /* ===================================================
702
+ Allocate a contiguous array to store all the slots.
703
+ =================================================== */
704
+ cls->instanceSlotCount = scnt;
705
+ cls->localInstanceSlotCount = 0;
706
+ if (scnt > 0)
707
+ cls->instanceTemplate = (SlotDescriptor **) gm2(theEnv,(scnt * sizeof(SlotDescriptor *)));
708
+ for (i = 0 ; i < scnt ; i++)
709
+ {
710
+ stmp = islots;
711
+ islots = islots->nxt;
712
+ cls->instanceTemplate[i] = stmp->desc;
713
+ if (stmp->desc->shared == 0)
714
+ cls->localInstanceSlotCount++;
715
+ rtn_struct(theEnv,tempSlotLink,stmp);
716
+ }
717
+ }
718
+
719
+ /**********************************************************
720
+ NAME : FormSlotNameMap
721
+ DESCRIPTION : Forms a mapping of the slot name ids into
722
+ the instance template. Given the slot
723
+ name id, this map provides a much faster
724
+ lookup of a slot. The id is stored
725
+ statically in object patterns and can
726
+ be looked up via a hash table at runtime
727
+ as well.
728
+ INPUTS : The class
729
+ RETURNS : Nothing useful
730
+ SIDE EFFECTS : Contiguous array of integers formed
731
+ The position in the array corresponding
732
+ to a slot name id holds an the index
733
+ into the instance template array holding
734
+ the slot
735
+ The max slot name id for the class is
736
+ also stored to make deletion of the slots
737
+ easier
738
+ NOTES : Assumes the instance template has already
739
+ been formed
740
+ **********************************************************/
741
+ static void FormSlotNameMap(
742
+ Environment *theEnv,
743
+ Defclass *cls)
744
+ {
745
+ unsigned i;
746
+
747
+ cls->maxSlotNameID = 0;
748
+ cls->slotNameMap = NULL;
749
+ if (cls->instanceSlotCount == 0)
750
+ return;
751
+ for (i = 0 ; i < cls->instanceSlotCount ; i++)
752
+ if (cls->instanceTemplate[i]->slotName->id > cls->maxSlotNameID)
753
+ cls->maxSlotNameID = cls->instanceTemplate[i]->slotName->id;
754
+ cls->slotNameMap = (unsigned *) gm2(theEnv,(sizeof(unsigned) * (cls->maxSlotNameID + 1)));
755
+ for (i = 0 ; i <= cls->maxSlotNameID ; i++)
756
+ cls->slotNameMap[i] = 0;
757
+ for (i = 0 ; i < cls->instanceSlotCount ; i++)
758
+ cls->slotNameMap[cls->instanceTemplate[i]->slotName->id] = i + 1;
759
+ }
760
+
761
+ /********************************************************************
762
+ NAME : MergeSlots
763
+ DESCRIPTION : Adds non-duplicate slots to list and increments
764
+ slot count for the class instance template
765
+ INPUTS : 1) The old slot list
766
+ 2) The address of class containing new slots
767
+ 3) Caller's buffer for # of slots
768
+ 4) A flag indicating whether the new list of slots
769
+ is from the direct parent-class or not.
770
+ RETURNS : The address of the new expanded list, or NULL
771
+ for an empty list
772
+ SIDE EFFECTS : The list is expanded
773
+ Caller's slot count is adjusted.
774
+ NOTES : Lists are assumed to contain no duplicates
775
+ *******************************************************************/
776
+ static TEMP_SLOT_LINK *MergeSlots(
777
+ Environment *theEnv,
778
+ TEMP_SLOT_LINK *old,
779
+ Defclass *cls,
780
+ unsigned short *scnt,
781
+ unsigned short src)
782
+ {
783
+ TEMP_SLOT_LINK *cur,*tmp;
784
+ unsigned int i;
785
+ SlotDescriptor *newSlot;
786
+
787
+ /*=========================================*/
788
+ /* Process the slots in reverse order */
789
+ /* since we are pushing them onto a stack. */
790
+ /*=========================================*/
791
+
792
+ for (i = cls->slotCount; i > 0 ; i--)
793
+ {
794
+ newSlot = &cls->slots[i-1];
795
+
796
+ /*=============================================*/
797
+ /* A class can prevent it slots from being */
798
+ /* propagated to all but its direct instances. */
799
+ /*=============================================*/
800
+
801
+ if ((newSlot->noInherit == 0) ? true : (src == DIRECT))
802
+ {
803
+ cur = old;
804
+ while ((cur != NULL) ? (newSlot->slotName != cur->desc->slotName) : false)
805
+ cur = cur->nxt;
806
+ if (cur == NULL)
807
+ {
808
+ tmp = get_struct(theEnv,tempSlotLink);
809
+ tmp->desc = newSlot;
810
+ tmp->nxt = old;
811
+ old = tmp;
812
+ (*scnt)++;
813
+ }
814
+ }
815
+ }
816
+
817
+ return old;
818
+ }
819
+
820
+ /***********************************************************************
821
+ NAME : PackSlots
822
+ DESCRIPTION : Groups class-slots into a contiguous array
823
+ "slots" field points to array
824
+ "slotCount" field set
825
+ INPUTS : 1) The class
826
+ 2) The list of slots
827
+ RETURNS : Nothing useful
828
+ SIDE EFFECTS : Temporary list deallocated, contiguous array allocated,
829
+ and nxt pointers linked
830
+ Class pointer set for slots
831
+ NOTES : Assumes class->slotCount == 0 && class->slots == NULL
832
+ ***********************************************************************/
833
+ static void PackSlots(
834
+ Environment *theEnv,
835
+ Defclass *cls,
836
+ TEMP_SLOT_LINK *slots)
837
+ {
838
+ TEMP_SLOT_LINK *stmp,*sprv;
839
+ long i;
840
+
841
+ stmp = slots;
842
+ while (stmp != NULL)
843
+ {
844
+ stmp->desc->cls = cls;
845
+ cls->slotCount++;
846
+ stmp = stmp->nxt;
847
+ }
848
+ cls->slots = (SlotDescriptor *) gm2(theEnv,(sizeof(SlotDescriptor) * cls->slotCount));
849
+ stmp = slots;
850
+ for (i = 0 ; i < cls->slotCount ; i++)
851
+ {
852
+ sprv = stmp;
853
+ stmp = stmp->nxt;
854
+ GenCopyMemory(SlotDescriptor,1,&(cls->slots[i]),sprv->desc);
855
+ cls->slots[i].sharedValue.desc = &(cls->slots[i]);
856
+ cls->slots[i].sharedValue.value = NULL;
857
+ rtn_struct(theEnv,slotDescriptor,sprv->desc);
858
+ rtn_struct(theEnv,tempSlotLink,sprv);
859
+ }
860
+ }
861
+
862
+ /*****************************************************************************
863
+ NAME : CreatePublicSlotMessageHandlers
864
+ DESCRIPTION : Creates a get-<slot-name> and
865
+ put-<slot-name> handler for every
866
+ public slot in a class.
867
+
868
+ The syntax of the message-handlers
869
+ created are:
870
+
871
+ (defmessage-handler <class> get-<slot-name> primary ()
872
+ ?self:<slot-name>)
873
+
874
+ For single-field slots:
875
+
876
+ (defmessage-handler <class> put-<slot-name> primary (?value)
877
+ (bind ?self:<slot-name> ?value))
878
+
879
+ For multifield slots:
880
+
881
+ (defmessage-handler <class> put-<slot-name> primary ($?value)
882
+ (bind ?self:<slot-name> ?value))
883
+ INPUTS : The defclass
884
+ RETURNS : Nothing useful
885
+ SIDE EFFECTS : Message-handlers created
886
+ NOTES : None
887
+ ******************************************************************************/
888
+ static void CreatePublicSlotMessageHandlers(
889
+ Environment *theEnv,
890
+ Defclass *theDefclass)
891
+ {
892
+ long i;
893
+ SlotDescriptor *sd;
894
+
895
+ for (i = 0 ; i < theDefclass->slotCount ; i++)
896
+ {
897
+ sd = &theDefclass->slots[i];
898
+ CreateGetAndPutHandlers(theEnv,sd);
899
+ }
900
+ for (i = 0 ; i < theDefclass->handlerCount ; i++)
901
+ theDefclass->handlers[i].system = true;
902
+ }
903
+
904
+ #endif
905
+
906
+ #if DEFMODULE_CONSTRUCT && OBJECT_SYSTEM
907
+
908
+ /********************************************************
909
+ NAME : CreateClassScopeMap
910
+ DESCRIPTION : Creates a bitmap where each bit position
911
+ corresponds to a module id. If the bit
912
+ is set, the class is in scope for that
913
+ module, otherwise it is not.
914
+ INPUTS : The class
915
+ RETURNS : Nothing useful
916
+ SIDE EFFECTS : Scope bitmap created and attached
917
+ NOTES : Uses FindImportedConstruct()
918
+ ********************************************************/
919
+ void *CreateClassScopeMap(
920
+ Environment *theEnv,
921
+ Defclass *theDefclass)
922
+ {
923
+ unsigned short scopeMapSize;
924
+ char *scopeMap;
925
+ const char *className;
926
+ Defmodule *matchModule, *theModule;
927
+ unsigned long moduleID;
928
+ unsigned int count;
929
+ void *theBitMap;
930
+
931
+ className = theDefclass->header.name->contents;
932
+ matchModule = theDefclass->header.whichModule->theModule;
933
+
934
+ scopeMapSize = (sizeof(char) * ((GetNumberOfDefmodules(theEnv) / BITS_PER_BYTE) + 1));
935
+ scopeMap = (char *) gm2(theEnv,scopeMapSize);
936
+
937
+ ClearBitString(scopeMap,scopeMapSize);
938
+ SaveCurrentModule(theEnv);
939
+ for (theModule = GetNextDefmodule(theEnv,NULL) ;
940
+ theModule != NULL ;
941
+ theModule = GetNextDefmodule(theEnv,theModule))
942
+ {
943
+ SetCurrentModule(theEnv,theModule);
944
+ moduleID = theModule->header.bsaveID;
945
+ if (FindImportedConstruct(theEnv,"defclass",matchModule,
946
+ className,&count,true,NULL) != NULL)
947
+ SetBitMap(scopeMap,moduleID);
948
+ }
949
+ RestoreCurrentModule(theEnv);
950
+ theBitMap = (CLIPSBitMap *) AddBitMap(theEnv,scopeMap,scopeMapSize);
951
+ IncrementBitMapCount(theBitMap);
952
+ rm(theEnv,scopeMap,scopeMapSize);
953
+ return(theBitMap);
954
+ }
955
+
956
+ #endif
957
+