Things working much better now. assoc works. Currently printing of

string-like-things does not work, but I suspect that's shallow.
This commit is contained in:
Simon Brooke 2026-04-18 15:44:14 +01:00
parent 02a4bc3e28
commit 9a0f186f29
13 changed files with 400 additions and 38 deletions

268
docs/shipnames.md Normal file
View file

@ -0,0 +1,268 @@
# Ship names from Iain M Banks' Culture series
This list is culled from the Wikipedia page. I don't know if it's comprehensive (although it looks it), and I haven't checked that all the names are either present in the books or spelled correctly here. I *think* they are, and that's good enough.
Note that these names are not all Culture ships; and I think I should probably prefer only to select ones that are.
The reason the list is here is that I propose to assign a codename taken from the list to each point release of Post Scarcity. starting from 0.1.0, which will be `A Momentary Lapse Of Sanity`. Names that have already been selected are **highlighted**.
I think my plan is to assign 0.1.X point releases names starting with `A`, 0.2.X releases names starting with `B`, and so on; but I reserve the right to change my mind or just be wildly inconsistent.
-----
- 5Gelish-Oplule
- 7Uagren
- 8401.00 Partial Photic Boundary
- 8Churkun
- Abalule-Sheliz
- Ablation
- Abundance Of Onslaught
- Advanced Case Of Chronic Patheticism
- A Fine Disregard For Awkward Facts
- All The Same, I Saw It First
- **A Momentary Lapse Of Sanity**
- Another Fine Product From The Nonsense Factory
- Anticipation Of A New Lover's Arrival, The
- Anything Legal Considered
- Appeal To Reason
- Arbitrary
- Armchair Traveller
- Arrested Development
- A Series Of Unlikely Explanations
- A Ship With A View
- Attitude Adjuster
- Awkward Customer
- Bad For Business
- Beastly To The Animals
- Beats Working
- Big Sexy Beast
- Bodhisattva, OAQS
- Boo!
- Bora Horza Gobuchul
- Break Even
- But Who's Counting?
- Caconym
- Cantankerous
- Cargo Cult
- CH2OH.(CHOH)4.CHO
- Charitable View
- Charming But Irrational
- Clear Air Turbulence or CAT for short
- Congenital Optimist
- Contents May Differ
- Control Surface
- Conventional Wisdom
- Credibility Problem
- Death And Gravity
- Demented But Determined
- Determinist
- Different Tan
- Displacement Activity
- Don't Try This At Home
- Dramatic Exit
- Dressed Up To Party
- Eight Rounds Rapid
- Empiricist
- Eschatologist (temporary name)
- Ethics Gradient
- Exaltation-Parsimony III
- Excuses And Accusations
- Experiencing A Significant Gravitas Shortfall
- Experiencing A Significant Gravitas Shortfall
- Falling Outside The Normal Moral Constraints
- “Fasilyce, Upon Waking”
- Fate Amenable To Change
- Fine Till You Came Along
- Fixed Grin
- Flexible Demeanour
- Fractious Person
- Frank Exchange Of Views
- Frightspear
- Fulanya-Guang
- Full Refund (formerly MBU 604)
- Funny, It Worked Last Time...
- Furious Purpose
- Gellemtyan-Asool-Anafawaya
- Germane Riposte
- God Told Me To Do It
- Grey Area (aka Meatfucker)
- Grey Area (aka Meatfucker)
- Gunboat Diplomat
- Halation Effect
- Hand Me The Gun And Ask Me Again
- Happy Idiot Talk
- Headcrash
- Heavy Messing
- Helpless In The Face Of Your Beauty
- Hence the Fortress
- Heresiarch
- Hidden Income
- Highpoint
- Honest Mistake
- Hundredth Idiot, The
- Hylozoist
- Iberre
- I Blame My Mother
- I Blame The Parents
- I Blame Your Mother
- Inappropriate Response
- Injury Time
- In One Ear
- Inspiral, Coalescence, Ringdown
- Invincible
- Irregular Apocalypse
- I Said, I've Got A Big Stick
- I Thought He Was With You
- It'll Be Over By Christmas
- It's Character Forming
- It's My Party And I'll Sing If I Want To
- Jaundiced Outlook
- Joiler Veppers (provisional name)
- Just Another Victim Of The Ambient Morality
- Just Passing Through
- Just Read The Instructions
- Just Testing
- Just The Washing Instruction Chip In Life's Rich Tapestry
- Kakistocrat
- Killing Time
- Kiss My Ass
- Kiss The Blade
- Kiss This Then
- Labtebricolephile
- Lacking That Small Match Temperament
- Lapsed Pacifist
- Laskuil-Hliz
- Lasting Damage
- Lasting Damage I
- Lasting Damage II
- later Sleeper Service
- Learned Response
- Lightly Seared On The Reality Grill
- Limiting Factor
- Limivorous
- Little Rascal
- Liveware Problem“Now, Turning to Reason, & its Just Sweetness”
- Long View
- Lucid Nonsense
- Me, I'm Counting
- Melancholia Enshrines All Triumph
- Messenger Of Truth
- Minority Report
- Misophist
- Mistake Not…
- Nervous Energy
- Never Talk To Strangers
- New Toy
- No Fixed Abode
- No More Mr Nice Guy
- No One Knows What The Dead Think
- Not Invented Here
- Not Wanted On Voyage
- Now Look What You've Made Me Do
- Now We Try It My Way
- Nuisance Value
- Oceanic Dissonance
- Of Course I Still Love You
- “On First Seeing Jhiriit”
- Only Slightly Bent
- Outstanding Contribution To The Historical Process
- Passing By And Thought I'd Drop In
- Peace Makes Plenty
- Pelagian
- Perfidy
- Piety
- Poke It With A Stick
- Pressure Drop
- Pride Comes Before A Fall
- Prime Mover
- Problem Child
- Profit Margin
- Prosthetic Conscience
- Pure Big Mad Boat Man
- Qualifier
- Questionable Ethics
- Quiatrea-Anang
- Quietly Confident,
- Rapid Random Response Unit
- Ravished By The Sheer Implausibility Of That Last Statement
- Reasonable Excuse
- Recent Convert
- Reformed Nice Guy
- Refreshingly Unconcerned With The Vulgar Exigencies Of Veracity
- Resistance Is Character-Forming
- Revisionist
- Riptalon
- Rubric Of Ruin
- Sacrificial Victim
- SacSlicer II
- Sanctioned Parts List
- Scar Glamour
- Screw Loose
- Seed Drill
- Sense Amid Madness, Wit Amidst Folly
- Serious Callers Only
- Shoot Them Later
- Size Isn't Everything
- Smile Tolerantly
- Sober Counsel
- Someone Else's Problem
- So Much For Subtlety
- Soulhaven
- Space Monster
- Steely Glint
- Stranger Here Myself
- Subtle Shift In Emphasis
- Sweet and Full of Grace
- Synchronize Your Dogmas
- T3OU 118
- T3OU 4
- T3OU 736
- Tactical Grace
- Teething Problems
- Thank You And Goodnight
- The Ends Of Invention
- The Hand of God 137
- The Precise Nature Of The Catastrophe
- The Usual But Etymologically Unsatisfactory
- Thorough But... Unreliable
- Total Internal Reflection
- Trade Surplus
- Transient Atmospheric Phenomenon
- Ucalegon
- Ultimate Ship The Second
- Unacceptable Behaviour
- Undesirable Alien
- Unfortunate Conflict Of Evidence
- Uninvited Guest
- Unreliable Witness
- Unwitting Accomplice
- Use Psychology
- Value Judgement
- Very Little Gravitas Indeed
- Vision Of Hope Surpassed
- Vulgarian
- Warm, Considering
- We Haven't Met But You're A Great Fan Of Mine
- Well I Was In The Neighbourhood
- What Are The Civilian Applications?
- What Is The Answer And Why?
- Wingclipper
- Winter Storm
- Wisdom Like Silence
- Within Reason
- Xenoclast
- Xenocrat
- Xenoglossicist
- Xenophobe
- Yawning Angel
- You Call This Clean?
- You'll Clean That Up Before You Leave
- You'll Thank Me Later
- You May Not Be The Coolest Person Here
- You Naughty Monsters
- Youthful Indiscretion
- You Would If You Really Loved Me
- Zealot
- Zero Credibility
- Zero Gravitas
- Zoologist

