diff --git a/generate/generate.go b/generate/generate.go index 8cb081a..427f638 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -87,7 +87,13 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) { n += nn; if err != nil { return n, err } } - // TODO: pull items from the request queue + // request queue + for { + hash, typ, ok := this.pullDecodeBranchRequest() + if !ok { break } + nn, err := this.generateDecodeBranch(hash, typ) + n += nn; if err != nil { return n, err } + } return n, nil } @@ -491,7 +497,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri } case TypeArray: // OTA: * - nn, err := this.generateDecodeBranch(typ, valueSource, tagSource) + nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource) n += nn; if err != nil { return n, err } case TypeTable: // KTV: ( )* @@ -503,7 +509,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri n += nn; if err != nil { return n, err } case TypeTableDefined: // KTV: ( )* - nn, err := this.generateDecodeBranch(typ, valueSource, tagSource) + nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource) n += nn; if err != nil { return n, err } case TypeNamed: // WHATEVER: [WHATEVER] @@ -518,8 +524,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri return n, nil } - -// generateDencodeValue generates code to call an aggregate decoder function, +// generateDecodeBranchCall generates code to call an aggregate decoder function, // for a specified type. The definition of the function is deferred so no // duplicates are created. The function overwrites memory pointed to by the // variable (or parenthetical statement) specified by valueSource, and the value @@ -531,10 +536,9 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri // - n int // - err error // - nn int -func (this *Generator) generateDecodeBranch(typ Type, valueSource, tagSource string) (n int, err error) { - hash := (HashType(typ)) - hashString := hex.EncodeToString(hash[:]) - nn, err := this.iprintf("nn, err = decodeBranch_%(%s, %s)\n", hashString, valueSource, tagSource) +func (this *Generator) generateDecodeBranchCall(typ Type, valueSource, tagSource string) (n int, err error) { + hash := HashType(typ) + nn, err := this.iprintf("nn, err = %s(%s, %s)\n", this.decodeBranchName(hash), valueSource, tagSource) n += nn; if err != nil { return n, err } nn, err = this.generateErrorCheck() n += nn; if err != nil { return n, err } @@ -542,6 +546,37 @@ func (this *Generator) generateDecodeBranch(typ Type, valueSource, tagSource str return n, nil } +// generateDecodeBranch generates an aggregate decoder function definition for a +// specified type. It assumes that hash == HashType(typ). +func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err error) { + nn, err := this.iprintf("func %s(this *", this.decodeBranchName(hash)) + n += nn; if err != nil { return n, err } + nn, err = this.generateType(typ) + n += nn; if err != nil { return n, err } + nn, err = this.printf(" decoder *tape.Decoder, tag tape.Tag) (nn int, err error) \n{") + n += nn; if err != nil { return n, err } + + switch typ := typ.(type) { + case TypeArray: + // OTA: * + + case TypeTableDefined: + // KTV: ( )* + // TODO + default: return n, fmt.Errorf("unexpected type: %T", typ) + } + + nn, err = this.iprintf("}") + n += nn; if err != nil { return n, err } + return n, nil +} + +func (this *Generator) decodeBranchName(hash [16]byte) string { + return fmt.Sprintf("decodeBranch_%s", hex.EncodeToString(hash[:])) +} + +// pushDecodeBranchRequest pushes a new branch decode function request to the +// back of the queue, if it is not already in the queue. func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type) { for _, item := range this.decodeBranchRequestQueue { if item.hash == hash { return } @@ -552,6 +587,8 @@ func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type) { }) } +// pullDecodeBranchRequest pulls a branch decode function request from the front +// of the queue. func (this *Generator) pullDecodeBranchRequest() (hash [16]byte, typ Type, ok bool) { if len(this.decodeBranchRequestQueue) < 1 { return [16]byte { }, nil, false