Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add json object #95

Merged
merged 13 commits into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions docs/content/docs/literals/json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
---
title: "JSON"
menu:
docs:
parent: "literals"
---
# JSON




```js
🚀 > JSON.parse('{"test": 123}')
=> {"test": 123.0}
```

## Literal Specific Methods

### parse(STRING)
> Returns `HASH`

Takes a STRING and parses it to a HASH or ARRAY. Numbers are always FLOAT.


```js
🚀 > JSON.parse('{"test": 123}')
=> {"test": 123.0}
🚀 > JSON.parse('["test", 123]')
=> ["test", 123.0]
```



## Generic Literal Methods

### methods()
> Returns `ARRAY`

Returns an array of all supported methods names.

```js
🚀 > "test".methods()
=> [count, downcase, find, reverse!, split, lines, upcase!, strip!, downcase!, size, plz_i, replace, reverse, strip, upcase]
```

### to_json()
> Returns `STRING|ERROR`

Returns the object as json notation.

```js
🚀 > a = {"test": 1234}
=> {"test": 1234}
🚀 > a.to_json()
=> "{"test":1234}"
```

### type()
> Returns `STRING`

Returns the type of the object.

```js
🚀 > "test".type()
=> "STRING"
```

### wat()
> Returns `STRING`

Returns the supported methods with usage information.

```js
🚀 > true.wat()
=> BOOLEAN supports the following methods:
plz_s()
```
11 changes: 10 additions & 1 deletion docs/generate.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package main

import (
"github.com/flipez/rocket-lang/object"
"os"
"text/template"

"github.com/flipez/rocket-lang/object"
)

type templateData struct {
Expand All @@ -26,6 +27,7 @@ func main() {
nil_methods := object.ListObjectMethods()[object.NIL_OBJ]
float_methods := object.ListObjectMethods()[object.FLOAT_OBJ]
http_methods := object.ListObjectMethods()[object.HTTP_OBJ]
json_methods := object.ListObjectMethods()[object.JSON_OBJ]

tempData := templateData{
Title: "String",
Expand Down Expand Up @@ -190,6 +192,13 @@ HTTP.listen(3000)
DefaultMethods: default_methods}
create_doc("docs/templates/literal.md", "docs/content/docs/literals/http.md", tempData)

tempData = templateData{
Title: "JSON",
Example: `🚀 > JSON.parse('{"test": 123}')
=> {"test": 123.0}`,
LiteralMethods: json_methods,
DefaultMethods: default_methods}
create_doc("docs/templates/literal.md", "docs/content/docs/literals/json.md", tempData)
}

func create_doc(path string, target string, data templateData) bool {
Expand Down
6 changes: 6 additions & 0 deletions fixtures/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"string": "Kadeem Sawyer",
"float": 12.3,
"array": ["11137", 1234],
"bool": true
}
11 changes: 7 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
module github.com/flipez/rocket-lang

go 1.17
go 1.18

require github.com/abiosoft/ishell/v2 v2.0.2
require (
github.com/abiosoft/ishell/v2 v2.0.2
github.com/spf13/pflag v1.0.5
)

require (
github.com/abiosoft/ishell v2.0.0+incompatible // indirect
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db // indirect
github.com/fatih/color v1.12.0 // indirect
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
)
11 changes: 10 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw=
github.com/abiosoft/ishell v2.0.0+incompatible/go.mod h1:HQR9AqF2R3P4XXpMpI0NAzgHf/aS6+zVXRj14cVk9qg=
github.com/abiosoft/ishell/v2 v2.0.2 h1:5qVfGiQISaYM8TkbBl7RFO6MddABoXpATrsFbVI+SNo=
github.com/abiosoft/ishell/v2 v2.0.2/go.mod h1:E4oTCXfo6QjoCart0QYa5m9w4S+deXs/P/9jA77A9Bs=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db h1:CjPUSXOiYptLbTdr1RceuZgSFDQ7U15ITERUGrUORx8=
github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db/go.mod h1:rB3B4rKii8V21ydCbIzH5hZiCQE7f5E9SzUb/ZZx530=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
Expand All @@ -13,13 +18,17 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
76 changes: 76 additions & 0 deletions object/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package object

import (
"encoding/json"
)

type JSON struct{}

func (j *JSON) Type() ObjectType { return JSON_OBJ }
func (j *JSON) Inspect() string { return "JSON" }
func (j *JSON) InvokeMethod(method string, env Environment, args ...Object) Object {
return objectMethodLookup(j, method, env, args)
}

func init() {
objectMethods[JSON_OBJ] = map[string]ObjectMethod{
"parse": ObjectMethod{
description: "Takes a STRING and parses it to a HASH or ARRAY. Numbers are always FLOAT.",
example: `🚀 > JSON.parse('{"test": 123}')
=> {"test": 123.0}
🚀 > JSON.parse('["test", 123]')
=> ["test", 123.0]`,
returnPattern: [][]string{
[]string{HASH_OBJ},
},
argPattern: [][]string{
[]string{STRING_OBJ},
},
method: func(_ Object, args []Object, _ Environment) Object {
var i interface{}
input := args[0].(*String).Value

err := json.Unmarshal([]byte(input), &i)

if err != nil {
return NewErrorFormat("Error while parsing json: %s", err)
}

return interfaceToObject(i)
},
},
}
}

func interfaceToObject(i interface{}) Object {
switch v := i.(type) {
case map[string]interface{}:
jsonObject := NewHash(nil)
for key, val := range v {
hp := HashPair{
Key: NewString(key),
Value: interfaceToObject(val),
}

jsonObject.Pairs[hp.Key.(Hashable).HashKey()] = hp
}

return jsonObject
case []interface{}:
jsonArray := NewArray(nil)
for _, element := range v {
jsonArray.Elements = append(jsonArray.Elements, interfaceToObject(element))
}
return jsonArray
case string:
return NewString(v)
case float64:
return NewFloat(v)
case bool:
if v {
return TRUE
}
return FALSE
}
return NIL
}
20 changes: 20 additions & 0 deletions object/json_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package object_test

import (
"testing"
)

func TestJSONObjectMethods(t *testing.T) {
tests := []inputTestCase{
{`JSON.nope()`, "undefined method `.nope()` for JSON"},
{`JSON.parse("{a}")`, "Error while parsing json: invalid character 'a' looking for beginning of object key string"},
{`JSON.parse("{}").type()`, "HASH"},
{`JSON.parse("[]").type()`, "ARRAY"},
{`a = open("../fixtures/data.json").content(); JSON.parse(a)["string"]`, "Kadeem Sawyer"},
{`a = open("../fixtures/data.json").content(); JSON.parse(a)["bool"]`, true},
{`a = open("../fixtures/data.json").content(); JSON.parse(a)["float"]`, 12.3},
{`a = open("../fixtures/data.json").content(); JSON.parse(a)["array"][1]`, 1234.0},
}

testInput(t, tests)
}
1 change: 1 addition & 0 deletions object/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
FILE_OBJ = "FILE"
MODULE_OBJ = "MODULE"
HTTP_OBJ = "HTTP"
JSON_OBJ = "JSON"
)

type ObjectMethod struct {
Expand Down
1 change: 1 addition & 0 deletions stdlib/std.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func init() {
RegisterFunction("open", openFunction)

RegisterClass("HTTP", &object.HTTP{})
RegisterClass("JSON", &object.JSON{})
}

func RegisterFunction(name string, function object.BuiltinFunction) {
Expand Down