Repository: d5/tengo
Pull request #419 (2023-03-27 21:30:19)

tutorial: use any instead of interface{}
simple doc change


Patch:
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 01aca2d..cb363d9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,11 +14,11 @@ jobs:
       - name: set up Go
         uses: actions/setup-go@v2
         with:
-          go-version: 1.16
+          go-version: 1.18
       - name: run goreleaser
         uses: goreleaser/goreleaser-action@v3
         with:
           version: latest
           args: release --rm-dist
         env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/docs/stdlib-json.md b/docs/stdlib-json.md
index 42d2c55..d127993 100644
--- a/docs/stdlib-json.md
+++ b/docs/stdlib-json.md
@@ -11,7 +11,7 @@ json := import("json")
 - `encode(o object) => bytes`: Returns the JSON string (bytes) of the object.
   Unlike Go's JSON package, this function does not HTML-escape texts, but, one
   can use `html_escape` function if needed.
-- `indent(b string/bytes) => bytes`: Returns an indented form of input JSON
+- `indent(b string/bytes, prefix string, indent string) => bytes`: Returns an indented form of input JSON
   bytes string.
 - `html_escape(b string/bytes) => bytes`: Return an HTML-safe form of input
   JSON bytes string.
@@ -22,7 +22,7 @@ json := import("json")
 json := import("json")
 
 encoded := json.encode({a: 1, b: [2, 3, 4]})  // JSON-encoded bytes string
-indentded := json.indent(encoded)             // indented form
+indentded := json.indent(encoded, "", "  ")   // indented form
 html_safe := json.html_escape(encoded)        // HTML escaped form
 
 decoded := json.decode(encoded)               // {a: 1, b: [2, 3, 4]}
diff --git a/docs/tutorial.md b/docs/tutorial.md
index 92c7a3c..b9e20c1 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -32,9 +32,9 @@ Here's a list of all available value types in Tengo.
 | bytes | byte array | `[]byte` |
 | error | [error](#error-values) value | - |
 | time | time value | `time.Time` |
-| array | value array _(mutable)_ | `[]interface{}` |
+| array | value array _(mutable)_ | `[]any` |
 | immutable array | [immutable](#immutable-values) array | - |
-| map | value map with string keys _(mutable)_ | `map[string]interface{}` |
+| map | value map with string keys _(mutable)_ | `map[string]any` |
 | immutable map | [immutable](#immutable-values) map | - |
 | undefined | [undefined](#undefined-values) value | - |
 | function | [function](#function-values) value | - |
diff --git a/parser/parser.go b/parser/parser.go
index eaa9dc9..a12af61 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -143,6 +143,7 @@ func (p *Parser) ParseFile() (file *File, err error) {
 	}
 
 	stmts := p.parseStmtList()
+	p.expect(token.EOF)
 	if p.errors.Len() > 0 {
 		return nil, p.errors.Err()
 	}
diff --git a/stdlib/json/decode.go b/stdlib/json/decode.go
index 37432d4..557fb9e 100644
--- a/stdlib/json/decode.go
+++ b/stdlib/json/decode.go
@@ -65,7 +65,7 @@ func (d *decodeState) scanNext() {
 func (d *decodeState) scanWhile(op int) (isFloat bool) {
 	s, data, i := &d.scan, d.data, d.off
 	for i < len(data) {
-		if data[i] == '.' {
+		if data[i] == '.' || data[i] == 'e' || data[i] == 'E' {
 			isFloat = true
 		}
 		newOp := s.step(s, data[i])


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index f2137f6..5edb1a3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,7 +12,7 @@ jobs:
     - name: set up Go
       uses: actions/setup-go@v1
       with:
-        go-version: 1.17
+        go-version: 1.18
       id: go
     - name: set up Go module cache
       uses: actions/cache@v1
diff --git a/parser/parser_test.go b/parser/parser_test.go
index 8c2c530..b0aaa87 100644
--- a/parser/parser_test.go
+++ b/parser/parser_test.go
@@ -1631,6 +1631,20 @@ func TestParseFloat(t *testing.T) {
 	}
 }
 
+func TestMismatchBrace(t *testing.T) {
+	expectParseError(t, `
+fmt := import("fmt")
+out := 0
+if 3 == 1 {
+	out = 1
+}
+} else {
+	out = 2
+}
+fmt.println(out)
+	`)
+}
+
 func TestParseNumberExpressions(t *testing.T) {
 	expectParse(t, `0x15e+2`, func(p pfn) []Stmt {
 		return stmts(
diff --git a/stdlib/json/json_test.go b/stdlib/json/json_test.go
index b12bd64..031307c 100644
--- a/stdlib/json/json_test.go
+++ b/stdlib/json/json_test.go
@@ -59,6 +59,7 @@ func TestJSON(t *testing.T) {
 		"arr": ARR{1, 2, 3, MAP{"a": false, "b": 109.4}}})
 
 	testJSONEncodeDecode(t, MAP{"id1": 7075984636689534001, "id2": 7075984636689534002})
+	testJSONEncodeDecode(t, ARR{1e3, 1E7})
 }
 
 func TestDecode(t *testing.T) {
diff --git a/vm_test.go b/vm_test.go
index dcde5ec..8c98b5a 100644
--- a/vm_test.go
+++ b/vm_test.go
@@ -2754,10 +2754,10 @@ export func(a) {
 		Opts().Module("mod0", `if 1 { } else { export true }`),
 		tengo.UndefinedValue)
 	expectRun(t, `out = import("mod0")`,
-		Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { export true } } }`),
+		Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { export true } }`),
 		true)
 	expectRun(t, `out = import("mod0")`,
-		Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { break } } }`),
+		Opts().Module("mod0", `for v:=0;;v++ { if v == 3 { break } }`),
 		tengo.UndefinedValue)
 
 	// duplicate compiled functions