feat: implement chr, ord, and hex (#425)

This commit is contained in:
Sahin Yort 2023-05-15 12:15:55 -07:00 committed by GitHub
parent f080671cec
commit 781d1cbebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 784 additions and 540 deletions

View File

@ -133,4 +133,9 @@ stardoc_with_diff_test(
bzl_library_target = "//lib:bazelrc_presets",
)
stardoc_with_diff_test(
name = "strings",
bzl_library_target = "//lib:strings",
)
update_docs()

86
docs/strings.md generated Normal file
View File

@ -0,0 +1,86 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->
Utilities for strings
<a id="chr"></a>
## chr
<pre>
chr(<a href="#chr-i">i</a>)
</pre>
returns a string encoding a codepoint
chr returns a string that encodes the single Unicode code
point whose value is specified by the integer `i`
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="chr-i"></a>i | position of the character | none |
**RETURNS**
unicode string of the position
<a id="hex"></a>
## hex
<pre>
hex(<a href="#hex-number">number</a>)
</pre>
Format integer to hexdecimal representation
Args:
number: number to format
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="hex-number"></a>number | <p align="center"> - </p> | none |
**RETURNS**
hexdecimal representation of the number argument
<a id="ord"></a>
## ord
<pre>
ord(<a href="#ord-c">c</a>)
</pre>
returns the codepoint of a character
ord(c) returns the integer value of the sole Unicode code point
encoded by the string `c`.
If `c` does not encode exactly one Unicode code point, `ord` fails.
Each invalid code within the string is treated as if it encodes the
Unicode replacement character, U+FFFD.
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="ord-c"></a>c | character whose codepoint to be returned. | none |
**RETURNS**
codepoint of `c` argument.

View File

@ -252,3 +252,9 @@ bzl_library(
srcs = ["bazelrc_presets.bzl"],
deps = [":write_source_files"],
)
bzl_library(
name = "strings",
srcs = ["strings.bzl"],
deps = ["//lib/private/docs:strings"],
)

View File

@ -6,6 +6,8 @@ Implementation based on https://gist.github.com/trondhumbor/ce57c0c2816bb45a8fbb
the subset of python available in Starlark.
"""
load(":strings.bzl", "ord", "chr")
def decode(data):
"""Decode a Base64 encoded string.
@ -31,7 +33,7 @@ def decode(data):
outstring = ""
for chunk in eight_chunks:
outstring += _int_to_char(int(chunk, 2))
outstring += chr(int(chunk, 2))
return outstring if padding == 0 else outstring[:-padding]
@ -56,7 +58,7 @@ def encode(data):
binstring = ""
for chunk in three_chunks:
for i in range(len(chunk)):
binstring += _int_to_binary(_char_to_int(chunk[i]))
binstring += _int_to_binary(ord(chunk[i]))
six_chunks = _chunk(binstring, 6)
@ -66,548 +68,13 @@ def encode(data):
return outstring if padding == 0 else outstring[:-padding] + "=" * padding
def _char_to_int(c):
if len(c) != 1:
fail("expected a string with a single character")
return CHAR_TO_INT.get(c)
def _int_to_binary(i, digits = 8):
if i < 0 or i > 255:
fail("expected a int between 0 and 255 (inclusive)")
if digits < 1 or digits > 8:
fail("expected digits to be between 1 and 8 (inclusive)")
return INT_TO_BINARY[i][8 - digits:]
def _int_to_char(i):
if i < 0 or i > 255:
fail("expected a int between 0 and 255 (inclusive)")
return INT_TO_CHAR[i]
def _chunk(data, length):
return [data[i:i + length] for i in range(0, len(data), length)]
BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
# Starlark support octal values that we can leverage for this conversion.
# Generated by lib/private/base64.py utility script.
CHAR_TO_INT = {
"\0": 0,
"\1": 1,
"\2": 2,
"\3": 3,
"\4": 4,
"\5": 5,
"\6": 6,
"\7": 7,
"\10": 8,
"\11": 9,
"\12": 10,
"\13": 11,
"\14": 12,
"\15": 13,
"\16": 14,
"\17": 15,
"\20": 16,
"\21": 17,
"\22": 18,
"\23": 19,
"\24": 20,
"\25": 21,
"\26": 22,
"\27": 23,
"\30": 24,
"\31": 25,
"\32": 26,
"\33": 27,
"\34": 28,
"\35": 29,
"\36": 30,
"\37": 31,
"\40": 32,
"\41": 33,
"\42": 34,
"\43": 35,
"\44": 36,
"\45": 37,
"\46": 38,
"\47": 39,
"\50": 40,
"\51": 41,
"\52": 42,
"\53": 43,
"\54": 44,
"\55": 45,
"\56": 46,
"\57": 47,
"\60": 48,
"\61": 49,
"\62": 50,
"\63": 51,
"\64": 52,
"\65": 53,
"\66": 54,
"\67": 55,
"\70": 56,
"\71": 57,
"\72": 58,
"\73": 59,
"\74": 60,
"\75": 61,
"\76": 62,
"\77": 63,
"\100": 64,
"\101": 65,
"\102": 66,
"\103": 67,
"\104": 68,
"\105": 69,
"\106": 70,
"\107": 71,
"\110": 72,
"\111": 73,
"\112": 74,
"\113": 75,
"\114": 76,
"\115": 77,
"\116": 78,
"\117": 79,
"\120": 80,
"\121": 81,
"\122": 82,
"\123": 83,
"\124": 84,
"\125": 85,
"\126": 86,
"\127": 87,
"\130": 88,
"\131": 89,
"\132": 90,
"\133": 91,
"\134": 92,
"\135": 93,
"\136": 94,
"\137": 95,
"\140": 96,
"\141": 97,
"\142": 98,
"\143": 99,
"\144": 100,
"\145": 101,
"\146": 102,
"\147": 103,
"\150": 104,
"\151": 105,
"\152": 106,
"\153": 107,
"\154": 108,
"\155": 109,
"\156": 110,
"\157": 111,
"\160": 112,
"\161": 113,
"\162": 114,
"\163": 115,
"\164": 116,
"\165": 117,
"\166": 118,
"\167": 119,
"\170": 120,
"\171": 121,
"\172": 122,
"\173": 123,
"\174": 124,
"\175": 125,
"\176": 126,
"\177": 127,
"\200": 128,
"\201": 129,
"\202": 130,
"\203": 131,
"\204": 132,
"\205": 133,
"\206": 134,
"\207": 135,
"\210": 136,
"\211": 137,
"\212": 138,
"\213": 139,
"\214": 140,
"\215": 141,
"\216": 142,
"\217": 143,
"\220": 144,
"\221": 145,
"\222": 146,
"\223": 147,
"\224": 148,
"\225": 149,
"\226": 150,
"\227": 151,
"\230": 152,
"\231": 153,
"\232": 154,
"\233": 155,
"\234": 156,
"\235": 157,
"\236": 158,
"\237": 159,
"\240": 160,
"\241": 161,
"\242": 162,
"\243": 163,
"\244": 164,
"\245": 165,
"\246": 166,
"\247": 167,
"\250": 168,
"\251": 169,
"\252": 170,
"\253": 171,
"\254": 172,
"\255": 173,
"\256": 174,
"\257": 175,
"\260": 176,
"\261": 177,
"\262": 178,
"\263": 179,
"\264": 180,
"\265": 181,
"\266": 182,
"\267": 183,
"\270": 184,
"\271": 185,
"\272": 186,
"\273": 187,
"\274": 188,
"\275": 189,
"\276": 190,
"\277": 191,
"\300": 192,
"\301": 193,
"\302": 194,
"\303": 195,
"\304": 196,
"\305": 197,
"\306": 198,
"\307": 199,
"\310": 200,
"\311": 201,
"\312": 202,
"\313": 203,
"\314": 204,
"\315": 205,
"\316": 206,
"\317": 207,
"\320": 208,
"\321": 209,
"\322": 210,
"\323": 211,
"\324": 212,
"\325": 213,
"\326": 214,
"\327": 215,
"\330": 216,
"\331": 217,
"\332": 218,
"\333": 219,
"\334": 220,
"\335": 221,
"\336": 222,
"\337": 223,
"\340": 224,
"\341": 225,
"\342": 226,
"\343": 227,
"\344": 228,
"\345": 229,
"\346": 230,
"\347": 231,
"\350": 232,
"\351": 233,
"\352": 234,
"\353": 235,
"\354": 236,
"\355": 237,
"\356": 238,
"\357": 239,
"\360": 240,
"\361": 241,
"\362": 242,
"\363": 243,
"\364": 244,
"\365": 245,
"\366": 246,
"\367": 247,
"\370": 248,
"\371": 249,
"\372": 250,
"\373": 251,
"\374": 252,
"\375": 253,
"\376": 254,
"\377": 255,
}
INT_TO_CHAR = [
"\0",
"\1",
"\2",
"\3",
"\4",
"\5",
"\6",
"\7",
"\10",
"\11",
"\12",
"\13",
"\14",
"\15",
"\16",
"\17",
"\20",
"\21",
"\22",
"\23",
"\24",
"\25",
"\26",
"\27",
"\30",
"\31",
"\32",
"\33",
"\34",
"\35",
"\36",
"\37",
"\40",
"\41",
"\42",
"\43",
"\44",
"\45",
"\46",
"\47",
"\50",
"\51",
"\52",
"\53",
"\54",
"\55",
"\56",
"\57",
"\60",
"\61",
"\62",
"\63",
"\64",
"\65",
"\66",
"\67",
"\70",
"\71",
"\72",
"\73",
"\74",
"\75",
"\76",
"\77",
"\100",
"\101",
"\102",
"\103",
"\104",
"\105",
"\106",
"\107",
"\110",
"\111",
"\112",
"\113",
"\114",
"\115",
"\116",
"\117",
"\120",
"\121",
"\122",
"\123",
"\124",
"\125",
"\126",
"\127",
"\130",
"\131",
"\132",
"\133",
"\134",
"\135",
"\136",
"\137",
"\140",
"\141",
"\142",
"\143",
"\144",
"\145",
"\146",
"\147",
"\150",
"\151",
"\152",
"\153",
"\154",
"\155",
"\156",
"\157",
"\160",
"\161",
"\162",
"\163",
"\164",
"\165",
"\166",
"\167",
"\170",
"\171",
"\172",
"\173",
"\174",
"\175",
"\176",
"\177",
"\200",
"\201",
"\202",
"\203",
"\204",
"\205",
"\206",
"\207",
"\210",
"\211",
"\212",
"\213",
"\214",
"\215",
"\216",
"\217",
"\220",
"\221",
"\222",
"\223",
"\224",
"\225",
"\226",
"\227",
"\230",
"\231",
"\232",
"\233",
"\234",
"\235",
"\236",
"\237",
"\240",
"\241",
"\242",
"\243",
"\244",
"\245",
"\246",
"\247",
"\250",
"\251",
"\252",
"\253",
"\254",
"\255",
"\256",
"\257",
"\260",
"\261",
"\262",
"\263",
"\264",
"\265",
"\266",
"\267",
"\270",
"\271",
"\272",
"\273",
"\274",
"\275",
"\276",
"\277",
"\300",
"\301",
"\302",
"\303",
"\304",
"\305",
"\306",
"\307",
"\310",
"\311",
"\312",
"\313",
"\314",
"\315",
"\316",
"\317",
"\320",
"\321",
"\322",
"\323",
"\324",
"\325",
"\326",
"\327",
"\330",
"\331",
"\332",
"\333",
"\334",
"\335",
"\336",
"\337",
"\340",
"\341",
"\342",
"\343",
"\344",
"\345",
"\346",
"\347",
"\350",
"\351",
"\352",
"\353",
"\354",
"\355",
"\356",
"\357",
"\360",
"\361",
"\362",
"\363",
"\364",
"\365",
"\366",
"\367",
"\370",
"\371",
"\372",
"\373",
"\374",
"\375",
"\376",
"\377",
]
# Generated by lib/private/string.py utility script.
INT_TO_BINARY = [
"00000000",
"00000001",
@ -866,3 +333,10 @@ INT_TO_BINARY = [
"11111110",
"11111111",
]
def _int_to_binary(i, digits = 8):
if i < 0 or i > 255:
fail("expected a int between 0 and 255 (inclusive)")
if digits < 1 or digits > 8:
fail("expected digits to be between 1 and 8 (inclusive)")
return INT_TO_BINARY[i][8 - digits:]

View File

@ -227,6 +227,9 @@ bzl_library(
bzl_library(
name = "base64",
srcs = ["//lib/private:base64.bzl"],
deps = [
":strings"
]
)
bzl_library(
@ -243,3 +246,9 @@ bzl_library(
name = "coreutils_toolchain",
srcs = ["//lib/private:coreutils_toolchain.bzl"],
)
bzl_library(
name = "strings",
srcs = ["//lib/private:strings.bzl"],
)

586
lib/private/strings.bzl Normal file
View File

@ -0,0 +1,586 @@
"String utilities"
CHAR_TO_INT = {
"\0": 0,
"\1": 1,
"\2": 2,
"\3": 3,
"\4": 4,
"\5": 5,
"\6": 6,
"\7": 7,
"\10": 8,
"\11": 9,
"\12": 10,
"\13": 11,
"\14": 12,
"\15": 13,
"\16": 14,
"\17": 15,
"\20": 16,
"\21": 17,
"\22": 18,
"\23": 19,
"\24": 20,
"\25": 21,
"\26": 22,
"\27": 23,
"\30": 24,
"\31": 25,
"\32": 26,
"\33": 27,
"\34": 28,
"\35": 29,
"\36": 30,
"\37": 31,
"\40": 32,
"\41": 33,
"\42": 34,
"\43": 35,
"\44": 36,
"\45": 37,
"\46": 38,
"\47": 39,
"\50": 40,
"\51": 41,
"\52": 42,
"\53": 43,
"\54": 44,
"\55": 45,
"\56": 46,
"\57": 47,
"\60": 48,
"\61": 49,
"\62": 50,
"\63": 51,
"\64": 52,
"\65": 53,
"\66": 54,
"\67": 55,
"\70": 56,
"\71": 57,
"\72": 58,
"\73": 59,
"\74": 60,
"\75": 61,
"\76": 62,
"\77": 63,
"\100": 64,
"\101": 65,
"\102": 66,
"\103": 67,
"\104": 68,
"\105": 69,
"\106": 70,
"\107": 71,
"\110": 72,
"\111": 73,
"\112": 74,
"\113": 75,
"\114": 76,
"\115": 77,
"\116": 78,
"\117": 79,
"\120": 80,
"\121": 81,
"\122": 82,
"\123": 83,
"\124": 84,
"\125": 85,
"\126": 86,
"\127": 87,
"\130": 88,
"\131": 89,
"\132": 90,
"\133": 91,
"\134": 92,
"\135": 93,
"\136": 94,
"\137": 95,
"\140": 96,
"\141": 97,
"\142": 98,
"\143": 99,
"\144": 100,
"\145": 101,
"\146": 102,
"\147": 103,
"\150": 104,
"\151": 105,
"\152": 106,
"\153": 107,
"\154": 108,
"\155": 109,
"\156": 110,
"\157": 111,
"\160": 112,
"\161": 113,
"\162": 114,
"\163": 115,
"\164": 116,
"\165": 117,
"\166": 118,
"\167": 119,
"\170": 120,
"\171": 121,
"\172": 122,
"\173": 123,
"\174": 124,
"\175": 125,
"\176": 126,
"\177": 127,
"\200": 128,
"\201": 129,
"\202": 130,
"\203": 131,
"\204": 132,
"\205": 133,
"\206": 134,
"\207": 135,
"\210": 136,
"\211": 137,
"\212": 138,
"\213": 139,
"\214": 140,
"\215": 141,
"\216": 142,
"\217": 143,
"\220": 144,
"\221": 145,
"\222": 146,
"\223": 147,
"\224": 148,
"\225": 149,
"\226": 150,
"\227": 151,
"\230": 152,
"\231": 153,
"\232": 154,
"\233": 155,
"\234": 156,
"\235": 157,
"\236": 158,
"\237": 159,
"\240": 160,
"\241": 161,
"\242": 162,
"\243": 163,
"\244": 164,
"\245": 165,
"\246": 166,
"\247": 167,
"\250": 168,
"\251": 169,
"\252": 170,
"\253": 171,
"\254": 172,
"\255": 173,
"\256": 174,
"\257": 175,
"\260": 176,
"\261": 177,
"\262": 178,
"\263": 179,
"\264": 180,
"\265": 181,
"\266": 182,
"\267": 183,
"\270": 184,
"\271": 185,
"\272": 186,
"\273": 187,
"\274": 188,
"\275": 189,
"\276": 190,
"\277": 191,
"\300": 192,
"\301": 193,
"\302": 194,
"\303": 195,
"\304": 196,
"\305": 197,
"\306": 198,
"\307": 199,
"\310": 200,
"\311": 201,
"\312": 202,
"\313": 203,
"\314": 204,
"\315": 205,
"\316": 206,
"\317": 207,
"\320": 208,
"\321": 209,
"\322": 210,
"\323": 211,
"\324": 212,
"\325": 213,
"\326": 214,
"\327": 215,
"\330": 216,
"\331": 217,
"\332": 218,
"\333": 219,
"\334": 220,
"\335": 221,
"\336": 222,
"\337": 223,
"\340": 224,
"\341": 225,
"\342": 226,
"\343": 227,
"\344": 228,
"\345": 229,
"\346": 230,
"\347": 231,
"\350": 232,
"\351": 233,
"\352": 234,
"\353": 235,
"\354": 236,
"\355": 237,
"\356": 238,
"\357": 239,
"\360": 240,
"\361": 241,
"\362": 242,
"\363": 243,
"\364": 244,
"\365": 245,
"\366": 246,
"\367": 247,
"\370": 248,
"\371": 249,
"\372": 250,
"\373": 251,
"\374": 252,
"\375": 253,
"\376": 254,
"\377": 255,
}
INT_TO_CHAR = [
"\0",
"\1",
"\2",
"\3",
"\4",
"\5",
"\6",
"\7",
"\10",
"\11",
"\12",
"\13",
"\14",
"\15",
"\16",
"\17",
"\20",
"\21",
"\22",
"\23",
"\24",
"\25",
"\26",
"\27",
"\30",
"\31",
"\32",
"\33",
"\34",
"\35",
"\36",
"\37",
"\40",
"\41",
"\42",
"\43",
"\44",
"\45",
"\46",
"\47",
"\50",
"\51",
"\52",
"\53",
"\54",
"\55",
"\56",
"\57",
"\60",
"\61",
"\62",
"\63",
"\64",
"\65",
"\66",
"\67",
"\70",
"\71",
"\72",
"\73",
"\74",
"\75",
"\76",
"\77",
"\100",
"\101",
"\102",
"\103",
"\104",
"\105",
"\106",
"\107",
"\110",
"\111",
"\112",
"\113",
"\114",
"\115",
"\116",
"\117",
"\120",
"\121",
"\122",
"\123",
"\124",
"\125",
"\126",
"\127",
"\130",
"\131",
"\132",
"\133",
"\134",
"\135",
"\136",
"\137",
"\140",
"\141",
"\142",
"\143",
"\144",
"\145",
"\146",
"\147",
"\150",
"\151",
"\152",
"\153",
"\154",
"\155",
"\156",
"\157",
"\160",
"\161",
"\162",
"\163",
"\164",
"\165",
"\166",
"\167",
"\170",
"\171",
"\172",
"\173",
"\174",
"\175",
"\176",
"\177",
"\200",
"\201",
"\202",
"\203",
"\204",
"\205",
"\206",
"\207",
"\210",
"\211",
"\212",
"\213",
"\214",
"\215",
"\216",
"\217",
"\220",
"\221",
"\222",
"\223",
"\224",
"\225",
"\226",
"\227",
"\230",
"\231",
"\232",
"\233",
"\234",
"\235",
"\236",
"\237",
"\240",
"\241",
"\242",
"\243",
"\244",
"\245",
"\246",
"\247",
"\250",
"\251",
"\252",
"\253",
"\254",
"\255",
"\256",
"\257",
"\260",
"\261",
"\262",
"\263",
"\264",
"\265",
"\266",
"\267",
"\270",
"\271",
"\272",
"\273",
"\274",
"\275",
"\276",
"\277",
"\300",
"\301",
"\302",
"\303",
"\304",
"\305",
"\306",
"\307",
"\310",
"\311",
"\312",
"\313",
"\314",
"\315",
"\316",
"\317",
"\320",
"\321",
"\322",
"\323",
"\324",
"\325",
"\326",
"\327",
"\330",
"\331",
"\332",
"\333",
"\334",
"\335",
"\336",
"\337",
"\340",
"\341",
"\342",
"\343",
"\344",
"\345",
"\346",
"\347",
"\350",
"\351",
"\352",
"\353",
"\354",
"\355",
"\356",
"\357",
"\360",
"\361",
"\362",
"\363",
"\364",
"\365",
"\366",
"\367",
"\370",
"\371",
"\372",
"\373",
"\374",
"\375",
"\376",
"\377",
]
def ord(c):
"""returns the codepoint of a character
ord(c) returns the integer value of the sole Unicode code point
encoded by the string `c`.
If `c` does not encode exactly one Unicode code point, `ord` fails.
Each invalid code within the string is treated as if it encodes the
Unicode replacement character, U+FFFD.
Args:
c: character whose codepoint to be returned.
Returns:
codepoint of `c` argument.
"""
if len(c) != 1:
fail("expected a string with a single character")
return CHAR_TO_INT.get(c)
def chr(i):
"""returns a string encoding a codepoint
chr returns a string that encodes the single Unicode code
point whose value is specified by the integer `i`
Args:
i: position of the character
Returns:
unicode string of the position
"""
if i < 0 or i > 255:
fail("expected a int between 0 and 255 (inclusive)")
return INT_TO_CHAR[i]
def _to_char(n):
alpha = "0123456789abcdef"
return alpha[n]
def hex(number):
"""Format integer to hexdecimal representation
Args:
number: number to format
Returns:
hexdecimal representation of the number argument
"""
hex_string = ""
is_signed = number < 0
r = number * -1 if is_signed else number
for _ in range(1000000):
if r > 0:
rem = r % 16
hex_string = _to_char(rem) + hex_string
r //= 16
else:
break
if not hex_string:
hex_string = "0"
return "{}0x{}".format("-" if is_signed else "", hex_string)

View File

@ -1,4 +1,4 @@
# python utility to seed the starlark constants in base64.bzl
# python utility to seed the starlark constants in strings.bzl
print("")
print("CHAR_TO_INT = {")

9
lib/strings.bzl Normal file
View File

@ -0,0 +1,9 @@
"Utilities for strings"
load("//lib/private:strings.bzl", _chr = "chr", _ord = "ord", _hex = "hex")
chr = _chr
ord = _ord
hex = _hex

View File

@ -9,6 +9,7 @@ load(":utils_test.bzl", "utils_test_suite")
load(":paths_test.bzl", "paths_test_suite")
load(":glob_match_test.bzl", "glob_match_test_suite")
load(":base64_tests.bzl", "base64_test_suite")
load(":strings_tests.bzl", "strings_test_suite")
config_setting(
name = "experimental_allow_unresolved_symlinks",
@ -26,6 +27,8 @@ glob_match_test_suite()
base64_test_suite()
strings_test_suite()
write_file(
name = "gen_template",
out = "template.txt",

View File

@ -1,7 +1,8 @@
"""unit tests for base64"""
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load("//lib/private:base64.bzl", "INT_TO_CHAR", "decode", "encode")
load("//lib/private:base64.bzl", "decode", "encode")
load("//lib/private:strings.bzl", "INT_TO_CHAR")
def _base64_test_impl(ctx):
env = unittest.begin(ctx)

View File

@ -0,0 +1,65 @@
"""unit tests for string"""
load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
load("//lib/private:strings.bzl", "ord", "chr", "hex")
def _ord_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, ord("a"), 97)
asserts.equals(env, ord("b"), 98)
asserts.equals(env, ord("/"), 47)
asserts.equals(env, ord("c"), 99)
asserts.equals(env, ord("x"), 120)
asserts.equals(env, ord("@"), 64)
asserts.equals(env, ord("%"), 37)
asserts.equals(env, ord("$"), 36)
asserts.equals(env, ord("+"), 43)
return unittest.end(env)
ord_test = unittest.make(_ord_test_impl)
def _chr_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, chr(97), "a")
asserts.equals(env, chr(98), "b")
asserts.equals(env, chr(47), "/")
asserts.equals(env, chr(99), "c")
asserts.equals(env, chr(120), "x")
asserts.equals(env, chr(64), "@")
asserts.equals(env, chr(37), "%")
asserts.equals(env, chr(36), "$")
asserts.equals(env, chr(43), "+")
return unittest.end(env)
chr_test = unittest.make(_chr_test_impl)
def _hex_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, hex(1111), "0x457")
asserts.equals(env, hex(97), "0x61")
asserts.equals(env, hex(1000000000000), "0xe8d4a51000")
asserts.equals(env, hex(1), "0x1")
# https://en.wikipedia.org/wiki/Signed_zero
asserts.equals(env, hex(0), "0x0")
asserts.equals(env, hex(-0), "0x0")
asserts.equals(env, hex(-1234), "-0x4d2")
asserts.equals(env, hex(-99999999), "-0x5f5e0ff")
return unittest.end(env)
hex_test = unittest.make(_hex_test_impl)
def strings_test_suite():
unittest.suite(
"strings_tests",
ord_test,
chr_test,
hex_test
)