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,1112 @@
|
|
1
|
+
/*******************************************************/
|
2
|
+
/* "C" Language Integrated Production System */
|
3
|
+
/* */
|
4
|
+
/* CLIPS Version 6.40 12/17/18 */
|
5
|
+
/* */
|
6
|
+
/* EXPRESSION PARSER MODULE */
|
7
|
+
/*******************************************************/
|
8
|
+
|
9
|
+
/*************************************************************/
|
10
|
+
/* Purpose: Provides routines for parsing expressions. */
|
11
|
+
/* */
|
12
|
+
/* Principal Programmer(s): */
|
13
|
+
/* Gary D. Riley */
|
14
|
+
/* */
|
15
|
+
/* Contributing Programmer(s): */
|
16
|
+
/* Brian L. Dantes */
|
17
|
+
/* */
|
18
|
+
/* Revision History: */
|
19
|
+
/* */
|
20
|
+
/* 6.23: Changed name of variable exp to theExp */
|
21
|
+
/* because of Unix compiler warnings of shadowed */
|
22
|
+
/* definitions. */
|
23
|
+
/* */
|
24
|
+
/* 6.24: Renamed BOOLEAN macro type to intBool. */
|
25
|
+
/* */
|
26
|
+
/* 6.30: Module specifier can be used within an */
|
27
|
+
/* expression to refer to a deffunction or */
|
28
|
+
/* defgeneric exported by the specified module, */
|
29
|
+
/* but not necessarily imported by the current */
|
30
|
+
/* module. */
|
31
|
+
/* */
|
32
|
+
/* Added const qualifiers to remove C++ */
|
33
|
+
/* deprecation warnings. */
|
34
|
+
/* */
|
35
|
+
/* Converted API macros to function calls. */
|
36
|
+
/* */
|
37
|
+
/* Changed find construct functionality so that */
|
38
|
+
/* imported modules are search when locating a */
|
39
|
+
/* named construct. */
|
40
|
+
/* */
|
41
|
+
/* 6.31: Fixed bug where sequence expansion was always */
|
42
|
+
/* occurring when using $ with global variables. */
|
43
|
+
/* */
|
44
|
+
/* Fast router used for ParseConstantArguments. */
|
45
|
+
/* */
|
46
|
+
/* Fixed crash bug when module separator :: is */
|
47
|
+
/* used but no module name specified. */
|
48
|
+
/* */
|
49
|
+
/* 6.40: Changed restrictions from char * to */
|
50
|
+
/* CLIPSLexeme * to support strings */
|
51
|
+
/* originating from sources that are not */
|
52
|
+
/* statically allocated. */
|
53
|
+
/* */
|
54
|
+
/* Pragma once and other inclusion changes. */
|
55
|
+
/* */
|
56
|
+
/* Added support for booleans with <stdbool.h>. */
|
57
|
+
/* */
|
58
|
+
/* Removed use of void pointers for specific */
|
59
|
+
/* data structures. */
|
60
|
+
/* */
|
61
|
+
/* ALLOW_ENVIRONMENT_GLOBALS no longer supported. */
|
62
|
+
/* */
|
63
|
+
/* Static constraint checking is always enabled. */
|
64
|
+
/* */
|
65
|
+
/* UDF redesign. */
|
66
|
+
/* */
|
67
|
+
/* Eval support for run time and bload only. */
|
68
|
+
/* */
|
69
|
+
/*************************************************************/
|
70
|
+
|
71
|
+
#include "setup.h"
|
72
|
+
|
73
|
+
#include <stdio.h>
|
74
|
+
#include <stdlib.h>
|
75
|
+
#include <string.h>
|
76
|
+
#include <ctype.h>
|
77
|
+
|
78
|
+
#include "argacces.h"
|
79
|
+
#include "constant.h"
|
80
|
+
#include "cstrnchk.h"
|
81
|
+
#include "envrnmnt.h"
|
82
|
+
#include "expressn.h"
|
83
|
+
#include "memalloc.h"
|
84
|
+
#include "modulutl.h"
|
85
|
+
#include "pprint.h"
|
86
|
+
#include "prcdrfun.h"
|
87
|
+
#include "prntutil.h"
|
88
|
+
#include "router.h"
|
89
|
+
#include "scanner.h"
|
90
|
+
#include "strngrtr.h"
|
91
|
+
|
92
|
+
#if DEFRULE_CONSTRUCT
|
93
|
+
#include "network.h"
|
94
|
+
#endif
|
95
|
+
|
96
|
+
#if DEFGENERIC_CONSTRUCT
|
97
|
+
#include "genrccom.h"
|
98
|
+
#endif
|
99
|
+
|
100
|
+
#if DEFFUNCTION_CONSTRUCT
|
101
|
+
#include "dffnxfun.h"
|
102
|
+
#endif
|
103
|
+
|
104
|
+
#include "exprnpsr.h"
|
105
|
+
|
106
|
+
#if (! RUN_TIME)
|
107
|
+
|
108
|
+
/***************************************************/
|
109
|
+
/* Function0Parse: Parses a function. Assumes that */
|
110
|
+
/* none of the function has been parsed yet. */
|
111
|
+
/***************************************************/
|
112
|
+
struct expr *Function0Parse(
|
113
|
+
Environment *theEnv,
|
114
|
+
const char *logicalName)
|
115
|
+
{
|
116
|
+
struct token theToken;
|
117
|
+
struct expr *top;
|
118
|
+
|
119
|
+
/*=================================*/
|
120
|
+
/* All functions begin with a '('. */
|
121
|
+
/*=================================*/
|
122
|
+
|
123
|
+
GetToken(theEnv,logicalName,&theToken);
|
124
|
+
if (theToken.tknType != LEFT_PARENTHESIS_TOKEN)
|
125
|
+
{
|
126
|
+
SyntaxErrorMessage(theEnv,"function calls");
|
127
|
+
return NULL;
|
128
|
+
}
|
129
|
+
|
130
|
+
/*=================================*/
|
131
|
+
/* Parse the rest of the function. */
|
132
|
+
/*=================================*/
|
133
|
+
|
134
|
+
top = Function1Parse(theEnv,logicalName);
|
135
|
+
return(top);
|
136
|
+
}
|
137
|
+
|
138
|
+
#endif
|
139
|
+
|
140
|
+
/*******************************************************/
|
141
|
+
/* Function1Parse: Parses a function. Assumes that the */
|
142
|
+
/* opening left parenthesis has already been parsed. */
|
143
|
+
/*******************************************************/
|
144
|
+
struct expr *Function1Parse(
|
145
|
+
Environment *theEnv,
|
146
|
+
const char *logicalName)
|
147
|
+
{
|
148
|
+
struct token theToken;
|
149
|
+
struct expr *top;
|
150
|
+
|
151
|
+
/*========================*/
|
152
|
+
/* Get the function name. */
|
153
|
+
/*========================*/
|
154
|
+
|
155
|
+
GetToken(theEnv,logicalName,&theToken);
|
156
|
+
if (theToken.tknType != SYMBOL_TOKEN)
|
157
|
+
{
|
158
|
+
PrintErrorID(theEnv,"EXPRNPSR",1,true);
|
159
|
+
WriteString(theEnv,STDERR,"A function name must be a symbol.\n");
|
160
|
+
return NULL;
|
161
|
+
}
|
162
|
+
|
163
|
+
/*=================================*/
|
164
|
+
/* Parse the rest of the function. */
|
165
|
+
/*=================================*/
|
166
|
+
|
167
|
+
top = Function2Parse(theEnv,logicalName,theToken.lexemeValue->contents);
|
168
|
+
return(top);
|
169
|
+
}
|
170
|
+
|
171
|
+
/****************************************************/
|
172
|
+
/* Function2Parse: Parses a function. Assumes that */
|
173
|
+
/* the opening left parenthesis and function name */
|
174
|
+
/* have already been parsed. */
|
175
|
+
/****************************************************/
|
176
|
+
struct expr *Function2Parse(
|
177
|
+
Environment *theEnv,
|
178
|
+
const char *logicalName,
|
179
|
+
const char *name)
|
180
|
+
{
|
181
|
+
struct functionDefinition *theFunction;
|
182
|
+
struct expr *top;
|
183
|
+
bool moduleSpecified = false;
|
184
|
+
unsigned position;
|
185
|
+
CLIPSLexeme *moduleName = NULL, *constructName = NULL;
|
186
|
+
#if DEFGENERIC_CONSTRUCT
|
187
|
+
Defgeneric *gfunc;
|
188
|
+
#endif
|
189
|
+
#if DEFFUNCTION_CONSTRUCT
|
190
|
+
Deffunction *dptr;
|
191
|
+
#endif
|
192
|
+
|
193
|
+
/*==============================*/
|
194
|
+
/* Look for a module specifier. */
|
195
|
+
/*==============================*/
|
196
|
+
|
197
|
+
if ((position = FindModuleSeparator(name)) != 0)
|
198
|
+
{
|
199
|
+
moduleName = ExtractModuleName(theEnv,position,name);
|
200
|
+
|
201
|
+
if (moduleName == NULL)
|
202
|
+
{
|
203
|
+
PrintErrorID(theEnv,"EXPRNPSR",7,true);
|
204
|
+
WriteString(theEnv,STDERR,"Missing module name for '");
|
205
|
+
WriteString(theEnv,STDERR,name);
|
206
|
+
WriteString(theEnv,STDERR,"'.\n");
|
207
|
+
return NULL;
|
208
|
+
}
|
209
|
+
|
210
|
+
constructName = ExtractConstructName(theEnv,position,name,SYMBOL_TYPE);
|
211
|
+
moduleSpecified = true;
|
212
|
+
}
|
213
|
+
|
214
|
+
/*================================*/
|
215
|
+
/* Has the function been defined? */
|
216
|
+
/*================================*/
|
217
|
+
|
218
|
+
theFunction = FindFunction(theEnv,name);
|
219
|
+
|
220
|
+
#if DEFGENERIC_CONSTRUCT
|
221
|
+
if (moduleSpecified)
|
222
|
+
{
|
223
|
+
if (ConstructExported(theEnv,"defgeneric",moduleName,constructName) ||
|
224
|
+
GetCurrentModule(theEnv) == FindDefmodule(theEnv,moduleName->contents))
|
225
|
+
{ gfunc = FindDefgenericInModule(theEnv,name); }
|
226
|
+
else
|
227
|
+
{ gfunc = NULL; }
|
228
|
+
}
|
229
|
+
else
|
230
|
+
{ gfunc = LookupDefgenericInScope(theEnv,name); }
|
231
|
+
#endif
|
232
|
+
|
233
|
+
#if DEFFUNCTION_CONSTRUCT
|
234
|
+
#if DEFGENERIC_CONSTRUCT
|
235
|
+
if ((theFunction == NULL)
|
236
|
+
&& (gfunc == NULL))
|
237
|
+
#else
|
238
|
+
if (theFunction == NULL)
|
239
|
+
#endif
|
240
|
+
if (moduleSpecified)
|
241
|
+
{
|
242
|
+
if (ConstructExported(theEnv,"deffunction",moduleName,constructName) ||
|
243
|
+
GetCurrentModule(theEnv) == FindDefmodule(theEnv,moduleName->contents))
|
244
|
+
{ dptr = FindDeffunctionInModule(theEnv,name); }
|
245
|
+
else
|
246
|
+
{ dptr = NULL; }
|
247
|
+
}
|
248
|
+
else
|
249
|
+
{ dptr = LookupDeffunctionInScope(theEnv,name); }
|
250
|
+
else
|
251
|
+
dptr = NULL;
|
252
|
+
#endif
|
253
|
+
|
254
|
+
/*=============================*/
|
255
|
+
/* Define top level structure. */
|
256
|
+
/*=============================*/
|
257
|
+
|
258
|
+
#if DEFFUNCTION_CONSTRUCT
|
259
|
+
if (dptr != NULL)
|
260
|
+
top = GenConstant(theEnv,PCALL,dptr);
|
261
|
+
else
|
262
|
+
#endif
|
263
|
+
#if DEFGENERIC_CONSTRUCT
|
264
|
+
if (gfunc != NULL)
|
265
|
+
top = GenConstant(theEnv,GCALL,gfunc);
|
266
|
+
else
|
267
|
+
#endif
|
268
|
+
if (theFunction != NULL)
|
269
|
+
top = GenConstant(theEnv,FCALL,theFunction);
|
270
|
+
else
|
271
|
+
{
|
272
|
+
PrintErrorID(theEnv,"EXPRNPSR",3,true);
|
273
|
+
WriteString(theEnv,STDERR,"Missing function declaration for '");
|
274
|
+
WriteString(theEnv,STDERR,name);
|
275
|
+
WriteString(theEnv,STDERR,"'.\n");
|
276
|
+
return NULL;
|
277
|
+
}
|
278
|
+
|
279
|
+
/*=======================================================*/
|
280
|
+
/* Check to see if function has its own parsing routine. */
|
281
|
+
/*=======================================================*/
|
282
|
+
|
283
|
+
PushRtnBrkContexts(theEnv);
|
284
|
+
ExpressionData(theEnv)->ReturnContext = false;
|
285
|
+
ExpressionData(theEnv)->BreakContext = false;
|
286
|
+
|
287
|
+
#if DEFGENERIC_CONSTRUCT || DEFFUNCTION_CONSTRUCT
|
288
|
+
if (top->type == FCALL)
|
289
|
+
#endif
|
290
|
+
{
|
291
|
+
if (theFunction->parser != NULL)
|
292
|
+
{
|
293
|
+
top = (*theFunction->parser)(theEnv,top,logicalName);
|
294
|
+
PopRtnBrkContexts(theEnv);
|
295
|
+
if (top == NULL) return NULL;
|
296
|
+
if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"),
|
297
|
+
FindFunction(theEnv,"expand$")))
|
298
|
+
{
|
299
|
+
ReturnExpression(theEnv,top);
|
300
|
+
return NULL;
|
301
|
+
}
|
302
|
+
return(top);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
/*========================================*/
|
307
|
+
/* Default parsing routine for functions. */
|
308
|
+
/*========================================*/
|
309
|
+
|
310
|
+
top = CollectArguments(theEnv,top,logicalName);
|
311
|
+
PopRtnBrkContexts(theEnv);
|
312
|
+
if (top == NULL) return NULL;
|
313
|
+
|
314
|
+
if (ReplaceSequenceExpansionOps(theEnv,top->argList,top,FindFunction(theEnv,"(expansion-call)"),
|
315
|
+
FindFunction(theEnv,"expand$")))
|
316
|
+
{
|
317
|
+
ReturnExpression(theEnv,top);
|
318
|
+
return NULL;
|
319
|
+
}
|
320
|
+
|
321
|
+
/*============================================================*/
|
322
|
+
/* If the function call uses the sequence expansion operator, */
|
323
|
+
/* its arguments cannot be checked until runtime. */
|
324
|
+
/*============================================================*/
|
325
|
+
|
326
|
+
if (top->value == FindFunction(theEnv,"(expansion-call)"))
|
327
|
+
{ return(top); }
|
328
|
+
|
329
|
+
/*============================*/
|
330
|
+
/* Check for argument errors. */
|
331
|
+
/*============================*/
|
332
|
+
|
333
|
+
if (top->type == FCALL)
|
334
|
+
{
|
335
|
+
if (CheckExpressionAgainstRestrictions(theEnv,top,theFunction,name))
|
336
|
+
{
|
337
|
+
ReturnExpression(theEnv,top);
|
338
|
+
return NULL;
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
#if DEFFUNCTION_CONSTRUCT
|
343
|
+
else if (top->type == PCALL)
|
344
|
+
{
|
345
|
+
if (CheckDeffunctionCall(theEnv,(Deffunction *) top->value,CountArguments(top->argList)) == false)
|
346
|
+
{
|
347
|
+
ReturnExpression(theEnv,top);
|
348
|
+
return NULL;
|
349
|
+
}
|
350
|
+
}
|
351
|
+
#endif
|
352
|
+
|
353
|
+
/*========================*/
|
354
|
+
/* Return the expression. */
|
355
|
+
/*========================*/
|
356
|
+
|
357
|
+
return(top);
|
358
|
+
}
|
359
|
+
|
360
|
+
/***********************************************************************
|
361
|
+
NAME : ReplaceSequenceExpansionOps
|
362
|
+
DESCRIPTION : Replaces function calls which have multifield
|
363
|
+
references as arguments into a call to a
|
364
|
+
special function which expands the multifield
|
365
|
+
into single arguments at run-time.
|
366
|
+
Multifield references which are not function
|
367
|
+
arguments are errors
|
368
|
+
INPUTS : 1) The expression
|
369
|
+
2) The current function call
|
370
|
+
3) The address of the internal H/L function
|
371
|
+
(expansion-call)
|
372
|
+
4) The address of the H/L function expand$
|
373
|
+
RETURNS : False if OK, true on errors
|
374
|
+
SIDE EFFECTS : Function call expressions modified, if necessary
|
375
|
+
NOTES : Function calls which truly want a multifield
|
376
|
+
to be passed need use only a single-field
|
377
|
+
refernce (i.e. ? instead of $? - the $ is
|
378
|
+
being treated as a special expansion operator)
|
379
|
+
**********************************************************************/
|
380
|
+
bool ReplaceSequenceExpansionOps(
|
381
|
+
Environment *theEnv,
|
382
|
+
Expression *actions,
|
383
|
+
Expression *fcallexp,
|
384
|
+
void *expcall,
|
385
|
+
void *expmult)
|
386
|
+
{
|
387
|
+
Expression *theExp;
|
388
|
+
|
389
|
+
while (actions != NULL)
|
390
|
+
{
|
391
|
+
if ((ExpressionData(theEnv)->SequenceOpMode == false) &&
|
392
|
+
((actions->type == MF_VARIABLE) || (actions->type == MF_GBL_VARIABLE)))
|
393
|
+
{
|
394
|
+
if (actions->type == MF_VARIABLE)
|
395
|
+
{ actions->type = SF_VARIABLE; }
|
396
|
+
else if (actions->type == MF_GBL_VARIABLE)
|
397
|
+
{ actions->type = GBL_VARIABLE; }
|
398
|
+
}
|
399
|
+
|
400
|
+
if ((actions->type == MF_VARIABLE) || (actions->type == MF_GBL_VARIABLE) ||
|
401
|
+
(actions->value == expmult))
|
402
|
+
{
|
403
|
+
if ((fcallexp->type != FCALL) ? false :
|
404
|
+
(fcallexp->functionValue->sequenceuseok == false))
|
405
|
+
{
|
406
|
+
PrintErrorID(theEnv,"EXPRNPSR",4,false);
|
407
|
+
WriteString(theEnv,STDERR,"$ Sequence operator not a valid argument for function '");
|
408
|
+
WriteString(theEnv,STDERR,fcallexp->functionValue->callFunctionName->contents);
|
409
|
+
WriteString(theEnv,STDERR,"'.\n");
|
410
|
+
return true;
|
411
|
+
}
|
412
|
+
if (fcallexp->value != expcall)
|
413
|
+
{
|
414
|
+
theExp = GenConstant(theEnv,fcallexp->type,fcallexp->value);
|
415
|
+
theExp->argList = fcallexp->argList;
|
416
|
+
theExp->nextArg = NULL;
|
417
|
+
fcallexp->type = FCALL;
|
418
|
+
fcallexp->value = expcall;
|
419
|
+
fcallexp->argList = theExp;
|
420
|
+
}
|
421
|
+
if (actions->value != expmult)
|
422
|
+
{
|
423
|
+
theExp = GenConstant(theEnv,SF_VARIABLE,actions->value);
|
424
|
+
if (actions->type == MF_GBL_VARIABLE)
|
425
|
+
theExp->type = GBL_VARIABLE;
|
426
|
+
actions->argList = theExp;
|
427
|
+
actions->type = FCALL;
|
428
|
+
actions->value = expmult;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
if (actions->argList != NULL)
|
432
|
+
{
|
433
|
+
if ((actions->type == GCALL) ||
|
434
|
+
(actions->type == PCALL) ||
|
435
|
+
(actions->type == FCALL))
|
436
|
+
theExp = actions;
|
437
|
+
else
|
438
|
+
theExp = fcallexp;
|
439
|
+
if (ReplaceSequenceExpansionOps(theEnv,actions->argList,theExp,expcall,expmult))
|
440
|
+
return true;
|
441
|
+
}
|
442
|
+
actions = actions->nextArg;
|
443
|
+
}
|
444
|
+
return false;
|
445
|
+
}
|
446
|
+
|
447
|
+
/*************************************************/
|
448
|
+
/* PushRtnBrkContexts: Saves the current context */
|
449
|
+
/* for the break/return functions. */
|
450
|
+
/*************************************************/
|
451
|
+
void PushRtnBrkContexts(
|
452
|
+
Environment *theEnv)
|
453
|
+
{
|
454
|
+
SavedContexts *svtmp;
|
455
|
+
|
456
|
+
svtmp = get_struct(theEnv,savedContexts);
|
457
|
+
svtmp->rtn = ExpressionData(theEnv)->ReturnContext;
|
458
|
+
svtmp->brk = ExpressionData(theEnv)->BreakContext;
|
459
|
+
svtmp->nxt = ExpressionData(theEnv)->svContexts;
|
460
|
+
ExpressionData(theEnv)->svContexts = svtmp;
|
461
|
+
}
|
462
|
+
|
463
|
+
/***************************************************/
|
464
|
+
/* PopRtnBrkContexts: Restores the current context */
|
465
|
+
/* for the break/return functions. */
|
466
|
+
/***************************************************/
|
467
|
+
void PopRtnBrkContexts(
|
468
|
+
Environment *theEnv)
|
469
|
+
{
|
470
|
+
SavedContexts *svtmp;
|
471
|
+
|
472
|
+
ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn;
|
473
|
+
ExpressionData(theEnv)->BreakContext = ExpressionData(theEnv)->svContexts->brk;
|
474
|
+
svtmp = ExpressionData(theEnv)->svContexts;
|
475
|
+
ExpressionData(theEnv)->svContexts = ExpressionData(theEnv)->svContexts->nxt;
|
476
|
+
rtn_struct(theEnv,savedContexts,svtmp);
|
477
|
+
}
|
478
|
+
|
479
|
+
#if (! RUN_TIME)
|
480
|
+
|
481
|
+
/**********************/
|
482
|
+
/* RestrictionExists: */
|
483
|
+
/**********************/
|
484
|
+
bool RestrictionExists(
|
485
|
+
const char *restrictionString,
|
486
|
+
int position)
|
487
|
+
{
|
488
|
+
int i = 0, currentPosition = 0;
|
489
|
+
|
490
|
+
if (restrictionString == NULL)
|
491
|
+
{ return false; }
|
492
|
+
|
493
|
+
while (restrictionString[i] != '\0')
|
494
|
+
{
|
495
|
+
if (restrictionString[i] == ';')
|
496
|
+
{
|
497
|
+
if (currentPosition == position) return true;
|
498
|
+
currentPosition++;
|
499
|
+
}
|
500
|
+
i++;
|
501
|
+
}
|
502
|
+
|
503
|
+
if (position == currentPosition) return true;
|
504
|
+
|
505
|
+
return false;
|
506
|
+
}
|
507
|
+
|
508
|
+
#endif
|
509
|
+
|
510
|
+
/*****************************************************************/
|
511
|
+
/* CheckExpressionAgainstRestrictions: Compares the arguments to */
|
512
|
+
/* a function to the set of restrictions for that function to */
|
513
|
+
/* determine if any incompatibilities exist. If so, the value */
|
514
|
+
/* true is returned, otherwise false is returned. */
|
515
|
+
/*****************************************************************/
|
516
|
+
FunctionArgumentsError CheckExpressionAgainstRestrictions(
|
517
|
+
Environment *theEnv,
|
518
|
+
struct expr *theExpression,
|
519
|
+
struct functionDefinition *theFunction,
|
520
|
+
const char *functionName)
|
521
|
+
{
|
522
|
+
unsigned int j = 1;
|
523
|
+
unsigned short number1, number2;
|
524
|
+
unsigned short argCount;
|
525
|
+
struct expr *argPtr;
|
526
|
+
const char *restrictions;
|
527
|
+
unsigned defaultRestriction2, argRestriction2;
|
528
|
+
|
529
|
+
if (theFunction->restrictions == NULL)
|
530
|
+
{ restrictions = NULL; }
|
531
|
+
else
|
532
|
+
{ restrictions = theFunction->restrictions->contents; }
|
533
|
+
|
534
|
+
/*=========================================*/
|
535
|
+
/* Count the number of function arguments. */
|
536
|
+
/*=========================================*/
|
537
|
+
|
538
|
+
argCount = CountArguments(theExpression->argList);
|
539
|
+
|
540
|
+
/*======================================*/
|
541
|
+
/* Get the minimum number of arguments. */
|
542
|
+
/*======================================*/
|
543
|
+
|
544
|
+
number1 = theFunction->minArgs;
|
545
|
+
|
546
|
+
/*======================================*/
|
547
|
+
/* Get the maximum number of arguments. */
|
548
|
+
/*======================================*/
|
549
|
+
|
550
|
+
number2 = theFunction->maxArgs;
|
551
|
+
|
552
|
+
/*============================================*/
|
553
|
+
/* Check for the correct number of arguments. */
|
554
|
+
/*============================================*/
|
555
|
+
|
556
|
+
if ((number1 == UNBOUNDED) && (number2 == UNBOUNDED))
|
557
|
+
{ /* Any number of arguments allowed. */ }
|
558
|
+
else if (number1 == number2)
|
559
|
+
{
|
560
|
+
if (argCount != number1)
|
561
|
+
{
|
562
|
+
ExpectedCountError(theEnv,functionName,EXACTLY,number1);
|
563
|
+
return FAE_COUNT_ERROR;
|
564
|
+
}
|
565
|
+
}
|
566
|
+
else if (argCount < number1)
|
567
|
+
{
|
568
|
+
ExpectedCountError(theEnv,functionName,AT_LEAST,number1);
|
569
|
+
return FAE_COUNT_ERROR;
|
570
|
+
}
|
571
|
+
else if ((number2 != UNBOUNDED) && (argCount > number2))
|
572
|
+
{
|
573
|
+
ExpectedCountError(theEnv,functionName,NO_MORE_THAN,number2);
|
574
|
+
return FAE_COUNT_ERROR;
|
575
|
+
}
|
576
|
+
|
577
|
+
/*===============================================*/
|
578
|
+
/* Return if there are no argument restrictions. */
|
579
|
+
/*===============================================*/
|
580
|
+
|
581
|
+
if (restrictions == NULL) return FAE_NO_ERROR;
|
582
|
+
|
583
|
+
/*=======================================*/
|
584
|
+
/* Check for the default argument types. */
|
585
|
+
/*=======================================*/
|
586
|
+
|
587
|
+
PopulateRestriction(theEnv,&defaultRestriction2,ANY_TYPE_BITS,restrictions,0);
|
588
|
+
|
589
|
+
/*======================*/
|
590
|
+
/* Check each argument. */
|
591
|
+
/*======================*/
|
592
|
+
|
593
|
+
for (argPtr = theExpression->argList;
|
594
|
+
argPtr != NULL;
|
595
|
+
argPtr = argPtr->nextArg)
|
596
|
+
{
|
597
|
+
PopulateRestriction(theEnv,&argRestriction2,defaultRestriction2,restrictions,j);
|
598
|
+
|
599
|
+
if (CheckArgumentAgainstRestriction(theEnv,argPtr,argRestriction2))
|
600
|
+
{
|
601
|
+
ExpectedTypeError0(theEnv,functionName,j);
|
602
|
+
PrintTypesString(theEnv,STDERR,argRestriction2,true);
|
603
|
+
return FAE_TYPE_ERROR;
|
604
|
+
}
|
605
|
+
|
606
|
+
j++;
|
607
|
+
}
|
608
|
+
|
609
|
+
return FAE_NO_ERROR;
|
610
|
+
}
|
611
|
+
|
612
|
+
/*******************************************************/
|
613
|
+
/* CollectArguments: Parses and groups together all of */
|
614
|
+
/* the arguments for a function call expression. */
|
615
|
+
/*******************************************************/
|
616
|
+
struct expr *CollectArguments(
|
617
|
+
Environment *theEnv,
|
618
|
+
struct expr *top,
|
619
|
+
const char *logicalName)
|
620
|
+
{
|
621
|
+
bool errorFlag;
|
622
|
+
struct expr *lastOne, *nextOne;
|
623
|
+
|
624
|
+
/*========================================*/
|
625
|
+
/* Default parsing routine for functions. */
|
626
|
+
/*========================================*/
|
627
|
+
|
628
|
+
lastOne = NULL;
|
629
|
+
|
630
|
+
while (true)
|
631
|
+
{
|
632
|
+
SavePPBuffer(theEnv," ");
|
633
|
+
|
634
|
+
errorFlag = false;
|
635
|
+
nextOne = ArgumentParse(theEnv,logicalName,&errorFlag);
|
636
|
+
|
637
|
+
if (errorFlag == true)
|
638
|
+
{
|
639
|
+
ReturnExpression(theEnv,top);
|
640
|
+
return NULL;
|
641
|
+
}
|
642
|
+
|
643
|
+
if (nextOne == NULL)
|
644
|
+
{
|
645
|
+
PPBackup(theEnv);
|
646
|
+
PPBackup(theEnv);
|
647
|
+
SavePPBuffer(theEnv,")");
|
648
|
+
return(top);
|
649
|
+
}
|
650
|
+
|
651
|
+
if (lastOne == NULL)
|
652
|
+
{ top->argList = nextOne; }
|
653
|
+
else
|
654
|
+
{ lastOne->nextArg = nextOne; }
|
655
|
+
|
656
|
+
lastOne = nextOne;
|
657
|
+
}
|
658
|
+
}
|
659
|
+
|
660
|
+
/********************************************/
|
661
|
+
/* ArgumentParse: Parses an argument within */
|
662
|
+
/* a function call expression. */
|
663
|
+
/********************************************/
|
664
|
+
struct expr *ArgumentParse(
|
665
|
+
Environment *theEnv,
|
666
|
+
const char *logicalName,
|
667
|
+
bool *errorFlag)
|
668
|
+
{
|
669
|
+
struct expr *top;
|
670
|
+
struct token theToken;
|
671
|
+
|
672
|
+
/*===============*/
|
673
|
+
/* Grab a token. */
|
674
|
+
/*===============*/
|
675
|
+
|
676
|
+
GetToken(theEnv,logicalName,&theToken);
|
677
|
+
|
678
|
+
/*============================*/
|
679
|
+
/* ')' counts as no argument. */
|
680
|
+
/*============================*/
|
681
|
+
|
682
|
+
if (theToken.tknType == RIGHT_PARENTHESIS_TOKEN)
|
683
|
+
{ return NULL; }
|
684
|
+
|
685
|
+
/*================================*/
|
686
|
+
/* Parse constants and variables. */
|
687
|
+
/*================================*/
|
688
|
+
|
689
|
+
if ((theToken.tknType == SF_VARIABLE_TOKEN) || (theToken.tknType == MF_VARIABLE_TOKEN) ||
|
690
|
+
(theToken.tknType == SYMBOL_TOKEN) || (theToken.tknType == STRING_TOKEN) ||
|
691
|
+
#if DEFGLOBAL_CONSTRUCT
|
692
|
+
(theToken.tknType == GBL_VARIABLE_TOKEN) ||
|
693
|
+
(theToken.tknType == MF_GBL_VARIABLE_TOKEN) ||
|
694
|
+
#endif
|
695
|
+
#if OBJECT_SYSTEM
|
696
|
+
(theToken.tknType == INSTANCE_NAME_TOKEN) ||
|
697
|
+
#endif
|
698
|
+
(theToken.tknType == FLOAT_TOKEN) || (theToken.tknType == INTEGER_TOKEN))
|
699
|
+
{ return(GenConstant(theEnv,TokenTypeToType(theToken.tknType),theToken.value)); }
|
700
|
+
|
701
|
+
/*======================*/
|
702
|
+
/* Parse function call. */
|
703
|
+
/*======================*/
|
704
|
+
|
705
|
+
if (theToken.tknType != LEFT_PARENTHESIS_TOKEN)
|
706
|
+
{
|
707
|
+
PrintErrorID(theEnv,"EXPRNPSR",2,true);
|
708
|
+
WriteString(theEnv,STDERR,"Expected a constant, variable, or expression.\n");
|
709
|
+
*errorFlag = true;
|
710
|
+
return NULL;
|
711
|
+
}
|
712
|
+
|
713
|
+
top = Function1Parse(theEnv,logicalName);
|
714
|
+
if (top == NULL) *errorFlag = true;
|
715
|
+
return(top);
|
716
|
+
}
|
717
|
+
|
718
|
+
/************************************************************/
|
719
|
+
/* ParseAtomOrExpression: Parses an expression which may be */
|
720
|
+
/* a function call, atomic value (string, symbol, etc.), */
|
721
|
+
/* or variable (local or global). */
|
722
|
+
/************************************************************/
|
723
|
+
struct expr *ParseAtomOrExpression(
|
724
|
+
Environment *theEnv,
|
725
|
+
const char *logicalName,
|
726
|
+
struct token *useToken)
|
727
|
+
{
|
728
|
+
struct token theToken, *thisToken;
|
729
|
+
struct expr *rv;
|
730
|
+
|
731
|
+
if (useToken == NULL)
|
732
|
+
{
|
733
|
+
thisToken = &theToken;
|
734
|
+
GetToken(theEnv,logicalName,thisToken);
|
735
|
+
}
|
736
|
+
else thisToken = useToken;
|
737
|
+
|
738
|
+
if ((thisToken->tknType == SYMBOL_TOKEN) || (thisToken->tknType == STRING_TOKEN) ||
|
739
|
+
(thisToken->tknType == INTEGER_TOKEN) || (thisToken->tknType == FLOAT_TOKEN) ||
|
740
|
+
#if OBJECT_SYSTEM
|
741
|
+
(thisToken->tknType == INSTANCE_NAME_TOKEN) ||
|
742
|
+
#endif
|
743
|
+
#if DEFGLOBAL_CONSTRUCT
|
744
|
+
(thisToken->tknType == GBL_VARIABLE_TOKEN) ||
|
745
|
+
(thisToken->tknType == MF_GBL_VARIABLE_TOKEN) ||
|
746
|
+
#endif
|
747
|
+
(thisToken->tknType == SF_VARIABLE_TOKEN) || (thisToken->tknType == MF_VARIABLE_TOKEN))
|
748
|
+
{ rv = GenConstant(theEnv,TokenTypeToType(thisToken->tknType),thisToken->value); }
|
749
|
+
else if (thisToken->tknType == LEFT_PARENTHESIS_TOKEN)
|
750
|
+
{
|
751
|
+
rv = Function1Parse(theEnv,logicalName);
|
752
|
+
if (rv == NULL) return NULL;
|
753
|
+
}
|
754
|
+
else
|
755
|
+
{
|
756
|
+
PrintErrorID(theEnv,"EXPRNPSR",2,true);
|
757
|
+
WriteString(theEnv,STDERR,"Expected a constant, variable, or expression.\n");
|
758
|
+
return NULL;
|
759
|
+
}
|
760
|
+
|
761
|
+
return(rv);
|
762
|
+
}
|
763
|
+
|
764
|
+
/*********************************************/
|
765
|
+
/* GroupActions: Groups together a series of */
|
766
|
+
/* actions within a progn expression. Used */
|
767
|
+
/* for example to parse the RHS of a rule. */
|
768
|
+
/*********************************************/
|
769
|
+
struct expr *GroupActions(
|
770
|
+
Environment *theEnv,
|
771
|
+
const char *logicalName,
|
772
|
+
struct token *theToken,
|
773
|
+
bool readFirstToken,
|
774
|
+
const char *endWord,
|
775
|
+
bool functionNameParsed)
|
776
|
+
{
|
777
|
+
struct expr *top, *nextOne, *lastOne = NULL;
|
778
|
+
|
779
|
+
/*=============================*/
|
780
|
+
/* Create the enclosing progn. */
|
781
|
+
/*=============================*/
|
782
|
+
|
783
|
+
top = GenConstant(theEnv,FCALL,FindFunction(theEnv,"progn"));
|
784
|
+
|
785
|
+
/*========================================================*/
|
786
|
+
/* Continue until all appropriate commands are processed. */
|
787
|
+
/*========================================================*/
|
788
|
+
|
789
|
+
while (true)
|
790
|
+
{
|
791
|
+
/*================================================*/
|
792
|
+
/* Skip reading in the token if this is the first */
|
793
|
+
/* pass and the initial token was already read */
|
794
|
+
/* before calling this function. */
|
795
|
+
/*================================================*/
|
796
|
+
|
797
|
+
if (readFirstToken)
|
798
|
+
{ GetToken(theEnv,logicalName,theToken); }
|
799
|
+
else
|
800
|
+
{ readFirstToken = true; }
|
801
|
+
|
802
|
+
/*=================================================*/
|
803
|
+
/* Look to see if a symbol has terminated the list */
|
804
|
+
/* of actions (such as "else" in an if function). */
|
805
|
+
/*=================================================*/
|
806
|
+
|
807
|
+
if ((theToken->tknType == SYMBOL_TOKEN) &&
|
808
|
+
(endWord != NULL) &&
|
809
|
+
(! functionNameParsed))
|
810
|
+
{
|
811
|
+
if (strcmp(theToken->lexemeValue->contents,endWord) == 0)
|
812
|
+
{ return(top); }
|
813
|
+
}
|
814
|
+
|
815
|
+
/*====================================*/
|
816
|
+
/* Process a function if the function */
|
817
|
+
/* name has already been read. */
|
818
|
+
/*====================================*/
|
819
|
+
|
820
|
+
if (functionNameParsed)
|
821
|
+
{
|
822
|
+
nextOne = Function2Parse(theEnv,logicalName,theToken->lexemeValue->contents);
|
823
|
+
functionNameParsed = false;
|
824
|
+
}
|
825
|
+
|
826
|
+
/*========================================*/
|
827
|
+
/* Process a constant or global variable. */
|
828
|
+
/*========================================*/
|
829
|
+
|
830
|
+
else if ((theToken->tknType == SYMBOL_TOKEN) || (theToken->tknType == STRING_TOKEN) ||
|
831
|
+
(theToken->tknType == INTEGER_TOKEN) || (theToken->tknType == FLOAT_TOKEN) ||
|
832
|
+
#if DEFGLOBAL_CONSTRUCT
|
833
|
+
(theToken->tknType == GBL_VARIABLE_TOKEN) ||
|
834
|
+
(theToken->tknType == MF_GBL_VARIABLE_TOKEN) ||
|
835
|
+
#endif
|
836
|
+
#if OBJECT_SYSTEM
|
837
|
+
(theToken->tknType == INSTANCE_NAME_TOKEN) ||
|
838
|
+
#endif
|
839
|
+
(theToken->tknType == SF_VARIABLE_TOKEN) || (theToken->tknType == MF_VARIABLE_TOKEN))
|
840
|
+
{ nextOne = GenConstant(theEnv,TokenTypeToType(theToken->tknType),theToken->value); }
|
841
|
+
|
842
|
+
/*=============================*/
|
843
|
+
/* Otherwise parse a function. */
|
844
|
+
/*=============================*/
|
845
|
+
|
846
|
+
else if (theToken->tknType == LEFT_PARENTHESIS_TOKEN)
|
847
|
+
{ nextOne = Function1Parse(theEnv,logicalName); }
|
848
|
+
|
849
|
+
/*======================================*/
|
850
|
+
/* Otherwise replace sequence expansion */
|
851
|
+
/* variables and return the expression. */
|
852
|
+
/*======================================*/
|
853
|
+
|
854
|
+
else
|
855
|
+
{
|
856
|
+
if (ReplaceSequenceExpansionOps(theEnv,top,NULL,
|
857
|
+
FindFunction(theEnv,"(expansion-call)"),
|
858
|
+
FindFunction(theEnv,"expand$")))
|
859
|
+
{
|
860
|
+
ReturnExpression(theEnv,top);
|
861
|
+
return NULL;
|
862
|
+
}
|
863
|
+
|
864
|
+
return(top);
|
865
|
+
}
|
866
|
+
|
867
|
+
/*===========================*/
|
868
|
+
/* Add the new action to the */
|
869
|
+
/* list of progn arguments. */
|
870
|
+
/*===========================*/
|
871
|
+
|
872
|
+
if (nextOne == NULL)
|
873
|
+
{
|
874
|
+
theToken->tknType = UNKNOWN_VALUE_TOKEN;
|
875
|
+
ReturnExpression(theEnv,top);
|
876
|
+
return NULL;
|
877
|
+
}
|
878
|
+
|
879
|
+
if (lastOne == NULL)
|
880
|
+
{ top->argList = nextOne; }
|
881
|
+
else
|
882
|
+
{ lastOne->nextArg = nextOne; }
|
883
|
+
|
884
|
+
lastOne = nextOne;
|
885
|
+
|
886
|
+
PPCRAndIndent(theEnv);
|
887
|
+
}
|
888
|
+
}
|
889
|
+
|
890
|
+
/************************/
|
891
|
+
/* PopulateRestriction: */
|
892
|
+
/************************/
|
893
|
+
void PopulateRestriction(
|
894
|
+
Environment *theEnv,
|
895
|
+
unsigned *restriction,
|
896
|
+
unsigned defaultRestriction,
|
897
|
+
const char *restrictionString,
|
898
|
+
unsigned int position)
|
899
|
+
{
|
900
|
+
unsigned int i = 0, currentPosition = 0, valuesRead = 0;
|
901
|
+
char buffer[2];
|
902
|
+
|
903
|
+
*restriction = 0;
|
904
|
+
|
905
|
+
if (restrictionString == NULL)
|
906
|
+
{
|
907
|
+
*restriction = defaultRestriction;
|
908
|
+
return;
|
909
|
+
}
|
910
|
+
|
911
|
+
while (restrictionString[i] != '\0')
|
912
|
+
{
|
913
|
+
char theChar = restrictionString[i];
|
914
|
+
|
915
|
+
switch(theChar)
|
916
|
+
{
|
917
|
+
case ';':
|
918
|
+
if (currentPosition == position) return;
|
919
|
+
currentPosition++;
|
920
|
+
*restriction = 0;
|
921
|
+
valuesRead = 0;
|
922
|
+
break;
|
923
|
+
|
924
|
+
case 'l':
|
925
|
+
*restriction |= INTEGER_BIT;
|
926
|
+
valuesRead++;
|
927
|
+
break;
|
928
|
+
|
929
|
+
case 'd':
|
930
|
+
*restriction |= FLOAT_BIT;
|
931
|
+
valuesRead++;
|
932
|
+
break;
|
933
|
+
|
934
|
+
case 's':
|
935
|
+
*restriction |= STRING_BIT;
|
936
|
+
valuesRead++;
|
937
|
+
break;
|
938
|
+
|
939
|
+
case 'y':
|
940
|
+
*restriction |= SYMBOL_BIT;
|
941
|
+
valuesRead++;
|
942
|
+
break;
|
943
|
+
|
944
|
+
case 'n':
|
945
|
+
*restriction |= INSTANCE_NAME_BIT;
|
946
|
+
valuesRead++;
|
947
|
+
break;
|
948
|
+
|
949
|
+
case 'm':
|
950
|
+
*restriction |= MULTIFIELD_BIT;
|
951
|
+
valuesRead++;
|
952
|
+
break;
|
953
|
+
|
954
|
+
case 'f':
|
955
|
+
*restriction |= FACT_ADDRESS_BIT;
|
956
|
+
valuesRead++;
|
957
|
+
break;
|
958
|
+
|
959
|
+
case 'i':
|
960
|
+
*restriction |= INSTANCE_ADDRESS_BIT;
|
961
|
+
valuesRead++;
|
962
|
+
break;
|
963
|
+
|
964
|
+
case 'e':
|
965
|
+
*restriction |= EXTERNAL_ADDRESS_BIT;
|
966
|
+
valuesRead++;
|
967
|
+
break;
|
968
|
+
|
969
|
+
case 'v':
|
970
|
+
*restriction |= VOID_BIT;
|
971
|
+
valuesRead++;
|
972
|
+
break;
|
973
|
+
|
974
|
+
case 'b':
|
975
|
+
*restriction |= BOOLEAN_BIT;
|
976
|
+
valuesRead++;
|
977
|
+
break;
|
978
|
+
|
979
|
+
case '*':
|
980
|
+
*restriction |= ANY_TYPE_BITS;
|
981
|
+
valuesRead++;
|
982
|
+
break;
|
983
|
+
|
984
|
+
default:
|
985
|
+
buffer[0] = theChar;
|
986
|
+
buffer[1] = 0;
|
987
|
+
WriteString(theEnv,STDERR,"Invalid argument type character ");
|
988
|
+
WriteString(theEnv,STDERR,buffer);
|
989
|
+
WriteString(theEnv,STDERR,"\n");
|
990
|
+
valuesRead++;
|
991
|
+
break;
|
992
|
+
}
|
993
|
+
|
994
|
+
i++;
|
995
|
+
}
|
996
|
+
|
997
|
+
if (position == currentPosition)
|
998
|
+
{
|
999
|
+
if (valuesRead == 0)
|
1000
|
+
{ *restriction = defaultRestriction; }
|
1001
|
+
return;
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
*restriction = defaultRestriction;
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
/*******************************************/
|
1008
|
+
/* ParseConstantArguments: Parses a string */
|
1009
|
+
/* into a set of constant expressions. */
|
1010
|
+
/*******************************************/
|
1011
|
+
Expression *ParseConstantArguments(
|
1012
|
+
Environment *theEnv,
|
1013
|
+
const char *argstr,
|
1014
|
+
bool *error)
|
1015
|
+
{
|
1016
|
+
Expression *top = NULL,*bot = NULL,*tmp;
|
1017
|
+
const char *router = "***FNXARGS***";
|
1018
|
+
struct token tkn;
|
1019
|
+
const char *oldRouter;
|
1020
|
+
const char *oldString;
|
1021
|
+
long oldIndex;
|
1022
|
+
|
1023
|
+
*error = false;
|
1024
|
+
|
1025
|
+
if (argstr == NULL) return NULL;
|
1026
|
+
|
1027
|
+
/*=============================*/
|
1028
|
+
/* Use the fast router bypass. */
|
1029
|
+
/*=============================*/
|
1030
|
+
|
1031
|
+
oldRouter = RouterData(theEnv)->FastCharGetRouter;
|
1032
|
+
oldString = RouterData(theEnv)->FastCharGetString;
|
1033
|
+
oldIndex = RouterData(theEnv)->FastCharGetIndex;
|
1034
|
+
|
1035
|
+
RouterData(theEnv)->FastCharGetRouter = router;
|
1036
|
+
RouterData(theEnv)->FastCharGetString = argstr;
|
1037
|
+
RouterData(theEnv)->FastCharGetIndex = 0;
|
1038
|
+
|
1039
|
+
/*======================*/
|
1040
|
+
/* Parse the constants. */
|
1041
|
+
/*======================*/
|
1042
|
+
|
1043
|
+
GetToken(theEnv,router,&tkn);
|
1044
|
+
while (tkn.tknType != STOP_TOKEN)
|
1045
|
+
{
|
1046
|
+
if ((tkn.tknType != SYMBOL_TOKEN) && (tkn.tknType != STRING_TOKEN) &&
|
1047
|
+
(tkn.tknType != FLOAT_TOKEN) && (tkn.tknType != INTEGER_TOKEN) &&
|
1048
|
+
(tkn.tknType != INSTANCE_NAME_TOKEN))
|
1049
|
+
{
|
1050
|
+
PrintErrorID(theEnv,"EXPRNPSR",6,false);
|
1051
|
+
WriteString(theEnv,STDERR,"Only constant arguments allowed for external function call.\n");
|
1052
|
+
ReturnExpression(theEnv,top);
|
1053
|
+
*error = true;
|
1054
|
+
CloseStringSource(theEnv,router);
|
1055
|
+
return NULL;
|
1056
|
+
}
|
1057
|
+
tmp = GenConstant(theEnv,TokenTypeToType(tkn.tknType),tkn.value);
|
1058
|
+
if (top == NULL)
|
1059
|
+
top = tmp;
|
1060
|
+
else
|
1061
|
+
bot->nextArg = tmp;
|
1062
|
+
bot = tmp;
|
1063
|
+
GetToken(theEnv,router,&tkn);
|
1064
|
+
}
|
1065
|
+
|
1066
|
+
/*===========================================*/
|
1067
|
+
/* Restore the old state of the fast router. */
|
1068
|
+
/*===========================================*/
|
1069
|
+
|
1070
|
+
RouterData(theEnv)->FastCharGetRouter = oldRouter;
|
1071
|
+
RouterData(theEnv)->FastCharGetString = oldString;
|
1072
|
+
RouterData(theEnv)->FastCharGetIndex = oldIndex;
|
1073
|
+
|
1074
|
+
/*=======================*/
|
1075
|
+
/* Return the arguments. */
|
1076
|
+
/*=======================*/
|
1077
|
+
|
1078
|
+
return(top);
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
/************************/
|
1082
|
+
/* RemoveUnneededProgn: */
|
1083
|
+
/************************/
|
1084
|
+
struct expr *RemoveUnneededProgn(
|
1085
|
+
Environment *theEnv,
|
1086
|
+
struct expr *theExpression)
|
1087
|
+
{
|
1088
|
+
struct functionDefinition *fptr;
|
1089
|
+
struct expr *temp;
|
1090
|
+
|
1091
|
+
if (theExpression == NULL) return(theExpression);
|
1092
|
+
|
1093
|
+
if (theExpression->type != FCALL) return(theExpression);
|
1094
|
+
|
1095
|
+
fptr = theExpression->functionValue;
|
1096
|
+
|
1097
|
+
if (fptr->functionPointer != PrognFunction)
|
1098
|
+
{ return(theExpression); }
|
1099
|
+
|
1100
|
+
if ((theExpression->argList != NULL) &&
|
1101
|
+
(theExpression->argList->nextArg == NULL))
|
1102
|
+
{
|
1103
|
+
temp = theExpression;
|
1104
|
+
theExpression = theExpression->argList;
|
1105
|
+
temp->argList = NULL;
|
1106
|
+
temp->nextArg = NULL;
|
1107
|
+
ReturnExpression(theEnv,temp);
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
return(theExpression);
|
1111
|
+
}
|
1112
|
+
|