forked from PuqiAR/Fig-TreeWalker
[VER] 0.3.7-alpha
[Fix] 修复科学表达式数字解析的问题(Lexer引起) 由 Satklomi发现,感谢 [Feat] 增加Compiler相关定义,将开发BytecodeVM [Tip] Evaluator进入Bug fix阶段,新功能延缓开发。转向VM
This commit is contained in:
143
src/Evaluator/Value/LvObject.hpp
Normal file
143
src/Evaluator/Value/LvObject.hpp
Normal file
@@ -0,0 +1,143 @@
|
||||
#pragma once
|
||||
|
||||
#include <Value/VariableSlot.hpp>
|
||||
#include <Value/value.hpp>
|
||||
|
||||
namespace Fig
|
||||
{
|
||||
|
||||
struct LvObject
|
||||
{
|
||||
enum class Kind
|
||||
{
|
||||
Variable,
|
||||
ListElement,
|
||||
MapElement,
|
||||
StringElement,
|
||||
} kind;
|
||||
std::shared_ptr<VariableSlot> slot;
|
||||
|
||||
ObjectPtr value = nullptr;
|
||||
size_t numIndex;
|
||||
|
||||
ObjectPtr mapIndex;
|
||||
|
||||
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, ContextPtr _ctx) :
|
||||
value(_v), numIndex(_index), ctx(_ctx)
|
||||
{
|
||||
kind = _kind;
|
||||
}
|
||||
LvObject(ObjectPtr _v, ObjectPtr _index, Kind _kind, ContextPtr _ctx) :
|
||||
value(_v), mapIndex(_index), ctx(_ctx)
|
||||
{
|
||||
kind = _kind;
|
||||
}
|
||||
|
||||
ObjectPtr get() const
|
||||
{
|
||||
if (kind == Kind::Variable)
|
||||
{
|
||||
auto s = resolve(slot);
|
||||
return s->value;
|
||||
}
|
||||
else if (kind == Kind::ListElement)
|
||||
{
|
||||
List &list = value->as<List>();
|
||||
if (numIndex >= list.size())
|
||||
throw RuntimeError(FString(
|
||||
std::format("Index {} out of range {}", numIndex, value->toString().toBasicString())));
|
||||
return list.at(numIndex).value;
|
||||
}
|
||||
else if (kind == Kind::MapElement) // map
|
||||
{
|
||||
Map &map = value->as<Map>();
|
||||
if (!map.contains(mapIndex))
|
||||
throw RuntimeError(FString(
|
||||
std::format("Key {} not found", mapIndex->toString().toBasicString())));
|
||||
return map.at(mapIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// string
|
||||
FString &string = value->as<ValueType::StringClass>();
|
||||
if (numIndex >= string.length())
|
||||
throw RuntimeError(FString(
|
||||
std::format("Index {} out of range {}", numIndex, value->toString().toBasicString())));
|
||||
|
||||
return std::make_shared<Object>(string.getRealChar(numIndex));
|
||||
}
|
||||
}
|
||||
|
||||
void set(const ObjectPtr &v)
|
||||
{
|
||||
if (kind == Kind::Variable)
|
||||
{
|
||||
auto s = resolve(slot);
|
||||
if (!isTypeMatch(s->declaredType, v, ctx))
|
||||
{
|
||||
throw RuntimeError(
|
||||
FString(
|
||||
std::format("Variable `{}` expects type `{}`, but got '{}'",
|
||||
s->name.toBasicString(),
|
||||
s->declaredType.toString().toBasicString(),
|
||||
v->getTypeInfo().toString().toBasicString())));
|
||||
}
|
||||
if (isAccessConst(s->am))
|
||||
{
|
||||
throw RuntimeError(FString(
|
||||
std::format("Variable `{}` is immutable", s->name.toBasicString())));
|
||||
}
|
||||
s->value = v;
|
||||
}
|
||||
else if (kind == Kind::ListElement)
|
||||
{
|
||||
List &list = value->as<List>();
|
||||
if (numIndex >= list.size())
|
||||
throw RuntimeError(FString(
|
||||
std::format("Index {} out of range", numIndex)));
|
||||
list[numIndex] = v;
|
||||
}
|
||||
else if (kind == Kind::MapElement) // map
|
||||
{
|
||||
Map &map = value->as<Map>();
|
||||
map[mapIndex] = v;
|
||||
}
|
||||
else if (kind == Kind::StringElement)
|
||||
{
|
||||
FString &string = value->as<ValueType::StringClass>();
|
||||
if (numIndex >= string.length())
|
||||
throw RuntimeError(FString(
|
||||
std::format("Index {} out of range {}", numIndex, value->toString().toBasicString())));
|
||||
|
||||
if (v->getTypeInfo() != ValueType::String)
|
||||
throw RuntimeError(FString(
|
||||
std::format("Could not assign {} to sub string", v->toString().toBasicString())
|
||||
));
|
||||
const FString &strReplace = v->as<ValueType::StringClass>();
|
||||
if (strReplace.length() > 1)
|
||||
throw RuntimeError(FString(
|
||||
std::format("Could not assign {} to sub string, expects length 1", v->toString().toBasicString())
|
||||
));
|
||||
string.realReplace(numIndex, strReplace);
|
||||
}
|
||||
}
|
||||
|
||||
FString name() const { return resolve(slot)->name; }
|
||||
TypeInfo declaredType() const { return resolve(slot)->declaredType; }
|
||||
AccessModifier access() const { return resolve(slot)->am; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<VariableSlot> resolve(std::shared_ptr<VariableSlot> s) const
|
||||
{
|
||||
while (s->isRef) s = s->refTarget;
|
||||
return s;
|
||||
}
|
||||
};
|
||||
} // namespace Fig
|
||||
Reference in New Issue
Block a user