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 @@

- returns the length of 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(