v0.3.1
This commit is contained in:
190
include/Value/BaseValue.hpp
Normal file
190
include/Value/BaseValue.hpp
Normal file
@@ -0,0 +1,190 @@
|
||||
#pragma once
|
||||
|
||||
#include <Value/Type.hpp>
|
||||
#include <fig_string.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <format>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
|
||||
template <class T>
|
||||
class __ValueWrapper
|
||||
{
|
||||
public:
|
||||
const TypeInfo ti;
|
||||
std::unique_ptr<T> data;
|
||||
|
||||
__ValueWrapper(const __ValueWrapper &other) :
|
||||
ti(other.ti)
|
||||
{
|
||||
if (other.data)
|
||||
data = std::make_unique<T>(*other.data);
|
||||
}
|
||||
|
||||
__ValueWrapper(__ValueWrapper &&other) noexcept
|
||||
:
|
||||
ti(other.ti), data(std::move(other.data)) {}
|
||||
|
||||
__ValueWrapper &operator=(const __ValueWrapper &other)
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
if (other.data)
|
||||
data = std::make_unique<T>(*other.data);
|
||||
else
|
||||
data.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
__ValueWrapper &operator=(__ValueWrapper &&other) noexcept
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
data = std::move(other.data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T &getValue() const
|
||||
{
|
||||
if (!data) throw std::runtime_error("Accessing null Value data");
|
||||
return *data;
|
||||
}
|
||||
|
||||
virtual size_t getSize() const
|
||||
{
|
||||
return sizeof(T);
|
||||
}
|
||||
|
||||
virtual bool isNull() const
|
||||
{
|
||||
return !data;
|
||||
}
|
||||
|
||||
virtual FString toString() const
|
||||
{
|
||||
if (!data)
|
||||
return FString(std::format("<{} object (null)>", ti.name.toBasicString()));
|
||||
|
||||
return FString(std::format(
|
||||
"<{} object @{:p}>",
|
||||
ti.name.toBasicString(),
|
||||
static_cast<const void *>(data.get())));
|
||||
}
|
||||
|
||||
__ValueWrapper(const TypeInfo &_ti) :
|
||||
ti(_ti) {}
|
||||
|
||||
__ValueWrapper(const T &x, const TypeInfo &_ti) :
|
||||
ti(_ti)
|
||||
{
|
||||
data = std::make_unique<T>(x);
|
||||
}
|
||||
};
|
||||
|
||||
class Int final : public __ValueWrapper<ValueType::IntClass>
|
||||
{
|
||||
public:
|
||||
Int(const ValueType::IntClass &x) :
|
||||
__ValueWrapper(x, ValueType::Int) {}
|
||||
|
||||
Int(const Int &) = default;
|
||||
Int(Int &&) noexcept = default;
|
||||
|
||||
Int &operator=(const Int &) = default;
|
||||
Int &operator=(Int &&) noexcept = default;
|
||||
|
||||
bool operator==(const Int &other) const noexcept
|
||||
{
|
||||
return getValue() == other.getValue();
|
||||
}
|
||||
bool operator!=(const Int &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class Double final : public __ValueWrapper<ValueType::DoubleClass>
|
||||
{
|
||||
public:
|
||||
Double(const ValueType::DoubleClass &x) :
|
||||
__ValueWrapper(x, ValueType::Double) {}
|
||||
Double(const Double &) = default;
|
||||
Double(Double &&) noexcept = default;
|
||||
|
||||
Double &operator=(const Double &) = default;
|
||||
Double &operator=(Double &&) noexcept = default;
|
||||
|
||||
bool operator==(const Double &other) const noexcept
|
||||
{
|
||||
return getValue() == other.getValue();
|
||||
}
|
||||
bool operator!=(const Double &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class Null final : public __ValueWrapper<ValueType::NullClass>
|
||||
{
|
||||
public:
|
||||
Null() :
|
||||
__ValueWrapper(ValueType::NullClass{}, ValueType::Null) {}
|
||||
|
||||
Null(const Null &) = default;
|
||||
Null(Null &&) noexcept = default;
|
||||
|
||||
Null &operator=(const Null &) = default;
|
||||
Null &operator=(Null &&) noexcept = default;
|
||||
|
||||
bool isNull() const override { return true; }
|
||||
bool operator==(const Null &) const noexcept { return true; }
|
||||
bool operator!=(const Null &) const noexcept { return false; }
|
||||
};
|
||||
|
||||
class String final : public __ValueWrapper<ValueType::StringClass>
|
||||
{
|
||||
public:
|
||||
String(const ValueType::StringClass &x) :
|
||||
__ValueWrapper(x, ValueType::String) {}
|
||||
String(const String &) = default;
|
||||
String(String &&) noexcept = default;
|
||||
|
||||
String &operator=(const String &) = default;
|
||||
String &operator=(String &&) noexcept = default;
|
||||
|
||||
bool operator==(const String &other) const noexcept
|
||||
{
|
||||
return getValue() == other.getValue();
|
||||
}
|
||||
bool operator!=(const String &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class Bool final : public __ValueWrapper<ValueType::BoolClass>
|
||||
{
|
||||
public:
|
||||
Bool(const ValueType::BoolClass &x) :
|
||||
__ValueWrapper(x, ValueType::Bool) {}
|
||||
|
||||
Bool(const Bool &) = default;
|
||||
Bool(Bool &&) noexcept = default;
|
||||
|
||||
Bool &operator=(const Bool &) = default;
|
||||
Bool &operator=(Bool &&) noexcept = default;
|
||||
|
||||
bool operator==(const Bool &other) const noexcept
|
||||
{
|
||||
return getValue() == other.getValue();
|
||||
}
|
||||
bool operator!=(const Bool &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
} // namespace Fig
|
||||
79
include/Value/Type.hpp
Normal file
79
include/Value/Type.hpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <fig_string.hpp>
|
||||
|
||||
#include <variant>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
|
||||
class TypeInfo final
|
||||
{
|
||||
private:
|
||||
size_t id;
|
||||
|
||||
public:
|
||||
FString name;
|
||||
|
||||
FString toString() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
static std::map<FString, size_t> typeMap;
|
||||
|
||||
static size_t getID(FString _name)
|
||||
{
|
||||
return typeMap.at(_name);
|
||||
}
|
||||
size_t getInstanceID(FString _name) const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
TypeInfo();
|
||||
TypeInfo(FString _name, bool reg = false);
|
||||
TypeInfo(const TypeInfo &other) = default;
|
||||
|
||||
bool operator==(const TypeInfo &other) const
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
};
|
||||
|
||||
// class Value;
|
||||
namespace ValueType
|
||||
{
|
||||
extern const TypeInfo Any;
|
||||
extern const TypeInfo Null;
|
||||
extern const TypeInfo Int;
|
||||
extern const TypeInfo String;
|
||||
extern const TypeInfo Bool;
|
||||
extern const TypeInfo Double;
|
||||
extern const TypeInfo Function;
|
||||
extern const TypeInfo StructType;
|
||||
extern const TypeInfo StructInstance;
|
||||
extern const TypeInfo List;
|
||||
extern const TypeInfo Map;
|
||||
extern const TypeInfo Tuple;
|
||||
|
||||
using IntClass = int64_t;
|
||||
using DoubleClass = double;
|
||||
using BoolClass = bool;
|
||||
using NullClass = std::monostate;
|
||||
using StringClass = FString;
|
||||
|
||||
/* complex types */
|
||||
struct FunctionStruct;
|
||||
using FunctionClass = FunctionStruct;
|
||||
|
||||
struct StructT;
|
||||
using StructTypeClass = StructT;
|
||||
|
||||
struct StructInstanceT;
|
||||
using StructInstanceClass = StructInstanceT;
|
||||
}; // namespace ValueType
|
||||
}; // namespace Fig
|
||||
74
include/Value/function.hpp
Normal file
74
include/Value/function.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <Value/BaseValue.hpp>
|
||||
#include <Value/Type.hpp>
|
||||
#include <Ast/functionParameters.hpp>
|
||||
|
||||
#include <atomic>
|
||||
namespace Fig
|
||||
{
|
||||
/* complex objects */
|
||||
struct FunctionStruct
|
||||
{
|
||||
std::size_t id;
|
||||
Ast::FunctionParameters paras;
|
||||
TypeInfo retType;
|
||||
Ast::BlockStatement body;
|
||||
|
||||
FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body) :
|
||||
id(nextId()), // 分配唯一 ID
|
||||
paras(std::move(_paras)),
|
||||
retType(std::move(_retType)),
|
||||
body(std::move(_body))
|
||||
{
|
||||
}
|
||||
|
||||
FunctionStruct(const FunctionStruct &other) :
|
||||
id(other.id), paras(other.paras), retType(other.retType), body(other.body) {}
|
||||
|
||||
FunctionStruct &operator=(const FunctionStruct &other) = default;
|
||||
FunctionStruct(FunctionStruct &&) noexcept = default;
|
||||
FunctionStruct &operator=(FunctionStruct &&) noexcept = default;
|
||||
|
||||
bool operator==(const FunctionStruct &other) const noexcept
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
bool operator!=(const FunctionStruct &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
static std::size_t nextId()
|
||||
{
|
||||
static std::atomic<std::size_t> counter{1};
|
||||
return counter++;
|
||||
}
|
||||
};
|
||||
|
||||
class Function final : public __ValueWrapper<FunctionStruct>
|
||||
{
|
||||
public:
|
||||
Function(const FunctionStruct &x) :
|
||||
__ValueWrapper(ValueType::Function)
|
||||
{
|
||||
data = std::make_unique<FunctionStruct>(x);
|
||||
}
|
||||
Function(Ast::FunctionParameters paras, TypeInfo ret, Ast::BlockStatement body) :
|
||||
__ValueWrapper(ValueType::Function)
|
||||
{
|
||||
data = std::make_unique<FunctionStruct>(
|
||||
std::move(paras), std::move(ret), std::move(body));
|
||||
}
|
||||
bool operator==(const Function &other) const noexcept
|
||||
{
|
||||
if (!data || !other.data) return false;
|
||||
return *data == *other.data; // call -> FunctionStruct::operator== (based on ID comparing)
|
||||
}
|
||||
Function(const Function &) = default;
|
||||
Function(Function &&) noexcept = default;
|
||||
Function &operator=(const Function &) = default;
|
||||
Function &operator=(Function &&) noexcept = default;
|
||||
};
|
||||
} // namespace Fig
|
||||
50
include/Value/structInstance.hpp
Normal file
50
include/Value/structInstance.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <Value/BaseValue.hpp>
|
||||
|
||||
#include <context_forward.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct StructInstanceT final
|
||||
{
|
||||
FString structName; // 类的名字 (StructType), 非变量名。用于获取所属类
|
||||
ContextPtr localContext;
|
||||
|
||||
StructInstanceT(FString _structName, ContextPtr _localContext) :
|
||||
structName(std::move(_structName)), localContext(std::move(_localContext)) {}
|
||||
|
||||
StructInstanceT(const StructInstanceT &other) :
|
||||
structName(other.structName), localContext(other.localContext) {}
|
||||
StructInstanceT &operator=(const StructInstanceT &) = default;
|
||||
StructInstanceT(StructInstanceT &&) = default;
|
||||
StructInstanceT &operator=(StructInstanceT &&) = default;
|
||||
|
||||
bool operator==(const StructInstanceT &) const = default;
|
||||
};
|
||||
|
||||
class StructInstance final : public __ValueWrapper<StructInstanceT>
|
||||
{
|
||||
public:
|
||||
StructInstance(const StructInstanceT &x) :
|
||||
__ValueWrapper(ValueType::StructInstance)
|
||||
{
|
||||
data = std::make_unique<StructInstanceT>(x);
|
||||
}
|
||||
StructInstance(FString _structName, ContextPtr _localContext) :
|
||||
__ValueWrapper(ValueType::StructInstance)
|
||||
{
|
||||
data = std::make_unique<StructInstanceT>(std::move(_structName), std::move(_localContext));
|
||||
}
|
||||
|
||||
bool operator==(const StructInstance &other) const noexcept
|
||||
{
|
||||
return data == other.data;
|
||||
}
|
||||
StructInstance(const StructInstance &) = default;
|
||||
StructInstance(StructInstance &&) = default;
|
||||
StructInstance &operator=(const StructInstance &) = default;
|
||||
StructInstance &operator=(StructInstance &&) = default;
|
||||
};
|
||||
|
||||
}; // namespace Fig
|
||||
95
include/Value/structType.hpp
Normal file
95
include/Value/structType.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
|
||||
#include <fig_string.hpp>
|
||||
#include <Ast/StructDefSt.hpp>
|
||||
|
||||
#include <Value/Type.hpp>
|
||||
#include <Value/BaseValue.hpp>
|
||||
|
||||
#include <context_forward.hpp>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct Field
|
||||
{
|
||||
bool isPublic() const
|
||||
{
|
||||
return am == AccessModifier::Public or am == AccessModifier::PublicConst or am == AccessModifier::PublicFinal;
|
||||
}
|
||||
bool isConst() const
|
||||
{
|
||||
return am == AccessModifier::Const or am == AccessModifier::PublicConst;
|
||||
}
|
||||
bool isFinal() const
|
||||
{
|
||||
return am == AccessModifier::Final or am == AccessModifier::PublicFinal;
|
||||
}
|
||||
|
||||
AccessModifier am;
|
||||
FString name;
|
||||
TypeInfo type;
|
||||
Ast::Expression defaultValue;
|
||||
|
||||
Field(AccessModifier _am, FString _name, TypeInfo _type, Ast::Expression _defaultValue) :
|
||||
am(std::move(_am)), name(std::move(_name)), type(std::move(_type)), defaultValue(std::move(_defaultValue)) {}
|
||||
};
|
||||
struct StructT final// = StructType 结构体定义
|
||||
{
|
||||
std::size_t id;
|
||||
ContextPtr defContext; // 定义时的上下文
|
||||
std::vector<Field> fields;
|
||||
StructT(ContextPtr _defContext, std::vector<Field> fieldsMap) :
|
||||
defContext(std::move(_defContext)),
|
||||
fields(std::move(fieldsMap))
|
||||
{
|
||||
id = nextId();
|
||||
}
|
||||
StructT(const StructT &other) :
|
||||
id(other.id), fields(other.fields) {}
|
||||
StructT &operator=(const StructT &other) = default;
|
||||
StructT(StructT &&) noexcept = default;
|
||||
StructT &operator=(StructT &&) noexcept = default;
|
||||
|
||||
bool operator==(const StructT &other) const noexcept
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
bool operator!=(const StructT &other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
private:
|
||||
static std::size_t nextId()
|
||||
{
|
||||
static std::atomic<std::size_t> counter{1};
|
||||
return counter++;
|
||||
}
|
||||
};
|
||||
|
||||
class StructType final : public __ValueWrapper<StructT>
|
||||
{
|
||||
public:
|
||||
StructType(const StructT &x) :
|
||||
__ValueWrapper(ValueType::StructType)
|
||||
{
|
||||
data = std::make_unique<StructT>(x);
|
||||
}
|
||||
StructType(ContextPtr _defContext, std::vector<Field> fieldsMap) :
|
||||
__ValueWrapper(ValueType::StructType)
|
||||
{
|
||||
data = std::make_unique<StructT>(std::move(_defContext), std::move(fieldsMap));
|
||||
}
|
||||
bool operator==(const StructType &other) const noexcept
|
||||
{
|
||||
return data == other.data;
|
||||
}
|
||||
StructType(const StructType &) = default;
|
||||
StructType(StructType &&) noexcept = default;
|
||||
StructType &operator=(const StructType &) = default;
|
||||
StructType &operator=(StructType &&) noexcept = default;
|
||||
};
|
||||
|
||||
}; // namespace Fig
|
||||
17
include/Value/valueError.hpp
Normal file
17
include/Value/valueError.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <error.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
class ValueError : public UnaddressableError
|
||||
{
|
||||
public:
|
||||
using UnaddressableError::UnaddressableError;
|
||||
virtual FString toString() const override
|
||||
{
|
||||
std::string msg = std::format("[ValueError] {} in [{}] {}", std::string(this->message.begin(), this->message.end()), this->src_loc.file_name(), this->src_loc.function_name());
|
||||
return FString(msg);
|
||||
}
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user