github.com/gotranspile/cxgo@v0.3.8-0.20240118201721-29871598a6a2/libs/math.go (about)

     1  package libs
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/gotranspile/cxgo/types"
     9  )
    10  
    11  const (
    12  	mathH = "math.h"
    13  )
    14  
    15  func init() {
    16  	const cpkg = "cmath"
    17  	RegisterLibrary(mathH, func(c *Env) *Library {
    18  		doubleT := types.FloatT(8)
    19  		floatT := types.FloatT(4)
    20  		var buf bytes.Buffer
    21  		buf.WriteString("const double M_PI_val = 3.1415;\n#define M_PI M_PI_val\n")
    22  		lib := &Library{
    23  			Imports: map[string]string{
    24  				cpkg:     RuntimePrefix + cpkg,
    25  				"math":   "math",
    26  				"math32": "github.com/chewxy/math32",
    27  			},
    28  			Idents: map[string]*types.Ident{
    29  				"atan2":    types.NewIdent("math.Atan2", c.FuncTT(doubleT, doubleT, doubleT)),
    30  				"modf":     types.NewIdent(cpkg+".Modf", c.FuncTT(doubleT, doubleT, c.PtrT(doubleT))),
    31  				"modff":    types.NewIdent(cpkg+".Modff", c.FuncTT(floatT, floatT, c.PtrT(floatT))),
    32  				"ldexp":    types.NewIdent("math.Ldexp", c.FuncTT(doubleT, doubleT, c.Go().Int())),
    33  				"fmod":     types.NewIdent("math.Mod", c.FuncTT(doubleT, doubleT, doubleT)),
    34  				"M_PI_val": types.NewIdent("math.Pi", doubleT),
    35  			},
    36  		}
    37  		func2arg := func(pkg, name, cname string, arg types.Type, argc string) {
    38  			fname := strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
    39  			lib.Idents[cname] = types.NewIdentGo(cname, pkg+"."+fname, c.FuncTT(arg, arg))
    40  			fmt.Fprintf(&buf, "%s %s(%s);\n", argc, cname, argc)
    41  		}
    42  		func3arg := func(pkg, name, cname string, arg types.Type, argc string) {
    43  			fname := strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
    44  			lib.Idents[cname] = types.NewIdentGo(cname, pkg+"."+fname, c.FuncTT(arg, arg, arg))
    45  			fmt.Fprintf(&buf, "%s %s(%s, %s);\n", argc, cname, argc, argc)
    46  		}
    47  		func2dfc := func(cname, name string) {
    48  			func2arg("math", name, cname, doubleT, "double")
    49  			// TODO: add Round to maze.io/x/math32
    50  			if cname == "round" {
    51  				fmt.Fprintf(&buf, "#define %sf(x) %s(x)\n", name, name)
    52  			} else {
    53  				func2arg("math32", name, cname+"f", floatT, "float")
    54  			}
    55  		}
    56  		func2df := func(name string) {
    57  			func2dfc(name, name)
    58  		}
    59  		func3df := func(name string) {
    60  			func3arg("math", name, name, doubleT, "double")
    61  			func3arg("math32", name, name+"f", floatT, "float")
    62  		}
    63  		for _, name := range []string{
    64  			"sin", "cos", "tan",
    65  		} {
    66  			for _, h := range []bool{false, true} {
    67  				for _, a := range []bool{false, true} {
    68  					ap := ""
    69  					if a {
    70  						ap = "a"
    71  					}
    72  					hs := ""
    73  					if h {
    74  						hs = "h"
    75  					}
    76  					func2df(ap + name + hs)
    77  				}
    78  			}
    79  		}
    80  		func2df("round")
    81  		func2df("ceil")
    82  		func2df("floor")
    83  		func2dfc("fabs", "abs")
    84  		func2dfc("fabsf", "abs")
    85  		func3df("pow")
    86  		func2df("sqrt")
    87  		func2df("exp")
    88  		func2df("exp2")
    89  		func2df("log")
    90  		func2df("log10")
    91  		func2df("log2")
    92  		buf.WriteString("double atan2(double y, double x);\n")
    93  		buf.WriteString("float atan2f(float y, float x);\n")
    94  		buf.WriteString("double modf(double x, double *iptr);\n")
    95  		buf.WriteString("float modff(float value, float *iptr);\n")
    96  		buf.WriteString("double ldexp(double x, _cxgo_go_int exp);\n")
    97  		buf.WriteString("double fmod(double x, double exp);\n")
    98  		buf.WriteString("int isnan(double x);\n")
    99  		buf.WriteString("double frexp(double x, int* exp);\n")
   100  		buf.WriteString("double hypot(double x, double y);\n")
   101  		buf.WriteString("float hypotf(float x, float y);\n")
   102  		buf.WriteString("double fmax(double x, double y);\n")
   103  		buf.WriteString("float fmaxf(float x, float y);\n")
   104  		lib.Header = buf.String()
   105  		return lib
   106  	})
   107  }