#include "value.h" #include #include #include namespace camellya { std::string NumberValue::to_string() const { if (std::floor(value) == value) { return std::to_string(static_cast(value)); } std::ostringstream oss; oss << std::fixed << std::setprecision(6) << value; std::string str = oss.str(); str.erase(str.find_last_not_of('0') + 1, std::string::npos); if (str.back() == '.') str.pop_back(); return str; } std::string ListValue::to_string() const { std::ostringstream oss; oss << "["; for (size_t i = 0; i < elements.size(); ++i) { if (i > 0) oss << ", "; oss << elements[i]->to_string(); } oss << "]"; return oss.str(); } ValuePtr ListValue::clone() const { std::vector cloned_elements; cloned_elements.reserve(elements.size()); for (const auto& elem : elements) { cloned_elements.push_back(elem->clone()); } return std::make_shared(std::move(cloned_elements)); } ValuePtr ListValue::get(size_t index) const { if (index >= elements.size()) { return std::make_shared(); } return elements[index]; } void ListValue::set(size_t index, ValuePtr value) { if (index >= elements.size()) { elements.resize(index + 1, std::make_shared()); } elements[index] = std::move(value); } std::string MapValue::to_string() const { std::ostringstream oss; oss << "{"; bool first = true; for (const auto& [key, value] : pairs) { if (!first) oss << ", "; first = false; oss << key << ": " << value->to_string(); } oss << "}"; return oss.str(); } ValuePtr MapValue::clone() const { std::map cloned_pairs; for (const auto& [key, value] : pairs) { cloned_pairs[key] = value->clone(); } return std::make_shared(std::move(cloned_pairs)); } ValuePtr MapValue::get(const std::string& key) const { auto it = pairs.find(key); if (it == pairs.end()) { return std::make_shared(); } return it->second; } ValuePtr ClassValue::clone() const { auto cloned = std::make_shared(name); cloned->fields = fields; cloned->methods = methods; return cloned; } ValuePtr InstanceValue::clone() const { auto cloned = std::make_shared(klass); for (const auto& [key, value] : fields) { cloned->fields[key] = value->clone(); } return cloned; } ValuePtr InstanceValue::get(const std::string& name) const { // First check fields auto field_it = fields.find(name); if (field_it != fields.end()) { return field_it->second; } // Then check methods and bind 'this' auto method_it = klass->methods.find(name); if (method_it != klass->methods.end()) { auto bound = std::make_shared(*method_it->second); auto self = std::static_pointer_cast( const_cast(this)->shared_from_this()); bound->bound_instance = self; return bound; } return std::make_shared(); } void InstanceValue::set(const std::string& name, ValuePtr value) { if (fields.find(name) != fields.end()) { fields[name] = std::move(value); } } } // namespace camellya