1 /* proc.h                              Copyright (C) 2010 Codemist Ltd */
2 
3 #ifndef header_proc_h
4 #define header_proc_h 1
5 
6 
7 
8 /**************************************************************************
9  * Copyright (C) 2010, Codemist Ltd.                     A C Norman       *
10  *                                                                        *
11  * Redistribution and use in source and binary forms, with or without     *
12  * modification, are permitted provided that the following conditions are *
13  * met:                                                                   *
14  *                                                                        *
15  *     * Redistributions of source code must retain the relevant          *
16  *       copyright notice, this list of conditions and the following      *
17  *       disclaimer.                                                      *
18  *     * Redistributions in binary form must reproduce the above          *
19  *       copyright notice, this list of conditions and the following      *
20  *       disclaimer in the documentation and/or other materials provided  *
21  *       with the distribution.                                           *
22  *                                                                        *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS    *
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      *
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS      *
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE         *
27  * COPYRIGHT OWNERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,   *
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,   *
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS  *
30  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR  *
32  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF     *
33  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH   *
34  * DAMAGE.                                                                *
35  *************************************************************************/
36 
37 /* Signature: 545be01d 22-Aug-2010 */
38 
39 
40 /*
41  * Definitions useful for driving the procedural interface to Reduce...
42  */
43 
44 /*
45  * These types are used for callback functions used to send and receive
46  * characters.
47  */
48 
49 typedef int character_reader(void);
50 typedef int character_writer(int);
51 
52 /*
53  * When a handle on an expression is returned to the user this is the
54  * type it has. The type should be treated as opaque, please.
55  */
56 
57 typedef void *PROC_handle;
58 
59 /*
60  * Before trying to do anything at all you must call cslstart. This will
61  * allocate memory, load an initial heap image etc etc. The argc and argv
62  * passed here are as per normal C startup. The key issue here is how
63  * Reduce will find the file "reduce.img" that it needs to load. There are
64  * two plausible ways you can achieve this.
65  * (a) argv[0] should contain a (for choice) fully rooted path as in
66  *     /usr/local/bin/reduce
67  * or  c:\my-reduce\binaries\reduce.exe
68  *     In that case the name of the supposed execitable has ".img" tagged
69  *     onto it, so the image is expected to be at say /usr/local/bin/reduce.img
70  *     If the application name is the name of a symbolic link then the
71  *     image file is looked for in the dircetory that the link points to.
72  * (b) You can put "-i" "/path/to/reduce.img" in two consecutive entries
73  *     in argv to give an explicit indication of where the image file
74  *     is to be found. This should override any attempt to look via
75  *     argv[0].
76  * Most users should not need to provide any further options, but options
77  * are decoded just as for the ordinary version of the system.
78  *
79  * Any textual output generated during system-started is sent, character
80  * by character, via the callback function. Eg pass an option "-v" in
81  * argv and see a big banner.
82  */
83 
84 extern void cslstart(int argc, char *argv[], character_writer *wr);
85 
86 /*
87  * At the end of a run please call cslfinish to close down everything
88  * in a reasonably orderly manner and release memory. I should cautiously
89  * note that the system will have some memory leaks so cslfinish will
90  * not return EVERYTHING that has been allocated - if this worries you
91  * please search for and correct the defects. Again the callback function
92  * is used to process any output generated during close-down.
93  */
94 
95 extern int cslfinish(character_writer *wr);
96 
97 /*
98  * As a general-purpose escape it is possible to get a Lisp function
99  * (with no arguments) called. This function does that re-binding
100  * what would otherwise be terminal input and output to the two
101  * callback functions. By writing your own custom Lisp function and then
102  * calling it this way you get almost ultimate flexibility, if not
103  * convenience! For used of the Reduce algebra system I hope that the
104  * suite of more specialised functions listed later on will prove
105  * easier to use.
106  */
107 
108 extern int execute_lisp_function(char *fname,
109                                  character_reader *r,
110                                  character_writer *w);
111 
112 
113 /*
114  * The next collection of functions provide for interaction with the
115  * Reduce algebra system using a model based on a Reverse Polish
116  * Calculator. You use RPN-style calls to build a fragment of parse
117  * tree and can them as Reduce to "simplify" it. Having simplified it
118  * you can ask for a simple prefix-form of the result to be generated and
119  * returned, and there are functions for traversing that.
120  */
121 
122 /*
123  * Example:
124  *  Task:   differentiate (x+1)^2 with respect to x
125  *  Method: clear_stack();
126  *          push_symbol("x");
127  *          push_small_integer(1);
128  *          make_function_call("plus",2);   function plus has 2 arguments.
129  *          push_small_integer(2);
130  *          make_function_call("expt",2);
131  *          push_symbol("x");
132  *          make_function_call("df",2);     "df" is for differentiate.
133  *                                          To use this you need to learn
134  *                                          the named Reduce uses for all
135  *                                          relevant operations.
136  *          simplify();                     up until now the form built
137  *                                          has been just the prefix form
138  *                                          (expt (plus x 1) 2).
139  *          dup();                          because save will pop the stack
140  *          save(1);                        save in "memory number 1".
141  *          make_printable();               the simplified form is in
142  *                                          a Reduce internal representation,
143  *                                          so this restores it to simple
144  *                                          prefix form.
145  *          p = get_value();
146  * now p holds a handle on the result, and it can be traversed
147  * using functions atom(), first(), rest() and functions that extract the
148  * name of a symbol or the value of an integer. You should assume that the
149  * handle becomes invalid as soon as you call one of the other functions.
150  * this is because they can all trigger garbage collection and that can
151  * relocate data.
152  * The functions used to build expressions all return zero on success or
153  * an error-code otherwise. In the initial release the error-codes are
154  * not documented other than via reading the source files. Furthermore the
155  * consequence of a calculation seeking input or generating output is not
156  * well sorted.
157  */
158 
159 
160 /*
161  * After having called cslstart() you can set the I/O callback functions
162  * using this. If you set one or both to NULL this indicates use of
163  * stdin/stdout as per usual rather than an callback, otherwise whenever
164  * anybody wants to read or write they use these procedures. It is then
165  * your responsibility to cope with whatever text gets exchanged!
166  */
167 
168 extern int PROC_set_callbacks(character_reader *r,
169                               character_writer *w);
170 
171 /*
172  * Load a Reduce "package".
173  */
174 
175 int PROC_load_package(char *name);
176 
177 /*
178  * Set of clear a Reduce switch. As on "on expandlogs;"
179  * which you do via PROC_set_switch("expandlogs", 1);
180  * Use 0 to switch something off and 1 to switch it on.
181  */
182 
183 int PROC_set_switch(char *name, int val);
184 
185 /*
186  * Set level of garbage collector noise. This might often be a bit irrelevant,
187  * but
188  *    0    no messages at all
189  *    +1   messages whenever garbage collection happens
190  *    +2   messages whenever a module of code is loaded
191  *    +4   extra details in the garbage collector messages
192  * Note that if an ALWAYS_NOISY option (probably set as a side effect
193  * of the debugging command line option "-g") is in play then any
194  * call here has +1 and +2 forced active.
195  */
196 
197 int PROC_gc_messages(int n);
198 
199 /*
200  *    stack = nil;
201  */
202 extern int PROC_clear_stack();
203 
204 /*
205  *    stack = name . stack;
206  */
207 
208 extern int PROC_push_symbol(const char *name);
209 
210 /*
211  *    stack = the-string . stack;
212  */
213 
214 extern int PROC_push_string(const char *data);
215 
216 /*
217  *    stack = n . stack;
218  * Small integers may be up to 28-bits of (signed) data, while
219  * big integers can be almost any size and are denoted here by strings.
220  * Eg:  PROC_push_small_integer(134217727);    largest positive small num
221  *      PROC_push_small_integer(-134217728);   extreme negative case
222  *      PROC_push_big_integer("-12345678901234567890");
223  */
224 
225 extern int PROC_push_small_integer(int32_t n);
226 
227 extern int PROC_push_big_integer(const char *n);
228 
229 extern int PROC_push_floating(double n);
230 
231 /*
232  * Takes n items from the top of the stack and uses them as arguments
233  * for a function as specified by the name. Leaves the result on the
234  * top of the stack. Arguments will have been pushed with arg1 pushed
235  * first and the last argument pushed last.
236  */
237 
238 extern int PROC_make_function_call(const char *name, int n);
239 
240 /*
241  * Save whatever is on top of the stack in memory location n. At present
242  * I provide 100 memory locations, whihc ar enumbered 0 to 99.
243  */
244 
245 extern int PROC_save(int n);
246 
247 /*
248  * Push the contents of memory location n onto the stack.
249  */
250 
251 extern int PROC_load(int n);
252 
253 /*
254  * Duplicate the top stack element.
255  */
256 
257 extern int PROC_dup();
258 
259 /*
260  * Discard the top stack element.
261  */
262 
263 extern int PROC_pop();
264 
265 /*
266  * The top item on the stack is replaced with what happens when Reduce
267  * is asked to "simplify" or "evaluate" it. The result can then be stored
268  * or combined with other items, but it will not in general be in a format
269  * directly convenient for use by humans.
270  */
271 
272 extern int PROC_simplify();
273 
274 /*
275  * Replace the top item on the stack with a version of the same expression
276  * in a reasonably simple prefix notation.
277  * This representation is NOT intended for re-input to any calculation -
278  * it is only intended for inspecial by the client code that is using Reduce
279  * via this interface. To that end it may in the future return big integers
280  * in a form where they have been converted to Lisp strings and may make
281  * other transformations that would hurt attempts to re-use the expression.
282  */
283 
284 extern int PROC_make_printable();
285 
286 /*
287  * Return a handle to the top item on the stack, and pop the stack. This
288  * will normally be called immediately after a call to PROC_make_printable.
289  * the stack is popped because I view the "printable" version as unsuitable
290  * for further use.
291  */
292 
293 extern PROC_handle PROC_get_value();
294 
295 /*
296  * The next few functions are predicates that may be applied to handles.
297  * An "atom" is any non-composite form. A fixnum is a small integer, and
298  * a symbol is a name.
299  */
300 
301 extern int PROC_atom(PROC_handle p);
302 extern int PROC_null(PROC_handle p);
303 extern int PROC_fixnum(PROC_handle p);
304 extern int PROC_floatnum(PROC_handle p);
305 extern int PROC_string(PROC_handle p);
306 extern int PROC_symbol(PROC_handle p);
307 
308 /*
309  * If something is not an atom it will be a list, and the following two
310  * functions return the components of it. In general non-atomic items will
311  * be structured as
312  *     (fname arg1 arg2 ...)
313  * with "well understood" function names "plus", "difference", "minus",
314  * "times", "quotient", "expt" being used to denote use of the main
315  * arithmetic connectives. A Lisp fanatic would have named the following
316  * two functions PROC_car and PROC_cdr!
317  */
318 
319 extern PROC_handle PROC_first(PROC_handle p);
320 extern PROC_handle PROC_rest(PROC_handle p);
321 
322 /*
323  * If something is an atom then these make it possible to extract details
324  * of what it represents. In due course I may support floating point values
325  * and big numbers, but release 1 of those code concentrates on the basics.
326  */
327 
328 extern int32_t PROC_integer_value(PROC_handle p);
329 extern double PROC_floating_value(PROC_handle p);
330 extern const char *PROC_symbol_name(PROC_handle p);
331 extern const char *PROC_string_data(PROC_handle p);
332 
333 /*
334  * I also provide some calls that support a sort of ultimate cop-out in
335  * that they maye it possible to call Lisp code directly rather than
336  * just invoking the Reduce simplifier. They also allow one to get back a
337  * raw Lisp result which will have had gensym-names solidified but which
338  * is otherwise unaltered. Note that the way this is achieved means that
339  * things will FAIL if the Lisp result were to be a cyclic structure!
340  */
341 
342 
343 /*
344  * Replace the top item on the stack with whatever is obtained by using
345  * the Lisp EVAL operation on it. Note that this is not intended for
346  * casual use - if there is any functionality that you need PLEASE ask
347  * me to put in a cleaner abstraction to support it.
348  */
349 
350 extern int PROC_lisp_eval();
351 
352 /*
353  * Return a handle to the top item on the stack, and pop the stack.
354  * The value here will be a RAW LISP structure and NOT at all necessarily
355  * anything neat.
356  */
357 
358 extern PROC_handle PROC_get_raw_value();
359 
360 
361 
362 #ifndef __cplusplus
363 #ifdef USE_SIGALTSTACK
364 extern sigjmp_buf my_exit_buffer;
365 #else
366 extern jmp_buf my_exit_buffer;
367 #endif
368 #endif
369 extern volatile int my_return_code;
370 
371 #endif /* header_proc_h */
372 
373 /* end of proc.h */
374 
375