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,1441 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 02/03/21 */
|
5
|
+
/* */
|
6
|
+
/* OBJECT MESSAGE DISPATCH CODE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Brian L. Dantes */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* */
|
17
|
+
/* Revision History: */
|
18
|
+
/* */
|
19
|
+
/* 6.23: Correction for FalseSymbol/TrueSymbol. DR0859 */
|
20
|
+
/* */
|
21
|
+
/* 6.24: Removed IMPERATIVE_MESSAGE_HANDLERS and */
|
22
|
+
/* AUXILIARY_MESSAGE_HANDLERS compilation flags. */
|
23
|
+
/* */
|
24
|
+
/* Renamed BOOLEAN macro type to intBool. */
|
25
|
+
/* */
|
26
|
+
/* 6.30: The return value of DirectMessage indicates */
|
27
|
+
/* whether an execution error has occurred. */
|
28
|
+
/* */
|
29
|
+
/* Removed conditional code for unsupported */
|
30
|
+
/* compilers/operating systems (IBM_MCW, */
|
31
|
+
/* MAC_MCW, and IBM_TBC). */
|
32
|
+
/* */
|
33
|
+
/* Changed garbage collection algorithm. */
|
34
|
+
/* */
|
35
|
+
/* Added const qualifiers to remove C++ */
|
36
|
+
/* deprecation warnings. */
|
37
|
+
/* */
|
38
|
+
/* Converted API macros to function calls. */
|
39
|
+
/* */
|
40
|
+
/* It's no longer necessary for a defclass to be */
|
41
|
+
/* in scope in order to sent a message to an */
|
42
|
+
/* instance of that class. */
|
43
|
+
/* */
|
44
|
+
/* 6.40: Added Env prefix to GetEvaluationError and */
|
45
|
+
/* SetEvaluationError functions. */
|
46
|
+
/* */
|
47
|
+
/* Pragma once and other inclusion changes. */
|
48
|
+
/* */
|
49
|
+
/* Added support for booleans with <stdbool.h>. */
|
50
|
+
/* */
|
51
|
+
/* Removed use of void pointers for specific */
|
52
|
+
/* data structures. */
|
53
|
+
/* */
|
54
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
55
|
+
/* */
|
56
|
+
/* UDF redesign. */
|
57
|
+
/* */
|
58
|
+
/* Added GCBlockStart and GCBlockEnd functions */
|
59
|
+
/* for garbage collection blocks. */
|
60
|
+
/* */
|
61
|
+
/*************************************************************/
|
62
|
+
|
63
|
+
/* =========================================
|
64
|
+
*****************************************
|
65
|
+
EXTERNAL DEFINITIONS
|
66
|
+
=========================================
|
67
|
+
***************************************** */
|
68
|
+
#include "setup.h"
|
69
|
+
|
70
|
+
#if OBJECT_SYSTEM
|
71
|
+
|
72
|
+
#include <stdio.h>
|
73
|
+
#include <stdlib.h>
|
74
|
+
|
75
|
+
#include "argacces.h"
|
76
|
+
#include "classcom.h"
|
77
|
+
#include "classfun.h"
|
78
|
+
#include "commline.h"
|
79
|
+
#include "constrct.h"
|
80
|
+
#include "envrnmnt.h"
|
81
|
+
#include "exprnpsr.h"
|
82
|
+
#include "inscom.h"
|
83
|
+
#include "insfun.h"
|
84
|
+
#include "memalloc.h"
|
85
|
+
#include "msgcom.h"
|
86
|
+
#include "msgfun.h"
|
87
|
+
#include "multifld.h"
|
88
|
+
#include "prccode.h"
|
89
|
+
#include "prcdrfun.h"
|
90
|
+
#include "prntutil.h"
|
91
|
+
#include "proflfun.h"
|
92
|
+
#include "router.h"
|
93
|
+
#include "strngfun.h"
|
94
|
+
#include "utility.h"
|
95
|
+
|
96
|
+
#include "msgpass.h"
|
97
|
+
|
98
|
+
/***************************************/
|
99
|
+
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
|
100
|
+
/***************************************/
|
101
|
+
|
102
|
+
static bool PerformMessage(Environment *,UDFValue *,Expression *,CLIPSLexeme *);
|
103
|
+
static HANDLER_LINK *FindApplicableHandlers(Environment *,Defclass *,CLIPSLexeme *);
|
104
|
+
static void CallHandlers(Environment *,UDFValue *);
|
105
|
+
static void EarlySlotBindError(Environment *,Instance *,Defclass *,unsigned);
|
106
|
+
|
107
|
+
/* =========================================
|
108
|
+
*****************************************
|
109
|
+
EXTERNALLY VISIBLE FUNCTIONS
|
110
|
+
=========================================
|
111
|
+
***************************************** */
|
112
|
+
|
113
|
+
/*****************************************************
|
114
|
+
NAME : DirectMessage
|
115
|
+
DESCRIPTION : Plugs in given instance and
|
116
|
+
performs specified message
|
117
|
+
INPUTS : 1) Message symbolic name
|
118
|
+
2) The instance address
|
119
|
+
3) Address of UDFValue buffer
|
120
|
+
(NULL if don't care)
|
121
|
+
4) Message argument expressions
|
122
|
+
RETURNS : Returns false is an execution error occurred
|
123
|
+
or execution is halted, otherwise true
|
124
|
+
SIDE EFFECTS : Side effects of message execution
|
125
|
+
NOTES : None
|
126
|
+
*****************************************************/
|
127
|
+
bool DirectMessage(
|
128
|
+
Environment *theEnv,
|
129
|
+
CLIPSLexeme *msg,
|
130
|
+
Instance *ins,
|
131
|
+
UDFValue *resultbuf,
|
132
|
+
Expression *remargs)
|
133
|
+
{
|
134
|
+
Expression args;
|
135
|
+
UDFValue temp;
|
136
|
+
|
137
|
+
if (resultbuf == NULL)
|
138
|
+
resultbuf = &temp;
|
139
|
+
|
140
|
+
args.nextArg = remargs;
|
141
|
+
args.argList = NULL;
|
142
|
+
args.type = INSTANCE_ADDRESS_TYPE;
|
143
|
+
args.value = ins;
|
144
|
+
|
145
|
+
return PerformMessage(theEnv,resultbuf,&args,msg);
|
146
|
+
}
|
147
|
+
|
148
|
+
/***************************************************
|
149
|
+
NAME : Send
|
150
|
+
DESCRIPTION : C Interface for sending messages to
|
151
|
+
instances
|
152
|
+
INPUTS : 1) The data object of the instance
|
153
|
+
2) The message name-string
|
154
|
+
3) The message arguments string
|
155
|
+
(Constants only)
|
156
|
+
4) Caller's buffer for result
|
157
|
+
RETURNS : Nothing useful
|
158
|
+
SIDE EFFECTS : Executes message and stores result
|
159
|
+
caller's buffer
|
160
|
+
NOTES : None
|
161
|
+
***************************************************/
|
162
|
+
void Send(
|
163
|
+
Environment *theEnv,
|
164
|
+
CLIPSValue *idata,
|
165
|
+
const char *msg,
|
166
|
+
const char *args,
|
167
|
+
CLIPSValue *returnValue)
|
168
|
+
{
|
169
|
+
bool error;
|
170
|
+
Expression *iexp;
|
171
|
+
CLIPSLexeme *msym;
|
172
|
+
// TBD GCBlock gcb;
|
173
|
+
UDFValue result;
|
174
|
+
|
175
|
+
/*=====================================*/
|
176
|
+
/* If embedded, clear the error flags. */
|
177
|
+
/*=====================================*/
|
178
|
+
|
179
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
180
|
+
{ ResetErrorFlags(theEnv); }
|
181
|
+
|
182
|
+
if (EvaluationData(theEnv)->CurrentExpression == NULL)
|
183
|
+
{
|
184
|
+
CleanCurrentGarbageFrame(theEnv,NULL);
|
185
|
+
CallPeriodicTasks(theEnv);
|
186
|
+
}
|
187
|
+
|
188
|
+
if (returnValue != NULL)
|
189
|
+
{ returnValue->value = FalseSymbol(theEnv); }
|
190
|
+
|
191
|
+
msym = FindSymbolHN(theEnv,msg,SYMBOL_BIT);
|
192
|
+
if (msym == NULL)
|
193
|
+
{
|
194
|
+
PrintNoHandlerError(theEnv,msg);
|
195
|
+
SetEvaluationError(theEnv,true);
|
196
|
+
return;
|
197
|
+
}
|
198
|
+
|
199
|
+
iexp = GenConstant(theEnv,idata->header->type,idata->value);
|
200
|
+
iexp->nextArg = ParseConstantArguments(theEnv,args,&error);
|
201
|
+
if (error == true)
|
202
|
+
{
|
203
|
+
ReturnExpression(theEnv,iexp);
|
204
|
+
SetEvaluationError(theEnv,true);
|
205
|
+
return;
|
206
|
+
}
|
207
|
+
|
208
|
+
PerformMessage(theEnv,&result,iexp,msym);
|
209
|
+
ReturnExpression(theEnv,iexp);
|
210
|
+
|
211
|
+
if (returnValue != NULL)
|
212
|
+
{
|
213
|
+
NormalizeMultifield(theEnv,&result);
|
214
|
+
returnValue->value = result.value;
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
/*****************************************************
|
219
|
+
NAME : DestroyHandlerLinks
|
220
|
+
DESCRIPTION : Iteratively deallocates handler-links
|
221
|
+
INPUTS : The handler-link list
|
222
|
+
RETURNS : Nothing useful
|
223
|
+
SIDE EFFECTS : Deallocation of links
|
224
|
+
NOTES : None
|
225
|
+
*****************************************************/
|
226
|
+
void DestroyHandlerLinks(
|
227
|
+
Environment *theEnv,
|
228
|
+
HANDLER_LINK *mhead)
|
229
|
+
{
|
230
|
+
HANDLER_LINK *tmp;
|
231
|
+
|
232
|
+
while (mhead != NULL)
|
233
|
+
{
|
234
|
+
tmp = mhead;
|
235
|
+
mhead = mhead->nxt;
|
236
|
+
tmp->hnd->busy--;
|
237
|
+
DecrementDefclassBusyCount(theEnv,tmp->hnd->cls);
|
238
|
+
rtn_struct(theEnv,messageHandlerLink,tmp);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
/***********************************************************************
|
243
|
+
NAME : SendCommand
|
244
|
+
DESCRIPTION : Determines the applicable handler(s) and sets up the
|
245
|
+
core calling frame. Then calls the core frame.
|
246
|
+
INPUTS : Caller's space for storing the result of the handler(s)
|
247
|
+
RETURNS : Nothing useful
|
248
|
+
SIDE EFFECTS : Any side-effects caused by the execution of handlers in
|
249
|
+
the core framework
|
250
|
+
NOTES : H/L Syntax : (send <instance> <hnd> <args>*)
|
251
|
+
***********************************************************************/
|
252
|
+
void SendCommand(
|
253
|
+
Environment *theEnv,
|
254
|
+
UDFContext *context,
|
255
|
+
UDFValue *returnValue)
|
256
|
+
{
|
257
|
+
Expression args;
|
258
|
+
CLIPSLexeme *msg;
|
259
|
+
UDFValue theArg;
|
260
|
+
|
261
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
262
|
+
|
263
|
+
if (! UDFNthArgument(context,2,SYMBOL_BIT,&theArg)) return;
|
264
|
+
msg = theArg.lexemeValue;
|
265
|
+
|
266
|
+
/* =============================================
|
267
|
+
Get the instance or primitive for the message
|
268
|
+
============================================= */
|
269
|
+
args.type = GetFirstArgument()->type;
|
270
|
+
args.value = GetFirstArgument()->value;
|
271
|
+
args.argList = GetFirstArgument()->argList;
|
272
|
+
args.nextArg = GetFirstArgument()->nextArg->nextArg;
|
273
|
+
|
274
|
+
PerformMessage(theEnv,returnValue,&args,msg);
|
275
|
+
}
|
276
|
+
|
277
|
+
/***************************************************
|
278
|
+
NAME : GetNthMessageArgument
|
279
|
+
DESCRIPTION : Returns the address of the nth
|
280
|
+
(starting at 1) which is an
|
281
|
+
argument of the current message
|
282
|
+
dispatch
|
283
|
+
INPUTS : None
|
284
|
+
RETURNS : The message argument
|
285
|
+
SIDE EFFECTS : None
|
286
|
+
NOTES : The active instance is always
|
287
|
+
stored as the first argument (0) in
|
288
|
+
the call frame of the message
|
289
|
+
***************************************************/
|
290
|
+
UDFValue *GetNthMessageArgument(
|
291
|
+
Environment *theEnv,
|
292
|
+
int n)
|
293
|
+
{
|
294
|
+
return(&ProceduralPrimitiveData(theEnv)->ProcParamArray[n]);
|
295
|
+
}
|
296
|
+
|
297
|
+
/********************************/
|
298
|
+
/* NextHandlerAvailableFunction */
|
299
|
+
/********************************/
|
300
|
+
void NextHandlerAvailableFunction(
|
301
|
+
Environment *theEnv,
|
302
|
+
UDFContext *context,
|
303
|
+
UDFValue *returnValue)
|
304
|
+
{
|
305
|
+
returnValue->lexemeValue = CreateBoolean(theEnv,NextHandlerAvailable(theEnv));
|
306
|
+
}
|
307
|
+
|
308
|
+
/*****************************************************
|
309
|
+
NAME : NextHandlerAvailable
|
310
|
+
DESCRIPTION : Determines if there the currently
|
311
|
+
executing handler can call a
|
312
|
+
shadowed handler
|
313
|
+
Used before calling call-next-handler
|
314
|
+
INPUTS : None
|
315
|
+
RETURNS : True if shadow ready, false otherwise
|
316
|
+
SIDE EFFECTS : None
|
317
|
+
NOTES : H/L Syntax: (next-handlerp)
|
318
|
+
*****************************************************/
|
319
|
+
bool NextHandlerAvailable(
|
320
|
+
Environment *theEnv)
|
321
|
+
{
|
322
|
+
if (MessageHandlerData(theEnv)->CurrentCore == NULL)
|
323
|
+
{ return false; }
|
324
|
+
|
325
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)
|
326
|
+
{ return (MessageHandlerData(theEnv)->NextInCore != NULL) ? true : false; }
|
327
|
+
|
328
|
+
if ((MessageHandlerData(theEnv)->CurrentCore->hnd->type == MPRIMARY) &&
|
329
|
+
(MessageHandlerData(theEnv)->NextInCore != NULL))
|
330
|
+
{ return (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY) ? true : false; }
|
331
|
+
|
332
|
+
return false;
|
333
|
+
}
|
334
|
+
|
335
|
+
/********************************************************
|
336
|
+
NAME : CallNextHandler
|
337
|
+
DESCRIPTION : This function allows around-handlers
|
338
|
+
to execute the rest of the core frame.
|
339
|
+
It also allows primary handlers
|
340
|
+
to execute shadowed primaries.
|
341
|
+
|
342
|
+
The original handler arguments are
|
343
|
+
left intact.
|
344
|
+
INPUTS : The caller's result-value buffer
|
345
|
+
RETURNS : Nothing useful
|
346
|
+
SIDE EFFECTS : The core frame is called and any
|
347
|
+
appropriate changes are made when
|
348
|
+
used in an around handler
|
349
|
+
See CallHandlers()
|
350
|
+
But when call-next-handler is called
|
351
|
+
from a primary, the same shadowed
|
352
|
+
primary is called over and over
|
353
|
+
again for repeated calls to
|
354
|
+
call-next-handler.
|
355
|
+
NOTES : H/L Syntax: (call-next-handler) OR
|
356
|
+
(override-next-handler <arg> ...)
|
357
|
+
********************************************************/
|
358
|
+
void CallNextHandler(
|
359
|
+
Environment *theEnv,
|
360
|
+
UDFContext *context,
|
361
|
+
UDFValue *returnValue)
|
362
|
+
{
|
363
|
+
Expression args;
|
364
|
+
int overridep;
|
365
|
+
HANDLER_LINK *oldNext,*oldCurrent;
|
366
|
+
#if PROFILING_FUNCTIONS
|
367
|
+
struct profileFrameInfo profileFrame;
|
368
|
+
#endif
|
369
|
+
|
370
|
+
returnValue->lexemeValue = FalseSymbol(theEnv);
|
371
|
+
|
372
|
+
EvaluationData(theEnv)->EvaluationError = false;
|
373
|
+
if (EvaluationData(theEnv)->HaltExecution)
|
374
|
+
return;
|
375
|
+
if (NextHandlerAvailable(theEnv) == false)
|
376
|
+
{
|
377
|
+
PrintErrorID(theEnv,"MSGPASS",1,false);
|
378
|
+
WriteString(theEnv,STDERR,"Shadowed message-handlers not applicable in current context.\n");
|
379
|
+
SetEvaluationError(theEnv,true);
|
380
|
+
return;
|
381
|
+
}
|
382
|
+
if (EvaluationData(theEnv)->CurrentExpression->value == (void *) FindFunction(theEnv,"override-next-handler"))
|
383
|
+
{
|
384
|
+
overridep = 1;
|
385
|
+
args.type = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].header->type;
|
386
|
+
if (args.type != MULTIFIELD_TYPE)
|
387
|
+
args.value = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value;
|
388
|
+
else
|
389
|
+
args.value = &ProceduralPrimitiveData(theEnv)->ProcParamArray[0];
|
390
|
+
args.nextArg = GetFirstArgument();
|
391
|
+
args.argList = NULL;
|
392
|
+
PushProcParameters(theEnv,&args,CountArguments(&args),
|
393
|
+
MessageHandlerData(theEnv)->CurrentMessageName->contents,"message",
|
394
|
+
UnboundHandlerErr);
|
395
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
396
|
+
{
|
397
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
398
|
+
return;
|
399
|
+
}
|
400
|
+
}
|
401
|
+
else
|
402
|
+
overridep = 0;
|
403
|
+
oldNext = MessageHandlerData(theEnv)->NextInCore;
|
404
|
+
oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
|
405
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)
|
406
|
+
{
|
407
|
+
if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAROUND)
|
408
|
+
{
|
409
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
|
410
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
411
|
+
#if DEBUGGING_FUNCTIONS
|
412
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
413
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
414
|
+
#endif
|
415
|
+
if (CheckHandlerArgCount(theEnv))
|
416
|
+
{
|
417
|
+
#if PROFILING_FUNCTIONS
|
418
|
+
StartProfile(theEnv,&profileFrame,
|
419
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
420
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
421
|
+
#endif
|
422
|
+
|
423
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
424
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
425
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
426
|
+
returnValue,UnboundHandlerErr);
|
427
|
+
#if PROFILING_FUNCTIONS
|
428
|
+
EndProfile(theEnv,&profileFrame);
|
429
|
+
#endif
|
430
|
+
}
|
431
|
+
#if DEBUGGING_FUNCTIONS
|
432
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
433
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
434
|
+
#endif
|
435
|
+
}
|
436
|
+
else
|
437
|
+
CallHandlers(theEnv,returnValue);
|
438
|
+
}
|
439
|
+
else
|
440
|
+
{
|
441
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
|
442
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
443
|
+
#if DEBUGGING_FUNCTIONS
|
444
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
445
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
446
|
+
#endif
|
447
|
+
if (CheckHandlerArgCount(theEnv))
|
448
|
+
{
|
449
|
+
#if PROFILING_FUNCTIONS
|
450
|
+
StartProfile(theEnv,&profileFrame,
|
451
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
452
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
453
|
+
#endif
|
454
|
+
|
455
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
456
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
457
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
458
|
+
returnValue,UnboundHandlerErr);
|
459
|
+
#if PROFILING_FUNCTIONS
|
460
|
+
EndProfile(theEnv,&profileFrame);
|
461
|
+
#endif
|
462
|
+
}
|
463
|
+
|
464
|
+
#if DEBUGGING_FUNCTIONS
|
465
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
466
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
467
|
+
#endif
|
468
|
+
}
|
469
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
470
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
471
|
+
if (overridep)
|
472
|
+
PopProcParameters(theEnv);
|
473
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
474
|
+
}
|
475
|
+
|
476
|
+
/*************************************************************************
|
477
|
+
NAME : FindApplicableOfName
|
478
|
+
DESCRIPTION : Groups all handlers of all types of the specified
|
479
|
+
class of the specified name into the applicable handler
|
480
|
+
list
|
481
|
+
INPUTS : 1) The class address
|
482
|
+
2-3) The tops and bottoms of the four handler type lists:
|
483
|
+
around, before, primary and after
|
484
|
+
4) The message name symbol
|
485
|
+
RETURNS : Nothing useful
|
486
|
+
SIDE EFFECTS : Modifies the handler lists to include applicable handlers
|
487
|
+
NOTES : None
|
488
|
+
*************************************************************************/
|
489
|
+
void FindApplicableOfName(
|
490
|
+
Environment *theEnv,
|
491
|
+
Defclass *cls,
|
492
|
+
HANDLER_LINK *tops[4],
|
493
|
+
HANDLER_LINK *bots[4],
|
494
|
+
CLIPSLexeme *mname)
|
495
|
+
{
|
496
|
+
int i;
|
497
|
+
int e;
|
498
|
+
DefmessageHandler *hnd;
|
499
|
+
unsigned *arr;
|
500
|
+
HANDLER_LINK *tmp;
|
501
|
+
|
502
|
+
i = FindHandlerNameGroup(cls,mname);
|
503
|
+
if (i == -1)
|
504
|
+
return;
|
505
|
+
e = ((int) cls->handlerCount) - 1;
|
506
|
+
hnd = cls->handlers;
|
507
|
+
arr = cls->handlerOrderMap;
|
508
|
+
for ( ; i <= e ; i++)
|
509
|
+
{
|
510
|
+
if (hnd[arr[i]].header.name != mname)
|
511
|
+
break;
|
512
|
+
|
513
|
+
tmp = get_struct(theEnv,messageHandlerLink);
|
514
|
+
hnd[arr[i]].busy++;
|
515
|
+
IncrementDefclassBusyCount(theEnv,hnd[arr[i]].cls);
|
516
|
+
tmp->hnd = &hnd[arr[i]];
|
517
|
+
if (tops[tmp->hnd->type] == NULL)
|
518
|
+
{
|
519
|
+
tmp->nxt = NULL;
|
520
|
+
tops[tmp->hnd->type] = bots[tmp->hnd->type] = tmp;
|
521
|
+
}
|
522
|
+
|
523
|
+
else if (tmp->hnd->type == MAFTER)
|
524
|
+
{
|
525
|
+
tmp->nxt = tops[tmp->hnd->type];
|
526
|
+
tops[tmp->hnd->type] = tmp;
|
527
|
+
}
|
528
|
+
|
529
|
+
else
|
530
|
+
{
|
531
|
+
bots[tmp->hnd->type]->nxt = tmp;
|
532
|
+
bots[tmp->hnd->type] = tmp;
|
533
|
+
tmp->nxt = NULL;
|
534
|
+
}
|
535
|
+
}
|
536
|
+
}
|
537
|
+
|
538
|
+
/*************************************************************************
|
539
|
+
NAME : JoinHandlerLinks
|
540
|
+
DESCRIPTION : Joins the queues of different handlers together
|
541
|
+
INPUTS : 1-2) The tops and bottoms of the four handler type lists:
|
542
|
+
around, before, primary and after
|
543
|
+
3) The message name symbol
|
544
|
+
RETURNS : The top of the joined lists, NULL on errors
|
545
|
+
SIDE EFFECTS : Links all the handler type lists together, or all the
|
546
|
+
lists are destroyed if there are no primary handlers
|
547
|
+
NOTES : None
|
548
|
+
*************************************************************************/
|
549
|
+
HANDLER_LINK *JoinHandlerLinks(
|
550
|
+
Environment *theEnv,
|
551
|
+
HANDLER_LINK *tops[4],
|
552
|
+
HANDLER_LINK *bots[4],
|
553
|
+
CLIPSLexeme *mname)
|
554
|
+
{
|
555
|
+
int i;
|
556
|
+
HANDLER_LINK *mlink;
|
557
|
+
|
558
|
+
if (tops[MPRIMARY] == NULL)
|
559
|
+
{
|
560
|
+
PrintNoHandlerError(theEnv,mname->contents);
|
561
|
+
for (i = MAROUND ; i <= MAFTER ; i++)
|
562
|
+
DestroyHandlerLinks(theEnv,tops[i]);
|
563
|
+
SetEvaluationError(theEnv,true);
|
564
|
+
return NULL;
|
565
|
+
}
|
566
|
+
|
567
|
+
mlink = tops[MPRIMARY];
|
568
|
+
|
569
|
+
if (tops[MBEFORE] != NULL)
|
570
|
+
{
|
571
|
+
bots[MBEFORE]->nxt = mlink;
|
572
|
+
mlink = tops[MBEFORE];
|
573
|
+
}
|
574
|
+
|
575
|
+
if (tops[MAROUND] != NULL)
|
576
|
+
{
|
577
|
+
bots[MAROUND]->nxt = mlink;
|
578
|
+
mlink = tops[MAROUND];
|
579
|
+
}
|
580
|
+
|
581
|
+
bots[MPRIMARY]->nxt = tops[MAFTER];
|
582
|
+
|
583
|
+
return(mlink);
|
584
|
+
}
|
585
|
+
|
586
|
+
/***************************************************
|
587
|
+
NAME : PrintHandlerSlotGetFunction
|
588
|
+
DESCRIPTION : Developer access function for
|
589
|
+
printing direct slot references
|
590
|
+
in message-handlers
|
591
|
+
INPUTS : 1) The logical name of the output
|
592
|
+
2) The bitmap expression
|
593
|
+
RETURNS : Nothing useful
|
594
|
+
SIDE EFFECTS : Expression printed
|
595
|
+
NOTES : None
|
596
|
+
***************************************************/
|
597
|
+
void PrintHandlerSlotGetFunction(
|
598
|
+
Environment *theEnv,
|
599
|
+
const char *logicalName,
|
600
|
+
void *theValue)
|
601
|
+
{
|
602
|
+
#if DEVELOPER
|
603
|
+
HANDLER_SLOT_REFERENCE *theReference;
|
604
|
+
Defclass *theDefclass;
|
605
|
+
SlotDescriptor *sd;
|
606
|
+
|
607
|
+
theReference = (HANDLER_SLOT_REFERENCE *) ((CLIPSBitMap *) theValue)->contents;
|
608
|
+
WriteString(theEnv,logicalName,"?self:[");
|
609
|
+
theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
|
610
|
+
WriteString(theEnv,logicalName,theDefclass->header.name->contents);
|
611
|
+
WriteString(theEnv,logicalName,"]");
|
612
|
+
sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[theReference->slotID] - 1];
|
613
|
+
WriteString(theEnv,logicalName,sd->slotName->name->contents);
|
614
|
+
#else
|
615
|
+
#if MAC_XCD
|
616
|
+
#pragma unused(theEnv)
|
617
|
+
#pragma unused(logicalName)
|
618
|
+
#pragma unused(theValue)
|
619
|
+
#endif
|
620
|
+
#endif
|
621
|
+
}
|
622
|
+
|
623
|
+
/***************************************************
|
624
|
+
NAME : HandlerSlotGetFunction
|
625
|
+
DESCRIPTION : Access function for handling the
|
626
|
+
statically-bound direct slot
|
627
|
+
references in message-handlers
|
628
|
+
INPUTS : 1) The bitmap expression
|
629
|
+
2) A data object buffer
|
630
|
+
RETURNS : True if OK, false
|
631
|
+
on errors
|
632
|
+
SIDE EFFECTS : Data object buffer gets value of
|
633
|
+
slot. On errors, buffer gets
|
634
|
+
symbol false, EvaluationError
|
635
|
+
is set and error messages are
|
636
|
+
printed
|
637
|
+
NOTES : It is possible for a handler
|
638
|
+
(attached to a superclass of
|
639
|
+
the currently active instance)
|
640
|
+
containing these static references
|
641
|
+
to be called for an instance
|
642
|
+
which does not contain the slots
|
643
|
+
(e.g., an instance of a subclass
|
644
|
+
where the original slot was
|
645
|
+
no-inherit or the subclass
|
646
|
+
overrode the original slot)
|
647
|
+
***************************************************/
|
648
|
+
bool HandlerSlotGetFunction(
|
649
|
+
Environment *theEnv,
|
650
|
+
void *theValue,
|
651
|
+
UDFValue *theResult)
|
652
|
+
{
|
653
|
+
const HANDLER_SLOT_REFERENCE *theReference;
|
654
|
+
Defclass *theDefclass;
|
655
|
+
Instance *theInstance;
|
656
|
+
InstanceSlot *sp;
|
657
|
+
unsigned instanceSlotIndex;
|
658
|
+
|
659
|
+
theReference = (const HANDLER_SLOT_REFERENCE *) ((CLIPSBitMap *) theValue)->contents;
|
660
|
+
theInstance = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].instanceValue;
|
661
|
+
theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
|
662
|
+
|
663
|
+
if (theInstance->garbage)
|
664
|
+
{
|
665
|
+
PrintErrorID(theEnv,"INSFUN",4,false);
|
666
|
+
WriteString(theEnv,STDERR,"Invalid instance-address in ?self slot reference.\n");
|
667
|
+
theResult->value = FalseSymbol(theEnv);
|
668
|
+
SetEvaluationError(theEnv,true);
|
669
|
+
return false;
|
670
|
+
}
|
671
|
+
|
672
|
+
if (theInstance->cls == theDefclass)
|
673
|
+
{
|
674
|
+
instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
|
675
|
+
sp = theInstance->slotAddresses[instanceSlotIndex - 1];
|
676
|
+
}
|
677
|
+
else
|
678
|
+
{
|
679
|
+
if (theReference->slotID > theInstance->cls->maxSlotNameID)
|
680
|
+
goto HandlerGetError;
|
681
|
+
instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
|
682
|
+
if (instanceSlotIndex == 0)
|
683
|
+
goto HandlerGetError;
|
684
|
+
instanceSlotIndex--;
|
685
|
+
sp = theInstance->slotAddresses[instanceSlotIndex];
|
686
|
+
if (sp->desc->cls != theDefclass)
|
687
|
+
goto HandlerGetError;
|
688
|
+
}
|
689
|
+
theResult->value = sp->value;
|
690
|
+
if (sp->type == MULTIFIELD_TYPE)
|
691
|
+
{
|
692
|
+
theResult->begin = 0;
|
693
|
+
theResult->range = sp->multifieldValue->length;
|
694
|
+
}
|
695
|
+
return true;
|
696
|
+
|
697
|
+
HandlerGetError:
|
698
|
+
EarlySlotBindError(theEnv,theInstance,theDefclass,theReference->slotID);
|
699
|
+
theResult->value = FalseSymbol(theEnv);
|
700
|
+
SetEvaluationError(theEnv,true);
|
701
|
+
return false;
|
702
|
+
}
|
703
|
+
|
704
|
+
/***************************************************
|
705
|
+
NAME : PrintHandlerSlotPutFunction
|
706
|
+
DESCRIPTION : Developer access function for
|
707
|
+
printing direct slot bindings
|
708
|
+
in message-handlers
|
709
|
+
INPUTS : 1) The logical name of the output
|
710
|
+
2) The bitmap expression
|
711
|
+
RETURNS : Nothing useful
|
712
|
+
SIDE EFFECTS : Expression printed
|
713
|
+
NOTES : None
|
714
|
+
***************************************************/
|
715
|
+
void PrintHandlerSlotPutFunction(
|
716
|
+
Environment *theEnv,
|
717
|
+
const char *logicalName,
|
718
|
+
void *theValue)
|
719
|
+
{
|
720
|
+
#if DEVELOPER
|
721
|
+
HANDLER_SLOT_REFERENCE *theReference;
|
722
|
+
Defclass *theDefclass;
|
723
|
+
SlotDescriptor *sd;
|
724
|
+
|
725
|
+
theReference = (HANDLER_SLOT_REFERENCE *) ((CLIPSBitMap *) theValue)->contents;
|
726
|
+
WriteString(theEnv,logicalName,"(bind ?self:[");
|
727
|
+
theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
|
728
|
+
WriteString(theEnv,logicalName,theDefclass->header.name->contents);
|
729
|
+
WriteString(theEnv,logicalName,"]");
|
730
|
+
sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[theReference->slotID] - 1];
|
731
|
+
WriteString(theEnv,logicalName,sd->slotName->name->contents);
|
732
|
+
if (GetFirstArgument() != NULL)
|
733
|
+
{
|
734
|
+
WriteString(theEnv,logicalName," ");
|
735
|
+
PrintExpression(theEnv,logicalName,GetFirstArgument());
|
736
|
+
}
|
737
|
+
WriteString(theEnv,logicalName,")");
|
738
|
+
#else
|
739
|
+
#if MAC_XCD
|
740
|
+
#pragma unused(theEnv)
|
741
|
+
#pragma unused(logicalName)
|
742
|
+
#pragma unused(theValue)
|
743
|
+
#endif
|
744
|
+
#endif
|
745
|
+
}
|
746
|
+
|
747
|
+
/***************************************************
|
748
|
+
NAME : HandlerSlotPutFunction
|
749
|
+
DESCRIPTION : Access function for handling the
|
750
|
+
statically-bound direct slot
|
751
|
+
bindings in message-handlers
|
752
|
+
INPUTS : 1) The bitmap expression
|
753
|
+
2) A data object buffer
|
754
|
+
RETURNS : True if OK, false
|
755
|
+
on errors
|
756
|
+
SIDE EFFECTS : Data object buffer gets symbol
|
757
|
+
TRUE and slot is set. On errors,
|
758
|
+
buffer gets symbol FALSE,
|
759
|
+
EvaluationError is set and error
|
760
|
+
messages are printed
|
761
|
+
NOTES : It is possible for a handler
|
762
|
+
(attached to a superclass of
|
763
|
+
the currently active instance)
|
764
|
+
containing these static references
|
765
|
+
to be called for an instance
|
766
|
+
which does not contain the slots
|
767
|
+
(e.g., an instance of a subclass
|
768
|
+
where the original slot was
|
769
|
+
no-inherit or the subclass
|
770
|
+
overrode the original slot)
|
771
|
+
***************************************************/
|
772
|
+
bool HandlerSlotPutFunction(
|
773
|
+
Environment *theEnv,
|
774
|
+
void *theValue,
|
775
|
+
UDFValue *theResult)
|
776
|
+
{
|
777
|
+
const HANDLER_SLOT_REFERENCE *theReference;
|
778
|
+
Defclass *theDefclass;
|
779
|
+
Instance *theInstance;
|
780
|
+
InstanceSlot *sp;
|
781
|
+
unsigned instanceSlotIndex;
|
782
|
+
UDFValue theSetVal;
|
783
|
+
|
784
|
+
theReference = (const HANDLER_SLOT_REFERENCE *) ((CLIPSBitMap *) theValue)->contents;
|
785
|
+
theInstance = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].instanceValue;
|
786
|
+
theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID];
|
787
|
+
|
788
|
+
if (theInstance->garbage)
|
789
|
+
{
|
790
|
+
StaleInstanceAddress(theEnv,"for slot put",0);
|
791
|
+
theResult->value = FalseSymbol(theEnv);
|
792
|
+
SetEvaluationError(theEnv,true);
|
793
|
+
return false;
|
794
|
+
}
|
795
|
+
|
796
|
+
if (theInstance->cls == theDefclass)
|
797
|
+
{
|
798
|
+
instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
|
799
|
+
sp = theInstance->slotAddresses[instanceSlotIndex - 1];
|
800
|
+
}
|
801
|
+
else
|
802
|
+
{
|
803
|
+
if (theReference->slotID > theInstance->cls->maxSlotNameID)
|
804
|
+
goto HandlerPutError;
|
805
|
+
instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID];
|
806
|
+
if (instanceSlotIndex == 0)
|
807
|
+
goto HandlerPutError;
|
808
|
+
instanceSlotIndex--;
|
809
|
+
sp = theInstance->slotAddresses[instanceSlotIndex];
|
810
|
+
if (sp->desc->cls != theDefclass)
|
811
|
+
goto HandlerPutError;
|
812
|
+
}
|
813
|
+
|
814
|
+
/* =======================================================
|
815
|
+
The slot has already been verified not to be read-only.
|
816
|
+
However, if it is initialize-only, we need to make sure
|
817
|
+
that we are initializing the instance (something we
|
818
|
+
could not verify at parse-time)
|
819
|
+
======================================================= */
|
820
|
+
if (sp->desc->initializeOnly && (!theInstance->initializeInProgress))
|
821
|
+
{
|
822
|
+
SlotAccessViolationError(theEnv,sp->desc->slotName->name->contents,
|
823
|
+
theInstance,NULL);
|
824
|
+
goto HandlerPutError2;
|
825
|
+
}
|
826
|
+
|
827
|
+
/* ======================================
|
828
|
+
No arguments means to use the
|
829
|
+
special NoParamValue to reset the slot
|
830
|
+
to its default value
|
831
|
+
====================================== */
|
832
|
+
if (GetFirstArgument())
|
833
|
+
{
|
834
|
+
if (EvaluateAndStoreInDataObject(theEnv,sp->desc->multiple,
|
835
|
+
GetFirstArgument(),&theSetVal,true) == false)
|
836
|
+
goto HandlerPutError2;
|
837
|
+
}
|
838
|
+
else
|
839
|
+
{
|
840
|
+
theSetVal.begin = 0;
|
841
|
+
theSetVal.range = 0;
|
842
|
+
theSetVal.value = ProceduralPrimitiveData(theEnv)->NoParamValue;
|
843
|
+
}
|
844
|
+
if (PutSlotValue(theEnv,theInstance,sp,&theSetVal,theResult,NULL) != PSE_NO_ERROR)
|
845
|
+
goto HandlerPutError2;
|
846
|
+
return true;
|
847
|
+
|
848
|
+
HandlerPutError:
|
849
|
+
EarlySlotBindError(theEnv,theInstance,theDefclass,theReference->slotID);
|
850
|
+
|
851
|
+
HandlerPutError2:
|
852
|
+
theResult->value = FalseSymbol(theEnv);
|
853
|
+
SetEvaluationError(theEnv,true);
|
854
|
+
|
855
|
+
return false;
|
856
|
+
}
|
857
|
+
|
858
|
+
/*****************************************************
|
859
|
+
NAME : DynamicHandlerGetSlot
|
860
|
+
DESCRIPTION : Directly references a slot's value
|
861
|
+
(uses dynamic binding to lookup slot)
|
862
|
+
INPUTS : The caller's result buffer
|
863
|
+
RETURNS : Nothing useful
|
864
|
+
SIDE EFFECTS : Caller's result buffer set
|
865
|
+
NOTES : H/L Syntax: (get <slot>)
|
866
|
+
*****************************************************/
|
867
|
+
void DynamicHandlerGetSlot(
|
868
|
+
Environment *theEnv,
|
869
|
+
UDFContext *context,
|
870
|
+
UDFValue *returnValue)
|
871
|
+
{
|
872
|
+
InstanceSlot *sp;
|
873
|
+
Instance *ins;
|
874
|
+
UDFValue temp;
|
875
|
+
|
876
|
+
returnValue->value = FalseSymbol(theEnv);
|
877
|
+
if (CheckCurrentMessage(theEnv,"dynamic-get",true) == false)
|
878
|
+
return;
|
879
|
+
EvaluateExpression(theEnv,GetFirstArgument(),&temp);
|
880
|
+
if (temp.header->type != SYMBOL_TYPE)
|
881
|
+
{
|
882
|
+
ExpectedTypeError1(theEnv,"dynamic-get",1,"symbol");
|
883
|
+
SetEvaluationError(theEnv,true);
|
884
|
+
return;
|
885
|
+
}
|
886
|
+
ins = GetActiveInstance(theEnv);
|
887
|
+
sp = FindInstanceSlot(theEnv,ins,temp.lexemeValue);
|
888
|
+
if (sp == NULL)
|
889
|
+
{
|
890
|
+
SlotExistError(theEnv,temp.lexemeValue->contents,"dynamic-get");
|
891
|
+
return;
|
892
|
+
}
|
893
|
+
if ((sp->desc->publicVisibility == 0) &&
|
894
|
+
(MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls))
|
895
|
+
{
|
896
|
+
SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls,false);
|
897
|
+
SetEvaluationError(theEnv,true);
|
898
|
+
return;
|
899
|
+
}
|
900
|
+
returnValue->value = sp->value;
|
901
|
+
if (sp->type == MULTIFIELD_TYPE)
|
902
|
+
{
|
903
|
+
returnValue->begin = 0;
|
904
|
+
returnValue->range = sp->multifieldValue->length;
|
905
|
+
}
|
906
|
+
}
|
907
|
+
|
908
|
+
/***********************************************************
|
909
|
+
NAME : DynamicHandlerPutSlot
|
910
|
+
DESCRIPTION : Directly puts a slot's value
|
911
|
+
(uses dynamic binding to lookup slot)
|
912
|
+
INPUTS : Data obejct buffer for holding slot value
|
913
|
+
RETURNS : Nothing useful
|
914
|
+
SIDE EFFECTS : Slot modified - and caller's buffer set
|
915
|
+
to value (or symbol FALSE on errors)
|
916
|
+
NOTES : H/L Syntax: (put <slot> <value>*)
|
917
|
+
***********************************************************/
|
918
|
+
void DynamicHandlerPutSlot(
|
919
|
+
Environment *theEnv,
|
920
|
+
UDFContext *context,
|
921
|
+
UDFValue *returnValue)
|
922
|
+
{
|
923
|
+
InstanceSlot *sp;
|
924
|
+
Instance *ins;
|
925
|
+
UDFValue temp;
|
926
|
+
|
927
|
+
returnValue->value = FalseSymbol(theEnv);
|
928
|
+
if (CheckCurrentMessage(theEnv,"dynamic-put",true) == false)
|
929
|
+
return;
|
930
|
+
EvaluateExpression(theEnv,GetFirstArgument(),&temp);
|
931
|
+
if (temp.header->type != SYMBOL_TYPE)
|
932
|
+
{
|
933
|
+
ExpectedTypeError1(theEnv,"dynamic-put",1,"symbol");
|
934
|
+
SetEvaluationError(theEnv,true);
|
935
|
+
return;
|
936
|
+
}
|
937
|
+
ins = GetActiveInstance(theEnv);
|
938
|
+
sp = FindInstanceSlot(theEnv,ins,temp.lexemeValue);
|
939
|
+
if (sp == NULL)
|
940
|
+
{
|
941
|
+
SlotExistError(theEnv,temp.lexemeValue->contents,"dynamic-put");
|
942
|
+
return;
|
943
|
+
}
|
944
|
+
if ((sp->desc->noWrite == 0) ? false :
|
945
|
+
((sp->desc->initializeOnly == 0) || (!ins->initializeInProgress)))
|
946
|
+
{
|
947
|
+
SlotAccessViolationError(theEnv,sp->desc->slotName->name->contents,
|
948
|
+
ins,NULL);
|
949
|
+
SetEvaluationError(theEnv,true);
|
950
|
+
return;
|
951
|
+
}
|
952
|
+
if ((sp->desc->publicVisibility == 0) &&
|
953
|
+
(MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls))
|
954
|
+
{
|
955
|
+
SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls,false);
|
956
|
+
SetEvaluationError(theEnv,true);
|
957
|
+
return;
|
958
|
+
}
|
959
|
+
if (GetFirstArgument()->nextArg)
|
960
|
+
{
|
961
|
+
if (EvaluateAndStoreInDataObject(theEnv,sp->desc->multiple,
|
962
|
+
GetFirstArgument()->nextArg,&temp,true) == false)
|
963
|
+
return;
|
964
|
+
}
|
965
|
+
else
|
966
|
+
{
|
967
|
+
temp.begin = 0;
|
968
|
+
temp.range = 0;
|
969
|
+
temp.value = ProceduralPrimitiveData(theEnv)->NoParamValue;
|
970
|
+
}
|
971
|
+
PutSlotValue(theEnv,ins,sp,&temp,returnValue,NULL);
|
972
|
+
}
|
973
|
+
|
974
|
+
/* =========================================
|
975
|
+
*****************************************
|
976
|
+
INTERNALLY VISIBLE FUNCTIONS
|
977
|
+
=========================================
|
978
|
+
***************************************** */
|
979
|
+
|
980
|
+
/*****************************************************
|
981
|
+
NAME : PerformMessage
|
982
|
+
DESCRIPTION : Calls core framework for a message
|
983
|
+
INPUTS : 1) Caller's result buffer
|
984
|
+
2) Message argument expressions
|
985
|
+
(including implicit object)
|
986
|
+
3) Message name
|
987
|
+
RETURNS : Returns false is an execution error occurred
|
988
|
+
or execution is halted, otherwise true
|
989
|
+
SIDE EFFECTS : Any side-effects of message execution
|
990
|
+
and caller's result buffer set
|
991
|
+
NOTES : It's no longer necessary for a defclass
|
992
|
+
to be in scope in order to sent a message
|
993
|
+
to an instance of that class.
|
994
|
+
*****************************************************/
|
995
|
+
static bool PerformMessage(
|
996
|
+
Environment *theEnv,
|
997
|
+
UDFValue *returnValue,
|
998
|
+
Expression *args,
|
999
|
+
CLIPSLexeme *mname)
|
1000
|
+
{
|
1001
|
+
bool oldce;
|
1002
|
+
/* HANDLER_LINK *oldCore; */
|
1003
|
+
Defclass *cls = NULL;
|
1004
|
+
Instance *ins = NULL;
|
1005
|
+
CLIPSLexeme *oldName;
|
1006
|
+
#if PROFILING_FUNCTIONS
|
1007
|
+
struct profileFrameInfo profileFrame;
|
1008
|
+
#endif
|
1009
|
+
GCBlock gcb;
|
1010
|
+
|
1011
|
+
returnValue->value = FalseSymbol(theEnv);
|
1012
|
+
EvaluationData(theEnv)->EvaluationError = false;
|
1013
|
+
if (EvaluationData(theEnv)->HaltExecution)
|
1014
|
+
return false;
|
1015
|
+
|
1016
|
+
GCBlockStart(theEnv,&gcb);
|
1017
|
+
|
1018
|
+
oldce = ExecutingConstruct(theEnv);
|
1019
|
+
SetExecutingConstruct(theEnv,true);
|
1020
|
+
oldName = MessageHandlerData(theEnv)->CurrentMessageName;
|
1021
|
+
MessageHandlerData(theEnv)->CurrentMessageName = mname;
|
1022
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth++;
|
1023
|
+
|
1024
|
+
PushProcParameters(theEnv,args,CountArguments(args),
|
1025
|
+
MessageHandlerData(theEnv)->CurrentMessageName->contents,"message",
|
1026
|
+
UnboundHandlerErr);
|
1027
|
+
|
1028
|
+
|
1029
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1030
|
+
{
|
1031
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth--;
|
1032
|
+
MessageHandlerData(theEnv)->CurrentMessageName = oldName;
|
1033
|
+
|
1034
|
+
GCBlockEndUDF(theEnv,&gcb,returnValue);
|
1035
|
+
CallPeriodicTasks(theEnv);
|
1036
|
+
|
1037
|
+
SetExecutingConstruct(theEnv,oldce);
|
1038
|
+
return false;
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
if (ProceduralPrimitiveData(theEnv)->ProcParamArray->header->type == INSTANCE_ADDRESS_TYPE)
|
1042
|
+
{
|
1043
|
+
ins = ProceduralPrimitiveData(theEnv)->ProcParamArray->instanceValue;
|
1044
|
+
if (ins->garbage == 1)
|
1045
|
+
{
|
1046
|
+
StaleInstanceAddress(theEnv,"send",0);
|
1047
|
+
SetEvaluationError(theEnv,true);
|
1048
|
+
}
|
1049
|
+
else
|
1050
|
+
{
|
1051
|
+
cls = ins->cls;
|
1052
|
+
ins->busy++;
|
1053
|
+
}
|
1054
|
+
}
|
1055
|
+
else if (ProceduralPrimitiveData(theEnv)->ProcParamArray->header->type == INSTANCE_NAME_TYPE)
|
1056
|
+
{
|
1057
|
+
ins = FindInstanceBySymbol(theEnv,ProceduralPrimitiveData(theEnv)->ProcParamArray->lexemeValue);
|
1058
|
+
if (ins == NULL)
|
1059
|
+
{
|
1060
|
+
PrintErrorID(theEnv,"MSGPASS",2,false);
|
1061
|
+
WriteString(theEnv,STDERR,"No such instance [");
|
1062
|
+
WriteString(theEnv,STDERR,ProceduralPrimitiveData(theEnv)->ProcParamArray->lexemeValue->contents);
|
1063
|
+
WriteString(theEnv,STDERR,"] in function 'send'.\n");
|
1064
|
+
SetEvaluationError(theEnv,true);
|
1065
|
+
}
|
1066
|
+
else
|
1067
|
+
{
|
1068
|
+
ProceduralPrimitiveData(theEnv)->ProcParamArray->value = ins;
|
1069
|
+
cls = ins->cls;
|
1070
|
+
ins->busy++;
|
1071
|
+
}
|
1072
|
+
}
|
1073
|
+
else if ((cls = DefclassData(theEnv)->PrimitiveClassMap[ProceduralPrimitiveData(theEnv)->ProcParamArray->header->type]) == NULL)
|
1074
|
+
{
|
1075
|
+
SystemError(theEnv,"MSGPASS",1);
|
1076
|
+
ExitRouter(theEnv,EXIT_FAILURE);
|
1077
|
+
}
|
1078
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1079
|
+
{
|
1080
|
+
PopProcParameters(theEnv);
|
1081
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth--;
|
1082
|
+
MessageHandlerData(theEnv)->CurrentMessageName = oldName;
|
1083
|
+
|
1084
|
+
GCBlockEndUDF(theEnv,&gcb,returnValue);
|
1085
|
+
CallPeriodicTasks(theEnv);
|
1086
|
+
|
1087
|
+
SetExecutingConstruct(theEnv,oldce);
|
1088
|
+
return false;
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
/* oldCore = MessageHandlerData(theEnv)->TopOfCore; */
|
1092
|
+
|
1093
|
+
if (MessageHandlerData(theEnv)->TopOfCore != NULL)
|
1094
|
+
{ MessageHandlerData(theEnv)->TopOfCore->nxtInStack = MessageHandlerData(theEnv)->OldCore; }
|
1095
|
+
MessageHandlerData(theEnv)->OldCore = MessageHandlerData(theEnv)->TopOfCore;
|
1096
|
+
|
1097
|
+
MessageHandlerData(theEnv)->TopOfCore = FindApplicableHandlers(theEnv,cls,mname);
|
1098
|
+
|
1099
|
+
if (MessageHandlerData(theEnv)->TopOfCore != NULL)
|
1100
|
+
{
|
1101
|
+
HANDLER_LINK *oldCurrent,*oldNext;
|
1102
|
+
|
1103
|
+
oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
|
1104
|
+
oldNext = MessageHandlerData(theEnv)->NextInCore;
|
1105
|
+
|
1106
|
+
if (MessageHandlerData(theEnv)->TopOfCore->hnd->type == MAROUND)
|
1107
|
+
{
|
1108
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->TopOfCore;
|
1109
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore->nxt;
|
1110
|
+
#if DEBUGGING_FUNCTIONS
|
1111
|
+
if (MessageHandlerData(theEnv)->WatchMessages)
|
1112
|
+
WatchMessage(theEnv,STDOUT,BEGIN_TRACE);
|
1113
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1114
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
1115
|
+
#endif
|
1116
|
+
if (CheckHandlerArgCount(theEnv))
|
1117
|
+
{
|
1118
|
+
#if PROFILING_FUNCTIONS
|
1119
|
+
StartProfile(theEnv,&profileFrame,
|
1120
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
1121
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
1122
|
+
#endif
|
1123
|
+
|
1124
|
+
|
1125
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
1126
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
1127
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
1128
|
+
returnValue,UnboundHandlerErr);
|
1129
|
+
|
1130
|
+
|
1131
|
+
#if PROFILING_FUNCTIONS
|
1132
|
+
EndProfile(theEnv,&profileFrame);
|
1133
|
+
#endif
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
#if DEBUGGING_FUNCTIONS
|
1137
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1138
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
1139
|
+
if (MessageHandlerData(theEnv)->WatchMessages)
|
1140
|
+
WatchMessage(theEnv,STDOUT,END_TRACE);
|
1141
|
+
#endif
|
1142
|
+
}
|
1143
|
+
else
|
1144
|
+
{
|
1145
|
+
MessageHandlerData(theEnv)->CurrentCore = NULL;
|
1146
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore;
|
1147
|
+
#if DEBUGGING_FUNCTIONS
|
1148
|
+
if (MessageHandlerData(theEnv)->WatchMessages)
|
1149
|
+
WatchMessage(theEnv,STDOUT,BEGIN_TRACE);
|
1150
|
+
#endif
|
1151
|
+
CallHandlers(theEnv,returnValue);
|
1152
|
+
#if DEBUGGING_FUNCTIONS
|
1153
|
+
if (MessageHandlerData(theEnv)->WatchMessages)
|
1154
|
+
WatchMessage(theEnv,STDOUT,END_TRACE);
|
1155
|
+
#endif
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
DestroyHandlerLinks(theEnv,MessageHandlerData(theEnv)->TopOfCore);
|
1159
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1160
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1161
|
+
}
|
1162
|
+
|
1163
|
+
/* MessageHandlerData(theEnv)->TopOfCore = oldCore; */
|
1164
|
+
MessageHandlerData(theEnv)->TopOfCore = MessageHandlerData(theEnv)->OldCore;
|
1165
|
+
if (MessageHandlerData(theEnv)->OldCore != NULL)
|
1166
|
+
{ MessageHandlerData(theEnv)->OldCore = MessageHandlerData(theEnv)->OldCore->nxtInStack; }
|
1167
|
+
|
1168
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
1169
|
+
|
1170
|
+
if (ins != NULL)
|
1171
|
+
ins->busy--;
|
1172
|
+
|
1173
|
+
/* ==================================
|
1174
|
+
Restore the original calling frame
|
1175
|
+
================================== */
|
1176
|
+
PopProcParameters(theEnv);
|
1177
|
+
EvaluationData(theEnv)->CurrentEvaluationDepth--;
|
1178
|
+
MessageHandlerData(theEnv)->CurrentMessageName = oldName;
|
1179
|
+
|
1180
|
+
GCBlockEndUDF(theEnv,&gcb,returnValue);
|
1181
|
+
CallPeriodicTasks(theEnv);
|
1182
|
+
|
1183
|
+
SetExecutingConstruct(theEnv,oldce);
|
1184
|
+
|
1185
|
+
if (EvaluationData(theEnv)->EvaluationError)
|
1186
|
+
{
|
1187
|
+
returnValue->value = FalseSymbol(theEnv);
|
1188
|
+
return false;
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
return true;
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
/*****************************************************************************
|
1195
|
+
NAME : FindApplicableHandlers
|
1196
|
+
DESCRIPTION : Given a message name, this routine forms the "core frame"
|
1197
|
+
for the message : a list of all applicable class handlers.
|
1198
|
+
An applicable class handler is one whose name matches
|
1199
|
+
the message and whose class matches the instance.
|
1200
|
+
|
1201
|
+
The list is in the following order :
|
1202
|
+
|
1203
|
+
All around handlers (from most specific to most general)
|
1204
|
+
All before handlers (from most specific to most general)
|
1205
|
+
All primary handlers (from most specific to most general)
|
1206
|
+
All after handlers (from most general to most specific)
|
1207
|
+
|
1208
|
+
INPUTS : 1) The class of the instance (or primitive) for the message
|
1209
|
+
2) The message name
|
1210
|
+
RETURNS : NULL if no applicable handlers or errors,
|
1211
|
+
the list of handlers otherwise
|
1212
|
+
SIDE EFFECTS : Links are allocated for the list
|
1213
|
+
NOTES : The instance is the first thing on the ProcParamArray
|
1214
|
+
The number of arguments is in ProcParamArraySize
|
1215
|
+
*****************************************************************************/
|
1216
|
+
static HANDLER_LINK *FindApplicableHandlers(
|
1217
|
+
Environment *theEnv,
|
1218
|
+
Defclass *cls,
|
1219
|
+
CLIPSLexeme *mname)
|
1220
|
+
{
|
1221
|
+
unsigned int i;
|
1222
|
+
HANDLER_LINK *tops[4],*bots[4];
|
1223
|
+
|
1224
|
+
for (i = MAROUND ; i <= MAFTER ; i++)
|
1225
|
+
tops[i] = bots[i] = NULL;
|
1226
|
+
|
1227
|
+
for (i = 0 ; i < cls->allSuperclasses.classCount ; i++)
|
1228
|
+
FindApplicableOfName(theEnv,cls->allSuperclasses.classArray[i],tops,bots,mname);
|
1229
|
+
return(JoinHandlerLinks(theEnv,tops,bots,mname));
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
/***************************************************************
|
1233
|
+
NAME : CallHandlers
|
1234
|
+
DESCRIPTION : Moves though the current message frame
|
1235
|
+
for a send-message as follows :
|
1236
|
+
|
1237
|
+
Call all before handlers and ignore their
|
1238
|
+
return values.
|
1239
|
+
Call the first primary handler and
|
1240
|
+
ignore the rest. The return value
|
1241
|
+
of the handler frame is this message's value.
|
1242
|
+
Call all after handlers and ignore their
|
1243
|
+
return values.
|
1244
|
+
INPUTS : Caller's buffer for the return value of
|
1245
|
+
the message
|
1246
|
+
RETURNS : Nothing useful
|
1247
|
+
SIDE EFFECTS : The handlers are evaluated.
|
1248
|
+
NOTES : IMPORTANT : The global NextInCore should be
|
1249
|
+
pointing to the first handler to be executed.
|
1250
|
+
***************************************************************/
|
1251
|
+
static void CallHandlers(
|
1252
|
+
Environment *theEnv,
|
1253
|
+
UDFValue *returnValue)
|
1254
|
+
{
|
1255
|
+
HANDLER_LINK *oldCurrent = NULL,*oldNext = NULL; /* prevents warning */
|
1256
|
+
UDFValue temp;
|
1257
|
+
#if PROFILING_FUNCTIONS
|
1258
|
+
struct profileFrameInfo profileFrame;
|
1259
|
+
#endif
|
1260
|
+
|
1261
|
+
if (EvaluationData(theEnv)->HaltExecution)
|
1262
|
+
return;
|
1263
|
+
|
1264
|
+
oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
|
1265
|
+
oldNext = MessageHandlerData(theEnv)->NextInCore;
|
1266
|
+
|
1267
|
+
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MBEFORE)
|
1268
|
+
{
|
1269
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
|
1270
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
1271
|
+
#if DEBUGGING_FUNCTIONS
|
1272
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1273
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
1274
|
+
#endif
|
1275
|
+
if (CheckHandlerArgCount(theEnv))
|
1276
|
+
{
|
1277
|
+
#if PROFILING_FUNCTIONS
|
1278
|
+
StartProfile(theEnv,&profileFrame,
|
1279
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
1280
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
1281
|
+
#endif
|
1282
|
+
|
1283
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
1284
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
1285
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
1286
|
+
&temp,UnboundHandlerErr);
|
1287
|
+
|
1288
|
+
|
1289
|
+
#if PROFILING_FUNCTIONS
|
1290
|
+
EndProfile(theEnv,&profileFrame);
|
1291
|
+
#endif
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
#if DEBUGGING_FUNCTIONS
|
1295
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1296
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
1297
|
+
#endif
|
1298
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
1299
|
+
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
|
1300
|
+
{
|
1301
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1302
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1303
|
+
return;
|
1304
|
+
}
|
1305
|
+
}
|
1306
|
+
if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
|
1307
|
+
{
|
1308
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
|
1309
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
1310
|
+
#if DEBUGGING_FUNCTIONS
|
1311
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1312
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
1313
|
+
#endif
|
1314
|
+
if (CheckHandlerArgCount(theEnv))
|
1315
|
+
{
|
1316
|
+
#if PROFILING_FUNCTIONS
|
1317
|
+
StartProfile(theEnv,&profileFrame,
|
1318
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
1319
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
1320
|
+
#endif
|
1321
|
+
|
1322
|
+
|
1323
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
1324
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
1325
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
1326
|
+
returnValue,UnboundHandlerErr);
|
1327
|
+
|
1328
|
+
#if PROFILING_FUNCTIONS
|
1329
|
+
EndProfile(theEnv,&profileFrame);
|
1330
|
+
#endif
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
|
1334
|
+
#if DEBUGGING_FUNCTIONS
|
1335
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1336
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
1337
|
+
#endif
|
1338
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
1339
|
+
|
1340
|
+
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
|
1341
|
+
{
|
1342
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1343
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1344
|
+
return;
|
1345
|
+
}
|
1346
|
+
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
|
1347
|
+
{
|
1348
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
1349
|
+
if (MessageHandlerData(theEnv)->NextInCore == NULL)
|
1350
|
+
{
|
1351
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1352
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1353
|
+
return;
|
1354
|
+
}
|
1355
|
+
}
|
1356
|
+
}
|
1357
|
+
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAFTER)
|
1358
|
+
{
|
1359
|
+
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
|
1360
|
+
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
|
1361
|
+
#if DEBUGGING_FUNCTIONS
|
1362
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1363
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
|
1364
|
+
#endif
|
1365
|
+
if (CheckHandlerArgCount(theEnv))
|
1366
|
+
{
|
1367
|
+
#if PROFILING_FUNCTIONS
|
1368
|
+
StartProfile(theEnv,&profileFrame,
|
1369
|
+
&MessageHandlerData(theEnv)->CurrentCore->hnd->header.usrData,
|
1370
|
+
ProfileFunctionData(theEnv)->ProfileConstructs);
|
1371
|
+
#endif
|
1372
|
+
|
1373
|
+
|
1374
|
+
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
|
1375
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
|
1376
|
+
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
|
1377
|
+
&temp,UnboundHandlerErr);
|
1378
|
+
|
1379
|
+
#if PROFILING_FUNCTIONS
|
1380
|
+
EndProfile(theEnv,&profileFrame);
|
1381
|
+
#endif
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
|
1385
|
+
#if DEBUGGING_FUNCTIONS
|
1386
|
+
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
|
1387
|
+
WatchHandler(theEnv,STDOUT,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
|
1388
|
+
#endif
|
1389
|
+
ProcedureFunctionData(theEnv)->ReturnFlag = false;
|
1390
|
+
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
|
1391
|
+
{
|
1392
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1393
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1394
|
+
return;
|
1395
|
+
}
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
MessageHandlerData(theEnv)->NextInCore = oldNext;
|
1399
|
+
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
|
1403
|
+
/********************************************************
|
1404
|
+
NAME : EarlySlotBindError
|
1405
|
+
DESCRIPTION : Prints out an error message when
|
1406
|
+
a message-handler from a superclass
|
1407
|
+
which contains a static-bind
|
1408
|
+
slot access is not valid for the
|
1409
|
+
currently active instance (i.e.
|
1410
|
+
the instance is not using the
|
1411
|
+
superclass's slot)
|
1412
|
+
INPUTS : 1) The currently active instance
|
1413
|
+
2) The defclass holding the invalid slot
|
1414
|
+
3) The canonical id of the slot
|
1415
|
+
RETURNS : Nothing useful
|
1416
|
+
SIDE EFFECTS : Error message printed
|
1417
|
+
NOTES : None
|
1418
|
+
********************************************************/
|
1419
|
+
static void EarlySlotBindError(
|
1420
|
+
Environment *theEnv,
|
1421
|
+
Instance *theInstance,
|
1422
|
+
Defclass *theDefclass,
|
1423
|
+
unsigned slotID)
|
1424
|
+
{
|
1425
|
+
SlotDescriptor *sd;
|
1426
|
+
|
1427
|
+
sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[slotID] - 1];
|
1428
|
+
PrintErrorID(theEnv,"MSGPASS",3,false);
|
1429
|
+
WriteString(theEnv,STDERR,"Static reference to slot '");
|
1430
|
+
WriteString(theEnv,STDERR,sd->slotName->name->contents);
|
1431
|
+
WriteString(theEnv,STDERR,"' of class ");
|
1432
|
+
PrintClassName(theEnv,STDERR,theDefclass,true,false);
|
1433
|
+
WriteString(theEnv,STDERR," does not apply to instance [");
|
1434
|
+
WriteString(theEnv,STDERR,InstanceName(theInstance));
|
1435
|
+
WriteString(theEnv,STDERR,"] of class ");
|
1436
|
+
PrintClassName(theEnv,STDERR,theInstance->cls,true,false);
|
1437
|
+
WriteString(theEnv,STDERR,".\n");
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
#endif /* OBJECT_SYSTEM */
|
1441
|
+
|