github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/backend/golang/funcmap.go (about) 1 package golang 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/nevalang/neva/internal/compiler" 8 "github.com/nevalang/neva/internal/runtime/ir" 9 ) 10 11 func getMsg(msg *ir.Msg) (string, error) { 12 if msg == nil { 13 return "nil", nil 14 } 15 switch msg.Type { 16 case ir.MsgTypeBool: 17 return fmt.Sprintf("runtime.NewBoolMsg(%v)", msg.Bool), nil 18 case ir.MsgTypeInt: 19 return fmt.Sprintf("runtime.NewIntMsg(%v)", msg.Int), nil 20 case ir.MsgTypeFloat: 21 return fmt.Sprintf("runtime.NewFloatMsg(%v)", msg.Float), nil 22 case ir.MsgTypeString: 23 return fmt.Sprintf(`runtime.NewStrMsg("%v")`, msg.Str), nil 24 case ir.MsgTypeList: 25 s := `runtime.NewListMsg( 26 ` 27 for _, v := range msg.List { 28 el, err := getMsg(compiler.Pointer(v)) 29 if err != nil { 30 return "", err 31 } 32 s += fmt.Sprintf(` %v, 33 `, el) 34 } 35 return s + ")", nil 36 case ir.MsgTypeMap: 37 s := `runtime.NewMapMsg(map[string]runtime.Msg{ 38 ` 39 for k, v := range msg.Map { 40 el, err := getMsg(compiler.Pointer(v)) 41 if err != nil { 42 return "", err 43 } 44 s += fmt.Sprintf(` "%v": %v, 45 `, k, el) 46 } 47 return s + `}, 48 )`, nil 49 } 50 51 return "", fmt.Errorf("%w: %v", ErrUnknownMsgType, msg.Type) 52 } 53 54 func getConnComment(conn *ir.Connection) string { 55 s := fmtPortAddr(conn.SenderSide) + " -> " 56 for _, rcvr := range conn.ReceiverSides { 57 s += fmtPortAddr(rcvr.PortAddr) 58 } 59 return "// " + s 60 } 61 62 func fmtPortAddr(addr ir.PortAddr) string { 63 return fmt.Sprintf("%s:%s[%d]", addr.Path, addr.Port, addr.Idx) 64 } 65 66 func getPortChanName(addr *ir.PortAddr) string { 67 path := handleSpecialChars(addr.Path) 68 port := addr.Port 69 result := fmt.Sprintf("%s_%s_%d_port", path, port, addr.Idx) 70 return result 71 } 72 73 func getFuncIOPorts(addrs []ir.PortAddr) string { 74 m := map[string][]string{} 75 for _, addr := range addrs { 76 m[addr.Port] = append( 77 m[addr.Port], 78 getPortChanName(compiler.Pointer(addr)), 79 ) 80 } 81 82 s := "" 83 for port, chans := range m { 84 s += fmt.Sprintf(`"%s": {`, port) 85 for _, ch := range chans { 86 s += ch + "," 87 } 88 s += "},\n" 89 } 90 91 return s 92 } 93 94 func handleSpecialChars(portPath string) string { 95 var buffer bytes.Buffer 96 for _, r := range portPath { 97 switch r { 98 case '$', '.', '/', ':': 99 buffer.WriteRune('_') 100 default: 101 buffer.WriteRune(r) 102 } 103 } 104 return buffer.String() 105 }