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 }