diff --git a/lang/funcs/core/fmt/printf_func.go b/lang/funcs/core/fmt/printf_func.go index 34326212..4057cc83 100644 --- a/lang/funcs/core/fmt/printf_func.go +++ b/lang/funcs/core/fmt/printf_func.go @@ -379,6 +379,14 @@ func (obj *PrintfFunc) Close() error { // valueToString prints our values how we expect for printf. // FIXME: if this turns out to be useful, add it to the types package. func valueToString(value types.Value) string { + switch x := value.Type().Kind; x { + // FIXME: floats don't print nicely: https://github.com/golang/go/issues/46118 + case types.KindFloat: + // TODO: use formatting flags ? + // FIXME: Our String() method in FloatValue doesn't print nicely + return value.String() + } + // FIXME: this is just an "easy-out" implementation for now... return fmt.Sprintf("%v", value.Value()) diff --git a/lang/funcs/core/math/fortytwo_func.go b/lang/funcs/core/math/fortytwo_func.go new file mode 100644 index 00000000..02bd268e --- /dev/null +++ b/lang/funcs/core/math/fortytwo_func.go @@ -0,0 +1,69 @@ +// Mgmt +// Copyright (C) 2013-2021+ James Shubin and the project contributors +// Written by James Shubin and the project contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package coremath + +import ( + "fmt" + + "github.com/purpleidea/mgmt/lang/funcs/simplepoly" + "github.com/purpleidea/mgmt/lang/types" +) + +func init() { + typInt := types.NewType("func() int") + typFloat := types.NewType("func() float") + simplepoly.ModuleRegister(ModuleName, "fortytwo", []*types.FuncValue{ + { + T: typInt, + V: fortyTwo(typInt), // generate the correct function here + }, + { + T: typFloat, + V: fortyTwo(typFloat), + }, + }) +} + +// fortyTwo is a helper function to build the correct function for the desired +// signature, because the simplepoly API doesn't tell the implementing function +// what its signature should be! In the next version of this API, we could pass +// in a sig field, like how we demonstrate in the implementation of FortyTwo. If +// the API doesn't change, then this is an example of how to build this as a +// wrapper. +func fortyTwo(sig *types.Type) func([]types.Value) (types.Value, error) { + return func(input []types.Value) (types.Value, error) { + return FortyTwo(sig, input) + } +} + +// FortyTwo returns 42 as either an int or a float. This is not especially +// useful, but was built for a fun test case of a simple poly function with two +// different return types, but no input args. +func FortyTwo(sig *types.Type, input []types.Value) (types.Value, error) { + if sig.Out.Kind == types.KindInt { + return &types.IntValue{ + V: 42, + }, nil + } + if sig.Out.Kind == types.KindFloat { + return &types.FloatValue{ + V: 42.0, + }, nil + } + return nil, fmt.Errorf("unknown output type: %+v", sig.Out) +} diff --git a/lang/interpret_test/TestAstFunc2/fortytwo.output b/lang/interpret_test/TestAstFunc2/fortytwo.output new file mode 100644 index 00000000..a8afdb37 --- /dev/null +++ b/lang/interpret_test/TestAstFunc2/fortytwo.output @@ -0,0 +1,2 @@ +Vertex: test[float: 42] +Vertex: test[int: 42] diff --git a/lang/interpret_test/TestAstFunc2/fortytwo/main.mcl b/lang/interpret_test/TestAstFunc2/fortytwo/main.mcl new file mode 100644 index 00000000..3e888213 --- /dev/null +++ b/lang/interpret_test/TestAstFunc2/fortytwo/main.mcl @@ -0,0 +1,6 @@ +import "fmt" +import "math" +# FIXME: floats don't print nicely: https://github.com/golang/go/issues/46118 +# FIXME: This means that we see "42" for both, instead of 42.0 ... +test fmt.printf("int: %d", math.fortytwo()) {} +test fmt.printf("float: %f", math.fortytwo()) {} diff --git a/lang/types/value.go b/lang/types/value.go index f428d164..7022c0d5 100644 --- a/lang/types/value.go +++ b/lang/types/value.go @@ -708,6 +708,7 @@ func NewFloat() *FloatValue { return &FloatValue{} } // String returns a visual representation of this value. func (obj *FloatValue) String() string { // TODO: is this the right display mode? + // FIXME: floats don't print nicely: https://github.com/golang/go/issues/46118 return strconv.FormatFloat(obj.V, 'f', -1, 64) // -1 for exact precision }