Skip to content

Instantly share code, notes, and snippets.

@danielmewes
Last active November 12, 2025 17:54
Show Gist options
  • Select an option

  • Save danielmewes/206c1fa66622f06f5976253365861c70 to your computer and use it in GitHub Desktop.

Select an option

Save danielmewes/206c1fa66622f06f5976253365861c70 to your computer and use it in GitHub Desktop.
with-output-to-string fix for uLisp
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