[VER] 0.3.3-alpha
[FEAT] interface + impl 支持! Duck Typing + 严格的检查让语言健壮 [FEAT][IMPL] 增加辅助函数 isTypeMatch等 [IMPL] TypeInfo构造函数FString 现在 explicit
This commit is contained in:
@@ -22,18 +22,20 @@ namespace Fig
|
||||
|
||||
ObjectPtr mapIndex;
|
||||
|
||||
LvObject(std::shared_ptr<VariableSlot> _slot) :
|
||||
slot(std::move(_slot))
|
||||
ContextPtr ctx;
|
||||
|
||||
LvObject(std::shared_ptr<VariableSlot> _slot, ContextPtr _ctx) :
|
||||
slot(std::move(_slot)), ctx(_ctx)
|
||||
{
|
||||
kind = Kind::Variable;
|
||||
}
|
||||
LvObject(ObjectPtr _v, size_t _index, Kind _kind) :
|
||||
value(_v), numIndex(_index)
|
||||
LvObject(ObjectPtr _v, size_t _index, Kind _kind, ContextPtr _ctx) :
|
||||
value(_v), numIndex(_index), ctx(_ctx)
|
||||
{
|
||||
kind = _kind;
|
||||
}
|
||||
LvObject(ObjectPtr _v, ObjectPtr _index, Kind _kind) :
|
||||
value(_v), mapIndex(_index)
|
||||
LvObject(ObjectPtr _v, ObjectPtr _index, Kind _kind, ContextPtr _ctx) :
|
||||
value(_v), mapIndex(_index), ctx(_ctx)
|
||||
{
|
||||
kind = _kind;
|
||||
}
|
||||
@@ -78,7 +80,7 @@ namespace Fig
|
||||
if (kind == Kind::Variable)
|
||||
{
|
||||
auto s = resolve(slot);
|
||||
if (s->declaredType != ValueType::Any && s->declaredType != v->getTypeInfo())
|
||||
if (!isTypeMatch(s->declaredType, v, ctx))
|
||||
{
|
||||
throw RuntimeError(
|
||||
FString(
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Fig
|
||||
}
|
||||
|
||||
TypeInfo();
|
||||
TypeInfo(FString _name, bool reg = false);
|
||||
explicit TypeInfo(const FString &_name, bool reg = false);
|
||||
TypeInfo(const TypeInfo &other) = default;
|
||||
|
||||
bool operator==(const TypeInfo &other) const
|
||||
@@ -68,7 +68,7 @@ namespace Fig
|
||||
extern const TypeInfo List;
|
||||
extern const TypeInfo Map;
|
||||
extern const TypeInfo Module;
|
||||
// extern const TypeInfo Tuple;
|
||||
extern const TypeInfo InterfaceType;
|
||||
|
||||
using IntClass = int64_t;
|
||||
using DoubleClass = double;
|
||||
|
||||
20
src/Value/interface.hpp
Normal file
20
src/Value/interface.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <Ast/Statements/InterfaceDefSt.hpp>
|
||||
#include <Value/Type.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
struct InterfaceType
|
||||
{
|
||||
TypeInfo type;
|
||||
std::vector<Ast::InterfaceMethod> methods;
|
||||
|
||||
bool operator==(const InterfaceType &other) const
|
||||
{
|
||||
return type == other.type; // only compare type info (chain -> typeinfo.id)
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "Value/Type.hpp"
|
||||
#include <Value/value.hpp>
|
||||
#include <Context/context.hpp>
|
||||
|
||||
@@ -7,12 +8,14 @@ namespace Fig
|
||||
{
|
||||
std::map<FString, size_t> TypeInfo::typeMap = {};
|
||||
|
||||
TypeInfo::TypeInfo() : // only allow use in evaluate time !! <---- dynamic type system requirement
|
||||
id(1), name(FString(u8"Any")) {}
|
||||
TypeInfo::TypeInfo(FString _name, bool reg)
|
||||
TypeInfo::TypeInfo() : // only allow use in evaluate time !! <---- dynamic type system requirement
|
||||
id(1), name(FString(u8"Any"))
|
||||
{
|
||||
}
|
||||
TypeInfo::TypeInfo(const FString &_name, bool reg)
|
||||
{
|
||||
static size_t id_count = 0;
|
||||
name = std::move(_name);
|
||||
name = _name;
|
||||
// std::cerr << "TypeInfo constructor called for type name: " << name.toBasicString() << "\n";
|
||||
if (reg)
|
||||
{
|
||||
@@ -21,10 +24,17 @@ namespace Fig
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!typeMap.contains(_name))
|
||||
{
|
||||
throw RuntimeError(FString(std::format(
|
||||
"No type named '{}'",
|
||||
_name.toBasicString())));
|
||||
// *this = ValueType::String;
|
||||
}
|
||||
id = typeMap.at(name); // may throw
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t ValueKeyHash::operator()(const ValueKey &key) const
|
||||
{
|
||||
{
|
||||
@@ -69,7 +79,7 @@ namespace Fig
|
||||
}
|
||||
}
|
||||
|
||||
FString prettyType(ObjectPtr obj)
|
||||
FString prettyType(std::shared_ptr<const Object> obj)
|
||||
{
|
||||
auto t = obj->getTypeInfo();
|
||||
if (t == ValueType::StructInstance)
|
||||
@@ -77,16 +87,51 @@ namespace Fig
|
||||
return t.toString();
|
||||
}
|
||||
|
||||
const TypeInfo ValueType::Any(FString(u8"Any"), true); // id: 1
|
||||
const TypeInfo ValueType::Null(FString(u8"Null"), true); // id: 2
|
||||
const TypeInfo ValueType::Int(FString(u8"Int"), true); // id: 3
|
||||
const TypeInfo ValueType::String(FString(u8"String"), true); // id: 4
|
||||
const TypeInfo ValueType::Bool(FString(u8"Bool"), true); // id: 5
|
||||
const TypeInfo ValueType::Double(FString(u8"Double"), true); // id: 6
|
||||
const TypeInfo ValueType::Function(FString(u8"Function"), true); // id: 7
|
||||
const TypeInfo ValueType::StructType(FString(u8"StructType"), true); // id: 8
|
||||
const TypeInfo ValueType::Any(FString(u8"Any"), true); // id: 1
|
||||
const TypeInfo ValueType::Null(FString(u8"Null"), true); // id: 2
|
||||
const TypeInfo ValueType::Int(FString(u8"Int"), true); // id: 3
|
||||
const TypeInfo ValueType::String(FString(u8"String"), true); // id: 4
|
||||
const TypeInfo ValueType::Bool(FString(u8"Bool"), true); // id: 5
|
||||
const TypeInfo ValueType::Double(FString(u8"Double"), true); // id: 6
|
||||
const TypeInfo ValueType::Function(FString(u8"Function"), true); // id: 7
|
||||
const TypeInfo ValueType::StructType(FString(u8"StructType"), true); // id: 8
|
||||
const TypeInfo ValueType::StructInstance(FString(u8"StructInstance"), true); // id: 9
|
||||
const TypeInfo ValueType::List(FString(u8"List"), true); // id: 10
|
||||
const TypeInfo ValueType::Map(FString(u8"Map"), true); // id: 11
|
||||
const TypeInfo ValueType::Module(FString(u8"Module"), true); // id: 12
|
||||
const TypeInfo ValueType::List(FString(u8"List"), true); // id: 10
|
||||
const TypeInfo ValueType::Map(FString(u8"Map"), true); // id: 11
|
||||
const TypeInfo ValueType::Module(FString(u8"Module"), true); // id: 12
|
||||
const TypeInfo ValueType::InterfaceType(FString(u8"InterfaceType"), true); // id: 13
|
||||
|
||||
|
||||
|
||||
bool implements(const TypeInfo &structType, const TypeInfo &interfaceType, ContextPtr ctx)
|
||||
{
|
||||
return ctx->hasImplRegisted(structType, interfaceType);
|
||||
}
|
||||
|
||||
bool isTypeMatch(const TypeInfo &expected, ObjectPtr obj, ContextPtr ctx)
|
||||
{
|
||||
if (expected == ValueType::Any)
|
||||
return true;
|
||||
|
||||
TypeInfo actual = obj->getTypeInfo();
|
||||
|
||||
if (obj->is<StructInstance>())
|
||||
{
|
||||
const StructInstance &si = obj->as<StructInstance>();
|
||||
if (si.parentType == expected)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (implements(si.parentType, expected, ctx))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return expected == actual;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Fig
|
||||
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
#include <Value/function.hpp>
|
||||
#include <Value/interface.hpp>
|
||||
#include <Value/structType.hpp>
|
||||
#include <Value/structInstance.hpp>
|
||||
#include <Value/Type.hpp>
|
||||
#include <Value/valueError.hpp>
|
||||
#include <Value/module.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
@@ -33,7 +35,7 @@ namespace Fig
|
||||
using ObjectPtr = std::shared_ptr<Object>;
|
||||
using List = std::vector<ObjectPtr>;
|
||||
|
||||
FString prettyType(ObjectPtr obj);
|
||||
FString prettyType(std::shared_ptr<const Object> obj);
|
||||
|
||||
struct ValueKey
|
||||
{
|
||||
@@ -48,7 +50,10 @@ namespace Fig
|
||||
};
|
||||
using Map = std::unordered_map<ValueKey, ObjectPtr, ValueKeyHash>;
|
||||
|
||||
class Object
|
||||
bool isTypeMatch(const TypeInfo &, ObjectPtr, ContextPtr);
|
||||
bool implements(const TypeInfo &, const TypeInfo &, ContextPtr);
|
||||
|
||||
class Object : public std::enable_shared_from_this<Object>
|
||||
{
|
||||
public:
|
||||
using VariantType = std::variant<
|
||||
@@ -62,7 +67,8 @@ namespace Fig
|
||||
StructInstance,
|
||||
List,
|
||||
Map,
|
||||
Module>;
|
||||
Module,
|
||||
InterfaceType>;
|
||||
|
||||
std::unordered_map<TypeInfo,
|
||||
std::unordered_map<FString,
|
||||
@@ -207,7 +213,9 @@ namespace Fig
|
||||
map.contains(index));
|
||||
}},
|
||||
}},
|
||||
{ValueType::Module, {}}};
|
||||
{ValueType::Module, {}},
|
||||
{ValueType::InterfaceType, {}},
|
||||
};
|
||||
std::unordered_map<TypeInfo, std::unordered_map<FString, int>, TypeInfoHash> memberTypeFunctionsParas{
|
||||
{ValueType::Null, {}},
|
||||
{ValueType::Int, {}},
|
||||
@@ -226,8 +234,8 @@ namespace Fig
|
||||
{u8"get", 1},
|
||||
{u8"contains", 1},
|
||||
}},
|
||||
{ValueType::Module, {}}
|
||||
|
||||
{ValueType::Module, {}},
|
||||
{ValueType::InterfaceType, {}},
|
||||
};
|
||||
bool hasMemberFunction(const FString &name) const
|
||||
{
|
||||
@@ -268,6 +276,8 @@ namespace Fig
|
||||
data(m) {}
|
||||
Object(const Module &m) :
|
||||
data(m) {}
|
||||
Object(const InterfaceType &i) :
|
||||
data(i) {}
|
||||
|
||||
Object(const Object &) = default;
|
||||
Object(Object &&) noexcept = default;
|
||||
@@ -364,6 +374,9 @@ namespace Fig
|
||||
else if constexpr (std::is_same_v<T, Module>)
|
||||
return ValueType::Module;
|
||||
|
||||
else if constexpr (std::is_same_v<T, InterfaceType>)
|
||||
return ValueType::InterfaceType;
|
||||
|
||||
else
|
||||
return ValueType::Any;
|
||||
},
|
||||
@@ -397,11 +410,11 @@ namespace Fig
|
||||
if (is<ValueType::StringClass>()) return FString(u8"<String \"") + as<ValueType::StringClass>() + FString(u8"\" >");
|
||||
if (is<ValueType::BoolClass>()) return as<ValueType::BoolClass>() ? FString(u8"true") : FString(u8"false");
|
||||
if (is<Function>())
|
||||
return FString(std::format("<Function {} at {:p}>",
|
||||
return FString(std::format("<Function '{}' at {:p}>",
|
||||
as<Function>().id,
|
||||
static_cast<const void *>(&as<Function>())));
|
||||
if (is<StructType>())
|
||||
return FString(std::format("<StructType {} at {:p}>",
|
||||
return FString(std::format("<StructType '{}' at {:p}>",
|
||||
as<StructType>().type.toString().toBasicString(),
|
||||
static_cast<const void *>(&as<StructType>())));
|
||||
if (is<StructInstance>())
|
||||
@@ -441,9 +454,17 @@ namespace Fig
|
||||
if (is<Module>())
|
||||
{
|
||||
return FString(std::format(
|
||||
"<Module at {:p}>",
|
||||
"<Module '{}' at {:p}>",
|
||||
as<Module>().name.toBasicString(),
|
||||
static_cast<const void *>(&as<Module>())));
|
||||
}
|
||||
if (is<InterfaceType>())
|
||||
{
|
||||
return FString(std::format(
|
||||
"<InterfaceType '{}' at {:p}",
|
||||
as<InterfaceType>().type.toString().toBasicString(),
|
||||
static_cast<const void *>(&as<InterfaceType>())));
|
||||
}
|
||||
return FString(u8"<error>");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user