From bda9ad880a3575c22ec69bfb531fb9e433ebfb93 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Thu, 10 Sep 2015 23:52:18 -0700 Subject: [PATCH] Flesh out string byte handling a bit: - Get rid of public byteAt(_) method on strings. It's redundant and longer than .bytes[_]. - Implement bytes.count natively so it's O(1). --- builtin/core.wren | 6 ++-- src/vm/wren_core.c | 14 +++++++-- test/core/string/byte_at.wren | 38 ----------------------- test/core/string/byte_at_not_int.wren | 1 - test/core/string/byte_at_not_num.wren | 1 - test/core/string/byte_at_too_large.wren | 1 - test/core/string/byte_at_too_small.wren | 1 - test/core/string_byte_sequence/count.wren | 15 +++++++++ test/language/string/byte_escapes.wren | 20 ++++++------ 9 files changed, 40 insertions(+), 57 deletions(-) delete mode 100644 test/core/string/byte_at.wren delete mode 100644 test/core/string/byte_at_not_int.wren delete mode 100644 test/core/string/byte_at_not_num.wren delete mode 100644 test/core/string/byte_at_too_large.wren delete mode 100644 test/core/string/byte_at_too_small.wren create mode 100644 test/core/string_byte_sequence/count.wren diff --git a/builtin/core.wren b/builtin/core.wren index 4186e200..3dd35156 100644 --- a/builtin/core.wren +++ b/builtin/core.wren @@ -137,9 +137,11 @@ class StringByteSequence is Sequence { _string = string } - [index] { _string.byteAt(index) } + [index] { _string.byteAt_(index) } iterate(iterator) { _string.iterateByte_(iterator) } - iteratorValue(iterator) { _string.byteAt(iterator) } + iteratorValue(iterator) { _string.byteAt_(iterator) } + + count { _string.byteCount_ } } class List is Sequence { diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index 8484ae6c..2250f9f1 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -151,9 +151,11 @@ static const char* coreLibSource = " _string = string\n" " }\n" "\n" -" [index] { _string.byteAt(index) }\n" +" [index] { _string.byteAt_(index) }\n" " iterate(iterator) { _string.iterateByte_(iterator) }\n" -" iteratorValue(iterator) { _string.byteAt(iterator) }\n" +" iteratorValue(iterator) { _string.byteAt_(iterator) }\n" +"\n" +" count { _string.byteCount_ }\n" "}\n" "\n" "class List is Sequence {\n" @@ -1079,6 +1081,11 @@ DEF_PRIMITIVE(string_byteAt) RETURN_NUM((uint8_t)string->value[index]); } +DEF_PRIMITIVE(string_byteCount) +{ + RETURN_NUM(AS_STRING(args[0])->length); +} + DEF_PRIMITIVE(string_codePointAt) { ObjString* string = AS_STRING(args[0]); @@ -1409,7 +1416,8 @@ void wrenInitializeCore(WrenVM* vm) PRIMITIVE(vm->stringClass->obj.classObj, "fromCodePoint(_)", string_fromCodePoint); PRIMITIVE(vm->stringClass, "+(_)", string_plus); PRIMITIVE(vm->stringClass, "[_]", string_subscript); - PRIMITIVE(vm->stringClass, "byteAt(_)", string_byteAt); + PRIMITIVE(vm->stringClass, "byteAt_(_)", string_byteAt); + PRIMITIVE(vm->stringClass, "byteCount_", string_byteCount); PRIMITIVE(vm->stringClass, "codePointAt(_)", string_codePointAt); PRIMITIVE(vm->stringClass, "contains(_)", string_contains); PRIMITIVE(vm->stringClass, "count", string_count); diff --git a/test/core/string/byte_at.wren b/test/core/string/byte_at.wren deleted file mode 100644 index cf2c20e5..00000000 --- a/test/core/string/byte_at.wren +++ /dev/null @@ -1,38 +0,0 @@ -// Bytes: 11111 -// 012345678901234 -// Chars: sø mé ஃ thî ng -var s = "søméஃthîng" - -IO.print(s.byteAt(0)) // expect: 115 -IO.print(s.byteAt(1)) // expect: 195 -IO.print(s.byteAt(2)) // expect: 184 -IO.print(s.byteAt(3)) // expect: 109 -IO.print(s.byteAt(4)) // expect: 195 -IO.print(s.byteAt(5)) // expect: 169 -IO.print(s.byteAt(6)) // expect: 224 -IO.print(s.byteAt(7)) // expect: 174 -IO.print(s.byteAt(8)) // expect: 131 -IO.print(s.byteAt(9)) // expect: 116 -IO.print(s.byteAt(10)) // expect: 104 -IO.print(s.byteAt(11)) // expect: 195 -IO.print(s.byteAt(12)) // expect: 174 -IO.print(s.byteAt(13)) // expect: 110 -IO.print(s.byteAt(14)) // expect: 103 - -IO.print(s.byteAt(-15)) // expect: 115 -IO.print(s.byteAt(-14)) // expect: 195 -IO.print(s.byteAt(-13)) // expect: 184 -IO.print(s.byteAt(-12)) // expect: 109 -IO.print(s.byteAt(-11)) // expect: 195 -IO.print(s.byteAt(-10)) // expect: 169 -IO.print(s.byteAt(-9)) // expect: 224 -IO.print(s.byteAt(-8)) // expect: 174 -IO.print(s.byteAt(-7)) // expect: 131 -IO.print(s.byteAt(-6)) // expect: 116 -IO.print(s.byteAt(-5)) // expect: 104 -IO.print(s.byteAt(-4)) // expect: 195 -IO.print(s.byteAt(-3)) // expect: 174 -IO.print(s.byteAt(-2)) // expect: 110 -IO.print(s.byteAt(-1)) // expect: 103 - -IO.print("\0".byteAt(0)) // expect: 0 diff --git a/test/core/string/byte_at_not_int.wren b/test/core/string/byte_at_not_int.wren deleted file mode 100644 index d9e22b8a..00000000 --- a/test/core/string/byte_at_not_int.wren +++ /dev/null @@ -1 +0,0 @@ -IO.print("string".byteAt(12.34)) // expect runtime error: Index must be an integer. diff --git a/test/core/string/byte_at_not_num.wren b/test/core/string/byte_at_not_num.wren deleted file mode 100644 index 23e5c7c3..00000000 --- a/test/core/string/byte_at_not_num.wren +++ /dev/null @@ -1 +0,0 @@ -IO.print("string".byteAt("not num")) // expect runtime error: Index must be a number. diff --git a/test/core/string/byte_at_too_large.wren b/test/core/string/byte_at_too_large.wren deleted file mode 100644 index 365687f9..00000000 --- a/test/core/string/byte_at_too_large.wren +++ /dev/null @@ -1 +0,0 @@ -IO.print("string".byteAt(6)) // expect runtime error: Index out of bounds. diff --git a/test/core/string/byte_at_too_small.wren b/test/core/string/byte_at_too_small.wren deleted file mode 100644 index 2a83555f..00000000 --- a/test/core/string/byte_at_too_small.wren +++ /dev/null @@ -1 +0,0 @@ -IO.print("string".byteAt(-7)) // expect runtime error: Index out of bounds. diff --git a/test/core/string_byte_sequence/count.wren b/test/core/string_byte_sequence/count.wren new file mode 100644 index 00000000..d9634dae --- /dev/null +++ b/test/core/string_byte_sequence/count.wren @@ -0,0 +1,15 @@ +// Simple. +IO.print("".bytes.count) // expect: 0 +IO.print("123".bytes.count) // expect: 3 + +// UTF-8. +// Bytes: +// 123456789 +// Chars: sø mé ஃ +IO.print("søméஃ".bytes.count) // expect: 9 + +// Null bytes. +IO.print("\0\0\0".bytes.count) // expect: 3 + +// Invalid UTF-8. +IO.print("\xef\x00".bytes.count) // expect: 2 diff --git a/test/language/string/byte_escapes.wren b/test/language/string/byte_escapes.wren index 184db639..9d29d148 100644 --- a/test/language/string/byte_escapes.wren +++ b/test/language/string/byte_escapes.wren @@ -1,12 +1,12 @@ -var s = "\x00\x12\x34\x56\x78\xab\xCD\xfFf" +var bytes = "\x00\x12\x34\x56\x78\xab\xCD\xfFf".bytes -IO.print(s.byteAt(0)) // expect: 0 -IO.print(s.byteAt(1)) // expect: 18 -IO.print(s.byteAt(2)) // expect: 52 -IO.print(s.byteAt(3)) // expect: 86 -IO.print(s.byteAt(4)) // expect: 120 -IO.print(s.byteAt(5)) // expect: 171 -IO.print(s.byteAt(6)) // expect: 205 -IO.print(s.byteAt(7)) // expect: 255 +IO.print(bytes[0]) // expect: 0 +IO.print(bytes[1]) // expect: 18 +IO.print(bytes[2]) // expect: 52 +IO.print(bytes[3]) // expect: 86 +IO.print(bytes[4]) // expect: 120 +IO.print(bytes[5]) // expect: 171 +IO.print(bytes[6]) // expect: 205 +IO.print(bytes[7]) // expect: 255 // "f". -IO.print(s.byteAt(8)) // expect: 102 +IO.print(bytes[8]) // expect: 102