github.com/gotranspile/cxgo@v0.3.7/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("#include <" + BuiltinH + ">\n")
    22  		buf.WriteString("const double M_PI = 3.1415;\n")
    23  		lib := &Library{
    24  			Imports: map[string]string{
    25  				cpkg:     RuntimePrefix + cpkg,
    26  				"math":   "math",
    27  				"math32": "maze.io/x/math32",
    28  			},
    29  			Idents: map[string]*types.Ident{
    30  				"atan2": types.NewIdent("math.Atan2", c.FuncTT(doubleT, doubleT, doubleT)),
    31  				"modf":  types.NewIdent(cpkg+".Modf", c.FuncTT(doubleT, doubleT, c.PtrT(doubleT))),
    32  				"modff": types.NewIdent(cpkg+".Modff", c.FuncTT(floatT, floatT, c.PtrT(floatT))),
    33  				"ldexp": types.NewIdent("math.Ldexp", c.FuncTT(doubleT, doubleT, c.Go().Int())),
    34  				"fmod":  types.NewIdent("math.Mod", c.FuncTT(doubleT, doubleT, doubleT)),
    35  				"M_PI":  types.NewIdent("math.Pi", doubleT),
    36  			},
    37  		}
    38  		func2arg := func(pkg, name, cname string, arg types.Type, argc string) {
    39  			fname := strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
    40  			lib.Idents[cname] = types.NewIdentGo(cname, pkg+"."+fname, c.FuncTT(arg, arg))
    41  			fmt.Fprintf(&buf, "%s %s(%s);\n", argc, cname, argc)
    42  		}
    43  		func3arg := func(pkg, name, cname string, arg types.Type, argc string) {
    44  			fname := strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
    45  			lib.Idents[cname] = types.NewIdentGo(cname, pkg+"."+fname, c.FuncTT(arg, arg, arg))
    46  			fmt.Fprintf(&buf, "%s %s(%s, %s);\n", argc, cname, argc, argc)
    47  		}
    48  		func2dfc := func(cname, name string) {
    49  			func2arg("math", name, cname, doubleT, "double")
    50  			// TODO: add Round to maze.io/x/math32
    51  			if cname == "round" {
    52  				fmt.Fprintf(&buf, "#define %sf(x) %s(x)\n", name, name)
    53  			} else {
    54  				func2arg("math32", name, cname+"f", floatT, "float")
    55  			}
    56  		}
    57  		func2df := func(name string) {
    58  			func2dfc(name, name)
    59  		}
    60  		func3df := func(name string) {
    61  			func3arg("math", name, name, doubleT, "double")
    62  			func3arg("math32", name, name+"f", floatT, "float")
    63  		}
    64  		for _, name := range []string{
    65  			"sin", "cos", "tan",
    66  		} {
    67  			for _, h := range []bool{false, true} {
    68  				for _, a := range []bool{false, true} {
    69  					ap := ""
    70  					if a {
    71  						ap = "a"
    72  					}
    73  					hs := ""
    74  					if h {
    75  						hs = "h"
    76  					}
    77  					func2df(ap + name + hs)
    78  				}
    79  			}
    80  		}
    81  		func2df("round")
    82  		func2df("ceil")
    83  		func2df("floor")
    84  		func2dfc("fabs", "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("double modf(double x, double *iptr);\n")
    94  		buf.WriteString("float modff(float value, float *iptr);\n")
    95  		buf.WriteString("double ldexp(double x, _cxgo_go_int exp);\n")
    96  		buf.WriteString("double fmod(double x, double exp);\n")
    97  		buf.WriteString("int isnan(double x);\n")
    98  		buf.WriteString("double frexp(double x, int* exp);\n")
    99  		lib.Header = buf.String()
   100  		return lib
   101  	})
   102  }