Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY committed Apr 26, 2024
1 parent 766cacf commit e471eee
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 54 deletions.
2 changes: 2 additions & 0 deletions dev/ast/error.go
Expand Up @@ -11,6 +11,8 @@ var (
// ErrNotExist means both key and value doesn't exist
ErrNotExist error = newError(errors.New("not exist"))

emptyNode = newError(errors.New("not exist"))

// ErrUnsupportType means API on the node is unsupported
ErrUnsupportType error = newError(errors.New("not exist"))
)
Expand Down
128 changes: 82 additions & 46 deletions dev/ast/native.go
Expand Up @@ -15,45 +15,85 @@ type Node struct {
}


// func (n *node) SetAt(i int32, val unsafe.Pointer) {
// x := len(n.mut)
// n.tape[i] = token(_K_MUT|x)
// n.mut = append(n.mut, val)
// }


// func (n *Node) objAt(i int) (Pair, error) {
// key, err := strForToken(n.Kids[i * 2], n.JSON)
// if err != nil {
// return Pair{}, err
// }

// node := n.Kids[i * 2 + 1]
// val := node.Raw(n.JSON)
// return Pair{key, newRawNodeUnsafe(val, node.Flag.IsEsc())}, nil
// }

// func (n *Node) arrAt(i int) Node {
// node := n.Kids[i * 2 + 1]
// val := node.Raw(n.JSON)
// return newRawNodeUnsafe(val, node.Flag.IsEsc())
// }


// func strForToken(t types.Token, json string) (string, error) {
// raw := t.Raw(json)
// if !t.Flag.IsEsc(){
// // remove the quotes
// return raw[1: len(raw) - 1], nil
// }
func (n *Node) arrSet(i int, typ types.Type, val unsafe.Pointer) error {
t := n.arrAt(i)
if t == nil {
return ErrNotExist
}
l := len(n.mut)
*t = types.Token{
Kind: typ,
Flag: _F_MUT,
Off: uint32(l),
}
n.mut = append(n.mut, val)
n.Flag |= _F_MUT
return nil
}

func (n *Node) objSet(key string, typ types.Type, val unsafe.Pointer) error {
t, err := n.objAt(key)
if err != nil {
return err
}
l := len(n.mut)
*t = types.Token{
Kind: typ,
Flag: _F_MUT,
Off: uint32(l),
}
n.mut = append(n.mut, val)
n.Flag |= _F_MUT
return nil
}

func (n *Node) objAt(key string) (*types.Token, error) {
for i := 0; i<len(n.Kids)/2; i++ {
k, err := strForToken(n.Kids[i * 2], n.JSON)
if err != nil {
return nil, err
}
if k == key {
return &n.Kids[i * 2+1], nil
}
}
return nil, ErrNotExist
}

// This will convert a token to Node
// - scalar type, directly slice original string
// - array/object, parse to Node for one layer
// - mut type, use unsafe.Pointer casting
// TODO: handle mut token
func (n *Node) sub(t types.Token) Node {
if t.Flag & _F_MUT == 0 {
return newRawNodeUnsafe(t.Raw(n.JSON), t.Flag.IsEsc())
} else {
panic("not implement!")
}
}

func (n *Node) arrAt(i int) *types.Token {
if i >= len(n.Kids) {
return nil
}
return &n.Kids[i]
}

func strForToken(t types.Token, json string) (string, error) {
raw := t.Raw(json)
if !t.Flag.IsEsc(){
// remove the quotes
return raw[1: len(raw) - 1], nil
}

// s, err := unquote(raw)
// if err != 0 {
// return "", makeSyntaxError(json, int(t.Off), err.Message())
// } else {
// return s, nil
// }
// }
s, err := unquote(raw)
if err != 0 {
return "", makeSyntaxError(json, int(t.Off), err.Message())
} else {
return s, nil
}
}

func makeSyntaxError(json string, p int, msg string) decoder.SyntaxError {
return decoder.SyntaxError{
Expand All @@ -63,8 +103,6 @@ func makeSyntaxError(json string, p int, msg string) decoder.SyntaxError {
}
}



// TODO: use flags to make, if is primitives
func parseLazy(json string, path *[]interface{}) (Node, error) {
// TODO: got real PC of biz caller
Expand Down Expand Up @@ -130,11 +168,9 @@ func parseLazy(json string, path *[]interface{}) (Node, error) {

// Note: not validate the input json, only used internal
func newRawNodeUnsafe(json string, hasEsc bool) Node {
ret := Node{
Node: types.NewNode(json, hasEsc),
n := types.NewNode(json, hasEsc)
if !n.Kind.IsComplex() {
return Node{n, nil}
}
// if (ret.Kind == types.T_ARRAY || ret.Kind == types.T_OBJECT) && isRaw {
// ret.Flag |= _F_RAW
// }
return ret
return NewRaw(json)
}
63 changes: 55 additions & 8 deletions dev/ast/node.go
Expand Up @@ -76,14 +76,11 @@ var (
// NewRaw creates a node of raw json.
// If the input json is invalid, NewRaw returns a error Node.
func NewRaw(json string) Node {
p := NewParser(json)
start, err := p.skip()
if err != nil {
return newError(err)
}

// TODO: FIXME, should has escaped flags
return newRawNodeUnsafe(json[start: p.pos], true)
n, e := NewParser(json).Parse()
if e != nil {
return newError(e)
}
return n
}

// NewAny creates a node of type V_ANY if any's type isn't Node or *Node
Expand Down Expand Up @@ -151,7 +148,57 @@ func NewBytes(src []byte) Node {
return NewString(out)
}

func (self *Node) should(t types.Type) error {
if err := self.Error(); err != "" {
return self
}
if self.Kind != t {
return ErrUnsupportType
}
return nil
}

func (n *Node) get(key string) (Node) {
t, err := n.objAt(key)
if err != nil {
return newError(err)
}
return n.sub(*t)
}

func (n *Node) index(key int) (Node) {
t := n.arrAt(key)
if t == nil {
return emptyNode
}
return n.sub(*t)
}


func (self *Node) GetByPath(path ...interface{}) Node {
if l := len(path); l == 0 {
return *self
} else if l == 1 {
switch p := path[0].(type) {
case int:
return self.index(p)
case string:
return self.get(p)
default:
panic("path must be either int or string")
}
} else {
n, err := NewParser(self.JSON).getByPath(path...)
if err != nil {
return newError(err)
}
return n
}
}

/***************** Cast APIs ***********************/




/***************** Set APIs ***********************/
3 changes: 3 additions & 0 deletions dev/ast/node_test.go
Expand Up @@ -25,6 +25,9 @@ func getSample(width int, depth int) string {
}

func TestNodeParse(t *testing.T) {
n1, err := NewParser(`[1,"1",true]`).Parse()
require.NoError(t, err)
spew.Dump(n1.Kids)
src := getSample(100, 0)
n, err := NewParser(src).Parse()
require.NoError(t, err)
Expand Down
3 changes: 3 additions & 0 deletions internal/native/types/types.go
Expand Up @@ -188,6 +188,9 @@ type Token struct {
Len uint32
}

func (t Type) IsComplex() bool {
return t == T_ARRAY || t == T_OBJECT
}

type Node struct {
Kind Type
Expand Down

0 comments on commit e471eee

Please sign in to comment.