Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
rhsfun.h
Go to the documentation of this file.
1 /*************************************************************************
2  * PLEASE SEE THE FILE "license.txt" (INCLUDED WITH THIS SOFTWARE PACKAGE)
3  * FOR LICENSE AND COPYRIGHT INFORMATION.
4  *************************************************************************/
5 
6 /* ====================================================================
7  rhsfun.h
8 
9  The system maintains a list of available RHS functions. Functions
10  can appear on the RHS of productions either as values (in make actions
11  or as arguments to other function calls) or as stand-alone actions
12  (e.g., "write" and "halt"). When a function is executed, its C code
13  is called with one parameter--a (consed) list of the arguments (symbols).
14  The C function should return either a symbol (if all goes well) or NIL
15  (if an error occurred, or if the function is a stand-alone action).
16 
17  All available RHS functions should be setup at system startup time via
18  calls to add_rhs_function(). It takes as arguments the name of the
19  function (a symbol), a pointer to the corresponding C function, the
20  number of arguments the function expects (-1 if the function can take
21  any number of arguments), and flags indicating whether the function can
22  be a RHS value or a stand-alone action.
23 
24  Lookup_rhs_function() takes a symbol and returns the corresponding
25  rhs_function structure (or NIL if there is no such function).
26 
27  Init_built_in_rhs_functions() should be called at system startup time
28  to setup all the built-in functions.
29 ==================================================================== */
30 
31 
32 /* -------------------------------------------------------------------
33  Right-Hand-Side Values
34 
35  Values on the RHS of productions can be given by symbols
36  (constants or variables), by Rete locations, by indices of variables
37  not bound on the LHS, or by function calls. We use the low-order two
38  bits of a pointer to differentiate between these types of values.
39 
40  If the low-order bits are: the rhs_value is:
41  00 a pointer to a symbol
42  01 a pointer to a list (for a function call)
43  10 a Rete location
44  11 the index of an RHS unbound variable
45 
46  For function calls, the list is a consed list whose first element is
47  the rhs_function structure, and whose remaining elements are the
48  arguments of the function call. (Each argument is an rhs_value.)
49 
50  WARNING: part of rete.cpp relies on the the fact that two rhs_values
51  representing the same symbol, reteloc, or unboundvar will be equal (==),
52  while two representing the same funcall will not be equal (==).
53 ------------------------------------------------------------------- */
54 
55 #ifndef RHSFUN_H
56 #define RHSFUN_H
57 
58 #ifdef __cplusplus
59 //extern "C"
60 //{
61 #endif
62 
63 typedef char * rhs_value;
64 typedef unsigned char byte;
65 typedef unsigned short rete_node_level;
66 typedef struct cons_struct cons;
67 typedef cons list;
68 typedef union symbol_union Symbol;
69 
70 
71 #ifdef USE_MACROS
72 
73 #define rhs_value_is_symbol(rv) ((((uint64_t)(rv)) & 3)==0)
74 #define rhs_value_is_funcall(rv) ((((uint64_t)(rv)) & 3)==1)
75 #define rhs_value_is_reteloc(rv) ((((uint64_t)(rv)) & 3)==2)
76 #define rhs_value_is_unboundvar(rv) ((((uint64_t)(rv)) & 3)==3)
77 
78 /* Warning: symbol_to_rhs_value() doesn't symbol_add_ref. The caller must
79  do the reference count update */
80 #define symbol_to_rhs_value(sym) ((rhs_value) (sym))
81 #define funcall_list_to_rhs_value(fl) ((rhs_value) (((char *)(fl))+1))
82 #define reteloc_to_rhs_value(field_num,levels_up) \
83  ((rhs_value) ( (levels_up)<<4) + ((field_num)<<2) + 2 )
84 #define unboundvar_to_rhs_value(n) ((rhs_value) (((n)<<2) + 3))
85 
86 #define rhs_value_to_symbol(rv) ((Symbol *)(rv))
87 #define rhs_value_to_funcall_list(rv) ((list *) (((char *)(rv))-1))
88 #define rhs_value_to_reteloc_field_num(rv) ((((uint64_t)(rv))>>2) & 3)
89 #define rhs_value_to_reteloc_levels_up(rv) ((((uint64_t)(rv))>>4)& 0xFFFF)
90 #define rhs_value_to_unboundvar(rv) (((uint64_t)(rv))>>2)
91 
92 #else
93 
94 //#define rhs_value_is_symbol(rv) ((((uintptr_t)(rv)) & 3)==0)
96 {
97  return (reinterpret_cast<uintptr_t>(rv) & 3) == 0;
98 }
99 
100 //#define rhs_value_is_funcall(rv) ((((uintptr_t)(rv)) & 3)==1)
102 {
103  return (reinterpret_cast<uintptr_t>(rv) & 3) == 1;
104 }
105 
106 //#define rhs_value_is_reteloc(rv) ((((uintptr_t)(rv)) & 3)==2)
108 {
109  return (reinterpret_cast<uintptr_t>(rv) & 3) == 2;
110 }
111 
112 //#define rhs_value_is_unboundvar(rv) ((((uintptr_t)(rv)) & 3)==3)
114 {
115  return (reinterpret_cast<uintptr_t>(rv) & 3) == 3;
116 }
117 
118 /* Warning: symbol_to_rhs_value() doesn't symbol_add_ref. The caller must
119  do the reference count update */
120 //#define symbol_to_rhs_value(sym) ((rhs_value) (sym))
122 {
123  return reinterpret_cast<rhs_value>(sym);
124 }
125 
126 //#define funcall_list_to_rhs_value(fl) ((rhs_value) (((char *)(fl))+1))
128 {
129  return reinterpret_cast<rhs_value>(reinterpret_cast<char *>(fl) + 1);
130 }
131 
132 //#define reteloc_to_rhs_value(field_num,levels_up) ((rhs_value) ( (levels_up)<<4) + ((field_num)<<2) + 2 )
133 inline rhs_value reteloc_to_rhs_value(byte field_num, rete_node_level levels_up)
134 {
135  return reinterpret_cast<rhs_value>(levels_up << 4) + (field_num << 2) + 2;
136 }
137 
138 //#define unboundvar_to_rhs_value(n) ((rhs_value) (((n)<<2) + 3))
140 {
141  return reinterpret_cast<rhs_value>((n << 2) + 3);
142 }
143 
144 //#define rhs_value_to_symbol(rv) ((Symbol *)(rv))
146 {
147  return reinterpret_cast<Symbol *>(rv);
148 }
149 
150 //#define rhs_value_to_funcall_list(rv) ((list *) (((char *)(rv))-1))
152 {
153  return reinterpret_cast< ::list * >(reinterpret_cast<char *>(rv) - 1);
154 }
155 
156 //#define rhs_value_to_reteloc_field_num(rv) ((((uintptr_t)(rv))>>2) & 3)
158 {
159  return static_cast<uint8_t>((reinterpret_cast<uintptr_t>(rv) >> 2) & 3);
160 }
161 
162 //#define rhs_value_to_reteloc_levels_up(rv) ((((uintptr_t)(rv))>>4)& 0xFFFF)
164 {
165  return static_cast<uint16_t>((reinterpret_cast<uintptr_t>(rv) >> 4) & 0xFFFF);
166 }
167 
168 //#define rhs_value_to_unboundvar(rv) (((uintptr_t)(rv))>>2)
170 {
171  return static_cast<uint64_t>((reinterpret_cast<uintptr_t>(rv) >> 2));
172 }
173 
174 #endif /* USE_MACROS */
175 
176 /* -------------------------------------------------------------------
177  RHS Actions
178 
179  Fields in an action:
180 
181  next: points to the next action in a singly-linked list of all
182  actions in the RHS.
183 
184  type: indicates the type of action: usually this is MAKE_ACTION,
185  but for function calls it is FUNCALL_ACTION.
186 
187  preference_type: for make actions, this indicates the type of the
188  preference being created: ACCEPTABLE_PREFERENCE_TYPE, etc.
189 
190  support: indicates the compile-time calculated o-support of the action.
191  This is either UNKNOWN_SUPPORT, O_SUPPORT, or I_SUPPORT.
192 
193  already_in_tc: (reserved for use by compile-time o-support calcs)
194 
195  id, attr: for make actions, these give the symbols (or Rete locations)
196  for the id and attribute fields of the preference.
197 
198  value: for MAKE_ACTION's, this gives the value field of the preference
199  (a symbol or function call). For FUNCALL_ACTION's, this holds the
200  function call itself.
201 
202  referent: for MAKE_ACTION's of binary preferences, this gives the
203  referent field of the preference.
204 ------------------------------------------------------------------- */
205 
206 #define MAKE_ACTION 0
207 #define FUNCALL_ACTION 1
208 
209 #define UNKNOWN_SUPPORT 0
210 #define O_SUPPORT 1
211 #define I_SUPPORT 2
212 
213 typedef char Bool;
214 typedef unsigned char byte;
215 
216 typedef struct agent_struct agent;
217 
218 typedef struct action_struct {
223  Bool already_in_tc; /* used only by compile-time o-support calcs */
226  rhs_value value; /* for FUNCALL_ACTION's, this holds the funcall */
228 } action;
229 
230 typedef Symbol * ((*rhs_function_routine)(agent* thisAgent, ::list *args, void* user_data));
231 
232 typedef struct rhs_function_struct {
236  int num_args_expected; /* -1 means it can take any number of args */
239  void* user_data; /* Pointer to anything the user may want to pass into the function */
240 } rhs_function;
241 
242 extern void add_rhs_function (agent* thisAgent,
243  Symbol *name,
245  int num_args_expected,
248  void* user_data);
249 extern void remove_rhs_function (agent* thisAgent, Symbol *name);
250 extern rhs_function *lookup_rhs_function(agent* thisAgent, Symbol *name);
251 extern void init_built_in_rhs_functions(agent* thisAgent);
252 extern void remove_built_in_rhs_functions(agent* thisAgent);
253 
254 #ifdef __cplusplus
255 //}
256 #endif
257 
258 #endif