github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/irgen/message.go (about) 1 package irgen 2 3 import ( 4 "errors" 5 6 "github.com/nevalang/neva/internal/compiler" 7 src "github.com/nevalang/neva/internal/compiler/sourcecode" 8 "github.com/nevalang/neva/internal/runtime/ir" 9 ) 10 11 func getIRMsgBySrcRef(constant src.Const, scope src.Scope) (*ir.Msg, *compiler.Error) { //nolint:funlen 12 if constant.Ref != nil { 13 entity, location, err := scope.Entity(*constant.Ref) 14 if err != nil { 15 return nil, &compiler.Error{ 16 Err: err, 17 Location: &scope.Location, 18 } 19 } 20 return getIRMsgBySrcRef(entity.Const, scope.WithLocation(location)) 21 } 22 23 switch { 24 case constant.Message.Bool != nil: 25 return &ir.Msg{ 26 Type: ir.MsgTypeBool, 27 Bool: *constant.Message.Bool, 28 }, nil 29 case constant.Message.Int != nil: 30 return &ir.Msg{ 31 Type: ir.MsgTypeInt, 32 Int: int64(*constant.Message.Int), 33 }, nil 34 case constant.Message.Float != nil: 35 return &ir.Msg{ 36 Type: ir.MsgTypeFloat, 37 Float: *constant.Message.Float, 38 }, nil 39 case constant.Message.Str != nil: 40 return &ir.Msg{ 41 Type: ir.MsgTypeString, 42 Str: *constant.Message.Str, 43 }, nil 44 case constant.Message.Enum != nil: 45 enumTypeExpr := constant.Message.TypeExpr.Lit.Enum 46 return &ir.Msg{ 47 Type: ir.MsgTypeInt, 48 Int: int64(getEnumMemberIndex(enumTypeExpr, constant.Message.Enum.MemberName)), 49 }, nil 50 case constant.Message.List != nil: 51 listMsg := make([]ir.Msg, len(constant.Message.List)) 52 53 for i, el := range constant.Message.List { 54 result, err := getIRMsgBySrcRef(el, scope) 55 if err != nil { 56 return nil, err 57 } 58 listMsg[i] = *result 59 } 60 61 return &ir.Msg{ 62 Type: ir.MsgTypeList, 63 List: listMsg, 64 }, nil 65 case constant.Message.MapOrStruct != nil: 66 mapMsg := make(map[string]ir.Msg, len(constant.Message.MapOrStruct)) 67 68 for name, el := range constant.Message.MapOrStruct { 69 result, err := getIRMsgBySrcRef(el, scope) 70 if err != nil { 71 return nil, err 72 } 73 mapMsg[name] = *result // see Q&A on why we don't create flat maps for nested structures 74 } 75 76 return &ir.Msg{ 77 Type: ir.MsgTypeMap, 78 Map: mapMsg, 79 }, nil 80 } 81 82 return nil, &compiler.Error{ 83 Err: errors.New("unknown msg type"), 84 Location: &scope.Location, 85 } 86 } 87 88 func getEnumMemberIndex(enum []string, value string) int { 89 for i, item := range enum { 90 if item == value { 91 return i 92 } 93 } 94 return -1 95 }