Files
Fig/include/evaluator.hpp
PuqiAR 6226059adc [Fix] 修复无法调用类函数的问题
[Feat] Context merge功能
[Feat] VSCode 拓展现已更为 fig-vscode.
2025-12-23 01:15:35 +08:00

131 lines
4.1 KiB
C++

#pragma once
#include <builtins.hpp>
#include <error.hpp>
#include <fig_string.hpp>
#include <ast.hpp>
#include <value.hpp>
#include <context.hpp>
#include <parser.hpp>
namespace Fig
{
template <const char *errName>
class EvaluatorError final : public AddressableError
{
public:
const char* errorName = errName;
virtual FString toString() const override
{
std::string msg = std::format("[Eve: {}] {} in [{}] {}", errName, std::string(this->message.begin(), this->message.end()), this->src_loc.file_name(), this->src_loc.function_name());
return FString(msg);
}
using AddressableError::AddressableError;
explicit EvaluatorError(FStringView _msg,
Ast::AstAddressInfo aai,
std::source_location loc = std::source_location::current()) :
AddressableError(_msg, aai.line, aai.column, loc)
{
}
virtual FString getErrorType() const override
{
return FString("[Eval]" + std::string(errorName));
}
};
struct StatementResult
{
ObjectPtr result;
enum class Flow
{
Normal,
Return,
Break,
Continue
} flow;
StatementResult(ObjectPtr val, Flow f = Flow::Normal) :
result(val), flow(f)
{
}
static StatementResult normal(ObjectPtr val = Object::getNullInstance())
{
return StatementResult(val, Flow::Normal);
}
static StatementResult returnFlow(ObjectPtr val)
{
return StatementResult(val, Flow::Return);
}
static StatementResult breakFlow()
{
return StatementResult(Object::getNullInstance(), Flow::Break);
}
static StatementResult continueFlow()
{
return StatementResult(Object::getNullInstance(), Flow::Continue);
}
bool isNormal() const { return flow == Flow::Normal; }
bool shouldReturn() const { return flow == Flow::Return; }
bool shouldBreak() const { return flow == Flow::Break; }
bool shouldContinue() const { return flow == Flow::Continue; }
};
class Evaluator
{
private:
std::vector<Ast::AstBase> asts;
std::shared_ptr<Context> globalContext;
std::shared_ptr<Context> currentContext;
Ast::AstAddressInfo currentAddressInfo;
public:
Evaluator(const std::vector<Ast::AstBase> &a) :
asts(a)
{
globalContext = std::make_shared<Context>(FString(u8"global"));
currentContext = globalContext;
for (auto &[name, fn] : Builtins::builtinFunctions)
{
int argc = Builtins::getBuiltinFunctionParamCount(name);
Function f(fn, argc);
globalContext->def(
name,
ValueType::Function,
AccessModifier::PublicConst,
std::make_shared<Object>(f));
}
for (auto &[name, val] : Builtins::builtinValues)
{
globalContext->def(
name,
val->getTypeInfo(),
AccessModifier::PublicConst,
val);
}
}
std::shared_ptr<Context> getCurrentContext() { return currentContext; }
std::shared_ptr<Context> getGlobalContext() { return globalContext; }
ObjectPtr __evalOp(Ast::Operator, const ObjectPtr &, const ObjectPtr & = Object::getNullInstance());
ObjectPtr evalBinary(const Ast::BinaryExpr &);
ObjectPtr evalUnary(const Ast::UnaryExpr &);
StatementResult evalBlockStatement(const Ast::BlockStatement &, ContextPtr = nullptr);
StatementResult evalStatement(const Ast::Statement &);
ObjectPtr evalFunctionCall(const Function &, const Ast::FunctionArguments &, FString fnName = u8"<anonymous>");
ObjectPtr eval(Ast::Expression);
void run();
void printStackTrace() const;
};
} // namespace Fig