Skip to content

Commit 248564d

Browse files
author
half-arch
committed
fix: type(), floating point precision, and set printing
- type(): Fixed to use std::string() constructor explicitly (was returning boolean) - ValueToString(): Now uses ostringstream with precision 17 for full double precision - Set printing: Added HavelSet case to ValueToString() - type(): Added HavelSet case Test results: type(2.3) => "number" type(set(1,2,3)) => "set" let a = 1.23456789012345 => 1.23456789012345 (full precision) let b = 1.23456789012346 => 1.23456789012346 (distinguishable) set(1,2,2,3) => set(1, 2, 3) (deduped and printable)
1 parent a874b70 commit 248564d

2 files changed

Lines changed: 52 additions & 30 deletions

File tree

scripts/test_return.hv

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
let spd=44
3+
fn a(){ if firstChat {
4+
mouse.clickAt(1,1, 0, spd)
5+
return
6+
} else {
7+
mouse.moveTo(5, 3,spd)
8+
}}

src/havel-lang/runtime/Interpreter.cpp

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,23 @@ static HavelValue unwrap(HavelResult &result) {
7272
}
7373

7474
std::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

Comments
 (0)