diff --git a/generate/protocol.go b/generate/protocol.go index 1c3ebc4..1610c86 100644 --- a/generate/protocol.go +++ b/generate/protocol.go @@ -1,5 +1,10 @@ package generate +import "fmt" +import "maps" +import "slices" +import "crypto/md5" + type Protocol struct { Messages map[uint16] Message Types map[string] Type @@ -11,7 +16,7 @@ type Message struct { } type Type interface { - + fmt.Stringer } type TypeInt struct { @@ -19,29 +24,84 @@ type TypeInt struct { Signed bool } +func (typ TypeInt) String() string { + output := "" + if typ.Signed { + output += "I" + } else { + output += "U" + } + output += fmt.Sprint(typ.Bits) + return output +} + type TypeFloat struct { Bits int } +func (typ TypeFloat) String() string { + return fmt.Sprintf("F%d", typ.Bits) +} + type TypeString struct { } +func (TypeString) String() string { + return "String" +} + type TypeBuffer struct { } +func (TypeBuffer) String() string { + return "Buffer" +} + type TypeArray struct { Element Type } +func (typ TypeArray) String() string { + return fmt.Sprintf("[]%v", typ.Element) +} + type TypeTable struct { } +func (TypeTable) String() string { + return "Table" +} + type TypeTableDefined struct { Fields map[uint16] Field } +func (typ TypeTableDefined) String() string { + output := "{" + for _, key := range slices.Sorted(maps.Keys(typ.Fields)) { + output += fmt.Sprintf("%04X %v", key, typ.Fields[key]) + } + output += "}" + return output +} + type Field struct { Name string Type Type } +func (field Field) String() string { + return fmt.Sprintf("%s %v", field.Name, field.Type) +} + type TypeNamed struct { Name string } + +func (typ TypeNamed) String() string { + return typ.Name +} + +func HashType(typ Type) [16]byte { + // TODO: if we ever want to make the compiler more efficient, this would + // be a good place to start, complex string concatenation in a hot path + // (sorta) + return md5.Sum([]byte(typ.String())) +}