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