fix stupid protodef stuff
This commit is contained in:
File diff suppressed because one or more lines are too long
+10351
-11359
File diff suppressed because it is too large
Load Diff
+4957
-5965
File diff suppressed because it is too large
Load Diff
+5118
-6126
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,12 @@ type ContainerStackEntry struct {
|
||||
VarToSet ast.Expr
|
||||
}
|
||||
|
||||
type ExprGeneratorFunc func(g *Generator, data any) (ast.Expr, error)
|
||||
|
||||
type CompareToGeneratorFunc func(g *Generator, parts []string, inExpr ast.Expr, data any) (e ast.Expr, cet CaseExprType, err error)
|
||||
|
||||
type FunctionGeneratorFunc func(g *Generator, varToSet ast.Expr, data any, name string) ([]ast.Stmt, error)
|
||||
|
||||
type Generator struct {
|
||||
packetInfos []PacketInfo
|
||||
|
||||
@@ -60,7 +66,6 @@ type Generator struct {
|
||||
Depth int
|
||||
Declared []string
|
||||
ContainerStack []ContainerStackEntry
|
||||
VtsStack []ast.Expr
|
||||
}
|
||||
|
||||
func (g *Generator) Decl(name string, t token.Token, e ast.Expr) {
|
||||
@@ -104,12 +109,6 @@ func ParseType(t any) (tName string, tData any, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
type ExprGeneratorFunc func(g *Generator, data any) (ast.Expr, error)
|
||||
|
||||
type CompareToGeneratorFunc func(g *Generator, parts []string, inExpr ast.Expr, data any) (ast.Expr, error)
|
||||
|
||||
type FunctionGeneratorFunc func(g *Generator, varToSet ast.Expr, data any, name string) ([]ast.Stmt, error)
|
||||
|
||||
func (g *Generator) VisitType(data any) (e ast.Expr, err error) {
|
||||
tName, tData, err := ParseType(data)
|
||||
if err != nil {
|
||||
|
||||
@@ -6,10 +6,11 @@ import (
|
||||
"go/ast"
|
||||
"strings"
|
||||
|
||||
"github.com/admin-else/strom/proto_generator/protodef"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
func (g *Generator) ParseCompareTo(compareTo string) (e ast.Expr, err error) {
|
||||
func (g *Generator) ParseCompareTo(compareTo string) (e ast.Expr, cet CaseExprType, err error) {
|
||||
parts := strings.Split(compareTo, "/")
|
||||
downPrefixCount := 0
|
||||
for _, part := range parts {
|
||||
@@ -19,12 +20,12 @@ func (g *Generator) ParseCompareTo(compareTo string) (e ast.Expr, err error) {
|
||||
}
|
||||
parts = parts[downPrefixCount:]
|
||||
startingPoint := g.ContainerStack[len(g.ContainerStack)-downPrefixCount-1]
|
||||
e, err = g.VisitCompareTo(parts, startingPoint.VarToSet, CombineNamAndData("container", startingPoint.Data))
|
||||
e, cet, err = g.VisitCompareTo(parts, startingPoint.VarToSet, CombineNamAndData("container", startingPoint.Data))
|
||||
// return ParseCompareToLegacy(compareTo, varToSet)
|
||||
return
|
||||
}
|
||||
|
||||
func (g *Generator) VisitCompareTo(parts []string, inExpr ast.Expr, data any) (e ast.Expr, err error) {
|
||||
func (g *Generator) VisitCompareTo(parts []string, inExpr ast.Expr, data any) (e ast.Expr, cet CaseExprType, err error) {
|
||||
tName, tData, err := ParseType(data)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -37,7 +38,7 @@ func (g *Generator) VisitCompareTo(parts []string, inExpr ast.Expr, data any) (e
|
||||
return
|
||||
}
|
||||
|
||||
func ContainerCompareTo(g *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, err error) {
|
||||
func ContainerCompareTo(g *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
|
||||
var data []struct {
|
||||
Name string
|
||||
Type any
|
||||
@@ -62,11 +63,43 @@ func ContainerCompareTo(g *Generator, parts []string, inExpr ast.Expr, dataRaw a
|
||||
return
|
||||
}
|
||||
|
||||
func ReturnInputCompareTo(_ *Generator, _ []string, inExpr ast.Expr, _ any) (e ast.Expr, err error) {
|
||||
return inExpr, nil
|
||||
func ReturnInputCompareTo(_ *Generator, _ []string, inExpr ast.Expr, _ any) (e ast.Expr, cet CaseExprType, err error) {
|
||||
return inExpr, CaseExprTypeUnset, nil
|
||||
}
|
||||
|
||||
func BitflagsCompareTo(_ *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, err error) {
|
||||
func BitfieldCompareTo(_ *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
|
||||
var data protodef.BitField
|
||||
err = mapstructure.Decode(dataRaw, &data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fieldName, parts, found := PopFront(parts)
|
||||
if !found {
|
||||
err = errors.New("expected name part")
|
||||
return
|
||||
}
|
||||
var field struct {
|
||||
Name string
|
||||
Singed bool
|
||||
Size int
|
||||
}
|
||||
for _, f := range data {
|
||||
if f.Name == fieldName {
|
||||
field = f
|
||||
break
|
||||
}
|
||||
}
|
||||
if field.Size == 1 {
|
||||
cet = CaseExprTypeOnlyBool
|
||||
} else {
|
||||
cet = CaseExprTypeOnlyNumber
|
||||
}
|
||||
|
||||
e = SelectorExprAndStr(inExpr, CamelCase(fieldName))
|
||||
return
|
||||
}
|
||||
|
||||
func BitflagsCompareTo(_ *Generator, parts []string, inExpr ast.Expr, dataRaw any) (e ast.Expr, cet CaseExprType, err error) {
|
||||
var data struct {
|
||||
Flags []string
|
||||
Type any
|
||||
@@ -98,7 +131,7 @@ func (g *Generator) RegisterCompareToNatives() {
|
||||
"bool": ReturnInputCompareTo,
|
||||
"mapper": ReturnInputCompareTo,
|
||||
"varint": ReturnInputCompareTo,
|
||||
"bitfield": ReturnInputCompareTo,
|
||||
"bitfield": BitfieldCompareTo,
|
||||
"u8": ReturnInputCompareTo,
|
||||
"i8": ReturnInputCompareTo,
|
||||
"bitflags": BitflagsCompareTo,
|
||||
|
||||
@@ -136,7 +136,7 @@ func ArrayDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s
|
||||
if err == nil {
|
||||
e = NumLit(n)
|
||||
} else {
|
||||
e, err = g.ParseCompareTo(data.Count)
|
||||
e, _, err = g.ParseCompareTo(data.Count)
|
||||
}
|
||||
s2 = append(s2, Assign121(Ident(lName), e))
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func TypeForwardDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name strin
|
||||
return g.VisitDecoder(varToSet, data.Type, name)
|
||||
}
|
||||
|
||||
var DontStringify = []string{"true", "false"}
|
||||
var BooleanValues = []string{"true", "false"}
|
||||
|
||||
// CaseExprType This exists to fix this
|
||||
// "switch",
|
||||
@@ -194,13 +194,22 @@ var DontStringify = []string{"true", "false"}
|
||||
// "default": [
|
||||
//
|
||||
// Protodef is best!!!
|
||||
// they are also inconsistent with bool compare to sometimes they use false sometimes they use numbers
|
||||
// that's why this bullshit exists
|
||||
type CaseExprType int
|
||||
|
||||
const (
|
||||
CaseExprTypeUnset CaseExprType = iota
|
||||
CaseExprTypeNumber
|
||||
CaseExprTypeSpecial
|
||||
CaseExprTypeBool
|
||||
CaseExprTypeString
|
||||
|
||||
// CaseExprTypeOnlyNumber CaseExprTypeOnlyBool CaseExprTypeStringOnly These are special overwrite values retuned by
|
||||
// the compare to for the case of being certain that it's the right type.
|
||||
|
||||
CaseExprTypeOnlyNumber
|
||||
CaseExprTypeOnlyBool
|
||||
CaseExprTypeStringOnly
|
||||
)
|
||||
|
||||
func MultiTypeFix(s string, t *CaseExprType) (e ast.Expr) {
|
||||
@@ -210,9 +219,9 @@ func MultiTypeFix(s string, t *CaseExprType) (e ast.Expr) {
|
||||
err = nil
|
||||
e = NumLit(n)
|
||||
ct = CaseExprTypeNumber
|
||||
} else if slices.Contains(DontStringify, s) {
|
||||
} else if slices.Contains(BooleanValues, s) {
|
||||
e = Ident(s)
|
||||
ct = CaseExprTypeSpecial
|
||||
ct = CaseExprTypeBool
|
||||
} else {
|
||||
e = StrLit(s)
|
||||
ct = CaseExprTypeString
|
||||
@@ -222,9 +231,19 @@ func MultiTypeFix(s string, t *CaseExprType) (e ast.Expr) {
|
||||
*t = ct
|
||||
return
|
||||
}
|
||||
if *t != ct {
|
||||
e = nil
|
||||
if *t == ct {
|
||||
return
|
||||
}
|
||||
|
||||
if ct == CaseExprTypeNumber && *t == CaseExprTypeOnlyBool {
|
||||
if s == "0" {
|
||||
e = Ident("false")
|
||||
} else {
|
||||
e = Ident("true")
|
||||
}
|
||||
return
|
||||
}
|
||||
e = nil
|
||||
return
|
||||
}
|
||||
|
||||
@@ -238,11 +257,10 @@ func SwitchDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
compareToExpr, err := g.ParseCompareTo(data.CompareTo)
|
||||
compareToExpr, cet, err := g.ParseCompareTo(data.CompareTo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cet := CaseExprTypeUnset
|
||||
for _, fName := range OrderedKeys(data.Fields) {
|
||||
fType := data.Fields[fName]
|
||||
e := MultiTypeFix(fName, &cet)
|
||||
@@ -375,7 +393,7 @@ func BufferDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s
|
||||
func BitFieldDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) {
|
||||
var data []struct {
|
||||
Name string
|
||||
Singed bool
|
||||
Signed bool
|
||||
Size int
|
||||
}
|
||||
err = mapstructure.Decode(dataRaw, &data)
|
||||
@@ -386,11 +404,74 @@ func BitFieldDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string)
|
||||
for _, field := range data {
|
||||
totalSize += field.Size
|
||||
}
|
||||
p, err := BitSizeToUnsignedProtodefName(totalSize)
|
||||
packedTypeProtodef, err := BitSizeToUnsignedProtodefName(totalSize)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return g.VisitDecoder(varToSet, p, name)
|
||||
t, err := g.VisitType(packedTypeProtodef)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
packed := name + "Packed"
|
||||
packedVarStmt := VarStmt(packed, t)
|
||||
stmts, err := g.VisitDecoder(Ident(packed), packedTypeProtodef, name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s = append(s, packedVarStmt)
|
||||
s = append(s, stmts...)
|
||||
lShiftBy := 0
|
||||
for _, field := range data {
|
||||
var fieldTypeProtodef string
|
||||
if field.Signed {
|
||||
fieldTypeProtodef, err = BitSizeToSignedProtodefName(field.Size)
|
||||
} else {
|
||||
fieldTypeProtodef, err = BitSizeToUnsignedProtodefName(field.Size)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var fieldType ast.Expr
|
||||
fieldType, err = g.VisitType(fieldTypeProtodef)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rShiftBy := totalSize - field.Size
|
||||
fieldToSet := SelectorExprAndStr(varToSet, CamelCase(field.Name))
|
||||
|
||||
var getDataExpr ast.Expr
|
||||
getDataExpr = RightShift(
|
||||
LeftShift(
|
||||
Ident(packed),
|
||||
NumLit(lShiftBy)),
|
||||
NumLit(rShiftBy),
|
||||
)
|
||||
if fieldTypeProtodef == "bool" {
|
||||
getDataExpr = Equals(getDataExpr, NumLit(1))
|
||||
} else if fieldTypeProtodef != packedTypeProtodef {
|
||||
getDataExpr = Call(fieldType, getDataExpr)
|
||||
}
|
||||
|
||||
s = append(s, Assign121(fieldToSet, getDataExpr))
|
||||
if field.Signed {
|
||||
s = append(s, If(
|
||||
GreaterThanOrEqual(
|
||||
fieldToSet,
|
||||
LeftShift(NumLit(1), NumLit(field.Size-1)),
|
||||
),
|
||||
NewBlockEllipsis(
|
||||
SubAssign(
|
||||
fieldToSet,
|
||||
LeftShift(NumLit(1), NumLit(field.Size)),
|
||||
),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
lShiftBy += field.Size
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RegistryEntryHolderSetDecoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"go/ast"
|
||||
"go/token"
|
||||
|
||||
"github.com/admin-else/strom/proto_generator/protodef"
|
||||
"github.com/go-viper/mapstructure/v2"
|
||||
)
|
||||
|
||||
@@ -146,11 +147,7 @@ func BufferEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s
|
||||
}
|
||||
|
||||
func BitFieldEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s []ast.Stmt, err error) {
|
||||
var data []struct {
|
||||
Name string
|
||||
Singed bool
|
||||
Size int
|
||||
}
|
||||
var data protodef.BitField
|
||||
err = mapstructure.Decode(dataRaw, &data)
|
||||
if err != nil {
|
||||
return
|
||||
@@ -176,11 +173,10 @@ func SwitchEncoder(g *Generator, varToSet ast.Expr, dataRaw any, name string) (s
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
compareToExpr, err := g.ParseCompareTo(data.CompareTo)
|
||||
compareToExpr, cet, err := g.ParseCompareTo(data.CompareTo)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cet := CaseExprTypeUnset
|
||||
for _, fName := range OrderedKeys(data.Fields) {
|
||||
fType := data.Fields[fName]
|
||||
e := MultiTypeFix(fName, &cet)
|
||||
|
||||
@@ -27,7 +27,8 @@ func VisitContainerType(g *Generator, dataRaw any) (ast.Expr, error) {
|
||||
|
||||
s := NewStruct()
|
||||
for _, field := range data {
|
||||
t, err := g.VisitType(field.Type)
|
||||
var t ast.Expr
|
||||
t, err = g.VisitType(field.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -106,7 +107,9 @@ func BitSizeToSignedProtodefName(totalSize int) (e string, err error) {
|
||||
}
|
||||
|
||||
func BitSizeToUnsignedProtodefName(totalSize int) (e string, err error) {
|
||||
if totalSize <= 8 {
|
||||
if totalSize == 1 {
|
||||
e = "bool"
|
||||
} else if totalSize <= 8 {
|
||||
e = "u8"
|
||||
} else if totalSize <= 16 {
|
||||
e = "u16"
|
||||
@@ -123,23 +126,33 @@ func BitSizeToUnsignedProtodefName(totalSize int) (e string, err error) {
|
||||
func VisitBitFieldType(g *Generator, dataRaw any) (e ast.Expr, err error) {
|
||||
var data []struct {
|
||||
Name string
|
||||
Singed bool
|
||||
Signed bool
|
||||
Size int
|
||||
}
|
||||
err = mapstructure.Decode(dataRaw, &data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
totalSize := 0
|
||||
ret := NewStruct()
|
||||
for _, field := range data {
|
||||
totalSize += field.Size
|
||||
var p string
|
||||
if field.Signed {
|
||||
p, err = BitSizeToSignedProtodefName(field.Size)
|
||||
} else {
|
||||
p, err = BitSizeToUnsignedProtodefName(field.Size)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var fieldType ast.Expr
|
||||
fieldType, err = g.VisitType(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
AddFieldToStruct(ret, CamelCase(field.Name), fieldType)
|
||||
}
|
||||
// TODO: we will want to generate Methods and other stuff
|
||||
p, err := BitSizeToUnsignedProtodefName(totalSize)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return g.VisitType(p)
|
||||
e = ret
|
||||
return
|
||||
}
|
||||
|
||||
func VisitBitFlagsType(g *Generator, dataRaw any) (e ast.Expr, err error) {
|
||||
|
||||
@@ -186,6 +186,14 @@ func Define121(lhs, rhs ast.Expr) (s *ast.AssignStmt) {
|
||||
}
|
||||
}
|
||||
|
||||
func SubAssign(lhs, rhs ast.Expr) (s *ast.AssignStmt) {
|
||||
return &ast.AssignStmt{
|
||||
Lhs: []ast.Expr{lhs},
|
||||
Tok: token.SUB_ASSIGN,
|
||||
Rhs: []ast.Expr{rhs},
|
||||
}
|
||||
}
|
||||
|
||||
func Exprs(exprs ...ast.Expr) []ast.Expr {
|
||||
return exprs
|
||||
}
|
||||
@@ -231,6 +239,14 @@ func Equals(lhs, rhs ast.Expr) *ast.BinaryExpr {
|
||||
}
|
||||
}
|
||||
|
||||
func GreaterThanOrEqual(lhs, rhs ast.Expr) *ast.BinaryExpr {
|
||||
return &ast.BinaryExpr{
|
||||
X: lhs,
|
||||
Op: token.GEQ,
|
||||
Y: rhs,
|
||||
}
|
||||
}
|
||||
|
||||
func Nil() ast.Expr {
|
||||
return Ident("nil")
|
||||
}
|
||||
@@ -479,3 +495,19 @@ func BinAnd(lhs, rhs ast.Expr) *ast.BinaryExpr {
|
||||
Y: rhs,
|
||||
}
|
||||
}
|
||||
|
||||
func RightShift(lhs, rhs ast.Expr) *ast.BinaryExpr {
|
||||
return &ast.BinaryExpr{
|
||||
X: lhs,
|
||||
Op: token.SHR,
|
||||
Y: rhs,
|
||||
}
|
||||
}
|
||||
|
||||
func LeftShift(lhs, rhs ast.Expr) *ast.BinaryExpr {
|
||||
return &ast.BinaryExpr{
|
||||
X: lhs,
|
||||
Op: token.SHL,
|
||||
Y: rhs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package protodef
|
||||
|
||||
type BitField []struct {
|
||||
Name string
|
||||
Singed bool
|
||||
Size int
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package main
|
||||
Reference in New Issue
Block a user