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  `