diff --git a/docs/lexicon.html b/docs/lexicon.html index 5f15df695d..f0924040c3 100644 --- a/docs/lexicon.html +++ b/docs/lexicon.html @@ -47,6 +47,16 @@
x
.
+ chr(i)
+ - returns a string containing the character whose Unicode code point
+ is the integer i
.
+
+ str:
+ pass
def len(obj:list|dict|str) -> int:
pass
def enumerate(seq:list):
diff --git a/src/parse/asp/builtins.go b/src/parse/asp/builtins.go
index 541555f349..dfb66e92ef 100644
--- a/src/parse/asp/builtins.go
+++ b/src/parse/asp/builtins.go
@@ -11,6 +11,7 @@ import (
"strconv"
"strings"
"sync"
+ "unicode"
"github.com/Masterminds/semver/v3"
"github.com/manifoldco/promptui"
@@ -47,6 +48,7 @@ func registerBuiltins(s *scope) {
setNativeCode(s, "all", allFunc)
setNativeCode(s, "min", min)
setNativeCode(s, "max", max)
+ setNativeCode(s, "chr", chr)
setNativeCode(s, "len", lenFunc)
setNativeCode(s, "glob", glob)
setNativeCode(s, "bool", boolType)
@@ -402,6 +404,13 @@ func objLen(obj pyObject) pyInt {
panic("object of type " + obj.Type() + " has no len()")
}
+func chr(s *scope, args []pyObject) pyObject {
+ i, isInt := args[0].(pyInt)
+ s.Assert(isInt, "Argument i must be an integer, not %s", args[0].Type())
+ s.Assert(i >= 0 && i <= unicode.MaxRune, "Argument i must be within the Unicode code point range")
+ return pyString(rune(i))
+}
+
func isinstance(s *scope, args []pyObject) pyObject {
obj := args[0]
typesArg := args[1]
diff --git a/src/parse/asp/interpreter_test.go b/src/parse/asp/interpreter_test.go
index 83c17e8bbd..43214d849e 100644
--- a/src/parse/asp/interpreter_test.go
+++ b/src/parse/asp/interpreter_test.go
@@ -487,6 +487,29 @@ func TestMax(t *testing.T) {
})
}
+func TestChr(t *testing.T) {
+ t.Run("OK", func(t *testing.T) {
+ s, err := parseFile("src/parse/asp/test_data/interpreter/chr.build")
+ assert.NoError(t, err)
+ assert.EqualValues(t, pyString("\x00"), s.Lookup("null"))
+ assert.EqualValues(t, pyString("a"), s.Lookup("a"))
+ assert.EqualValues(t, pyString("€"), s.Lookup("euro"))
+ assert.EqualValues(t, pyString("\U0010FFFF"), s.Lookup("maximum"))
+ })
+ t.Run("Wrong parameter type", func(t *testing.T) {
+ _, err := parseFile("src/parse/asp/test_data/interpreter/chr_wrong_type.build")
+ assert.ErrorContains(t, err, "Invalid type for argument i to chr; expected int, was str")
+ })
+ t.Run("Parameter out of bounds (too low)", func(t *testing.T) {
+ _, err := parseFile("src/parse/asp/test_data/interpreter/chr_bounds_low.build")
+ assert.ErrorContains(t, err, "Argument i must be within the Unicode code point range")
+ })
+ t.Run("Parameter out of bounds (too high)", func(t *testing.T) {
+ _, err := parseFile("src/parse/asp/test_data/interpreter/chr_bounds_high.build")
+ assert.ErrorContains(t, err, "Argument i must be within the Unicode code point range")
+ })
+}
+
func TestIsSemver(t *testing.T) {
t.Run("OK", func(t *testing.T) {
s, err := parseFile("src/parse/asp/test_data/interpreter/is_semver.build")
diff --git a/src/parse/asp/test_data/interpreter/chr.build b/src/parse/asp/test_data/interpreter/chr.build
new file mode 100644
index 0000000000..2442074914
--- /dev/null
+++ b/src/parse/asp/test_data/interpreter/chr.build
@@ -0,0 +1,4 @@
+null = chr(0)
+a = chr(97)
+euro = chr(8364)
+maximum = chr(1114111)
diff --git a/src/parse/asp/test_data/interpreter/chr_bounds_high.build b/src/parse/asp/test_data/interpreter/chr_bounds_high.build
new file mode 100644
index 0000000000..acd939e408
--- /dev/null
+++ b/src/parse/asp/test_data/interpreter/chr_bounds_high.build
@@ -0,0 +1 @@
+x = chr(1114112)
diff --git a/src/parse/asp/test_data/interpreter/chr_bounds_low.build b/src/parse/asp/test_data/interpreter/chr_bounds_low.build
new file mode 100644
index 0000000000..3fe15be6b4
--- /dev/null
+++ b/src/parse/asp/test_data/interpreter/chr_bounds_low.build
@@ -0,0 +1 @@
+x = chr(-1)
diff --git a/src/parse/asp/test_data/interpreter/chr_wrong_type.build b/src/parse/asp/test_data/interpreter/chr_wrong_type.build
new file mode 100644
index 0000000000..fd8b8fa2fe
--- /dev/null
+++ b/src/parse/asp/test_data/interpreter/chr_wrong_type.build
@@ -0,0 +1 @@
+x = chr("x")
diff --git a/third_party/go/BUILD b/third_party/go/BUILD
index ff8179e108..aac205d456 100644
--- a/third_party/go/BUILD
+++ b/third_party/go/BUILD
@@ -83,7 +83,7 @@ go_repo(
go_repo(
module = "github.com/stretchr/testify",
- version = "v1.7.0",
+ version = "v1.8.4",
)
go_repo(