1
- /* uLisp ESP Version 3.6 - www.ulisp.com
2
- David Johnson-Davies - www.technoblogy.com - 4th April 2021
1
+ /* uLisp ESP Version 3.6b - www.ulisp.com
2
+ David Johnson-Davies - www.technoblogy.com - 20th June 2021
3
3
4
4
Licensed under the MIT license: https://opensource.org/licenses/MIT
5
5
*/
@@ -226,6 +226,7 @@ object *apply (symbol_t name, object *function, object *args, object *env);
226
226
char *lookupsymbol (symbol_t name);
227
227
char *cstring (object *form, char *buffer, int buflen);
228
228
object *edit (object *fun);
229
+ void pfstring (PGM_P s, pfun_t pfun);
229
230
230
231
// Error handling
231
232
@@ -353,6 +354,13 @@ object *stream (uint8_t streamtype, uint8_t address) {
353
354
return ptr;
354
355
}
355
356
357
+ object *newstring () {
358
+ object *ptr = myalloc ();
359
+ ptr->type = STRING;
360
+ ptr->chars = 0 ;
361
+ return ptr;
362
+ }
363
+
356
364
// Garbage collection
357
365
358
366
void markobject (object *obj) {
@@ -993,21 +1001,20 @@ void indent (uint8_t spaces, char ch, pfun_t pfun) {
993
1001
}
994
1002
995
1003
object *startstring (symbol_t name) {
996
- object *string = myalloc ();
997
- string->type = STRING;
998
- GlobalString = NULL ;
1004
+ object *string = newstring ();
1005
+ GlobalString = string;
999
1006
GlobalStringIndex = 0 ;
1000
1007
return string;
1001
1008
}
1002
1009
1003
- void buildstring (uint8_t ch, int *chars, object **head ) {
1010
+ void buildstring (uint8_t ch, object *string, int *chars ) {
1004
1011
static object* tail;
1005
1012
static uint8_t shift;
1006
1013
if (*chars == 0 ) {
1007
1014
shift = (sizeof (int )-1 )*8 ;
1008
1015
*chars = ch<<shift;
1009
1016
object *cell = myalloc ();
1010
- if (*head == NULL ) *head = cell; else tail->car = cell;
1017
+ if (cdr (string) == NULL ) cdr (string) = cell; else tail->car = cell;
1011
1018
cell->car = NULL ;
1012
1019
cell->chars = *chars;
1013
1020
tail = cell;
@@ -1020,18 +1027,15 @@ void buildstring (uint8_t ch, int *chars, object **head) {
1020
1027
}
1021
1028
1022
1029
object *readstring (uint8_t delim, gfun_t gfun) {
1023
- object *obj = myalloc ();
1024
- obj->type = STRING;
1030
+ object *obj = newstring ();
1025
1031
int ch = gfun ();
1026
1032
if (ch == -1 ) return nil;
1027
- object *head = NULL ;
1028
1033
int chars = 0 ;
1029
1034
while ((ch != delim) && (ch != -1 )) {
1030
1035
if (ch == ' \\ ' ) ch = gfun ();
1031
- buildstring (ch, &chars , &head );
1036
+ buildstring (ch, obj , &chars );
1032
1037
ch = gfun ();
1033
1038
}
1034
- obj->cdr = head;
1035
1039
return obj;
1036
1040
}
1037
1041
@@ -1073,7 +1077,7 @@ int gstr () {
1073
1077
}
1074
1078
1075
1079
void pstr (char c) {
1076
- buildstring (c, &GlobalStringIndex , &GlobalString );
1080
+ buildstring (c, GlobalString , &GlobalStringIndex );
1077
1081
}
1078
1082
1079
1083
char *cstringbuf (object *arg) {
@@ -1100,17 +1104,14 @@ char *cstring (object *form, char *buffer, int buflen) {
1100
1104
}
1101
1105
1102
1106
object *lispstring (char *s) {
1103
- object *obj = myalloc ();
1104
- obj->type = STRING;
1107
+ object *obj = newstring ();
1105
1108
char ch = *s++;
1106
- object *head = NULL ;
1107
1109
int chars = 0 ;
1108
1110
while (ch) {
1109
1111
if (ch == ' \\ ' ) ch = *s++;
1110
- buildstring (ch, &chars , &head );
1112
+ buildstring (ch, obj , &chars );
1111
1113
ch = *s++;
1112
1114
}
1113
- obj->cdr = head;
1114
1115
return obj;
1115
1116
}
1116
1117
@@ -1857,10 +1858,10 @@ object *sp_withoutputtostring (object *args, object *env) {
1857
1858
object *pair = cons (var, stream (STRINGSTREAM, 0 ));
1858
1859
push (pair,env);
1859
1860
object *string = startstring (WITHOUTPUTTOSTRING);
1861
+ push (string, GCStack);
1860
1862
object *forms = cdr (args);
1861
1863
eval (tf_progn (forms,env), env);
1862
- string->cdr = GlobalString;
1863
- GlobalString = NULL ;
1864
+ pop (GCStack);
1864
1865
return string;
1865
1866
}
1866
1867
@@ -1887,7 +1888,7 @@ object *sp_withi2c (object *args, object *env) {
1887
1888
object *var = first (params);
1888
1889
int address = checkinteger (WITHI2C, eval (second (params), env));
1889
1890
params = cddr (params);
1890
- if (address == 0 ) params = cdr (params); // Ignore port
1891
+ if (address == 0 && params != NULL ) params = cdr (params); // Ignore port
1891
1892
int read = 0 ; // Write
1892
1893
I2CCount = 0 ;
1893
1894
if (params != NULL ) {
@@ -3066,8 +3067,7 @@ object *fn_stringfn (object *args, object *env) {
3066
3067
object *arg = first (args);
3067
3068
int type = arg->type ;
3068
3069
if (type == STRING) return arg;
3069
- object *obj = myalloc ();
3070
- obj->type = STRING;
3070
+ object *obj = newstring ();
3071
3071
if (type == CHARACTER) {
3072
3072
object *cell = myalloc ();
3073
3073
cell->car = NULL ;
@@ -3077,14 +3077,12 @@ object *fn_stringfn (object *args, object *env) {
3077
3077
} else if (type == SYMBOL) {
3078
3078
char *s = symbolname (arg->name );
3079
3079
char ch = *s++;
3080
- object *head = NULL ;
3081
3080
int chars = 0 ;
3082
3081
while (ch) {
3083
3082
if (ch == ' \\ ' ) ch = *s++;
3084
- buildstring (ch, &chars , &head );
3083
+ buildstring (ch, arg , &chars );
3085
3084
ch = *s++;
3086
3085
}
3087
- obj->cdr = head;
3088
3086
} else error (STRINGFN, PSTR (" can't convert to string" ), arg);
3089
3087
return obj;
3090
3088
}
@@ -3094,9 +3092,7 @@ object *fn_concatenate (object *args, object *env) {
3094
3092
object *arg = first (args);
3095
3093
if (arg->name != STRINGFN) error2 (CONCATENATE, PSTR (" only supports strings" ));
3096
3094
args = cdr (args);
3097
- object *result = myalloc ();
3098
- result->type = STRING;
3099
- object *head = NULL ;
3095
+ object *result = newstring ();
3100
3096
int chars = 0 ;
3101
3097
while (args != NULL ) {
3102
3098
object *obj = first (args);
@@ -3106,14 +3102,13 @@ object *fn_concatenate (object *args, object *env) {
3106
3102
int quad = obj->chars ;
3107
3103
while (quad != 0 ) {
3108
3104
char ch = quad>>((sizeof (int )-1 )*8 ) & 0xFF ;
3109
- buildstring (ch, &chars , &head );
3105
+ buildstring (ch, result , &chars );
3110
3106
quad = quad<<8 ;
3111
3107
}
3112
3108
obj = car (obj);
3113
3109
}
3114
3110
args = cdr (args);
3115
3111
}
3116
- result->cdr = head;
3117
3112
return result;
3118
3113
}
3119
3114
@@ -3126,16 +3121,13 @@ object *fn_subseq (object *args, object *env) {
3126
3121
int end;
3127
3122
args = cddr (args);
3128
3123
if (args != NULL ) end = checkinteger (SUBSEQ, car (args)); else end = stringlength (arg);
3129
- object *result = myalloc ();
3130
- result->type = STRING;
3131
- object *head = NULL ;
3124
+ object *result = newstring ();
3132
3125
int chars = 0 ;
3133
3126
for (int i=start; i<end; i++) {
3134
3127
char ch = nthchar (arg, i);
3135
3128
if (ch == 0 ) error2 (SUBSEQ, PSTR (" index out of range" ));
3136
- buildstring (ch, &chars , &head );
3129
+ buildstring (ch, result , &chars );
3137
3130
}
3138
- result->cdr = head;
3139
3131
return result;
3140
3132
}
3141
3133
@@ -3153,7 +3145,6 @@ object *fn_princtostring (object *args, object *env) {
3153
3145
object *arg = first (args);
3154
3146
object *obj = startstring (PRINCTOSTRING);
3155
3147
prin1object (arg, pstr);
3156
- obj->cdr = GlobalString;
3157
3148
return obj;
3158
3149
}
3159
3150
@@ -3162,7 +3153,6 @@ object *fn_prin1tostring (object *args, object *env) {
3162
3153
object *arg = first (args);
3163
3154
object *obj = startstring (PRIN1TOSTRING);
3164
3155
printobject (arg, pstr);
3165
- obj->cdr = GlobalString;
3166
3156
return obj;
3167
3157
}
3168
3158
@@ -3641,7 +3631,7 @@ object *fn_format (object *args, object *env) {
3641
3631
}
3642
3632
n++;
3643
3633
}
3644
- if (output == nil) { obj-> cdr = GlobalString; return obj; }
3634
+ if (output == nil) return obj;
3645
3635
else return nil;
3646
3636
}
3647
3637
0 commit comments