Working on converting string_append to call into cont

This commit is contained in:
Justin Ethier 2015-10-12 22:49:31 -04:00
parent e6880850bc
commit 1bc65d99cd
3 changed files with 37 additions and 50 deletions

View file

@ -126,8 +126,7 @@ object Cyc_string2symbol(object str);
object Cyc_list2string(object cont, object lst); object Cyc_list2string(object cont, object lst);
common_type Cyc_string2number(object str); common_type Cyc_string2number(object str);
void dispatch_string_91append(int argc, object clo, object cont, object str1, ...); void dispatch_string_91append(int argc, object clo, object cont, object str1, ...);
string_type Cyc_string_append(int argc, object str1, ...); object Cyc_string_append(int argc, object cont, object str1, ...);
string_type Cyc_string_append_va_list(int argc, object str1, va_list ap);
integer_type Cyc_string_length(object str); integer_type Cyc_string_length(object str);
object Cyc_substring(object cont, object str, object start, object end); object Cyc_substring(object cont, object str, object start, object end);
object Cyc_string_ref(object str, object k); object Cyc_string_ref(object str, object k);

View file

@ -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; string_type result;
va_list ap; va_list ap;
va_start(ap, str1); va_start(ap, str1);
result = Cyc_string_append_va_list(argc - 1, str1, ap); Cyc_string_append_va_list(_argc - 1);
va_end(ap);
return_closcall1(cont, &result);
} }
string_type Cyc_string_append(int argc, object str1, ...) { object Cyc_string_append(int _argc, object cont, object str1, ...) {
string_type result; string_type result;
va_list ap; va_list ap;
va_start(ap, str1); va_start(ap, str1);
result = Cyc_string_append_va_list(argc, str1, ap); Cyc_string_append_va_list(_argc);
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;
} }
integer_type Cyc_string_length(object str) { integer_type Cyc_string_length(object str) {

View file

@ -574,7 +574,7 @@
((eq? p '/) "common_type") ((eq? p '/) "common_type")
((eq? p 'string->number) "common_type") ((eq? p 'string->number) "common_type")
((eq? p 'string-cmp) "integer_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 'string-length) "integer_type")
((eq? p 'apply) "object") ((eq? p 'apply) "object")
((eq? p 'Cyc-read-line) "object") ((eq? p 'Cyc-read-line) "object")
@ -614,14 +614,14 @@
(define (prim:cont? exp) (define (prim:cont? exp)
(and (prim? exp) (and (prim? exp)
(member exp '(Cyc-read-line apply command-line-arguments number->string (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)))) make-vector list->vector Cyc-installation-dir))))
;; TODO: this is a hack, right answer is to include information about ;; TODO: this is a hack, right answer is to include information about
;; how many args each primitive is supposed to take ;; how many args each primitive is supposed to take
(define (prim:cont-has-args? exp) (define (prim:cont-has-args? exp)
(and (prim? exp) (and (prim? exp)
(member exp '(Cyc-read-line apply number->string symbol->string (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)))) make-vector list->vector Cyc-installation-dir))))
;; Pass an integer arg count as the function's first parameter? ;; Pass an integer arg count as the function's first parameter?