init
This commit is contained in:
211
value.h
Normal file
211
value.h
Normal file
@@ -0,0 +1,211 @@
|
||||
#ifndef CAMELLYA_VALUE_H
|
||||
#define CAMELLYA_VALUE_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <functional>
|
||||
|
||||
namespace camellya {
|
||||
|
||||
class Value;
|
||||
|
||||
using ValuePtr = std::shared_ptr<Value>;
|
||||
using NativeFunction = std::function<ValuePtr(const std::vector<ValuePtr>&)>;
|
||||
|
||||
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<NilValue>(); }
|
||||
};
|
||||
|
||||
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<NumberValue>(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<StringValue>(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<BoolValue>(value); }
|
||||
};
|
||||
|
||||
class ListValue : public Value {
|
||||
public:
|
||||
std::vector<ValuePtr> elements;
|
||||
|
||||
ListValue() = default;
|
||||
explicit ListValue(std::vector<ValuePtr> 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<std::string, ValuePtr> pairs;
|
||||
|
||||
MapValue() = default;
|
||||
explicit MapValue(std::map<std::string, ValuePtr> 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<std::pair<std::string, std::string>> parameters;
|
||||
std::string return_type;
|
||||
std::shared_ptr<FunctionDecl> declaration;
|
||||
NativeFunction native_func;
|
||||
bool is_native;
|
||||
std::shared_ptr<InstanceValue> bound_instance;
|
||||
|
||||
// Script function
|
||||
FunctionValue(std::string name, std::shared_ptr<FunctionDecl> declaration,
|
||||
std::shared_ptr<InstanceValue> 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 "<function " + name + ">"; }
|
||||
ValuePtr clone() const override { return std::make_shared<FunctionValue>(*this); }
|
||||
};
|
||||
|
||||
class ClassValue : public Value {
|
||||
public:
|
||||
std::string name;
|
||||
std::map<std::string, std::string> fields; // field_name -> type_name
|
||||
std::map<std::string, std::shared_ptr<FunctionValue>> methods;
|
||||
|
||||
explicit ClassValue(std::string name) : name(std::move(name)) {}
|
||||
|
||||
Type type() const override { return Type::CLASS; }
|
||||
std::string to_string() const override { return "<class " + name + ">"; }
|
||||
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<FunctionValue> method) {
|
||||
methods[name] = std::move(method);
|
||||
}
|
||||
};
|
||||
|
||||
class InstanceValue : public Value, public std::enable_shared_from_this<InstanceValue> {
|
||||
public:
|
||||
std::shared_ptr<ClassValue> klass;
|
||||
std::map<std::string, ValuePtr> fields;
|
||||
|
||||
explicit InstanceValue(std::shared_ptr<ClassValue> 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<NilValue>();
|
||||
}
|
||||
}
|
||||
|
||||
Type type() const override { return Type::INSTANCE; }
|
||||
std::string to_string() const override { return "<instance of " + klass->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<BoolValue>(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<NumberValue>(a)->value ==
|
||||
std::dynamic_pointer_cast<NumberValue>(b)->value;
|
||||
case Type::STRING:
|
||||
return std::dynamic_pointer_cast<StringValue>(a)->value ==
|
||||
std::dynamic_pointer_cast<StringValue>(b)->value;
|
||||
case Type::BOOL:
|
||||
return std::dynamic_pointer_cast<BoolValue>(a)->value ==
|
||||
std::dynamic_pointer_cast<BoolValue>(b)->value;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace camellya
|
||||
|
||||
#endif // CAMELLYA_VALUE_H
|
||||
Reference in New Issue
Block a user