@@ -72,12 +72,23 @@ static HavelValue unwrap(HavelResult &result) {
7272}
7373
7474std::string Interpreter::ValueToString (const HavelValue &value) {
75- // Helper to format numbers nicely (remove trailing zeros)
75+ // Helper to format numbers nicely (remove trailing zeros, preserve precision )
7676 auto formatNumber = [](double d) -> std::string {
77- std::string s = std::to_string (d);
78- s.erase (s.find_last_not_of (' 0' ) + 1 , std::string::npos);
79- if (s.back () == ' .' )
80- s.pop_back ();
77+ // Use ostringstream with high precision
78+ std::ostringstream oss;
79+ oss.precision (17 ); // Max precision for double
80+ oss << d;
81+ std::string s = oss.str ();
82+
83+ // Remove trailing zeros after decimal point
84+ if (s.find (' .' ) != std::string::npos) {
85+ size_t last = s.find_last_not_of (' 0' );
86+ if (last != std::string::npos && s[last] == ' .' ) {
87+ s = s.substr (0 , last); // Remove decimal point too if no decimals
88+ } else if (last != std::string::npos) {
89+ s = s.substr (0 , last + 1 );
90+ }
91+ }
8192 return s;
8293 };
8394
@@ -124,6 +135,18 @@ std::string Interpreter::ValueToString(const HavelValue &value) {
124135 }
125136 result += " }" ;
126137 return result;
138+ } else if constexpr (std::is_same_v<T, HavelSet>) {
139+ // Format set like array but with set() notation
140+ std::string result = " set(" ;
141+ if (arg.elements ) {
142+ for (size_t i = 0 ; i < arg.elements ->size (); ++i) {
143+ result += ValueToString ((*arg.elements )[i]);
144+ if (i < arg.elements ->size () - 1 )
145+ result += " , " ;
146+ }
147+ }
148+ result += " )" ;
149+ return result;
127150 } else
128151 return " unprintable" ;
129152 },
@@ -3780,31 +3803,22 @@ void Interpreter::InitializeSystemBuiltins() {
37803803 BuiltinFunction ([](const std::vector<HavelValue> &args) -> HavelResult {
37813804 if (args.empty ())
37823805 return HavelRuntimeError (" type() requires an argument" );
3783- return std::visit (
3784- [](auto &&arg) -> HavelValue {
3785- using T = std::decay_t <decltype (arg)>;
3786- if constexpr (std::is_same_v<T, std::nullptr_t >)
3787- return HavelValue (" null" );
3788- else if constexpr (std::is_same_v<T, bool >)
3789- return HavelValue (" boolean" );
3790- else if constexpr (std::is_same_v<T, int > ||
3791- std::is_same_v<T, double >)
3792- return HavelValue (" number" );
3793- else if constexpr (std::is_same_v<T, std::string>)
3794- return HavelValue (" string" );
3795- else if constexpr (std::is_same_v<T, HavelArray>)
3796- return HavelValue (" array" );
3797- else if constexpr (std::is_same_v<T, HavelObject>)
3798- return HavelValue (" object" );
3799- else if constexpr (std::is_same_v<T,
3800- std::shared_ptr<HavelFunction>>)
3801- return HavelValue (" function" );
3802- else if constexpr (std::is_same_v<T, BuiltinFunction>)
3803- return HavelValue (" builtin" );
3804- else
3805- return HavelValue (" unknown" );
3806- },
3807- args[0 ].data );
3806+
3807+ // Check type using variant index
3808+ switch (args[0 ].data .index ()) {
3809+ case 0 : return HavelValue (std::string (" null" )); // nullptr_t
3810+ case 1 : return HavelValue (std::string (" boolean" )); // bool
3811+ case 2 : return HavelValue (std::string (" number" )); // int
3812+ case 3 : return HavelValue (std::string (" number" )); // double
3813+ case 4 : return HavelValue (std::string (" string" )); // std::string
3814+ case 5 : return HavelValue (std::string (" array" )); // HavelArray
3815+ case 6 : return HavelValue (std::string (" object" )); // HavelObject
3816+ case 7 : return HavelValue (std::string (" set" )); // HavelSet
3817+ case 8 : return HavelValue (std::string (" function" )); // shared_ptr<HavelFunction>
3818+ case 9 : return HavelValue (std::string (" channel" )); // shared_ptr<Channel>
3819+ case 10 : return HavelValue (std::string (" builtin" )); // BuiltinFunction
3820+ default : return HavelValue (std::string (" unknown" ));
3821+ }
38083822 }));
38093823
38103824 // Send text/keys to the system
0 commit comments