#include #include #include namespace Fig { ExprResult Evaluator::eval(Ast::Expression exp, ContextPtr ctx) { using Ast::AstType; AstType type = exp->getType(); switch (type) { case AstType::ValueExpr: { auto val = std::static_pointer_cast(exp); return val->val; } case AstType::VarExpr: { auto varExpr = std::static_pointer_cast(exp); return check_unwrap_lv(evalVarExpr(varExpr, ctx)).get(); // LvObject -> RvObject } case AstType::BinaryExpr: { auto bin = std::static_pointer_cast(exp); return evalBinary(bin, ctx); } case AstType::UnaryExpr: { auto un = std::static_pointer_cast(exp); return evalUnary(un, ctx); } case AstType::TernaryExpr: { auto te = std::static_pointer_cast(exp); return evalTernary(te, ctx); } case AstType::MemberExpr: case AstType::IndexExpr: return check_unwrap_lv(evalLv(exp, ctx)).get(); case AstType::FunctionCall: { auto fnCall = std::static_pointer_cast(exp); return evalFunctionCall(fnCall, ctx); } case AstType::FunctionLiteralExpr: { auto fnLiteral = std::static_pointer_cast(exp); Ast::BlockStatement body = nullptr; if (fnLiteral->isExprMode()) { Ast::Expression exprBody = fnLiteral->getExprBody(); const Ast::AstAddressInfo &aai = exprBody->getAAI(); Ast::Return st = std::make_shared(exprBody); st->setAAI(aai); body = std::make_shared(); body->stmts.push_back(st); // convert to Ast::Statement body->setAAI(aai); } else { body = fnLiteral->getBlockBody(); } Function fn(FString(std::format("")),fnLiteral->paras, ValueType::Any, body, ctx /* pass the ctx(fnLiteral eval context) as closure context */ ); return std::make_shared(std::move(fn)); } case AstType::InitExpr: { auto initExpr = std::static_pointer_cast(exp); return evalInitExpr(initExpr, ctx); } case AstType::ListExpr: { auto lstExpr = std::static_pointer_cast(exp); List list; for (auto &exp : lstExpr->val) { list.push_back(check_unwrap(eval(exp, ctx))); } return std::make_shared(std::move(list)); } case AstType::MapExpr: { auto mapExpr = std::static_pointer_cast(exp); Map map; for (auto &[key, value] : mapExpr->val) { map[check_unwrap(eval(key, ctx))] = check_unwrap(eval(value, ctx)); } return std::make_shared(std::move(map)); } default: { throw RuntimeError(FString(std::format("err type of expr: {}", magic_enum::enum_name(type)))); } } return Object::getNullInstance(); // ignore warning } };