clipsruby 0.0.39 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +359 -400
  3. data/ext/clipsruby/clipsruby.c +420 -31
  4. metadata +2 -2
@@ -476,31 +476,6 @@ static VALUE clips_environment_defclass_static_get_instance_list(int argc, VALUE
476
476
  }
477
477
 
478
478
 
479
- static VALUE clips_environment_make_instance(VALUE self, VALUE string)
480
- {
481
- Environment *env;
482
-
483
- TypedData_Get_Struct(self, Environment, &Environment_type, env);
484
-
485
- Instance *instance = MakeInstance(env, StringValueCStr(string));
486
-
487
- if (instance == NULL) {
488
- return Qnil;
489
- }
490
-
491
- VALUE rb_instance =
492
- TypedData_Wrap_Struct(rb_const_get(CLASS_OF(self), rb_intern("Instance")), &Instance_type, instance);
493
-
494
- rb_iv_set(rb_instance, "@environment", self);
495
-
496
- return rb_instance;
497
- }
498
-
499
- static VALUE clips_environment_static_make_instance(VALUE self, VALUE rbEnvironment, VALUE string)
500
- {
501
- return clips_environment_make_instance(rbEnvironment, string);
502
- }
503
-
504
479
  static VALUE clips_environment_instance_unmake(VALUE self)
