std.codepoint, std.char + a bunch of tests

This commit is contained in:
Stanisław Barzowski 2017-09-12 14:52:00 -04:00 committed by Dave Cunningham
parent 4c5938c1f0
commit cab0cc887e
37 changed files with 68 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"fmt"
"math" "math"
"sort" "sort"
@ -384,6 +385,34 @@ func builtinMd5(e *evaluator, xp potentialValue) (value, error) {
return makeValueString(hex.EncodeToString(hash[:])), nil return makeValueString(hex.EncodeToString(hash[:])), nil
} }
// Maximum allowed unicode codepoint
// https://en.wikipedia.org/wiki/Unicode#Architecture_and_terminology
const codepointMax = 0x10FFFF
func builtinChar(e *evaluator, xp potentialValue) (value, error) {
x, err := e.evaluateNumber(xp)
if err != nil {
return nil, err
}
if x.value > codepointMax {
return nil, e.Error(fmt.Sprintf("Invalid unicode codepoint, got %v", x.value))
} else if x.value < 0 {
return nil, e.Error(fmt.Sprintf("Codepoints must be >= 0, got %v", x.value))
}
return makeValueString(string(rune(x.value))), nil
}
func builtinCodepoint(e *evaluator, xp potentialValue) (value, error) {
x, err := e.evaluateString(xp)
if err != nil {
return nil, err
}
if x.length() != 1 {
return nil, e.Error(fmt.Sprintf("codepoint takes a string of length 1, got length %v", x.length()))
}
return makeValueNumber(float64(x.value[0])), nil
}
func makeDoubleCheck(e *evaluator, x float64) (value, error) { func makeDoubleCheck(e *evaluator, x float64) (value, error) {
if math.IsNaN(x) { if math.IsNaN(x) {
return nil, e.Error("Not a number") return nil, e.Error("Not a number")
@ -612,6 +641,8 @@ var funcBuiltins = map[string]evalCallable{
"objectFieldsEx": &BinaryBuiltin{name: "objectFields", function: builtinObjectFieldsEx, parameters: ast.Identifiers{"obj", "hidden"}}, "objectFieldsEx": &BinaryBuiltin{name: "objectFields", function: builtinObjectFieldsEx, parameters: ast.Identifiers{"obj", "hidden"}},
"objectHasEx": &TernaryBuiltin{name: "objectHasEx", function: builtinObjectHasEx, parameters: ast.Identifiers{"obj", "fname", "hidden"}}, "objectHasEx": &TernaryBuiltin{name: "objectHasEx", function: builtinObjectHasEx, parameters: ast.Identifiers{"obj", "fname", "hidden"}},
"type": &UnaryBuiltin{name: "type", function: builtinType, parameters: ast.Identifiers{"x"}}, "type": &UnaryBuiltin{name: "type", function: builtinType, parameters: ast.Identifiers{"x"}},
"char": &UnaryBuiltin{name: "char", function: builtinChar, parameters: ast.Identifiers{"x"}},
"codepoint": &UnaryBuiltin{name: "codepoint", function: builtinCodepoint, parameters: ast.Identifiers{"x"}},
"ceil": &UnaryBuiltin{name: "ceil", function: builtinCeil, parameters: ast.Identifiers{"x"}}, "ceil": &UnaryBuiltin{name: "ceil", function: builtinCeil, parameters: ast.Identifiers{"x"}},
"floor": &UnaryBuiltin{name: "floor", function: builtinFloor, parameters: ast.Identifiers{"x"}}, "floor": &UnaryBuiltin{name: "floor", function: builtinFloor, parameters: ast.Identifiers{"x"}},
"sqrt": &UnaryBuiltin{name: "sqrt", function: builtinSqrt, parameters: ast.Identifiers{"x"}}, "sqrt": &UnaryBuiltin{name: "sqrt", function: builtinSqrt, parameters: ast.Identifiers{"x"}},

1
testdata/builtinChar.golden vendored Normal file
View File

@ -0,0 +1 @@
"A"

1
testdata/builtinChar.input vendored Normal file
View File

@ -0,0 +1 @@
std.char(65)

1
testdata/builtinChar2.golden vendored Normal file
View File

@ -0,0 +1 @@
"\u0000"

1
testdata/builtinChar2.input vendored Normal file
View File

@ -0,0 +1 @@
std.char(0)

1
testdata/builtinChar3.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: Codepoints must be >= 0, got -1

1
testdata/builtinChar3.input vendored Normal file
View File

@ -0,0 +1 @@
std.char(-1)

1
testdata/builtinChar4.golden vendored Normal file
View File

@ -0,0 +1 @@
"*"

1
testdata/builtinChar4.input vendored Normal file
View File

@ -0,0 +1 @@
std.char(42)

1
testdata/builtinChar5.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: Invalid unicode codepoint, got 1.114112e+06

2
testdata/builtinChar5.input vendored Normal file
View File

@ -0,0 +1,2 @@
// too big
std.char(1114112)

1
testdata/builtinChar6.golden vendored Normal file
View File

@ -0,0 +1 @@
"􏿿"

2
testdata/builtinChar6.input vendored Normal file
View File

@ -0,0 +1,2 @@
// biggest allowed
std.char(1114111)

1
testdata/error_hexnumber.golden vendored Normal file
View File

@ -0,0 +1 @@
testdata/error_hexnumber:1:2-5 Did not expect: (IDENTIFIER, "x42")

1
testdata/error_hexnumber.input vendored Normal file
View File

@ -0,0 +1 @@
0x42

1
testdata/number_leading_zero.golden vendored Normal file
View File

@ -0,0 +1 @@
testdata/number_leading_zero:1:2-4 Did not expect: (NUMBER, "42")

1
testdata/number_leading_zero.input vendored Normal file
View File

@ -0,0 +1 @@
042

1
testdata/std.codepoint.golden vendored Normal file
View File

@ -0,0 +1 @@
65

1
testdata/std.codepoint.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint('A')

1
testdata/std.codepoint2.golden vendored Normal file
View File

@ -0,0 +1 @@
0

1
testdata/std.codepoint2.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint("\u0000")

1
testdata/std.codepoint3.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: codepoint takes a string of length 1, got length 2

1
testdata/std.codepoint3.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint("aa")

1
testdata/std.codepoint4.golden vendored Normal file
View File

@ -0,0 +1 @@
261

1
testdata/std.codepoint4.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint("ą")

1
testdata/std.codepoint5.golden vendored Normal file
View File

@ -0,0 +1 @@
21488

1
testdata/std.codepoint5.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint("台")

1
testdata/std.codepoint6.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: codepoint takes a string of length 1, got length 0

1
testdata/std.codepoint6.input vendored Normal file
View File

@ -0,0 +1 @@
std.codepoint("")

1
testdata/std.codepoint7.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: codepoint takes a string of length 1, got length 2

2
testdata/std.codepoint7.input vendored Normal file
View File

@ -0,0 +1,2 @@
// Two codepoint version using combining ogonek u0328
std.codepoint("ą")

1
testdata/type_builtin_function.golden vendored Normal file
View File

@ -0,0 +1 @@
"function"

1
testdata/type_builtin_function.input vendored Normal file
View File

@ -0,0 +1 @@
std.type(std.type)

1
testdata/type_error.golden vendored Normal file
View File

@ -0,0 +1 @@
RUNTIME ERROR: xxx

1
testdata/type_error.input vendored Normal file
View File

@ -0,0 +1 @@
std.type(error "xxx")