View file

@ -143,7 +143,7 @@ void debug_print_object( struct pso_pointer pointer, int level, int indent ) {
if ( level & verbosity ) { if ( level & verbosity ) {
URL_FILE *ustderr = file_to_url_file( stderr ); URL_FILE *ustderr = file_to_url_file( stderr );
fwide( stderr, 1 ); fwide( stderr, 1 );
in_print( pointer, ustderr ); in_write( pointer, ustderr, PRINT_VARIANT_PRINT );
free( ustderr ); free( ustderr );
} }
#endif #endif

View file

@ -89,7 +89,7 @@ struct pso_pointer lisp_io_out;
struct pso_pointer lisp_stdout; struct pso_pointer lisp_stdout;
/** /**
* @brief bound to the Lisp symbol representing C_IO_log in initialisation. * @brief bound to the Lisp symbol representing C_IO_LOG in initialisation.
*/ */
struct pso_pointer lisp_io_log; struct pso_pointer lisp_io_log;
@ -99,6 +99,11 @@ struct pso_pointer lisp_io_log;
*/ */
struct pso_pointer lisp_stderr; struct pso_pointer lisp_stderr;
/**
* @brief bound to the Lisp symbol representing C_IO_PROMPT in initialisation
*/
struct pso_pointer lisp_io_prompt;
/** /**
* Allow a one-character unget facility. This may not be enough - we may need * Allow a one-character unget facility. This may not be enough - we may need
* to allocate a buffer. * to allocate a buffer.
@ -147,11 +152,16 @@ struct pso_pointer initialise_default_streams( struct pso_pointer env ) {
lisp_io_in = c_string_to_lisp_symbol( C_IO_IN ); lisp_io_in = c_string_to_lisp_symbol( C_IO_IN );
lisp_io_out = c_string_to_lisp_symbol( C_IO_OUT ); lisp_io_out = c_string_to_lisp_symbol( C_IO_OUT );
lisp_io_log = c_string_to_lisp_symbol( C_IO_LOG ); lisp_io_log = c_string_to_lisp_symbol( C_IO_LOG );
lisp_io_prompt = c_string_to_lisp_symbol( C_IO_PROMPT );
debug_print( L"In initialise_default_streams; environment is: ", DEBUG_IO, debug_print( L"In initialise_default_streams; environment is: ", DEBUG_IO,
0 ); 0 );
debug_print_object( env, DEBUG_IO, 0 ); debug_print_object( env, DEBUG_IO, 0 );
env =
c_bind( lisp_io_prompt, c_string_to_lisp_string( INITIAL_PROMPT ),
env );
lisp_stdin = lock_object( make_read_stream( file_to_url_file( stdin ), lisp_stdin = lock_object( make_read_stream( file_to_url_file( stdin ),
c_cons( c_cons c_cons( c_cons
( c_string_to_lisp_keyword ( c_string_to_lisp_keyword
@ -367,8 +377,8 @@ struct pso_pointer push_back_character( struct pso_pointer c,
if ( characterp( c ) && readp( r ) ) { if ( characterp( c ) && readp( r ) ) {
if ( url_ungetwc( ( wint_t ) if ( url_ungetwc( ( wint_t )
( pointer_to_object( c )->payload.character. ( pointer_to_object( c )->payload.
character ), character.character ),
pointer_to_object( r )->payload.stream.stream ) >= pointer_to_object( r )->payload.stream.stream ) >=
0 ) { 0 ) {
result = t; result = t;

View file

@ -33,6 +33,11 @@ extern struct pso_pointer lisp_stdin;
extern struct pso_pointer lisp_stdout; extern struct pso_pointer lisp_stdout;
extern struct pso_pointer lisp_stderr; extern struct pso_pointer lisp_stderr;
#define INITIAL_PROMPT L"psse ]"
#define C_IO_PROMPT L"*prompt*"
extern struct pso_pointer lisp_io_prompt;
URL_FILE *file_to_url_file( FILE * f ); URL_FILE *file_to_url_file( FILE * f );
wint_t url_fgetwc( URL_FILE * input ); wint_t url_fgetwc( URL_FILE * input );
wint_t url_ungetwc( wint_t wc, URL_FILE * input ); wint_t url_ungetwc( wint_t wc, URL_FILE * input );

View file

@ -11,6 +11,7 @@
* Licensed under GPL version 2.0, or, at your option, any later version. * Licensed under GPL version 2.0, or, at your option, any later version.
*/ */
#include <stdbool.h>
#include <ctype.h> #include <ctype.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -26,6 +27,7 @@
#include "io/fopen.h" #include "io/fopen.h"
#include "io/io.h" #include "io/io.h"
#include "io/print.h"
#include "memory/node.h" #include "memory/node.h"
#include "memory/pointer.h" #include "memory/pointer.h"
@ -33,22 +35,26 @@
#include "memory/pso2.h" #include "memory/pso2.h"
#include "memory/tags.h" #include "memory/tags.h"
#include "ops/string_ops.h"
#include "payloads/character.h" #include "payloads/character.h"
#include "payloads/cons.h" #include "payloads/cons.h"
#include "payloads/exception.h"
#include "payloads/integer.h" #include "payloads/integer.h"
#include "ops/truth.h" #include "ops/truth.h"
struct pso_pointer in_print( struct pso_pointer p, URL_FILE * output ); struct pso_pointer in_write( struct pso_pointer p, URL_FILE * output,
bool escape );
struct pso_pointer print_string_like_thing( struct pso_pointer p, struct pso_pointer print_string_like_thing( struct pso_pointer p,
URL_FILE *output ) { URL_FILE *output, bool escape ) {
switch ( get_tag_value( p ) ) { switch ( get_tag_value( p ) ) {
case KEYTV: case KEYTV:
url_fputwc( L':', output ); url_fputwc( L':', output );
break; break;
case STRINGTV: case STRINGTV:
url_fputwc( L'"', output ); if ( !escape )
url_fputwc( L'"', output );
break; break;
} }
@ -61,18 +67,20 @@ struct pso_pointer print_string_like_thing( struct pso_pointer p,
} }
if ( stringp( p ) ) { if ( stringp( p ) ) {
url_fputwc( L'"', output ); if ( !escape )
url_fputwc( L'"', output );
} }
} }
struct pso_pointer print_list_content( struct pso_pointer p, URL_FILE *output ) { struct pso_pointer print_list_content( struct pso_pointer p, URL_FILE *output,
bool escape ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
if ( consp( p ) ) { if ( consp( p ) ) {
for ( ; consp( p ); p = c_cdr( p ) ) { for ( ; consp( p ); p = c_cdr( p ) ) {
struct pso2 *object = pointer_to_object( p ); struct pso2 *object = pointer_to_object( p );
result = in_print( object->payload.cons.car, output ); result = in_write( object->payload.cons.car, output, escape );
if ( exceptionp( result ) ) if ( exceptionp( result ) )
break; break;
@ -85,7 +93,8 @@ struct pso_pointer print_list_content( struct pso_pointer p, URL_FILE *output )
break; break;
default: default:
url_fputws( L" . ", output ); url_fputws( L" . ", output );
result = in_print( object->payload.cons.cdr, output ); result =
in_write( object->payload.cons.cdr, output, escape );
} }
} }
} else { } else {
@ -95,7 +104,18 @@ struct pso_pointer print_list_content( struct pso_pointer p, URL_FILE *output )
return result; return result;
} }
struct pso_pointer in_print( struct pso_pointer p, URL_FILE *output ) { /**
* This is kind of modelled after the implementation of PRIN* variants on page
* 383 of the aluminium book. It is the inner workings of all PRIN* functions.
*
* @param p pointer to the object to print.
* @param output stream to print to.
* @param escape if true, print everything so that it can be read by the Lisp
* reader; otherwise, print it appropriately for human readers.
* @return p on success, exception on failure.
*/
struct pso_pointer in_write( struct pso_pointer p, URL_FILE *output,
bool escape ) {
struct pso2 *object = pointer_to_object( p ); struct pso2 *object = pointer_to_object( p );
struct pso_pointer result = nil; struct pso_pointer result = nil;
@ -107,7 +127,7 @@ struct pso_pointer in_print( struct pso_pointer p, URL_FILE *output ) {
break; break;
case CONSTV: case CONSTV:
url_fputwc( L'(', output ); url_fputwc( L'(', output );
result = print_list_content( p, output ); result = print_list_content( p, output, escape );
url_fputwc( L')', output ); url_fputwc( L')', output );
break; break;
case INTEGERTV: case INTEGERTV:
@ -117,7 +137,7 @@ struct pso_pointer in_print( struct pso_pointer p, URL_FILE *output ) {
case KEYTV: case KEYTV:
case STRINGTV: case STRINGTV:
case SYMBOLTV: case SYMBOLTV:
print_string_like_thing( p, output ); print_string_like_thing( p, output, escape );
break; break;
case NILTV: case NILTV:
url_fputws( L"nil", output ); url_fputws( L"nil", output );
@ -126,7 +146,7 @@ struct pso_pointer in_print( struct pso_pointer p, URL_FILE *output ) {
case WRITETV: case WRITETV:
url_fwprintf( output, L"<%s stream: ", url_fwprintf( output, L"<%s stream: ",
v == READTV ? "read" : "write" ); v == READTV ? "read" : "write" );
in_print( object->payload.stream.meta, output ); in_write( object->payload.stream.meta, output, escape );
url_fputwc( L'>', output ); url_fputwc( L'>', output );
break; break;
case TRUETV: case TRUETV:
@ -143,13 +163,19 @@ struct pso_pointer in_print( struct pso_pointer p, URL_FILE *output ) {
} }
/** /**
* @brief Simple print for bootstrap layer. * This is kind of modelled after the implementation of PRIN* variants on page
* 383 of the aluminium book. It is the inner workings of all PRIN* functions.
* *
* @param p pointer to the object to print. * @param p pointer to the object to print.
* @param stream if a pointer to an open write stream, print to there. * @param output stream to print to.
* @return struct pso_pointer `nil`, or an exception if some erroe occurred. * @param escape if true, print everything so that it can be read by the Lisp
* reader; otherwise, print it appropriately for human readers.
* @param nl_before if true, print a newline *before* printing `p`.
* @param nl_after if true, print a newline *after* printing `p`; else a space.
* @return p on success, exception on failure.
*/ */
struct pso_pointer c_print( struct pso_pointer p, struct pso_pointer stream ) { struct pso_pointer write( struct pso_pointer p, struct pso_pointer stream,
bool escape, bool nl_before, bool nl_after ) {
struct pso_pointer result = p; struct pso_pointer result = p;
URL_FILE *output = writep( stream ) URL_FILE *output = writep( stream )
? pointer_to_object( stream )->payload.stream.stream ? pointer_to_object( stream )->payload.stream.stream
@ -158,10 +184,38 @@ struct pso_pointer c_print( struct pso_pointer p, struct pso_pointer stream ) {
if ( writep( stream ) ) { if ( writep( stream ) ) {
inc_ref( stream ); inc_ref( stream );
result = in_print( p, output ); if ( nl_before )
url_fputwc( L'\n', output );
result = in_write( p, output, true );
url_fputwc( nl_after ? L'\n' : L' ', output );
dec_ref( stream ); dec_ref( stream );
} else {
result =
make_exception( c_string_to_lisp_string
( L"Bad write stream passed to write." ), nil, nil,
nil );
} }
return result; return result;
} }
/**
* @brief Simple print for bootstrap layer.
*
* @param p pointer to the object to print.
* @param stream if a pointer to an open write stream, print to there.
* @return struct pso_pointer `nil`, or an exception if some erroe occurred.
*/
struct pso_pointer c_print( struct pso_pointer p, struct pso_pointer stream ) {
return write( p, stream, true, true, false );
}
/**
* @brief princ is pretty much like print except things are printed `unescaped`
*/
struct pso_pointer c_princ( struct pso_pointer p, struct pso_pointer stream ) {
return write( p, stream, false, true, false );
}

View file

@ -13,10 +13,17 @@
#ifndef __psse_io_print_h #ifndef __psse_io_print_h
#define __psse_io_print_h #define __psse_io_print_h
#include <stdbool.h>
#include "io/fopen.h" #include "io/fopen.h"
struct pso_pointer c_print( struct pso_pointer p, struct pso_pointer stream ); struct pso_pointer c_print( struct pso_pointer p, struct pso_pointer stream );
struct pso_pointer c_princ( struct pso_pointer p, struct pso_pointer stream );
struct pso_pointer in_print( struct pso_pointer p, URL_FILE * output ); #define PRINT_VARIANT_PRINT 0
#define PRINT_VARIANT_PRIN1 1
#define PRINT_VARIANT_PRINC 2
struct pso_pointer in_write( struct pso_pointer p, URL_FILE * output,
bool variant );
#endif #endif

View file

@ -55,7 +55,7 @@ struct pso_pointer destroy( struct pso_pointer p ) {
destroy_string( f, nil ); destroy_string( f, nil );
break; break;
case STACKTV: case STACKTV:
destroy_stack_frame( f, nil ); // destroy_stack_frame( f, nil );
break; break;
// TODO: others. // TODO: others.
} }

View file

@ -14,7 +14,9 @@
* Licensed under GPL version 2.0, or, at your option, any later version. * Licensed under GPL version 2.0, or, at your option, any later version.
*/ */
#include <math.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -92,10 +94,15 @@ struct pso_pointer allocate( char *tag, uint8_t size_class ) {
return result; return result;
} }
uint32_t payload_size( struct pso2 *object ) { int payload_size( struct pso2 *object ) {
// TODO: Unit tests DEFINITELY needed! // TODO: Unit tests DEFINITELY needed!
return ( ( 1 << object->header.tag.bytes.size_class ) - int sc = object->header.tag.bytes.size_class;
sizeof( struct pso_header ) ); int hs = sizeof( struct pso_header ) / sizeof( uint64_t );
int p = pow( 2, sc );
int result = abs( p - hs );
return result;
} }
/** /**
@ -190,8 +197,8 @@ struct pso_pointer lock_object( struct pso_pointer pointer ) {
struct pso_pointer free_object( struct pso_pointer p ) { struct pso_pointer free_object( struct pso_pointer p ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
struct pso2 *obj = pointer_to_object( p ); struct pso2 *obj = pointer_to_object( p );
uint32_t array_size = payload_size( obj ); uint32_t array_size = ( uint32_t ) payload_size( obj );
uint8_t size_class = obj->header.tag.bytes.size_class; uint8_t size_class = ( obj->header.tag.bytes.size_class );
result = destroy( p ); result = destroy( p );

View file

@ -41,7 +41,7 @@ bool c_eq( struct pso_pointer a, struct pso_pointer b ) {
} }
bool c_equal( struct pso_pointer a, struct pso_pointer b ) { bool c_equal( struct pso_pointer a, struct pso_pointer b ) {
bool result = false; bool result = true;
if ( c_eq( a, b ) ) { if ( c_eq( a, b ) ) {
result = true; result = true;
@ -66,15 +66,19 @@ bool c_equal( struct pso_pointer a, struct pso_pointer b ) {
case KEYTV: case KEYTV:
case STRINGTV: case STRINGTV:
case SYMBOLTV: case SYMBOLTV:
while ( !nilp( a ) && !nilp( b ) ) { while ( result && !nilp( a ) && !nilp( b ) ) {
if ( pointer_to_object( a )->payload.string.character == if ( pointer_to_object( a )->payload.string.character ==
pointer_to_object( b )->payload.string.character ) { pointer_to_object( b )->payload.string.character ) {
a = c_cdr( a ); a = c_cdr( a );
b = c_cdr( b ); b = c_cdr( b );
} else {
result = false;
} }
} }
result = nilp( a ) && nilp( b ); result = result && nilp( a ) && nilp( b );
break; break;
default:
result = false;
} }
} }

View file

@ -47,7 +47,7 @@ void int_handler( int dummy ) {
/** /**
* Very simple read/eval/print loop for bootstrapping. * Very simple read/eval/print loop for bootstrapping.
*/ */
void c_repl( ) { void c_repl( bool show_prompt ) {
signal( SIGINT, int_handler ); signal( SIGINT, int_handler );
debug_print( L"Entered repl\n", DEBUG_REPL, 0 ); debug_print( L"Entered repl\n", DEBUG_REPL, 0 );
@ -68,6 +68,9 @@ void c_repl( ) {
while ( readp( input_stream ) && while ( readp( input_stream ) &&
!url_feof( stream_get_url_file( input_stream ) ) ) { !url_feof( stream_get_url_file( input_stream ) ) ) {
if ( show_prompt )
c_princ( c_assoc( lisp_io_prompt, env ), output_stream );
/* bottom of stack */ /* bottom of stack */
struct pso_pointer frame_pointer = make_frame( 1, nil, input_stream ); struct pso_pointer frame_pointer = make_frame( 1, nil, input_stream );

View file

@ -50,7 +50,7 @@ struct pso_pointer c_cons( struct pso_pointer car, struct pso_pointer cdr ) {
*/ */
struct pso_pointer c_car( struct pso_pointer cons ) { struct pso_pointer c_car( struct pso_pointer cons ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
struct pso2 *object = pointer_to_object( result ); struct pso2 *object = pointer_to_object( cons );
if ( consp( cons ) ) { if ( consp( cons ) ) {
result = object->payload.cons.car; result = object->payload.cons.car;

View file

@ -125,12 +125,16 @@ int main( int argc, char *argv[] ) {
exit( 1 ); exit( 1 );
} }
c_print( c_cons( c_string_to_lisp_keyword( L"a" ), if ( show_prompt ) {
( c_cons( c_string_to_lisp_keyword( L"b" ), fwprintf( stdout,
c_cons( c_string_to_lisp_keyword( L"c" ), L"Post-scarcity Software Environment version %s\n'%s'\n\n",
nil ) ) ) ), lisp_stdout ); VERSION, VERSION_CODENAME );
fputws
( L"Licensed under GPL version 2.0, or, at your option, any later version\n\n",
stdout );
}
// c_repl(); c_repl( show_prompt );
exit( 0 ); exit( 0 );
} }

View file

@ -3,9 +3,9 @@
* *
* Just the version number. There's DEFINITELY a better way to do this! * Just the version number. There's DEFINITELY a better way to do this!
* *
*
* (c) 2026 Simon Brooke <simon@journeyman.cc> * (c) 2026 Simon Brooke <simon@journeyman.cc>
* Licensed under GPL version 2.0, or, at your option, any later version. * Licensed under GPL version 2.0, or, at your option, any later version.
*/ */
#define VERSION "0.1.0-SNAPSHOT" #define VERSION "0.1.0-SNAPSHOT"
#define VERSION_CODENAME "A Momentary Lapse Of Sanity"