Closes #18. Change to char32_t everywhere; builds fine, behaviour as before.

This commit is contained in:
Simon Brooke 2026-04-20 12:10:38 +01:00
parent 812a1be7d9
commit c59825d7fe
33 changed files with 116 additions and 76 deletions

View file

@ -57,7 +57,7 @@ void debug_print_exception( struct cons_pointer ex_ptr ) {
* `verbosity` is a set of flags, see debug_print.h; so you can * `verbosity` is a set of flags, see debug_print.h; so you can
* turn debugging on for only one part of the system. * turn debugging on for only one part of the system.
*/ */
void debug_print( wchar_t *message, int level ) { void debug_print( char32_t *message, int level ) {
#ifdef DEBUG #ifdef DEBUG
if ( level & verbosity ) { if ( level & verbosity ) {
fwide( stderr, 1 ); fwide( stderr, 1 );
@ -117,7 +117,7 @@ void debug_println( int level ) {
* Print to stderr only if `verbosity` matches `level`. All other arguments * Print to stderr only if `verbosity` matches `level`. All other arguments
* as for `wprintf`. * as for `wprintf`.
*/ */
void debug_printf( int level, wchar_t *format, ... ) { void debug_printf( int level, char32_t *format, ... ) {
#ifdef DEBUG #ifdef DEBUG
if ( level & verbosity ) { if ( level & verbosity ) {
fwide( stderr, 1 ); fwide( stderr, 1 );
@ -169,7 +169,7 @@ void debug_dump_object( struct cons_pointer pointer, int level ) {
void debug_print_binding( struct cons_pointer key, struct cons_pointer val, void debug_print_binding( struct cons_pointer key, struct cons_pointer val,
bool deep, int level ) { bool deep, int level ) {
#ifdef DEBUG #ifdef DEBUG
// wchar_t * depth = (deep ? L"Deep" : L"Shallow"); // char32_t * depth = (deep ? L"Deep" : L"Shallow");
debug_print( ( deep ? L"Deep" : L"Shallow" ), level ); debug_print( ( deep ? L"Deep" : L"Shallow" ), level );
debug_print( L" binding `", level ); debug_print( L" binding `", level );

View file

@ -89,10 +89,10 @@
extern int verbosity; extern int verbosity;
void debug_print_exception( struct cons_pointer ex_ptr ); void debug_print_exception( struct cons_pointer ex_ptr );
void debug_print( wchar_t *message, int level ); void debug_print( char32_t *message, int level );
void debug_print_128bit( __int128_t n, int level ); void debug_print_128bit( __int128_t n, int level );
void debug_println( int level ); void debug_println( int level );
void debug_printf( int level, wchar_t *format, ... ); void debug_printf( int level, char32_t *format, ... );
void debug_print_object( struct cons_pointer pointer, int level ); void debug_print_object( struct cons_pointer pointer, int level );
void debug_dump_object( struct cons_pointer pointer, int level ); void debug_dump_object( struct cons_pointer pointer, int level );
void debug_print_binding( struct cons_pointer key, struct cons_pointer val, void debug_print_binding( struct cons_pointer key, struct cons_pointer val,

View file

@ -110,8 +110,8 @@ void free_init_symbols( ) {
* the name on the source pointer. Would make stack frames potentially * the name on the source pointer. Would make stack frames potentially
* more readable and aid debugging generally. * more readable and aid debugging generally.
*/ */
struct cons_pointer bind_function( wchar_t *name, struct cons_pointer bind_function( char32_t *name,
wchar_t *doc, char32_t *doc,
struct cons_pointer ( *executable ) struct cons_pointer ( *executable )
( struct stack_frame *, ( struct stack_frame *,
struct cons_pointer, struct cons_pointer,
@ -141,8 +141,8 @@ struct cons_pointer bind_function( wchar_t *name,
* Bind this compiled `executable` function, as a Lisp special form, to * Bind this compiled `executable` function, as a Lisp special form, to
* this `name` in the `oblist`. * this `name` in the `oblist`.
*/ */
struct cons_pointer bind_special( wchar_t *name, struct cons_pointer bind_special( char32_t *name,
wchar_t *doc, char32_t *doc,
struct cons_pointer ( *executable ) struct cons_pointer ( *executable )
( struct stack_frame *, struct cons_pointer, ( struct stack_frame *, struct cons_pointer,
struct cons_pointer ) ) { struct cons_pointer ) ) {
@ -188,7 +188,7 @@ bind_symbol_value( struct cons_pointer symbol, struct cons_pointer value,
/** /**
* Bind this `value` to this `name` in the `oblist`. * Bind this `value` to this `name` in the `oblist`.
*/ */
struct cons_pointer bind_value( wchar_t *name, struct cons_pointer value, struct cons_pointer bind_value( char32_t *name, struct cons_pointer value,
bool lock ) { bool lock ) {
struct cons_pointer p = c_string_to_lisp_symbol( name ); struct cons_pointer p = c_string_to_lisp_symbol( name );

View file

@ -103,7 +103,7 @@ char *lisp_string_to_c_string( struct cons_pointer s ) {
len++; len++;
} }
wchar_t *buffer = calloc( len + 1, sizeof( wchar_t ) ); char32_t *buffer = calloc( len + 1, sizeof( char32_t ) );
/* worst case, one wide char = four utf bytes */ /* worst case, one wide char = four utf bytes */
result = calloc( ( len * 4 ) + 1, sizeof( char ) ); result = calloc( ( len * 4 ) + 1, sizeof( char ) );
@ -164,8 +164,8 @@ wint_t url_fgetwc( URL_FILE *input ) {
case CFTYPE_CURL:{ case CFTYPE_CURL:{
char *cbuff = char *cbuff =
calloc( sizeof( wchar_t ) + 2, sizeof( char ) ); calloc( sizeof( char32_t ) + 2, sizeof( char ) );
wchar_t *wbuff = calloc( 2, sizeof( wchar_t ) ); char32_t *wbuff = calloc( 2, sizeof( char32_t ) );
size_t count = 0; size_t count = 0;
@ -265,7 +265,7 @@ lisp_close( struct stack_frame *frame, struct cons_pointer frame_pointer,
return result; return result;
} }
struct cons_pointer add_meta_integer( struct cons_pointer meta, wchar_t *key, struct cons_pointer add_meta_integer( struct cons_pointer meta, char32_t *key,
long int value ) { long int value ) {
return return
make_cons( make_cons make_cons( make_cons
@ -273,17 +273,17 @@ struct cons_pointer add_meta_integer( struct cons_pointer meta, wchar_t *key,
make_integer( value, NIL ) ), meta ); make_integer( value, NIL ) ), meta );
} }
struct cons_pointer add_meta_string( struct cons_pointer meta, wchar_t *key, struct cons_pointer add_meta_string( struct cons_pointer meta, char32_t *key,
char *value ) { char *value ) {
value = trim( value ); value = trim( value );
wchar_t buffer[strlen( value ) + 1]; char32_t buffer[strlen( value ) + 1];
mbstowcs( buffer, value, strlen( value ) + 1 ); mbstowcs( buffer, value, strlen( value ) + 1 );
return make_cons( make_cons( c_string_to_lisp_keyword( key ), return make_cons( make_cons( c_string_to_lisp_keyword( key ),
c_string_to_lisp_string( buffer ) ), meta ); c_string_to_lisp_string( buffer ) ), meta );
} }
struct cons_pointer add_meta_time( struct cons_pointer meta, wchar_t *key, struct cons_pointer add_meta_time( struct cons_pointer meta, char32_t *key,
time_t *value ) { time_t *value ) {
/* I don't yet have a concept of a date-time object, which is a /* I don't yet have a concept of a date-time object, which is a
* bit of an oversight! */ * bit of an oversight! */
@ -317,7 +317,7 @@ static size_t write_meta_callback( char *string, size_t size, size_t nmemb,
s[offset] = ( char ) 0; s[offset] = ( char ) 0;
char *name = trim( s ); char *name = trim( s );
char *value = trim( &s[++offset] ); char *value = trim( &s[++offset] );
wchar_t wname[strlen( name )]; char32_t wname[strlen( name )];
mbstowcs( wname, name, strlen( name ) + 1 ); mbstowcs( wname, name, strlen( name ) + 1 );
@ -548,7 +548,7 @@ lisp_slurp( struct stack_frame *frame, struct cons_pointer frame_pointer,
debug_println( DEBUG_IO ); debug_println( DEBUG_IO );
struct cons_space_object *cell = &pointer2cell( cursor ); struct cons_space_object *cell = &pointer2cell( cursor );
cursor = make_string( ( wchar_t ) c, NIL ); cursor = make_string( ( char32_t ) c, NIL );
cell->payload.string.cdr = cursor; cell->payload.string.cdr = cursor;
} }
} }

View file

@ -37,7 +37,7 @@
void print_string_contents( URL_FILE *output, struct cons_pointer pointer ) { void print_string_contents( URL_FILE *output, struct cons_pointer pointer ) {
while ( stringp( pointer ) || symbolp( pointer ) || keywordp( pointer ) ) { while ( stringp( pointer ) || symbolp( pointer ) || keywordp( pointer ) ) {
struct cons_space_object *cell = &pointer2cell( pointer ); struct cons_space_object *cell = &pointer2cell( pointer );
wchar_t c = cell->payload.string.character; char32_t c = cell->payload.string.character;
if ( c != '\0' ) { if ( c != '\0' ) {
url_fputwc( c, output ); url_fputwc( c, output );

View file

@ -181,7 +181,7 @@ struct cons_pointer c_type( struct cons_pointer pointer ) {
* strings made with NIL termination. The question is which should be * strings made with NIL termination. The question is which should be
* fixed, and actually that's probably strings read by `read`. However, * fixed, and actually that's probably strings read by `read`. However,
* for now, it was easier to add a null character here. */ * for now, it was easier to add a null character here. */
struct cons_pointer result = make_string( ( wchar_t ) 0, NIL ); struct cons_pointer result = make_string( ( char32_t ) 0, NIL );
struct cons_space_object *cell = &pointer2cell( pointer ); struct cons_space_object *cell = &pointer2cell( pointer );
if ( cell->tag.value == VECTORPOINTTV ) { if ( cell->tag.value == VECTORPOINTTV ) {
@ -189,11 +189,11 @@ struct cons_pointer c_type( struct cons_pointer pointer ) {
for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { for ( int i = TAGLENGTH - 1; i >= 0; i-- ) {
result = result =
make_string( ( wchar_t ) vec->header.tag.bytes[i], result ); make_string( ( char32_t ) vec->header.tag.bytes[i], result );
} }
} else { } else {
for ( int i = TAGLENGTH - 1; i >= 0; i-- ) { for ( int i = TAGLENGTH - 1; i >= 0; i-- ) {
result = make_string( ( wchar_t ) cell->tag.bytes[i], result ); result = make_string( ( char32_t ) cell->tag.bytes[i], result );
} }
} }
@ -518,11 +518,11 @@ struct cons_pointer make_write_stream( URL_FILE *output,
* Return a lisp keyword representation of this wide character string. In * Return a lisp keyword representation of this wide character string. In
* keywords, I am accepting only lower case characters and numbers. * keywords, I am accepting only lower case characters and numbers.
*/ */
struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) { struct cons_pointer c_string_to_lisp_keyword( char32_t *symbol ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) { for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
wchar_t c = towlower( symbol[i] ); char32_t c = towlower( symbol[i] );
if ( iswalnum( c ) || c == L'-' ) { if ( iswalnum( c ) || c == L'-' ) {
result = make_keyword( c, result ); result = make_keyword( c, result );
@ -535,7 +535,7 @@ struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) {
/** /**
* Return a lisp string representation of this wide character string. * Return a lisp string representation of this wide character string.
*/ */
struct cons_pointer c_string_to_lisp_string( wchar_t *string ) { struct cons_pointer c_string_to_lisp_string( char32_t *string ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
for ( int i = wcslen( string ) - 1; i >= 0; i-- ) { for ( int i = wcslen( string ) - 1; i >= 0; i-- ) {
@ -550,7 +550,7 @@ struct cons_pointer c_string_to_lisp_string( wchar_t *string ) {
/** /**
* Return a lisp symbol representation of this wide character string. * Return a lisp symbol representation of this wide character string.
*/ */
struct cons_pointer c_string_to_lisp_symbol( wchar_t *symbol ) { struct cons_pointer c_string_to_lisp_symbol( char32_t *symbol ) {
struct cons_pointer result = NIL; struct cons_pointer result = NIL;
for ( int i = wcslen( symbol ); i > 0; i-- ) { for ( int i = wcslen( symbol ); i > 0; i-- ) {

View file

@ -773,7 +773,7 @@ struct cons_pointer make_function( struct cons_pointer src,
struct cons_pointer, struct cons_pointer,
struct cons_pointer ) ); struct cons_pointer ) );
struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ); struct cons_pointer c_string_to_lisp_keyword( char32_t *symbol );
struct cons_pointer make_lambda( struct cons_pointer args, struct cons_pointer make_lambda( struct cons_pointer args,
struct cons_pointer body ); struct cons_pointer body );
@ -805,8 +805,8 @@ struct cons_pointer make_read_stream( URL_FILE * input,
struct cons_pointer make_write_stream( URL_FILE * output, struct cons_pointer make_write_stream( URL_FILE * output,
struct cons_pointer metadata ); struct cons_pointer metadata );
struct cons_pointer c_string_to_lisp_string( wchar_t *string ); struct cons_pointer c_string_to_lisp_string( char32_t *string );
struct cons_pointer c_string_to_lisp_symbol( wchar_t *symbol ); struct cons_pointer c_string_to_lisp_symbol( char32_t *symbol );
#endif #endif

View file

@ -29,7 +29,7 @@
#include "memory/vectorspace.h" #include "memory/vectorspace.h"
void dump_string_cell( URL_FILE *output, wchar_t *prefix, void dump_string_cell( URL_FILE *output, char32_t *prefix,
struct cons_pointer pointer ) { struct cons_pointer pointer ) {
struct cons_space_object cell = pointer2cell( pointer ); struct cons_space_object cell = pointer2cell( pointer );
if ( cell.payload.string.character == 0 ) { if ( cell.payload.string.character == 0 ) {

View file

@ -19,7 +19,7 @@
#ifndef __dump_h #ifndef __dump_h
#define __dump_h #define __dump_h
void dump_string_cell( URL_FILE * output, wchar_t *prefix, void dump_string_cell( URL_FILE * output, char32_t *prefix,
struct cons_pointer pointer ); struct cons_pointer pointer );
void dump_object( URL_FILE * output, struct cons_pointer pointer ); void dump_object( URL_FILE * output, struct cons_pointer pointer );

View file

@ -369,7 +369,7 @@ bool c_equal( struct cons_pointer a, struct cons_pointer b ) {
* iteration (and even that is problematic) */ * iteration (and even that is problematic) */
if ( cell_a->payload.string.hash == if ( cell_a->payload.string.hash ==
cell_b->payload.string.hash ) { cell_b->payload.string.hash ) {
wchar_t a_buff[STRING_SHIPYARD_SIZE], char32_t a_buff[STRING_SHIPYARD_SIZE],
b_buff[STRING_SHIPYARD_SIZE]; b_buff[STRING_SHIPYARD_SIZE];
uint32_t tag = cell_a->tag.value; uint32_t tag = cell_a->tag.value;
int i = 0; int i = 0;

View file

@ -502,8 +502,8 @@ c_apply( struct stack_frame *frame, struct cons_pointer frame_pointer,
default: default:
{ {
int bs = sizeof( wchar_t ) * 1024; int bs = sizeof( char32_t ) * 1024;
wchar_t *buffer = malloc( bs ); char32_t *buffer = malloc( bs );
memset( buffer, '\0', bs ); memset( buffer, '\0', bs );
swprintf( buffer, bs, swprintf( buffer, bs,
L"Unexpected cell with tag %d (%4.4s) in function position", L"Unexpected cell with tag %d (%4.4s) in function position",

View file

@ -99,7 +99,7 @@ struct cons_pointer time_to_string( struct cons_pointer pointer ) {
if ( t != 0 ) { if ( t != 0 ) {
char *bytes = ctime( &t ); char *bytes = ctime( &t );
int l = strlen( bytes ) + 1; int l = strlen( bytes ) + 1;
wchar_t buffer[l]; char32_t buffer[l];
mbstowcs( buffer, bytes, l ); mbstowcs( buffer, bytes, l );
result = c_string_to_lisp_string( buffer ); result = c_string_to_lisp_string( buffer );

View file

@ -1,12 +1,32 @@
# State of Play # State of Play
## 20260420
Still on side projects, but those side-projects are giving me thinking time;
and over the past few days I've logged four issues that I've tagged
[`Architecture change`](https://git.journeyman.cc/simon/post-scarcity/issues?q=&type=all&state=open&labels=15&milestone=0&assignee=0&poster=0).
These are:
* 17: [Add readtables; implement quote and keyword through readtables.](https://git.journeyman.cc/simon/post-scarcity/issues/17)
* 18: [Consider converting from `char32_t` to `char32_t`, everywhere.](https://git.journeyman.cc/simon/post-scarcity/issues/18)
* 20: [Environment in stack frame.](https://git.journeyman.cc/simon/post-scarcity/issues/20)
* 21: [Temporary objects in a function must be bound to a locals slot in the stack frame](https://git.journeyman.cc/simon/post-scarcity/issues/21)
These, especially the last, mean a fundamental change not only to the Lisp calling convention, but also to everything which may create objects — even if they're never expected to be called directly from Lisp. Generally, **every** such thing must be called with the standard Lisp calling convention (and so potentially could be called directly from Lisp), except for those very rare things where calling them with the standard calling convention would cause a runaway infinite recursion (the obvious ones are the constructors for `stack_frame` and `cons`, but there may be others); and the Lisp calling convention has to change. Which means a lot of things which have already been written for `0.1.0` have to change.
So I have this morning started a new feature branch, `feature/reengineering-17-21`, to work on these four issues together; and I think the first thing to do is to audit the existing code for functions that are affected by these changes (I mean: *every* Lisp-callable function is affected by 20, but apart from that). This may also resolve the `[MANAGED_POINTER_ONLY](https://git.journeyman.cc/simon/post-scarcity/src/commit/812a1be7d9eb97c25aa07477eb71605b1af93397/src/c/payloads/function.h#L16)` issue (see [20260415](#20260415)). I *may* leave that in as a compile time switch because passing the unmanaged pointer is certainly a performance optimisation, but it will make writing the compiler a bit harder.
I'm not ignoring the fact that a lot of stuff in `0.1.0` is still fundamentally broken, and the REPL still doesn't work; but getting the calling convention right at this point is still the right thing to do, and won't make any of those problems worse. Indeed, it may resolve some of them.
I think this week is going to be mostly a thinking week — partly because the weather forecast is unusually benign, and it would be sensible get some outdoor work done.
## 20260415 ## 20260415
OK, I have been diverted down a side-project on a side-project. I decided OK, I have been diverted down a side-project on a side-project. I decided
that since Post Scarcity definitely needs a compiler, I should learn to write that since Post Scarcity definitely needs a compiler, I should learn to write
a compiler, and so I should start by writing one for a simpler Lisp than Post a compiler, and so I should start by writing one for a simpler Lisp than Post
Scarcity. So I started to write Scarcity. So I started to write [one in Guile Scheme for Beowulf](https://git.journeyman.cc/simon/naegling).
[one in Guile Scheme for Beowulf](https://git.journeyman.cc/simon/naegling).
This is started but a long way from finished. I'm also not very enamoured of This is started but a long way from finished. I'm also not very enamoured of
Guile Scheme, and am starting to wonder whether in fact I should be writing Guile Scheme, and am starting to wonder whether in fact I should be writing
if in [Beowulf](https://git.journeyman.cc/simon/beowulf) for Beowulf. if in [Beowulf](https://git.journeyman.cc/simon/beowulf) for Beowulf.
@ -75,7 +95,7 @@ managed pointer is cheap, it isn't free.
But it's worth thinking about. But it's worth thinking about.
## 20260331 ## 20260331
Substrate layer `print` is written; all the building blocks for substrate Substrate layer `print` is written; all the building blocks for substrate

View file

@ -37,7 +37,7 @@ int verbosity = 0;
* `level` is non-zero, print this `message`, else don't. * `level` is non-zero, print this `message`, else don't.
* @param indent print `indent` spaces before the message. * @param indent print `indent` spaces before the message.
*/ */
void debug_print( wchar_t *message, int level, int indent ) { void debug_print( char32_t *message, int level, int indent ) {
#ifdef DEBUG #ifdef DEBUG
if ( level & verbosity ) { if ( level & verbosity ) {
fwide( stderr, 1 ); fwide( stderr, 1 );
@ -116,7 +116,7 @@ void debug_println( int level ) {
* *
* Remaining arguments should match the slots in the format string. * Remaining arguments should match the slots in the format string.
*/ */
void debug_printf( int level, int indent, wchar_t *format, ... ) { void debug_printf( int level, int indent, char32_t *format, ... ) {
#ifdef DEBUG #ifdef DEBUG
if ( level & verbosity ) { if ( level & verbosity ) {
fwide( stderr, 1 ); fwide( stderr, 1 );
@ -172,7 +172,7 @@ void debug_dump_object( struct pso_pointer pointer, int level, int indent ) {
//void debug_print_binding( struct cons_pointer key, struct cons_pointer val, //void debug_print_binding( struct cons_pointer key, struct cons_pointer val,
// bool deep, int level, int indent ) { // bool deep, int level, int indent ) {
//#ifdef DEBUG //#ifdef DEBUG
// // wchar_t * depth = (deep ? L"Deep" : L"Shallow"); // // char32_t * depth = (deep ? L"Deep" : L"Shallow");
// //
// debug_print( ( deep ? L"Deep" : L"Shallow" ), level, indent ); // debug_print( ( deep ? L"Deep" : L"Shallow" ), level, indent );
// debug_print( L" binding `", level, indent ); // debug_print( L" binding `", level, indent );

View file

@ -20,6 +20,8 @@
/* /*
* wide characters * wide characters
*/ */
#include <uchar.h>
#include <uchar.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
@ -102,7 +104,7 @@
*/ */
extern int verbosity; extern int verbosity;
void debug_print( wchar_t *message, int level, int indent ); void debug_print( char32_t *message, int level, int indent );
void debug_print_object( struct pso_pointer object, int level, int indent ); void debug_print_object( struct pso_pointer object, int level, int indent );
@ -112,6 +114,6 @@ void debug_print_128bit( __int128_t n, int level );
void debug_println( int level ); void debug_println( int level );
void debug_printf( int level, int indent, wchar_t *format, ... ); void debug_printf( int level, int indent, char32_t *format, ... );
#endif #endif

View file

@ -18,6 +18,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#include <uchar.h>
#include <unistd.h> #include <unistd.h>
#include <uuid/uuid.h> #include <uuid/uuid.h>
/* /*
@ -149,6 +150,9 @@ int initialise_io( ) {
} }
struct pso_pointer initialise_default_streams( struct pso_pointer env ) { struct pso_pointer initialise_default_streams( struct pso_pointer env ) {
// todo: issue #21: should this have stack frame passed in?
// It's called in initialisation before everything else is set
// up, so **possibly** not?
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 );
@ -226,7 +230,7 @@ char *lisp_string_to_c_string( struct pso_pointer s ) {
len++; len++;
} }
wchar_t *buffer = calloc( len + 1, sizeof( wchar_t ) ); char32_t *buffer = calloc( len + 1, sizeof( char32_t ) );
/* worst case, one wide char = four utf bytes */ /* worst case, one wide char = four utf bytes */
result = calloc( ( len * 4 ) + 1, sizeof( char ) ); result = calloc( ( len * 4 ) + 1, sizeof( char ) );
@ -268,8 +272,8 @@ wint_t url_fgetwc( URL_FILE *input ) {
case CFTYPE_CURL:{ case CFTYPE_CURL:{
char *cbuff = char *cbuff =
calloc( sizeof( wchar_t ) + 2, sizeof( char ) ); calloc( sizeof( char32_t ) + 2, sizeof( char ) );
wchar_t *wbuff = calloc( 2, sizeof( wchar_t ) ); char32_t *wbuff = calloc( 2, sizeof( char32_t ) );
size_t count = 0; size_t count = 0;
@ -414,18 +418,20 @@ struct pso_pointer lisp_close( struct pso_pointer frame_pointer,
return result; return result;
} }
struct pso_pointer add_meta_integer( struct pso_pointer meta, wchar_t *key, struct pso_pointer add_meta_integer( struct pso_pointer meta, char32_t *key,
long int value ) { long int value ) {
// todo: issue #21: must have stack frame passed in.
return return
c_cons( c_cons c_cons( c_cons
( c_string_to_lisp_keyword( key ), make_integer( value ) ), ( c_string_to_lisp_keyword( key ), make_integer( value ) ),
meta ); meta );
} }
struct pso_pointer add_meta_string( struct pso_pointer meta, wchar_t *key, struct pso_pointer add_meta_string( struct pso_pointer meta, char32_t *key,
char *value ) { char *value ) {
// todo: issue #21: must have stack frame passed in.
value = trim( value ); value = trim( value );
wchar_t buffer[strlen( value ) + 1]; char32_t buffer[strlen( value ) + 1];
mbstowcs( buffer, value, strlen( value ) + 1 ); mbstowcs( buffer, value, strlen( value ) + 1 );
return return
@ -434,10 +440,9 @@ struct pso_pointer add_meta_string( struct pso_pointer meta, wchar_t *key,
c_string_to_lisp_string( buffer ) ), meta ); c_string_to_lisp_string( buffer ) ), meta );
} }
struct pso_pointer add_meta_time( struct pso_pointer meta, wchar_t *key, struct pso_pointer add_meta_time( struct pso_pointer meta, char32_t *key,
time_t *value ) { time_t *value ) {
/* I don't yet have a concept of a date-time object, which is a // todo: issue #21: must have stack frame passed in.
* bit of an oversight! */
char datestring[256]; char datestring[256];
strftime( datestring, sizeof( datestring ), nl_langinfo( D_T_FMT ), strftime( datestring, sizeof( datestring ), nl_langinfo( D_T_FMT ),
@ -469,7 +474,7 @@ static size_t write_meta_callback( char *string, size_t size, size_t nmemb,
// s[offset] = ( char ) 0; // s[offset] = ( char ) 0;
// char *name = trim( s ); // char *name = trim( s );
// char *value = trim( &s[++offset] ); // char *value = trim( &s[++offset] );
// wchar_t wname[strlen( name )]; // char32_t wname[strlen( name )];
// mbstowcs( wname, name, strlen( name ) + 1 ); // mbstowcs( wname, name, strlen( name ) + 1 );
@ -716,7 +721,7 @@ struct pso_pointer lisp_slurp( struct pso_pointer frame_pointer,
debug_println( DEBUG_IO ); debug_println( DEBUG_IO );
struct pso2 *cell = pointer_to_object( cursor ); struct pso2 *cell = pointer_to_object( cursor );
cursor = make_string( ( wchar_t ) c, nil ); cursor = make_string( ( char32_t ) c, nil );
cell->payload.string.cdr = cursor; cell->payload.string.cdr = cursor;
} }
} }

View file

@ -20,6 +20,7 @@
/* /*
* wide characters * wide characters
*/ */
#include <uchar.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
/* libcurl, used for io */ /* libcurl, used for io */
@ -54,7 +55,7 @@ struct pso_pointer in_write(struct pso_pointer p, URL_FILE *output,
* TODO: this does not yet even nearly cope with all the possible special * TODO: this does not yet even nearly cope with all the possible special
* cases. * cases.
*/ */
void write_char( wchar_t wc, URL_FILE * output, bool escape) { void write_char( char32_t wc, URL_FILE * output, bool escape) {
if (escape && !iswprint(wc)) { if (escape && !iswprint(wc)) {
url_fwprintf(output, L"\\%04x", wc); url_fwprintf(output, L"\\%04x", wc);
// url_fputwc(L'\\', output); // url_fputwc(L'\\', output);
@ -79,7 +80,7 @@ struct pso_pointer print_string_like_thing(struct pso_pointer p,
if (keywordp(p) || stringp(p) || symbolp(p)) { if (keywordp(p) || stringp(p) || symbolp(p)) {
for (struct pso_pointer cursor = p; !nilp(cursor); for (struct pso_pointer cursor = p; !nilp(cursor);
cursor = pointer_to_object(cursor)->payload.string.cdr) { cursor = pointer_to_object(cursor)->payload.string.cdr) {
wchar_t wc = pointer_to_object(cursor)->payload.string.character; char32_t wc = pointer_to_object(cursor)->payload.string.character;
write_char( wc, output, escape); write_char( wc, output, escape);
} }

View file

@ -118,7 +118,7 @@ struct pso_pointer read_number(
if ( nilp( character ) ) { if ( nilp( character ) ) {
character = get_character( stream ); character = get_character( stream );
} }
wchar_t c = nilp( character ) char32_t c = nilp( character )
? 0 : pointer_to_object( character )->payload.character.character; ? 0 : pointer_to_object( character )->payload.character.character;
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream; URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;
@ -150,7 +150,7 @@ struct pso_pointer read_symbol(
character = get_character( stream ); character = get_character( stream );
} }
wchar_t c = nilp( character ) char32_t c = nilp( character )
? 0 : pointer_to_object( character )->payload.character.character; ? 0 : pointer_to_object( character )->payload.character.character;
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream; URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;
@ -207,7 +207,7 @@ struct pso_pointer read(
if ( !nilp( readmacro ) ) { if ( !nilp( readmacro ) ) {
// invoke the read macro on the stream // invoke the read macro on the stream
} else if ( readp( stream ) && characterp( character ) ) { } else if ( readp( stream ) && characterp( character ) ) {
wchar_t c = char32_t c =
pointer_to_object( character )->payload.character.character; pointer_to_object( character )->payload.character.character;
URL_FILE *input = pointer_to_object( stream )->payload.stream.stream; URL_FILE *input = pointer_to_object( stream )->payload.stream.stream;

View file

@ -41,6 +41,7 @@
* @return struct pso_pointer a pointer to the newly allocated object * @return struct pso_pointer a pointer to the newly allocated object
*/ */
struct pso_pointer allocate( char *tag, uint8_t size_class ) { struct pso_pointer allocate( char *tag, uint8_t size_class ) {
// todo: issue #21: must have stack frame passed in.
// `t`, because if `allocate_page` fails it will be set to `nil`. // `t`, because if `allocate_page` fails it will be set to `nil`.
struct pso_pointer result = t; struct pso_pointer result = t;

View file

@ -15,6 +15,7 @@
#include "memory/header.h" #include "memory/header.h"
#include "memory/pointer.h" #include "memory/pointer.h"
// todo: issue #21: must have stack frame passed in.
struct pso_pointer allocate( char *tag, uint8_t size_class ); struct pso_pointer allocate( char *tag, uint8_t size_class );
struct pso_pointer dec_ref( struct pso_pointer pointer ); struct pso_pointer dec_ref( struct pso_pointer pointer );

View file

@ -37,7 +37,7 @@ struct pso_pointer get_tag_string( struct pso_pointer p ) {
for ( int i = 2 - 1; i >= 0; i-- ) { for ( int i = 2 - 1; i >= 0; i-- ) {
result = result =
make_string( ( wchar_t ) ( object->header.tag.bytes.mnemonic[i] ), make_string( ( char32_t ) ( object->header.tag.bytes.mnemonic[i] ),
result ); result );
} }

View file

@ -41,5 +41,6 @@ struct pso_pointer lisp_bind(
struct pso_pointer c_bind( struct pso_pointer key, struct pso_pointer c_bind( struct pso_pointer key,
struct pso_pointer value, struct pso_pointer value,
struct pso_pointer store ) { struct pso_pointer store ) {
// todo: issue #21: must have stack frame passed in.
return c_cons( c_cons( key, value ), store ); return c_cons( c_cons( key, value ), store );
} }

View file

@ -48,6 +48,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( bool show_prompt ) { void c_repl( bool show_prompt ) {
// todo: issue #21: must have stack frame passed in.
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 );

View file

@ -13,7 +13,7 @@
#define SRC_C_OPS_REPL_H_ #define SRC_C_OPS_REPL_H_
// todo: issue #21: must have stack frame passed in.
void c_repl( ); void c_repl( );

View file

@ -36,6 +36,7 @@
* the argument was not a sequence. * the argument was not a sequence.
*/ */
struct pso_pointer c_reverse( struct pso_pointer sequence ) { struct pso_pointer c_reverse( struct pso_pointer sequence ) {
// todo: issue #21: must have stack frame passed in.
struct pso_pointer result = nil; struct pso_pointer result = nil;
for ( struct pso_pointer cursor = sequence; !nilp( sequence ); for ( struct pso_pointer cursor = sequence; !nilp( sequence );

View file

@ -66,7 +66,7 @@ uint32_t calculate_hash( wint_t c, struct pso_pointer ptr ) {
* pointer to next is nil. * pointer to next is nil.
* *
* NOTE THAT: in 0.1.X, we may allocate symbols and keywords as arrays of * NOTE THAT: in 0.1.X, we may allocate symbols and keywords as arrays of
* wchar_t in larger pso classes, so this function may be only for strings * char32_t in larger pso classes, so this function may be only for strings
* (and thus simpler). * (and thus simpler).
*/ */
struct pso_pointer make_string_like_thing( wint_t c, struct pso_pointer tail, struct pso_pointer make_string_like_thing( wint_t c, struct pso_pointer tail,
@ -138,7 +138,7 @@ struct pso_pointer make_symbol( wint_t c, struct pso_pointer tail ) {
/** /**
* Return a lisp string representation of this wide character string. * Return a lisp string representation of this wide character string.
*/ */
struct pso_pointer c_string_to_lisp_string( wchar_t *string ) { struct pso_pointer c_string_to_lisp_string( char32_t *string ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
for ( int i = wcslen( string ) - 1; i >= 0; i-- ) { for ( int i = wcslen( string ) - 1; i >= 0; i-- ) {
@ -157,11 +157,11 @@ struct pso_pointer c_string_to_lisp_string( wchar_t *string ) {
* Return a lisp symbol representation of this wide character string. In * Return a lisp symbol representation of this wide character string. In
* symbols, I am accepting only lower case characters. * symbols, I am accepting only lower case characters.
*/ */
struct pso_pointer c_string_to_lisp_symbol( wchar_t *symbol ) { struct pso_pointer c_string_to_lisp_symbol( char32_t *symbol ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) { for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
wchar_t c = towlower( symbol[i] ); char32_t c = towlower( symbol[i] );
if ( iswalpha( c ) || c == L'-' || c == L'*' ) { if ( iswalpha( c ) || c == L'-' || c == L'*' ) {
result = make_symbol( c, result ); result = make_symbol( c, result );
@ -175,11 +175,11 @@ struct pso_pointer c_string_to_lisp_symbol( wchar_t *symbol ) {
* Return a lisp keyword representation of this wide character string. In * Return a lisp keyword representation of this wide character string. In
* keywords, I am accepting only lower case characters and numbers. * keywords, I am accepting only lower case characters and numbers.
*/ */
struct pso_pointer c_string_to_lisp_keyword( wchar_t *symbol ) { struct pso_pointer c_string_to_lisp_keyword( char32_t *symbol ) {
struct pso_pointer result = nil; struct pso_pointer result = nil;
for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) { for ( int i = wcslen( symbol ) - 1; i >= 0; i-- ) {
wchar_t c = towlower( symbol[i] ); char32_t c = towlower( symbol[i] );
if ( iswalnum( c ) || c == L'-' ) { if ( iswalnum( c ) || c == L'-' ) {
result = make_keyword( c, result ); result = make_keyword( c, result );

View file

@ -13,6 +13,7 @@
/* /*
* wide characters * wide characters
*/ */
#include <uchar.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
@ -25,10 +26,10 @@ struct pso_pointer make_keyword( wint_t c, struct pso_pointer tail );
struct pso_pointer make_symbol( wint_t c, struct pso_pointer tail ); struct pso_pointer make_symbol( wint_t c, struct pso_pointer tail );
struct pso_pointer c_string_to_lisp_string( wchar_t *string ); struct pso_pointer c_string_to_lisp_string( char32_t *string );
struct pso_pointer c_string_to_lisp_keyword( wchar_t *symbol ); struct pso_pointer c_string_to_lisp_keyword( char32_t *symbol );
struct pso_pointer c_string_to_lisp_symbol( wchar_t *symbol ); struct pso_pointer c_string_to_lisp_symbol( char32_t *symbol );
#endif #endif

View file

@ -10,6 +10,7 @@
/* /*
* wide characters * wide characters
*/ */
#include <uchar.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
@ -28,7 +29,7 @@ struct pso_pointer make_character( wint_t c ) {
if ( !nilp( result ) ) { if ( !nilp( result ) ) {
pointer_to_object( result )->payload.character.character = pointer_to_object( result )->payload.character.character =
( wchar_t ) c; ( char32_t ) c;
} }
return result; return result;

View file

@ -22,6 +22,7 @@
/* /*
* wide characters * wide characters
*/ */
#include <uchar.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
@ -33,7 +34,7 @@
* @brief a single character, as returned by the reader. * @brief a single character, as returned by the reader.
*/ */
struct character_payload { struct character_payload {
wchar_t character; char32_t character;
}; };
struct pso_pointer make_character( wint_t c ); struct pso_pointer make_character( wint_t c );

View file

@ -30,7 +30,8 @@
* @param cdr the pointer which should form the cdr of this cons cell. * @param cdr the pointer which should form the cdr of this cons cell.
* @return struct pso_pointer a pointer to the newly allocated cons cell. * @return struct pso_pointer a pointer to the newly allocated cons cell.
*/ */
struct pso_pointer c_cons( struct pso_pointer car, struct pso_pointer cdr ) { struct pso_pointer c_cons(struct pso_pointer car, struct pso_pointer cdr) {
// todo: issue #21: must have stack frame passed in.
struct pso_pointer result = allocate( CONSTAG, 2 ); struct pso_pointer result = allocate( CONSTAG, 2 );
struct pso2 *object = pointer_to_object( result ); struct pso2 *object = pointer_to_object( result );
@ -67,7 +68,8 @@ struct pso_pointer c_car( struct pso_pointer cons ) {
* @return the cdr of the indicated cell. * @return the cdr of the indicated cell.
* @exception if the pointer does not indicate a cons cell. * @exception if the pointer does not indicate a cons cell.
*/ */
struct pso_pointer c_cdr( struct pso_pointer p ) { struct pso_pointer c_cdr(struct pso_pointer p) {
// todo: issue #21: must have stack frame passed in.
struct pso_pointer result = nil; struct pso_pointer result = nil;
struct pso2 *object = pointer_to_object( p ); struct pso2 *object = pointer_to_object( p );

View file

@ -30,6 +30,7 @@ struct pso_pointer c_car( struct pso_pointer cons );
struct pso_pointer c_cdr( struct pso_pointer cons ); struct pso_pointer c_cdr( struct pso_pointer cons );
// todo: issue #21: must have stack frame passed in.
struct pso_pointer c_cons( struct pso_pointer car, struct pso_pointer cdr ); struct pso_pointer c_cons( struct pso_pointer car, struct pso_pointer cdr );
struct pso_pointer destroy_cons( struct pso_pointer fp, struct pso_pointer destroy_cons( struct pso_pointer fp,

View file

@ -33,6 +33,7 @@
*/ */
struct pso_pointer make_frame( int arg_count, struct pso_pointer previous, struct pso_pointer make_frame( int arg_count, struct pso_pointer previous,
... ) { ... ) {
// todo: issue #21: must have stack frame passed in.
va_list args; va_list args;
va_start( args, previous ); va_start( args, previous );

View file

@ -7,7 +7,7 @@ int main( int argc, char *argv[] ) {
fwide( stdin, 1 ); fwide( stdin, 1 );
fwide( stdout, 1 ); fwide( stdout, 1 );
for (wchar_t c = fgetwc( stdin ); !feof( stdin); c = fgetwc( stdin )) { for (char32_t c = fgetwc( stdin ); !feof( stdin); c = fgetwc( stdin )) {
if (c != '\n') { if (c != '\n') {
fwprintf( stdout, L"Read character %d, %C\t", (int)c, c); fwprintf( stdout, L"Read character %d, %C\t", (int)c, c);
fputwc( c, stdout); fputwc( c, stdout);