This commit is contained in:
2025-12-22 13:39:17 +08:00
parent 720ae2bb26
commit 26bc387032
5 changed files with 69 additions and 12 deletions

View File

@@ -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)),

View File

@@ -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))

View File

@@ -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()

View File

@@ -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
// { // {

View File

@@ -1,6 +1,9 @@
const println := __fstdout_println; var call := 0;
func t()
for var i=0;i<10;i=i+1
{ {
println("Loop ", i); call = call + 1;
} __fstdout_println(call);
t();
}
t();