Compare commits

...

3 Commits

View File

@ -94,7 +94,7 @@ func (this *Generator) generateTypedef(name string, typ Type) (n int, err error)
nn, err = this.println() nn, err = this.println()
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
// Tag method // 'Tag' method
// to be honest we probably don't need this method at all // to be honest we probably don't need this method at all
// nn, err = this.iprintf("\n// Tag returns the preferred TAPE tag.\n") // nn, err = this.iprintf("\n// Tag returns the preferred TAPE tag.\n")
// n += nn; if err != nil { return n, err } // n += nn; if err != nil { return n, err }
@ -181,7 +181,7 @@ func (this *Generator) generateMessage(method uint16, message Message) (n int, e
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.println() nn, err = this.println()
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.iprintf("nn, err := encoder.WriteUint8()\n") nn, err = this.iprintf("nn, err := encoder.WriteUint8(uint8(tag))\n")
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 }
@ -217,13 +217,17 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
// SI stores the value in the tag, so we write nothing here // SI stores the value in the tag, so we write nothing here
break break
} }
nn, err := this.iprintf("nn, err = encoder.WriteInt%d(%s)\n", bitsToBytes(typ.Bits), valueSource) prefix := "WriteUint"
if typ.Signed {
prefix = "WriteInt"
}
nn, err := this.iprintf("nn, err = encoder.%s%d(%s)\n", prefix, typ.Bits, valueSource)
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 }
case TypeFloat: case TypeFloat:
// FP: <value: FloatN> // FP: <value: FloatN>
nn, err := this.iprintf("nn, err = encoder.WriteFloat%d(%s)\n", bitsToBytes(typ.Bits), valueSource) nn, err := this.iprintf("nn, err = encoder.WriteFloat%d(%s)\n", typ.Bits, valueSource)
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 }
@ -238,13 +242,13 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
this.push() this.push()
nn, err = this.iprintf( nn, err = this.iprintf(
"nn, err = encoder.WriteUintN(%s.CN(), uint64(len(%s)))\n", "nn, err = encoder.WriteUintN(uint64(%s.CN()), len(%s))\n",
tagSource, valueSource) tagSource, valueSource)
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.pop() this.pop()
nn, err = this.iprintf("}\n", tagSource) nn, err = this.iprintf("}\n")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.iprintf("nn, err = encoder.Write([]byte(%s))\n", valueSource) nn, err = this.iprintf("nn, err = encoder.Write([]byte(%s))\n", valueSource)
@ -254,7 +258,7 @@ func (this *Generator) generateEncodeValue(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.iprintf( nn, err := this.iprintf(
"nn, err = encoder.WriteUintN(%s.CN(), uint64(len(%s)))\n", "nn, err = encoder.WriteUintN(uint64(%s.CN()), len(%s))\n",
tagSource, valueSource) tagSource, valueSource)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.generateErrorCheck() nn, err = this.generateErrorCheck()
@ -268,9 +272,14 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.println() nn, err = this.println()
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
// TODO: we don't have to do this for loop for some
// types such as integers because the CN will be the
// same
nn, err = this.iprintf("for _, item := range %s {\n", valueSource) nn, err = this.iprintf("for _, item := range %s {\n", valueSource)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
this.push() this.push()
nn, err = this.iprintf("_ = item\n")
n += nn; if err != nil { return n, err }
nn, err = this.iprintf("tag := ") nn, err = this.iprintf("tag := ")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.generateTag(typ.Element, "item") nn, err = this.generateTag(typ.Element, "item")
@ -279,7 +288,7 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.iprintf("if tag.Is(tape.SBA) { continue }\n") nn, err = this.iprintf("if tag.Is(tape.SBA) { continue }\n")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
nn, err = this.iprintf("if tag.CN() > itemTag.CN() { largest = tag }\n") nn, err = this.iprintf("if tag.CN() > itemTag.CN() { itemTag = tag }\n")
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")
@ -342,6 +351,11 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeNamed: case TypeNamed:
// WHATEVER: [WHATEVER] // WHATEVER: [WHATEVER]
if builtin := this.resolveBuiltinType(typ.Name); builtin != nil {
nn, err := this.generateEncodeValue(builtin, valueSource, tagSource)
n += nn; if err != nil { return n, err }
return n, nil
}
nn, err := this.iprintf("nn, err = %s.EncodeValue(encoder, %s)\n", valueSource, tagSource) nn, err := this.iprintf("nn, err = %s.EncodeValue(encoder, %s)\n", 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()
@ -386,13 +400,13 @@ func (this *Generator) generateTag(typ Type, source string) (n int, err error) {
nn, err := this.printf("tape.FP.WithCN(%d)", bitsToCN(typ.Bits)) nn, err := this.printf("tape.FP.WithCN(%d)", bitsToCN(typ.Bits))
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeString: case TypeString:
nn, err := this.generateTag(TypeBuffer { }, source) nn, err := this.printf("tape.StringTag(%s)", source)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeBuffer: case TypeBuffer:
nn, err := this.printf("tape.BufferTag(%s)", source) nn, err := this.printf("tape.BufferTag(%s)", source)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeArray: case TypeArray:
nn, err := this.printf("arrayTag(tape.OTA.WithCN(tape.IntBytes(uint64(len(%s)))))", source) nn, err := this.printf("tape.OTA.WithCN(tape.IntBytes(uint64(len(%s))))", source)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeTable: case TypeTable:
nn, err := this.printf("tape.KTV.WithCN(tape.IntBytes(uint64(len(%s))))", source) nn, err := this.printf("tape.KTV.WithCN(tape.IntBytes(uint64(len(%s))))", source)
@ -418,29 +432,29 @@ func (this *Generator) generateTN(typ Type) (n int, err error) {
switch typ := typ.(type) { switch typ := typ.(type) {
case TypeInt: case TypeInt:
if typ.Bits <= 5 { if typ.Bits <= 5 {
nn, err := this.printf("tape.TagSI") nn, err := this.printf("tape.SI")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
} else { } else {
nn, err := this.printf("tape.TagLI") nn, err := this.printf("tape.LI")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
} }
case TypeFloat: case TypeFloat:
nn, err := this.printf("tape.TagFP",) nn, err := this.printf("tape.FP",)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeString: case TypeString:
nn, err := this.generateTN(TypeBuffer { }) nn, err := this.generateTN(TypeBuffer { })
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeBuffer: case TypeBuffer:
nn, err := this.printf("tape.TagLBA") nn, err := this.printf("tape.LBA")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeArray: case TypeArray:
nn, err := this.printf("tape.TagOTA") nn, err := this.printf("tape.OTA")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeTable: case TypeTable:
nn, err := this.printf("tape.TagKTV") nn, err := this.printf("tape.KTV")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeTableDefined: case TypeTableDefined:
nn, err := this.printf("tape.TagKTV") nn, err := this.printf("tape.KTV")
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeNamed: case TypeNamed:
resolved, err := this.resolveTypeName(typ.Name) resolved, err := this.resolveTypeName(typ.Name)
@ -494,9 +508,12 @@ func (this *Generator) generateType(typ Type) (n int, err error) {
nn, err := this.generateTypeTableDefined(typ) nn, err := this.generateTypeTableDefined(typ)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
case TypeNamed: case TypeNamed:
actual, err := this.resolveTypeName(typ.Name) if builtin := this.resolveBuiltinType(typ.Name); builtin != nil {
if err != nil { return n, err } nn, err := this.generateType(builtin)
nn, err := this.generateType(actual) n += nn; if err != nil { return n, err }
return n, nil
}
nn, err := this.print(typ.Name)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
} }
return n, nil return n, nil
@ -581,27 +598,8 @@ func (this *Generator) resolveMessageName(message string) string {
} }
func (this *Generator) resolveTypeName(name string) (Type, error) { func (this *Generator) resolveTypeName(name string) (Type, error) {
switch name { if typ := this.resolveBuiltinType(name); typ != nil {
case "U8": return TypeInt { Bits: 8 }, nil return typ, nil
case "U16": return TypeInt { Bits: 16 }, nil
case "U32": return TypeInt { Bits: 32 }, nil
case "U64": return TypeInt { Bits: 64 }, nil
case "U128": return TypeInt { Bits: 128 }, nil
case "U256": return TypeInt { Bits: 256 }, nil
case "I8": return TypeInt { Bits: 8, Signed: true }, nil
case "I16": return TypeInt { Bits: 16, Signed: true }, nil
case "I32": return TypeInt { Bits: 32, Signed: true }, nil
case "I64": return TypeInt { Bits: 64, Signed: true }, nil
case "I128": return TypeInt { Bits: 128, Signed: true }, nil
case "I256": return TypeInt { Bits: 256, Signed: true }, nil
case "F16": return TypeFloat { Bits: 16 }, nil
case "F32": return TypeFloat { Bits: 32 }, nil
case "F64": return TypeFloat { Bits: 64 }, nil
case "F128": return TypeFloat { Bits: 128 }, nil
case "F256": return TypeFloat { Bits: 256 }, nil
case "String": return TypeString { }, nil
case "Buffer": return TypeBuffer { }, nil
case "Table": return TypeTable { }, nil
} }
if typ, ok := this.protocol.Types[name]; ok { if typ, ok := this.protocol.Types[name]; ok {
@ -614,6 +612,32 @@ func (this *Generator) resolveTypeName(name string) (Type, error) {
return nil, fmt.Errorf("no type exists called %s", name) return nil, fmt.Errorf("no type exists called %s", name)
} }
func (this *Generator) resolveBuiltinType(name string) Type {
switch name {
case "U8": return TypeInt { Bits: 8 }
case "U16": return TypeInt { Bits: 16 }
case "U32": return TypeInt { Bits: 32 }
case "U64": return TypeInt { Bits: 64 }
case "U128": return TypeInt { Bits: 128 }
case "U256": return TypeInt { Bits: 256 }
case "I8": return TypeInt { Bits: 8, Signed: true }
case "I16": return TypeInt { Bits: 16, Signed: true }
case "I32": return TypeInt { Bits: 32, Signed: true }
case "I64": return TypeInt { Bits: 64, Signed: true }
case "I128": return TypeInt { Bits: 128, Signed: true }
case "I256": return TypeInt { Bits: 256, Signed: true }
case "F16": return TypeFloat { Bits: 16 }
case "F32": return TypeFloat { Bits: 32 }
case "F64": return TypeFloat { Bits: 64 }
case "F128": return TypeFloat { Bits: 128 }
case "F256": return TypeFloat { Bits: 256 }
case "String": return TypeString { }
case "Buffer": return TypeBuffer { }
case "Table": return TypeTable { }
}
return nil
}
func bitsToBytes(bits int) int { func bitsToBytes(bits int) int {
return int(math.Ceil(float64(bits) / 8.0)) return int(math.Ceil(float64(bits) / 8.0))
} }