github.com/expr-lang/expr@v1.16.9/vm/func_types/main.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "fmt" 6 "go/format" 7 "reflect" 8 "strings" 9 "text/template" 10 . "time" 11 ) 12 13 // Keep sorted. 14 var types = []any{ 15 nil, 16 new(func() Duration), 17 new(func() Month), 18 new(func() Time), 19 new(func() Weekday), 20 new(func() []any), 21 new(func() []byte), 22 new(func() any), 23 new(func() bool), 24 new(func() byte), 25 new(func() float32), 26 new(func() float64), 27 new(func() int), 28 new(func() int16), 29 new(func() int32), 30 new(func() int64), 31 new(func() int8), 32 new(func() map[string]any), 33 new(func() rune), 34 new(func() string), 35 new(func() uint), 36 new(func() uint16), 37 new(func() uint32), 38 new(func() uint64), 39 new(func() uint8), 40 new(func(Duration) Duration), 41 new(func(Duration) Time), 42 new(func(Time) Duration), 43 new(func(Time) bool), 44 new(func([]any) []any), 45 new(func([]any) any), 46 new(func([]any) map[string]any), 47 new(func([]any, string) string), 48 new(func([]byte) string), 49 new(func([]string, string) string), 50 new(func(any) []any), 51 new(func(any) any), 52 new(func(any) bool), 53 new(func(any) float64), 54 new(func(any) int), 55 new(func(any) map[string]any), 56 new(func(any) string), 57 new(func(any, any) []any), 58 new(func(any, any) any), 59 new(func(any, any) bool), 60 new(func(any, any) string), 61 new(func(bool) bool), 62 new(func(bool) float64), 63 new(func(bool) int), 64 new(func(bool) string), 65 new(func(bool, bool) bool), 66 new(func(float32) float64), 67 new(func(float64) bool), 68 new(func(float64) float32), 69 new(func(float64) float64), 70 new(func(float64) int), 71 new(func(float64) string), 72 new(func(float64, float64) bool), 73 new(func(int) bool), 74 new(func(int) float64), 75 new(func(int) int), 76 new(func(int) string), 77 new(func(int, int) bool), 78 new(func(int, int) int), 79 new(func(int, int) string), 80 new(func(int16) int32), 81 new(func(int32) float64), 82 new(func(int32) int), 83 new(func(int32) int64), 84 new(func(int64) Time), 85 new(func(int8) int), 86 new(func(int8) int16), 87 new(func(string) []byte), 88 new(func(string) []string), 89 new(func(string) bool), 90 new(func(string) float64), 91 new(func(string) int), 92 new(func(string) string), 93 new(func(string, byte) int), 94 new(func(string, int) int), 95 new(func(string, rune) int), 96 new(func(string, string) bool), 97 new(func(string, string) string), 98 new(func(uint) float64), 99 new(func(uint) int), 100 new(func(uint) uint), 101 new(func(uint16) uint), 102 new(func(uint32) uint64), 103 new(func(uint64) float64), 104 new(func(uint64) int64), 105 new(func(uint8) byte), 106 } 107 108 func main() { 109 data := struct { 110 Index string 111 Code string 112 }{} 113 114 for i, t := range types { 115 if i == 0 { 116 continue 117 } 118 fn := reflect.ValueOf(t).Elem().Type() 119 data.Index += fmt.Sprintf("%v: new(%v),\n", i, fn) 120 data.Code += fmt.Sprintf("case %d:\n", i) 121 args := make([]string, fn.NumIn()) 122 for j := fn.NumIn() - 1; j >= 0; j-- { 123 cast := fmt.Sprintf(".(%v)", fn.In(j)) 124 if fn.In(j).Kind() == reflect.Interface { 125 cast = "" 126 } 127 data.Code += fmt.Sprintf("arg%v := vm.pop()%v\n", j+1, cast) 128 args[j] = fmt.Sprintf("arg%v", j+1) 129 } 130 data.Code += fmt.Sprintf("return fn.(%v)(%v)\n", fn, strings.Join(args, ", ")) 131 } 132 133 var b bytes.Buffer 134 err := template.Must( 135 template.New("func_types"). 136 Parse(source), 137 ).Execute(&b, data) 138 if err != nil { 139 panic(err) 140 } 141 142 formatted, err := format.Source(b.Bytes()) 143 if err != nil { 144 panic(err) 145 } 146 fmt.Print(string(formatted)) 147 } 148 149 const source = `// Code generated by vm/func_types/main.go. DO NOT EDIT. 150 151 package vm 152 153 import ( 154 "fmt" 155 "time" 156 ) 157 158 var FuncTypes = []any{ 159 {{ .Index }} 160 } 161 162 func (vm *VM) call(fn any, kind int) any { 163 switch kind { 164 {{ .Code }} 165 } 166 panic(fmt.Sprintf("unknown function kind (%v)", kind)) 167 } 168 `