Post Scarcity
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 = NIL;
51
52 struct cons_space_object *object = &pointer2cell( pointer );
53
54 if ( exceptionp( pointer ) ) {
55 fprintf( stderr, "ERROR: Exception at %s: ", location_descriptor );
56 URL_FILE *ustderr = file_to_url_file( stderr );
57 fwide( stderr, 1 );
58 print( ustderr, object->payload.exception.payload );
59 free( ustderr );
60
61 dec_ref( pointer );
62 } else {
63 result = pointer;
64 }
65
66 return result;
67}
68
72
76 c_string_to_lisp_keyword( L"documentation" );
77 }
78 if ( nilp( init_name_symbol ) ) {
80 }
81 if ( nilp( init_primitive_symbol ) ) {
83 }
84 if ( nilp( privileged_symbol_nil ) ) {
86 }
88 // we can't make this string when we need it, because memory is then
89 // exhausted!
91 c_string_to_lisp_string( L"Memory exhausted." );
92 }
93}
94
100
101/**
102 * Bind this compiled `executable` function, as a Lisp function, to
103 * this name in the `oblist`.
104 * \todo where a function is not compiled from source, we could cache
105 * the name on the source pointer. Would make stack frames potentially
106 * more readable and aid debugging generally.
107 */
108struct cons_pointer bind_function( wchar_t *name,
109 wchar_t *doc,
110 struct cons_pointer ( *executable )
111 ( struct stack_frame *,
112 struct cons_pointer,
113 struct cons_pointer ) ) {
114 struct cons_pointer n = c_string_to_lisp_symbol( name );
115 struct cons_pointer d = c_string_to_lisp_string( doc );
116
117 struct cons_pointer meta =
122 NIL ) ) );
123
124 struct cons_pointer r =
125 check_exception( deep_bind( n, make_function( meta, executable ) ),
126 "bind_function" );
127
128 dec_ref( n );
129 dec_ref( d );
130
131 return r;
132}
133
134/**
135 * Bind this compiled `executable` function, as a Lisp special form, to
136 * this `name` in the `oblist`.
137 */
138struct cons_pointer bind_special( wchar_t *name,
139 wchar_t *doc,
140 struct cons_pointer ( *executable )
141 ( struct stack_frame *, struct cons_pointer,
142 struct cons_pointer ) ) {
143 struct cons_pointer n = c_string_to_lisp_symbol( name );
144 struct cons_pointer d = c_string_to_lisp_string( doc );
145
146 struct cons_pointer meta =
151 NIL ) ) );
152
153 struct cons_pointer r =
154 check_exception( deep_bind( n, make_special( meta, executable ) ),
155 "bind_special" );
156
157 dec_ref( n );
158 dec_ref( d );
159
160 return r;
161}
162
163/**
164 * Bind this `value` to this `symbol` in the `oblist`.
165 */
166struct cons_pointer
167bind_symbol_value( struct cons_pointer symbol, struct cons_pointer value,
168 bool lock ) {
169 struct cons_pointer r = check_exception( deep_bind( symbol, value ),
170 "bind_symbol_value" );
171
172 if ( lock && !exceptionp( r ) ) {
173 struct cons_space_object *cell = &pointer2cell( r );
174
175 cell->count = UINT32_MAX;
176 }
177
178 return r;
179}
180
181/**
182 * Bind this `value` to this `name` in the `oblist`.
183 */
184struct cons_pointer bind_value( wchar_t *name, struct cons_pointer value,
185 bool lock ) {
186 struct cons_pointer p = c_string_to_lisp_symbol( name );
187
188 struct cons_pointer r = bind_symbol_value( p, value, lock );
189
190 dec_ref( p );
191
192 return r;
193}
194
196 fwprintf( stdout, L"Post-Scarcity Software Environment version %s\n\n",
197 VERSION );
198}
199
200/**
201 * Print command line options to this `stream`.
202 *
203 * @stream the stream to print to.
204 */
205void print_options( FILE *stream ) {
206 fwprintf( stream, L"Expected options are:\n" );
207 fwprintf( stream,
208 L"\t-d\tDump memory to standard out at end of run (copious!);\n" );
209 fwprintf( stream, L"\t-h\tPrint this message and exit;\n" );
210 fwprintf( stream, L"\t-p\tShow a prompt (default is no prompt);\n" );
211#ifdef DEBUG
212 fwprintf( stream,
213 L"\t-v LEVEL\n\t\tSet verbosity to the specified level (0...512)\n" );
214 fwprintf( stream, L"\t\tWhere bits are interpreted as follows:\n" );
215 fwprintf( stream, L"\t\t1\tALLOC;\n" );
216 fwprintf( stream, L"\t\t2\tARITH;\n" );
217 fwprintf( stream, L"\t\t4\tBIND;\n" );
218 fwprintf( stream, L"\t\t8\tBOOTSTRAP;\n" );
219 fwprintf( stream, L"\t\t16\tEVAL;\n" );
220 fwprintf( stream, L"\t\t32\tINPUT/OUTPUT;\n" );
221 fwprintf( stream, L"\t\t64\tLAMBDA;\n" );
222 fwprintf( stream, L"\t\t128\tREPL;\n" );
223 fwprintf( stream, L"\t\t256\tSTACK.\n" );
224#endif
225}
226
227/**
228 * main entry point; parse command line arguments, initialise the environment,
229 * and enter the read-eval-print loop.
230 */
231int main( int argc, char *argv[] ) {
232 int option;
233 bool dump_at_end = false;
234 bool show_prompt = false;
235 char *infilename = NULL;
236
237 setlocale( LC_ALL, "" );
238 if ( io_init( ) != 0 ) {
239 fputs( "Failed to initialise I/O subsystem\n", stderr );
240 exit( 1 );
241 }
242
243 while ( ( option = getopt( argc, argv, "phdv:i:" ) ) != -1 ) {
244 switch ( option ) {
245 case 'd':
246 dump_at_end = true;
247 break;
248 case 'h':
249 print_banner( );
250 print_options( stdout );
251 exit( 0 );
252 break;
253 case 'i':
254 infilename = optarg;
255 break;
256 case 'p':
257 show_prompt = true;
258 break;
259 case 'v':
260 verbosity = atoi( optarg );
261 break;
262 default:
263 fwprintf( stderr, L"Unexpected option %c\n", option );
264 print_options( stderr );
265 exit( 1 );
266 break;
267 }
268 }
269
271
273
274
275 if ( show_prompt ) {
276 print_banner( );
277 }
278
279 debug_print( L"About to initialise oblist\n", DEBUG_BOOTSTRAP );
280
281 oblist = make_hashmap( 32, NIL, TRUE );
282
283 debug_print( L"About to bind\n", DEBUG_BOOTSTRAP );
284
285 /*
286 * privileged variables (keywords)
287 */
289 bind_value( L"t", TRUE, true );
290
291 /*
292 * standard input, output, error and sink streams
293 * attempt to set wide character acceptance on all streams
294 */
295 URL_FILE *sink = url_fopen( "/dev/null", "w" );
296 fwide( stdin, 1 );
297 fwide( stdout, 1 );
298 fwide( stderr, 1 );
299 fwide( sink->handle.file, 1 );
300
301 FILE *infile = infilename == NULL ? stdin : fopen( infilename, "r" );
302
303
304 lisp_io_in =
309 ( L"url" ),
311 ( L"system:standard input" ) ),
312 NIL ) ), false );
318 ( L"url" ),
320 ( L"system:standard output]" ) ),
321 NIL ) ), false );
322 bind_value( L"*log*",
326 ( L"url" ),
328 ( L"system:standard log" ) ),
329 NIL ) ), false );
330 bind_value( L"*sink*",
331 make_write_stream( sink,
334 ( L"url" ),
336 ( L"system:standard sink" ) ),
337 NIL ) ), false );
338 /*
339 * the default prompt
340 */
341 prompt_name = bind_value( L"*prompt*",
342 show_prompt ? c_string_to_lisp_symbol( L":: " ) :
343 NIL, false );
344 /*
345 * primitive function operations
346 */
347 /* TODO: docstrings should be moved to a header file, or even to an at-run-time resolution system.
348 * HTTP from an address at journeyman? */
349 bind_function( L"absolute",
350 L"`(absolute arg)`: If `arg` is a number, return the absolute value of that number, else `nil`.",
351 &lisp_absolute );
352 bind_function( L"add",
353 L"`(+ args...)`: If `args` are all numbers, return the sum of those numbers.",
354 &lisp_add );
355 bind_function( L"and",
356 L"`(and args...)`: Return a logical `and` of all the arguments and return `t` only if all are truthy, else `nil`.",
357 &lisp_and );
358 bind_function( L"append",
359 L"`(append args...)`: If args are all collections, return the concatenation of those collections.",
360 &lisp_append );
361 bind_function( L"apply",
362 L"`(apply f args)`: If `f` is usable as a function, and `args` is a collection, apply `f` to `args` and return the value.",
363 &lisp_apply );
364 bind_function( L"assoc",
365 L"`(assoc key store)`: Return the value associated with this `key` in this `store`.",
366 &lisp_assoc );
367 bind_function( L"car",
368 L"`(car arg)`: If `arg` is a sequence, return the item which is the head of that sequence.",
369 &lisp_car );
370 bind_function( L"cdr",
371 L"`(cdr arg)`: If `arg` is a sequence, return the remainder of that sequence with the first item removed.",
372 &lisp_cdr );
373 bind_function( L"close",
374 L"`(close stream)`: If `stream` is a stream, close that stream.",
375 &lisp_close );
376 bind_function( L"cons",
377 L"`(cons a b)`: Return a cons cell whose `car` is `a` and whose `cdr` is `b`.",
378 &lisp_cons );
379 bind_function( L"count",
380 L"`(count s)`: Return the number of items in the sequence `s`.",
381 &lisp_count );
382 bind_function( L"divide",
383 L"`(/ a b)`: If `a` and `b` are both numbers, return the numeric result of dividing `a` by `b`.",
384 &lisp_divide );
385 bind_function( L"eq?",
386 L"`(eq? args...)`: Return `t` if all args are the exact same object, else `nil`.",
387 &lisp_eq );
388 bind_function( L"equal?",
389 L"`(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`.",
390 &lisp_equal );
391 bind_function( L"eval", L"", &lisp_eval );
392 bind_function( L"exception",
393 L"`(exception message)`: Return (throw) an exception with this `message`.",
395 bind_function( L"get-hash",
396 L"`(get-hash arg)`: returns the natural number hash value of `arg`.",
397 &lisp_get_hash );
398 bind_function( L"hashmap",
399 L"`(hashmap n-buckets hashfn store acl)`: Return a new hashmap, with `n-buckets` buckets and this `hashfn`, containing the content of this `store`.",
401 bind_function( L"inspect",
402 L"`(inspect object ouput-stream)`: Print details of this `object` to this `output-stream` or `*out*`.",
403 &lisp_inspect );
404 bind_function( L"keys",
405 L"`(keys store)`: Return a list of all keys in this `store`.",
406 &lisp_keys );
407 bind_function( L"list", L"`(list args...): Return a list of these `args`.",
408 &lisp_list );
409 bind_function( L"mapcar",
410 L"`(mapcar function sequence)`: Apply `function` to each element of `sequence` in turn, and return a sequence of the results.",
411 &lisp_mapcar );
412 bind_function( L"meta",
413 L"`(meta symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`.",
414 &lisp_metadata );
415 bind_function( L"metadata",
416 L"`(metadata symbol)`: If the binding of `symbol` has metadata, return that metadata, else `nil`.",
417 &lisp_metadata );
418 bind_function( L"multiply",
419 L"`(* args...)` Multiply these `args`, all of which should be numbers.",
420 &lisp_multiply );
421 bind_function( L"negative?",
422 L"`(negative? n)`: Return `t` if `n` is a negative number, else `nil`.",
424 bind_function( L"not",
425 L"`(not arg)`: Return`t` only if `arg` is `nil`, else `nil`.",
426 &lisp_not );
427 bind_function( L"oblist",
428 L"`(oblist)`: Return the current symbol bindings, as a map.",
429 &lisp_oblist );
430 bind_function( L"open",
431 L"`(open url write?)`: Open a stream to this `url`. If `write?` is present and is non-nil, open it for writing, else reading.",
432 &lisp_open );
433 bind_function( L"or",
434 L"`(or args...)`: Return a logical `or` of all the arguments and return `t` if any is truthy, else `nil`.",
435 &lisp_or );
436 bind_function( L"print",
437 L"`(print object stream)`: Print `object` to `stream`, if specified, else to `*out*`.",
438 &lisp_print );
439 bind_function( L"println",
440 L"`(println stream)`: Print a new line character to `stream`, if specified, else to `*out*`.",
441 &lisp_print );
442 bind_function( L"put!", L"", lisp_hashmap_put );
443 bind_function( L"put-all!",
444 L"`(put-all! dest source)`: If `dest` is a namespace and is writable, copies all key-value pairs from `source` into `dest`.",
446 bind_function( L"ratio->real",
447 L"`(ratio->real r)`: If `r` is a rational number, return the real number equivalent.",
449 bind_function( L"read",
450 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.",
451 &lisp_read );
452 bind_function( L"read-char",
453 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.",
455 bind_function( L"repl",
456 L"`(repl prompt input output)`: Starts a new read-eval-print-loop. All arguments are optional.",
457 &lisp_repl );
458 bind_function( L"reverse",
459 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.",
460 &lisp_reverse );
461 bind_function( L"set", L"", &lisp_set );
462 bind_function( L"slurp",
463 L"`(slurp read-stream)` Read all the characters from `read-stream` to the end of stream, and return them as a string.",
464 &lisp_slurp );
465 bind_function( L"source",
466 L"`(source object)`: If `object` is an interpreted function or interpreted special form, returns the source code; else nil.",
467 &lisp_source );
468 bind_function( L"subtract",
469 L"`(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers.",
470 &lisp_subtract );
471 bind_function( L"throw", L"", &lisp_exception );
472 bind_function( L"time",
473 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.",
474 &lisp_time );
475 bind_function( L"type",
476 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.",
477 &lisp_type );
478 bind_function( L"+",
479 L"`(+ args...)`: If `args` are all numbers, return the sum of those numbers.",
480 &lisp_add );
481 bind_function( L"*",
482 L"`(* args...)` Multiply these `args`, all of which should be numbers.",
483 &lisp_multiply );
484 bind_function( L"-",
485 L"`(- a b)`: Subtracts `b` from `a` and returns the result. Expects both arguments to be numbers.",
486 &lisp_subtract );
487 bind_function( L"/",
488 L"`(/ a b)`: If `a` and `b` are both numbers, return the numeric result of dividing `a` by `b`.",
489 &lisp_divide );
490 bind_function( L"=",
491 L"`(equal? args...)`: Return `t` if all args have logically equivalent value, else `nil`.",
492 &lisp_equal );
493 /*
494 * primitive special forms
495 */
496 bind_special( L"cond",
497 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.",
498 &lisp_cond );
499 bind_special( L"lambda",
500 L"`(lambda arg-list forms...)`: Construct an interpretable λ funtion.",
501 &lisp_lambda );
502 bind_special( L"\u03bb", L"", &lisp_lambda ); // λ
503 bind_special( L"let",
504 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.",
505 &lisp_let );
506 bind_special( L"nlambda",
507 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.",
508 &lisp_nlambda );
509 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λ
510 bind_special( L"progn",
511 L"`(progn forms...)` Evaluate `forms` sequentially, and return the value of the last.",
512 &lisp_progn );
513 bind_special( L"quote",
514 L"`(quote form)`: Returns `form`, unevaluated. More idiomatically expressed `'form`, where the quote mark is a reader macro which is expanded to `(quote form)`.",
515 &lisp_quote );
516 bind_special( L"set!",
517 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.",
519 bind_special( L"try", L"", &lisp_try );
520 debug_print( L"Initialised oblist\n", DEBUG_BOOTSTRAP );
522
523 repl( show_prompt );
524
526
527 debug_print( L"Freeing oblist\n", DEBUG_BOOTSTRAP );
528 while ( ( pointer2cell( oblist ) ).count > 0 ) {
529 fprintf( stderr, "Dangling refs on oblist: %d\n",
530 ( pointer2cell( oblist ) ).count );
531 dec_ref( oblist );
532 }
533
535
536 if ( dump_at_end ) {
537 dump_pages( file_to_url_file( stdout ) );
538 }
539
541 curl_global_cleanup( );
542 return ( 0 );
543}
void dump_pages(URL_FILE *output)
dump the allocated pages to this output stream.
Definition conspage.c:130
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:280
void initialise_cons_pages()
initialise the cons page system; to be called exactly once during startup.
Definition conspage.c:266
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 c_string_to_lisp_keyword(wchar_t *symbol)
Return a lisp keyword representation of this wide character string.
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 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 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 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:136
void debug_print(wchar_t *message, int level)
print this debug message to stderr, if verbosity matches level.
Definition debug.c:41
#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:231
void maybe_bind_init_symbols()
Definition init.c:73
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:138
void print_options(FILE *stream)
Print command line options to this stream.
Definition init.c:205
struct cons_pointer init_documentation_symbol
Definition init.c:69
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:108
struct cons_pointer init_name_symbol
Definition init.c:70
struct cons_pointer init_primitive_symbol
Definition init.c:71
void free_init_symbols()
Definition init.c:95
void print_banner()
Definition init.c:195
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:167
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:184
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:452
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:241
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:836
struct cons_pointer lisp_source(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Function.
Definition lispops.c:1419
struct cons_pointer lisp_mapcar(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Definition lispops.c:1511
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:703
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:871
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:962
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:1285
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:736
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:943
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:1581
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:1057
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:1657
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:158
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:565
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:505
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:1094
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:1135
struct cons_pointer lisp_keys(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Definition lispops.c:855
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:896
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:1305
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:655
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:1499
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:1678
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:595
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:617
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:224
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:780
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:1561
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:187
struct cons_pointer lisp_cond(struct stack_frame *frame, struct cons_pointer frame_pointer, struct cons_pointer env)
Special form: conditional.
Definition lispops.c:1213
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:1037
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:1636
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:797
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:572
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:683
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:698
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:494
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:355
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
#define VERSION
version.h
Definition version.h:11