Post Scarcity 0.0.6
A prototype for a post scarcity programming environment
Loading...
Searching...
No Matches
init.c
Go to the documentation of this file.
1/*
2 * init.c
3 *
4 * Start up and initialise the environement - just enough to get working
5 * and (ultimately) hand off to the executive.
6 *
7 *
8 * (c) 2017 Simon Brooke <simon@journeyman.cc>
9 * Licensed under GPL version 2.0, or, at your option, any later version.
10 */
11
12#include <getopt.h>
13#include <locale.h>
14#include <stdbool.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h>
18#include <wchar.h>
19
20/* libcurl, used for io */
21#include <curl/curl.h>
22
23#include "arith/peano.h"
24#include "arith/ratio.h"
25#include "debug.h"
26#include "io/fopen.h"
27#include "io/io.h"
28#include "io/print.h"
29#include "memory/conspage.h"
31#include "memory/hashmap.h"
32#include "memory/stack.h"
33#include "ops/intern.h"
34#include "ops/lispops.h"
35#include "ops/meta.h"
36#include "repl.h"
37#include "time/psse_time.h"
38#include "version.h"
39
40/**
41 * @brief If `pointer` is an exception, display that exception to stderr,
42 * decrement that exception, and return NIL; else return the pointer.
43 *
44 * @param pointer a cons pointer.
45 * @param location_descriptor a description of where the pointer was caught.
46 * @return struct cons_pointer
47 */
49 char *location_descriptor ) {
50 struct cons_pointer result = pointer;
51
52 if ( exceptionp( pointer ) ) {
53 struct cons_space_object *object = &pointer2cell( pointer );
54 result = NIL;
55
56 fprintf( stderr, "ERROR: Exception at %s: ", location_descriptor );
57 URL_FILE *ustderr = file_to_url_file( stderr );
58 fwide( stderr, 1 );
59 print( ustderr, object->payload.exception.payload );
60 free( ustderr );
61
62 dec_ref( pointer );
63 }
64
65 return result;
66}
67
71 c_string_to_lisp_keyword( L"documentation" );
72 }
75 }
78 c_string_to_lisp_keyword( L"primitive" );
79 }
80 if ( nilp( privileged_symbol_nil ) ) {
82 }
83 // we can't make this string when we need it, because memory is then
84 // exhausted!
87 c_string_to_lisp_string( L"Memory exhausted." );
88 }
91 }
94 }
97 }
98}
99
105
106/**
107 * Bind this compiled `executable` function, as a Lisp function, to
108 * this name in the `oblist`.
109 * \todo where a function is not compiled from source, we could cache
110 * the name on the source pointer. Would make stack frames potentially
111 * more readable and aid debugging generally.
112 */
113struct cons_pointer bind_function( wchar_t *name,
114 wchar_t *doc,
115 struct cons_pointer ( *executable )
116 ( struct stack_frame *,
117 struct cons_pointer,
118 struct cons_pointer ) ) {
119 struct cons_pointer n = c_string_to_lisp_symbol( name );
120 struct cons_pointer d = c_string_to_lisp_string( doc );
121
122 struct cons_pointer meta =
127 d ),
128 NIL ) ) );
129
130 struct cons_pointer r =
131 check_exception( deep_bind( n, make_function( meta, executable ) ),
132 "bind_function" );
133
134 dec_ref( n );
135 dec_ref( d );
136
137 return r;
138}
139
140/**
141 * Bind this compiled `executable` function, as a Lisp special form, to
142 * this `name` in the `oblist`.
143 */
144struct cons_pointer bind_special( wchar_t *name,
145 wchar_t *doc,
146 struct cons_pointer ( *executable )
147 ( struct stack_frame *, struct cons_pointer,
148 struct cons_pointer ) ) {
149 struct cons_pointer n = c_string_to_lisp_symbol( name );
150 struct cons_pointer d = c_string_to_lisp_string( doc );
151
152 struct cons_pointer meta =
157 d ),
158 NIL ) ) );
159
160 struct cons_pointer r =
161 check_exception( deep_bind( n, make_special( meta, executable ) ),
162 "bind_special" );
163
164 dec_ref( n );
165 dec_ref( d );
166
167 return r;
168}
169
170/**
171 * Bind this `value` to this `symbol` in the `oblist`.
172 */
173struct cons_pointer
174bind_symbol_value( struct cons_pointer symbol, struct cons_pointer value,
175 bool lock ) {
176 struct cons_pointer r = check_exception( deep_bind( symbol, value ),
177 "bind_symbol_value" );
178
179 if ( lock && !exceptionp( r ) ) {
180 struct cons_space_object *cell = &pointer2cell( r );
181
182 cell->count = UINT32_MAX;
183 }
184
185 return r;
186}
187
188/**
189 * Bind this `value` to this `name` in the `oblist`.
190 */
191struct cons_pointer bind_value( wchar_t *name, struct cons_pointer value,
192 bool lock ) {
193 struct cons_pointer p = c_string_to_lisp_symbol( name );
194
195 struct cons_pointer r = bind_symbol_value( p, value, lock );
196
197 dec_ref( p );
198
199 return r;
200}
201
203 fwprintf( stdout, L"Post-Scarcity Software Environment version %s\n\n",
204 VERSION );
205}
206
207/**
208 * Print command line options to this `stream`.
209 *
210 * @stream the stream to print to.
211 */
212void print_options( FILE *stream ) {
213 fwprintf( stream, L"Expected options are:\n" );
214 fwprintf( stream,
215 L"\t-d\tDump memory to standard out at end of run (copious!);\n" );
216 fwprintf( stream, L"\t-h\tPrint this message and exit;\n" );
217 fwprintf( stream, L"\t-p\tShow a prompt (default is no prompt);\n" );
218 fwprintf( stream,
219 L"\t-s LIMIT\n\t\tSet the maximum stack depth to this LIMIT (int)\n" );
220#ifdef DEBUG
221 fwprintf( stream,
222 L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n" );
223 fwprintf( stream, L"\t\tWhere bits are interpreted as follows:\n" );
224 fwprintf( stream, L"\t\t1\tALLOC;\n" );
225 fwprintf( stream, L"\t\t2\tARITH;\n" );
226 fwprintf( stream, L"\t\t4\tBIND;\n" );
227 fwprintf( stream, L"\t\t8\tBOOTSTRAP;\n" );
228 fwprintf( stream, L"\t\t16\tEVAL;\n" );
229 fwprintf( stream, L"\t\t32\tINPUT/OUTPUT;\n" );
230 fwprintf( stream, L"\t\t64\tLAMBDA;\n" );
231 fwprintf( stream, L"\t\t128\tREPL;\n" );
232 fwprintf( stream, L"\t\t256\tSTACK;\n" );
233 fwprintf( stream, L"\t\t512\tEQUAL.\n" );
234#endif
235}
236
237/**
238 * main entry point; parse command line arguments, initialise the environment,
239 * and enter the read-eval-print loop.
240 */
241int main( int argc, char *argv[] ) {
242 int option;
243 bool dump_at_end = false;
244 bool show_prompt = false;
245 char *infilename = NULL;
246
247 setlocale( LC_ALL, "" );
248 if ( io_init( ) != 0 ) {
249 fputs( "Failed to initialise I/O subsystem\n", stderr );
250 exit( 1 );
251 }
252
253 while ( ( option = getopt( argc, argv, "dhi:ps:v:" ) ) != -1 ) {
254 switch ( option ) {
255 case 'd':
256 dump_at_end = true;
257 break;
258 case 'h':
259 print_banner( );
260 print_options( stdout );
261 exit( 0 );
262 break;
263 case 'i':
264 infilename = optarg;
265 break;
266 case 'p':
267 show_prompt = true;
268 break;
269 case 's':
270 stack_limit = atoi( optarg );
271 break;
272 case 'v':
273 verbosity = atoi( optarg );
274 break;
275 default:
276 fwprintf( stderr, L"Unexpected option %c\n", option );
277 print_options( stderr );
278 exit( 1 );
279 break;
280 }
281 }
282
284
286
287
288 if ( show_prompt ) {
289 print_banner( );
290 }
291
292 debug_print( L"About to initialise oblist\n", DEBUG_BOOTSTRAP );
293
294 oblist = make_hashmap( 32, NIL, TRUE );
295
296 debug_print( L"About to bind\n", DEBUG_BOOTSTRAP );
297
298 /*
299 * privileged variables (keywords)
300 */
302 bind_value( L"t", TRUE, true );
305
306 /*
307 * standard input, output, error and sink streams
308 * attempt to set wide character acceptance on all streams
309 */
310 URL_FILE *sink = url_fopen( "/dev/null", "w" );
311 fwide( stdin, 1 );
312 fwide( stdout, 1 );
313 fwide( stderr, 1 );
314 fwide( sink->handle.file, 1 );
315
316 FILE *infile = infilename == NULL ? stdin : fopen( infilename, "r" );
317
318
319 lisp_io_in =
324 ( L"url" ),
326 ( L"system:standard input" ) ),
327 NIL ) ), false );
333 ( L"url" ),
335 ( L"system:standard output" ) ),
336 NIL ) ), false );
337 bind_value( L"*log*",
341 ( L"url" ),
343 ( L"system:standard log" ) ),
344 NIL ) ), false );
345 bind_value( L"*sink*",
346 make_write_stream( sink,
349 ( L"url" ),
351 ( L"system:standard sink" ) ),
352 NIL ) ), false );
353 /*
354 * the default prompt
355 */
356 prompt_name = bind_value( L"*prompt*",
357 show_prompt ? c_string_to_lisp_symbol( L":: " ) :
358 NIL, false );
359 /*
360 * primitive function operations
361 */
362 /* TODO: docstrings should be moved to a header file, or even to an at-run-time resolution system.
363 * HTTP from an address at journeyman? */
364 bind_function( L"absolute",
365 L"`(absolute arg)`: If `arg` is a number, return the absolute value of that number, else `nil`.",
366 &lisp_absolute );
367 bind_function( L"add",
368 L"`(+ args...)`: If `args` are all numbers, return the sum of those numbers.",
369 &lisp_add );
370 bind_function( L"and",
371 L"`(and args...)`: Return a logical `and` of all the arguments and return `t` only if all are truthy, else `nil`.",
372 &lisp_and );
373 bind_function( L"append",
374 L"`(append args...)`: If args are all collections, return the concatenation of those collections.",
375 &lisp_append );
376 bind_function( L"apply",
377 L"`(apply f args)`: If `f` is usable as a function, and `args` is a collection, apply `f` to `args` and return the value.",
378 &lisp_apply );
379 bind_function( L"assoc",
380 L"`(assoc key store)`: Return the value associated with this `key` in this `store`.",
381 &lisp_assoc );
382 bind_function( L"car",
383 L"`(car arg)`: If `arg` is a sequence, return the item which is the head of that sequence.",
384 &lisp_car );
385 bind_function( L"cdr",
386 L"`(cdr arg)`: If `arg` is a sequence, return the remainder of that sequence with the first item removed.",
387 &lisp_cdr );
388 bind_function( L"close",
389 L"`(close stream)`: If `stream` is a stream, close that stream.",
390 &lisp_close );
391 bind_function( L"cons",
392 L"`(cons a b)`: Return a cons cell whose `car` is `a` and whose `cdr` is `b`.",
393 &lisp_cons );
394 bind_function( L"count",
395 L"`(count s)`: Return the number of items in the sequence `s`.",
396 &lisp_count );
397 bind_function( L"divide",
398 L"`(/ a b)`: If `a` and `b` are both numbers, return the numeric result of dividing `a` by `b`.",
399 &lisp_divide );
400 bind_function( L"eq?",
401 L"`(eq? args...)`: Return `t` if all args are the exact same object, else `nil`.",
402 &lisp_eq );
403 bind_function( L"equal?",
404 L"`(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`.",
405 &lisp_equal );
406 bind_function( L"eval", L"", &lisp_eval );
407 bind_function( L"exception",
408 L"`(exception message)`: Return (throw) an exception with this `message`.",
410 bind_function( L"get-hash",
411 L"`(get-hash arg)`: returns the natural number hash value of `arg`.",
412 &lisp_get_hash );
413 bind_function( L"hashmap",
414 L"`(hashmap n-buckets hashfn store acl)`: Return a new hashmap, with `n-buckets` buckets and this `hashfn`, containing the content of this `store`.",
416 bind_function( L"inspect",
417 L"`(inspect object ouput-stream)`: Print details of this `object` to this `output-stream` or `*out*`.",
418 &lisp_inspect );
419 bind_function( L"interned?",
420 L"`(interned? key store)`: Return `t` if the symbol or keyword `key` is bound in this `store`, else `nil`.",
422 bind_function( L"keys",
423 L"`(keys store)`: Return a list of all keys in this `store`.",
424 &lisp_keys );
425 bind_function( L"list",
426 L"`(list args...)`: Return a list of these `args`.",
427 &lisp_list );
428 bind_function( L"mapcar",
429 L"`(mapcar function sequence)`: Apply `function` to each element of `sequence` in turn, and return a sequence of the results.",
430 &lisp_mapcar );
431 bind_function( L"meta",
432 L"`(meta symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`.",
433 &lisp_metadata );
434 bind_function( L"metadata",
435 L"`(metadata symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`.",
436 &lisp_metadata );
437 bind_function( L"multiply",
438 L"`(* args...)` Multiply these `args`, all of which should be numbers.",
439 &lisp_multiply );
440 bind_function( L"negative?",
441 L"`(negative? n)`: Return `t` if `n` is a negative number, else `nil`.",
443 bind_function( L"not",
444 L"`(not arg)`: Return`t` only if `arg` is `nil`, else `nil`.",
445 &lisp_not );
446 bind_function( L"oblist",
447 L"`(oblist)`: Return the current symbol bindings, as a map.",
448 &lisp_oblist );
449 bind_function( L"open",
450 L"`(open url write?)`: Open a stream to this `url`. If `write?` is present and is non-nil, open it for writing, else reading.",
451 &lisp_open );
452 bind_function( L"or",
453 L"`(or args...)`: Return a logical `or` of all the arguments and return `t` if any is truthy, else `nil`.",
454 &lisp_or );
455 bind_function( L"print",
456 L"`(print object stream)`: Print `object` to `stream`, if specified, else to `*out*`.",
457 &lisp_print );
458 bind_function( L"println",
459 L"`(println stream)`: Print a new line character to `stream`, if specified, else to `*out*`.",
460 &lisp_println );
461 bind_function( L"put!", L"", lisp_hashmap_put );
462 bind_function( L"put-all!",
463 L"`(put-all! dest source)`: If `dest` is a namespace and is writable, copies all key-value pairs from `source` into `dest`.",
465 bind_function( L"ratio->real",
466 L"`(ratio->real r)`: If `r` is a rational number, return the real number equivalent.",
468 bind_function( L"read",
469 L"`(read stream)`: read one complete lisp form and return it. If `stream` is specified and is a read stream, then read from that stream, else the stream which is the value of `*in*` in the environment.",
470 &lisp_read );
471 bind_function( L"read-char",
472 L"`(read-char stream)`: Return the next character. If `stream` is specified and is a read stream, then read from that stream, else the stream which is the value of `*in*` in the environment.",
474 bind_function( L"repl",
475 L"`(repl prompt input output)`: Starts a new read-eval-print-loop. All arguments are optional.",
476 &lisp_repl );
477 bind_function( L"reverse",
478 L"`(reverse sequence)` Returns a sequence of the top level elements of this `sequence`, which may be a list or a string, in the reverse order.",
479 &lisp_reverse );
480 bind_function( L"set", L"", &lisp_set );
481 bind_function( L"slurp",
482 L"`(slurp read-stream)` Read all the characters from `read-stream` to the end of stream, and return them as a string.",
483 &lisp_slurp );
484 bind_function( L"source",
485 L"`(source object)`: If `object` is an interpreted function or interpreted special form, returns the source code; else nil.",
486 &lisp_source );
487 bind_function( L"subtract",
488 L"`(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers.",
489 &lisp_subtract );
490 bind_function( L"throw",
491 L"`(throw message cause)`: Throw an exception with this `message`, and, if specified, this `cause` (which is expected to be an exception but need not be).",
493 bind_function( L"time",
494 L"`(time arg)`: Return a time object. If an `arg` is supplied, it should be an integer which will be interpreted as a number of microseconds since the big bang, which is assumed to have happened 441,806,400,000,000,000 seconds before the UNIX epoch.",
495 &lisp_time );
496 bind_function( L"type",
497 L"`(type object)`: returns the type of the specified `object`. Currently (0.0.6) the type is returned as a four character string; this may change.",
498 &lisp_type );
499 bind_function( L"+",
500 L"`(+ args...)`: If `args` are all numbers, return the sum of those numbers.",
501 &lisp_add );
502 bind_function( L"*",
503 L"`(* args...)` Multiply these `args`, all of which should be numbers.",
504 &lisp_multiply );
505 bind_function( L"-",
506 L"`(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers.",
507 &lisp_subtract );
508 bind_function( L"/",
509 L"`(/ a b)`: If `a` and `b` are both numbers, return the numeric result of dividing `a` by `b`.",
510 &lisp_divide );
511 bind_function( L"=",
512 L"`(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`.",
513 &lisp_equal );
514 /*
515 * primitive special forms
516 */
517 bind_special( L"cond",
518 L"`(cond clauses...)`: Conditional evaluation, `clauses` is a sequence of lists of forms such that if evaluating the first form in any clause returns non-`nil`, the subsequent forms in that clause will be evaluated and the value of the last returned; but any subsequent clauses will not be evaluated.",
519 &lisp_cond );
520 bind_special( L"lambda",
521 L"`(lambda arg-list forms...)`: Construct an interpretable λ funtion.",
522 &lisp_lambda );
523 bind_special( L"\u03bb", L"", &lisp_lambda ); // λ
524 bind_special( L"let",
525 L"`(let bindings forms)`: Bind these `bindings`, which should be specified as an association list, into the local environment and evaluate these forms sequentially in that context, returning the value of the last.",
526 &lisp_let );
527 bind_special( L"nlambda",
528 L"`(nlamda arg-list forms...)`: Construct an interpretable special form. When the form is interpreted, arguments specified in the `arg-list` will not be evaluated.",
529 &lisp_nlambda );
530 bind_special( L"n\u03bb", L"`(nlamda arg-list forms...)`: Construct an interpretable special form. When the form is interpreted, arguments specified in the `arg-list` will not be evaluated.", &lisp_nlambda ); // nλ
531 bind_special( L"progn",
532 L"`(progn forms...)` Evaluate `forms` sequentially, and return the value of the last.",
533 &lisp_progn );
534 bind_special( L"quote",
535 L"`(quote form)`: Returns `form`, unevaluated. More idiomatically expressed `'form`, where the quote mark is a reader macro which is expanded to `(quote form)`.",
536 &lisp_quote );
537 bind_special( L"set!",
538 L"`(set! symbol value namespace)`: Binds `symbol` in `namespace` to the value of `value`, altering the namespace in so doing, and returns `value`. If `namespace` is not specified, it defaults to the default namespace.",
540 bind_special( L"try",
541 L"`(try forms... (catch catch-forms...))`: Evaluate `forms` sequentially, and return the value of the last. If an exception is thrown in any, evaluate `catch-forms` sequentially in an environment in which `*exception*` is bound to that exception, and return the value of the last of these.",
542 &lisp_try );
543 debug_print( L"Initialised oblist\n", DEBUG_BOOTSTRAP );
545
546 repl( show_prompt );
547
549
550 debug_print( L"Freeing oblist\n", DEBUG_BOOTSTRAP );
551 while ( ( pointer2cell( oblist ) ).count > 0 ) {
552 fprintf( stderr, "Dangling refs on oblist: %d\n",
553 ( pointer2cell( oblist ) ).count );
554 dec_ref( oblist );
555 }
556
558
559 if ( dump_at_end ) {
560 dump_pages( file_to_url_file( stdout ) );
561 }
562
564 curl_global_cleanup( );
565 return ( 0 );
566}
void dump_pages(URL_FILE *output)
dump the allocated pages to this output stream.
Definition conspage.c:134
struct cons_pointer privileged_string_memory_exhausted
The exception message printed when the world blows up, initialised in maybe_bind_init_symbols() in in...
Definition conspage.c:52
void summarise_allocation()
Definition conspage.c:285
void initialise_cons_pages()
initialise the cons page system; to be called exactly once during startup.
Definition conspage.c:271
struct cons_pointer make_special(struct cons_pointer meta, struct cons_pointer(*executable)(struct stack_frame *frame, struct cons_pointer, struct cons_pointer env))
Construct a cell which points to an executable Lisp special form.
struct cons_pointer privileged_keyword_primitive
keywords used in documentation: :primitive.
struct cons_pointer c_string_to_lisp_keyword(wchar_t *symbol)
Return a lisp keyword representation of this wide character string.
struct cons_pointer privileged_keyword_cause
Keywords used when constructing exceptions: :payload.
struct cons_pointer make_function(struct cons_pointer meta, struct cons_pointer(*executable)(struct stack_frame *, struct cons_pointer, struct cons_pointer))
Construct a cell which points to an executable Lisp function.
struct cons_pointer privileged_keyword_name
keywords used in documentation: :name.
struct cons_pointer privileged_keyword_documentation
keywords used in documentation: :documentation.
struct cons_pointer make_write_stream(URL_FILE *output, struct cons_pointer metadata)
Construct a cell which points to a stream open for writing.
struct cons_pointer c_string_to_lisp_string(wchar_t *string)
Return a lisp string representation of this wide character string.
struct cons_pointer make_read_stream(URL_FILE *input, struct cons_pointer metadata)
Construct a cell which points to a stream open for reading.
struct cons_pointer privileged_keyword_payload
Keywords used when constructing exceptions: :payload.
struct cons_pointer c_string_to_lisp_symbol(wchar_t *symbol)
Return a lisp symbol representation of this wide character string.
struct cons_pointer dec_ref(struct cons_pointer pointer)
Decrement the reference count of the object at this cons pointer.
struct cons_pointer privileged_keyword_location
Keywords used when constructing exceptions: :location.
struct cons_pointer make_cons(struct cons_pointer car, struct cons_pointer cdr)
Construct a cons cell from this pair of pointers.
#define exceptionp(conspoint)
true if conspoint points to an exception, else false
union cons_space_object::@3 payload
#define NIL
a cons pointer which points to the special NIL cell
#define nilp(conspoint)
true if conspoint points to the special cell NIL, else false (there should only be one of these so it...
uint32_t count
the count of the number of references to this cell
#define TRUE
a cons pointer which points to the special T cell
struct cons_pointer c_string_to_lisp_symbol(wchar_t *symbol)
Return a lisp symbol representation of this wide character string.
struct cons_pointer dec_ref(struct cons_pointer pointer)
Decrement the reference count of the object at this cons pointer.
#define pointer2cell(pointer)
given a cons_pointer as argument, return the cell.
An indirect pointer to a cons cell.
an object in cons space.
A stack frame.
int verbosity
the controlling flags for debug_print; set in init.c, q.v.
Definition debug.c:33
void debug_dump_object(struct cons_pointer pointer, int level)
Like dump_object, q.v., but protected by the verbosity mechanism.
Definition debug.c:155
void debug_print(wchar_t *message, int level)
print this debug message to stderr, if verbosity matches level.
Definition debug.c:60
#define DEBUG_BOOTSTRAP
Print messages debugging bootstrapping and teardown.
Definition debug.h:45
URL_FILE * url_fopen(const char *url, const char *operation)
Definition fopen.c:202
union fcurl_data::@0 handle
struct cons_pointer lisp_hashmap_put_all(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Lisp function expecting two arguments, a hashmap and an assoc list.
Definition hashmap.c:126
struct cons_pointer lisp_get_hash(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
A lisp function signature conforming wrapper around get_hash, q.v.
Definition hashmap.c:25
struct cons_pointer lisp_hashmap_put(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Expects frame->arg[1] to be a hashmap or namespace; frame->arg[2] to be a string-like-thing (perhaps ...
Definition hashmap.c:106
struct cons_pointer lisp_make_hashmap(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Lisp funtion of up to four args (all optional), where.
Definition hashmap.c:39
struct cons_pointer check_exception(struct cons_pointer pointer, char *location_descriptor)
If pointer is an exception, display that exception to stderr, decrement that exception,...
Definition init.c:48
int main(int argc, char *argv[])
main entry point; parse command line arguments, initialise the environment, and enter the read-eval-p...
Definition init.c:241
void maybe_bind_init_symbols()
Definition init.c:68
struct cons_pointer bind_special(wchar_t *name, wchar_t *doc, struct cons_pointer(*executable)(struct stack_frame *, struct cons_pointer, struct cons_pointer))
Bind this compiled executable function, as a Lisp special form, to this name in the oblist.
Definition init.c:144
void print_options(FILE *stream)
Print command line options to this stream.
Definition init.c:212
struct cons_pointer bind_function(wchar_t *name, wchar_t *doc, struct cons_pointer(*executable)(struct stack_frame *, struct cons_pointer, struct cons_pointer))
Bind this compiled executable function, as a Lisp function, to this name in the oblist.
Definition init.c:113
void free_init_symbols()
Definition init.c:100
void print_banner()
Definition init.c:202
struct cons_pointer bind_symbol_value(struct cons_pointer symbol, struct cons_pointer value, bool lock)
Bind this value to this symbol in the oblist.
Definition init.c:174
struct cons_pointer bind_value(wchar_t *name, struct cons_pointer value, bool lock)
Bind this value to this name in the oblist.
Definition init.c:191
struct cons_pointer privileged_symbol_nil
the symbol NIL, which is special!
Definition intern.c:55
struct cons_pointer make_hashmap(uint32_t n_buckets, struct cons_pointer hash_fn, struct cons_pointer write_acl)
Make a hashmap with this number of buckets, using this hash_fn.
Definition intern.c:138
struct cons_pointer oblist
The global object list/or, to put it differently, the root namespace.
Definition intern.c:49
struct cons_pointer deep_bind(struct cons_pointer key, struct cons_pointer value)
Binds this key to this value in the global oblist, and returns the key.
Definition intern.c:545
int io_init()
Initialise the I/O subsystem.
Definition io.c:69
struct cons_pointer lisp_io_in
bound to the Lisp string representing C_IO_IN in initialisation.
Definition io.c:51
struct cons_pointer lisp_open(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return a stream open on the URL indicated by the first argument; if a second argument is pr...
Definition io.c:437
struct cons_pointer lisp_io_out
bound to the Lisp string representing C_IO_OUT in initialisation.
Definition io.c:55
struct cons_pointer lisp_slurp(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return a string representing all characters from the stream indicated by arg 0; further arg...
Definition io.c:533
URL_FILE * file_to_url_file(FILE *f)
given this file handle f, return a new url_file handle wrapping it.
Definition io.c:134
struct cons_pointer lisp_close(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function, sort-of: close the file indicated by my first arg, and return nil.
Definition io.c:254
struct cons_pointer lisp_read_char(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return the next character from the stream indicated by arg 0; further arguments are ignored...
Definition io.c:504
#define C_IO_IN
Definition io.h:20
#define C_IO_OUT
Definition io.h:21
struct cons_pointer lisp_nlambda(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Construct an interpretable special form.
Definition lispops.c:244
struct cons_pointer lisp_assoc(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; look up the value of a key in a store.
Definition lispops.c:886
struct cons_pointer lisp_source(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function.
Definition lispops.c:1574
struct cons_pointer lisp_mapcar(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Definition lispops.c:1669
struct cons_pointer lisp_cons(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns a cell constructed from a and b.
Definition lispops.c:751
struct cons_pointer lisp_eq(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; are these two objects the same object? Shallow, cheap equality.
Definition lispops.c:958
struct cons_pointer lisp_read(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; read one complete lisp form and return it.
Definition lispops.c:1049
struct cons_pointer lisp_exception(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; create an exception.
Definition lispops.c:1421
struct cons_pointer lisp_car(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns the first item (head) of a sequence.
Definition lispops.c:784
struct cons_pointer lisp_count(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return the number of top level forms in the object which is the first (and only) argument,...
Definition lispops.c:1030
struct cons_pointer lisp_let(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form: evaluate a series of forms in an environment in which these bindings are bound.
Definition lispops.c:1738
struct cons_pointer lisp_inspect(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: dump/inspect one complete lisp expression and return NIL.
Definition lispops.c:1148
struct cons_pointer lisp_or(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Boolean or of arbitrarily many arguments.
Definition lispops.c:1815
struct cons_pointer lisp_try(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
OK, the idea here (and I know this is less than perfect) is that the basic try special form in PSSE t...
Definition lispops.c:161
struct cons_pointer lisp_apply(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; apply the function which is the result of evaluating the first argument to the list of valu...
Definition lispops.c:611
struct cons_pointer lisp_eval(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; evaluate the expression which is the first argument in the frame; further arguments are ign...
Definition lispops.c:550
struct cons_pointer lisp_type(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: get the Lisp type of the single argument.
Definition lispops.c:1185
struct cons_pointer lisp_internedp(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
(interned? key store): Return t if the symbol or keyword key is bound in this store,...
Definition lispops.c:901
struct cons_pointer lisp_progn(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; evaluate the expressions which are listed in my arguments sequentially and return the v...
Definition lispops.c:1226
struct cons_pointer lisp_keys(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Definition lispops.c:942
struct cons_pointer lisp_equal(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; are these two arguments identical? Deep, expensive equality.
Definition lispops.c:983
struct cons_pointer lisp_repl(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: the read/eval/print loop.
Definition lispops.c:1442
struct cons_pointer lisp_set_shriek(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; binds symbol in the namespace to value of value, altering the namespace in so doing,...
Definition lispops.c:702
struct cons_pointer lisp_append(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
should really be overwritten with a version in Lisp, since this is much easier to write in Lisp
Definition lispops.c:1657
struct cons_pointer lisp_not(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Logical inverese: if the first argument is nil, return t, else nil.
Definition lispops.c:1836
struct cons_pointer lisp_quote(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form; returns its argument (strictly first argument - only one is expected but this isn't at ...
Definition lispops.c:641
struct cons_pointer lisp_set(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; binds the value of name in the namespace to value of value, altering the namespace in so do...
Definition lispops.c:663
struct cons_pointer lisp_lambda(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Construct an interpretable function.
Definition lispops.c:227
struct cons_pointer lisp_cdr(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; returns the remainder of a sequence when the head is removed.
Definition lispops.c:829
struct cons_pointer lisp_list(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
construct and return a list of arbitrarily many arguments.
Definition lispops.c:1718
struct cons_pointer lisp_oblist(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Return the object list (root namespace).
Definition lispops.c:190
struct cons_pointer lisp_cond(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form: conditional.
Definition lispops.c:1308
struct cons_pointer lisp_reverse(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; reverse the order of members in s sequence.
Definition lispops.c:1128
struct cons_pointer prompt_name
the name of the symbol to which the prompt is bound;
Definition lispops.c:47
struct cons_pointer lisp_and(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Boolean and of arbitrarily many arguments.
Definition lispops.c:1794
struct cons_pointer lisp_metadata(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: get metadata describing my first argument.
Definition meta.c:20
struct cons_pointer lisp_absolute(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: calculate the absolute value of a number.
Definition peano.c:248
struct cons_pointer lisp_ratio_to_real(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: return a real (approcimately) equal in value to the ratio which is the first argument.
Definition peano.c:811
struct cons_pointer lisp_is_negative(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function: is this number negative?
Definition peano.c:580
struct cons_pointer lisp_subtract(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Subtract one number from another.
Definition peano.c:694
struct cons_pointer lisp_divide(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Divide one number by another.
Definition peano.c:709
struct cons_pointer lisp_multiply(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Multiply an indefinite number of numbers together.
Definition peano.c:502
struct cons_pointer lisp_add(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Add an indefinite number of numbers together.
Definition peano.c:360
struct cons_pointer lisp_println(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
(prinln out-stream): Print a new line character to out-stream, if it is specified and is an output st...
Definition print.c:343
struct cons_pointer print(URL_FILE *output, struct cons_pointer pointer)
Print the cons-space object indicated by pointer to the stream indicated by output.
Definition print.c:156
struct cons_pointer lisp_print(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; print one complete lisp expression and return NIL.
Definition print.c:295
struct cons_pointer lisp_time(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function; return a time representation of the first argument in the frame; further arguments are igno...
Definition psse_time.c:86
void repl()
The read/eval/print loop.
Definition repl.c:33
uint32_t stack_limit
If non-zero, maximum depth of stack.
Definition stack.c:33
#define VERSION
version.h
Definition version.h:11