#ifndef CAMELLYA_VALUE_H #define CAMELLYA_VALUE_H #include #include #include #include #include #include namespace camellya { class Value; using ValuePtr = std::shared_ptr; using NativeFunction = std::function&)>; enum class Type { NIL, NUMBER, STRING, BOOL, LIST, MAP, FUNCTION, CLASS, INSTANCE }; class Value { public: virtual ~Value() = default; virtual Type type() const = 0; virtual std::string to_string() const = 0; virtual ValuePtr clone() const = 0; }; class NilValue : public Value { public: Type type() const override { return Type::NIL; } std::string to_string() const override { return "nil"; } ValuePtr clone() const override { return std::make_shared(); } }; class NumberValue : public Value { public: double value; explicit NumberValue(double value) : value(value) {} Type type() const override { return Type::NUMBER; } std::string to_string() const override; ValuePtr clone() const override { return std::make_shared(value); } }; class StringValue : public Value { public: std::string value; explicit StringValue(std::string value) : value(std::move(value)) {} Type type() const override { return Type::STRING; } std::string to_string() const override { return value; } ValuePtr clone() const override { return std::make_shared(value); } }; class BoolValue : public Value { public: bool value; explicit BoolValue(bool value) : value(value) {} Type type() const override { return Type::BOOL; } std::string to_string() const override { return value ? "true" : "false"; } ValuePtr clone() const override { return std::make_shared(value); } }; class ListValue : public Value { public: std::vector elements; ListValue() = default; explicit ListValue(std::vector elements) : elements(std::move(elements)) {} Type type() const override { return Type::LIST; } std::string to_string() const override; ValuePtr clone() const override; void push(ValuePtr value) { elements.push_back(std::move(value)); } ValuePtr get(size_t index) const; void set(size_t index, ValuePtr value); size_t size() const { return elements.size(); } }; class MapValue : public Value { public: std::map pairs; MapValue() = default; explicit MapValue(std::map pairs) : pairs(std::move(pairs)) {} Type type() const override { return Type::MAP; } std::string to_string() const override; ValuePtr clone() const override; void set(const std::string& key, ValuePtr value) { pairs[key] = std::move(value); } ValuePtr get(const std::string& key) const; bool has(const std::string& key) const { return pairs.find(key) != pairs.end(); } }; // Forward declarations struct FunctionDecl; class ClassValue; class InstanceValue; class FunctionValue : public Value { public: std::string name; std::vector> parameters; std::string return_type; std::shared_ptr declaration; NativeFunction native_func; bool is_native; std::shared_ptr bound_instance; // Script function FunctionValue(std::string name, std::shared_ptr declaration, std::shared_ptr bound_instance = nullptr) : name(std::move(name)), declaration(std::move(declaration)), is_native(false), bound_instance(std::move(bound_instance)) {} // Native function FunctionValue(std::string name, NativeFunction func) : name(std::move(name)), native_func(std::move(func)), is_native(true) {} Type type() const override { return Type::FUNCTION; } std::string to_string() const override { return ""; } ValuePtr clone() const override { return std::make_shared(*this); } }; class ClassValue : public Value { public: std::string name; std::map fields; // field_name -> type_name std::map> methods; explicit ClassValue(std::string name) : name(std::move(name)) {} Type type() const override { return Type::CLASS; } std::string to_string() const override { return ""; } ValuePtr clone() const override; void add_field(const std::string& name, const std::string& type) { fields[name] = type; } void add_method(const std::string& name, std::shared_ptr method) { methods[name] = std::move(method); } }; class InstanceValue : public Value, public std::enable_shared_from_this { public: std::shared_ptr klass; std::map fields; explicit InstanceValue(std::shared_ptr klass) : klass(std::move(klass)) { // Initialize fields with nil for (const auto& [field_name, type_name] : this->klass->fields) { fields[field_name] = std::make_shared(); } } Type type() const override { return Type::INSTANCE; } std::string to_string() const override { return "name + ">"; } ValuePtr clone() const override; ValuePtr get(const std::string& name) const; void set(const std::string& name, ValuePtr value); }; // Helper functions inline bool is_truthy(const ValuePtr& value) { if (!value || value->type() == Type::NIL) return false; if (value->type() == Type::BOOL) { return std::dynamic_pointer_cast(value)->value; } return true; } inline bool values_equal(const ValuePtr& a, const ValuePtr& b) { if (!a || !b) return false; if (a->type() != b->type()) return false; switch (a->type()) { case Type::NIL: return true; case Type::NUMBER: return std::dynamic_pointer_cast(a)->value == std::dynamic_pointer_cast(b)->value; case Type::STRING: return std::dynamic_pointer_cast(a)->value == std::dynamic_pointer_cast(b)->value; case Type::BOOL: return std::dynamic_pointer_cast(a)->value == std::dynamic_pointer_cast(b)->value; default: return false; } } } // namespace camellya #endif // CAMELLYA_VALUE_H