generate: The generics idea didn't work, use type names instead
This commit is contained in:
parent
a99d4dee66
commit
a270c22cb9
@ -67,6 +67,7 @@ type Generator struct {
|
|||||||
type decodeBranchRequest struct {
|
type decodeBranchRequest struct {
|
||||||
hash [16]byte
|
hash [16]byte
|
||||||
typ Type
|
typ Type
|
||||||
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Generator) Generate(protocol *Protocol) (n int, err error) {
|
func (this *Generator) Generate(protocol *Protocol) (n int, err error) {
|
||||||
@ -102,9 +103,9 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) {
|
|||||||
|
|
||||||
// request queue
|
// request queue
|
||||||
for {
|
for {
|
||||||
hash, typ, ok := this.pullDecodeBranchRequest()
|
hash, typ, name, ok := this.pullDecodeBranchRequest()
|
||||||
if !ok { break }
|
if !ok { break }
|
||||||
nn, err := this.generateDecodeBranch(hash, typ)
|
nn, err := this.generateDecodeBranch(hash, typ, name)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +194,7 @@ func (this *Generator) generateTypedef(name string, typ Type) (n int, err error)
|
|||||||
nn, err = this.iprintf("}\n")
|
nn, err = this.iprintf("}\n")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
|
|
||||||
nn, err = this.generateDecodeValue(typ, "this", "tag")
|
nn, err = this.generateDecodeValue(typ, name, "this", "tag")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
nn, err = this.iprintf("return n, nil\n")
|
nn, err = this.iprintf("return n, nil\n")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
@ -282,7 +283,7 @@ func (this *Generator) generateMessage(method uint16, message Message) (n int, e
|
|||||||
nn, err = this.iprintf("}\n")
|
nn, err = this.iprintf("}\n")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
|
|
||||||
nn, err = this.generateDecodeValue(message.Type, "this", "tag")
|
nn, err = this.generateDecodeValue(message.Type, this.resolveMessageName(message.Name), "this", "tag")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
nn, err = this.iprintf("return n, nil\n")
|
nn, err = this.iprintf("return n, nil\n")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
@ -471,7 +472,10 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
|
|||||||
// - n int
|
// - n int
|
||||||
// - err error
|
// - err error
|
||||||
// - nn int
|
// - nn int
|
||||||
func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource string) (n int, err error) {
|
//
|
||||||
|
// The typeName paramterer is handled in the way described in the documentation
|
||||||
|
// for [Generator.generateDecodeBranch].
|
||||||
|
func (this *Generator) generateDecodeValue(typ Type, typeName, valueSource, tagSource string) (n int, err error) {
|
||||||
switch typ := typ.(type) {
|
switch typ := typ.(type) {
|
||||||
case TypeInt:
|
case TypeInt:
|
||||||
// SI: (none)
|
// SI: (none)
|
||||||
@ -537,7 +541,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri
|
|||||||
}
|
}
|
||||||
case TypeArray:
|
case TypeArray:
|
||||||
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
|
// OTA: <length: UN> <elementTag: tape.Tag> <values>*
|
||||||
nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource)
|
nn, err := this.generateDecodeBranchCall(typ, typeName, valueSource, tagSource)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
case TypeTable:
|
case TypeTable:
|
||||||
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
||||||
@ -549,7 +553,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri
|
|||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
case TypeTableDefined:
|
case TypeTableDefined:
|
||||||
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
// KTV: <length: UN> (<key: U16> <tag: Tag> <value>)*
|
||||||
nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource)
|
nn, err := this.generateDecodeBranchCall(typ, typeName, valueSource, tagSource)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
case TypeNamed:
|
case TypeNamed:
|
||||||
// WHATEVER: [WHATEVER]
|
// WHATEVER: [WHATEVER]
|
||||||
@ -576,24 +580,36 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri
|
|||||||
// - n int
|
// - n int
|
||||||
// - err error
|
// - err error
|
||||||
// - nn int
|
// - nn int
|
||||||
func (this *Generator) generateDecodeBranchCall(typ Type, valueSource, tagSource string) (n int, err error) {
|
//
|
||||||
|
// The typeName paramterer is handled in the way described in the documentation
|
||||||
|
// for [Generator.generateDecodeBranch].
|
||||||
|
func (this *Generator) generateDecodeBranchCall(typ Type, typeName, valueSource, tagSource string) (n int, err error) {
|
||||||
hash := HashType(typ)
|
hash := HashType(typ)
|
||||||
nn, err := this.iprintf("nn, err = %s(%s, decoder, %s)\n", this.decodeBranchName(hash), valueSource, tagSource)
|
nn, err := this.iprintf(
|
||||||
|
"nn, err = %s(%s, decoder, %s)\n",
|
||||||
|
this.decodeBranchName(hash, typeName), valueSource, tagSource)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
nn, err = this.generateErrorCheck()
|
nn, err = this.generateErrorCheck()
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
this.pushDecodeBranchRequest(hash, typ)
|
this.pushDecodeBranchRequest(hash, typ, typeName)
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateDecodeBranch generates an aggregate decoder function definition for a
|
// generateDecodeBranch generates an aggregate decoder function definition for a
|
||||||
// specified type. It assumes that hash == HashType(typ).
|
// specified type. It assumes that hash == HashType(typ). If typeName is not
|
||||||
func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err error) {
|
// empty, it will be used as the type in the argument list instead of the result
|
||||||
nn, err := this.iprintf("\nfunc %s[T ~", this.decodeBranchName(hash))
|
// of [Generator.generateType].
|
||||||
|
func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type, typeName string) (n int, err error) {
|
||||||
|
nn, err := this.iprintf("\nfunc %s(this *", this.decodeBranchName(hash, typeName))
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
nn, err = this.generateType(typ)
|
if typeName == "" {
|
||||||
n += nn; if err != nil { return n, err }
|
nn, err = this.generateType(typ)
|
||||||
nn, err = this.printf("](this *T, decoder *tape.Decoder, tag tape.Tag) (n int, err error) {\n")
|
n += nn; if err != nil { return n, err }
|
||||||
|
} else {
|
||||||
|
nn, err = this.print(typeName)
|
||||||
|
n += nn; if err != nil { return n, err }
|
||||||
|
}
|
||||||
|
nn, err = this.printf(", decoder *tape.Decoder, tag tape.Tag) (n int, err error) {\n")
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
this.push()
|
this.push()
|
||||||
|
|
||||||
@ -665,7 +681,7 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err
|
|||||||
nn, err = this.iprintf("for index := range int(%s) {\n", lengthVar)
|
nn, err = this.iprintf("for index := range int(%s) {\n", lengthVar)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
this.push()
|
this.push()
|
||||||
nn, err = this.generateDecodeValue(typ.Element, "(*this)[index]", elementTagVar)
|
nn, err = this.generateDecodeValue(typ.Element, "", "(*this)[index]", elementTagVar)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
this.pop()
|
this.pop()
|
||||||
nn, err = this.iprintf("}\n")
|
nn, err = this.iprintf("}\n")
|
||||||
@ -740,7 +756,9 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err
|
|||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
|
|
||||||
// decode payload
|
// decode payload
|
||||||
nn, err = this.generateDecodeValue(field.Type, fmt.Sprintf("&(this.%s)", field.Name), fieldTagVar)
|
nn, err = this.generateDecodeValue(
|
||||||
|
field.Type, "",
|
||||||
|
fmt.Sprintf("&(this.%s)", field.Name), fieldTagVar)
|
||||||
n += nn; if err != nil { return n, err }
|
n += nn; if err != nil { return n, err }
|
||||||
this.pop()
|
this.pop()
|
||||||
}
|
}
|
||||||
@ -775,31 +793,36 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Generator) decodeBranchName(hash [16]byte) string {
|
func (this *Generator) decodeBranchName(hash [16]byte, name string) string {
|
||||||
return fmt.Sprintf("decodeBranch_%s", hex.EncodeToString(hash[:]))
|
if name == "" {
|
||||||
|
return fmt.Sprintf("decodeBranch_%s", hex.EncodeToString(hash[:]))
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("decodeBranch_%s_%s", hex.EncodeToString(hash[:]), name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pushDecodeBranchRequest pushes a new branch decode function request to the
|
// pushDecodeBranchRequest pushes a new branch decode function request to the
|
||||||
// back of the queue, if it is not already in the queue.
|
// back of the queue, if it is not already in the queue.
|
||||||
func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type) {
|
func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type, name string) {
|
||||||
for _, item := range this.decodeBranchRequestQueue {
|
for _, item := range this.decodeBranchRequestQueue {
|
||||||
if item.hash == hash { return }
|
if item.hash == hash && item.name == name { return }
|
||||||
}
|
}
|
||||||
this.decodeBranchRequestQueue = append(this.decodeBranchRequestQueue, decodeBranchRequest {
|
this.decodeBranchRequestQueue = append(this.decodeBranchRequestQueue, decodeBranchRequest {
|
||||||
hash: hash,
|
hash: hash,
|
||||||
typ: typ,
|
typ: typ,
|
||||||
|
name: name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// pullDecodeBranchRequest pulls a branch decode function request from the front
|
// pullDecodeBranchRequest pulls a branch decode function request from the front
|
||||||
// of the queue.
|
// of the queue.
|
||||||
func (this *Generator) pullDecodeBranchRequest() (hash [16]byte, typ Type, ok bool) {
|
func (this *Generator) pullDecodeBranchRequest() (hash [16]byte, typ Type, name string, ok bool) {
|
||||||
if len(this.decodeBranchRequestQueue) < 1 {
|
if len(this.decodeBranchRequestQueue) < 1 {
|
||||||
return [16]byte { }, nil, false
|
return [16]byte { }, nil, "", false
|
||||||
}
|
}
|
||||||
request := this.decodeBranchRequestQueue[0]
|
request := this.decodeBranchRequestQueue[0]
|
||||||
this.decodeBranchRequestQueue = this.decodeBranchRequestQueue[1:]
|
this.decodeBranchRequestQueue = this.decodeBranchRequestQueue[1:]
|
||||||
return request.hash, request.typ, true
|
return request.hash, request.typ, request.name, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Generator) generateErrorCheck() (n int, err error) {
|
func (this *Generator) generateErrorCheck() (n int, err error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user