Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

1014 lines
59KB

  1. #ifndef S7_H
  2. #define S7_H
  3. #define S7_VERSION "4.10"
  4. #define S7_DATE "9-Aug-16"
  5. typedef long long int s7_int; /* This sets the size of integers in Scheme; it needs to be big enough to accomodate a C pointer. */
  6. typedef double s7_double; /* similarly for Scheme reals; only "double" works in C++ */
  7. /* old forms... */
  8. typedef s7_int s7_Int;
  9. typedef s7_double s7_Double;
  10. #include <stdio.h>
  11. #ifndef __cplusplus
  12. #ifndef _MSC_VER
  13. #include <stdbool.h>
  14. #else
  15. #ifndef true
  16. #define bool unsigned char
  17. #define true 1
  18. #define false 0
  19. #endif
  20. #endif
  21. #endif
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. typedef struct s7_scheme s7_scheme;
  26. typedef struct s7_cell *s7_pointer;
  27. s7_scheme *s7_init(void);
  28. /* s7_scheme is our interpreter
  29. * s7_pointer is a Scheme object of any (Scheme) type
  30. * s7_init creates the interpreter.
  31. */
  32. typedef s7_pointer (*s7_function)(s7_scheme *sc, s7_pointer args); /* that is, obj = func(s7, args) -- args is a list of arguments */
  33. s7_pointer s7_f(s7_scheme *sc); /* #f */
  34. s7_pointer s7_t(s7_scheme *sc); /* #t */
  35. s7_pointer s7_nil(s7_scheme *sc); /* () */
  36. s7_pointer s7_undefined(s7_scheme *sc); /* #<undefined> */
  37. s7_pointer s7_unspecified(s7_scheme *sc); /* #<unspecified> */
  38. bool s7_is_unspecified(s7_scheme *sc, s7_pointer val); /* returns true if val is #<unspecified> */
  39. s7_pointer s7_eof_object(s7_scheme *sc); /* #<eof> */
  40. bool s7_is_null(s7_scheme *sc, s7_pointer p); /* null? */
  41. /* these are the Scheme constants; they do not change in value during a run,
  42. * so they can be safely assigned to C global variables if desired.
  43. */
  44. bool s7_is_valid(s7_scheme *sc, s7_pointer arg); /* does 'arg' look like an s7 object? */
  45. bool s7_is_c_pointer(s7_pointer arg);
  46. void *s7_c_pointer(s7_pointer p);
  47. s7_pointer s7_make_c_pointer(s7_scheme *sc, void *ptr); /* these are for passing uninterpreted C pointers through Scheme */
  48. s7_pointer s7_eval_c_string(s7_scheme *sc, const char *str); /* (eval-string str) */
  49. s7_pointer s7_eval_c_string_with_environment(s7_scheme *sc, const char *str, s7_pointer e);
  50. s7_pointer s7_object_to_string(s7_scheme *sc, s7_pointer arg, bool use_write);
  51. /* (object->string obj) */
  52. char *s7_object_to_c_string(s7_scheme *sc, s7_pointer obj); /* same as object->string but returns a C char* directly */
  53. /* the returned value should be freed by the caller */
  54. s7_pointer s7_load(s7_scheme *sc, const char *file); /* (load file) */
  55. s7_pointer s7_load_with_environment(s7_scheme *sc, const char *filename, s7_pointer e);
  56. s7_pointer s7_load_path(s7_scheme *sc); /* *load-path* */
  57. s7_pointer s7_add_to_load_path(s7_scheme *sc, const char *dir); /* (set! *load-path* (cons dir *load-path*)) */
  58. s7_pointer s7_autoload(s7_scheme *sc, s7_pointer symbol, s7_pointer file_or_function); /* (autoload symbol file-or-function) */
  59. /* the load path is a list of directories to search if load can't find the file passed as its argument.
  60. */
  61. void s7_quit(s7_scheme *sc);
  62. /* this tries to break out of the current evaluation, leaving everything else intact */
  63. void (*s7_begin_hook(s7_scheme *sc))(s7_scheme *sc, bool *val);
  64. void s7_set_begin_hook(s7_scheme *sc, void (*hook)(s7_scheme *sc, bool *val));
  65. /* call "hook" at the start of any block; use NULL to cancel.
  66. * s7_begin_hook returns the current begin_hook function or NULL.
  67. */
  68. s7_pointer s7_eval(s7_scheme *sc, s7_pointer code, s7_pointer e); /* (eval code e) -- e is the optional environment */
  69. void s7_provide(s7_scheme *sc, const char *feature); /* add feature (as a symbol) to the *features* list */
  70. bool s7_is_provided(s7_scheme *sc, const char *feature); /* (provided? feature) */
  71. s7_pointer s7_error(s7_scheme *sc, s7_pointer type, s7_pointer info);
  72. s7_pointer s7_wrong_type_arg_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr);
  73. /* set arg_n to 0 to indicate that caller takes only one argument (so the argument number need not be reported */
  74. s7_pointer s7_out_of_range_error(s7_scheme *sc, const char *caller, int arg_n, s7_pointer arg, const char *descr);
  75. s7_pointer s7_wrong_number_of_args_error(s7_scheme *sc, const char *caller, s7_pointer args);
  76. s7_pointer s7_stacktrace(s7_scheme *sc);
  77. /* these are equivalent to (error ...) in Scheme
  78. * the first argument to s7_error is a symbol that can be caught (via (catch tag ...))
  79. * the rest of the arguments are passed to the error handler (if in catch)
  80. * or printed out (in the default case). If the first element of the list
  81. * of args ("info") is a string, the default error handler treats it as
  82. * a format control string, and passes it to format with the rest of the
  83. * info list as the format function arguments.
  84. *
  85. * s7_wrong_type_arg_error is equivalent to s7_error with a type of 'wrong-type-arg
  86. * and similarly s7_out_of_range_error with type 'out-of-range.
  87. *
  88. * catch in Scheme is taken from Guile:
  89. *
  90. * (catch tag thunk handler)
  91. *
  92. * evaluates 'thunk'. If an error occurs, and the type matches 'tag' (or if 'tag' is #t),
  93. * the handler is called, passing it the arguments (including the type) passed to the
  94. * error function. If no handler is found, the default error handler is called,
  95. * normally printing the error arguments to current-error-port.
  96. */
  97. unsigned int s7_gc_protect(s7_scheme *sc, s7_pointer x);
  98. void s7_gc_unprotect(s7_scheme *sc, s7_pointer x);
  99. void s7_gc_unprotect_at(s7_scheme *sc, unsigned int loc);
  100. s7_pointer s7_gc_protected_at(s7_scheme *sc, unsigned int loc);
  101. s7_pointer s7_gc_on(s7_scheme *sc, bool on);
  102. void s7_gc_stats(s7_scheme *sc, bool on);
  103. unsigned int s7_heap_size(s7_scheme *sc);
  104. int s7_gc_freed(s7_scheme *sc);
  105. /* any s7_pointer object held in C (as a local variable for example) needs to be
  106. * protected from garbage collection if there is any chance the GC may run without
  107. * an existing Scheme-level reference to that object. s7_gc_protect places the
  108. * object in a vector that the GC always checks, returning the object's location
  109. * in that table. s7_gc_unprotect and s7_gc_unprotect_at unprotect the object
  110. * (remove it from the vector). s7_gc_unprotect_at uses the location passed
  111. * to it, whereas s7_gc_unprotect scans the vector to find the object.
  112. * s7_gc_protected_at returns the object at the given location.
  113. *
  114. * You can turn the GC on and off via s7_gc_on.
  115. *
  116. * There is a built-in lag between the creation of a new object and its first possible GC
  117. * (the lag time is set indirectly by GC_TEMPS_SIZE in s7.c), so you don't need to worry about
  118. * very short term temps such as the arguments to s7_cons in:
  119. *
  120. * s7_cons(s7, s7_make_real(s7, 3.14),
  121. * s7_cons(s7, s7_make_integer(s7, 123),
  122. * s7_nil(s7)));
  123. */
  124. bool s7_is_eq(s7_pointer a, s7_pointer b); /* (eq? a b) */
  125. bool s7_is_eqv(s7_pointer a, s7_pointer b); /* (eqv? a b) */
  126. bool s7_is_equal(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (equal? a b) */
  127. bool s7_is_boolean(s7_pointer x); /* (boolean? x) */
  128. bool s7_boolean(s7_scheme *sc, s7_pointer x); /* Scheme boolean -> C bool */
  129. s7_pointer s7_make_boolean(s7_scheme *sc, bool x); /* C bool -> Scheme boolean */
  130. /* for each Scheme type (boolean, integer, string, etc), there are three
  131. * functions: s7_<type>(...), s7_make_<type>(...), and s7_is_<type>(...):
  132. *
  133. * s7_boolean(s7, obj) returns the C bool corresponding to the value of 'obj' (#f -> false)
  134. * s7_make_boolean(s7, false|true) returns the s7 boolean corresponding to the C bool argument (false -> #f)
  135. * s7_is_boolean(s7, obj) returns true if 'obj' has a boolean value (#f or #t).
  136. */
  137. bool s7_is_pair(s7_pointer p); /* (pair? p) */
  138. s7_pointer s7_cons(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (cons a b) */
  139. s7_pointer s7_car(s7_pointer p); /* (car p) */
  140. s7_pointer s7_cdr(s7_pointer p); /* (cdr p) */
  141. s7_pointer s7_set_car(s7_pointer p, s7_pointer q); /* (set-car! p q) */
  142. s7_pointer s7_set_cdr(s7_pointer p, s7_pointer q); /* (set-cdr! p q) */
  143. s7_pointer s7_cadr(s7_pointer p); /* (cadr p) */
  144. s7_pointer s7_cddr(s7_pointer p); /* (cddr p) */
  145. s7_pointer s7_cdar(s7_pointer p); /* (cdar p) */
  146. s7_pointer s7_caar(s7_pointer p); /* (caar p) */
  147. s7_pointer s7_caadr(s7_pointer p); /* etc */
  148. s7_pointer s7_caddr(s7_pointer p);
  149. s7_pointer s7_cadar(s7_pointer p);
  150. s7_pointer s7_caaar(s7_pointer p);
  151. s7_pointer s7_cdadr(s7_pointer p);
  152. s7_pointer s7_cdddr(s7_pointer p);
  153. s7_pointer s7_cddar(s7_pointer p);
  154. s7_pointer s7_cdaar(s7_pointer p);
  155. s7_pointer s7_caaadr(s7_pointer p);
  156. s7_pointer s7_caaddr(s7_pointer p);
  157. s7_pointer s7_caadar(s7_pointer p);
  158. s7_pointer s7_caaaar(s7_pointer p);
  159. s7_pointer s7_cadadr(s7_pointer p);
  160. s7_pointer s7_cadddr(s7_pointer p);
  161. s7_pointer s7_caddar(s7_pointer p);
  162. s7_pointer s7_cadaar(s7_pointer p);
  163. s7_pointer s7_cdaadr(s7_pointer p);
  164. s7_pointer s7_cdaddr(s7_pointer p);
  165. s7_pointer s7_cdadar(s7_pointer p);
  166. s7_pointer s7_cdaaar(s7_pointer p);
  167. s7_pointer s7_cddadr(s7_pointer p);
  168. s7_pointer s7_cddddr(s7_pointer p);
  169. s7_pointer s7_cdddar(s7_pointer p);
  170. s7_pointer s7_cddaar(s7_pointer p);
  171. bool s7_is_list(s7_scheme *sc, s7_pointer p); /* (list? p) -> (or (pair? p) (null? p)) */
  172. int s7_list_length(s7_scheme *sc, s7_pointer a); /* (length a) */
  173. s7_pointer s7_list(s7_scheme *sc, int num_values, ...); /* (list ...) */
  174. s7_pointer s7_reverse(s7_scheme *sc, s7_pointer a); /* (reverse a) */
  175. s7_pointer s7_append(s7_scheme *sc, s7_pointer a, s7_pointer b); /* (append a b) */
  176. s7_pointer s7_list_ref(s7_scheme *sc, s7_pointer lst, int num); /* (list-ref lst num) */
  177. s7_pointer s7_list_set(s7_scheme *sc, s7_pointer lst, int num, s7_pointer val); /* (list-set! lst num val) */
  178. s7_pointer s7_assoc(s7_scheme *sc, s7_pointer obj, s7_pointer lst); /* (assoc obj lst) */
  179. s7_pointer s7_assq(s7_scheme *sc, s7_pointer obj, s7_pointer x); /* (assq obj lst) */
  180. s7_pointer s7_member(s7_scheme *sc, s7_pointer obj, s7_pointer lst); /* (member obj lst) */
  181. s7_pointer s7_memq(s7_scheme *sc, s7_pointer obj, s7_pointer x); /* (memq obj lst) */
  182. bool s7_is_string(s7_pointer p); /* (string? p) */
  183. const char *s7_string(s7_pointer p); /* Scheme string -> C string (do not free the string) */
  184. s7_pointer s7_make_string(s7_scheme *sc, const char *str); /* C string -> Scheme string (str is copied) */
  185. s7_pointer s7_make_string_with_length(s7_scheme *sc, const char *str, int len); /* same as s7_make_string, but provides strlen */
  186. s7_pointer s7_make_permanent_string(const char *str); /* make a string that will never be GC'd */
  187. unsigned int s7_string_length(s7_pointer str); /* (string-length str) */
  188. bool s7_is_character(s7_pointer p); /* (character? p) */
  189. char s7_character(s7_pointer p); /* Scheme character -> C char */
  190. s7_pointer s7_make_character(s7_scheme *sc, unsigned int c); /* C char (as unsigned int) -> Scheme character */
  191. bool s7_is_number(s7_pointer p); /* (number? p) */
  192. bool s7_is_integer(s7_pointer p); /* (integer? p) */
  193. s7_int s7_integer(s7_pointer p); /* Scheme integer -> C int (long long int probably) */
  194. s7_pointer s7_make_integer(s7_scheme *sc, s7_int num); /* C long long int -> Scheme integer */
  195. bool s7_is_real(s7_pointer p); /* (real? p) */
  196. s7_double s7_real(s7_pointer p); /* Scheme real -> C double */
  197. s7_pointer s7_make_real(s7_scheme *sc, s7_double num); /* C double -> Scheme real */
  198. s7_pointer s7_make_mutable_real(s7_scheme *sc, s7_double n);
  199. s7_double s7_number_to_real(s7_scheme *sc, s7_pointer x); /* x can be any kind of number */
  200. s7_double s7_number_to_real_with_caller(s7_scheme *sc, s7_pointer x, const char *caller);
  201. s7_int s7_number_to_integer(s7_scheme *sc, s7_pointer x);
  202. s7_int s7_number_to_integer_with_caller(s7_scheme *sc, s7_pointer x, const char *caller);
  203. bool s7_is_ulong(s7_pointer arg); /* returns true if arg is an unsigned long */
  204. unsigned long s7_ulong(s7_pointer p); /* Scheme unsigned long -> C */
  205. s7_pointer s7_make_ulong(s7_scheme *sc, unsigned long n); /* C unsigned lonog -> Scheme */
  206. bool s7_is_ulong_long(s7_pointer arg); /* returns true if arg is an unsigned long long */
  207. unsigned long long s7_ulong_long(s7_pointer p); /* Scheme unsigned long long -> C */
  208. s7_pointer s7_make_ulong_long(s7_scheme *sc, unsigned long long n); /* C unsigned long long -> Scheme */
  209. /* the ulong stuff is intended for passing uninterpreted C pointers through Scheme and back to C */
  210. bool s7_is_rational(s7_pointer arg); /* (rational? arg) -- integer or ratio */
  211. bool s7_is_ratio(s7_pointer arg); /* true if arg is a ratio, not an integer */
  212. s7_pointer s7_make_ratio(s7_scheme *sc, s7_int a, s7_int b); /* returns the Scheme object a/b */
  213. s7_pointer s7_rationalize(s7_scheme *sc, s7_double x, s7_double error); /* (rationalize x error) */
  214. s7_int s7_numerator(s7_pointer x); /* (numerator x) */
  215. s7_int s7_denominator(s7_pointer x); /* (denominator x) */
  216. s7_double s7_random(s7_scheme *sc, s7_pointer state); /* (random x) */
  217. s7_pointer s7_random_state(s7_scheme *sc, s7_pointer seed); /* (random-state seed) */
  218. s7_pointer s7_random_state_to_list(s7_scheme *sc, s7_pointer args); /* (random-state->list r) */
  219. void s7_set_default_random_state(s7_scheme *sc, s7_int seed, s7_int carry);
  220. bool s7_is_complex(s7_pointer arg); /* (complex? arg) */
  221. s7_pointer s7_make_complex(s7_scheme *sc, s7_double a, s7_double b); /* returns the Scheme object a+bi */
  222. s7_double s7_real_part(s7_pointer z); /* (real-part z) */
  223. s7_double s7_imag_part(s7_pointer z); /* (imag-part z) */
  224. char *s7_number_to_string(s7_scheme *sc, s7_pointer obj, int radix); /* (number->string obj radix) */
  225. bool s7_is_vector(s7_pointer p); /* (vector? p) */
  226. s7_int s7_vector_length(s7_pointer vec); /* (vector-length vec) */
  227. int s7_vector_rank(s7_pointer vect); /* number of dimensions in vect */
  228. s7_int *s7_vector_dimensions(s7_pointer vec); /* dimensions */
  229. s7_int *s7_vector_offsets(s7_pointer vec); /* precalculated offsets to speed-up addressing */
  230. s7_pointer *s7_vector_elements(s7_pointer vec); /* a pointer to the array of s7_pointers */
  231. s7_int *s7_int_vector_elements(s7_pointer vec);
  232. s7_double *s7_float_vector_elements(s7_pointer vec);
  233. bool s7_is_float_vector(s7_pointer p);
  234. bool s7_is_int_vector(s7_pointer p);
  235. s7_pointer s7_vector_ref(s7_scheme *sc, s7_pointer vec, s7_int index); /* (vector-ref vec index) */
  236. s7_pointer s7_vector_set(s7_scheme *sc, s7_pointer vec, s7_int index, s7_pointer a); /* (vector-set! vec index a) */
  237. s7_pointer s7_vector_ref_n(s7_scheme *sc, s7_pointer vector, int indices, ...); /* multidimensional vector-ref */
  238. s7_pointer s7_vector_set_n(s7_scheme *sc, s7_pointer vector, s7_pointer value, int indices, ...); /* multidimensional vector-set! */
  239. s7_pointer s7_make_vector(s7_scheme *sc, s7_int len); /* (make-vector len) */
  240. s7_pointer s7_make_int_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info);
  241. s7_pointer s7_make_float_vector(s7_scheme *sc, s7_int len, int dims, s7_int *dim_info);
  242. s7_pointer s7_make_float_vector_wrapper(s7_scheme *sc, s7_int len, s7_double *data, int dims, s7_int *dim_info, bool free_data);
  243. s7_pointer s7_make_and_fill_vector(s7_scheme *sc, s7_int len, s7_pointer fill); /* (make-vector len fill) */
  244. void s7_vector_fill(s7_scheme *sc, s7_pointer vec, s7_pointer obj); /* (vector-fill! vec obj) */
  245. s7_pointer s7_vector_copy(s7_scheme *sc, s7_pointer old_vect);
  246. s7_pointer s7_vector_to_list(s7_scheme *sc, s7_pointer vect); /* (vector->list vec) */
  247. s7_int s7_print_length(s7_scheme *sc); /* value of (*s7* 'print-length) */
  248. s7_int s7_set_print_length(s7_scheme *sc, s7_int new_len); /* sets (*s7* 'print-length), returns old value */
  249. /*
  250. * (vect i) is the same as (vector-ref vect i)
  251. * (set! (vect i) x) is the same as (vector-set! vect i x)
  252. * (vect i j k) accesses the 3-dimensional vect
  253. * (set! (vect i j k) x) sets that element (vector-ref and vector-set! can also be used)
  254. * (make-vector (list 2 3 4)) returns a 3-dimensional vector with the given dimension sizes
  255. * (make-vector '(2 3) 1.0) returns a 2-dim vector with all elements set to 1.0
  256. */
  257. bool s7_is_hash_table(s7_pointer p); /* (hash-table? p) */
  258. s7_pointer s7_make_hash_table(s7_scheme *sc, s7_int size); /* (make-hash-table size) */
  259. s7_pointer s7_hash_table_ref(s7_scheme *sc, s7_pointer table, s7_pointer key);
  260. /* (hash-table-ref table key) */
  261. s7_pointer s7_hash_table_set(s7_scheme *sc, s7_pointer table, s7_pointer key, s7_pointer value);
  262. /* (hash-table-set! table key value) */
  263. s7_pointer s7_hook_functions(s7_scheme *sc, s7_pointer hook); /* (hook-functions hook) */
  264. s7_pointer s7_hook_set_functions(s7_scheme *sc, s7_pointer hook, s7_pointer functions); /* (set! (hook-functions hook) ...) */
  265. bool s7_is_input_port(s7_scheme *sc, s7_pointer p); /* (input-port? p) */
  266. bool s7_is_output_port(s7_scheme *sc, s7_pointer p); /* (output-port? p) */
  267. const char *s7_port_filename(s7_pointer x); /* (port-filename p) */
  268. int s7_port_line_number(s7_pointer p); /* (port-line-number p) */
  269. s7_pointer s7_current_input_port(s7_scheme *sc); /* (current-input-port) */
  270. s7_pointer s7_set_current_input_port(s7_scheme *sc, s7_pointer p); /* (set-current-input-port) */
  271. s7_pointer s7_current_output_port(s7_scheme *sc); /* (current-output-port) */
  272. s7_pointer s7_set_current_output_port(s7_scheme *sc, s7_pointer p); /* (set-current-output-port) */
  273. s7_pointer s7_current_error_port(s7_scheme *sc); /* (current-error-port) */
  274. s7_pointer s7_set_current_error_port(s7_scheme *sc, s7_pointer port); /* (set-current-error-port port) */
  275. void s7_close_input_port(s7_scheme *sc, s7_pointer p); /* (close-input-port p) */
  276. void s7_close_output_port(s7_scheme *sc, s7_pointer p); /* (close-output-port p) */
  277. s7_pointer s7_open_input_file(s7_scheme *sc, const char *name, const char *mode);
  278. /* (open-input-file name mode) */
  279. s7_pointer s7_open_output_file(s7_scheme *sc, const char *name, const char *mode);
  280. /* (open-output-file name mode) */
  281. /* mode here is an optional C style flag, "a" for "alter", etc ("r" is the input default, "w" is the output default) */
  282. s7_pointer s7_open_input_string(s7_scheme *sc, const char *input_string);
  283. /* (open-input-string str) */
  284. s7_pointer s7_open_output_string(s7_scheme *sc); /* (open-output-string) */
  285. const char *s7_get_output_string(s7_scheme *sc, s7_pointer out_port); /* (get-output-string port) -- current contents of output string */
  286. /* don't free the string */
  287. void s7_flush_output_port(s7_scheme *sc, s7_pointer p); /* (flush-output-port port) */
  288. typedef enum {S7_READ, S7_READ_CHAR, S7_READ_LINE, S7_READ_BYTE, S7_PEEK_CHAR, S7_IS_CHAR_READY} s7_read_t;
  289. s7_pointer s7_open_output_function(s7_scheme *sc, void (*function)(s7_scheme *sc, unsigned char c, s7_pointer port));
  290. s7_pointer s7_open_input_function(s7_scheme *sc, s7_pointer (*function)(s7_scheme *sc, s7_read_t read_choice, s7_pointer port));
  291. int s7_read_char(s7_scheme *sc, s7_pointer port); /* (read-char port) */
  292. int s7_peek_char(s7_scheme *sc, s7_pointer port); /* (peek-char port) */
  293. s7_pointer s7_read(s7_scheme *sc, s7_pointer port); /* (read port) */
  294. void s7_newline(s7_scheme *sc, s7_pointer port); /* (newline port) */
  295. void s7_write_char(s7_scheme *sc, int c, s7_pointer port); /* (write-char c port) */
  296. void s7_write(s7_scheme *sc, s7_pointer obj, s7_pointer port); /* (write obj port) */
  297. void s7_display(s7_scheme *sc, s7_pointer obj, s7_pointer port); /* (display obj port) */
  298. const char *s7_format(s7_scheme *sc, s7_pointer args); /* (format ... */
  299. bool s7_is_procedure(s7_pointer x); /* (procedure? x) */
  300. bool s7_is_macro(s7_scheme *sc, s7_pointer x); /* (macro? x) */
  301. s7_pointer s7_closure_body(s7_scheme *sc, s7_pointer p);
  302. s7_pointer s7_closure_let(s7_scheme *sc, s7_pointer p);
  303. s7_pointer s7_closure_args(s7_scheme *sc, s7_pointer p);
  304. s7_pointer s7_funclet(s7_scheme *sc, s7_pointer p); /* (funclet x) */
  305. const char *s7_procedure_documentation(s7_scheme *sc, s7_pointer p); /* (procedure-documentation x) if any (don't free the string) */
  306. s7_pointer s7_make_signature(s7_scheme *sc, int len, ...); /* procedure-signature data */
  307. s7_pointer s7_make_circular_signature(s7_scheme *sc, int cycle_point, int len, ...);
  308. bool s7_is_aritable(s7_scheme *sc, s7_pointer x, int args); /* (aritable? x args) */
  309. s7_pointer s7_arity(s7_scheme *sc, s7_pointer x); /* (arity x) */
  310. const char *s7_help(s7_scheme *sc, s7_pointer obj); /* (help obj) */
  311. s7_pointer s7_make_continuation(s7_scheme *sc); /* call/cc... (see example below) */
  312. bool s7_is_syntax(s7_pointer p);
  313. bool s7_is_symbol(s7_pointer p); /* (symbol? p) */
  314. const char *s7_symbol_name(s7_pointer p); /* (symbol->string p) -- don't free the string */
  315. s7_pointer s7_make_symbol(s7_scheme *sc, const char *name); /* (string->symbol name) */
  316. s7_pointer s7_gensym(s7_scheme *sc, const char *prefix); /* (gensym prefix) */
  317. bool s7_is_keyword(s7_pointer obj); /* (keyword? obj) */
  318. s7_pointer s7_make_keyword(s7_scheme *sc, const char *key); /* (make-keyword key) */
  319. s7_pointer s7_symbol_access(s7_scheme *sc, s7_pointer sym);
  320. s7_pointer s7_symbol_set_access(s7_scheme *sc, s7_pointer symbol, s7_pointer func);
  321. s7_pointer s7_slot(s7_scheme *sc, s7_pointer symbol);
  322. s7_pointer s7_slot_value(s7_pointer slot);
  323. s7_pointer s7_slot_set_value(s7_scheme *sc, s7_pointer slot, s7_pointer value);
  324. s7_pointer s7_make_slot(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value);
  325. s7_pointer s7_rootlet(s7_scheme *sc); /* (rootlet) */
  326. s7_pointer s7_shadow_rootlet(s7_scheme *sc);
  327. s7_pointer s7_set_shadow_rootlet(s7_scheme *sc, s7_pointer let);
  328. s7_pointer s7_curlet(s7_scheme *sc); /* (curlet) */
  329. s7_pointer s7_set_curlet(s7_scheme *sc, s7_pointer e); /* returns previous curlet */
  330. s7_pointer s7_outlet(s7_scheme *sc, s7_pointer e); /* (outlet e) */
  331. s7_pointer s7_sublet(s7_scheme *sc, s7_pointer env, s7_pointer bindings); /* (sublet e ...) */
  332. s7_pointer s7_inlet(s7_scheme *sc, s7_pointer bindings); /* (inlet ...) */
  333. s7_pointer s7_varlet(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value); /* (varlet env symbol value) */
  334. s7_pointer s7_let_to_list(s7_scheme *sc, s7_pointer env); /* (let->list env) */
  335. bool s7_is_let(s7_pointer e); /* )let? e) */
  336. s7_pointer s7_let_ref(s7_scheme *sc, s7_pointer env, s7_pointer sym); /* (let-ref e sym) */
  337. s7_pointer s7_let_set(s7_scheme *sc, s7_pointer env, s7_pointer sym, s7_pointer val); /* (let-set! e sym val) */
  338. s7_pointer s7_openlet(s7_scheme *sc, s7_pointer e); /* (openlet e) */
  339. bool s7_is_openlet(s7_pointer e); /* (openlet? e) */
  340. s7_pointer s7_method(s7_scheme *sc, s7_pointer obj, s7_pointer method);
  341. s7_pointer s7_name_to_value(s7_scheme *sc, const char *name);
  342. s7_pointer s7_symbol_table_find_name(s7_scheme *sc, const char *name);
  343. s7_pointer s7_symbol_value(s7_scheme *sc, s7_pointer sym);
  344. s7_pointer s7_symbol_set_value(s7_scheme *sc, s7_pointer sym, s7_pointer val);
  345. s7_pointer s7_symbol_local_value(s7_scheme *sc, s7_pointer sym, s7_pointer local_env);
  346. char *s7_symbol_documentation(s7_scheme *sc, s7_pointer sym);
  347. char *s7_symbol_set_documentation(s7_scheme *sc, s7_pointer sym, const char *new_doc);
  348. bool s7_for_each_symbol_name(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, void *data), void *data);
  349. bool s7_for_each_symbol(s7_scheme *sc, bool (*symbol_func)(const char *symbol_name, s7_pointer value, void *data), void *data);
  350. /* these access the current environment and symbol table, providing
  351. * a symbol's current binding (s7_name_to_value takes the symbol name as a char*,
  352. * s7_symbol_value takes the symbol itself, s7_symbol_set_value changes the
  353. * current binding, and s7_symbol_local_value uses the environment passed
  354. * as its third argument).
  355. *
  356. * To iterate over the complete symbol table, use s7_for_each_symbol_name,
  357. * and s7_for_each_symbol. The latter calls the 'symbol_func' on each
  358. * symbol, passing the symbol name, its current binding, and the uninterpreted
  359. * 'data' pointer. s7_for_each_symbol_name is similar, but does not include
  360. * the current binding.
  361. *
  362. * The for-each loop stops if the symbol_func returns true, or at the end of the table.
  363. */
  364. void s7_define(s7_scheme *sc, s7_pointer env, s7_pointer symbol, s7_pointer value);
  365. bool s7_is_defined(s7_scheme *sc, const char *name);
  366. s7_pointer s7_define_variable(s7_scheme *sc, const char *name, s7_pointer value);
  367. s7_pointer s7_define_variable_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help);
  368. s7_pointer s7_define_constant(s7_scheme *sc, const char *name, s7_pointer value);
  369. s7_pointer s7_define_constant_with_documentation(s7_scheme *sc, const char *name, s7_pointer value, const char *help);
  370. bool s7_is_constant(s7_pointer p);
  371. /* These three functions add a symbol and its binding to either the top-level environment
  372. * or the 'env' passed as the second argument to s7_define.
  373. *
  374. * s7_define_variable(sc, "*features*", sc->NIL);
  375. *
  376. * in s7.c is equivalent to the top level form
  377. *
  378. * (define *features* ())
  379. *
  380. * s7_define_variable is simply s7_define with string->symbol and the global environment.
  381. * s7_define_constant is s7_define but makes its "definee" immutable.
  382. * s7_define is equivalent to define in Scheme.
  383. */
  384. bool s7_is_function(s7_pointer p);
  385. s7_pointer s7_make_function(s7_scheme *sc, const char *name, s7_function fnc,
  386. int required_args, int optional_args, bool rest_arg, const char *doc);
  387. s7_pointer s7_make_safe_function(s7_scheme *sc, const char *name, s7_function fnc,
  388. int required_args, int optional_args, bool rest_arg, const char *doc);
  389. s7_pointer s7_make_typed_function(s7_scheme *sc, const char *name, s7_function f,
  390. int required_args, int optional_args, bool rest_arg, const char *doc, s7_pointer signature);
  391. s7_pointer s7_define_function(s7_scheme *sc, const char *name, s7_function fnc,
  392. int required_args, int optional_args, bool rest_arg, const char *doc);
  393. s7_pointer s7_define_safe_function(s7_scheme *sc, const char *name, s7_function fnc,
  394. int required_args, int optional_args, bool rest_arg, const char *doc);
  395. s7_pointer s7_define_typed_function(s7_scheme *sc, const char *name, s7_function fnc,
  396. int required_args, int optional_args, bool rest_arg,
  397. const char *doc, s7_pointer signature);
  398. s7_pointer s7_define_unsafe_typed_function(s7_scheme *sc, const char *name, s7_function fnc,
  399. int required_args, int optional_args, bool rest_arg,
  400. const char *doc, s7_pointer signature);
  401. void s7_define_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc);
  402. void s7_define_safe_function_star(s7_scheme *sc, const char *name, s7_function fnc, const char *arglist, const char *doc);
  403. void s7_define_function_with_setter(s7_scheme *sc, const char *name, s7_function get_fnc,
  404. s7_function set_fnc, int req_args, int opt_args, const char *doc);
  405. /* this is now the same as s7_dilambda (different args) */
  406. s7_pointer s7_apply_function(s7_scheme *sc, s7_pointer fnc, s7_pointer args);
  407. s7_pointer s7_define_macro(s7_scheme *sc, const char *name, s7_function fnc, int required_args, int optional_args, bool rest_arg, const char *doc);
  408. /* s7_make_function creates a Scheme function object from the s7_function 'fnc'.
  409. * Its name (for s7_describe_object) is 'name', it requires 'required_args' arguments,
  410. * can accept 'optional_args' other arguments, and if 'rest_arg' is true, it accepts
  411. * a "rest" argument (a list of all the trailing arguments). The function's documentation
  412. * is 'doc'.
  413. *
  414. * s7_define_function is the same as s7_make_function, but it also adds 'name' (as a symbol) to the
  415. * global (top-level) environment, with the function as its value. For example, the Scheme
  416. * function 'car' is essentially:
  417. *
  418. * s7_pointer g_car(s7_scheme *sc, s7_pointer args)
  419. * {return(s7_car(sc, s7_car(sc, args)));}
  420. *
  421. * then bound to the name "car":
  422. *
  423. * s7_define_function(sc, "car", g_car, 1, 0, false, "(car obj)");
  424. * one required arg, no optional arg, no "rest" arg
  425. *
  426. * s7_is_function returns true if its argument is a function defined in this manner.
  427. * s7_apply_function applies the function (the result of s7_make_function) to the arguments.
  428. *
  429. * s7_define_macro defines a Scheme macro; its arguments are not evaluated (unlike a function),
  430. * but its returned value (assumed to be some sort of Scheme expression) is evaluated.
  431. */
  432. /* In s7, (define* (name . args) body) or (define name (lambda* args body))
  433. * define a function that takes optional (keyword) named arguments.
  434. * The "args" is a list that can contain either names (normal arguments),
  435. * or lists of the form (name default-value), in any order. When called,
  436. * the names are bound to their default values (or #f), then the function's
  437. * current arglist is scanned. Any name that occurs as a keyword (":name")
  438. * precedes that argument's new value. Otherwise, as values occur, they
  439. * are plugged into the environment based on their position in the arglist
  440. * (as normal for a function). So,
  441. *
  442. * (define* (hi a (b 32) (c "hi")) (list a b c))
  443. * (hi 1) -> '(1 32 "hi")
  444. * (hi :b 2 :a 3) -> '(3 2 "hi")
  445. * (hi 3 2 1) -> '(3 2 1)
  446. *
  447. * :rest causes its argument to be bound to the rest of the arguments at that point.
  448. *
  449. * The C connection to this takes the function name, the C function to call, the argument
  450. * list as written in Scheme, and the documentation string. s7 makes sure the arguments
  451. * are ordered correctly and have the specified defaults before calling the C function.
  452. * s7_define_function_star(sc, "a-func", a_func, "arg1 (arg2 32)", "an example of C define*");
  453. * Now (a-func :arg1 2) calls the C function a_func(2, 32). See the example program in s7.html.
  454. *
  455. * In s7 Scheme, define* can be used just for its optional arguments feature, but that is
  456. * included in s7_define_function. s7_define_function_star implements keyword arguments
  457. * for C-level functions (as well as optional/rest arguments).
  458. */
  459. s7_pointer s7_call(s7_scheme *sc, s7_pointer func, s7_pointer args);
  460. s7_pointer s7_call_with_location(s7_scheme *sc, s7_pointer func, s7_pointer args, const char *caller, const char *file, int line);
  461. /* s7_call takes a Scheme function (e.g. g_car above), and applies it to 'args' (a list of arguments)
  462. * returning the result.
  463. *
  464. * s7_integer(s7_call(s7, g_car, s7_cons(s7, s7_make_integer(s7, 123), s7_nil(s7))));
  465. *
  466. * returns 123.
  467. *
  468. * s7_call_with_location passes some information to the error handler.
  469. */
  470. s7_pointer s7_dynamic_wind(s7_scheme *sc, s7_pointer init, s7_pointer body, s7_pointer finish);
  471. bool s7_is_dilambda(s7_pointer obj);
  472. s7_pointer s7_dilambda(s7_scheme *sc,
  473. const char *name,
  474. s7_pointer (*getter)(s7_scheme *sc, s7_pointer args),
  475. int get_req_args, int get_opt_args,
  476. s7_pointer (*setter)(s7_scheme *sc, s7_pointer args),
  477. int set_req_args, int set_opt_args,
  478. const char *documentation);
  479. s7_pointer s7_typed_dilambda(s7_scheme *sc,
  480. const char *name,
  481. s7_pointer (*getter)(s7_scheme *sc, s7_pointer args),
  482. int get_req_args, int get_opt_args,
  483. s7_pointer (*setter)(s7_scheme *sc, s7_pointer args),
  484. int set_req_args, int set_opt_args,
  485. const char *documentation,
  486. s7_pointer get_sig, s7_pointer set_sig);
  487. s7_pointer s7_procedure_setter(s7_scheme *sc, s7_pointer obj);
  488. s7_pointer s7_values(s7_scheme *sc, s7_pointer args);
  489. s7_pointer s7_make_iterator(s7_scheme *sc, s7_pointer e);
  490. bool s7_is_iterator(s7_pointer obj);
  491. bool s7_iterator_is_at_end(s7_pointer obj);
  492. s7_pointer s7_iterate(s7_scheme *sc, s7_pointer iter);
  493. /* ancient form -- backwards compatibility */
  494. int s7_new_type(const char *name,
  495. char *(*print)(s7_scheme *sc, void *value),
  496. void (*free)(void *value),
  497. bool (*equal)(void *val1, void *val2),
  498. void (*gc_mark)(void *val),
  499. s7_pointer (*apply)(s7_scheme *sc, s7_pointer obj, s7_pointer args),
  500. s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args));
  501. /* new form */
  502. int s7_new_type_x(s7_scheme *sc,
  503. const char *name,
  504. char *(*print)(s7_scheme *sc, void *value),
  505. void (*free)(void *value),
  506. bool (*equal)(void *val1, void *val2),
  507. void (*gc_mark)(void *val),
  508. s7_pointer (*apply)(s7_scheme *sc, s7_pointer obj, s7_pointer args),
  509. s7_pointer (*set)(s7_scheme *sc, s7_pointer obj, s7_pointer args),
  510. s7_pointer (*length)(s7_scheme *sc, s7_pointer obj),
  511. s7_pointer (*copy)(s7_scheme *sc, s7_pointer args),
  512. s7_pointer (*reverse)(s7_scheme *sc, s7_pointer obj),
  513. s7_pointer (*fill)(s7_scheme *sc, s7_pointer args));
  514. bool s7_is_object(s7_pointer p);
  515. int s7_object_type(s7_pointer obj);
  516. void *s7_object_value(s7_pointer obj);
  517. void *s7_object_value_checked(s7_pointer obj, int type);
  518. s7_pointer s7_make_object(s7_scheme *sc, int type, void *value);
  519. void s7_mark_object(s7_pointer p);
  520. s7_pointer s7_object_let(s7_pointer obj);
  521. s7_pointer s7_object_set_let(s7_pointer obj, s7_pointer e);
  522. void s7_set_object_print_readably(int type, char *(*printer)(s7_scheme *sc, void *val));
  523. /* These functions create a new Scheme object type. There is a simple example in s7.html.
  524. *
  525. * s7_new_type describes the type for Scheme:
  526. * name: the name used by describe-object
  527. * print: the function called whenever s7 is asked to display a value with this type
  528. * free: the function called when an object of this type is about to be garbage collected
  529. * equal: compare two objects of this type; (equal? obj1 obj2)
  530. * gc_mark: called during the GC mark pass -- you should call s7_mark_object
  531. * on any embedded s7_pointer associated with the object.
  532. * apply: a function that is called whenever an object of this type
  533. * occurs in the function position (at the car of a list; the rest of the list
  534. * is passed to the apply function as the arguments).
  535. * set: a function that is called whenever an object of this type occurs as
  536. * the target of a generalized set!
  537. *
  538. * in the extended version (s7_new_type_x), you can also set the following:
  539. * length: the function called when the object is asked what its length is.
  540. * copy: the function called when a copy of the object is needed.
  541. * fill: the function called to fill the object with some value.
  542. *
  543. * s7_new_type and s7_new_typ_x return an integer that identifies the new type for the other functions.
  544. *
  545. * s7_is_object returns true if 'p' holds a value of a type created by s7_new_type.
  546. * s7_object_type returns the object's type
  547. * s7_object_value returns the value bound to that object (the void *value of s7_make_object)
  548. * s7_make_object creates a new Scheme entity of the given type with the given (uninterpreted) value
  549. * s7_mark_object marks any Scheme object as in-use (use this in the gc_mark function to mark
  550. * any embedded s7_pointer variables).
  551. */
  552. void s7_autoload_set_names(s7_scheme *sc, const char **names, int size);
  553. s7_pointer s7_copy(s7_scheme *sc, s7_pointer args);
  554. s7_pointer s7_fill(s7_scheme *sc, s7_pointer args);
  555. /* these are aimed at the CLM optimizer -- they change daily! */
  556. typedef s7_double (*s7_rf_t)(s7_scheme *sc, s7_pointer **p);
  557. typedef s7_rf_t (*s7_rp_t)(s7_scheme *sc, s7_pointer expr);
  558. void s7_rf_set_function(s7_pointer f, s7_rp_t rp);
  559. s7_rp_t s7_rf_function(s7_scheme *sc, s7_pointer func);
  560. s7_rf_t s7_rf_1(s7_scheme *sc, s7_pointer expr, s7_rf_t r, s7_rf_t s, s7_rf_t x);
  561. s7_rf_t s7_rf_2(s7_scheme *sc, s7_pointer expr, s7_rf_t rr, s7_rf_t sr, s7_rf_t xr, s7_rf_t rs, s7_rf_t ss, s7_rf_t xs, s7_rf_t rx, s7_rf_t sx, s7_rf_t xx);
  562. typedef s7_int (*s7_if_t)(s7_scheme *sc, s7_pointer **p);
  563. typedef s7_if_t (*s7_ip_t)(s7_scheme *sc, s7_pointer expr);
  564. void s7_if_set_function(s7_pointer f, s7_ip_t rp);
  565. s7_ip_t s7_if_function(s7_scheme *sc, s7_pointer func);
  566. typedef s7_pointer (*s7_pf_t)(s7_scheme *sc, s7_pointer **p);
  567. typedef s7_pf_t (*s7_pp_t)(s7_scheme *sc, s7_pointer expr);
  568. void s7_pf_set_function(s7_pointer f, s7_pp_t rp);
  569. s7_pp_t s7_pf_function(s7_scheme *sc, s7_pointer func);
  570. void s7_gf_set_function(s7_pointer f, s7_pp_t gp);
  571. s7_pp_t s7_gf_function(s7_scheme *sc, s7_pointer func);
  572. void *s7_xf_new(s7_scheme *sc, s7_pointer e);
  573. void s7_xf_free(s7_scheme *sc);
  574. s7_int s7_xf_store(s7_scheme *sc, s7_pointer val);
  575. void s7_xf_store_at(s7_scheme *sc, s7_int index, s7_pointer val);
  576. void *s7_xf_detach(s7_scheme *sc);
  577. void s7_xf_attach(s7_scheme *sc, void *ur);
  578. s7_pointer *s7_xf_start(s7_scheme *sc);
  579. s7_pointer *s7_xf_top(s7_scheme *sc, void *ur);
  580. bool s7_xf_is_stepper(s7_scheme *sc, s7_pointer sym);
  581. bool s7_arg_to_gf(s7_scheme *sc, s7_pointer a1);
  582. bool s7_arg_to_pf(s7_scheme *sc, s7_pointer a1);
  583. bool s7_arg_to_if(s7_scheme *sc, s7_pointer a1);
  584. bool s7_arg_to_rf(s7_scheme *sc, s7_pointer a1);
  585. s7_int s7_slot_integer_value(s7_pointer slot);
  586. bool s7_is_stepper(s7_pointer p);
  587. s7_double s7_slot_real_value(s7_scheme *sc, s7_pointer slot, const char *caller);
  588. void s7_slot_set_real_value(s7_scheme *sc, s7_pointer slot, s7_double value);
  589. void s7_object_type_set_xf(int tag, s7_ip_t ip, s7_ip_t set_ip, s7_rp_t rp, s7_rp_t set_rp);
  590. void s7_object_type_set_direct(int tag,
  591. s7_pointer (*dref)(s7_scheme *sc, s7_pointer obj, s7_int index),
  592. s7_pointer (*dset)(s7_scheme *sc, s7_pointer obj, s7_int index, s7_pointer val));
  593. /* end CLM stuff */
  594. /* this is experimental */
  595. s7_pointer s7_apply_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1));
  596. s7_pointer s7_apply_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2));
  597. s7_pointer s7_apply_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3));
  598. s7_pointer s7_apply_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4));
  599. s7_pointer s7_apply_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5));
  600. s7_pointer s7_apply_6(s7_scheme *sc, s7_pointer args,
  601. s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  602. s7_pointer a5, s7_pointer a6));
  603. s7_pointer s7_apply_7(s7_scheme *sc, s7_pointer args,
  604. s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  605. s7_pointer a5, s7_pointer a6, s7_pointer a7));
  606. s7_pointer s7_apply_8(s7_scheme *sc, s7_pointer args,
  607. s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  608. s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8));
  609. s7_pointer s7_apply_9(s7_scheme *sc, s7_pointer args,
  610. s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  611. s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9));
  612. s7_pointer s7_apply_n_1(s7_scheme *sc, s7_pointer args, s7_pointer (*f1)(s7_pointer a1));
  613. s7_pointer s7_apply_n_2(s7_scheme *sc, s7_pointer args, s7_pointer (*f2)(s7_pointer a1, s7_pointer a2));
  614. s7_pointer s7_apply_n_3(s7_scheme *sc, s7_pointer args, s7_pointer (*f3)(s7_pointer a1, s7_pointer a2, s7_pointer a3));
  615. s7_pointer s7_apply_n_4(s7_scheme *sc, s7_pointer args, s7_pointer (*f4)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4));
  616. s7_pointer s7_apply_n_5(s7_scheme *sc, s7_pointer args, s7_pointer (*f5)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4, s7_pointer a5));
  617. s7_pointer s7_apply_n_6(s7_scheme *sc, s7_pointer args,
  618. s7_pointer (*f6)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  619. s7_pointer a5, s7_pointer a6));
  620. s7_pointer s7_apply_n_7(s7_scheme *sc, s7_pointer args,
  621. s7_pointer (*f7)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  622. s7_pointer a5, s7_pointer a6, s7_pointer a7));
  623. s7_pointer s7_apply_n_8(s7_scheme *sc, s7_pointer args,
  624. s7_pointer (*f8)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  625. s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8));
  626. s7_pointer s7_apply_n_9(s7_scheme *sc, s7_pointer args,
  627. s7_pointer (*f9)(s7_pointer a1, s7_pointer a2, s7_pointer a3, s7_pointer a4,
  628. s7_pointer a5, s7_pointer a6, s7_pointer a7, s7_pointer a8, s7_pointer a9));
  629. #if WITH_GMP
  630. #include <gmp.h>
  631. #include <mpfr.h>
  632. #include <mpc.h>
  633. bool s7_is_bignum(s7_pointer obj);
  634. mpfr_t *s7_big_real(s7_pointer x);
  635. mpz_t *s7_big_integer(s7_pointer x);
  636. mpq_t *s7_big_ratio(s7_pointer x);
  637. mpc_t *s7_big_complex(s7_pointer x);
  638. s7_pointer s7_make_big_integer(s7_scheme *sc, mpz_t *val);
  639. s7_pointer s7_make_big_ratio(s7_scheme *sc, mpq_t *val);
  640. s7_pointer s7_make_big_real(s7_scheme *sc, mpfr_t *val);
  641. s7_pointer s7_make_big_complex(s7_scheme *sc, mpc_t *val);
  642. #endif
  643. #ifdef __cplusplus
  644. }
  645. #endif
  646. #endif
  647. #if (!DISABLE_DEPRECATED)
  648. /* cm uses this: */
  649. #define s7_UNSPECIFIED(Sc) s7_unspecified(Sc)
  650. #define s7_NIL(Sc) s7_nil(Sc)
  651. #define s7_is_procedure_with_setter s7_is_dilambda
  652. #define s7_make_procedure_with_setter s7_dilambda
  653. #define s7_define_integer_function s7_define_safe_function
  654. #define s7_make_random_state s7_random_state
  655. #define s7_eval_form s7_eval
  656. #endif
  657. /* --------------------------------------------------------------------------------
  658. *
  659. * s7 changes
  660. *
  661. * 9-Aug: s7_varlet.
  662. * 29-Jul: s7_define_unsafe_typed_function.
  663. * 30-May: symbol takes any number of args. make-vector no longer takes an optional fourth argument.
  664. * 24-May: let-ref/set! check rootlet now if let is not an open let; setter for with-let.
  665. * 20-Feb: removed last vestiges of quasiquoted vector support.
  666. * 3-Feb: *cload-directory*.
  667. * 14-Jan: profile.scm. Moved multiple-value-set! to stuff.scm. Setter for port-line-number.
  668. * 7-Jan: s7_load_with_environment.
  669. * s7_eval_c_string takes only one statement now (use begin to handle multiple statements)
  670. * 4-Jan-16: remove s7_eval_form, change s7_eval to take its place.
  671. * --------
  672. * 11-Dec: owlet error-history field if WITH_HISTORY=1
  673. * 6-Nov: removed :key and :optional.
  674. * 16-Oct: s7_make_random_state -> s7_random_state.
  675. * 16-Aug: remove s7_define_integer_function, s7_function_set_removes_temp,
  676. * add s7_define_typed_function, s7_make_signature.
  677. * 5-Aug: added s7_scheme* arg to s7_openlet and s7_outlet.
  678. * 3-Jul: s7_Double -> s7_double, s7_Int -> s7_int. Removed function_chooser_data.
  679. * 27-Jun: s7_rf_t, s7_rp_t etc.
  680. * 19-Jun: removed the ex_parser stuff, set_step_safe, s7_ex_fallback.
  681. * 5-May: s7_make_iterator and friends.
  682. * 16-Apr: added s7_fill, changed arg interpretation of s7_copy, s7_dynamic_wind.
  683. * 30-Mar: s7_eval_c_string_with_environment (repl experiment).
  684. * 19-Mar: repl.scm.
  685. * 28-Feb: s7_vector_print_length -> s7_print_length, set case also.
  686. * 25-Feb: s7_closure_* funcs to replace clumsy (deprecated) s7_procedure_source.
  687. * 29-Jan: changed args to s7_new_type_x (added s7_scheme arg, fill! takes s7_function).
  688. * 14-Jan-15: make-iterator, iterator?
  689. * --------
  690. * 26-Dec: s7_arity replaces s7_procedure_arity. s7_define_integer_function. deprecate s7_procedure_name.
  691. * 5-Nov: s7_shadow_rootlet and s7_set_shadow_rootlet.
  692. * 30-Aug: s7_make_safe_function (for cload.scm).
  693. * 25-July: define and friends now return the value, not the symbol.
  694. * procedure_with_setter -> dilambda.
  695. * environment -> let. All the replaced names are deprecated.
  696. * 30-June: s7_method.
  697. * 16-June: remove unoptimize and s7_unoptimize.
  698. * 14-May: s7_define_safe_function_star. Removed s7_catch_all.
  699. * 22-Apr: remove s7_apply_n_10, s7_is_valid_pointer, s7_keyword_eq_p.
  700. * 5-Mar-14: s7_heap_size, s7_gc_freed.
  701. * --------
  702. * 8-Nov: s7_symbol_documentation, s7_define_constant_with_documentation.
  703. * 17-Oct: bignum-precision (procedure-with-setter) is now an integer variable named *bignum-precision*.
  704. * 28-Aug: s7_int|float_vector_elements (homogeneous vectors), libc.scm.
  705. * 16-Aug: ~W directive in format, make-shared-vector.
  706. * 23-Jul: s7_autoload_set_names, libm.scm, libdl.scm, libgdbm.scm, r7rs.scm, s7libtest.scm.
  707. * 21-Jul: s7_is_valid (replaces deprecated s7_is_valid_pointer).
  708. * 24-Jun: some bool-related changes for Windows Visual C++, including change to s7_begin_hook.
  709. * 3-June: s7_autoload.
  710. * 28-May: export s7_is_provided. Added s7_scheme* arg to s7_procedure_environment.
  711. * 21-May: equality predicate optional arg in make-hash-table.
  712. * 14-May: glistener.c, glistener.h, s7_symbol_table_find_name (for glistener).
  713. * 2-May: r7rs changes: flush-output-port, vector-append, read|write-string, boolean=?, symbol=?.
  714. * start/end args for string-fill!, vector-fill!, string->list, vector->list, and copy.
  715. * exit, emergency-exit.
  716. * 7-Apr: removed s7_scheme* arg from s7_slot_value, added s7_is_local_variable.
  717. * 25-Mar: char-position, string-position, environment-ref, environment-set! added to the scheme side.
  718. * 9-Jan-13: s7_cos, s7_sin, other optimization changes.
  719. * --------
  720. * 24-Dec: s7_set_object_array_info and other such changes.
  721. * 20-Nov: removed s7_set_error_exiter and s7_error_and_exit which I think have never been used.
  722. * 22-Oct: changed args to s7_function_class and s7_function_set_class.
  723. * 22-Aug: symbol->dynamic-value.
  724. * 10-Aug: exported s7_outer_environment.
  725. * 6-Aug: removed WITH_OPTIMIZATION.
  726. * 25-July: environment (in scheme). s7_vector_ref_n and s7_vector_set_n. s7_copy.
  727. * added s7_scheme arg to s7_number_to_real|integer.
  728. * 16-July: s7_function_returns_temp (an experiment).
  729. * 2-July: s7_object_set_* functions.
  730. * 11-June: throw.
  731. * 4-June. s7_object_environment.
  732. * 31-May: added s7_scheme argument to all the optimizer chooser functions.
  733. * 24-May: open-environment?
  734. * 17-May: arity, aritable?
  735. * removed trace and untrace.
  736. * 14-May: s7_list. s7_procedure_set_setter. Removed s7_procedure_getter.
  737. * procedure-setter is settable: removed most of procedure-with-setter.
  738. * make-type replaced by open-environment.
  739. * 11-May: s7 2.0: hook implementation changed completely.
  740. * s7_environment_ref|set.
  741. * 4-May: *error-info* replaced by error-environment, and stacktrace has changed.
  742. * 22-Apr: #_<name> = startup (built-in) value of name
  743. * 17-Apr: with-baffle.
  744. * 14-Apr: WITH_SYSTEM_EXTRAS (default 0) has additional OS and IO functions:
  745. * directory? file-exists? delete-file getenv directory->list system
  746. * 26-Mar: "@" as exponent, WITH_AT_SIGN_AS_EXPONENT switch (default is 1).
  747. * 18-Mar: removed *trace-hook*.
  748. * 6-Feb: random-state?, hash-table-iterator?, and morally-equal?
  749. * 18-Jan: s7_environment_to_list and environment->list return just the local environment's bindings.
  750. * outer-environment returns the environment enclosing its argument (an environment).
  751. * environments are now applicable objects.
  752. * added the object system example to s7.html.
  753. * 12-Jan: added reverse argument to s7_new_type_x. This is needed because an object might implement
  754. * the apply and set methods, but they might refer to different things.
  755. * 6-Jan-12: added (scheme side) logbit?.
  756. * --------
  757. * 21-Dec: s7_eval, s7_make_slot, s7_slot_set_value.
  758. * changed s7_symbol_slot to s7_slot, and s7_symbol_slot_value to s7_slot_value.
  759. * 26-Oct: s7_procedure_name.
  760. * 6-Oct: changed s7_make_closure args: split the code argument in two (args and body).
  761. * s7_make_closure(... code ...) is now s7_make_closure(... car(code), cdr(code) ...)
  762. * s7_is_environment.
  763. * 19-Aug: s7_function_chooser_data.
  764. * 11-Aug: s7_symbol_accessor functions. s7_cxxxxr.
  765. * 9-Aug: s7_function_chooser, s7_function_choice, s7_function_choice_set_direct.
  766. * 20-Jul: s7_function_class, s7_function_set_class, and s7_function_set_chooser.
  767. * 14-Jul: removed thread and profiling support.
  768. * 5-June: s7_define_safe_function and s7_unoptimize exported; added unoptimize function in scheme.
  769. * 30-May: environment->list and s7_environment_to_list since environments are no longer alists internally.
  770. * 26-May: added s7_scheme argument to s7_procedure_setter and getter (old names had "with_setter_").
  771. * 28-Apr: s7_help.
  772. * 5-Apr: pair-line-number.
  773. * 14-Mar: s7_make_random_state, optional state argument to s7_random, random-state->list, s7_random_state_to_list.
  774. * 10-Feb: s7_vector_print_length, s7_set_vector_print_length.
  775. * 7-Feb: s7_begin_hook, s7_set_begin_hook.
  776. * 25-Jan: s7_is_thread, s7_thread, s7_make_thread, s7_thread_s7, s7_thread_data.
  777. * s7_is_lock, s7_make_lock, s7_lock.
  778. * changed s7_thread_variable_value to s7_thread_variable.
  779. * 23-Jan: removed (scheme-level) quit.
  780. * 17-Jan-11: make-hash-table-iterator.
  781. * map and for-each accept any applicable object as the first argument.
  782. * format's ~{...~} directive can handle any applicable object.
  783. * --------
  784. * 17-Dec: removed unquote-splicing; replaced by (unquote (apply values ...)).
  785. * 12-Dec: environment?
  786. * 7-Dec: member and assoc have an optional third arg, the comparison function.
  787. * 1-Dec: *gc-stats* in Scheme, s7_gc_stats in C.
  788. * gmp and gtk-repl examples in s7.html.
  789. * 21-Nov: Load C module example in s7.html.
  790. * 12-Nov: *trace-hook*, *load-hook*, *error-hook*, and *unbound-variable-hook* are now s7 hooks.
  791. * 9-Nov: hooks: C side: s7_is_hook, s7_make_hook, s7_hook_apply, s7_hook_functions, s7_hook_arity, s7_hook_documentation.
  792. * s7 side: hook?, make-hook, hook, hook-apply, hook-functions, hook-arity, hook-documentation.
  793. * 8-Nov: Closure defined in C example in s7.html.
  794. * 23-Oct: s7_call_with_location for better error reporting.
  795. * 19-Oct: *stdin*, *stdout*, *stderr* for default IO ports (rather than nil which is ambiguous).
  796. * 14-Oct: removed special variable support.
  797. * 30-Sep: setters for current-input-port, current-output-port, and current-error-port.
  798. * 30-Aug: :allow-other-keys in define*.
  799. * 10-Aug: added boolean argument use_write to s7_object_to_string (true=write, false=display).
  800. * 30-July: special macro for access to dynamic binding.
  801. * s7_symbol_special_value for C-side access to dynamic bindings.
  802. * s7_is_macro.
  803. * port-closed? returns #t if its argument (a port) is closed.
  804. * 22-July: s7_make_character takes unsigned int, rather than int.
  805. * added symbol function for funny symbol names.
  806. * 12-July: initial-environment.
  807. * 7-July: removed force and delay: use slib.
  808. * 3-July: new backquote implementation.
  809. * 28-June: syntactic keywords (e.g. lambda) are applicable.
  810. * 7-June: changed key arg in s7_hash_table_ref|set to be s7_pointer, not const char*.
  811. * hash-tables can now handle any s7 object as the key.
  812. * map and for-each now pass a hash-table entry to the function, rather than an internal alist.
  813. * reverse of a hash-table reverses the keys and values (i.e. old value becomes new key, etc).
  814. * 2-June: removed procedure-with-setter-setter-arity and folded that info into procedure-arity (use cdddr).
  815. * 22-May: multidimensional vectors are no longer optional.
  816. * 9-May: s7_read_char and s7_peek_char have to return an int, not a char (<eof>=-1, but 255 is a legit char).
  817. * s7_write_char and s7_open_output_function have similar changes.
  818. * 3-May: *#readers* to customize #... reading. Also nan? and infinite?.
  819. * multidimensional vector constants using #nD(...): (#2D((1 2 3) (4 5 6)) 0 0) -> 1.
  820. * 13-Apr: removed hash-table|vector|string-for-each -- these are handled by for-each.
  821. * also removed vector-map -- map is generic, but always returns a list.
  822. * 12-Apr: removed immutable constant checks -- see s7.html.
  823. * 7-Apr: *unbound-variable-hook*.
  824. * augment-environment and s7_augment_environment.
  825. * 29-Mar: symbol-access, s7_symbol_access, s7_symbol_set_access.
  826. * C example of notification in s7.html.
  827. * 25-Mar: make-type. s7_is_equal now includes an s7_scheme pointer as its first argument.
  828. * 24-Mar: s7_is_defined.
  829. * 19-Mar: removed encapsulation mechanism and s7_define_set_function.
  830. * 18-Mar: added macro?.
  831. * 27-Feb: removed r4rs-style macro syntax.
  832. * 17-Feb: s7_number_to_integer.
  833. * 20-Jan-10: removed the stack function.
  834. * --------
  835. * 16-Dec: hash-table-for-each.
  836. * 1-Dec: mpc versions before 0.8.0 are no longer supported.
  837. * 24-Nov: define-macro* and defmacro*.
  838. * force and delay included only if WITH_FORCE set, promise? removed.
  839. * 17-Nov: s7_is_boolean no longer takes the s7_scheme argument.
  840. * 7-Nov: s7_vector_dimensions, s7_vector_offsets, example of use.
  841. * 3-Nov: s7_vector_rank.
  842. * 30-Oct: *trace-hook*.
  843. * 12-Oct: s7_port_filename.
  844. * 5-Oct: s7_c_pointer and friends.
  845. * 14-Sep: s7_values, s7_make_continuation, and a better interrupt example.
  846. * vector-for-each, vector-map, string-for-each.
  847. * 7-Sep: s7_open_input_function. with-environment. receive.
  848. * 3-Sep: s7.html, s7-slib-init.scm.
  849. * s7_stacktrace in s7.h.
  850. * 27-Aug: vector and hash-table sizes are now s7_ints, rather than ints.
  851. * 20-Aug: s7_remove_from_heap.
  852. * 17-Aug: *error-info*.
  853. * 14-Aug: define-expansion.
  854. * 7-Aug: s7_define_function_with_setter.
  855. * s7_quit and example of signal handling.
  856. * 6-Aug: encapsulation. s7_define_set_function. s7_new_type_x.
  857. * generic function: copy, and length is generic.
  858. * 1-Aug: lower-case versions of s7_T and friends.
  859. * s7_define_macro. macroexpand.
  860. * strings are set-applicable (like vectors).
  861. * 31-Jul: *error-hook*.
  862. * 30-Jul: changed backtrace handling: removed backtrace stuff, added stacktrace.
  863. * removed gc-verbose and load-verbose replaced by *load-hook*.
  864. * 23-Jul: __func__.
  865. * 20-Jul: trace and untrace.
  866. * 14-Jul: replaced s7_make_closure_star with s7_define_function_star.
  867. * 29-Jun: s7_format declaration.
  868. * 12-May: s7_is_constant.
  869. * 20-Apr: changed rationalize to be both r5rs-acceptable and fast.
  870. * 6-Apr: added s7_make_permanent_string.
  871. * 14-Mar: removed s7_local_gc_protect and s7_local_gc_unprotect.
  872. * 4-Mar: multidimensional and applicable vectors.
  873. * 1-Mar: s7_random added to s7.h.
  874. * 29-Jan: s7_is_bignum and friends.
  875. * 26-Jan: added s7_scheme arg to s7_vector_fill.
  876. * 16-Jan: s7_is_ulong_long and friends for C pointers in 64-bit situations.
  877. * 9-Jan-09 multiprecision arithmetic (gmp, mpfr, mpc) on the WITH_GMP switch
  878. * --------
  879. * 29-Dec: "+" specialization example, s7_apply_function.
  880. * 3-Dec: s7_open_output_function.
  881. * 30-Nov: s7_wrong_number_of_args_error.
  882. * 24-Nov: changed s7_make_counted_string to s7_make_string_with_length.
  883. * also added built-in format and define*
  884. * 10-Nov: s7_define_constant,
  885. * built-in (scheme-side) pi, most-positive-fixnum, most-negative-fixnum
  886. * 7-Nov: removed s7_is_immutable and friends, s7_reverse_in_place.
  887. * removed the s7_pointer arg to s7_gc_on.
  888. * added s7_UNSPECIFIED
  889. * 25-Oct: added name arg to s7_make_procedure_with_setter,
  890. * and s7_scheme arg to new_type print func.
  891. * 1-Oct-08 version 1.0
  892. */