diff options
author | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-10 16:16:39 +0100 |
---|---|---|
committer | Stephen Dolan <mu@netsoc.tcd.ie> | 2012-09-10 16:16:39 +0100 |
commit | 65ce73deb4eab4ef6d83a0ad44c603d6286e964d (patch) | |
tree | 01b93824048fa2a674d66bf84046e45f5af40cf8 | |
parent | e718bd50b63380a0be2c8f9ae7cb837bcf01c48e (diff) |
String concatenation.
-rw-r--r-- | c/builtin.c | 2 | ||||
-rw-r--r-- | c/jv.c | 21 | ||||
-rw-r--r-- | c/jv.h | 1 | ||||
-rw-r--r-- | c/testdata | 8 |
4 files changed, 32 insertions, 0 deletions
diff --git a/c/builtin.c b/c/builtin.c index 45056fc0..bdca2540 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -22,6 +22,8 @@ static void f_plus(jv input[], jv output[]) { if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) { output[0] = jv_number(jv_number_value(a) + jv_number_value(b)); + } else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) { + output[0] = jv_string_concat(a, b); } else if (jv_get_kind(a) == JV_KIND_ARRAY && jv_get_kind(b) == JV_KIND_ARRAY) { output[0] = jv_array_concat(a, b); } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) { @@ -355,6 +355,7 @@ static jv_complex jvp_string_new(const char* data, uint32_t length) { return r; } + static void jvp_string_free(jv_complex* s) { if (jvp_refcnt_dec(s)) { jvp_string* str = jvp_string_ptr(s); @@ -377,6 +378,16 @@ static uint32_t jvp_string_length(jvp_string* s) { return s->length_hashed >> 1; } +static jv_complex jvp_string_concat(jvp_string* a, jvp_string* b) { + uint32_t la = jvp_string_length(a), lb = jvp_string_length(b); + jvp_string* s = jvp_string_alloc(la + lb); + memcpy(s->data, a->data, la); + memcpy(s->data + la, b->data, lb); + s->data[la + lb] = 0; + jv_complex r = {&s->refcnt, {0,0}}; + return r; +} + static const uint32_t HASH_SEED = 0x432A9843; static uint32_t rotl32 (uint32_t x, int8_t r){ @@ -488,6 +499,16 @@ const char* jv_string_value(jv j) { return jvp_string_ptr(&j.val.complex)->data; } +jv jv_string_concat(jv a, jv b) { + jv j; + j.kind = JV_KIND_STRING; + j.val.complex = jvp_string_concat(jvp_string_ptr(&a.val.complex), + jvp_string_ptr(&b.val.complex)); + jv_free(a); + jv_free(b); + return j; +} + jv jv_string_fmt(const char* fmt, ...) { int size = 1024; while (1) { @@ -76,6 +76,7 @@ jv jv_string_sized(const char*, int); int jv_string_length(jv); uint32_t jv_string_hash(jv); const char* jv_string_value(jv); +jv jv_string_concat(jv, jv); jv jv_string_fmt(const char*, ...); jv jv_object(); @@ -159,6 +159,14 @@ null "asdfasdf" {"a":1, "b":2, "c":3} +"asdf" + "jkl;" + . +"some string" +"asdfjkl;some string" + +"\u0000\u0020\u0000" + . +"\u0000\u0020\u0000" +"\u0000 \u0000\u0000 \u0000" + # # User-defined functions # Oh god. |