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,819 @@
1
+ /*******************************************************/
2
+ /* "C" Language Integrated Production System */
3
+ /* */
4
+ /* CLIPS Version 6.40 08/11/16 */
5
+ /* */
6
+ /* DEFTEMPLATE PARSER MODULE */
7
+ /*******************************************************/
8
+
9
+ /*************************************************************/
10
+ /* Purpose: Parses the deftemplate construct. */
11
+ /* */
12
+ /* Principal Programmer(s): */
13
+ /* Gary D. Riley */
14
+ /* */
15
+ /* Contributing Programmer(s): */
16
+ /* */
17
+ /* Revision History: */
18
+ /* */
19
+ /* 6.23: Added support for templates maintaining their */
20
+ /* own list of facts. */
21
+ /* */
22
+ /* 6.30: Removed conditional code for unsupported */
23
+ /* compilers/operating systems (IBM_MCW and */
24
+ /* MAC_MCW). */
25
+ /* */
26
+ /* GetConstructNameAndComment API change. */
27
+ /* */
28
+ /* Support for deftemplate slot facets. */
29
+ /* */
30
+ /* Added const qualifiers to remove C++ */
31
+ /* deprecation warnings. */
32
+ /* */
33
+ /* Changed find construct functionality so that */
34
+ /* imported modules are search when locating a */
35
+ /* named construct. */
36
+ /* */
37
+ /* 6.40: Pragma once and other inclusion changes. */
38
+ /* */
39
+ /* Added support for booleans with <stdbool.h>. */
40
+ /* */
41
+ /* Removed use of void pointers for specific */
42
+ /* data structures. */
43
+ /* */
44
+ /* Static constraint checking is always enabled. */
45
+ /* */
46
+ /*************************************************************/
47
+
48
+ #include "setup.h"
49
+
50
+ #if DEFTEMPLATE_CONSTRUCT
51
+
52
+ #include <stdio.h>
53
+ #include <string.h>
54
+
55
+ #if BLOAD || BLOAD_AND_BSAVE
56
+ #include "bload.h"
57
+ #endif
58
+ #include "constant.h"
59
+ #include "constrct.h"
60
+ #include "cstrcpsr.h"
61
+ #include "cstrnchk.h"
62
+ #include "cstrnpsr.h"
63
+ #include "cstrnutl.h"
64
+ #include "default.h"
65
+ #include "envrnmnt.h"
66
+ #include "exprnpsr.h"
67
+ #include "factmngr.h"
68
+ #include "memalloc.h"
69
+ #include "modulutl.h"
70
+ #include "pattern.h"
71
+ #include "pprint.h"
72
+ #include "prntutil.h"
73
+ #include "router.h"
74
+ #include "scanner.h"
75
+ #include "symbol.h"
76
+ #include "tmpltbsc.h"
77
+ #include "tmpltdef.h"
78
+ #include "watch.h"
79
+
80
+ #include "tmpltpsr.h"
81
+
82
+ /***************************************/
83
+ /* LOCAL INTERNAL FUNCTION DEFINITIONS */
84
+ /***************************************/
85
+
86
+ #if (! RUN_TIME) && (! BLOAD_ONLY)
87
+ static struct templateSlot *SlotDeclarations(Environment *,const char *,struct token *);
88
+ static struct templateSlot *ParseSlot(Environment *,const char *,struct token *,struct templateSlot *);
89
+ static struct templateSlot *DefinedSlots(Environment *,const char *,CLIPSLexeme *,bool,struct token *);
90
+ static bool ParseFacetAttribute(Environment *,const char *,struct templateSlot *,bool);
91
+ #endif
92
+
93
+ /*******************************************************/
94
+ /* ParseDeftemplate: Parses the deftemplate construct. */
95
+ /*******************************************************/
96
+ bool ParseDeftemplate(
97
+ Environment *theEnv,
98
+ const char *readSource)
99
+ {
100
+ #if (! RUN_TIME) && (! BLOAD_ONLY)
101
+ CLIPSLexeme *deftemplateName;
102
+ Deftemplate *newDeftemplate;
103
+ struct templateSlot *slots;
104
+ struct token inputToken;
105
+
106
+ /*================================================*/
107
+ /* Initialize pretty print and error information. */
108
+ /*================================================*/
109
+
110
+ DeftemplateData(theEnv)->DeftemplateError = false;
111
+ SetPPBufferStatus(theEnv,true);
112
+ FlushPPBuffer(theEnv);
113
+ SavePPBuffer(theEnv,"(deftemplate ");
114
+
115
+ /*==============================================================*/
116
+ /* Deftemplates can not be added when a binary image is loaded. */
117
+ /*==============================================================*/
118
+
119
+ #if BLOAD || BLOAD_AND_BSAVE
120
+ if ((Bloaded(theEnv) == true) && (! ConstructData(theEnv)->CheckSyntaxMode))
121
+ {
122
+ CannotLoadWithBloadMessage(theEnv,"deftemplate");
123
+ return true;
124
+ }
125
+ #endif
126
+
127
+ /*=======================================================*/
128
+ /* Parse the name and comment fields of the deftemplate. */
129
+ /*=======================================================*/
130
+
131
+ #if DEBUGGING_FUNCTIONS
132
+ DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0;
133
+ #endif
134
+
135
+ deftemplateName = GetConstructNameAndComment(theEnv,readSource,&inputToken,"deftemplate",
136
+ (FindConstructFunction *) FindDeftemplateInModule,
137
+ (DeleteConstructFunction *) Undeftemplate,"%",
138
+ true,true,true,false);
139
+
140
+ if (deftemplateName == NULL) return true;
141
+
142
+ if (ReservedPatternSymbol(theEnv,deftemplateName->contents,"deftemplate"))
143
+ {
144
+ ReservedPatternSymbolErrorMsg(theEnv,deftemplateName->contents,"a deftemplate name");
145
+ return true;
146
+ }
147
+
148
+ /*===========================================*/
149
+ /* Parse the slot fields of the deftemplate. */
150
+ /*===========================================*/
151
+
152
+ slots = SlotDeclarations(theEnv,readSource,&inputToken);
153
+ if (DeftemplateData(theEnv)->DeftemplateError == true) return true;
154
+
155
+ /*==============================================*/
156
+ /* If we're only checking syntax, don't add the */
157
+ /* successfully parsed deftemplate to the KB. */
158
+ /*==============================================*/
159
+
160
+ if (ConstructData(theEnv)->CheckSyntaxMode)
161
+ {
162
+ ReturnSlots(theEnv,slots);
163
+ return false;
164
+ }
165
+
166
+ /*=====================================*/
167
+ /* Create a new deftemplate structure. */
168
+ /*=====================================*/
169
+
170
+ newDeftemplate = get_struct(theEnv,deftemplate);
171
+ newDeftemplate->header.name = deftemplateName;
172
+ newDeftemplate->header.next = NULL;
173
+ newDeftemplate->header.usrData = NULL;
174
+ newDeftemplate->header.constructType = DEFTEMPLATE;
175
+ newDeftemplate->header.env = theEnv;
176
+ newDeftemplate->slotList = slots;
177
+ newDeftemplate->implied = false;
178
+ newDeftemplate->numberOfSlots = 0;
179
+ newDeftemplate->busyCount = 0;
180
+ newDeftemplate->watch = 0;
181
+ newDeftemplate->inScope = true;
182
+ newDeftemplate->patternNetwork = NULL;
183
+ newDeftemplate->factList = NULL;
184
+ newDeftemplate->lastFact = NULL;
185
+ newDeftemplate->header.whichModule = (struct defmoduleItemHeader *)
186
+ GetModuleItem(theEnv,NULL,DeftemplateData(theEnv)->DeftemplateModuleIndex);
187
+
188
+ /*================================*/
189
+ /* Determine the number of slots. */
190
+ /*================================*/
191
+
192
+ while (slots != NULL)
193
+ {
194
+ newDeftemplate->numberOfSlots++;
195
+ slots = slots->next;
196
+ }
197
+
198
+ /*====================================*/
199
+ /* Store pretty print representation. */
200
+ /*====================================*/
201
+
202
+ if (GetConserveMemory(theEnv) == true)
203
+ { newDeftemplate->header.ppForm = NULL; }
204
+ else
205
+ { newDeftemplate->header.ppForm = CopyPPBuffer(theEnv); }
206
+
207
+ /*=======================================================================*/
208
+ /* If a template is redefined, then we want to restore its watch status. */
209
+ /*=======================================================================*/
210
+
211
+ #if DEBUGGING_FUNCTIONS
212
+ if ((BitwiseTest(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0)) ||
213
+ (GetWatchItem(theEnv,"facts") == 1))
214
+ { DeftemplateSetWatch(newDeftemplate,true); }
215
+ #endif
216
+
217
+ /*==============================================*/
218
+ /* Add deftemplate to the list of deftemplates. */
219
+ /*==============================================*/
220
+
221
+ AddConstructToModule(&newDeftemplate->header);
222
+
223
+ InstallDeftemplate(theEnv,newDeftemplate);
224
+
225
+ #else
226
+ #if MAC_XCD
227
+ #pragma unused(theEnv)
228
+ #endif
229
+ #endif
230
+
231
+ return false;
232
+ }
233
+
234
+ #if (! RUN_TIME) && (! BLOAD_ONLY)
235
+
236
+ /**************************************************************/
237
+ /* InstallDeftemplate: Increments all occurrences in the hash */
238
+ /* table of symbols found in an deftemplate and adds it to */
239
+ /* the hash table. */
240
+ /**************************************************************/
241
+ void InstallDeftemplate(
242
+ Environment *theEnv,
243
+ Deftemplate *theDeftemplate)
244
+ {
245
+ struct templateSlot *slotPtr;
246
+ struct expr *tempExpr;
247
+
248
+ IncrementLexemeCount(theDeftemplate->header.name);
249
+
250
+ for (slotPtr = theDeftemplate->slotList;
251
+ slotPtr != NULL;
252
+ slotPtr = slotPtr->next)
253
+ {
254
+ IncrementLexemeCount(slotPtr->slotName);
255
+ tempExpr = AddHashedExpression(theEnv,slotPtr->defaultList);
256
+ ReturnExpression(theEnv,slotPtr->defaultList);
257
+ slotPtr->defaultList = tempExpr;
258
+ tempExpr = AddHashedExpression(theEnv,slotPtr->facetList);
259
+ ReturnExpression(theEnv,slotPtr->facetList);
260
+ slotPtr->facetList = tempExpr;
261
+ slotPtr->constraints = AddConstraint(theEnv,slotPtr->constraints);
262
+ }
263
+ }
264
+
265
+ /********************************************************************/
266
+ /* SlotDeclarations: Parses the slot declarations of a deftemplate. */
267
+ /********************************************************************/
268
+ static struct templateSlot *SlotDeclarations(
269
+ Environment *theEnv,
270
+ const char *readSource,
271
+ struct token *inputToken)
272
+ {
273
+ struct templateSlot *newSlot, *slotList = NULL, *lastSlot = NULL;
274
+ struct templateSlot *multiSlot = NULL;
275
+
276
+ while (inputToken->tknType != RIGHT_PARENTHESIS_TOKEN)
277
+ {
278
+ /*====================================================*/
279
+ /* Slots begin with a '(' followed by a slot keyword. */
280
+ /*====================================================*/
281
+
282
+ if (inputToken->tknType != LEFT_PARENTHESIS_TOKEN)
283
+ {
284
+ SyntaxErrorMessage(theEnv,"deftemplate");
285
+ ReturnSlots(theEnv,slotList);
286
+ ReturnSlots(theEnv,multiSlot);
287
+ DeftemplateData(theEnv)->DeftemplateError = true;
288
+ return NULL;
289
+ }
290
+
291
+ GetToken(theEnv,readSource,inputToken);
292
+ if (inputToken->tknType != SYMBOL_TOKEN)
293
+ {
294
+ SyntaxErrorMessage(theEnv,"deftemplate");
295
+ ReturnSlots(theEnv,slotList);
296
+ ReturnSlots(theEnv,multiSlot);
297
+ DeftemplateData(theEnv)->DeftemplateError = true;
298
+ return NULL;
299
+ }
300
+
301
+ /*=================*/
302
+ /* Parse the slot. */
303
+ /*=================*/
304
+
305
+ newSlot = ParseSlot(theEnv,readSource,inputToken,slotList);
306
+ if (DeftemplateData(theEnv)->DeftemplateError == true)
307
+ {
308
+ ReturnSlots(theEnv,newSlot);
309
+ ReturnSlots(theEnv,slotList);
310
+ ReturnSlots(theEnv,multiSlot);
311
+ return NULL;
312
+ }
313
+
314
+ /*===========================================*/
315
+ /* Attach the new slot to the list of slots. */
316
+ /*===========================================*/
317
+
318
+ if (newSlot != NULL)
319
+ {
320
+ if (lastSlot == NULL)
321
+ { slotList = newSlot; }
322
+ else
323
+ { lastSlot->next = newSlot; }
324
+ lastSlot = newSlot;
325
+ }
326
+
327
+ /*================================*/
328
+ /* Check for closing parenthesis. */
329
+ /*================================*/
330
+
331
+ GetToken(theEnv,readSource,inputToken);
332
+ if (inputToken->tknType != RIGHT_PARENTHESIS_TOKEN)
333
+ {
334
+ PPBackup(theEnv);
335
+ SavePPBuffer(theEnv,"\n ");
336
+ SavePPBuffer(theEnv,inputToken->printForm);
337
+ }
338
+ }
339
+
340
+ SavePPBuffer(theEnv,"\n");
341
+
342
+ /*=======================*/
343
+ /* Return the slot list. */
344
+ /*=======================*/
345
+
346
+ return(slotList);
347
+ }
348
+
349
+ /*****************************************************/
350
+ /* ParseSlot: Parses a single slot of a deftemplate. */
351
+ /*****************************************************/
352
+ static struct templateSlot *ParseSlot(
353
+ Environment *theEnv,
354
+ const char *readSource,
355
+ struct token *inputToken,
356
+ struct templateSlot *slotList)
357
+ {
358
+ bool parsingMultislot;
359
+ CLIPSLexeme *slotName;
360
+ struct templateSlot *newSlot;
361
+ ConstraintViolationType rv;
362
+
363
+ /*=====================================================*/
364
+ /* Slots must begin with keyword field or multifield. */
365
+ /*=====================================================*/
366
+
367
+ if ((strcmp(inputToken->lexemeValue->contents,"field") != 0) &&
368
+ (strcmp(inputToken->lexemeValue->contents,"multifield") != 0) &&
369
+ (strcmp(inputToken->lexemeValue->contents,"slot") != 0) &&
370
+ (strcmp(inputToken->lexemeValue->contents,"multislot") != 0))
371
+ {
372
+ SyntaxErrorMessage(theEnv,"deftemplate");
373
+ DeftemplateData(theEnv)->DeftemplateError = true;
374
+ return NULL;
375
+ }
376
+
377
+ /*===============================================*/
378
+ /* Determine if multifield slot is being parsed. */
379
+ /*===============================================*/
380
+
381
+ if ((strcmp(inputToken->lexemeValue->contents,"multifield") == 0) ||
382
+ (strcmp(inputToken->lexemeValue->contents,"multislot") == 0))
383
+ { parsingMultislot = true; }
384
+ else
385
+ { parsingMultislot = false; }
386
+
387
+ /*========================================*/
388
+ /* The name of the slot must be a symbol. */
389
+ /*========================================*/
390
+
391
+ SavePPBuffer(theEnv," ");
392
+ GetToken(theEnv,readSource,inputToken);
393
+ if (inputToken->tknType != SYMBOL_TOKEN)
394
+ {
395
+ SyntaxErrorMessage(theEnv,"deftemplate");
396
+ DeftemplateData(theEnv)->DeftemplateError = true;
397
+ return NULL;
398
+ }
399
+
400
+ slotName = inputToken->lexemeValue;
401
+
402
+ /*================================================*/
403
+ /* Determine if the slot has already been parsed. */
404
+ /*================================================*/
405
+
406
+ while (slotList != NULL)
407
+ {
408
+ if (slotList->slotName == slotName)
409
+ {
410
+ AlreadyParsedErrorMessage(theEnv,"slot ",slotList->slotName->contents);
411
+ DeftemplateData(theEnv)->DeftemplateError = true;
412
+ return NULL;
413
+ }
414
+
415
+ slotList = slotList->next;
416
+ }
417
+
418
+ /*===================================*/
419
+ /* Parse the attributes of the slot. */
420
+ /*===================================*/
421
+
422
+ newSlot = DefinedSlots(theEnv,readSource,slotName,parsingMultislot,inputToken);
423
+ if (newSlot == NULL)
424
+ {
425
+ DeftemplateData(theEnv)->DeftemplateError = true;
426
+ return NULL;
427
+ }
428
+
429
+ /*=================================*/
430
+ /* Check for slot conflict errors. */
431
+ /*=================================*/
432
+
433
+ if (CheckConstraintParseConflicts(theEnv,newSlot->constraints) == false)
434
+ {
435
+ ReturnSlots(theEnv,newSlot);
436
+ DeftemplateData(theEnv)->DeftemplateError = true;
437
+ return NULL;
438
+ }
439
+
440
+ if ((newSlot->defaultPresent) || (newSlot->defaultDynamic))
441
+ { rv = ConstraintCheckExpressionChain(theEnv,newSlot->defaultList,newSlot->constraints); }
442
+ else
443
+ { rv = NO_VIOLATION; }
444
+
445
+ if (rv != NO_VIOLATION)
446
+ {
447
+ const char *temp;
448
+ if (newSlot->defaultDynamic) temp = "the default-dynamic attribute";
449
+ else temp = "the default attribute";
450
+ ConstraintViolationErrorMessage(theEnv,"An expression",temp,false,0,
451
+ newSlot->slotName,0,rv,newSlot->constraints,true);
452
+ ReturnSlots(theEnv,newSlot);
453
+ DeftemplateData(theEnv)->DeftemplateError = true;
454
+ return NULL;
455
+ }
456
+
457
+ /*==================*/
458
+ /* Return the slot. */
459
+ /*==================*/
460
+
461
+ return(newSlot);
462
+ }
463
+
464
+ /**************************************************************/
465
+ /* DefinedSlots: Parses a field or multifield slot attribute. */
466
+ /**************************************************************/
467
+ static struct templateSlot *DefinedSlots(
468
+ Environment *theEnv,
469
+ const char *readSource,
470
+ CLIPSLexeme *slotName,
471
+ bool multifieldSlot,
472
+ struct token *inputToken)
473
+ {
474
+ struct templateSlot *newSlot;
475
+ struct expr *defaultList;
476
+ bool defaultFound = false;
477
+ bool noneSpecified, deriveSpecified;
478
+ CONSTRAINT_PARSE_RECORD parsedConstraints;
479
+
480
+ /*===========================*/
481
+ /* Build the slot container. */
482
+ /*===========================*/
483
+
484
+ newSlot = get_struct(theEnv,templateSlot);
485
+ newSlot->slotName = slotName;
486
+ newSlot->defaultList = NULL;
487
+ newSlot->facetList = NULL;
488
+ newSlot->constraints = GetConstraintRecord(theEnv);
489
+ if (multifieldSlot)
490
+ { newSlot->constraints->multifieldsAllowed = true; }
491
+ newSlot->multislot = multifieldSlot;
492
+ newSlot->noDefault = false;
493
+ newSlot->defaultPresent = false;
494
+ newSlot->defaultDynamic = false;
495
+ newSlot->next = NULL;
496
+
497
+ /*========================================*/
498
+ /* Parse the primitive slot if it exists. */
499
+ /*========================================*/
500
+
501
+ InitializeConstraintParseRecord(&parsedConstraints);
502
+ GetToken(theEnv,readSource,inputToken);
503
+
504
+ while (inputToken->tknType != RIGHT_PARENTHESIS_TOKEN)
505
+ {
506
+ PPBackup(theEnv);
507
+ SavePPBuffer(theEnv," ");
508
+ SavePPBuffer(theEnv,inputToken->printForm);
509
+
510
+ /*================================================*/
511
+ /* Slot attributes begin with a left parenthesis. */
512
+ /*================================================*/
513
+
514
+ if (inputToken->tknType != LEFT_PARENTHESIS_TOKEN)
515
+ {
516
+ SyntaxErrorMessage(theEnv,"deftemplate");
517
+ ReturnSlots(theEnv,newSlot);
518
+ DeftemplateData(theEnv)->DeftemplateError = true;
519
+ return NULL;
520
+ }
521
+
522
+ /*=============================================*/
523
+ /* The name of the attribute must be a symbol. */
524
+ /*=============================================*/
525
+
526
+ GetToken(theEnv,readSource,inputToken);
527
+ if (inputToken->tknType != SYMBOL_TOKEN)
528
+ {
529
+ SyntaxErrorMessage(theEnv,"deftemplate");
530
+ ReturnSlots(theEnv,newSlot);
531
+ DeftemplateData(theEnv)->DeftemplateError = true;
532
+ return NULL;
533
+ }
534
+
535
+ /*================================================================*/
536
+ /* Determine if the attribute is one of the standard constraints. */
537
+ /*================================================================*/
538
+
539
+ if (StandardConstraint(inputToken->lexemeValue->contents))
540
+ {
541
+ if (ParseStandardConstraint(theEnv,readSource,(inputToken->lexemeValue->contents),
542
+ newSlot->constraints,&parsedConstraints,
543
+ multifieldSlot) == false)
544
+ {
545
+ DeftemplateData(theEnv)->DeftemplateError = true;
546
+ ReturnSlots(theEnv,newSlot);
547
+ return NULL;
548
+ }
549
+ }
550
+
551
+ /*=================================================*/
552
+ /* else if the attribute is the default attribute, */
553
+ /* then get the default list for this slot. */
554
+ /*=================================================*/
555
+
556
+ else if ((strcmp(inputToken->lexemeValue->contents,"default") == 0) ||
557
+ (strcmp(inputToken->lexemeValue->contents,"default-dynamic") == 0))
558
+ {
559
+ /*======================================================*/
560
+ /* Check to see if the default has already been parsed. */
561
+ /*======================================================*/
562
+
563
+ if (defaultFound)
564
+ {
565
+ AlreadyParsedErrorMessage(theEnv,"default attribute",NULL);
566
+ DeftemplateData(theEnv)->DeftemplateError = true;
567
+ ReturnSlots(theEnv,newSlot);
568
+ return NULL;
569
+ }
570
+
571
+ newSlot->noDefault = false;
572
+
573
+ /*=====================================================*/
574
+ /* Determine whether the default is dynamic or static. */
575
+ /*=====================================================*/
576
+
577
+ if (strcmp(inputToken->lexemeValue->contents,"default") == 0)
578
+ {
579
+ newSlot->defaultPresent = true;
580
+ newSlot->defaultDynamic = false;
581
+ }
582
+ else
583
+ {
584
+ newSlot->defaultPresent = false;
585
+ newSlot->defaultDynamic = true;
586
+ }
587
+
588
+ /*===================================*/
589
+ /* Parse the list of default values. */
590
+ /*===================================*/
591
+
592
+ defaultList = ParseDefault(theEnv,readSource,multifieldSlot,newSlot->defaultDynamic,
593
+ true,&noneSpecified,&deriveSpecified,&DeftemplateData(theEnv)->DeftemplateError);
594
+ if (DeftemplateData(theEnv)->DeftemplateError == true)
595
+ {
596
+ ReturnSlots(theEnv,newSlot);
597
+ return NULL;
598
+ }
599
+
600
+ /*==================================*/
601
+ /* Store the default with the slot. */
602
+ /*==================================*/
603
+
604
+ defaultFound = true;
605
+ if (deriveSpecified) newSlot->defaultPresent = false;
606
+ else if (noneSpecified)
607
+ {
608
+ newSlot->noDefault = true;
609
+ newSlot->defaultPresent = false;
610
+ }
611
+ newSlot->defaultList = defaultList;
612
+ }
613
+
614
+ /*===============================================*/
615
+ /* else if the attribute is the facet attribute. */
616
+ /*===============================================*/
617
+
618
+ else if (strcmp(inputToken->lexemeValue->contents,"facet") == 0)
619
+ {
620
+ if (! ParseFacetAttribute(theEnv,readSource,newSlot,false))
621
+ {
622
+ ReturnSlots(theEnv,newSlot);
623
+ DeftemplateData(theEnv)->DeftemplateError = true;
624
+ return NULL;
625
+ }
626
+ }
627
+
628
+ else if (strcmp(inputToken->lexemeValue->contents,"multifacet") == 0)
629
+ {
630
+ if (! ParseFacetAttribute(theEnv,readSource,newSlot,true))
631
+ {
632
+ ReturnSlots(theEnv,newSlot);
633
+ DeftemplateData(theEnv)->DeftemplateError = true;
634
+ return NULL;
635
+ }
636
+ }
637
+
638
+ /*============================================*/
639
+ /* Otherwise the attribute is an invalid one. */
640
+ /*============================================*/
641
+
642
+ else
643
+ {
644
+ SyntaxErrorMessage(theEnv,"slot attributes");
645
+ ReturnSlots(theEnv,newSlot);
646
+ DeftemplateData(theEnv)->DeftemplateError = true;
647
+ return NULL;
648
+ }
649
+
650
+ /*===================================*/
651
+ /* Begin parsing the next attribute. */
652
+ /*===================================*/
653
+
654
+ GetToken(theEnv,readSource,inputToken);
655
+ }
656
+
657
+ /*============================*/
658
+ /* Return the attribute list. */
659
+ /*============================*/
660
+
661
+ return(newSlot);
662
+ }
663
+
664
+ /***************************************************/
665
+ /* ParseFacetAttribute: Parses the type attribute. */
666
+ /***************************************************/
667
+ static bool ParseFacetAttribute(
668
+ Environment *theEnv,
669
+ const char *readSource,
670
+ struct templateSlot *theSlot,
671
+ bool multifacet)
672
+ {
673
+ struct token inputToken;
674
+ CLIPSLexeme *facetName;
675
+ struct expr *facetPair, *tempFacet, *facetValue = NULL, *lastValue = NULL;
676
+
677
+ /*==============================*/
678
+ /* Parse the name of the facet. */
679
+ /*==============================*/
680
+
681
+ SavePPBuffer(theEnv," ");
682
+ GetToken(theEnv,readSource,&inputToken);
683
+
684
+ /*==================================*/
685
+ /* The facet name must be a symbol. */
686
+ /*==================================*/
687
+
688
+ if (inputToken.tknType != SYMBOL_TOKEN)
689
+ {
690
+ if (multifacet) SyntaxErrorMessage(theEnv,"multifacet attribute");
691
+ else SyntaxErrorMessage(theEnv,"facet attribute");
692
+ return false;
693
+ }
694
+
695
+ facetName = inputToken.lexemeValue;
696
+
697
+ /*===================================*/
698
+ /* Don't allow facets with the same */
699
+ /* name as a predefined CLIPS facet. */
700
+ /*===================================*/
701
+
702
+ /*====================================*/
703
+ /* Has the facet already been parsed? */
704
+ /*====================================*/
705
+
706
+ for (tempFacet = theSlot->facetList;
707
+ tempFacet != NULL;
708
+ tempFacet = tempFacet->nextArg)
709
+ {
710
+ if (tempFacet->value == facetName)
711
+ {
712
+ if (multifacet) AlreadyParsedErrorMessage(theEnv,"multifacet ",facetName->contents);
713
+ else AlreadyParsedErrorMessage(theEnv,"facet ",facetName->contents);
714
+ return false;
715
+ }
716
+ }
717
+
718
+ /*===============================*/
719
+ /* Parse the value of the facet. */
720
+ /*===============================*/
721
+
722
+ SavePPBuffer(theEnv," ");
723
+ GetToken(theEnv,readSource,&inputToken);
724
+
725
+ while (inputToken.tknType != RIGHT_PARENTHESIS_TOKEN)
726
+ {
727
+ /*=====================================*/
728
+ /* The facet value must be a constant. */
729
+ /*=====================================*/
730
+
731
+ if (! ConstantType(TokenTypeToType(inputToken.tknType)))
732
+ {
733
+ if (multifacet) SyntaxErrorMessage(theEnv,"multifacet attribute");
734
+ else SyntaxErrorMessage(theEnv,"facet attribute");
735
+ ReturnExpression(theEnv,facetValue);
736
+ return false;
737
+ }
738
+
739
+ /*======================================*/
740
+ /* Add the value to the list of values. */
741
+ /*======================================*/
742
+
743
+ if (lastValue == NULL)
744
+ {
745
+ facetValue = GenConstant(theEnv,TokenTypeToType(inputToken.tknType),inputToken.value);
746
+ lastValue = facetValue;
747
+ }
748
+ else
749
+ {
750
+ lastValue->nextArg = GenConstant(theEnv,TokenTypeToType(inputToken.tknType),inputToken.value);
751
+ lastValue = lastValue->nextArg;
752
+ }
753
+
754
+ /*=====================*/
755
+ /* Get the next token. */
756
+ /*=====================*/
757
+
758
+ SavePPBuffer(theEnv," ");
759
+ GetToken(theEnv,readSource,&inputToken);
760
+
761
+ /*===============================================*/
762
+ /* A facet can't contain more than one constant. */
763
+ /*===============================================*/
764
+
765
+ if ((! multifacet) && (inputToken.tknType != RIGHT_PARENTHESIS_TOKEN))
766
+ {
767
+ SyntaxErrorMessage(theEnv,"facet attribute");
768
+ ReturnExpression(theEnv,facetValue);
769
+ return false;
770
+ }
771
+ }
772
+
773
+ /*========================================================*/
774
+ /* Remove the space before the closing right parenthesis. */
775
+ /*========================================================*/
776
+
777
+ PPBackup(theEnv);
778
+ PPBackup(theEnv);
779
+ SavePPBuffer(theEnv,")");
780
+
781
+ /*====================================*/
782
+ /* A facet must contain one constant. */
783
+ /*====================================*/
784
+
785
+ if ((! multifacet) && (facetValue == NULL))
786
+ {
787
+ SyntaxErrorMessage(theEnv,"facet attribute");
788
+ return false;
789
+ }
790
+
791
+ /*=================================================*/
792
+ /* Add the facet to the list of the slot's facets. */
793
+ /*=================================================*/
794
+
795
+ facetPair = GenConstant(theEnv,SYMBOL_TYPE,facetName);
796
+
797
+ if (multifacet)
798
+ {
799
+ facetPair->argList = GenConstant(theEnv,FCALL,FindFunction(theEnv,"create$"));
800
+ facetPair->argList->argList = facetValue;
801
+ }
802
+ else
803
+ { facetPair->argList = facetValue; }
804
+
805
+ facetPair->nextArg = theSlot->facetList;
806
+ theSlot->facetList = facetPair;
807
+
808
+ /*===============================================*/
809
+ /* The facet/multifacet was successfully parsed. */
810
+ /*===============================================*/
811
+
812
+ return true;
813
+ }
814
+
815
+ #endif /* (! RUN_TIME) && (! BLOAD_ONLY) */
816
+
817
+ #endif /* DEFTEMPLATE_CONSTRUCT */
818
+
819
+