fix
This commit is contained in:
@@ -24,6 +24,8 @@ namespace Fig
|
|||||||
|
|
||||||
std::shared_ptr<Context> closureContext;
|
std::shared_ptr<Context> closureContext;
|
||||||
|
|
||||||
|
FunctionStruct() = default;
|
||||||
|
|
||||||
FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body, ContextPtr _closureContext) :
|
FunctionStruct(Ast::FunctionParameters _paras, TypeInfo _retType, Ast::BlockStatement _body, ContextPtr _closureContext) :
|
||||||
id(nextId()), // 分配唯一 ID
|
id(nextId()), // 分配唯一 ID
|
||||||
paras(std::move(_paras)),
|
paras(std::move(_paras)),
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace Fig
|
|||||||
std::unordered_map<FString, Value> variables;
|
std::unordered_map<FString, Value> variables;
|
||||||
std::unordered_map<FString, AccessModifier> ams;
|
std::unordered_map<FString, AccessModifier> ams;
|
||||||
|
|
||||||
|
std::unordered_map<std::size_t, FunctionStruct> functions;
|
||||||
|
std::unordered_map<std::size_t, FString> functionNames;
|
||||||
public:
|
public:
|
||||||
ContextPtr parent;
|
ContextPtr parent;
|
||||||
|
|
||||||
@@ -113,13 +115,52 @@ namespace Fig
|
|||||||
}
|
}
|
||||||
void def(const FString &name, const TypeInfo &ti, AccessModifier am, const Value &value = Any())
|
void def(const FString &name, const TypeInfo &ti, AccessModifier am, const Value &value = Any())
|
||||||
{
|
{
|
||||||
if (variables.contains(name))
|
if (containsInThisScope(name))
|
||||||
{
|
{
|
||||||
throw RuntimeError(FStringView(std::format("Variable '{}' already defined in this scope", name.toBasicString())));
|
throw RuntimeError(FStringView(std::format("Variable '{}' already defined in this scope", name.toBasicString())));
|
||||||
}
|
}
|
||||||
variables[name] = value;
|
variables[name] = value;
|
||||||
varTypes[name] = ti;
|
varTypes[name] = ti;
|
||||||
ams[name] = am;
|
ams[name] = am;
|
||||||
|
|
||||||
|
if (ti == ValueType::Function and value.getTypeInfo() == ValueType::Function)
|
||||||
|
{
|
||||||
|
auto &fn = value.as<Function>().getValue();
|
||||||
|
functions[fn.id] = fn;
|
||||||
|
functionNames[fn.id] = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::optional<FunctionStruct> getFunction(std::size_t id)
|
||||||
|
{
|
||||||
|
auto it = functions.find(id);
|
||||||
|
if (it != functions.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
else if (parent)
|
||||||
|
{
|
||||||
|
return parent->getFunction(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::optional<FString> getFunctionName(std::size_t id)
|
||||||
|
{
|
||||||
|
auto it = functionNames.find(id);
|
||||||
|
if (it != functionNames.end())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
else if (parent)
|
||||||
|
{
|
||||||
|
return parent->getFunctionName(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool contains(const FString &name)
|
bool contains(const FString &name)
|
||||||
{
|
{
|
||||||
@@ -133,6 +174,11 @@ namespace Fig
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool containsInThisScope(const FString &name) const
|
||||||
|
{
|
||||||
|
return variables.contains(name);
|
||||||
|
}
|
||||||
|
|
||||||
TypeInfo getTypeInfo(const FString &name)
|
TypeInfo getTypeInfo(const FString &name)
|
||||||
{
|
{
|
||||||
if (varTypes.contains(name))
|
if (varTypes.contains(name))
|
||||||
|
|||||||
@@ -33,18 +33,18 @@ namespace Fig
|
|||||||
|
|
||||||
class SemicolonDisabler
|
class SemicolonDisabler
|
||||||
{
|
{
|
||||||
Parser &p;
|
Parser *p;
|
||||||
bool original;
|
bool original;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SemicolonDisabler(Parser &parser) :
|
SemicolonDisabler(Parser *parser) :
|
||||||
p(parser), original(p.needSemicolon)
|
p(parser), original(p->needSemicolon)
|
||||||
{
|
{
|
||||||
p.needSemicolon = false;
|
p->needSemicolon = false;
|
||||||
}
|
}
|
||||||
~SemicolonDisabler()
|
~SemicolonDisabler()
|
||||||
{
|
{
|
||||||
p.needSemicolon = original;
|
p->needSemicolon = original;
|
||||||
}
|
}
|
||||||
// disable copy and assign
|
// disable copy and assign
|
||||||
SemicolonDisabler(const SemicolonDisabler &) = delete;
|
SemicolonDisabler(const SemicolonDisabler &) = delete;
|
||||||
@@ -253,7 +253,7 @@ namespace Fig
|
|||||||
|
|
||||||
[[nodiscard]] SemicolonDisabler disableSemicolon()
|
[[nodiscard]] SemicolonDisabler disableSemicolon()
|
||||||
{
|
{
|
||||||
return SemicolonDisabler(*this);
|
return SemicolonDisabler(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void expectSemicolon()
|
void expectSemicolon()
|
||||||
|
|||||||
@@ -169,6 +169,12 @@ int main(int argc, char **argv)
|
|||||||
evaluator.printStackTrace();
|
evaluator.printStackTrace();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
std::cerr << "uncaught exception of: " << e.what() << '\n';
|
||||||
|
evaluator.printStackTrace();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// try
|
// try
|
||||||
// {
|
// {
|
||||||
|
|||||||
Reference in New Issue
Block a user