From a437e804ba49c418af58442504a70bd163b491b4 Mon Sep 17 00:00:00 2001 From: Walter Schell Date: Wed, 27 Feb 2019 08:05:07 -0500 Subject: [PATCH] Added String.fromByte with docs and unit test --- doc/site/modules/core/string.markdown | 9 +++++++++ src/vm/wren_core.c | 16 ++++++++++++++++ src/vm/wren_value.c | 9 +++++++++ src/vm/wren_value.h | 3 +++ test/core/string/from_byte.wren | 3 +++ test/core/string/from_byte_not_int.wren | 1 + test/core/string/from_byte_not_num.wren | 1 + test/core/string/from_byte_too_large.wren | 1 + test/core/string/from_byte_too_small.wren | 1 + 9 files changed, 44 insertions(+) create mode 100644 test/core/string/from_byte.wren create mode 100644 test/core/string/from_byte_not_int.wren create mode 100644 test/core/string/from_byte_not_num.wren create mode 100644 test/core/string/from_byte_too_large.wren create mode 100644 test/core/string/from_byte_too_small.wren diff --git a/doc/site/modules/core/string.markdown b/doc/site/modules/core/string.markdown index b9b459e6..5af2fce3 100644 --- a/doc/site/modules/core/string.markdown +++ b/doc/site/modules/core/string.markdown @@ -57,6 +57,15 @@ Creates a new string containing the UTF-8 encoding of `codePoint`. It is a runtime error if `codePoint` is not an integer between `0` and `0x10ffff`, inclusive. +### String.**fromByte**(byte) + +Creates a new string containing the single byte `byte`. + + :::wren + String.fromByte(255) //> � + +It is a runtime error if `byte` is not an integer between `0` and `0xff`, inclusive. + ## Methods ### **bytes** diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index eaeb64de..f3f00277 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -920,6 +920,21 @@ DEF_PRIMITIVE(string_fromCodePoint) RETURN_VAL(wrenStringFromCodePoint(vm, codePoint)); } +DEF_PRIMITIVE(string_fromByte) +{ + if (!validateInt(vm, args[1], "Byte")) return false; + int byte = (int) AS_NUM(args[1]); + if (byte < 0) + { + RETURN_ERROR("Byte cannot be negative."); + } + else if (byte > 0xff) + { + RETURN_ERROR("Byte cannot be greater than 0xff."); + } + RETURN_VAL(wrenStringFromByte(vm, (uint8_t) byte)); +} + DEF_PRIMITIVE(string_byteAt) { ObjString* string = AS_STRING(args[0]); @@ -1305,6 +1320,7 @@ void wrenInitializeCore(WrenVM* vm) vm->stringClass = AS_CLASS(wrenFindVariable(vm, coreModule, "String")); PRIMITIVE(vm->stringClass->obj.classObj, "fromCodePoint(_)", string_fromCodePoint); + PRIMITIVE(vm->stringClass->obj.classObj, "fromByte(_)", string_fromByte); PRIMITIVE(vm->stringClass, "+(_)", string_plus); PRIMITIVE(vm->stringClass, "[_]", string_subscript); PRIMITIVE(vm->stringClass, "byteAt_(_)", string_byteAt); diff --git a/src/vm/wren_value.c b/src/vm/wren_value.c index 40931920..3ce4366f 100644 --- a/src/vm/wren_value.c +++ b/src/vm/wren_value.c @@ -802,6 +802,15 @@ Value wrenStringFromCodePoint(WrenVM* vm, int value) return OBJ_VAL(string); } +Value wrenStringFromByte(WrenVM *vm, uint8_t value) +{ + int length = 1; + ObjString* string = allocateString(vm, length); + string->value[0] = value; + hashString(string); + return OBJ_VAL(string); +} + Value wrenStringFormat(WrenVM* vm, const char* format, ...) { va_list argList; diff --git a/src/vm/wren_value.h b/src/vm/wren_value.h index 59531230..358418fa 100644 --- a/src/vm/wren_value.h +++ b/src/vm/wren_value.h @@ -738,6 +738,9 @@ Value wrenStringFormat(WrenVM* vm, const char* format, ...); // Creates a new string containing the UTF-8 encoding of [value]. Value wrenStringFromCodePoint(WrenVM* vm, int value); +// Creates a new string from the integer representation of a byte +Value wrenStringFromByte(WrenVM* vm, uint8_t value); + // Creates a new string containing the code point in [string] starting at byte // [index]. If [index] points into the middle of a UTF-8 sequence, returns an // empty string. diff --git a/test/core/string/from_byte.wren b/test/core/string/from_byte.wren new file mode 100644 index 00000000..33d51764 --- /dev/null +++ b/test/core/string/from_byte.wren @@ -0,0 +1,3 @@ +System.print(String.fromByte(65)) // expect: A +System.print(String.fromByte(0).bytes[0]) // expect: 0 +System.print(String.fromByte(255).bytes[0]) // expect: 255 diff --git a/test/core/string/from_byte_not_int.wren b/test/core/string/from_byte_not_int.wren new file mode 100644 index 00000000..97ace76d --- /dev/null +++ b/test/core/string/from_byte_not_int.wren @@ -0,0 +1 @@ +System.print(String.fromByte(12.34)) // expect runtime error: Byte must be an integer. diff --git a/test/core/string/from_byte_not_num.wren b/test/core/string/from_byte_not_num.wren new file mode 100644 index 00000000..312708d8 --- /dev/null +++ b/test/core/string/from_byte_not_num.wren @@ -0,0 +1 @@ +System.print(String.fromByte("not num")) // expect runtime error: Byte must be a number. diff --git a/test/core/string/from_byte_too_large.wren b/test/core/string/from_byte_too_large.wren new file mode 100644 index 00000000..7f01cc50 --- /dev/null +++ b/test/core/string/from_byte_too_large.wren @@ -0,0 +1 @@ +System.print(String.fromByte(0xff + 1)) // expect runtime error: Byte cannot be greater than 0xff. diff --git a/test/core/string/from_byte_too_small.wren b/test/core/string/from_byte_too_small.wren new file mode 100644 index 00000000..ef88cf53 --- /dev/null +++ b/test/core/string/from_byte_too_small.wren @@ -0,0 +1 @@ +System.print(String.fromByte(-1)) // expect runtime error: Byte cannot be negative.