505
480
  {
506
481
  Instance *instance;
@@ -869,6 +844,329 @@ static VALUE clips_environment_static_assert_hash(VALUE self, VALUE environment,
869
844
  return clips_environment_assert_hash(environment, deftemplate_name, hash);
870
845
  }
871
846
 
847
+ static int _clips_environment_make_instance(VALUE key, VALUE value, VALUE args)
848
+ {
849
+ const char *cslot_name;
850
+ switch(TYPE(key))
851
+ {
852
+ case T_SYMBOL:
853
+ cslot_name = rb_id2name(SYM2ID(key));
854
+ break;
855
+ case T_STRING:
856
+ cslot_name = StringValueCStr(key);
857
+ break;
858
+ default:
859
+ rb_raise(rb_eTypeError, "Slot name must be a String or a Symbol");
860
+ return ST_CONTINUE;
861
+ }
862
+
863
+ VALUE *ib_and_env = (VALUE*)args;
864
+ InstanceBuilder *ib = (InstanceBuilder*) ib_and_env[0];
865
+ Environment *env = (Environment*) ib_and_env[1];
866
+ CLIPSValue cv = VALUE_to_CLIPSValue(value, env);
867
+ handle_pse_error(IBPutSlot(ib, cslot_name, &cv), cslot_name);
868
+
869
+ return ST_CONTINUE;
870
+ }
871
+
872
+ static VALUE clips_environment_make_instance(int argc, VALUE *argv, VALUE rbEnvironment) {
873
+ VALUE first_argument, second_argument, third_argument, defclass_class, rb_instance;
874
+ Environment *env;
875
+ Defclass *defclass;
876
+ InstanceBuilder *ib;
877
+ Instance *instance;
878
+ const char *instance_name;
879
+
880
+ TypedData_Get_Struct(rbEnvironment, Environment, &Environment_type, env);
881
+
882
+ rb_scan_args(argc, argv, "12", &first_argument, &second_argument, &third_argument);
883
+
884
+ defclass_class = rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Defclass"));
885
+
886
+ // first argument must be a defclass
887
+ switch (TYPE(first_argument))
888
+ {
889
+ case T_OBJECT:
890
+ case T_DATA:
891
+ if (CLASS_OF(first_argument) == defclass_class) {
892
+ TypedData_Get_Struct(first_argument, Defclass, &Defclass_type, defclass);
893
+ ib = CreateInstanceBuilder(env, DefclassName(defclass));
894
+ break;
895
+ } else {
896
+ rb_warn("First argument must be a Defclass; first argument was an object, but not %s class; it was a %s", rb_class2name(defclass_class), rb_class2name(first_argument));
897
+ return Qnil;
898
+ }
899
+ case T_STRING:
900
+ ib = CreateInstanceBuilder(env, StringValueCStr(first_argument));
901
+ break;
902
+ case T_SYMBOL:
903
+ ib = CreateInstanceBuilder(env, rb_id2name(SYM2ID(first_argument)));
904
+ break;
905
+ default:
906
+ rb_warn("First argument must be a Defclass; type wasn't a Defclass, a string, or a symbol; it was a %s!", rb_class2name(rb_obj_class(first_argument)));
907
+ return Qnil;
908
+ }
909
+
910
+ switch (IBError(env))
911
+ {
912
+ case IBE_NO_ERROR:
913
+ break;
914
+ case IBE_NULL_POINTER_ERROR:
915
+ rb_warn("Could not make instance; null pointer error. This could be a bug in clipsruby!");
916
+ IBDispose(ib);
917
+ return Qnil;
918
+ case IBE_DEFCLASS_NOT_FOUND_ERROR:
919
+ IBDispose(ib);
920
+ switch (TYPE(first_argument)) {
921
+ case T_STRING:
922
+ instance = MakeInstance(env, StringValueCStr(first_argument));
923
+ break;
924
+ case T_SYMBOL:
925
+ instance = MakeInstance(env, rb_id2name(SYM2ID(first_argument)));
926
+ break;
927
+ default:
928
+ instance = NULL;
929
+ break;
930
+ }
931
+ if (instance == NULL) {
932
+ rb_warn("Could not make instance; defclass not found, and first argument was not a valid make-instance string!");
933
+ return Qnil;
934
+ } else {
935
+ rb_instance =
936
+ TypedData_Wrap_Struct(rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Instance")), &Instance_type, instance);
937
+
938
+ rb_iv_set(rb_instance, "@environment", rbEnvironment);
939
+
940
+ return rb_instance;
941
+ }
942
+ case IBE_COULD_NOT_CREATE_ERROR:
943
+ rb_warn("Could not make instance; This could be a bug in clipsruby!");
944
+ IBDispose(ib);
945
+ return Qnil;
946
+ case IBE_RULE_NETWORK_ERROR:
947
+ rb_warn("Could not make instance; Rule network error!");
948
+ IBDispose(ib);
949
+ return Qnil;
950
+ }
951
+
952
+ void *args[2] = { (void *)ib, (void *)env };
953
+
954
+ switch(TYPE(second_argument))
955
+ {
956
+ case T_STRING:
957
+ case T_SYMBOL:
958
+ instance_name = rb_id2name(SYM2ID(second_argument));
959
+ break;
960
+ case T_NIL:
961
+ instance_name = NULL;
962
+ break;
963
+ case T_HASH:
964
+ instance_name = NULL;
965
+ rb_hash_foreach(second_argument, _clips_environment_make_instance, (VALUE)args);
966
+ break;
967
+ default:
968
+ rb_warn("Could not make instance; second argument must be the name of the new instance or the slot hash!");
969
+ IBDispose(ib);
970
+ return Qnil;
971
+ }
972
+
973
+ switch(TYPE(third_argument))
974
+ {
975
+ case T_NIL:
976
+ break;
977
+ case T_HASH:
978
+ rb_hash_foreach(third_argument, _clips_environment_make_instance, (VALUE)args);
979
+ break;
980
+ default:
981
+ rb_warn("Could not make instance; third argument must be nil or the slot hash!");
982
+ IBDispose(ib);
983
+ return Qnil;
984
+ }
985
+
986
+ if ((instance = IBMake(ib, instance_name)) == NULL)
987
+ {
988
+ switch (IBError(env))
989
+ {
990
+ case IBE_NO_ERROR:
991
+ break;
992
+ case IBE_NULL_POINTER_ERROR:
993
+ rb_warn("Could not make instance; null pointer error. This could be a bug in clipsruby!");
994
+ IBDispose(ib);
995
+ return Qnil;
996
+ case IBE_DEFCLASS_NOT_FOUND_ERROR:
997
+ rb_warn("Could not make instance; defclass not found!");
998
+ IBDispose(ib);
999
+ return Qnil;
1000
+ case IBE_COULD_NOT_CREATE_ERROR:
1001
+ rb_warn("Could not make instance; This could be a bug in clipsruby!");
1002
+ IBDispose(ib);
1003
+ return Qnil;
1004
+ case IBE_RULE_NETWORK_ERROR:
1005
+ rb_warn("Could not make instance; Rule network error!");
1006
+ IBDispose(ib);
1007
+ return Qnil;
1008
+ }
1009
+ }
1010
+
1011
+ IBDispose(ib);
1012
+
1013
+ rb_instance =
1014
+ TypedData_Wrap_Struct(rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Instance")), &Instance_type, instance);
1015
+
1016
+ rb_iv_set(rb_instance, "@environment", rbEnvironment);
1017
+
1018
+ return rb_instance;
1019
+ }
1020
+
1021
+ static VALUE clips_environment_static_make_instance(int argc, VALUE *argv, VALUE klass) {
1022
+ VALUE rbEnvironment, first_argument, second_argument, third_argument, defclass_class, rb_instance;
1023
+ Environment *env;
1024
+ Defclass *defclass;
1025
+ InstanceBuilder *ib;
1026
+ Instance *instance;
1027
+ const char *instance_name;
1028
+
1029
+ rb_scan_args(argc, argv, "22", &rbEnvironment, &first_argument, &second_argument, &third_argument);
1030
+
1031
+ TypedData_Get_Struct(rbEnvironment, Environment, &Environment_type, env);
1032
+
1033
+ defclass_class = rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Defclass"));
1034
+
1035
+ // first argument must be a defclass
1036
+ switch (TYPE(first_argument))
1037
+ {
1038
+ case T_OBJECT:
1039
+ case T_DATA:
1040
+ if (CLASS_OF(first_argument) == defclass_class) {
1041
+ TypedData_Get_Struct(first_argument, Defclass, &Defclass_type, defclass);
1042
+ ib = CreateInstanceBuilder(env, DefclassName(defclass));
1043
+ break;
1044
+ } else {
1045
+ rb_warn("First argument must be a Defclass; first argument was an object, but not %s class; it was a %s", rb_class2name(defclass_class), rb_class2name(first_argument));
1046
+ return Qnil;
1047
+ }
1048
+ case T_STRING:
1049
+ ib = CreateInstanceBuilder(env, StringValueCStr(first_argument));
1050
+ break;
1051
+ case T_SYMBOL:
1052
+ ib = CreateInstanceBuilder(env, rb_id2name(SYM2ID(first_argument)));
1053
+ break;
1054
+ default:
1055
+ rb_warn("First argument must be a Defclass; type wasn't a Defclass, a string, or a symbol; it was a %s!", rb_class2name(rb_obj_class(first_argument)));
1056
+ return Qnil;
1057
+ }
1058
+
1059
+ switch (IBError(env))
1060
+ {
1061
+ case IBE_NO_ERROR:
1062
+ break;
1063
+ case IBE_NULL_POINTER_ERROR:
1064
+ rb_warn("Could not make instance; null pointer error. This could be a bug in clipsruby!");
1065
+ IBDispose(ib);
1066
+ return Qnil;
1067
+ case IBE_DEFCLASS_NOT_FOUND_ERROR:
1068
+ IBDispose(ib);
1069
+ switch (TYPE(first_argument)) {
1070
+ case T_STRING:
1071
+ instance = MakeInstance(env, StringValueCStr(first_argument));
1072
+ break;
1073
+ case T_SYMBOL:
1074
+ instance = MakeInstance(env, rb_id2name(SYM2ID(first_argument)));
1075
+ break;
1076
+ default:
1077
+ instance = NULL;
1078
+ break;
1079
+ }
1080
+ if (instance == NULL) {
1081
+ rb_warn("Could not make instance; defclass not found, and first argument was not a valid make-instance string!");
1082
+ return Qnil;
1083
+ } else {
1084
+ rb_instance =
1085
+ TypedData_Wrap_Struct(rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Instance")), &Instance_type, instance);
1086
+
1087
+ rb_iv_set(rb_instance, "@environment", rbEnvironment);
1088
+
1089
+ return rb_instance;
1090
+ }
1091
+ case IBE_COULD_NOT_CREATE_ERROR:
1092
+ rb_warn("Could not make instance; This could be a bug in clipsruby!");
1093
+ IBDispose(ib);
1094
+ return Qnil;
1095
+ case IBE_RULE_NETWORK_ERROR:
1096
+ rb_warn("Could not make instance; Rule network error!");
1097
+ IBDispose(ib);
1098
+ return Qnil;
1099
+ }
1100
+
1101
+ void *args[2] = { (void *)ib, (void *)env };
1102
+
1103
+ switch(TYPE(second_argument))
1104
+ {
1105
+ case T_STRING:
1106
+ case T_SYMBOL:
1107
+ instance_name = rb_id2name(SYM2ID(second_argument));
1108
+ break;
1109
+ case T_NIL:
1110
+ instance_name = NULL;
1111
+ break;
1112
+ case T_HASH:
1113
+ instance_name = NULL;
1114
+ rb_hash_foreach(second_argument, _clips_environment_make_instance, (VALUE)args);
1115
+ break;
1116
+ default:
1117
+ rb_warn("Could not make instance; second argument must be the name of the new instance or the slot hash!");
1118
+ IBDispose(ib);
1119
+ return Qnil;
1120
+ }
1121
+
1122
+ switch(TYPE(third_argument))
1123
+ {
1124
+ case T_NIL:
1125
+ break;
1126
+ case T_HASH:
1127
+ rb_hash_foreach(third_argument, _clips_environment_make_instance, (VALUE)args);
1128
+ break;
1129
+ default:
1130
+ rb_warn("Could not make instance; third argument must be nil or the slot hash!");
1131
+ IBDispose(ib);
1132
+ return Qnil;
1133
+ }
1134
+
1135
+ if ((instance = IBMake(ib, instance_name)) == NULL)
1136
+ {
1137
+ switch (IBError(env))
1138
+ {
1139
+ case IBE_NO_ERROR:
1140
+ break;
1141
+ case IBE_NULL_POINTER_ERROR:
1142
+ rb_warn("Could not make instance; null pointer error. This could be a bug in clipsruby!");
1143
+ IBDispose(ib);
1144
+ return Qnil;
1145
+ case IBE_DEFCLASS_NOT_FOUND_ERROR:
1146
+ rb_warn("Could not make instance; defclass not found!");
1147
+ IBDispose(ib);
1148
+ return Qnil;
1149
+ case IBE_COULD_NOT_CREATE_ERROR:
1150
+ rb_warn("Could not make instance; This could be a bug in clipsruby!");
1151
+ IBDispose(ib);
1152
+ return Qnil;
1153
+ case IBE_RULE_NETWORK_ERROR:
1154
+ rb_warn("Could not make instance; Rule network error!");
1155
+ IBDispose(ib);
1156
+ return Qnil;
1157
+ }
1158
+ }
1159
+
1160
+ IBDispose(ib);
1161
+
1162
+ rb_instance =
1163
+ TypedData_Wrap_Struct(rb_const_get(CLASS_OF(rbEnvironment), rb_intern("Instance")), &Instance_type, instance);
1164
+
1165
+ rb_iv_set(rb_instance, "@environment", rbEnvironment);
1166
+
1167
+ return rb_instance;
1168
+ }
1169
+
872
1170
  static VALUE clips_environment_deftemplate_assert_hash(VALUE self, VALUE hash)
873
1171
  {
874
1172
  const char *cdeftemplate_name;
@@ -1266,10 +1564,6 @@ static VALUE clips_environment_defclass_subclasses(int argc, VALUE *argv, VALUE
1266
1564
 
1267
1565
  rb_scan_args(argc, argv, "01", &inherit);
1268
1566
 
1269
- if (NIL_P(inherit)) {
1270
- inherit = Qfalse;
1271
- }
1272
-
1273
1567
  TypedData_Get_Struct(rbDefclass, Defclass, &Defclass_type, defclass);
1274
1568
 
1275
1569
  ClassSubclasses(defclass, &value, RTEST(inherit));
@@ -1299,6 +1593,46 @@ static VALUE clips_environment_defclass_static_subclasses(int argc, VALUE *argv,
1299
1593
  return out;
1300
1594
  }
1301
1595
 
1596
+ static VALUE clips_environment_defclass_slots(int argc, VALUE *argv, VALUE rbDefclass)
1597
+ {
1598
+ VALUE rbEnvironment, inherit;
1599
+ Defclass *defclass;
1600
+ CLIPSValue value;
1601
+ VALUE out;
1602
+
1603
+ rbEnvironment = rb_iv_get(rbDefclass, "@environment");
1604
+
1605
+ rb_scan_args(argc, argv, "01", &inherit);
1606
+
1607
+ TypedData_Get_Struct(rbDefclass, Defclass, &Defclass_type, defclass);
1608
+
1609
+ ClassSlots(defclass, &value, RTEST(inherit));
1610
+
1611
+ CLIPSValue_to_VALUE(&value, &out, &rbEnvironment);
1612
+
1613
+ return out;
1614
+ }
1615
+
1616
+ static VALUE clips_environment_defclass_static_slots(int argc, VALUE *argv, VALUE klass)
1617
+ {
1618
+ VALUE rbEnvironment, inherit, rbDefclass;
1619
+ Defclass *defclass;
1620
+ CLIPSValue value;
1621
+ VALUE out;
1622
+
1623
+ rb_scan_args(argc, argv, "11", &rbDefclass, &inherit);
1624
+
1625
+ TypedData_Get_Struct(rbDefclass, Defclass, &Defclass_type, defclass);
1626
+
1627
+ rbEnvironment = rb_iv_get(rbDefclass, "@environment");
1628
+
1629
+ ClassSlots(defclass, &value, RTEST(inherit));
1630
+
1631
+ CLIPSValue_to_VALUE(&value, &out, &rbEnvironment);
1632
+
1633
+ return out;
1634
+ }
1635
+
1302
1636
  static VALUE clips_environment_run(int argc, VALUE *argv, VALUE environment) {
1303
1637
  VALUE integer;
1304
1638
  Environment *env;
@@ -1436,6 +1770,57 @@ static VALUE clips_environment_fact_static_to_h(VALUE self, VALUE rbFact)
1436
1770
  return clips_environment_fact_to_h(rbFact);
1437
1771
  }
1438
1772
 
1773
+ static VALUE clips_environment_instance_to_h(int argc, VALUE *argv, VALUE rbInstance)
1774
+ {
1775
+ VALUE rbEnvironment, inherit;
1776
+ Instance *instance;
1777
+ CLIPSValue key, value;
1778
+ rbEnvironment = rb_iv_get(rbInstance, "@environment");
1779
+
1780
+ TypedData_Get_Struct(rbInstance, Instance, &Instance_type, instance);
1781
+
1782
+ rb_scan_args(argc, argv, "01", &inherit);
1783
+
1784
+ ClassSlots(InstanceClass(instance), &key, RTEST(inherit));
1785
+
1786
+ VALUE hash = rb_hash_new();
1787
+ for (size_t i = 0; i < key.multifieldValue->length; i++)
1788
+ {
1789
+ VALUE innerValue;
1790
+ DirectGetSlot(instance, key.multifieldValue->contents[i].lexemeValue->contents, &value);
1791
+ CLIPSValue_to_VALUE(&value, &innerValue, &rbEnvironment);
1792
+ rb_hash_aset(hash, ID2SYM(rb_intern(key.multifieldValue->contents[i].lexemeValue->contents)), innerValue);
1793
+ }
1794
+
1795
+ return hash;
1796
+ }
1797
+
1798
+ static VALUE clips_environment_instance_static_to_h(int argc, VALUE *argv, VALUE klass)
1799
+ {
1800
+ VALUE rbInstance, rbEnvironment, inherit;
1801
+ Instance *instance;
1802
+ CLIPSValue key, value;
1803
+
1804
+ rb_scan_args(argc, argv, "11", &rbInstance, &inherit);
1805
+
1806
+ rbEnvironment = rb_iv_get(rbInstance, "@environment");
1807
+
1808
+ TypedData_Get_Struct(rbInstance, Instance, &Instance_type, instance);
1809
+
1810
+ ClassSlots(InstanceClass(instance), &key, RTEST(inherit));
1811
+
1812
+ VALUE hash = rb_hash_new();
1813
+ for (size_t i = 0; i < key.multifieldValue->length; i++)
1814
+ {
1815
+ VALUE innerValue;
1816
+ DirectGetSlot(instance, key.multifieldValue->contents[i].lexemeValue->contents, &value);
1817
+ CLIPSValue_to_VALUE(&value, &innerValue, &rbEnvironment);
1818
+ rb_hash_aset(hash, ID2SYM(rb_intern(key.multifieldValue->contents[i].lexemeValue->contents)), innerValue);
1819
+ }
1820
+
1821
+ return hash;
1822
+ }
1823
+
1439
1824
  static VALUE clips_environment_batch_star(VALUE self, VALUE path)
1440
1825
  {
1441
1826
  Environment *env;
@@ -4290,8 +4675,8 @@ void Init_clipsruby(void)
4290
4675
  rb_define_method(rbEnvironment, "unwatch_focus", clips_environment_unwatch_focus, 0);
4291
4676
  rb_define_singleton_method(rbEnvironment, "get_watch_state", clips_environment_static_get_watch_state, 2);
4292
4677
  rb_define_method(rbEnvironment, "get_watch_state", clips_environment_get_watch_state, 1);
4293
- rb_define_singleton_method(rbEnvironment, "make_instance", clips_environment_static_make_instance, 2);
4294
- rb_define_method(rbEnvironment, "make_instance", clips_environment_make_instance, 1);
4678
+ rb_define_singleton_method(rbEnvironment, "make_instance", clips_environment_static_make_instance, -1);
4679
+ rb_define_method(rbEnvironment, "make_instance", clips_environment_make_instance, -1);
4295
4680
 
4296
4681
  VALUE rbDeffacts = rb_define_class_under(rbEnvironment, "Deffacts", rb_cObject);
4297
4682
  rb_define_alloc_func(rbDeffacts, deffacts_alloc);
@@ -4416,6 +4801,8 @@ void Init_clipsruby(void)
4416
4801
  rb_define_method(rbDefclass, "superclasses", clips_environment_defclass_superclasses, -1);
4417
4802
  rb_define_singleton_method(rbDefclass, "subclasses", clips_environment_defclass_static_subclasses, -1);
4418
4803
  rb_define_method(rbDefclass, "subclasses", clips_environment_defclass_subclasses, -1);
4804
+ rb_define_singleton_method(rbDefclass, "slots", clips_environment_defclass_static_slots, -1);
4805
+ rb_define_method(rbDefclass, "slots", clips_environment_defclass_slots, -1);
4419
4806
 
4420
4807
  VALUE rbInstance = rb_define_class_under(rbEnvironment, "Instance", rb_cObject);
4421
4808
  rb_define_alloc_func(rbInstance, instance_alloc);
@@ -4429,4 +4816,6 @@ void Init_clipsruby(void)
4429
4816
  rb_define_method(rbInstance, "name", clips_environment_instance_name, 0);
4430
4817
  rb_define_singleton_method(rbInstance, "pp_form", clips_environment_instance_static_pp_form, 1);
4431
4818
  rb_define_method(rbInstance, "pp_form", clips_environment_instance_pp_form, 0);
4819
+ rb_define_singleton_method(rbInstance, "to_h", clips_environment_instance_static_to_h, -1);
4820
+ rb_define_method(rbInstance, "to_h", clips_environment_instance_to_h, -1);
4432
4821
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clipsruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.39
4
+ version: 0.0.41
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Johnston
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-30 00:00:00.000000000 Z
11
+ date: 2024-10-02 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Calling the CLIPS programming language from within Ruby
14
14
  email: mrryanjohnston@gmail.com