Pass all test cases

This commit is contained in:
Masaaki Goshima 2020-11-15 15:31:10 +09:00
parent 039bdf2791
commit c2307ab6d7
3 changed files with 48 additions and 40 deletions

View File

@ -765,10 +765,10 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, named
} else if op != f.op { } else if op != f.op {
if existsKey { if existsKey {
f.op = opStructFieldAnonymousHead f.op = opStructFieldAnonymousHead
} else { } else if named == "" {
f.op = op f.op = op
} }
} else if f.op == opStructEnd { } else if named == "" && f.op == opStructEnd {
f.op = opStructAnonymousEnd f.op = opStructAnonymousEnd
} else if existsKey { } else if existsKey {
diff := f.nextField.displayIdx - f.displayIdx diff := f.nextField.displayIdx - f.displayIdx
@ -808,9 +808,9 @@ func (e *Encoder) anonymousStructFieldPairMap(typ *rtype, tags structTags, named
} }
func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]structFieldPair) { func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]structFieldPair) {
fmt.Printf("anonymousFields = %+v\n", anonymousFields) //fmt.Printf("anonymousFields = %+v\n", anonymousFields)
removedFields := map[*opcode]struct{}{} removedFields := map[*opcode]struct{}{}
for name, fieldPairs := range anonymousFields { for _, fieldPairs := range anonymousFields {
if len(fieldPairs) == 1 { if len(fieldPairs) == 1 {
continue continue
} }
@ -823,24 +823,24 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
if !fieldPair.linked { if !fieldPair.linked {
if fieldPair.prevField == nil { if fieldPair.prevField == nil {
// head operation // head operation
fmt.Println("omit:", fieldPair.curField.displayKey) //fmt.Println("omit:", fieldPair.curField.displayKey)
fieldPair.curField.op = opStructFieldAnonymousHead fieldPair.curField.op = opStructFieldAnonymousHead
} else { } else {
fmt.Println("remove", name) //fmt.Println("remove", name)
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey) //fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
fmt.Println("diff = ", diff) //fmt.Println("diff = ", diff)
for i := 0; i < diff; i++ { for i := 0; i < diff; i++ {
fieldPair.curField.nextField.decOpcodeIndex() fieldPair.curField.nextField.decOpcodeIndex()
} }
fmt.Println("cur.nextField") //fmt.Println("cur.nextField")
fmt.Println(fieldPair.curField.nextField.dump()) //fmt.Println(fieldPair.curField.nextField.dump())
fmt.Println("===========") //fmt.Println("===========")
removedFields[fieldPair.curField] = struct{}{} removedFields[fieldPair.curField] = struct{}{}
linkPrevToNextField(fieldPair.curField, removedFields) linkPrevToNextField(fieldPair.curField, removedFields)
fmt.Println("linked. prevField") //fmt.Println("linked. prevField")
fmt.Println(fieldPair.prevField.dump()) //fmt.Println(fieldPair.prevField.dump())
fmt.Println("===========") //fmt.Println("===========")
// tagggedPairs に入れた方にもこの結果を反映させないといけない // tagggedPairs に入れた方にもこの結果を反映させないといけない
} }
fieldPair.linked = true fieldPair.linked = true
@ -854,13 +854,13 @@ func (e *Encoder) optimizeConflictAnonymousFields(anonymousFields map[string][]s
// head operation // head operation
fieldPair.curField.op = opStructFieldAnonymousHead fieldPair.curField.op = opStructFieldAnonymousHead
} else { } else {
fmt.Println("TAGGED PAIRS REMOVE") //fmt.Println("TAGGED PAIRS REMOVE")
fmt.Println("remove", name) //fmt.Println("remove", name)
fmt.Println("removedFields = ", removedFields) //fmt.Println("removedFields = ", removedFields)
fmt.Printf("prev = %p cur = %p next = %p\n", fieldPair.curField.prevField, fieldPair.curField, fieldPair.curField.nextField) //fmt.Printf("prev = %p cur = %p next = %p\n", fieldPair.curField.prevField, fieldPair.curField, fieldPair.curField.nextField)
diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx diff := fieldPair.curField.nextField.displayIdx - fieldPair.curField.displayIdx
fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey) //fmt.Println("link:", fieldPair.prevField.displayKey, "=>", fieldPair.curField.nextField.displayKey)
fmt.Println("diff = ", diff) //fmt.Println("diff = ", diff)
removedFields[fieldPair.curField] = struct{}{} removedFields[fieldPair.curField] = struct{}{}
for i := 0; i < diff; i++ { for i := 0; i < diff; i++ {
fieldPair.curField.nextField.decOpcodeIndex() fieldPair.curField.nextField.decOpcodeIndex()
@ -1035,23 +1035,23 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
head.end = structEndCode head.end = structEndCode
code.next = structEndCode code.next = structEndCode
/*
fmt.Println("head") fmt.Println("head")
fmt.Println(head.dump()) fmt.Println(head.dump())
fmt.Println("===============") fmt.Println("===============")
*/
e.optimizeConflictAnonymousFields(anonymousFields) e.optimizeConflictAnonymousFields(anonymousFields)
/*
fmt.Println("remove conflicted key head") fmt.Println("remove conflicted key head")
fmt.Println(head.dump()) fmt.Println(head.dump())
fmt.Println("===============") fmt.Println("===============")
*/
e.optimizeAnonymousFields(head) e.optimizeAnonymousFields(head)
/*
fmt.Println("optimized head") fmt.Println("optimized head")
fmt.Println(head.dump()) fmt.Println(head.dump())
fmt.Println("===============") fmt.Println("===============")
*/
ret := (*opcode)(unsafe.Pointer(head)) ret := (*opcode)(unsafe.Pointer(head))
compiled.code = ret compiled.code = ret

View File

@ -38,10 +38,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
seenPtr := map[uintptr]struct{}{} seenPtr := map[uintptr]struct{}{}
ptrOffset := uintptr(0) ptrOffset := uintptr(0)
ctxptr := ctx.ptr() ctxptr := ctx.ptr()
fmt.Println(code.dump()) //fmt.Println(code.dump())
for { for {
fmt.Printf("[%d]:[%s]\n", code.displayIdx, code.op) //fmt.Printf("[%d]:[%s]\n", code.displayIdx, code.op)
switch code.op { switch code.op {
default: default:
return fmt.Errorf("failed to handle opcode. doesn't implement %s", code.op) return fmt.Errorf("failed to handle opcode. doesn't implement %s", code.op)
@ -4195,7 +4195,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
code = code.next code = code.next
} }
case opStructField: case opStructField:
if e.buf[len(e.buf)-1] != '{' { if e.buf[len(e.buf)-1] != '{' && e.buf[len(e.buf)-1] != ',' {
e.encodeByte(',') e.encodeByte(',')
} }
if !code.anonymousKey { if !code.anonymousKey {
@ -4218,7 +4218,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
} }
code = code.next code = code.next
case opStructFieldInt: case opStructFieldInt:
if e.buf[len(e.buf)-1] != '{' { if e.buf[len(e.buf)-1] != '{' && e.buf[len(e.buf)-1] != ',' {
e.encodeByte(',') e.encodeByte(',')
} }
ptr := load(ctxptr, code.headIdx) ptr := load(ctxptr, code.headIdx)
@ -5900,7 +5900,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error {
e.encodeString(*(*string)(unsafe.Pointer(&bytes))) e.encodeString(*(*string)(unsafe.Pointer(&bytes)))
code = code.next code = code.next
case opStructEnd: case opStructEnd:
last := len(e.buf) - 1
if e.buf[last] == ',' {
e.buf[last] = '}'
} else {
e.encodeByte('}') e.encodeByte('}')
}
code = code.next code = code.next
case opStructAnonymousEnd: case opStructAnonymousEnd:
code = code.next code = code.next

View File

@ -317,6 +317,9 @@ func (n Number) Int64() (int64, error) {
} }
func (n Number) MarshalJSON() ([]byte, error) { func (n Number) MarshalJSON() ([]byte, error) {
if n == "" {
return []byte("0"), nil
}
if _, err := n.Float64(); err != nil { if _, err := n.Float64(); err != nil {
return nil, err return nil, err
} }