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.
- checksums.yaml +7 -0
- data/ext/clipsruby/agenda.c +1373 -0
- data/ext/clipsruby/agenda.h +169 -0
- data/ext/clipsruby/analysis.c +1142 -0
- data/ext/clipsruby/analysis.h +61 -0
- data/ext/clipsruby/argacces.c +526 -0
- data/ext/clipsruby/argacces.h +77 -0
- data/ext/clipsruby/bload.c +884 -0
- data/ext/clipsruby/bload.h +94 -0
- data/ext/clipsruby/bmathfun.c +557 -0
- data/ext/clipsruby/bmathfun.h +66 -0
- data/ext/clipsruby/bsave.c +634 -0
- data/ext/clipsruby/bsave.h +130 -0
- data/ext/clipsruby/classcom.c +976 -0
- data/ext/clipsruby/classcom.h +115 -0
- data/ext/clipsruby/classexm.c +1376 -0
- data/ext/clipsruby/classexm.h +97 -0
- data/ext/clipsruby/classfun.c +1392 -0
- data/ext/clipsruby/classfun.h +164 -0
- data/ext/clipsruby/classinf.c +1245 -0
- data/ext/clipsruby/classinf.h +94 -0
- data/ext/clipsruby/classini.c +843 -0
- data/ext/clipsruby/classini.h +75 -0
- data/ext/clipsruby/classpsr.c +957 -0
- data/ext/clipsruby/classpsr.h +73 -0
- data/ext/clipsruby/clips.h +133 -0
- data/ext/clipsruby/clipsruby.c +619 -0
- data/ext/clipsruby/clsltpsr.c +931 -0
- data/ext/clipsruby/clsltpsr.h +72 -0
- data/ext/clipsruby/commline.c +1217 -0
- data/ext/clipsruby/commline.h +131 -0
- data/ext/clipsruby/conscomp.c +1593 -0
- data/ext/clipsruby/conscomp.h +150 -0
- data/ext/clipsruby/constant.h +264 -0
- data/ext/clipsruby/constrct.c +1090 -0
- data/ext/clipsruby/constrct.h +216 -0
- data/ext/clipsruby/constrnt.c +554 -0
- data/ext/clipsruby/constrnt.h +132 -0
- data/ext/clipsruby/crstrtgy.c +1088 -0
- data/ext/clipsruby/crstrtgy.h +85 -0
- data/ext/clipsruby/cstrcbin.c +185 -0
- data/ext/clipsruby/cstrcbin.h +61 -0
- data/ext/clipsruby/cstrccmp.h +43 -0
- data/ext/clipsruby/cstrccom.c +1791 -0
- data/ext/clipsruby/cstrccom.h +115 -0
- data/ext/clipsruby/cstrcpsr.c +835 -0
- data/ext/clipsruby/cstrcpsr.h +97 -0
- data/ext/clipsruby/cstrnbin.c +282 -0
- data/ext/clipsruby/cstrnbin.h +55 -0
- data/ext/clipsruby/cstrnchk.c +826 -0
- data/ext/clipsruby/cstrnchk.h +91 -0
- data/ext/clipsruby/cstrncmp.c +238 -0
- data/ext/clipsruby/cstrncmp.h +57 -0
- data/ext/clipsruby/cstrnops.c +1176 -0
- data/ext/clipsruby/cstrnops.h +47 -0
- data/ext/clipsruby/cstrnpsr.c +1394 -0
- data/ext/clipsruby/cstrnpsr.h +88 -0
- data/ext/clipsruby/cstrnutl.c +564 -0
- data/ext/clipsruby/cstrnutl.h +54 -0
- data/ext/clipsruby/default.c +454 -0
- data/ext/clipsruby/default.h +57 -0
- data/ext/clipsruby/defins.c +971 -0
- data/ext/clipsruby/defins.h +127 -0
- data/ext/clipsruby/developr.c +677 -0
- data/ext/clipsruby/developr.h +69 -0
- data/ext/clipsruby/dffctbin.c +477 -0
- data/ext/clipsruby/dffctbin.h +76 -0
- data/ext/clipsruby/dffctbsc.c +308 -0
- data/ext/clipsruby/dffctbsc.h +72 -0
- data/ext/clipsruby/dffctcmp.c +297 -0
- data/ext/clipsruby/dffctcmp.h +44 -0
- data/ext/clipsruby/dffctdef.c +364 -0
- data/ext/clipsruby/dffctdef.h +104 -0
- data/ext/clipsruby/dffctpsr.c +179 -0
- data/ext/clipsruby/dffctpsr.h +49 -0
- data/ext/clipsruby/dffnxbin.c +520 -0
- data/ext/clipsruby/dffnxbin.h +67 -0
- data/ext/clipsruby/dffnxcmp.c +378 -0
- data/ext/clipsruby/dffnxcmp.h +54 -0
- data/ext/clipsruby/dffnxexe.c +241 -0
- data/ext/clipsruby/dffnxexe.h +58 -0
- data/ext/clipsruby/dffnxfun.c +1192 -0
- data/ext/clipsruby/dffnxfun.h +155 -0
- data/ext/clipsruby/dffnxpsr.c +514 -0
- data/ext/clipsruby/dffnxpsr.h +57 -0
- data/ext/clipsruby/dfinsbin.c +509 -0
- data/ext/clipsruby/dfinsbin.h +66 -0
- data/ext/clipsruby/dfinscmp.c +345 -0
- data/ext/clipsruby/dfinscmp.h +48 -0
- data/ext/clipsruby/drive.c +1191 -0
- data/ext/clipsruby/drive.h +65 -0
- data/ext/clipsruby/emathfun.c +1213 -0
- data/ext/clipsruby/emathfun.h +99 -0
- data/ext/clipsruby/engine.c +1568 -0
- data/ext/clipsruby/engine.h +203 -0
- data/ext/clipsruby/entities.h +276 -0
- data/ext/clipsruby/envrnbld.c +514 -0
- data/ext/clipsruby/envrnbld.h +40 -0
- data/ext/clipsruby/envrnmnt.c +257 -0
- data/ext/clipsruby/envrnmnt.h +112 -0
- data/ext/clipsruby/evaluatn.c +1736 -0
- data/ext/clipsruby/evaluatn.h +211 -0
- data/ext/clipsruby/expressn.c +494 -0
- data/ext/clipsruby/expressn.h +154 -0
- data/ext/clipsruby/exprnbin.c +538 -0
- data/ext/clipsruby/exprnbin.h +60 -0
- data/ext/clipsruby/exprnops.c +564 -0
- data/ext/clipsruby/exprnops.h +67 -0
- data/ext/clipsruby/exprnpsr.c +1112 -0
- data/ext/clipsruby/exprnpsr.h +98 -0
- data/ext/clipsruby/extconf.rb +2 -0
- data/ext/clipsruby/extnfunc.c +1015 -0
- data/ext/clipsruby/extnfunc.h +157 -0
- data/ext/clipsruby/factbin.c +447 -0
- data/ext/clipsruby/factbin.h +56 -0
- data/ext/clipsruby/factbld.c +1035 -0
- data/ext/clipsruby/factbld.h +63 -0
- data/ext/clipsruby/factcmp.c +386 -0
- data/ext/clipsruby/factcmp.h +46 -0
- data/ext/clipsruby/factcom.c +759 -0
- data/ext/clipsruby/factcom.h +80 -0
- data/ext/clipsruby/factfile.c +1761 -0
- data/ext/clipsruby/factfile.h +54 -0
- data/ext/clipsruby/factfun.c +682 -0
- data/ext/clipsruby/factfun.h +77 -0
- data/ext/clipsruby/factgen.c +1305 -0
- data/ext/clipsruby/factgen.h +229 -0
- data/ext/clipsruby/facthsh.c +438 -0
- data/ext/clipsruby/facthsh.h +81 -0
- data/ext/clipsruby/factlhs.c +250 -0
- data/ext/clipsruby/factlhs.h +54 -0
- data/ext/clipsruby/factmch.c +905 -0
- data/ext/clipsruby/factmch.h +68 -0
- data/ext/clipsruby/factmngr.c +3373 -0
- data/ext/clipsruby/factmngr.h +325 -0
- data/ext/clipsruby/factprt.c +498 -0
- data/ext/clipsruby/factprt.h +60 -0
- data/ext/clipsruby/factqpsr.c +796 -0
- data/ext/clipsruby/factqpsr.h +61 -0
- data/ext/clipsruby/factqury.c +1267 -0
- data/ext/clipsruby/factqury.h +112 -0
- data/ext/clipsruby/factrete.c +978 -0
- data/ext/clipsruby/factrete.h +70 -0
- data/ext/clipsruby/factrhs.c +667 -0
- data/ext/clipsruby/factrhs.h +55 -0
- data/ext/clipsruby/filecom.c +353 -0
- data/ext/clipsruby/filecom.h +137 -0
- data/ext/clipsruby/filertr.c +481 -0
- data/ext/clipsruby/filertr.h +94 -0
- data/ext/clipsruby/fileutil.c +1020 -0
- data/ext/clipsruby/fileutil.h +50 -0
- data/ext/clipsruby/generate.c +1079 -0
- data/ext/clipsruby/generate.h +57 -0
- data/ext/clipsruby/genrcbin.c +902 -0
- data/ext/clipsruby/genrcbin.h +69 -0
- data/ext/clipsruby/genrccmp.c +640 -0
- data/ext/clipsruby/genrccmp.h +59 -0
- data/ext/clipsruby/genrccom.c +2017 -0
- data/ext/clipsruby/genrccom.h +119 -0
- data/ext/clipsruby/genrcexe.c +737 -0
- data/ext/clipsruby/genrcexe.h +73 -0
- data/ext/clipsruby/genrcfun.c +890 -0
- data/ext/clipsruby/genrcfun.h +185 -0
- data/ext/clipsruby/genrcpsr.c +1618 -0
- data/ext/clipsruby/genrcpsr.h +80 -0
- data/ext/clipsruby/globlbin.c +458 -0
- data/ext/clipsruby/globlbin.h +71 -0
- data/ext/clipsruby/globlbsc.c +361 -0
- data/ext/clipsruby/globlbsc.h +83 -0
- data/ext/clipsruby/globlcmp.c +330 -0
- data/ext/clipsruby/globlcmp.h +52 -0
- data/ext/clipsruby/globlcom.c +289 -0
- data/ext/clipsruby/globlcom.h +63 -0
- data/ext/clipsruby/globldef.c +1087 -0
- data/ext/clipsruby/globldef.h +151 -0
- data/ext/clipsruby/globlpsr.c +530 -0
- data/ext/clipsruby/globlpsr.h +59 -0
- data/ext/clipsruby/immthpsr.c +431 -0
- data/ext/clipsruby/immthpsr.h +55 -0
- data/ext/clipsruby/incrrset.c +530 -0
- data/ext/clipsruby/incrrset.h +73 -0
- data/ext/clipsruby/inherpsr.c +850 -0
- data/ext/clipsruby/inherpsr.h +52 -0
- data/ext/clipsruby/inscom.c +2076 -0
- data/ext/clipsruby/inscom.h +182 -0
- data/ext/clipsruby/insfile.c +1764 -0
- data/ext/clipsruby/insfile.h +96 -0
- data/ext/clipsruby/insfun.c +1451 -0
- data/ext/clipsruby/insfun.h +134 -0
- data/ext/clipsruby/insmngr.c +2550 -0
- data/ext/clipsruby/insmngr.h +125 -0
- data/ext/clipsruby/insmoddp.c +1041 -0
- data/ext/clipsruby/insmoddp.h +91 -0
- data/ext/clipsruby/insmult.c +804 -0
- data/ext/clipsruby/insmult.h +62 -0
- data/ext/clipsruby/inspsr.c +602 -0
- data/ext/clipsruby/inspsr.h +60 -0
- data/ext/clipsruby/insquery.c +1278 -0
- data/ext/clipsruby/insquery.h +115 -0
- data/ext/clipsruby/insqypsr.c +729 -0
- data/ext/clipsruby/insqypsr.h +63 -0
- data/ext/clipsruby/iofun.c +2045 -0
- data/ext/clipsruby/iofun.h +116 -0
- data/ext/clipsruby/lgcldpnd.c +644 -0
- data/ext/clipsruby/lgcldpnd.h +75 -0
- data/ext/clipsruby/main.c +112 -0
- data/ext/clipsruby/match.h +142 -0
- data/ext/clipsruby/memalloc.c +481 -0
- data/ext/clipsruby/memalloc.h +197 -0
- data/ext/clipsruby/miscfun.c +1801 -0
- data/ext/clipsruby/miscfun.h +132 -0
- data/ext/clipsruby/modulbin.c +607 -0
- data/ext/clipsruby/modulbin.h +84 -0
- data/ext/clipsruby/modulbsc.c +347 -0
- data/ext/clipsruby/modulbsc.h +67 -0
- data/ext/clipsruby/modulcmp.c +499 -0
- data/ext/clipsruby/modulcmp.h +54 -0
- data/ext/clipsruby/moduldef.c +817 -0
- data/ext/clipsruby/moduldef.h +271 -0
- data/ext/clipsruby/modulpsr.c +1150 -0
- data/ext/clipsruby/modulpsr.h +69 -0
- data/ext/clipsruby/modulutl.c +1036 -0
- data/ext/clipsruby/modulutl.h +84 -0
- data/ext/clipsruby/msgcom.c +1221 -0
- data/ext/clipsruby/msgcom.h +125 -0
- data/ext/clipsruby/msgfun.c +1076 -0
- data/ext/clipsruby/msgfun.h +118 -0
- data/ext/clipsruby/msgpass.c +1441 -0
- data/ext/clipsruby/msgpass.h +103 -0
- data/ext/clipsruby/msgpsr.c +698 -0
- data/ext/clipsruby/msgpsr.h +73 -0
- data/ext/clipsruby/multifld.c +1404 -0
- data/ext/clipsruby/multifld.h +130 -0
- data/ext/clipsruby/multifun.c +2182 -0
- data/ext/clipsruby/multifun.h +102 -0
- data/ext/clipsruby/network.h +142 -0
- data/ext/clipsruby/objbin.c +1522 -0
- data/ext/clipsruby/objbin.h +79 -0
- data/ext/clipsruby/objcmp.c +1507 -0
- data/ext/clipsruby/objcmp.h +71 -0
- data/ext/clipsruby/object.h +260 -0
- data/ext/clipsruby/objrtbin.c +701 -0
- data/ext/clipsruby/objrtbin.h +79 -0
- data/ext/clipsruby/objrtbld.c +2393 -0
- data/ext/clipsruby/objrtbld.h +66 -0
- data/ext/clipsruby/objrtcmp.c +734 -0
- data/ext/clipsruby/objrtcmp.h +66 -0
- data/ext/clipsruby/objrtfnx.c +1330 -0
- data/ext/clipsruby/objrtfnx.h +222 -0
- data/ext/clipsruby/objrtgen.c +736 -0
- data/ext/clipsruby/objrtgen.h +63 -0
- data/ext/clipsruby/objrtmch.c +1524 -0
- data/ext/clipsruby/objrtmch.h +160 -0
- data/ext/clipsruby/parsefun.c +415 -0
- data/ext/clipsruby/parsefun.h +67 -0
- data/ext/clipsruby/pattern.c +1265 -0
- data/ext/clipsruby/pattern.h +163 -0
- data/ext/clipsruby/pprint.c +328 -0
- data/ext/clipsruby/pprint.h +79 -0
- data/ext/clipsruby/prccode.c +1478 -0
- data/ext/clipsruby/prccode.h +145 -0
- data/ext/clipsruby/prcdrfun.c +640 -0
- data/ext/clipsruby/prcdrfun.h +95 -0
- data/ext/clipsruby/prcdrpsr.c +1068 -0
- data/ext/clipsruby/prcdrpsr.h +79 -0
- data/ext/clipsruby/prdctfun.c +869 -0
- data/ext/clipsruby/prdctfun.h +77 -0
- data/ext/clipsruby/prntutil.c +878 -0
- data/ext/clipsruby/prntutil.h +125 -0
- data/ext/clipsruby/proflfun.c +827 -0
- data/ext/clipsruby/proflfun.h +118 -0
- data/ext/clipsruby/reorder.c +2082 -0
- data/ext/clipsruby/reorder.h +172 -0
- data/ext/clipsruby/reteutil.c +1732 -0
- data/ext/clipsruby/reteutil.h +111 -0
- data/ext/clipsruby/retract.c +710 -0
- data/ext/clipsruby/retract.h +74 -0
- data/ext/clipsruby/router.c +737 -0
- data/ext/clipsruby/router.h +147 -0
- data/ext/clipsruby/rulebin.c +1136 -0
- data/ext/clipsruby/rulebin.h +153 -0
- data/ext/clipsruby/rulebld.c +1328 -0
- data/ext/clipsruby/rulebld.h +62 -0
- data/ext/clipsruby/rulebsc.c +517 -0
- data/ext/clipsruby/rulebsc.h +91 -0
- data/ext/clipsruby/rulecmp.c +733 -0
- data/ext/clipsruby/rulecmp.h +63 -0
- data/ext/clipsruby/rulecom.c +1583 -0
- data/ext/clipsruby/rulecom.h +116 -0
- data/ext/clipsruby/rulecstr.c +892 -0
- data/ext/clipsruby/rulecstr.h +53 -0
- data/ext/clipsruby/ruledef.c +559 -0
- data/ext/clipsruby/ruledef.h +179 -0
- data/ext/clipsruby/ruledlt.c +599 -0
- data/ext/clipsruby/ruledlt.h +58 -0
- data/ext/clipsruby/rulelhs.c +1216 -0
- data/ext/clipsruby/rulelhs.h +52 -0
- data/ext/clipsruby/rulepsr.c +1073 -0
- data/ext/clipsruby/rulepsr.h +61 -0
- data/ext/clipsruby/scanner.c +856 -0
- data/ext/clipsruby/scanner.h +112 -0
- data/ext/clipsruby/setup.h +488 -0
- data/ext/clipsruby/sortfun.c +433 -0
- data/ext/clipsruby/sortfun.h +55 -0
- data/ext/clipsruby/strngfun.c +1173 -0
- data/ext/clipsruby/strngfun.h +96 -0
- data/ext/clipsruby/strngrtr.c +523 -0
- data/ext/clipsruby/strngrtr.h +97 -0
- data/ext/clipsruby/symblbin.c +648 -0
- data/ext/clipsruby/symblbin.h +64 -0
- data/ext/clipsruby/symblcmp.c +893 -0
- data/ext/clipsruby/symblcmp.h +61 -0
- data/ext/clipsruby/symbol.c +1961 -0
- data/ext/clipsruby/symbol.h +243 -0
- data/ext/clipsruby/sysdep.c +894 -0
- data/ext/clipsruby/sysdep.h +164 -0
- data/ext/clipsruby/textpro.c +1388 -0
- data/ext/clipsruby/textpro.h +77 -0
- data/ext/clipsruby/tmpltbin.c +609 -0
- data/ext/clipsruby/tmpltbin.h +108 -0
- data/ext/clipsruby/tmpltbsc.c +327 -0
- data/ext/clipsruby/tmpltbsc.h +87 -0
- data/ext/clipsruby/tmpltcmp.c +450 -0
- data/ext/clipsruby/tmpltcmp.h +57 -0
- data/ext/clipsruby/tmpltdef.c +584 -0
- data/ext/clipsruby/tmpltdef.h +155 -0
- data/ext/clipsruby/tmpltfun.c +2477 -0
- data/ext/clipsruby/tmpltfun.h +122 -0
- data/ext/clipsruby/tmpltlhs.c +379 -0
- data/ext/clipsruby/tmpltlhs.h +50 -0
- data/ext/clipsruby/tmpltpsr.c +819 -0
- data/ext/clipsruby/tmpltpsr.h +59 -0
- data/ext/clipsruby/tmpltrhs.c +595 -0
- data/ext/clipsruby/tmpltrhs.h +55 -0
- data/ext/clipsruby/tmpltutl.c +637 -0
- data/ext/clipsruby/tmpltutl.h +82 -0
- data/ext/clipsruby/userdata.c +156 -0
- data/ext/clipsruby/userdata.h +72 -0
- data/ext/clipsruby/userfunctions.c +70 -0
- data/ext/clipsruby/usrsetup.h +7 -0
- data/ext/clipsruby/utility.c +1594 -0
- data/ext/clipsruby/utility.h +250 -0
- data/ext/clipsruby/watch.c +865 -0
- data/ext/clipsruby/watch.h +124 -0
- data/lib/clipsruby.rb +1 -0
- metadata +388 -0
@@ -0,0 +1,2550 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.41 03/11/23 */
|
5
|
+
/* */
|
6
|
+
/* INSTANCE PRIMITIVE SUPPORT MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Creation and Deletion of Instances Routines */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Brian L. Dantes */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* */
|
17
|
+
/* */
|
18
|
+
/* Revision History: */
|
19
|
+
/* */
|
20
|
+
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
|
21
|
+
/* */
|
22
|
+
/* 6.24: Removed LOGICAL_DEPENDENCIES compilation flag. */
|
23
|
+
/* */
|
24
|
+
/* Converted INSTANCE_PATTERN_MATCHING to */
|
25
|
+
/* DEFRULE_CONSTRUCT. */
|
26
|
+
/* */
|
27
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
28
|
+
/* */
|
29
|
+
/* 6.30: Changed integer type/precision. */
|
30
|
+
/* */
|
31
|
+
/* Used gensprintf instead of sprintf. */
|
32
|
+
/* */
|
33
|
+
/* Changed garbage collection algorithm. */
|
34
|
+
/* */
|
35
|
+
/* Added const qualifiers to remove C++ */
|
36
|
+
/* deprecation warnings. */
|
37
|
+
/* */
|
38
|
+
/* Newly created instances can no longer use */
|
39
|
+
/* a preexisting instance name of another class */
|
40
|
+
/* [INSMNGR16]. */
|
41
|
+
/* */
|
42
|
+
/* 6.31: Marked deleted instances so that partial */
|
43
|
+
/* matches will not be propagated when the match */
|
44
|
+
/* is based on both the existence and */
|
45
|
+
/* non-existence of an instance. */
|
46
|
+
/* */
|
47
|
+
/* 6.32: Fixed instance redefinition crash with rules */
|
48
|
+
/* in JNSimpleCompareFunction1 when deleted */
|
49
|
+
/* instance slots are referenced. */
|
50
|
+
/* */
|
51
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
52
|
+
/* SetEvaluationError functions. */
|
53
|
+
/* */
|
54
|
+
/* Pragma once and other inclusion changes. */
|
55
|
+
/* */
|
56
|
+
/* Added support for booleans with <stdbool.h>. */
|
57
|
+
/* */
|
58
|
+
/* Removed use of void pointers for specific */
|
59
|
+
/* data structures. */
|
60
|
+
/* */
|
61
|
+
/* UDF redesign. */
|
62
|
+
/* */
|
63
|
+
/* 6.41: Instance builders and modifiers were not */
|
64
|
+
/* allocating storage for inherited slots. */
|
65
|
+
/* */
|
66
|
+
/* Removed unnecessary variable initialization */
|
67
|
+
/* in IBAbort. */
|
68
|
+
/* */
|
69
|
+
/* Calling IMPutSlot with empty multifield to */
|
70
|
+
/* multifield slot did not assign value. */
|
71
|
+
/* */
|
72
|
+
/*************************************************************/
|
73
|
+
|
74
|
+
/* =========================================
|
75
|
+
*****************************************
|
76
|
+
EXTERNAL DEFINITIONS
|
77
|
+
=========================================
|
78
|
+
***************************************** */
|
79
|
+
#include "setup.h"
|
80
|
+
|
81
|
+
#if OBJECT_SYSTEM
|
82
|
+
|
83
|
+
#if DEFRULE_CONSTRUCT
|
84
|
+
#include "network.h"
|
85
|
+
#include "drive.h"
|
86
|
+
#include "objrtmch.h"
|
87
|
+
#include "lgcldpnd.h"
|
88
|
+
#include "objrtfnx.h"
|
89
|
+
#endif
|
90
|
+
|
91
|
+
#include "classcom.h"
|
92
|
+
#include "classfun.h"
|
93
|
+
#include "cstrnchk.h"
|
94
|
+
#include "engine.h"
|
95
|
+
#include "envrnmnt.h"
|
96
|
+
#include "extnfunc.h"
|
97
|
+
#include "insfun.h"
|
98
|
+
#include "memalloc.h"
|
99
|
+
#include "miscfun.h"
|
100
|
+
#include "modulutl.h"
|
101
|
+
#include "msgcom.h"
|
102
|
+
#include "msgfun.h"
|
103
|
+
#include "prccode.h"
|
104
|
+
#include "prntutil.h"
|
105
|
+
#include "router.h"
|
106
|
+
#include "sysdep.h"
|
107
|
+
#include "utility.h"
|
108
|
+
|
109
|
+
#include "insmngr.h"
|
110
|
+
|
111
|
+
#include "inscom.h"
|
112
|
+
#include "watch.h"
|
113
|
+
|
114
|
+
/* =========================================
|
115
|
+
*****************************************
|
116
|
+
CONSTANTS
|
117
|
+
=========================================
|
118
|
+
***************************************** */
|
119
|
+
#define MAKE_TRACE "==>"
|
120
|
+
#define UNMAKE_TRACE "<=="
|
121
|
+
|
122
|
+
/***************************************/
|
123
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
124
|
+
/***************************************/
|
125
|
+
|
126
|
+
static Instance *NewInstance(Environment *);
|
127
|
+
static Instance *InstanceLocationInfo(Environment *,Defclass *,CLIPSLexeme *,Instance **,
|
128
|
+
unsigned *);
|
129
|
+
static void InstallInstance(Environment *,Instance *,bool);
|
130
|
+
static void BuildDefaultSlots(Environment *,bool);
|
131
|
+
static bool CoreInitializeInstance(Environment *,Instance *,Expression *);
|
132
|
+
static bool CoreInitializeInstanceCV(Environment *,Instance *,CLIPSValue *);
|
133
|
+
static bool InsertSlotOverrides(Environment *,Instance *,Expression *);
|
134
|
+
static bool InsertSlotOverridesCV(Environment *,Instance *,CLIPSValue *);
|
135
|
+
static void EvaluateClassDefaults(Environment *,Instance *);
|
136
|
+
static bool IMModifySlots(Environment *,Instance *,CLIPSValue *);
|
137
|
+
|
138
|
+
#if DEBUGGING_FUNCTIONS
|
139
|
+
static void PrintInstanceWatch(Environment *,const char *,Instance *);
|
140
|
+
#endif
|
141
|
+
|
142
|
+
/* =========================================
|
143
|
+
*****************************************
|
144
|
+
EXTERNALLY VISIBLE FUNCTIONS
|
145
|
+
=========================================
|
146
|
+
***************************************** */
|
147
|
+
|
148
|
+
/***********************************************************
|
149
|
+
NAME : InitializeInstanceCommand
|
150
|
+
DESCRIPTION : Initializes an instance of a class
|
151
|
+
INPUTS : The address of the result value
|
152
|
+
RETURNS : Nothing useful
|
153
|
+
SIDE EFFECTS : Instance intialized
|
154
|
+
NOTES : H/L Syntax:
|
155
|
+
(active-initialize-instance <instance-name>
|
156
|
+
<slot-override>*)
|
157
|
+
***********************************************************/
|
158
|
+
void InitializeInstanceCommand(
|
159
|
+
Environment *theEnv,
|
160
|
+
UDFContext *context,
|
161
|
+
UDFValue *returnValue)
|
162
|
+
{
|
163
|
+
Instance *ins;
|
164
|
+
|
165
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
166
|
+
ins = CheckInstance(context);
|
167
|
+
if (ins == NULL)
|
168
|
+
return;
|
169
|
+
if (CoreInitializeInstance(theEnv,ins,GetFirstArgument()->nextArg) == true)
|
170
|
+
{ returnValue->value = ins->name; }
|
171
|
+
}
|
172
|
+
|
173
|
+
/****************************************************************
|
174
|
+
NAME : MakeInstanceCommand
|
175
|
+
DESCRIPTION : Creates and initializes an instance of a class
|
176
|
+
INPUTS : The address of the result value
|
177
|
+
RETURNS : Nothing useful
|
178
|
+
SIDE EFFECTS : Instance intialized
|
179
|
+
NOTES : H/L Syntax:
|
180
|
+
(active-make-instance <instance-name> of <class>
|
181
|
+
<slot-override>*)
|
182
|
+
CHANGES : It's now possible to create an instance of a
|
183
|
+
class that's not in scope if the module name
|
184
|
+
is specified.
|
185
|
+
****************************************************************/
|
186
|
+
void MakeInstanceCommand(
|
187
|
+
Environment *theEnv,
|
188
|
+
UDFContext *context,
|
189
|
+
UDFValue *returnValue)
|
190
|
+
{
|
191
|
+
CLIPSLexeme *iname;
|
192
|
+
Instance *ins;
|
193
|
+
UDFValue temp;
|
194
|
+
Defclass *cls;
|
195
|
+
|
196
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
197
|
+
EvaluateExpression(theEnv,GetFirstArgument(),&temp);
|
198
|
+
|
199
|
+
if (temp.header->type == INSTANCE_NAME_TYPE)
|
200
|
+
{ iname = temp.lexemeValue; }
|
201
|
+
else if (temp.header->type == SYMBOL_TYPE)
|
202
|
+
{ iname = CreateInstanceName(theEnv,temp.lexemeValue->contents); }
|
203
|
+
else
|
204
|
+
{
|
205
|
+
PrintErrorID(theEnv,"INSMNGR",1,false);
|
206
|
+
WriteString(theEnv,STDERR,"Expected a valid name for new instance.\n");
|
207
|
+
SetEvaluationError(theEnv,true);
|
208
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
209
|
+
return;
|
210
|
+
}
|
211
|
+
|
212
|
+
if (GetFirstArgument()->nextArg->type == DEFCLASS_PTR)
|
213
|
+
cls = (Defclass *) GetFirstArgument()->nextArg->value;
|
214
|
+
else
|
215
|
+
{
|
216
|
+
EvaluateExpression(theEnv,GetFirstArgument()->nextArg,&temp);
|
217
|
+
if (temp.header->type != SYMBOL_TYPE)
|
218
|
+
{
|
219
|
+
PrintErrorID(theEnv,"INSMNGR",2,false);
|
220
|
+
WriteString(theEnv,STDERR,"Expected a valid class name for new instance.\n");
|
221
|
+
SetEvaluationError(theEnv,true);
|
222
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
223
|
+
return;
|
224
|
+
}
|
225
|
+
|
226
|
+
cls = LookupDefclassByMdlOrScope(theEnv,temp.lexemeValue->contents); // Module or scope is now allowed
|
227
|
+
|
228
|
+
if (cls == NULL)
|
229
|
+
{
|
230
|
+
ClassExistError(theEnv,ExpressionFunctionCallName(EvaluationData(theEnv)->CurrentExpression)->contents,
|
231
|
+
temp.lexemeValue->contents);
|
232
|
+
SetEvaluationError(theEnv,true);
|
233
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
234
|
+
return;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
ins = BuildInstance(theEnv,iname,cls,true);
|
239
|
+
if (ins == NULL) return;
|
240
|
+
|
241
|
+
if (CoreInitializeInstance(theEnv,ins,GetFirstArgument()->nextArg->nextArg) == true)
|
242
|
+
{ returnValue->value = GetFullInstanceName(theEnv,ins); }
|
243
|
+
else
|
244
|
+
QuashInstance(theEnv,ins);
|
245
|
+
}
|
246
|
+
|
247
|
+
/***************************************************
|
248
|
+
NAME : GetFullInstanceName
|
249
|
+
DESCRIPTION : If this function is called while
|
250
|
+
the current module is other than
|
251
|
+
the one in which the instance
|
252
|
+
resides, then the module name is
|
253
|
+
prepended to the instance name.
|
254
|
+
Otherwise - the base name only is
|
255
|
+
returned.
|
256
|
+
INPUTS : The instance
|
257
|
+
RETURNS : The instance name symbol (with
|
258
|
+
module name and :: prepended)
|
259
|
+
SIDE EFFECTS : Temporary buffer allocated possibly
|
260
|
+
and new symbol created
|
261
|
+
NOTES : Used to differentiate between
|
262
|
+
instances of the same name in
|
263
|
+
different modules.
|
264
|
+
Instances are now global in scope so
|
265
|
+
each instance name must belong to a
|
266
|
+
single instance. It's no longer
|
267
|
+
necessary to return the full instance
|
268
|
+
name.
|
269
|
+
***************************************************/
|
270
|
+
CLIPSLexeme *GetFullInstanceName(
|
271
|
+
Environment *theEnv,
|
272
|
+
Instance *ins)
|
273
|
+
{
|
274
|
+
if (ins == &InstanceData(theEnv)->DummyInstance)
|
275
|
+
{ return CreateInstanceName(theEnv,"Dummy Instance"); }
|
276
|
+
|
277
|
+
return ins->name;
|
278
|
+
}
|
279
|
+
|
280
|
+
/***************************************************
|
281
|
+
NAME : BuildInstance
|
282
|
+
DESCRIPTION : Creates an uninitialized instance
|
283
|
+
INPUTS : 1) Name of the instance
|
284
|
+
2) Class pointer
|
285
|
+
3) Flag indicating whether init
|
286
|
+
message will be called for
|
287
|
+
this instance or not
|
288
|
+
RETURNS : The address of the new instance,
|
289
|
+
NULL on errors (or when a
|
290
|
+
a logical basis in a rule was
|
291
|
+
deleted int the same RHS in
|
292
|
+
which the instance creation
|
293
|
+
occurred)
|
294
|
+
SIDE EFFECTS : Old definition (if any) is deleted
|
295
|
+
NOTES : None
|
296
|
+
***************************************************/
|
297
|
+
Instance *BuildInstance(
|
298
|
+
Environment *theEnv,
|
299
|
+
CLIPSLexeme *iname,
|
300
|
+
Defclass *cls,
|
301
|
+
bool initMessage)
|
302
|
+
{
|
303
|
+
Instance *ins,*iprv;
|
304
|
+
unsigned hashTableIndex;
|
305
|
+
unsigned modulePosition;
|
306
|
+
CLIPSLexeme *moduleName;
|
307
|
+
UDFValue temp;
|
308
|
+
|
309
|
+
if (iname->header.type == SYMBOL_TYPE)
|
310
|
+
{ iname = CreateInstanceName(theEnv,iname->contents); }
|
311
|
+
|
312
|
+
#if DEFRULE_CONSTRUCT
|
313
|
+
if (EngineData(theEnv)->JoinOperationInProgress && cls->reactive)
|
314
|
+
{
|
315
|
+
PrintErrorID(theEnv,"INSMNGR",10,false);
|
316
|
+
WriteString(theEnv,STDERR,"Cannot create instances of reactive classes while ");
|
317
|
+
WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
|
318
|
+
SetEvaluationError(theEnv,true);
|
319
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
320
|
+
return NULL;
|
321
|
+
}
|
322
|
+
#endif
|
323
|
+
if (cls->abstract)
|
324
|
+
{
|
325
|
+
PrintErrorID(theEnv,"INSMNGR",3,false);
|
326
|
+
WriteString(theEnv,STDERR,"Cannot create instances of abstract class '");
|
327
|
+
WriteString(theEnv,STDERR,DefclassName(cls));
|
328
|
+
WriteString(theEnv,STDERR,"'.\n");
|
329
|
+
SetEvaluationError(theEnv,true);
|
330
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
331
|
+
return NULL;
|
332
|
+
}
|
333
|
+
modulePosition = FindModuleSeparator(iname->contents);
|
334
|
+
if (modulePosition)
|
335
|
+
{
|
336
|
+
moduleName = ExtractModuleName(theEnv,modulePosition,iname->contents);
|
337
|
+
if ((moduleName == NULL) ||
|
338
|
+
(moduleName != cls->header.whichModule->theModule->header.name))
|
339
|
+
{
|
340
|
+
PrintErrorID(theEnv,"INSMNGR",11,true);
|
341
|
+
WriteString(theEnv,STDERR,"Invalid module specifier in new instance name.\n");
|
342
|
+
SetEvaluationError(theEnv,true);
|
343
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
344
|
+
return NULL;
|
345
|
+
}
|
346
|
+
iname = ExtractConstructName(theEnv,modulePosition,iname->contents,INSTANCE_NAME_TYPE);
|
347
|
+
}
|
348
|
+
ins = InstanceLocationInfo(theEnv,cls,iname,&iprv,&hashTableIndex);
|
349
|
+
|
350
|
+
if (ins != NULL)
|
351
|
+
{
|
352
|
+
if (ins->cls != cls)
|
353
|
+
{
|
354
|
+
PrintErrorID(theEnv,"INSMNGR",16,false);
|
355
|
+
WriteString(theEnv,STDERR,"The instance name [");
|
356
|
+
WriteString(theEnv,STDERR,iname->contents);
|
357
|
+
WriteString(theEnv,STDERR,"] is in use by an instance of class '");
|
358
|
+
WriteString(theEnv,STDERR,ins->cls->header.name->contents);
|
359
|
+
WriteString(theEnv,STDERR,"'.\n");
|
360
|
+
SetEvaluationError(theEnv,true);
|
361
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
362
|
+
return NULL;
|
363
|
+
}
|
364
|
+
|
365
|
+
if (ins->installed == 0)
|
366
|
+
{
|
367
|
+
PrintErrorID(theEnv,"INSMNGR",4,false);
|
368
|
+
WriteString(theEnv,STDERR,"The instance [");
|
369
|
+
WriteString(theEnv,STDERR,iname->contents);
|
370
|
+
WriteString(theEnv,STDERR,"] has a slot-value which depends on the instance definition.\n");
|
371
|
+
SetEvaluationError(theEnv,true);
|
372
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
373
|
+
return NULL;
|
374
|
+
}
|
375
|
+
ins->busy++;
|
376
|
+
IncrementLexemeCount(iname);
|
377
|
+
if (ins->garbage == 0)
|
378
|
+
{
|
379
|
+
if (InstanceData(theEnv)->MkInsMsgPass)
|
380
|
+
DirectMessage(theEnv,MessageHandlerData(theEnv)->DELETE_SYMBOL,ins,NULL,NULL);
|
381
|
+
else
|
382
|
+
QuashInstance(theEnv,ins);
|
383
|
+
}
|
384
|
+
ins->busy--;
|
385
|
+
ReleaseLexeme(theEnv,iname);
|
386
|
+
if (ins->garbage == 0)
|
387
|
+
{
|
388
|
+
PrintErrorID(theEnv,"INSMNGR",5,false);
|
389
|
+
WriteString(theEnv,STDERR,"Unable to delete old instance [");
|
390
|
+
WriteString(theEnv,STDERR,iname->contents);
|
391
|
+
WriteString(theEnv,STDERR,"].\n");
|
392
|
+
SetEvaluationError(theEnv,true);
|
393
|
+
InstanceData(theEnv)->makeInstanceError = MIE_COULD_NOT_CREATE_ERROR;
|
394
|
+
return NULL;
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
/* =============================================================
|
399
|
+
Create the base instance from the defaults of the inheritance
|
400
|
+
precedence list
|
401
|
+
============================================================= */
|
402
|
+
InstanceData(theEnv)->CurrentInstance = NewInstance(theEnv);
|
403
|
+
|
404
|
+
#if DEFRULE_CONSTRUCT
|
405
|
+
/* ==============================================
|
406
|
+
Add this new instance as a dependent to
|
407
|
+
any currently active basis - if the partial
|
408
|
+
match was deleted, abort the instance creation
|
409
|
+
============================================== */
|
410
|
+
if (AddLogicalDependencies(theEnv,(struct patternEntity *) InstanceData(theEnv)->CurrentInstance,false)
|
411
|
+
== false)
|
412
|
+
{
|
413
|
+
rtn_struct(theEnv,instance,InstanceData(theEnv)->CurrentInstance);
|
414
|
+
InstanceData(theEnv)->CurrentInstance = NULL;
|
415
|
+
return NULL;
|
416
|
+
}
|
417
|
+
#endif
|
418
|
+
|
419
|
+
InstanceData(theEnv)->CurrentInstance->name = iname;
|
420
|
+
InstanceData(theEnv)->CurrentInstance->cls = cls;
|
421
|
+
BuildDefaultSlots(theEnv,initMessage);
|
422
|
+
|
423
|
+
/* ============================================================
|
424
|
+
Put the instance in the instance hash table and put it on its
|
425
|
+
class's instance list
|
426
|
+
============================================================ */
|
427
|
+
InstanceData(theEnv)->CurrentInstance->hashTableIndex = hashTableIndex;
|
428
|
+
if (iprv == NULL)
|
429
|
+
{
|
430
|
+
InstanceData(theEnv)->CurrentInstance->nxtHash = InstanceData(theEnv)->InstanceTable[hashTableIndex];
|
431
|
+
if (InstanceData(theEnv)->InstanceTable[hashTableIndex] != NULL)
|
432
|
+
InstanceData(theEnv)->InstanceTable[hashTableIndex]->prvHash = InstanceData(theEnv)->CurrentInstance;
|
433
|
+
InstanceData(theEnv)->InstanceTable[hashTableIndex] = InstanceData(theEnv)->CurrentInstance;
|
434
|
+
}
|
435
|
+
else
|
436
|
+
{
|
437
|
+
InstanceData(theEnv)->CurrentInstance->nxtHash = iprv->nxtHash;
|
438
|
+
if (iprv->nxtHash != NULL)
|
439
|
+
iprv->nxtHash->prvHash = InstanceData(theEnv)->CurrentInstance;
|
440
|
+
iprv->nxtHash = InstanceData(theEnv)->CurrentInstance;
|
441
|
+
InstanceData(theEnv)->CurrentInstance->prvHash = iprv;
|
442
|
+
}
|
443
|
+
|
444
|
+
/* ======================================
|
445
|
+
Put instance in global and class lists
|
446
|
+
====================================== */
|
447
|
+
if (InstanceData(theEnv)->CurrentInstance->cls->instanceList == NULL)
|
448
|
+
InstanceData(theEnv)->CurrentInstance->cls->instanceList = InstanceData(theEnv)->CurrentInstance;
|
449
|
+
else
|
450
|
+
InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom->nxtClass = InstanceData(theEnv)->CurrentInstance;
|
451
|
+
InstanceData(theEnv)->CurrentInstance->prvClass = InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom;
|
452
|
+
InstanceData(theEnv)->CurrentInstance->cls->instanceListBottom = InstanceData(theEnv)->CurrentInstance;
|
453
|
+
|
454
|
+
if (InstanceData(theEnv)->InstanceList == NULL)
|
455
|
+
InstanceData(theEnv)->InstanceList = InstanceData(theEnv)->CurrentInstance;
|
456
|
+
else
|
457
|
+
InstanceData(theEnv)->InstanceListBottom->nxtList = InstanceData(theEnv)->CurrentInstance;
|
458
|
+
InstanceData(theEnv)->CurrentInstance->prvList = InstanceData(theEnv)->InstanceListBottom;
|
459
|
+
InstanceData(theEnv)->InstanceListBottom = InstanceData(theEnv)->CurrentInstance;
|
460
|
+
InstanceData(theEnv)->ChangesToInstances = true;
|
461
|
+
|
462
|
+
/* ==============================================================================
|
463
|
+
Install the instance's name and slot-value symbols (prevent them from becoming
|
464
|
+
ephemeral) - the class name and slot names are accounted for by the class
|
465
|
+
============================================================================== */
|
466
|
+
InstallInstance(theEnv,InstanceData(theEnv)->CurrentInstance,true);
|
467
|
+
|
468
|
+
ins = InstanceData(theEnv)->CurrentInstance;
|
469
|
+
InstanceData(theEnv)->CurrentInstance = NULL;
|
470
|
+
|
471
|
+
if (InstanceData(theEnv)->MkInsMsgPass)
|
472
|
+
{ DirectMessage(theEnv,MessageHandlerData(theEnv)->CREATE_SYMBOL,ins,&temp,NULL); }
|
473
|
+
|
474
|
+
#if DEFRULE_CONSTRUCT
|
475
|
+
if (ins->cls->reactive)
|
476
|
+
ObjectNetworkAction(theEnv,OBJECT_ASSERT,ins,-1);
|
477
|
+
#endif
|
478
|
+
|
479
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
480
|
+
{ InstanceData(theEnv)->makeInstanceError = MIE_RULE_NETWORK_ERROR; }
|
481
|
+
else
|
482
|
+
{ InstanceData(theEnv)->makeInstanceError = MIE_NO_ERROR; }
|
483
|
+
|
484
|
+
return ins;
|
485
|
+
}
|
486
|
+
|
487
|
+
/*****************************************************************************
|
488
|
+
NAME : InitSlotsCommand
|
489
|
+
DESCRIPTION : Calls Kernel Expression Evaluator EvaluateExpression
|
490
|
+
for each expression-value of an instance expression
|
491
|
+
|
492
|
+
Evaluates default slots only - slots that were specified
|
493
|
+
by overrides (sp->override == 1) are ignored)
|
494
|
+
INPUTS : 1) Instance address
|
495
|
+
RETURNS : Nothing useful
|
496
|
+
SIDE EFFECTS : Each UDFValue slot in the instance's slot array is replaced
|
497
|
+
by the evaluation (by EvaluateExpression) of the expression
|
498
|
+
in the slot list. The old expression-values
|
499
|
+
are deleted.
|
500
|
+
NOTES : H/L Syntax: (init-slots <instance>)
|
501
|
+
*****************************************************************************/
|
502
|
+
void InitSlotsCommand(
|
503
|
+
Environment *theEnv,
|
504
|
+
UDFContext *context,
|
505
|
+
UDFValue *returnValue)
|
506
|
+
{
|
507
|
+
EvaluationData(theEnv)->EvaluationError = false;
|
508
|
+
|
509
|
+
if (CheckCurrentMessage(theEnv,"init-slots",true) == false)
|
510
|
+
{
|
511
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
512
|
+
return;
|
513
|
+
}
|
514
|
+
|
515
|
+
EvaluateClassDefaults(theEnv,GetActiveInstance(theEnv));
|
516
|
+
|
517
|
+
if (! EvaluationData(theEnv)->EvaluationError)
|
518
|
+
{ returnValue->instanceValue = GetActiveInstance(theEnv); }
|
519
|
+
else
|
520
|
+
{ returnValue->lexemeValue = FalseSymbol(theEnv); }
|
521
|
+
}
|
522
|
+
|
523
|
+
/******************************************************
|
524
|
+
NAME : QuashInstance
|
525
|
+
DESCRIPTION : Deletes an instance if it is not in
|
526
|
+
use, otherwise sticks it on the
|
527
|
+
garbage list
|
528
|
+
INPUTS : The instance
|
529
|
+
RETURNS : 1 if successful, 0 otherwise
|
530
|
+
SIDE EFFECTS : Instance deleted or added to garbage
|
531
|
+
NOTES : Even though the instance is removed
|
532
|
+
from the class list, hash table and
|
533
|
+
instance list, its links remain
|
534
|
+
unchanged so that outside loops
|
535
|
+
can still determine where the next
|
536
|
+
node in the list is (assuming the
|
537
|
+
instance was garbage collected).
|
538
|
+
******************************************************/
|
539
|
+
UnmakeInstanceError QuashInstance(
|
540
|
+
Environment *theEnv,
|
541
|
+
Instance *ins)
|
542
|
+
{
|
543
|
+
int iflag;
|
544
|
+
IGARBAGE *gptr;
|
545
|
+
|
546
|
+
#if DEFRULE_CONSTRUCT
|
547
|
+
int syncFlag;
|
548
|
+
|
549
|
+
if (EngineData(theEnv)->JoinOperationInProgress && ins->cls->reactive)
|
550
|
+
{
|
551
|
+
PrintErrorID(theEnv,"INSMNGR",12,false);
|
552
|
+
WriteString(theEnv,STDERR,"Cannot delete instances of reactive classes while ");
|
553
|
+
WriteString(theEnv,STDERR,"pattern-matching is in process.\n");
|
554
|
+
SetEvaluationError(theEnv,true);
|
555
|
+
InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
|
556
|
+
return UIE_COULD_NOT_DELETE_ERROR;
|
557
|
+
}
|
558
|
+
#endif
|
559
|
+
|
560
|
+
if (ins->garbage == 1)
|
561
|
+
{
|
562
|
+
InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
|
563
|
+
return UIE_DELETED_ERROR;
|
564
|
+
}
|
565
|
+
|
566
|
+
if (ins->installed == 0)
|
567
|
+
{
|
568
|
+
PrintErrorID(theEnv,"INSMNGR",6,false);
|
569
|
+
WriteString(theEnv,STDERR,"Cannot delete instance [");
|
570
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
571
|
+
WriteString(theEnv,STDERR,"] during initialization.\n");
|
572
|
+
SetEvaluationError(theEnv,true);
|
573
|
+
InstanceData(theEnv)->unmakeInstanceError = UIE_COULD_NOT_DELETE_ERROR;
|
574
|
+
return UIE_COULD_NOT_DELETE_ERROR;
|
575
|
+
}
|
576
|
+
|
577
|
+
#if DEBUGGING_FUNCTIONS
|
578
|
+
if (ins->cls->traceInstances)
|
579
|
+
PrintInstanceWatch(theEnv,UNMAKE_TRACE,ins);
|
580
|
+
#endif
|
581
|
+
|
582
|
+
#if DEFRULE_CONSTRUCT
|
583
|
+
syncFlag = ins->reteSynchronized;
|
584
|
+
RemoveEntityDependencies(theEnv,(struct patternEntity *) ins);
|
585
|
+
|
586
|
+
if (ins->cls->reactive)
|
587
|
+
{
|
588
|
+
ins->garbage = 1;
|
589
|
+
ObjectNetworkAction(theEnv,OBJECT_RETRACT,ins,-1);
|
590
|
+
ins->garbage = 0;
|
591
|
+
}
|
592
|
+
#endif
|
593
|
+
|
594
|
+
if (ins->prvHash != NULL)
|
595
|
+
ins->prvHash->nxtHash = ins->nxtHash;
|
596
|
+
else
|
597
|
+
InstanceData(theEnv)->InstanceTable[ins->hashTableIndex] = ins->nxtHash;
|
598
|
+
if (ins->nxtHash != NULL)
|
599
|
+
ins->nxtHash->prvHash = ins->prvHash;
|
600
|
+
|
601
|
+
if (ins->prvClass != NULL)
|
602
|
+
ins->prvClass->nxtClass = ins->nxtClass;
|
603
|
+
else
|
604
|
+
ins->cls->instanceList = ins->nxtClass;
|
605
|
+
if (ins->nxtClass != NULL)
|
606
|
+
ins->nxtClass->prvClass = ins->prvClass;
|
607
|
+
else
|
608
|
+
ins->cls->instanceListBottom = ins->prvClass;
|
609
|
+
|
610
|
+
if (ins->prvList != NULL)
|
611
|
+
ins->prvList->nxtList = ins->nxtList;
|
612
|
+
else
|
613
|
+
InstanceData(theEnv)->InstanceList = ins->nxtList;
|
614
|
+
if (ins->nxtList != NULL)
|
615
|
+
ins->nxtList->prvList = ins->prvList;
|
616
|
+
else
|
617
|
+
InstanceData(theEnv)->InstanceListBottom = ins->prvList;
|
618
|
+
|
619
|
+
iflag = ins->installed;
|
620
|
+
InstallInstance(theEnv,ins,false);
|
621
|
+
|
622
|
+
/* ==============================================
|
623
|
+
If the instance is the basis for an executing
|
624
|
+
rule, don't bother deleting its slots yet, for
|
625
|
+
they may still be needed by pattern variables
|
626
|
+
============================================== */
|
627
|
+
|
628
|
+
#if DEFRULE_CONSTRUCT
|
629
|
+
if ((iflag == 1) && (ins->patternHeader.busyCount == 0))
|
630
|
+
{
|
631
|
+
if ((ObjectReteData(theEnv)->DelayObjectPatternMatching == false) ||
|
632
|
+
(syncFlag == false))
|
633
|
+
{ RemoveInstanceData(theEnv,ins); }
|
634
|
+
else
|
635
|
+
{ ins->dataRemovalDeferred = true; }
|
636
|
+
}
|
637
|
+
#else
|
638
|
+
if (iflag == 1)
|
639
|
+
{ RemoveInstanceData(theEnv,ins); }
|
640
|
+
#endif
|
641
|
+
|
642
|
+
if ((ins->busy == 0) &&
|
643
|
+
(InstanceData(theEnv)->MaintainGarbageInstances == false)
|
644
|
+
#if DEFRULE_CONSTRUCT
|
645
|
+
&& (ins->patternHeader.busyCount == 0)
|
646
|
+
#endif
|
647
|
+
)
|
648
|
+
{
|
649
|
+
ReleaseLexeme(theEnv,ins->name);
|
650
|
+
rtn_struct(theEnv,instance,ins);
|
651
|
+
}
|
652
|
+
else
|
653
|
+
{
|
654
|
+
gptr = get_struct(theEnv,igarbage);
|
655
|
+
ins->garbage = 1;
|
656
|
+
gptr->ins = ins;
|
657
|
+
gptr->nxt = InstanceData(theEnv)->InstanceGarbageList;
|
658
|
+
InstanceData(theEnv)->InstanceGarbageList = gptr;
|
659
|
+
UtilityData(theEnv)->CurrentGarbageFrame->dirty = true;
|
660
|
+
}
|
661
|
+
|
662
|
+
InstanceData(theEnv)->ChangesToInstances = true;
|
663
|
+
|
664
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
665
|
+
{
|
666
|
+
InstanceData(theEnv)->unmakeInstanceError = UIE_RULE_NETWORK_ERROR;
|
667
|
+
return UIE_RULE_NETWORK_ERROR;
|
668
|
+
}
|
669
|
+
|
670
|
+
InstanceData(theEnv)->unmakeInstanceError = UIE_NO_ERROR;
|
671
|
+
return UIE_NO_ERROR;
|
672
|
+
}
|
673
|
+
|
674
|
+
|
675
|
+
#if DEFRULE_CONSTRUCT
|
676
|
+
|
677
|
+
/****************************************************
|
678
|
+
NAME : InactiveInitializeInstance
|
679
|
+
DESCRIPTION : Initializes an instance of a class
|
680
|
+
Pattern-matching is automatically
|
681
|
+
delayed until the instance is
|
682
|
+
completely initialized
|
683
|
+
INPUTS : The address of the result value
|
684
|
+
RETURNS : Nothing useful
|
685
|
+
SIDE EFFECTS : Instance intialized
|
686
|
+
NOTES : H/L Syntax:
|
687
|
+
(initialize-instance <instance-name>
|
688
|
+
<slot-override>*)
|
689
|
+
****************************************************/
|
690
|
+
void InactiveInitializeInstance(
|
691
|
+
Environment *theEnv,
|
692
|
+
UDFContext *context,
|
693
|
+
UDFValue *returnValue)
|
694
|
+
{
|
695
|
+
bool ov;
|
696
|
+
|
697
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
698
|
+
InitializeInstanceCommand(theEnv,context,returnValue);
|
699
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
700
|
+
}
|
701
|
+
|
702
|
+
/**************************************************************
|
703
|
+
NAME : InactiveMakeInstance
|
704
|
+
DESCRIPTION : Creates and initializes an instance of a class
|
705
|
+
Pattern-matching is automatically
|
706
|
+
delayed until the instance is
|
707
|
+
completely initialized
|
708
|
+
INPUTS : The address of the result value
|
709
|
+
RETURNS : Nothing useful
|
710
|
+
SIDE EFFECTS : Instance intialized
|
711
|
+
NOTES : H/L Syntax:
|
712
|
+
(make-instance <instance-name> of <class>
|
713
|
+
<slot-override>*)
|
714
|
+
**************************************************************/
|
715
|
+
void InactiveMakeInstance(
|
716
|
+
Environment *theEnv,
|
717
|
+
UDFContext *context,
|
718
|
+
UDFValue *returnValue)
|
719
|
+
{
|
720
|
+
bool ov;
|
721
|
+
|
722
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
723
|
+
MakeInstanceCommand(theEnv,context,returnValue);
|
724
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
725
|
+
}
|
726
|
+
|
727
|
+
#endif
|
728
|
+
|
729
|
+
/* =========================================
|
730
|
+
*****************************************
|
731
|
+
INTERNALLY VISIBLE FUNCTIONS
|
732
|
+
=========================================
|
733
|
+
***************************************** */
|
734
|
+
|
735
|
+
/********************************************************
|
736
|
+
NAME : NewInstance
|
737
|
+
DESCRIPTION : Allocates and initializes a new instance
|
738
|
+
INPUTS : None
|
739
|
+
RETURNS : The address of the new instance
|
740
|
+
SIDE EFFECTS : None
|
741
|
+
NOTES : None
|
742
|
+
********************************************************/
|
743
|
+
static Instance *NewInstance(
|
744
|
+
Environment *theEnv)
|
745
|
+
{
|
746
|
+
Instance *instance;
|
747
|
+
|
748
|
+
instance = get_struct(theEnv,instance);
|
749
|
+
#if DEFRULE_CONSTRUCT
|
750
|
+
instance->patternHeader.theInfo = &InstanceData(theEnv)->InstanceInfo;
|
751
|
+
|
752
|
+
instance->patternHeader.dependents = NULL;
|
753
|
+
instance->patternHeader.busyCount = 0;
|
754
|
+
instance->patternHeader.timeTag = 0L;
|
755
|
+
|
756
|
+
instance->partialMatchList = NULL;
|
757
|
+
instance->basisSlots = NULL;
|
758
|
+
instance->reteSynchronized = false;
|
759
|
+
instance->dataRemovalDeferred = false;
|
760
|
+
#endif
|
761
|
+
instance->patternHeader.header.type = INSTANCE_ADDRESS_TYPE;
|
762
|
+
instance->busy = 0;
|
763
|
+
instance->installed = 0;
|
764
|
+
instance->garbage = 0;
|
765
|
+
instance->initSlotsCalled = 0;
|
766
|
+
instance->initializeInProgress = 0;
|
767
|
+
instance->name = NULL;
|
768
|
+
instance->hashTableIndex = 0;
|
769
|
+
instance->cls = NULL;
|
770
|
+
instance->slots = NULL;
|
771
|
+
instance->slotAddresses = NULL;
|
772
|
+
instance->prvClass = NULL;
|
773
|
+
instance->nxtClass = NULL;
|
774
|
+
instance->prvHash = NULL;
|
775
|
+
instance->nxtHash = NULL;
|
776
|
+
instance->prvList = NULL;
|
777
|
+
instance->nxtList = NULL;
|
778
|
+
return(instance);
|
779
|
+
}
|
780
|
+
|
781
|
+
/*****************************************************************
|
782
|
+
NAME : InstanceLocationInfo
|
783
|
+
DESCRIPTION : Determines where a specified instance belongs
|
784
|
+
in the instance hash table
|
785
|
+
INPUTS : 1) The class of the new instance
|
786
|
+
2) The symbol for the name of the instance
|
787
|
+
3) Caller's buffer for previous node address
|
788
|
+
4) Caller's buffer for hash value
|
789
|
+
RETURNS : The address of the found instance, NULL otherwise
|
790
|
+
SIDE EFFECTS : None
|
791
|
+
NOTES : Instance names only have to be unique within
|
792
|
+
a module.
|
793
|
+
Change: instance names must be unique regardless
|
794
|
+
of module.
|
795
|
+
*****************************************************************/
|
796
|
+
static Instance *InstanceLocationInfo(
|
797
|
+
Environment *theEnv,
|
798
|
+
Defclass *cls,
|
799
|
+
CLIPSLexeme *iname,
|
800
|
+
Instance **prv,
|
801
|
+
unsigned *hashTableIndex)
|
802
|
+
{
|
803
|
+
Instance *ins;
|
804
|
+
|
805
|
+
*hashTableIndex = HashInstance(iname);
|
806
|
+
ins = InstanceData(theEnv)->InstanceTable[*hashTableIndex];
|
807
|
+
|
808
|
+
/* ========================================
|
809
|
+
Make sure all instances of the same name
|
810
|
+
are grouped together regardless of what
|
811
|
+
module their classes are in
|
812
|
+
======================================== */
|
813
|
+
*prv = NULL;
|
814
|
+
while (ins != NULL)
|
815
|
+
{
|
816
|
+
if (ins->name == iname)
|
817
|
+
{ return(ins); }
|
818
|
+
*prv = ins;
|
819
|
+
ins = ins->nxtHash;
|
820
|
+
}
|
821
|
+
|
822
|
+
/*
|
823
|
+
while ((ins != NULL) ? (ins->name != iname) : false)
|
824
|
+
{
|
825
|
+
*prv = ins;
|
826
|
+
ins = ins->nxtHash;
|
827
|
+
}
|
828
|
+
while ((ins != NULL) ? (ins->name == iname) : false)
|
829
|
+
{
|
830
|
+
if (ins->cls->header.whichModule->theModule ==
|
831
|
+
cls->header.whichModule->theModule)
|
832
|
+
return(ins);
|
833
|
+
*prv = ins;
|
834
|
+
ins = ins->nxtHash;
|
835
|
+
}
|
836
|
+
*/
|
837
|
+
return NULL;
|
838
|
+
}
|
839
|
+
|
840
|
+
/********************************************************
|
841
|
+
NAME : InstallInstance
|
842
|
+
DESCRIPTION : Prevent name and slot value symbols
|
843
|
+
from being ephemeral (all others
|
844
|
+
taken care of by class defn)
|
845
|
+
INPUTS : 1) The address of the instance
|
846
|
+
2) A flag indicating whether to
|
847
|
+
install or deinstall
|
848
|
+
RETURNS : Nothing useful
|
849
|
+
SIDE EFFECTS : Symbol counts incremented or decremented
|
850
|
+
NOTES : Slot symbol installations are handled
|
851
|
+
by PutSlotValue
|
852
|
+
********************************************************/
|
853
|
+
static void InstallInstance(
|
854
|
+
Environment *theEnv,
|
855
|
+
Instance *ins,
|
856
|
+
bool set)
|
857
|
+
{
|
858
|
+
if (set == true)
|
859
|
+
{
|
860
|
+
if (ins->installed)
|
861
|
+
return;
|
862
|
+
#if DEBUGGING_FUNCTIONS
|
863
|
+
if (ins->cls->traceInstances)
|
864
|
+
PrintInstanceWatch(theEnv,MAKE_TRACE,ins);
|
865
|
+
#endif
|
866
|
+
ins->installed = 1;
|
867
|
+
IncrementLexemeCount(ins->name);
|
868
|
+
IncrementDefclassBusyCount(theEnv,ins->cls);
|
869
|
+
InstanceData(theEnv)->GlobalNumberOfInstances++;
|
870
|
+
}
|
871
|
+
else
|
872
|
+
{
|
873
|
+
if (! ins->installed)
|
874
|
+
return;
|
875
|
+
ins->installed = 0;
|
876
|
+
InstanceData(theEnv)->GlobalNumberOfInstances--;
|
877
|
+
|
878
|
+
/* =======================================
|
879
|
+
Class counts is decremented by
|
880
|
+
RemoveInstanceData() when slot data is
|
881
|
+
truly deleted - and name count is
|
882
|
+
deleted by CleanupInstances() or
|
883
|
+
QuashInstance() when instance is
|
884
|
+
truly deleted
|
885
|
+
======================================= */
|
886
|
+
}
|
887
|
+
}
|
888
|
+
|
889
|
+
/****************************************************************
|
890
|
+
NAME : BuildDefaultSlots
|
891
|
+
DESCRIPTION : The current instance's address is
|
892
|
+
in the global variable CurrentInstance.
|
893
|
+
This builds the slots and the default values
|
894
|
+
from the direct class of the instance and its
|
895
|
+
inheritances.
|
896
|
+
INPUTS : Flag indicating whether init message will be
|
897
|
+
called for this instance or not
|
898
|
+
RETURNS : Nothing useful
|
899
|
+
SIDE EFFECTS : Allocates the slot array for
|
900
|
+
the current instance
|
901
|
+
NOTES : The current instance's address is
|
902
|
+
stored in a global variable
|
903
|
+
****************************************************************/
|
904
|
+
static void BuildDefaultSlots(
|
905
|
+
Environment *theEnv,
|
906
|
+
bool initMessage)
|
907
|
+
{
|
908
|
+
unsigned i,j;
|
909
|
+
unsigned scnt;
|
910
|
+
unsigned lscnt;
|
911
|
+
InstanceSlot *dst = NULL,**adst;
|
912
|
+
SlotDescriptor **src;
|
913
|
+
|
914
|
+
scnt = InstanceData(theEnv)->CurrentInstance->cls->instanceSlotCount;
|
915
|
+
lscnt = InstanceData(theEnv)->CurrentInstance->cls->localInstanceSlotCount;
|
916
|
+
if (scnt > 0)
|
917
|
+
{
|
918
|
+
InstanceData(theEnv)->CurrentInstance->slotAddresses = adst =
|
919
|
+
(InstanceSlot **) gm2(theEnv,(sizeof(InstanceSlot *) * scnt));
|
920
|
+
if (lscnt != 0)
|
921
|
+
InstanceData(theEnv)->CurrentInstance->slots = dst =
|
922
|
+
(InstanceSlot *) gm2(theEnv,(sizeof(InstanceSlot) * lscnt));
|
923
|
+
src = InstanceData(theEnv)->CurrentInstance->cls->instanceTemplate;
|
924
|
+
|
925
|
+
/* ==================================================
|
926
|
+
A map of slot addresses is created - shared slots
|
927
|
+
point at values in the class, and local slots
|
928
|
+
point at values in the instance
|
929
|
+
|
930
|
+
Also - slots are always given an initial value
|
931
|
+
(since slots cannot be unbound). If there is
|
932
|
+
already an instance of a class with a shared slot,
|
933
|
+
that value is left alone
|
934
|
+
================================================== */
|
935
|
+
for (i = 0 , j = 0 ; i < scnt ; i++)
|
936
|
+
{
|
937
|
+
if (src[i]->shared)
|
938
|
+
{
|
939
|
+
src[i]->sharedCount++;
|
940
|
+
adst[i] = &(src[i]->sharedValue);
|
941
|
+
}
|
942
|
+
else
|
943
|
+
{
|
944
|
+
dst[j].desc = src[i];
|
945
|
+
dst[j].value = NULL;
|
946
|
+
adst[i] = &dst[j++];
|
947
|
+
}
|
948
|
+
if (adst[i]->value == NULL)
|
949
|
+
{
|
950
|
+
adst[i]->valueRequired = initMessage;
|
951
|
+
if (adst[i]->desc->multiple)
|
952
|
+
{
|
953
|
+
adst[i]->type = MULTIFIELD_TYPE;
|
954
|
+
adst[i]->value = CreateUnmanagedMultifield(theEnv,0L);
|
955
|
+
RetainMultifield(theEnv,adst[i]->multifieldValue);
|
956
|
+
}
|
957
|
+
else
|
958
|
+
{
|
959
|
+
adst[i]->type = SYMBOL_TYPE;
|
960
|
+
adst[i]->value = CreateSymbol(theEnv,"nil");
|
961
|
+
AtomInstall(theEnv,adst[i]->type,adst[i]->value);
|
962
|
+
}
|
963
|
+
}
|
964
|
+
else
|
965
|
+
adst[i]->valueRequired = false;
|
966
|
+
adst[i]->override = false;
|
967
|
+
}
|
968
|
+
}
|
969
|
+
}
|
970
|
+
|
971
|
+
/*******************************************************************
|
972
|
+
NAME : CoreInitializeInstance
|
973
|
+
DESCRIPTION : Performs the core work for initializing an instance
|
974
|
+
INPUTS : 1) The instance address
|
975
|
+
2) Slot override expressions
|
976
|
+
RETURNS : True if all OK, false otherwise
|
977
|
+
SIDE EFFECTS : EvaluationError set on errors - slots evaluated
|
978
|
+
NOTES : None
|
979
|
+
*******************************************************************/
|
980
|
+
static bool CoreInitializeInstance(
|
981
|
+
Environment *theEnv,
|
982
|
+
Instance *ins,
|
983
|
+
Expression *ovrexp)
|
984
|
+
{
|
985
|
+
UDFValue temp;
|
986
|
+
|
987
|
+
if (ins->installed == 0)
|
988
|
+
{
|
989
|
+
PrintErrorID(theEnv,"INSMNGR",7,false);
|
990
|
+
WriteString(theEnv,STDERR,"Instance [");
|
991
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
992
|
+
WriteString(theEnv,STDERR,"] is already being initialized.\n");
|
993
|
+
SetEvaluationError(theEnv,true);
|
994
|
+
return false;
|
995
|
+
}
|
996
|
+
|
997
|
+
/* =======================================================
|
998
|
+
Replace all default-slot values with any slot-overrides
|
999
|
+
======================================================= */
|
1000
|
+
ins->busy++;
|
1001
|
+
ins->installed = 0;
|
1002
|
+
|
1003
|
+
/* =================================================================
|
1004
|
+
If the slots are initialized properly - the initializeInProgress
|
1005
|
+
flag will be turned off.
|
1006
|
+
================================================================= */
|
1007
|
+
ins->initializeInProgress = 1;
|
1008
|
+
ins->initSlotsCalled = 0;
|
1009
|
+
|
1010
|
+
if (InsertSlotOverrides(theEnv,ins,ovrexp) == false)
|
1011
|
+
{
|
1012
|
+
ins->installed = 1;
|
1013
|
+
ins->busy--;
|
1014
|
+
return false;
|
1015
|
+
}
|
1016
|
+
|
1017
|
+
/* =================================================================
|
1018
|
+
Now that all the slot expressions are established - replace them
|
1019
|
+
with their evaluation
|
1020
|
+
================================================================= */
|
1021
|
+
|
1022
|
+
if (InstanceData(theEnv)->MkInsMsgPass)
|
1023
|
+
DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,ins,&temp,NULL);
|
1024
|
+
else
|
1025
|
+
EvaluateClassDefaults(theEnv,ins);
|
1026
|
+
|
1027
|
+
ins->busy--;
|
1028
|
+
ins->installed = 1;
|
1029
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1030
|
+
{
|
1031
|
+
PrintErrorID(theEnv,"INSMNGR",8,false);
|
1032
|
+
WriteString(theEnv,STDERR,"An error occurred during the initialization of instance [");
|
1033
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1034
|
+
WriteString(theEnv,STDERR,"].\n");
|
1035
|
+
return false;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
ins->initializeInProgress = 0;
|
1039
|
+
return (ins->initSlotsCalled == 0) ? false : true;
|
1040
|
+
}
|
1041
|
+
|
1042
|
+
/*******************************************************************
|
1043
|
+
NAME : CoreInitializeInstanceCV
|
1044
|
+
DESCRIPTION : Performs the core work for initializing an instance
|
1045
|
+
INPUTS : 1) The instance address
|
1046
|
+
2) Slot override CLIPSValues
|
1047
|
+
RETURNS : True if all OK, false otherwise
|
1048
|
+
SIDE EFFECTS : EvaluationError set on errors - slots evaluated
|
1049
|
+
NOTES : None
|
1050
|
+
*******************************************************************/
|
1051
|
+
static bool CoreInitializeInstanceCV(
|
1052
|
+
Environment *theEnv,
|
1053
|
+
Instance *ins,
|
1054
|
+
CLIPSValue *overrides)
|
1055
|
+
{
|
1056
|
+
UDFValue temp;
|
1057
|
+
|
1058
|
+
if (ins->installed == 0)
|
1059
|
+
{
|
1060
|
+
PrintErrorID(theEnv,"INSMNGR",7,false);
|
1061
|
+
WriteString(theEnv,STDERR,"Instance ");
|
1062
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1063
|
+
WriteString(theEnv,STDERR," is already being initialized.\n");
|
1064
|
+
SetEvaluationError(theEnv,true);
|
1065
|
+
return false;
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
/*==========================================================*/
|
1069
|
+
/* Replace all default-slot values with any slot-overrides. */
|
1070
|
+
/*==========================================================*/
|
1071
|
+
|
1072
|
+
ins->busy++;
|
1073
|
+
ins->installed = 0;
|
1074
|
+
|
1075
|
+
/*===============================================*/
|
1076
|
+
/* If the slots are initialized properly - the */
|
1077
|
+
/* initializeInProgress flag will be turned off. */
|
1078
|
+
/*===============================================*/
|
1079
|
+
|
1080
|
+
ins->initializeInProgress = 1;
|
1081
|
+
ins->initSlotsCalled = 0;
|
1082
|
+
|
1083
|
+
if (InsertSlotOverridesCV(theEnv,ins,overrides) == false)
|
1084
|
+
{
|
1085
|
+
ins->installed = 1;
|
1086
|
+
ins->busy--;
|
1087
|
+
return false;
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
/*====================================================*/
|
1091
|
+
/* Now that all the slot expressions are established, */
|
1092
|
+
/* replace them with their evaluation. */
|
1093
|
+
/*====================================================*/
|
1094
|
+
|
1095
|
+
if (InstanceData(theEnv)->MkInsMsgPass)
|
1096
|
+
{ DirectMessage(theEnv,MessageHandlerData(theEnv)->INIT_SYMBOL,ins,&temp,NULL); }
|
1097
|
+
else
|
1098
|
+
{ EvaluateClassDefaults(theEnv,ins); }
|
1099
|
+
|
1100
|
+
ins->busy--;
|
1101
|
+
ins->installed = 1;
|
1102
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1103
|
+
{
|
1104
|
+
PrintErrorID(theEnv,"INSMNGR",8,false);
|
1105
|
+
WriteString(theEnv,STDERR,"An error occurred during the initialization of instance [");
|
1106
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1107
|
+
WriteString(theEnv,STDERR,"].\n");
|
1108
|
+
return false;
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
ins->initializeInProgress = 0;
|
1112
|
+
return (ins->initSlotsCalled == 0) ? false : true;
|
1113
|
+
}
|
1114
|
+
|
1115
|
+
/**********************************************************
|
1116
|
+
NAME : InsertSlotOverrides
|
1117
|
+
DESCRIPTION : Replaces value-expression for a slot
|
1118
|
+
INPUTS : 1) The instance address
|
1119
|
+
2) The address of the beginning of the
|
1120
|
+
list of slot-expressions
|
1121
|
+
RETURNS : True if all okay, false otherwise
|
1122
|
+
SIDE EFFECTS : Old slot expression deallocated
|
1123
|
+
NOTES : Assumes symbols not yet installed
|
1124
|
+
EVALUATES the slot-name expression but
|
1125
|
+
simply copies the slot value-expression
|
1126
|
+
**********************************************************/
|
1127
|
+
static bool InsertSlotOverrides(
|
1128
|
+
Environment *theEnv,
|
1129
|
+
Instance *ins,
|
1130
|
+
Expression *slot_exp)
|
1131
|
+
{
|
1132
|
+
InstanceSlot *slot;
|
1133
|
+
UDFValue temp, junk;
|
1134
|
+
|
1135
|
+
EvaluationData(theEnv)->EvaluationError = false;
|
1136
|
+
while (slot_exp != NULL)
|
1137
|
+
{
|
1138
|
+
if ((EvaluateExpression(theEnv,slot_exp,&temp) == true) ? true :
|
1139
|
+
(temp.header->type != SYMBOL_TYPE))
|
1140
|
+
{
|
1141
|
+
PrintErrorID(theEnv,"INSMNGR",9,false);
|
1142
|
+
WriteString(theEnv,STDERR,"Expected a valid slot name for slot-override.\n");
|
1143
|
+
SetEvaluationError(theEnv,true);
|
1144
|
+
return false;
|
1145
|
+
}
|
1146
|
+
slot = FindInstanceSlot(theEnv,ins,temp.lexemeValue);
|
1147
|
+
if (slot == NULL)
|
1148
|
+
{
|
1149
|
+
PrintErrorID(theEnv,"INSMNGR",13,false);
|
1150
|
+
WriteString(theEnv,STDERR,"Slot '");
|
1151
|
+
WriteString(theEnv,STDERR,temp.lexemeValue->contents);
|
1152
|
+
WriteString(theEnv,STDERR,"' does not exist in instance [");
|
1153
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1154
|
+
WriteString(theEnv,STDERR,"].\n");
|
1155
|
+
SetEvaluationError(theEnv,true);
|
1156
|
+
return false;
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
if (InstanceData(theEnv)->MkInsMsgPass)
|
1160
|
+
{ DirectMessage(theEnv,slot->desc->overrideMessage,
|
1161
|
+
ins,NULL,slot_exp->nextArg->argList); }
|
1162
|
+
else if (slot_exp->nextArg->argList)
|
1163
|
+
{
|
1164
|
+
if (EvaluateAndStoreInDataObject(theEnv,slot->desc->multiple,
|
1165
|
+
slot_exp->nextArg->argList,&temp,true))
|
1166
|
+
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
|
1167
|
+
}
|
1168
|
+
else
|
1169
|
+
{
|
1170
|
+
temp.begin = 0;
|
1171
|
+
temp.range = 0;
|
1172
|
+
temp.value = ProceduralPrimitiveData(theEnv)->NoParamValue;
|
1173
|
+
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function make-instance");
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1177
|
+
return false;
|
1178
|
+
slot->override = true;
|
1179
|
+
slot_exp = slot_exp->nextArg->nextArg;
|
1180
|
+
}
|
1181
|
+
return true;
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
/**********************************************************
|
1185
|
+
NAME : InsertSlotOverridesCV
|
1186
|
+
DESCRIPTION : Replaces value-expression for a slot
|
1187
|
+
INPUTS : 1) The instance address
|
1188
|
+
2) The address of the beginning of the
|
1189
|
+
list of slot-expressions
|
1190
|
+
RETURNS : True if all okay, false otherwise
|
1191
|
+
SIDE EFFECTS : Old slot expression deallocated
|
1192
|
+
NOTES : Assumes symbols not yet installed
|
1193
|
+
EVALUATES the slot-name expression but
|
1194
|
+
simply copies the slot value-expression
|
1195
|
+
**********************************************************/
|
1196
|
+
static bool InsertSlotOverridesCV(
|
1197
|
+
Environment *theEnv,
|
1198
|
+
Instance *ins,
|
1199
|
+
CLIPSValue *overrides)
|
1200
|
+
{
|
1201
|
+
unsigned int i;
|
1202
|
+
InstanceSlot *slot;
|
1203
|
+
UDFValue temp, junk;
|
1204
|
+
|
1205
|
+
EvaluationData(theEnv)->EvaluationError = false;
|
1206
|
+
|
1207
|
+
for (i = 0; i < ins->cls->instanceSlotCount; i++)
|
1208
|
+
{
|
1209
|
+
if (overrides[i].value == VoidConstant(theEnv)) continue;
|
1210
|
+
|
1211
|
+
slot = ins->slotAddresses[i];
|
1212
|
+
CLIPSToUDFValue(&overrides[i],&temp);
|
1213
|
+
PutSlotValue(theEnv,ins,slot,&temp,&junk,"InstanceBuilder call");
|
1214
|
+
|
1215
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1216
|
+
{ return false; }
|
1217
|
+
|
1218
|
+
slot->override = true;
|
1219
|
+
}
|
1220
|
+
|
1221
|
+
return true;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
/*****************************************************************************
|
1225
|
+
NAME : EvaluateClassDefaults
|
1226
|
+
DESCRIPTION : Evaluates default slots only - slots that were specified
|
1227
|
+
by overrides (sp->override == 1) are ignored)
|
1228
|
+
INPUTS : 1) Instance address
|
1229
|
+
RETURNS : Nothing useful
|
1230
|
+
SIDE EFFECTS : Each UDFValue slot in the instance's slot array is replaced
|
1231
|
+
by the evaluation (by EvaluateExpression) of the expression
|
1232
|
+
in the slot list. The old expression-values
|
1233
|
+
are deleted.
|
1234
|
+
NOTES : None
|
1235
|
+
*****************************************************************************/
|
1236
|
+
static void EvaluateClassDefaults(
|
1237
|
+
Environment *theEnv,
|
1238
|
+
Instance *ins)
|
1239
|
+
{
|
1240
|
+
InstanceSlot *slot;
|
1241
|
+
UDFValue temp,junk;
|
1242
|
+
unsigned long i;
|
1243
|
+
|
1244
|
+
if (ins->initializeInProgress == 0)
|
1245
|
+
{
|
1246
|
+
PrintErrorID(theEnv,"INSMNGR",15,false);
|
1247
|
+
SetEvaluationError(theEnv,true);
|
1248
|
+
WriteString(theEnv,STDERR,"init-slots not valid in this context.\n");
|
1249
|
+
return;
|
1250
|
+
}
|
1251
|
+
for (i = 0 ; i < ins->cls->instanceSlotCount ; i++)
|
1252
|
+
{
|
1253
|
+
slot = ins->slotAddresses[i];
|
1254
|
+
|
1255
|
+
/* ===========================================================
|
1256
|
+
Slot-overrides are just a short-hand for put-slots, so they
|
1257
|
+
should be done with messages. Defaults are from the class
|
1258
|
+
definition and can be placed directly.
|
1259
|
+
=========================================================== */
|
1260
|
+
if (!slot->override)
|
1261
|
+
{
|
1262
|
+
if (slot->desc->dynamicDefault)
|
1263
|
+
{
|
1264
|
+
if (EvaluateAndStoreInDataObject(theEnv,slot->desc->multiple,
|
1265
|
+
(Expression *) slot->desc->defaultValue,
|
1266
|
+
&temp,true))
|
1267
|
+
PutSlotValue(theEnv,ins,slot,&temp,&junk,"function init-slots");
|
1268
|
+
}
|
1269
|
+
else if (((slot->desc->shared == 0) || (slot->desc->sharedCount == 1)) &&
|
1270
|
+
(slot->desc->noDefault == 0))
|
1271
|
+
DirectPutSlotValue(theEnv,ins,slot,(UDFValue *) slot->desc->defaultValue,&junk);
|
1272
|
+
else if (slot->valueRequired)
|
1273
|
+
{
|
1274
|
+
PrintErrorID(theEnv,"INSMNGR",14,false);
|
1275
|
+
WriteString(theEnv,STDERR,"Override required for slot '");
|
1276
|
+
WriteString(theEnv,STDERR,slot->desc->slotName->name->contents);
|
1277
|
+
WriteString(theEnv,STDERR,"' in instance [");
|
1278
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1279
|
+
WriteString(theEnv,STDERR,"].\n");
|
1280
|
+
SetEvaluationError(theEnv,true);
|
1281
|
+
}
|
1282
|
+
slot->valueRequired = false;
|
1283
|
+
if (ins->garbage == 1)
|
1284
|
+
{
|
1285
|
+
WriteString(theEnv,STDERR,ins->name->contents);
|
1286
|
+
WriteString(theEnv,STDERR," instance deleted by slot-override evaluation.\n");
|
1287
|
+
SetEvaluationError(theEnv,true);
|
1288
|
+
}
|
1289
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1290
|
+
return;
|
1291
|
+
}
|
1292
|
+
slot->override = false;
|
1293
|
+
}
|
1294
|
+
ins->initSlotsCalled = 1;
|
1295
|
+
}
|
1296
|
+
|
1297
|
+
#if DEBUGGING_FUNCTIONS
|
1298
|
+
|
1299
|
+
/***************************************************
|
1300
|
+
NAME : PrintInstanceWatch
|
1301
|
+
DESCRIPTION : Prints out a trace message for the
|
1302
|
+
creation/deletion of an instance
|
1303
|
+
INPUTS : 1) The trace string indicating if
|
1304
|
+
this is a creation or deletion
|
1305
|
+
2) The instance
|
1306
|
+
RETURNS : Nothing usful
|
1307
|
+
SIDE EFFECTS : Watch message printed
|
1308
|
+
NOTES : None
|
1309
|
+
***************************************************/
|
1310
|
+
static void PrintInstanceWatch(
|
1311
|
+
Environment *theEnv,
|
1312
|
+
const char *traceString,
|
1313
|
+
Instance *theInstance)
|
1314
|
+
{
|
1315
|
+
if (ConstructData(theEnv)->ClearReadyInProgress ||
|
1316
|
+
ConstructData(theEnv)->ClearInProgress)
|
1317
|
+
{ return; }
|
1318
|
+
|
1319
|
+
WriteString(theEnv,STDOUT,traceString);
|
1320
|
+
WriteString(theEnv,STDOUT," instance ");
|
1321
|
+
PrintInstanceNameAndClass(theEnv,STDOUT,theInstance,true);
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
#endif
|
1325
|
+
|
1326
|
+
/**************************/
|
1327
|
+
/* CreateInstanceBuilder: */
|
1328
|
+
/**************************/
|
1329
|
+
InstanceBuilder *CreateInstanceBuilder(
|
1330
|
+
Environment *theEnv,
|
1331
|
+
const char *defclassName)
|
1332
|
+
{
|
1333
|
+
InstanceBuilder *theIB;
|
1334
|
+
Defclass *theDefclass;
|
1335
|
+
unsigned int i;
|
1336
|
+
|
1337
|
+
if (theEnv == NULL) return NULL;
|
1338
|
+
|
1339
|
+
if (defclassName != NULL)
|
1340
|
+
{
|
1341
|
+
theDefclass = FindDefclass(theEnv,defclassName);
|
1342
|
+
if (theDefclass == NULL)
|
1343
|
+
{
|
1344
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_DEFCLASS_NOT_FOUND_ERROR;
|
1345
|
+
return NULL;
|
1346
|
+
}
|
1347
|
+
}
|
1348
|
+
else
|
1349
|
+
{ theDefclass = NULL; }
|
1350
|
+
|
1351
|
+
theIB = get_struct(theEnv,instanceBuilder);
|
1352
|
+
theIB->ibEnv = theEnv;
|
1353
|
+
theIB->ibDefclass = theDefclass;
|
1354
|
+
|
1355
|
+
if ((theDefclass == NULL) || (theDefclass->instanceSlotCount == 0))
|
1356
|
+
{ theIB->ibValueArray = NULL; }
|
1357
|
+
else
|
1358
|
+
{
|
1359
|
+
theIB->ibValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theDefclass->instanceSlotCount);
|
1360
|
+
|
1361
|
+
for (i = 0; i < theDefclass->instanceSlotCount; i++)
|
1362
|
+
{ theIB->ibValueArray[i].voidValue = VoidConstant(theEnv); }
|
1363
|
+
}
|
1364
|
+
|
1365
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
|
1366
|
+
|
1367
|
+
return theIB;
|
1368
|
+
}
|
1369
|
+
|
1370
|
+
/*************************/
|
1371
|
+
/* IBPutSlotCLIPSInteger */
|
1372
|
+
/*************************/
|
1373
|
+
PutSlotError IBPutSlotCLIPSInteger(
|
1374
|
+
InstanceBuilder *theIB,
|
1375
|
+
const char *slotName,
|
1376
|
+
CLIPSInteger *slotValue)
|
1377
|
+
{
|
1378
|
+
CLIPSValue theValue;
|
1379
|
+
|
1380
|
+
theValue.integerValue = slotValue;
|
1381
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
/********************/
|
1385
|
+
/* IBPutSlotInteger */
|
1386
|
+
/********************/
|
1387
|
+
PutSlotError IBPutSlotInteger(
|
1388
|
+
InstanceBuilder *theIB,
|
1389
|
+
const char *slotName,
|
1390
|
+
long long longLongValue)
|
1391
|
+
{
|
1392
|
+
CLIPSValue theValue;
|
1393
|
+
|
1394
|
+
if (theIB == NULL)
|
1395
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1396
|
+
|
1397
|
+
theValue.integerValue = CreateInteger(theIB->ibEnv,longLongValue);
|
1398
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1399
|
+
}
|
1400
|
+
|
1401
|
+
/************************/
|
1402
|
+
/* IBPutSlotCLIPSLexeme */
|
1403
|
+
/************************/
|
1404
|
+
PutSlotError IBPutSlotCLIPSLexeme(
|
1405
|
+
InstanceBuilder *theIB,
|
1406
|
+
const char *slotName,
|
1407
|
+
CLIPSLexeme *slotValue)
|
1408
|
+
{
|
1409
|
+
CLIPSValue theValue;
|
1410
|
+
|
1411
|
+
theValue.lexemeValue = slotValue;
|
1412
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1413
|
+
}
|
1414
|
+
|
1415
|
+
/*******************/
|
1416
|
+
/* IBPutSlotSymbol */
|
1417
|
+
/*******************/
|
1418
|
+
PutSlotError IBPutSlotSymbol(
|
1419
|
+
InstanceBuilder *theIB,
|
1420
|
+
const char *slotName,
|
1421
|
+
const char *stringValue)
|
1422
|
+
{
|
1423
|
+
CLIPSValue theValue;
|
1424
|
+
|
1425
|
+
if (theIB == NULL)
|
1426
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1427
|
+
|
1428
|
+
theValue.lexemeValue = CreateSymbol(theIB->ibEnv,stringValue);
|
1429
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1430
|
+
}
|
1431
|
+
|
1432
|
+
/*******************/
|
1433
|
+
/* IBPutSlotString */
|
1434
|
+
/*******************/
|
1435
|
+
PutSlotError IBPutSlotString(
|
1436
|
+
InstanceBuilder *theIB,
|
1437
|
+
const char *slotName,
|
1438
|
+
const char *stringValue)
|
1439
|
+
{
|
1440
|
+
CLIPSValue theValue;
|
1441
|
+
|
1442
|
+
if (theIB == NULL)
|
1443
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1444
|
+
|
1445
|
+
theValue.lexemeValue = CreateString(theIB->ibEnv,stringValue);
|
1446
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
/*************************/
|
1450
|
+
/* IBPutSlotInstanceName */
|
1451
|
+
/*************************/
|
1452
|
+
PutSlotError IBPutSlotInstanceName(
|
1453
|
+
InstanceBuilder *theIB,
|
1454
|
+
const char *slotName,
|
1455
|
+
const char *stringValue)
|
1456
|
+
{
|
1457
|
+
CLIPSValue theValue;
|
1458
|
+
|
1459
|
+
if (theIB == NULL)
|
1460
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1461
|
+
|
1462
|
+
theValue.lexemeValue = CreateInstanceName(theIB->ibEnv,stringValue);
|
1463
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
/***********************/
|
1467
|
+
/* IBPutSlotCLIPSFloat */
|
1468
|
+
/***********************/
|
1469
|
+
PutSlotError IBPutSlotCLIPSFloat(
|
1470
|
+
InstanceBuilder *theIB,
|
1471
|
+
const char *slotName,
|
1472
|
+
CLIPSFloat *slotValue)
|
1473
|
+
{
|
1474
|
+
CLIPSValue theValue;
|
1475
|
+
|
1476
|
+
theValue.floatValue = slotValue;
|
1477
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
/******************/
|
1481
|
+
/* IBPutSlotFloat */
|
1482
|
+
/******************/
|
1483
|
+
PutSlotError IBPutSlotFloat(
|
1484
|
+
InstanceBuilder *theIB,
|
1485
|
+
const char *slotName,
|
1486
|
+
double doubleValue)
|
1487
|
+
{
|
1488
|
+
CLIPSValue theValue;
|
1489
|
+
|
1490
|
+
if (theIB == NULL)
|
1491
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1492
|
+
|
1493
|
+
theValue.floatValue = CreateFloat(theIB->ibEnv,doubleValue);
|
1494
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1495
|
+
}
|
1496
|
+
|
1497
|
+
/*****************/
|
1498
|
+
/* IBPutSlotFact */
|
1499
|
+
/*****************/
|
1500
|
+
PutSlotError IBPutSlotFact(
|
1501
|
+
InstanceBuilder *theIB,
|
1502
|
+
const char *slotName,
|
1503
|
+
Fact *slotValue)
|
1504
|
+
{
|
1505
|
+
CLIPSValue theValue;
|
1506
|
+
|
1507
|
+
theValue.factValue = slotValue;
|
1508
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
/*********************/
|
1512
|
+
/* IBPutSlotInstance */
|
1513
|
+
/*********************/
|
1514
|
+
PutSlotError IBPutSlotInstance(
|
1515
|
+
InstanceBuilder *theIB,
|
1516
|
+
const char *slotName,
|
1517
|
+
Instance *slotValue)
|
1518
|
+
{
|
1519
|
+
CLIPSValue theValue;
|
1520
|
+
|
1521
|
+
theValue.instanceValue = slotValue;
|
1522
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
/****************************/
|
1526
|
+
/* IBPutSlotExternalAddress */
|
1527
|
+
/****************************/
|
1528
|
+
PutSlotError IBPutSlotExternalAddress(
|
1529
|
+
InstanceBuilder *theIB,
|
1530
|
+
const char *slotName,
|
1531
|
+
CLIPSExternalAddress *slotValue)
|
1532
|
+
{
|
1533
|
+
CLIPSValue theValue;
|
1534
|
+
|
1535
|
+
theValue.externalAddressValue = slotValue;
|
1536
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
/***********************/
|
1540
|
+
/* IBPutSlotMultifield */
|
1541
|
+
/***********************/
|
1542
|
+
PutSlotError IBPutSlotMultifield(
|
1543
|
+
InstanceBuilder *theIB,
|
1544
|
+
const char *slotName,
|
1545
|
+
Multifield *slotValue)
|
1546
|
+
{
|
1547
|
+
CLIPSValue theValue;
|
1548
|
+
|
1549
|
+
theValue.multifieldValue = slotValue;
|
1550
|
+
return IBPutSlot(theIB,slotName,&theValue);
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
/**************/
|
1554
|
+
/* IBPutSlot: */
|
1555
|
+
/**************/
|
1556
|
+
PutSlotError IBPutSlot(
|
1557
|
+
InstanceBuilder *theIB,
|
1558
|
+
const char *slotName,
|
1559
|
+
CLIPSValue *slotValue)
|
1560
|
+
{
|
1561
|
+
Environment *theEnv;
|
1562
|
+
int whichSlot;
|
1563
|
+
CLIPSValue oldValue;
|
1564
|
+
unsigned int i;
|
1565
|
+
SlotDescriptor *theSlot;
|
1566
|
+
ConstraintViolationType cvType;
|
1567
|
+
|
1568
|
+
/*==========================*/
|
1569
|
+
/* Check for NULL pointers. */
|
1570
|
+
/*==========================*/
|
1571
|
+
|
1572
|
+
if ((theIB == NULL) || (slotName == NULL) || (slotValue == NULL))
|
1573
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1574
|
+
|
1575
|
+
if ((theIB->ibDefclass == NULL) || (slotValue->value == NULL))
|
1576
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1577
|
+
|
1578
|
+
theEnv = theIB->ibEnv;
|
1579
|
+
|
1580
|
+
/*===================================*/
|
1581
|
+
/* Make sure the slot name requested */
|
1582
|
+
/* corresponds to a valid slot name. */
|
1583
|
+
/*===================================*/
|
1584
|
+
|
1585
|
+
whichSlot = FindInstanceTemplateSlot(theEnv,theIB->ibDefclass,CreateSymbol(theIB->ibEnv,slotName));
|
1586
|
+
if (whichSlot == -1)
|
1587
|
+
{ return PSE_SLOT_NOT_FOUND_ERROR; }
|
1588
|
+
theSlot = theIB->ibDefclass->instanceTemplate[whichSlot];
|
1589
|
+
|
1590
|
+
/*=============================================*/
|
1591
|
+
/* Make sure a single field value is not being */
|
1592
|
+
/* stored in a multifield slot or vice versa. */
|
1593
|
+
/*=============================================*/
|
1594
|
+
|
1595
|
+
if (((theSlot->multiple == 0) && (slotValue->header->type == MULTIFIELD_TYPE)) ||
|
1596
|
+
((theSlot->multiple == 1) && (slotValue->header->type != MULTIFIELD_TYPE)))
|
1597
|
+
{ return PSE_CARDINALITY_ERROR; }
|
1598
|
+
|
1599
|
+
/*=================================*/
|
1600
|
+
/* Check constraints for the slot. */
|
1601
|
+
/*=================================*/
|
1602
|
+
|
1603
|
+
if (theSlot->constraint != NULL)
|
1604
|
+
{
|
1605
|
+
if ((cvType = ConstraintCheckValue(theEnv,slotValue->header->type,slotValue->value,theSlot->constraint)) != NO_VIOLATION)
|
1606
|
+
{
|
1607
|
+
switch(cvType)
|
1608
|
+
{
|
1609
|
+
case NO_VIOLATION:
|
1610
|
+
case FUNCTION_RETURN_TYPE_VIOLATION:
|
1611
|
+
SystemError(theEnv,"INSMNGR",1);
|
1612
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
1613
|
+
break;
|
1614
|
+
|
1615
|
+
case TYPE_VIOLATION:
|
1616
|
+
return PSE_TYPE_ERROR;
|
1617
|
+
|
1618
|
+
case RANGE_VIOLATION:
|
1619
|
+
return PSE_RANGE_ERROR;
|
1620
|
+
|
1621
|
+
case ALLOWED_VALUES_VIOLATION:
|
1622
|
+
return PSE_ALLOWED_VALUES_ERROR;
|
1623
|
+
|
1624
|
+
case CARDINALITY_VIOLATION:
|
1625
|
+
return PSE_CARDINALITY_ERROR;
|
1626
|
+
|
1627
|
+
case ALLOWED_CLASSES_VIOLATION:
|
1628
|
+
return PSE_ALLOWED_CLASSES_ERROR;
|
1629
|
+
}
|
1630
|
+
}
|
1631
|
+
}
|
1632
|
+
|
1633
|
+
/*===================================*/
|
1634
|
+
/* Create the value array if needed. */
|
1635
|
+
/*===================================*/
|
1636
|
+
|
1637
|
+
if (theIB->ibValueArray == NULL)
|
1638
|
+
{
|
1639
|
+
theIB->ibValueArray = (CLIPSValue *) gm2(theIB->ibEnv,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount);
|
1640
|
+
for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
|
1641
|
+
{ theIB->ibValueArray[i].voidValue = theIB->ibEnv->VoidConstant; }
|
1642
|
+
}
|
1643
|
+
|
1644
|
+
/*=====================*/
|
1645
|
+
/* Set the slot value. */
|
1646
|
+
/*=====================*/
|
1647
|
+
|
1648
|
+
oldValue.value = theIB->ibValueArray[whichSlot].value;
|
1649
|
+
|
1650
|
+
if (oldValue.header->type == MULTIFIELD_TYPE)
|
1651
|
+
{
|
1652
|
+
if (MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
|
1653
|
+
{ return PSE_NO_ERROR; }
|
1654
|
+
}
|
1655
|
+
else
|
1656
|
+
{
|
1657
|
+
if (oldValue.value == slotValue->value)
|
1658
|
+
{ return PSE_NO_ERROR; }
|
1659
|
+
}
|
1660
|
+
|
1661
|
+
Release(theEnv,oldValue.header);
|
1662
|
+
|
1663
|
+
if (oldValue.header->type == MULTIFIELD_TYPE)
|
1664
|
+
{ ReturnMultifield(theEnv,oldValue.multifieldValue); }
|
1665
|
+
|
1666
|
+
if (slotValue->header->type == MULTIFIELD_TYPE)
|
1667
|
+
{ theIB->ibValueArray[whichSlot].multifieldValue = CopyMultifield(theEnv,slotValue->multifieldValue); }
|
1668
|
+
else
|
1669
|
+
{ theIB->ibValueArray[whichSlot].value = slotValue->value; }
|
1670
|
+
|
1671
|
+
Retain(theEnv,theIB->ibValueArray[whichSlot].header);
|
1672
|
+
|
1673
|
+
return PSE_NO_ERROR;
|
1674
|
+
}
|
1675
|
+
|
1676
|
+
/***********/
|
1677
|
+
/* IBMake: */
|
1678
|
+
/***********/
|
1679
|
+
Instance *IBMake(
|
1680
|
+
InstanceBuilder *theIB,
|
1681
|
+
const char *instanceName)
|
1682
|
+
{
|
1683
|
+
Environment *theEnv;
|
1684
|
+
Instance *theInstance;
|
1685
|
+
CLIPSLexeme *instanceLexeme;
|
1686
|
+
UDFValue rv;
|
1687
|
+
unsigned int i;
|
1688
|
+
#if DEFRULE_CONSTRUCT
|
1689
|
+
bool ov;
|
1690
|
+
#endif
|
1691
|
+
|
1692
|
+
if (theIB == NULL) return NULL;
|
1693
|
+
theEnv = theIB->ibEnv;
|
1694
|
+
|
1695
|
+
if (theIB->ibDefclass == NULL)
|
1696
|
+
{
|
1697
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_NULL_POINTER_ERROR;
|
1698
|
+
return NULL;
|
1699
|
+
}
|
1700
|
+
|
1701
|
+
if (instanceName == NULL)
|
1702
|
+
{
|
1703
|
+
GensymStar(theEnv,&rv);
|
1704
|
+
instanceLexeme = CreateInstanceName(theEnv,rv.lexemeValue->contents);
|
1705
|
+
}
|
1706
|
+
else
|
1707
|
+
{ instanceLexeme = CreateInstanceName(theEnv,instanceName); }
|
1708
|
+
|
1709
|
+
#if DEFRULE_CONSTRUCT
|
1710
|
+
ov = SetDelayObjectPatternMatching(theEnv,true);
|
1711
|
+
#endif
|
1712
|
+
|
1713
|
+
theInstance = BuildInstance(theEnv,instanceLexeme,theIB->ibDefclass,true);
|
1714
|
+
|
1715
|
+
if (theInstance == NULL)
|
1716
|
+
{
|
1717
|
+
if (InstanceData(theEnv)->makeInstanceError == MIE_COULD_NOT_CREATE_ERROR)
|
1718
|
+
{ InstanceData(theEnv)->instanceBuilderError = IBE_COULD_NOT_CREATE_ERROR; }
|
1719
|
+
else if (InstanceData(theEnv)->makeInstanceError == MIE_RULE_NETWORK_ERROR)
|
1720
|
+
{ InstanceData(theEnv)->instanceBuilderError = IBE_RULE_NETWORK_ERROR; }
|
1721
|
+
else
|
1722
|
+
{
|
1723
|
+
SystemError(theEnv,"INSMNGR",3);
|
1724
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
1725
|
+
}
|
1726
|
+
|
1727
|
+
#if DEFRULE_CONSTRUCT
|
1728
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
1729
|
+
#endif
|
1730
|
+
|
1731
|
+
return NULL;
|
1732
|
+
}
|
1733
|
+
|
1734
|
+
if (CoreInitializeInstanceCV(theIB->ibEnv,theInstance,theIB->ibValueArray) == false)
|
1735
|
+
{
|
1736
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_COULD_NOT_CREATE_ERROR;
|
1737
|
+
QuashInstance(theIB->ibEnv,theInstance);
|
1738
|
+
#if DEFRULE_CONSTRUCT
|
1739
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
1740
|
+
#endif
|
1741
|
+
return NULL;
|
1742
|
+
}
|
1743
|
+
|
1744
|
+
#if DEFRULE_CONSTRUCT
|
1745
|
+
SetDelayObjectPatternMatching(theEnv,ov);
|
1746
|
+
#endif
|
1747
|
+
|
1748
|
+
for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
|
1749
|
+
{
|
1750
|
+
if (theIB->ibValueArray[i].voidValue != VoidConstant(theEnv))
|
1751
|
+
{
|
1752
|
+
Release(theEnv,theIB->ibValueArray[i].header);
|
1753
|
+
|
1754
|
+
if (theIB->ibValueArray[i].header->type == MULTIFIELD_TYPE)
|
1755
|
+
{ ReturnMultifield(theEnv,theIB->ibValueArray[i].multifieldValue); }
|
1756
|
+
|
1757
|
+
theIB->ibValueArray[i].voidValue = VoidConstant(theEnv);
|
1758
|
+
}
|
1759
|
+
}
|
1760
|
+
|
1761
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
|
1762
|
+
|
1763
|
+
return theInstance;
|
1764
|
+
}
|
1765
|
+
|
1766
|
+
/**************/
|
1767
|
+
/* IBDispose: */
|
1768
|
+
/**************/
|
1769
|
+
void IBDispose(
|
1770
|
+
InstanceBuilder *theIB)
|
1771
|
+
{
|
1772
|
+
Environment *theEnv;
|
1773
|
+
|
1774
|
+
if (theIB == NULL) return;
|
1775
|
+
|
1776
|
+
theEnv = theIB->ibEnv;
|
1777
|
+
|
1778
|
+
IBAbort(theIB);
|
1779
|
+
|
1780
|
+
if (theIB->ibValueArray != NULL)
|
1781
|
+
{ rm(theEnv,theIB->ibValueArray,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount); }
|
1782
|
+
|
1783
|
+
rtn_struct(theEnv,instanceBuilder,theIB);
|
1784
|
+
}
|
1785
|
+
|
1786
|
+
/************/
|
1787
|
+
/* IBAbort: */
|
1788
|
+
/************/
|
1789
|
+
void IBAbort(
|
1790
|
+
InstanceBuilder *theIB)
|
1791
|
+
{
|
1792
|
+
Environment *theEnv;
|
1793
|
+
unsigned int i;
|
1794
|
+
|
1795
|
+
if (theIB == NULL) return;
|
1796
|
+
|
1797
|
+
if (theIB->ibDefclass == NULL) return;
|
1798
|
+
|
1799
|
+
theEnv = theIB->ibEnv;
|
1800
|
+
|
1801
|
+
for (i = 0; i < theIB->ibDefclass->instanceSlotCount; i++)
|
1802
|
+
{
|
1803
|
+
Release(theEnv,theIB->ibValueArray[i].header);
|
1804
|
+
|
1805
|
+
if (theIB->ibValueArray[i].header->type == MULTIFIELD_TYPE)
|
1806
|
+
{ ReturnMultifield(theEnv,theIB->ibValueArray[i].multifieldValue); }
|
1807
|
+
|
1808
|
+
theIB->ibValueArray[i].voidValue = VoidConstant(theEnv);
|
1809
|
+
}
|
1810
|
+
}
|
1811
|
+
|
1812
|
+
/*****************/
|
1813
|
+
/* IBSetDefclass */
|
1814
|
+
/*****************/
|
1815
|
+
InstanceBuilderError IBSetDefclass(
|
1816
|
+
InstanceBuilder *theIB,
|
1817
|
+
const char *defclassName)
|
1818
|
+
{
|
1819
|
+
Defclass *theDefclass;
|
1820
|
+
Environment *theEnv;
|
1821
|
+
unsigned int i;
|
1822
|
+
|
1823
|
+
if (theIB == NULL)
|
1824
|
+
{ return IBE_NULL_POINTER_ERROR; }
|
1825
|
+
|
1826
|
+
theEnv = theIB->ibEnv;
|
1827
|
+
|
1828
|
+
IBAbort(theIB);
|
1829
|
+
|
1830
|
+
if (defclassName != NULL)
|
1831
|
+
{
|
1832
|
+
theDefclass = FindDefclass(theIB->ibEnv,defclassName);
|
1833
|
+
|
1834
|
+
if (theDefclass == NULL)
|
1835
|
+
{
|
1836
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_DEFCLASS_NOT_FOUND_ERROR;
|
1837
|
+
return IBE_DEFCLASS_NOT_FOUND_ERROR;
|
1838
|
+
}
|
1839
|
+
}
|
1840
|
+
else
|
1841
|
+
{ theDefclass = NULL; }
|
1842
|
+
|
1843
|
+
if (theIB->ibValueArray != NULL)
|
1844
|
+
{ rm(theEnv,theIB->ibValueArray,sizeof(CLIPSValue) * theIB->ibDefclass->instanceSlotCount); }
|
1845
|
+
|
1846
|
+
theIB->ibDefclass = theDefclass;
|
1847
|
+
|
1848
|
+
if ((theDefclass == NULL) || (theDefclass->instanceSlotCount == 0))
|
1849
|
+
{ theIB->ibValueArray = NULL; }
|
1850
|
+
else
|
1851
|
+
{
|
1852
|
+
theIB->ibValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * theDefclass->instanceSlotCount);
|
1853
|
+
|
1854
|
+
for (i = 0; i < theDefclass->instanceSlotCount; i++)
|
1855
|
+
{ theIB->ibValueArray[i].voidValue = VoidConstant(theEnv); }
|
1856
|
+
}
|
1857
|
+
|
1858
|
+
InstanceData(theEnv)->instanceBuilderError = IBE_NO_ERROR;
|
1859
|
+
return IBE_NO_ERROR;
|
1860
|
+
}
|
1861
|
+
|
1862
|
+
/************/
|
1863
|
+
/* IBError: */
|
1864
|
+
/************/
|
1865
|
+
InstanceBuilderError IBError(
|
1866
|
+
Environment *theEnv)
|
1867
|
+
{
|
1868
|
+
return InstanceData(theEnv)->instanceBuilderError;
|
1869
|
+
}
|
1870
|
+
|
1871
|
+
/***************************/
|
1872
|
+
/* CreateInstanceModifier: */
|
1873
|
+
/***************************/
|
1874
|
+
InstanceModifier *CreateInstanceModifier(
|
1875
|
+
Environment *theEnv,
|
1876
|
+
Instance *oldInstance)
|
1877
|
+
{
|
1878
|
+
InstanceModifier *theIM;
|
1879
|
+
unsigned int i;
|
1880
|
+
|
1881
|
+
if (theEnv == NULL) return NULL;
|
1882
|
+
|
1883
|
+
if (oldInstance != NULL)
|
1884
|
+
{
|
1885
|
+
if (oldInstance->garbage)
|
1886
|
+
{
|
1887
|
+
InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
|
1888
|
+
return NULL;
|
1889
|
+
}
|
1890
|
+
|
1891
|
+
RetainInstance(oldInstance);
|
1892
|
+
}
|
1893
|
+
|
1894
|
+
theIM = get_struct(theEnv,instanceModifier);
|
1895
|
+
theIM->imEnv = theEnv;
|
1896
|
+
theIM->imOldInstance = oldInstance;
|
1897
|
+
|
1898
|
+
if ((oldInstance == NULL) || (oldInstance->cls->instanceSlotCount == 0))
|
1899
|
+
{
|
1900
|
+
theIM->imValueArray = NULL;
|
1901
|
+
theIM->changeMap = NULL;
|
1902
|
+
}
|
1903
|
+
else
|
1904
|
+
{
|
1905
|
+
unsigned short slotCount = oldInstance->cls->instanceSlotCount;
|
1906
|
+
|
1907
|
+
theIM->imValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * slotCount);
|
1908
|
+
|
1909
|
+
for (i = 0; i < slotCount; i++)
|
1910
|
+
{ theIM->imValueArray[i].voidValue = VoidConstant(theEnv); }
|
1911
|
+
|
1912
|
+
theIM->changeMap = (char *) gm2(theEnv,CountToBitMapSize(slotCount));
|
1913
|
+
ClearBitString((void *) theIM->changeMap,CountToBitMapSize(slotCount));
|
1914
|
+
}
|
1915
|
+
|
1916
|
+
InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR;
|
1917
|
+
return theIM;
|
1918
|
+
}
|
1919
|
+
|
1920
|
+
/*************************/
|
1921
|
+
/* IMPutSlotCLIPSInteger */
|
1922
|
+
/*************************/
|
1923
|
+
PutSlotError IMPutSlotCLIPSInteger(
|
1924
|
+
InstanceModifier *theFM,
|
1925
|
+
const char *slotName,
|
1926
|
+
CLIPSInteger *slotValue)
|
1927
|
+
{
|
1928
|
+
CLIPSValue theValue;
|
1929
|
+
|
1930
|
+
theValue.integerValue = slotValue;
|
1931
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
1932
|
+
}
|
1933
|
+
|
1934
|
+
/********************/
|
1935
|
+
/* IMPutSlotInteger */
|
1936
|
+
/********************/
|
1937
|
+
PutSlotError IMPutSlotInteger(
|
1938
|
+
InstanceModifier *theIM,
|
1939
|
+
const char *slotName,
|
1940
|
+
long long longLongValue)
|
1941
|
+
{
|
1942
|
+
CLIPSValue theValue;
|
1943
|
+
|
1944
|
+
if (theIM == NULL)
|
1945
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1946
|
+
|
1947
|
+
theValue.integerValue = CreateInteger(theIM->imEnv,longLongValue);
|
1948
|
+
return IMPutSlot(theIM,slotName,&theValue);
|
1949
|
+
}
|
1950
|
+
|
1951
|
+
/************************/
|
1952
|
+
/* IMPutSlotCLIPSLexeme */
|
1953
|
+
/************************/
|
1954
|
+
PutSlotError IMPutSlotCLIPSLexeme(
|
1955
|
+
InstanceModifier *theFM,
|
1956
|
+
const char *slotName,
|
1957
|
+
CLIPSLexeme *slotValue)
|
1958
|
+
{
|
1959
|
+
CLIPSValue theValue;
|
1960
|
+
|
1961
|
+
theValue.lexemeValue = slotValue;
|
1962
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
1963
|
+
}
|
1964
|
+
|
1965
|
+
/*******************/
|
1966
|
+
/* IMPutSlotSymbol */
|
1967
|
+
/*******************/
|
1968
|
+
PutSlotError IMPutSlotSymbol(
|
1969
|
+
InstanceModifier *theIM,
|
1970
|
+
const char *slotName,
|
1971
|
+
const char *stringValue)
|
1972
|
+
{
|
1973
|
+
CLIPSValue theValue;
|
1974
|
+
|
1975
|
+
if (theIM == NULL)
|
1976
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1977
|
+
|
1978
|
+
theValue.lexemeValue = CreateSymbol(theIM->imEnv,stringValue);
|
1979
|
+
return IMPutSlot(theIM,slotName,&theValue);
|
1980
|
+
}
|
1981
|
+
|
1982
|
+
/*******************/
|
1983
|
+
/* IMPutSlotString */
|
1984
|
+
/*******************/
|
1985
|
+
PutSlotError IMPutSlotString(
|
1986
|
+
InstanceModifier *theIM,
|
1987
|
+
const char *slotName,
|
1988
|
+
const char *stringValue)
|
1989
|
+
{
|
1990
|
+
CLIPSValue theValue;
|
1991
|
+
|
1992
|
+
if (theIM == NULL)
|
1993
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
1994
|
+
|
1995
|
+
theValue.lexemeValue = CreateString(theIM->imEnv,stringValue);
|
1996
|
+
return IMPutSlot(theIM,slotName,&theValue);
|
1997
|
+
}
|
1998
|
+
|
1999
|
+
/*************************/
|
2000
|
+
/* IMPutSlotInstanceName */
|
2001
|
+
/*************************/
|
2002
|
+
PutSlotError IMPutSlotInstanceName(
|
2003
|
+
InstanceModifier *theIM,
|
2004
|
+
const char *slotName,
|
2005
|
+
const char *stringValue)
|
2006
|
+
{
|
2007
|
+
CLIPSValue theValue;
|
2008
|
+
|
2009
|
+
if (theIM == NULL)
|
2010
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
2011
|
+
|
2012
|
+
theValue.lexemeValue = CreateInstanceName(theIM->imEnv,stringValue);
|
2013
|
+
return IMPutSlot(theIM,slotName,&theValue);
|
2014
|
+
}
|
2015
|
+
|
2016
|
+
/***********************/
|
2017
|
+
/* IMPutSlotCLIPSFloat */
|
2018
|
+
/***********************/
|
2019
|
+
PutSlotError IMPutSlotCLIPSFloat(
|
2020
|
+
InstanceModifier *theFM,
|
2021
|
+
const char *slotName,
|
2022
|
+
CLIPSFloat *slotValue)
|
2023
|
+
{
|
2024
|
+
CLIPSValue theValue;
|
2025
|
+
|
2026
|
+
theValue.floatValue = slotValue;
|
2027
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
2028
|
+
}
|
2029
|
+
|
2030
|
+
/******************/
|
2031
|
+
/* IMPutSlotFloat */
|
2032
|
+
/******************/
|
2033
|
+
PutSlotError IMPutSlotFloat(
|
2034
|
+
InstanceModifier *theIM,
|
2035
|
+
const char *slotName,
|
2036
|
+
double doubleValue)
|
2037
|
+
{
|
2038
|
+
CLIPSValue theValue;
|
2039
|
+
|
2040
|
+
if (theIM == NULL)
|
2041
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
2042
|
+
|
2043
|
+
theValue.floatValue = CreateFloat(theIM->imEnv,doubleValue);
|
2044
|
+
return IMPutSlot(theIM,slotName,&theValue);
|
2045
|
+
}
|
2046
|
+
|
2047
|
+
/*****************/
|
2048
|
+
/* IMPutSlotFact */
|
2049
|
+
/*****************/
|
2050
|
+
PutSlotError IMPutSlotFact(
|
2051
|
+
InstanceModifier *theFM,
|
2052
|
+
const char *slotName,
|
2053
|
+
Fact *slotValue)
|
2054
|
+
{
|
2055
|
+
CLIPSValue theValue;
|
2056
|
+
|
2057
|
+
theValue.factValue = slotValue;
|
2058
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
2059
|
+
}
|
2060
|
+
|
2061
|
+
/*********************/
|
2062
|
+
/* IMPutSlotInstance */
|
2063
|
+
/*********************/
|
2064
|
+
PutSlotError IMPutSlotInstance(
|
2065
|
+
InstanceModifier *theFM,
|
2066
|
+
const char *slotName,
|
2067
|
+
Instance *slotValue)
|
2068
|
+
{
|
2069
|
+
CLIPSValue theValue;
|
2070
|
+
|
2071
|
+
theValue.instanceValue = slotValue;
|
2072
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
2073
|
+
}
|
2074
|
+
|
2075
|
+
/****************************/
|
2076
|
+
/* IMPutSlotExternalAddress */
|
2077
|
+
/****************************/
|
2078
|
+
PutSlotError IMPutSlotExternalAddress(
|
2079
|
+
InstanceModifier *theFM,
|
2080
|
+
const char *slotName,
|
2081
|
+
CLIPSExternalAddress *slotValue)
|
2082
|
+
{
|
2083
|
+
CLIPSValue theValue;
|
2084
|
+
|
2085
|
+
theValue.externalAddressValue = slotValue;
|
2086
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
2087
|
+
}
|
2088
|
+
|
2089
|
+
/***********************/
|
2090
|
+
/* IMPutSlotMultifield */
|
2091
|
+
/***********************/
|
2092
|
+
PutSlotError IMPutSlotMultifield(
|
2093
|
+
InstanceModifier *theFM,
|
2094
|
+
const char *slotName,
|
2095
|
+
Multifield *slotValue)
|
2096
|
+
{
|
2097
|
+
CLIPSValue theValue;
|
2098
|
+
|
2099
|
+
theValue.multifieldValue = slotValue;
|
2100
|
+
return IMPutSlot(theFM,slotName,&theValue);
|
2101
|
+
}
|
2102
|
+
|
2103
|
+
/**************/
|
2104
|
+
/* IMPutSlot: */
|
2105
|
+
/**************/
|
2106
|
+
PutSlotError IMPutSlot(
|
2107
|
+
InstanceModifier *theIM,
|
2108
|
+
const char *slotName,
|
2109
|
+
CLIPSValue *slotValue)
|
2110
|
+
{
|
2111
|
+
Environment *theEnv;
|
2112
|
+
int whichSlot;
|
2113
|
+
CLIPSValue oldValue;
|
2114
|
+
CLIPSValue oldInstanceValue;
|
2115
|
+
unsigned int i;
|
2116
|
+
SlotDescriptor *theSlot;
|
2117
|
+
ConstraintViolationType cvType;
|
2118
|
+
|
2119
|
+
/*==========================*/
|
2120
|
+
/* Check for NULL pointers. */
|
2121
|
+
/*==========================*/
|
2122
|
+
|
2123
|
+
if ((theIM == NULL) || (slotName == NULL) || (slotValue == NULL))
|
2124
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
2125
|
+
|
2126
|
+
if ((theIM->imOldInstance == NULL) || (slotValue->value == NULL))
|
2127
|
+
{ return PSE_NULL_POINTER_ERROR; }
|
2128
|
+
|
2129
|
+
theEnv = theIM->imEnv;
|
2130
|
+
|
2131
|
+
/*======================================*/
|
2132
|
+
/* Deleted instances can't be modified. */
|
2133
|
+
/*======================================*/
|
2134
|
+
|
2135
|
+
if (theIM->imOldInstance->garbage)
|
2136
|
+
{ return PSE_INVALID_TARGET_ERROR; }
|
2137
|
+
|
2138
|
+
/*===================================*/
|
2139
|
+
/* Make sure the slot name requested */
|
2140
|
+
/* corresponds to a valid slot name. */
|
2141
|
+
/*===================================*/
|
2142
|
+
|
2143
|
+
whichSlot = FindInstanceTemplateSlot(theEnv,theIM->imOldInstance->cls,CreateSymbol(theIM->imEnv,slotName));
|
2144
|
+
if (whichSlot == -1)
|
2145
|
+
{ return PSE_SLOT_NOT_FOUND_ERROR; }
|
2146
|
+
theSlot = theIM->imOldInstance->cls->instanceTemplate[whichSlot];
|
2147
|
+
|
2148
|
+
/*=============================================*/
|
2149
|
+
/* Make sure a single field value is not being */
|
2150
|
+
/* stored in a multifield slot or vice versa. */
|
2151
|
+
/*=============================================*/
|
2152
|
+
|
2153
|
+
if (((theSlot->multiple == 0) && (slotValue->header->type == MULTIFIELD_TYPE)) ||
|
2154
|
+
((theSlot->multiple == 1) && (slotValue->header->type != MULTIFIELD_TYPE)))
|
2155
|
+
{ return PSE_CARDINALITY_ERROR; }
|
2156
|
+
|
2157
|
+
/*=================================*/
|
2158
|
+
/* Check constraints for the slot. */
|
2159
|
+
/*=================================*/
|
2160
|
+
|
2161
|
+
if (theSlot->constraint != NULL)
|
2162
|
+
{
|
2163
|
+
if ((cvType = ConstraintCheckValue(theEnv,slotValue->header->type,slotValue->value,theSlot->constraint)) != NO_VIOLATION)
|
2164
|
+
{
|
2165
|
+
switch(cvType)
|
2166
|
+
{
|
2167
|
+
case NO_VIOLATION:
|
2168
|
+
case FUNCTION_RETURN_TYPE_VIOLATION:
|
2169
|
+
SystemError(theEnv,"INSMNGR",2);
|
2170
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
2171
|
+
break;
|
2172
|
+
|
2173
|
+
case TYPE_VIOLATION:
|
2174
|
+
return PSE_TYPE_ERROR;
|
2175
|
+
|
2176
|
+
case RANGE_VIOLATION:
|
2177
|
+
return PSE_RANGE_ERROR;
|
2178
|
+
|
2179
|
+
case ALLOWED_VALUES_VIOLATION:
|
2180
|
+
return PSE_ALLOWED_VALUES_ERROR;
|
2181
|
+
|
2182
|
+
case CARDINALITY_VIOLATION:
|
2183
|
+
return PSE_CARDINALITY_ERROR;
|
2184
|
+
|
2185
|
+
case ALLOWED_CLASSES_VIOLATION:
|
2186
|
+
return PSE_ALLOWED_CLASSES_ERROR;
|
2187
|
+
}
|
2188
|
+
}
|
2189
|
+
}
|
2190
|
+
|
2191
|
+
/*===========================*/
|
2192
|
+
/* Set up the change arrays. */
|
2193
|
+
/*===========================*/
|
2194
|
+
|
2195
|
+
if (theIM->imValueArray == NULL)
|
2196
|
+
{
|
2197
|
+
theIM->imValueArray = (CLIPSValue *) gm2(theIM->imEnv,sizeof(CLIPSValue) * theIM->imOldInstance->cls->instanceSlotCount);
|
2198
|
+
for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
|
2199
|
+
{ theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant; }
|
2200
|
+
}
|
2201
|
+
|
2202
|
+
if (theIM->changeMap == NULL)
|
2203
|
+
{
|
2204
|
+
theIM->changeMap = (char *) gm2(theIM->imEnv,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount));
|
2205
|
+
ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount));
|
2206
|
+
}
|
2207
|
+
|
2208
|
+
/*=====================*/
|
2209
|
+
/* Set the slot value. */
|
2210
|
+
/*=====================*/
|
2211
|
+
|
2212
|
+
oldValue.value = theIM->imValueArray[whichSlot].value;
|
2213
|
+
oldInstanceValue.value = theIM->imOldInstance->slotAddresses[whichSlot]->value;
|
2214
|
+
|
2215
|
+
if (oldInstanceValue.header->type == MULTIFIELD_TYPE)
|
2216
|
+
{
|
2217
|
+
if (MultifieldsEqual(oldInstanceValue.multifieldValue,slotValue->multifieldValue))
|
2218
|
+
{
|
2219
|
+
Release(theIM->imEnv,oldValue.header);
|
2220
|
+
if (oldValue.header->type == MULTIFIELD_TYPE)
|
2221
|
+
{ ReturnMultifield(theIM->imEnv,oldValue.multifieldValue); }
|
2222
|
+
theIM->imValueArray[whichSlot].voidValue = theIM->imEnv->VoidConstant;
|
2223
|
+
ClearBitMap(theIM->changeMap,whichSlot);
|
2224
|
+
return PSE_NO_ERROR;
|
2225
|
+
}
|
2226
|
+
|
2227
|
+
if ((oldValue.header->type == MULTIFIELD_TYPE) &&
|
2228
|
+
MultifieldsEqual(oldValue.multifieldValue,slotValue->multifieldValue))
|
2229
|
+
{ return PSE_NO_ERROR; }
|
2230
|
+
}
|
2231
|
+
else
|
2232
|
+
{
|
2233
|
+
if (slotValue->value == oldInstanceValue.value)
|
2234
|
+
{
|
2235
|
+
Release(theIM->imEnv,oldValue.header);
|
2236
|
+
theIM->imValueArray[whichSlot].voidValue = theIM->imEnv->VoidConstant;
|
2237
|
+
ClearBitMap(theIM->changeMap,whichSlot);
|
2238
|
+
return PSE_NO_ERROR;
|
2239
|
+
}
|
2240
|
+
|
2241
|
+
if (oldValue.value == slotValue->value)
|
2242
|
+
{ return PSE_NO_ERROR; }
|
2243
|
+
}
|
2244
|
+
|
2245
|
+
SetBitMap(theIM->changeMap,whichSlot);
|
2246
|
+
|
2247
|
+
Release(theIM->imEnv,oldValue.header);
|
2248
|
+
|
2249
|
+
if (oldValue.header->type == MULTIFIELD_TYPE)
|
2250
|
+
{ ReturnMultifield(theIM->imEnv,oldValue.multifieldValue); }
|
2251
|
+
|
2252
|
+
if (slotValue->header->type == MULTIFIELD_TYPE)
|
2253
|
+
{ theIM->imValueArray[whichSlot].multifieldValue = CopyMultifield(theIM->imEnv,slotValue->multifieldValue); }
|
2254
|
+
else
|
2255
|
+
{ theIM->imValueArray[whichSlot].value = slotValue->value; }
|
2256
|
+
|
2257
|
+
Retain(theIM->imEnv,theIM->imValueArray[whichSlot].header);
|
2258
|
+
|
2259
|
+
return PSE_NO_ERROR;
|
2260
|
+
}
|
2261
|
+
|
2262
|
+
/*************/
|
2263
|
+
/* IMModify: */
|
2264
|
+
/*************/
|
2265
|
+
Instance *IMModify(
|
2266
|
+
InstanceModifier *theIM)
|
2267
|
+
{
|
2268
|
+
Environment *theEnv;
|
2269
|
+
#if DEFRULE_CONSTRUCT
|
2270
|
+
bool ov;
|
2271
|
+
#endif
|
2272
|
+
|
2273
|
+
if (theIM == NULL)
|
2274
|
+
{ return NULL; }
|
2275
|
+
|
2276
|
+
theEnv = theIM->imEnv;
|
2277
|
+
|
2278
|
+
if (theIM->imOldInstance == NULL)
|
2279
|
+
{
|
2280
|
+
InstanceData(theEnv)->instanceModifierError = IME_NULL_POINTER_ERROR;
|
2281
|
+
return NULL;
|
2282
|
+
}
|
2283
|
+
|
2284
|
+
if (theIM->imOldInstance->garbage)
|
2285
|
+
{
|
2286
|
+
InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
|
2287
|
+
return NULL;
|
2288
|
+
}
|
2289
|
+
|
2290
|
+
if (theIM->changeMap == NULL)
|
2291
|
+
{ return theIM->imOldInstance; }
|
2292
|
+
|
2293
|
+
if (! BitStringHasBitsSet(theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)))
|
2294
|
+
{ return theIM->imOldInstance; }
|
2295
|
+
|
2296
|
+
#if DEFRULE_CONSTRUCT
|
2297
|
+
ov = SetDelayObjectPatternMatching(theIM->imEnv,true);
|
2298
|
+
#endif
|
2299
|
+
|
2300
|
+
IMModifySlots(theIM->imEnv,theIM->imOldInstance,theIM->imValueArray);
|
2301
|
+
|
2302
|
+
if ((InstanceData(theEnv)->makeInstanceError == MIE_RULE_NETWORK_ERROR) ||
|
2303
|
+
(InstanceData(theEnv)->unmakeInstanceError == UIE_RULE_NETWORK_ERROR))
|
2304
|
+
{ InstanceData(theEnv)->instanceModifierError = IME_RULE_NETWORK_ERROR; }
|
2305
|
+
else if ((InstanceData(theEnv)->unmakeInstanceError == UIE_COULD_NOT_DELETE_ERROR) ||
|
2306
|
+
(InstanceData(theEnv)->makeInstanceError == MIE_COULD_NOT_CREATE_ERROR))
|
2307
|
+
{ InstanceData(theEnv)->instanceModifierError = IME_COULD_NOT_MODIFY_ERROR; }
|
2308
|
+
else
|
2309
|
+
{ InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR; }
|
2310
|
+
|
2311
|
+
#if DEFRULE_CONSTRUCT
|
2312
|
+
SetDelayObjectPatternMatching(theIM->imEnv,ov);
|
2313
|
+
#endif
|
2314
|
+
|
2315
|
+
IMAbort(theIM);
|
2316
|
+
|
2317
|
+
return theIM->imOldInstance;
|
2318
|
+
}
|
2319
|
+
|
2320
|
+
/*****************/
|
2321
|
+
/* IMModifySlots */
|
2322
|
+
/*****************/
|
2323
|
+
static bool IMModifySlots(
|
2324
|
+
Environment *theEnv,
|
2325
|
+
Instance *theInstance,
|
2326
|
+
CLIPSValue *overrides)
|
2327
|
+
{
|
2328
|
+
UDFValue temp, junk;
|
2329
|
+
InstanceSlot *insSlot;
|
2330
|
+
unsigned int i;
|
2331
|
+
|
2332
|
+
for (i = 0; i < theInstance->cls->instanceSlotCount; i++)
|
2333
|
+
{
|
2334
|
+
if (overrides[i].value == VoidConstant(theEnv))
|
2335
|
+
{ continue; }
|
2336
|
+
|
2337
|
+
insSlot = theInstance->slotAddresses[i];
|
2338
|
+
|
2339
|
+
if (insSlot->desc->multiple && (overrides[i].header->type != MULTIFIELD_TYPE))
|
2340
|
+
{
|
2341
|
+
temp.value = CreateMultifield(theEnv,1L);
|
2342
|
+
temp.begin = 0;
|
2343
|
+
temp.range = 1;
|
2344
|
+
temp.multifieldValue->contents[0].value = overrides[i].value;
|
2345
|
+
}
|
2346
|
+
else
|
2347
|
+
{ CLIPSToUDFValue(&overrides[i],&temp); }
|
2348
|
+
|
2349
|
+
if (PutSlotValue(theEnv,theInstance,insSlot,&temp,&junk,"InstanceModifier call") != PSE_NO_ERROR)
|
2350
|
+
{ return false; }
|
2351
|
+
}
|
2352
|
+
|
2353
|
+
return true;
|
2354
|
+
}
|
2355
|
+
|
2356
|
+
/**************/
|
2357
|
+
/* IMDispose: */
|
2358
|
+
/**************/
|
2359
|
+
void IMDispose(
|
2360
|
+
InstanceModifier *theIM)
|
2361
|
+
{
|
2362
|
+
Environment *theEnv = theIM->imEnv;
|
2363
|
+
unsigned int i;
|
2364
|
+
|
2365
|
+
/*========================*/
|
2366
|
+
/* Clear the value array. */
|
2367
|
+
/*========================*/
|
2368
|
+
|
2369
|
+
if (theIM->imOldInstance != NULL)
|
2370
|
+
{
|
2371
|
+
for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
|
2372
|
+
{
|
2373
|
+
Release(theEnv,theIM->imValueArray[i].header);
|
2374
|
+
|
2375
|
+
if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
|
2376
|
+
{ ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
|
2377
|
+
}
|
2378
|
+
}
|
2379
|
+
|
2380
|
+
/*=====================================*/
|
2381
|
+
/* Return the value and change arrays. */
|
2382
|
+
/*=====================================*/
|
2383
|
+
|
2384
|
+
if (theIM->imValueArray != NULL)
|
2385
|
+
{ rm(theEnv,theIM->imValueArray,sizeof(CLIPSValue) * theIM->imOldInstance->cls->instanceSlotCount); }
|
2386
|
+
|
2387
|
+
if (theIM->changeMap != NULL)
|
2388
|
+
{ rm(theEnv,(void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
|
2389
|
+
|
2390
|
+
/*========================================*/
|
2391
|
+
/* Return the InstanceModifier structure. */
|
2392
|
+
/*========================================*/
|
2393
|
+
|
2394
|
+
ReleaseInstance(theIM->imOldInstance);
|
2395
|
+
|
2396
|
+
rtn_struct(theEnv,instanceModifier,theIM);
|
2397
|
+
}
|
2398
|
+
|
2399
|
+
/************/
|
2400
|
+
/* IMAbort: */
|
2401
|
+
/************/
|
2402
|
+
void IMAbort(
|
2403
|
+
InstanceModifier *theIM)
|
2404
|
+
{
|
2405
|
+
GCBlock gcb;
|
2406
|
+
Environment *theEnv;
|
2407
|
+
unsigned int i;
|
2408
|
+
|
2409
|
+
if (theIM == NULL) return;
|
2410
|
+
|
2411
|
+
if (theIM->imOldInstance == NULL) return;
|
2412
|
+
|
2413
|
+
theEnv = theIM->imEnv;
|
2414
|
+
|
2415
|
+
GCBlockStart(theEnv,&gcb);
|
2416
|
+
|
2417
|
+
for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
|
2418
|
+
{
|
2419
|
+
Release(theEnv,theIM->imValueArray[i].header);
|
2420
|
+
|
2421
|
+
if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
|
2422
|
+
{ ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
|
2423
|
+
|
2424
|
+
theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant;
|
2425
|
+
}
|
2426
|
+
|
2427
|
+
if (theIM->changeMap != NULL)
|
2428
|
+
{ ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
|
2429
|
+
|
2430
|
+
GCBlockEnd(theEnv,&gcb);
|
2431
|
+
}
|
2432
|
+
|
2433
|
+
/******************/
|
2434
|
+
/* IMSetInstance: */
|
2435
|
+
/******************/
|
2436
|
+
InstanceModifierError IMSetInstance(
|
2437
|
+
InstanceModifier *theIM,
|
2438
|
+
Instance *oldInstance)
|
2439
|
+
{
|
2440
|
+
Environment *theEnv;
|
2441
|
+
unsigned int currentSlotCount, newSlotCount;
|
2442
|
+
unsigned int i;
|
2443
|
+
|
2444
|
+
if (theIM == NULL)
|
2445
|
+
{ return IME_NULL_POINTER_ERROR; }
|
2446
|
+
|
2447
|
+
theEnv = theIM->imEnv;
|
2448
|
+
|
2449
|
+
/*=============================================*/
|
2450
|
+
/* Modifiers can only be created for instances */
|
2451
|
+
/* that have not been deleted. */
|
2452
|
+
/*=============================================*/
|
2453
|
+
|
2454
|
+
if (oldInstance != NULL)
|
2455
|
+
{
|
2456
|
+
if (oldInstance->garbage)
|
2457
|
+
{
|
2458
|
+
InstanceData(theEnv)->instanceModifierError = IME_DELETED_ERROR;
|
2459
|
+
return IME_DELETED_ERROR;
|
2460
|
+
}
|
2461
|
+
}
|
2462
|
+
|
2463
|
+
/*========================*/
|
2464
|
+
/* Clear the value array. */
|
2465
|
+
/*========================*/
|
2466
|
+
|
2467
|
+
if (theIM->imValueArray != NULL)
|
2468
|
+
{
|
2469
|
+
for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
|
2470
|
+
{
|
2471
|
+
Release(theEnv,theIM->imValueArray[i].header);
|
2472
|
+
|
2473
|
+
if (theIM->imValueArray[i].header->type == MULTIFIELD_TYPE)
|
2474
|
+
{ ReturnMultifield(theEnv,theIM->imValueArray[i].multifieldValue); }
|
2475
|
+
}
|
2476
|
+
}
|
2477
|
+
|
2478
|
+
/*==================================================*/
|
2479
|
+
/* Resize the value and change arrays if necessary. */
|
2480
|
+
/*==================================================*/
|
2481
|
+
|
2482
|
+
if (theIM->imOldInstance == NULL)
|
2483
|
+
{ currentSlotCount = 0; }
|
2484
|
+
else
|
2485
|
+
{ currentSlotCount = theIM->imOldInstance->cls->instanceSlotCount; }
|
2486
|
+
|
2487
|
+
if (oldInstance == NULL)
|
2488
|
+
{ newSlotCount = 0; }
|
2489
|
+
else
|
2490
|
+
{ newSlotCount = oldInstance->cls->instanceSlotCount; }
|
2491
|
+
|
2492
|
+
if (newSlotCount != currentSlotCount)
|
2493
|
+
{
|
2494
|
+
if (theIM->imValueArray != NULL)
|
2495
|
+
{ rm(theEnv,theIM->imValueArray,sizeof(CLIPSValue) * currentSlotCount); }
|
2496
|
+
|
2497
|
+
if (theIM->changeMap != NULL)
|
2498
|
+
{ rm(theEnv,(void *) theIM->changeMap,currentSlotCount); }
|
2499
|
+
|
2500
|
+
if (oldInstance->cls->instanceSlotCount == 0)
|
2501
|
+
{
|
2502
|
+
theIM->imValueArray = NULL;
|
2503
|
+
theIM->changeMap = NULL;
|
2504
|
+
}
|
2505
|
+
else
|
2506
|
+
{
|
2507
|
+
theIM->imValueArray = (CLIPSValue *) gm2(theEnv,sizeof(CLIPSValue) * newSlotCount);
|
2508
|
+
theIM->changeMap = (char *) gm2(theEnv,CountToBitMapSize(newSlotCount));
|
2509
|
+
}
|
2510
|
+
}
|
2511
|
+
|
2512
|
+
/*=================================*/
|
2513
|
+
/* Update the fact being modified. */
|
2514
|
+
/*=================================*/
|
2515
|
+
|
2516
|
+
RetainInstance(oldInstance);
|
2517
|
+
ReleaseInstance(theIM->imOldInstance);
|
2518
|
+
theIM->imOldInstance = oldInstance;
|
2519
|
+
|
2520
|
+
/*=========================================*/
|
2521
|
+
/* Initialize the value and change arrays. */
|
2522
|
+
/*=========================================*/
|
2523
|
+
|
2524
|
+
for (i = 0; i < theIM->imOldInstance->cls->instanceSlotCount; i++)
|
2525
|
+
{ theIM->imValueArray[i].voidValue = theIM->imEnv->VoidConstant; }
|
2526
|
+
|
2527
|
+
if (newSlotCount != 0)
|
2528
|
+
{ ClearBitString((void *) theIM->changeMap,CountToBitMapSize(theIM->imOldInstance->cls->instanceSlotCount)); }
|
2529
|
+
|
2530
|
+
/*================================================================*/
|
2531
|
+
/* Return true to indicate the modifier was successfully created. */
|
2532
|
+
/*================================================================*/
|
2533
|
+
|
2534
|
+
InstanceData(theEnv)->instanceModifierError = IME_NO_ERROR;
|
2535
|
+
return IME_NO_ERROR;
|
2536
|
+
}
|
2537
|
+
|
2538
|
+
/************/
|
2539
|
+
/* IMError: */
|
2540
|
+
/************/
|
2541
|
+
InstanceModifierError IMError(
|
2542
|
+
Environment *theEnv)
|
2543
|
+
{
|
2544
|
+
return InstanceData(theEnv)->instanceModifierError;
|
2545
|
+
}
|
2546
|
+
|
2547
|
+
#endif
|
2548
|
+
|
2549
|
+
|
2550
|
+
|