diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index 9141b406..10291097 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -126,8 +126,7 @@ object Cyc_string2symbol(object str); object Cyc_list2string(object cont, object lst); common_type Cyc_string2number(object str); void dispatch_string_91append(int argc, object clo, object cont, object str1, ...); -string_type Cyc_string_append(int argc, object str1, ...); -string_type Cyc_string_append_va_list(int argc, object str1, va_list ap); +object Cyc_string_append(int argc, object cont, object str1, ...); integer_type Cyc_string_length(object str); object Cyc_substring(object cont, object str, object start, object end); object Cyc_string_ref(object str, object k); diff --git a/runtime.c b/runtime.c index 828475d7..5b87b259 100644 --- a/runtime.c +++ b/runtime.c @@ -930,59 +930,47 @@ integer_type Cyc_string_cmp(object str1, object str2) { } } -void dispatch_string_91append(int argc, object clo, object cont, object str1, ...) { +#define Cyc_string_append_va_list(argc) { \ + int i = 0, total_len = 1; \ + int *len = alloca(sizeof(int) * argc); \ + char *buffer, *bufferp, **str = alloca(sizeof(char *) * argc); \ + object tmp; \ + if (argc > 0) { \ + Cyc_check_str(str1); \ + str[i] = ((string_type *)str1)->str; \ + len[i] = strlen(str[i]); \ + total_len += len[i]; \ + } \ + for (i = 1; i < argc; i++) { \ + tmp = va_arg(ap, object); \ + Cyc_check_str(tmp); \ + str[i] = ((string_type *)tmp)->str; \ + len[i] = strlen(str[i]); \ + total_len += len[i]; \ + } \ + buffer = bufferp = alloca(sizeof(char) * total_len); \ + for (i = 0; i < argc; i++) { \ + memcpy(bufferp, str[i], len[i]); \ + bufferp += len[i]; \ + } \ + *bufferp = '\0'; \ + make_string(result, buffer); \ + va_end(ap); \ + return_closcall1(cont, &result); \ +} + +void dispatch_string_91append(int _argc, object clo, object cont, object str1, ...) { string_type result; va_list ap; va_start(ap, str1); - result = Cyc_string_append_va_list(argc - 1, str1, ap); - va_end(ap); - return_closcall1(cont, &result); + Cyc_string_append_va_list(_argc - 1); } -string_type Cyc_string_append(int argc, object str1, ...) { +object Cyc_string_append(int _argc, object cont, object str1, ...) { string_type result; va_list ap; va_start(ap, str1); - result = Cyc_string_append_va_list(argc, str1, ap); - va_end(ap); - return result; -} - -string_type Cyc_string_append_va_list(int argc, object str1, va_list ap) { - // TODO: one way to do this, perhaps not the most efficient: - // compute lengths of the strings, - // store lens and str ptrs - // allocate buffer, memcpy each str to buffer - // make_string using buffer - - int i = 0, total_len = 1; // for null char - int *len = alloca(sizeof(int) * argc); - char *buffer, *bufferp, **str = alloca(sizeof(char *) * argc); - object tmp; - - if (argc > 0) { - Cyc_check_str(str1); - str[i] = ((string_type *)str1)->str; - len[i] = strlen(str[i]); - total_len += len[i]; - } - - for (i = 1; i < argc; i++) { - tmp = va_arg(ap, object); - Cyc_check_str(tmp); - str[i] = ((string_type *)tmp)->str; - len[i] = strlen(str[i]); - total_len += len[i]; - } - - buffer = bufferp = alloca(sizeof(char) * total_len); - for (i = 0; i < argc; i++) { - memcpy(bufferp, str[i], len[i]); - bufferp += len[i]; - } - *bufferp = '\0'; - make_string(result, buffer); - return result; + Cyc_string_append_va_list(_argc); } integer_type Cyc_string_length(object str) { diff --git a/scheme/cyclone/cgen.sld b/scheme/cyclone/cgen.sld index 74cb0454..b1d7be0d 100644 --- a/scheme/cyclone/cgen.sld +++ b/scheme/cyclone/cgen.sld @@ -574,7 +574,7 @@ ((eq? p '/) "common_type") ((eq? p 'string->number) "common_type") ((eq? p 'string-cmp) "integer_type") - ((eq? p 'string-append) "string_type") + ((eq? p 'string-append) "object") ((eq? p 'string-length) "integer_type") ((eq? p 'apply) "object") ((eq? p 'Cyc-read-line) "object") @@ -614,14 +614,14 @@ (define (prim:cont? exp) (and (prim? exp) (member exp '(Cyc-read-line apply command-line-arguments number->string - symbol->string list->string substring + symbol->string list->string substring string-append make-vector list->vector Cyc-installation-dir)))) ;; TODO: this is a hack, right answer is to include information about ;; how many args each primitive is supposed to take (define (prim:cont-has-args? exp) (and (prim? exp) (member exp '(Cyc-read-line apply number->string symbol->string - list->string substring + list->string substring string-append make-vector list->vector Cyc-installation-dir)))) ;; Pass an integer arg count as the function's first parameter?