Repository: d5/tengo
Pull request #404 (2023-01-11 10:24:08)

Added more math consts
Hello, I've added some more of the consts from the math package. https://pkg.go.dev/math#pkg-constants

geseq: Can you rebase master please?

Patch:
diff --git a/docs/stdlib-math.md b/docs/stdlib-math.md
index d68eb77..ce8d2cd 100644
--- a/docs/stdlib-math.md
+++ b/docs/stdlib-math.md
@@ -18,6 +18,28 @@ math := import("math")
 - `ln10`
 - `ln10E`
 
+Mathematical constants.
+
+- `maxFloat32`
+- `smallestNonzeroFloat32`
+- `maxFloat64`
+- `smallestNonzeroFloat64`
+
+Floating-point limit values. Max is the largest finite value representable by the type. SmallestNonzero is the smallest positive, non-zero value representable by the type.
+
+- `maxInt`
+- `minInt`
+- `maxInt8`
+- `minInt8`
+- `maxInt16`
+- `minInt16`
+- `maxInt32`
+- `minInt32`
+- `maxInt64`
+- `minInt64`
+
+Integer limit values.
+
 ## Functions
 
 - `abs(x float) => float`: returns the absolute value of x.
diff --git a/stdlib/json/decode.go b/stdlib/json/decode.go
index 6d468ef..37432d4 100644
--- a/stdlib/json/decode.go
+++ b/stdlib/json/decode.go
@@ -62,9 +62,12 @@ func (d *decodeState) scanNext() {
 
 // scanWhile processes bytes in d.data[d.off:] until it
 // receives a scan code not equal to op.
-func (d *decodeState) scanWhile(op int) {
+func (d *decodeState) scanWhile(op int) (isFloat bool) {
 	s, data, i := &d.scan, d.data, d.off
 	for i < len(data) {
+		if data[i] == '.' {
+			isFloat = true
+		}
 		newOp := s.step(s, data[i])
 		i++
 		if newOp != op {
@@ -76,6 +79,7 @@ func (d *decodeState) scanWhile(op int) {
 
 	d.off = len(data) + 1 // mark processed EOF with len+1
 	d.opcode = d.scan.eof()
+	return
 }
 
 func (d *decodeState) value() (tengo.Object, error) {
@@ -185,7 +189,7 @@ func (d *decodeState) object() (tengo.Object, error) {
 func (d *decodeState) literal() (tengo.Object, error) {
 	// All bytes inside literal return scanContinue op code.
 	start := d.readIndex()
-	d.scanWhile(scanContinue)
+	isFloat := d.scanWhile(scanContinue)
 
 	item := d.data[start:d.readIndex()]
 
@@ -210,8 +214,12 @@ func (d *decodeState) literal() (tengo.Object, error) {
 		if c != '-' && (c < '0' || c > '9') {
 			panic(phasePanicMsg)
 		}
-		n, _ := strconv.ParseFloat(string(item), 10)
-		return &tengo.Float{Value: n}, nil
+		if isFloat {
+			n, _ := strconv.ParseFloat(string(item), 10)
+			return &tengo.Float{Value: n}, nil
+		}
+		n, _ := strconv.ParseInt(string(item), 10, 64)
+		return &tengo.Int{Value: n}, nil
 	}
 }
 
diff --git a/stdlib/math.go b/stdlib/math.go
index 633ea09..1bd9ba6 100644
--- a/stdlib/math.go
+++ b/stdlib/math.go
@@ -7,17 +7,31 @@ import (
 )
 
 var mathModule = map[string]tengo.Object{
-	"e":       &tengo.Float{Value: math.E},
-	"pi":      &tengo.Float{Value: math.Pi},
-	"phi":     &tengo.Float{Value: math.Phi},
-	"sqrt2":   &tengo.Float{Value: math.Sqrt2},
-	"sqrtE":   &tengo.Float{Value: math.SqrtE},
-	"sqrtPi":  &tengo.Float{Value: math.SqrtPi},
-	"sqrtPhi": &tengo.Float{Value: math.SqrtPhi},
-	"ln2":     &tengo.Float{Value: math.Ln2},
-	"log2E":   &tengo.Float{Value: math.Log2E},
-	"ln10":    &tengo.Float{Value: math.Ln10},
-	"log10E":  &tengo.Float{Value: math.Log10E},
+	"e":                      &tengo.Float{Value: math.E},
+	"pi":                     &tengo.Float{Value: math.Pi},
+	"phi":                    &tengo.Float{Value: math.Phi},
+	"sqrt2":                  &tengo.Float{Value: math.Sqrt2},
+	"sqrtE":                  &tengo.Float{Value: math.SqrtE},
+	"sqrtPi":                 &tengo.Float{Value: math.SqrtPi},
+	"sqrtPhi":                &tengo.Float{Value: math.SqrtPhi},
+	"ln2":                    &tengo.Float{Value: math.Ln2},
+	"log2E":                  &tengo.Float{Value: math.Log2E},
+	"ln10":                   &tengo.Float{Value: math.Ln10},
+	"log10E":                 &tengo.Float{Value: math.Log10E},
+	"maxFloat32":             &tengo.Float{Value: math.MaxFloat32},
+	"smallestNonzeroFloat32": &tengo.Float{Value: math.SmallestNonzeroFloat32},
+	"maxFloat64":             &tengo.Float{Value: math.MaxFloat64},
+	"smallestNonzeroFloat64": &tengo.Float{Value: math.SmallestNonzeroFloat64},
+	"maxInt":                 &tengo.Int{Value: math.MaxInt},
+	"minInt":                 &tengo.Int{Value: math.MinInt},
+	"maxInt8":                &tengo.Int{Value: math.MaxInt8},
+	"minInt8":                &tengo.Int{Value: math.MinInt8},
+	"maxInt16":               &tengo.Int{Value: math.MaxInt16},
+	"minInt16":               &tengo.Int{Value: math.MinInt16},
+	"maxInt32":               &tengo.Int{Value: math.MaxInt32},
+	"minInt32":               &tengo.Int{Value: math.MinInt32},
+	"maxInt64":               &tengo.Int{Value: math.MaxInt64},
+	"minInt64":               &tengo.Int{Value: math.MinInt64},
 	"abs": &tengo.UserFunction{
 		Name:  "abs",
 		Value: FuncAFRF(math.Abs),


Test patch:
diff --git a/stdlib/json/json_test.go b/stdlib/json/json_test.go
index 5abfdec..b12bd64 100644
--- a/stdlib/json/json_test.go
+++ b/stdlib/json/json_test.go
@@ -57,6 +57,8 @@ func TestJSON(t *testing.T) {
 		"arr": ARR{1, 2, 3, "four"}})
 	testJSONEncodeDecode(t, MAP{"a": 0, "b": "bee",
 		"arr": ARR{1, 2, 3, MAP{"a": false, "b": 109.4}}})
+
+	testJSONEncodeDecode(t, MAP{"id1": 7075984636689534001, "id2": 7075984636689534002})
 }
 
 func TestDecode(t *testing.T) {
diff --git a/stdlib/json_test.go b/stdlib/json_test.go
index adf7037..ac8dcf1 100644
--- a/stdlib/json_test.go
+++ b/stdlib/json_test.go
@@ -48,13 +48,13 @@ func TestJSON(t *testing.T) {
 		expect([]byte("[[\"bar\",1],[\"bar\",1]]"))
 
 	module(t, "json").call("decode", `5`).
-		expect(5.0)
+		expect(5)
 	module(t, "json").call("decode", `"foo"`).
 		expect("foo")
 	module(t, "json").call("decode", `[1,2,3,"bar"]`).
-		expect(ARR{1.0, 2.0, 3.0, "bar"})
+		expect(ARR{1, 2, 3, "bar"})
 	module(t, "json").call("decode", `{"foo":5}`).
-		expect(MAP{"foo": 5.0})
+		expect(MAP{"foo": 5})
 	module(t, "json").call("decode", `{"foo":2.5}`).
 		expect(MAP{"foo": 2.5})
 	module(t, "json").call("decode", `{"foo":true}`).
@@ -62,7 +62,7 @@ func TestJSON(t *testing.T) {
 	module(t, "json").call("decode", `{"foo":"bar"}`).
 		expect(MAP{"foo": "bar"})
 	module(t, "json").call("decode", `{"foo":[1,2,3,"bar"]}`).
-		expect(MAP{"foo": ARR{1.0, 2.0, 3.0, "bar"}})
+		expect(MAP{"foo": ARR{1, 2, 3, "bar"}})
 
 	module(t, "json").
 		call("indent", []byte("{\"foo\":[\"bar\",1,1.8,56,true]}"), "", "  ").