Last active
November 12, 2025 17:54
-
-
Save danielmewes/206c1fa66622f06f5976253365861c70 to your computer and use it in GitHub Desktop.
with-output-to-string fix for uLisp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/c99/ulisp.c b/c99/ulisp.c | |
| index 4318099..52a997e 100644 | |
| --- a/c99/ulisp.c | |
| +++ b/c99/ulisp.c | |
| @@ -275,6 +275,7 @@ object *GCStack = NULL; | |
| object *GlobalString; | |
| object *GlobalStringTail; | |
| int GlobalStringIndex = 0; | |
| +object *GlobalStringStreamTail = NULL; | |
| uint8_t PrintCount = 0; | |
| uint8_t BreakLevel = 0; | |
| char LastChar = 0; | |
| @@ -332,6 +333,7 @@ bool keywordp (object *obj); | |
| int stringcompare (object *args, bool lt, bool gt, bool eq); | |
| object *eval (object *form, object *env); | |
| void pstr (char c); | |
| +void pstrstream (char c); | |
| object *findpair (object *var, object *env); | |
| char *lookupdoc (builtin_t name); | |
| char *cstring (object *form, char *buffer, int buflen); | |
| @@ -535,7 +537,11 @@ void errorsub (symbol_t fname, const char *string) { | |
| pfstring(string, pserial); | |
| } | |
| -void errorend () { GCStack = NULL; longjmp(*handler, 1); } | |
| +void errorend () { | |
| + GCStack = NULL; | |
| + GlobalStringStreamTail = NULL; | |
| + longjmp(*handler, 1); | |
| +} | |
| /* | |
| errorsym - prints an error message and reenters the REPL. | |
| @@ -616,6 +618,8 @@ const char indexrange[] = "index out of range"; | |
| const char canttakecar[] = "can't take car"; | |
| const char canttakecdr[] = "can't take cdr"; | |
| const char unknownstreamtype[] = "unknown stream type"; | |
| +const char streamalreadyopen[] = "stream already open"; | |
| +const char streamclosed[] = "stream has been closed"; | |
| // Set up workspace | |
| @@ -2008,7 +2012,7 @@ uint8_t nthchar (object *string, int n) { | |
| } | |
| /* | |
| - gstr - reads a character from a string stream | |
| + gstr - reads a character from the global string | |
| */ | |
| int gstr () { | |
| if (LastChar) { | |
| @@ -2022,12 +2026,19 @@ int gstr () { | |
| } | |
| /* | |
| - pstr - prints a character to a string stream | |
| + pstr - prints a character to the global string | |
| */ | |
| void pstr (char c) { | |
| buildstring(c, &GlobalStringTail); | |
| } | |
| +/* | |
| + pstrstream - prints a character to a string stream | |
| +*/ | |
| +void pstrstream (char c) { | |
| + buildstring(c, &GlobalStringStreamTail); | |
| +} | |
| + | |
| /* | |
| lispstring - converts a C string to a Lisp string | |
| */ | |
| @@ -2705,7 +2716,8 @@ pfun_t pfun_serial (uint8_t address) { | |
| pfun_t pfun_string (uint8_t address) { | |
| (void) address; | |
| - return pstr; | |
| + if (GlobalStringStreamTail == NULL) error2(streamclosed); | |
| + return pstrstream; | |
| } | |
| pfun_t pfun_sd (uint8_t address) { | |
| @@ -3450,14 +3462,17 @@ object *sp_time (object *args, object *env) { | |
| */ | |
| object *sp_withoutputtostring (object *args, object *env) { | |
| object *params = checkarguments(args, 1, 1); | |
| + if (GlobalStringStreamTail != NULL) error2(streamalreadyopen); | |
| object *var = first(params); | |
| object *pair = cons(var, stream(STRINGSTREAM, 0)); | |
| push(pair,env); | |
| - object *string = startstring(); | |
| + object *string = newstring(); | |
| + GlobalStringStreamTail = string; | |
| protect(string); | |
| object *forms = cdr(args); | |
| eval(tf_progn(forms,env), env); | |
| unprotect(); | |
| + GlobalStringStreamTail = NULL; | |
| return string; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment