39 explicit Engine(std::pmr::memory_resource *mr);
42 Engine(
const Engine &) =
delete;
43 Engine &operator=(
const Engine &) =
delete;
44 Engine(Engine &&) =
delete;
45 Engine &operator=(Engine &&) =
delete;
49 std::pmr::memory_resource *resource()
const noexcept {
return mr_; }
51 void registerBinaryOp(
const std::string &op, BinaryOpFunc func);
52 void registerUnaryOp(
const std::string &op, UnaryOpFunc func);
63 void registerFunction(
const std::string &name, ExternalFunc func);
64 void registerFunction(
const std::string &ns,
65 const std::string &name,
74 const BuiltinClass *findClass(
const std::string &name)
const;
82 void registerCallbackBuiltin(
const std::string &name, std::shared_ptr<CallbackBuiltin> cb);
87 bool isUserCodeHandle(
const Value &handle)
const;
98 void registerBuiltinMSource(
const std::string &src);
103 void registerBuiltinClassSource(
const std::string &src);
107 void reinstallBuiltinSources();
119 void registerClassDef(
const ASTNode *classdef,
const std::string &qualifiedName =
"");
123 void clearClassDefs();
138 void enforceMethodAccess(
const std::string &className,
const std::string &method);
146 const UserFunction *classGetter(
const std::string &className,
147 const std::string &prop)
const;
148 const UserFunction *classSetter(
const std::string &className,
149 const std::string &prop)
const;
150 void enforcePropGetAccess(
const std::string &className,
const std::string &prop);
151 void enforcePropSetAccess(
const std::string &className,
const std::string &prop);
161 const Value &rhs, std::string &ownerClassOut);
163 std::string &ownerClassOut);
172 std::string &ownerClassOut,
173 std::vector<Value> &argsOut);
175 std::string &ownerClassOut,
176 std::vector<Value> &argsOut);
184 Value superConstruct(
const std::string &base,
const Value &seed,
186 std::vector<Value> superMethod(
const std::string &base,
const std::string &method,
195 void pushClassCtx(std::string className,
bool isCtor);
197 bool classCtxAllows(
const std::string &declClass,
bool privateOnly)
const;
198 bool classCtxInCtorOf(
const std::string &declClass)
const;
210 Value makeDefaultInstance(
const std::string &className);
213 const UserFunction *classCtor(
const std::string &className)
const;
218 void enforceCtorAccess(
const std::string &className);
221 std::string formatObjectDisplay(
const std::string &name,
const Value &obj)
const;
227 void displayObject(
const std::string &name,
const Value &obj);
236 bool tryObjectBinaryOp(
const std::string &op,
const Value &lhs,
const Value &rhs,
243 bool tryObjectUnaryOp(
const std::string &op,
const Value &operand,
254 Value applyBinaryOp(
const std::string &op,
const Value &lhs,
const Value &rhs);
255 Value applyUnaryOp(
const std::string &op,
const Value &operand);
264 void objectStoreSlice(
Value &dst,
const std::vector<std::vector<size_t>> &perDim,
278 const std::vector<std::string> &namespaces()
const {
return namespaceOrder_; }
283 const std::unordered_multimap<std::string, std::string> &shortNameIndex()
const
285 return shortNameIndex_;
300 const ExternalFunc *findExternal(
const std::string &name,
306 std::string bareNameSource(
const std::string &name)
const;
311 bool isKnownLeafName(
const std::string &name)
const
313 return externalFuncs_.find(name) != externalFuncs_.end()
314 || shortNameIndex_.find(name) != shortNameIndex_.end();
317 void setVariable(
const std::string &name,
Value val);
318 Value *getVariable(
const std::string &name);
328 Value eval(
const std::string &code,
bool suppressTopLevelDisplay =
false);
336 std::shared_ptr<const std::string> src);
339 void rewriteVarHeadedCommands(
ASTNode *root);
347 bool suppressTopLevelDisplay =
false);
353 bool debugStop =
false;
354 std::string errorMessage;
357 std::string errorFunc;
358 std::string errorContext;
363 enum class Backend { VM, TreeWalker };
364 void setBackend(Backend b) { backend_ = b; }
365 Backend backend()
const {
return backend_; }
370 void addFusionRule(FusionRule rule) { fusionRules_.push_back(std::move(rule)); }
371 const std::vector<FusionRule> &fusionRules()
const {
return fusionRules_; }
372 void setFusion(
bool on) { fusionEnabled_ = on; }
373 bool fusionEnabled()
const {
return fusionEnabled_ && !fusionRules_.empty(); }
377 void noteFusionHit() { ++fusionHits_; }
378 size_t fusionHits()
const {
return fusionHits_; }
379 void resetFusionHits() { fusionHits_ = 0; }
381 using OutputFunc = std::function<void(
const std::string &)>;
382 void setOutputFunc(OutputFunc f);
383 OutputFunc outputFunc()
const {
return outputFunc_; }
390 using InputProvider = std::function<std::string()>;
391 void setInputProvider(InputProvider p) { inputProvider_ = std::move(p); }
392 const InputProvider &inputProvider()
const {
return inputProvider_; }
393 void setMaxRecursionDepth(
int depth);
395 std::vector<std::string> workspaceVarNames()
const;
396 std::string workspaceJSON()
const;
397 void outputText(
const std::string &s);
399 FigureManager &figureManager() {
return figureManager_; }
400 const FigureManager &figureManager()
const {
return figureManager_; }
402 Environment &workspaceEnv() {
return *workspaceEnv_; }
403 Environment &constantsEnv() {
return *constantsEnv_; }
404 Environment &globalsEnv() {
return *globalsEnv_; }
406 bool hasFunction(
const std::string &name)
const;
407 bool hasUserFunction(
const std::string &name)
const;
408 bool hasExternalFunction(
const std::string &name)
const;
414 bool hasCallableName(
const std::string &name)
const;
426 Value callFunctionHandle(
const Value &handle,
427 Span<const Value> args,
428 Environment *env =
nullptr);
429 std::vector<Value> callFunctionHandleMulti(
const Value &handle,
430 Span<const Value> args,
432 Environment *env =
nullptr);
445 const UserFunction *lookupUserFunction(
const std::string &name,
446 const Environment *env);
450 const UserFunction *lookupUserFunctionLocal(
const std::string &name)
const;
456 void clearUserFunctions();
465 void adoptUserFunction(
const std::string &name,
467 bool scriptScope =
false);
478 void addPath(
const std::string &dir);
479 void rmPath(
const std::string &dir);
480 const std::vector<std::string> &path()
const {
return mPath_; }
491 void refreshStaleMFiles();
495 void reloadEvictedClassBases_(
const std::vector<std::string> &bases);
505 void beginScript(
const ASTNode *ast);
515 void promoteScriptLocalsToWorkspace();
524 friend class DebugFacade;
525 void setDebugObserver(std::shared_ptr<DebugObserver> observer);
526 DebugObserver *debugObserver()
const {
return debugObserver_.get(); }
527 BreakpointManager &breakpointManager() {
return breakpointManager_; }
528 const BreakpointManager &breakpointManager()
const {
return breakpointManager_; }
529 DebugController *debugController() {
return debugController_.get(); }
530 const DebugController *debugController()
const {
return debugController_.get(); }
535 ExecStatus debugResume(DebugAction action);
543 void reinstallConstants();
549 void registerConstant(
const std::string &name, Value val);
555 bool isReservedName(
const std::string &name)
const;
558 void setTicTimer(TimePoint tp)
563 TimePoint ticTimer()
const {
return ticBase_; }
564 bool ticWasCalled()
const {
return ticCalled_; }
568 bool isInsideFunctionCall()
const;
580 Environment *callerEnv(
int n = 0);
585 int callerDepth()
const;
591 void assignToCaller(
int n,
const std::string &name, Value val);
600 std::string inputName(
int k);
617 void registerVirtualFS(std::unique_ptr<VirtualFS> fs);
618 VirtualFS *findVirtualFS(
const std::string &name)
const;
629 void pushScriptOrigin(
const std::string &fsName);
630 void pushScriptOrigin(
const std::string &fsName,
const std::string &scriptDir);
631 void popScriptOrigin();
632 const std::string *currentScriptOrigin()
const;
633 const std::string *currentScriptDir()
const;
642 const std::string &cwd()
const {
return fsCtx_.cwd(); }
643 void setCwd(
const std::string &p) { fsCtx_.setCwd(p); }
647 using ResolvedPath = FsContext::ResolvedPath;
648 ResolvedPath resolvePath(
const std::string &userPath)
const;
654 FsContext &fsContext() noexcept {
return fsCtx_; }
655 const FsContext &fsContext() const noexcept {
return fsCtx_; }
660 ops::RngContext &rng() noexcept {
return rng_; }
661 const ops::RngContext &rng() const noexcept {
return rng_; }
670 using OpenFile = FsContext::OpenFile;
671 int openFile(
const std::string &userPath,
const std::string &mode)
672 {
return fsCtx_.openFile(userPath, mode); }
673 bool closeFile(
int fid) {
return fsCtx_.closeFile(fid); }
674 void closeAllFiles() { fsCtx_.closeAllFiles(); }
675 OpenFile *findFile(
int fid) {
return fsCtx_.findFile(fid); }
676 std::vector<int> openFileIds()
const {
return fsCtx_.openFileIds(); }
677 const std::string &lastFopenError()
const {
return fsCtx_.lastFopenError(); }
680 std::pmr::memory_resource *mr_;
681 std::unique_ptr<Environment> globalsEnv_;
682 std::unique_ptr<Environment> constantsEnv_;
683 std::unique_ptr<Environment> workspaceEnv_;
685 std::unordered_map<std::string, BinaryOpFunc> binaryOps_;
686 std::unordered_map<std::string, UnaryOpFunc> unaryOps_;
687 std::unordered_map<std::string, ExternalFunc> externalFuncs_;
690 std::unordered_map<std::string, BuiltinClass> classes_;
693 std::unordered_map<std::string, std::shared_ptr<ClassDefDesc>> classDefs_;
697 std::unordered_map<std::string, std::shared_ptr<const ASTNode>> classDefAst_;
701 bool suppressDependentCascade_ =
false;
705 std::unordered_map<std::string, std::shared_ptr<CallbackBuiltin>> callbackBuiltins_;
706 std::unordered_map<std::string, UserFunction> userFuncs_;
711 std::vector<std::string> builtinMSourceTexts_;
712 std::vector<std::string> builtinClassSourceTexts_;
715 void adoptBuiltinMSource_(
const std::string &src);
716 void adoptBuiltinClassSource_(
const std::string &src);
726 std::string className;
729 std::vector<ClassCtxFrame> classCtx_;
732 std::string currentClassCtx_()
const;
737 std::unordered_multimap<std::string, std::string> shortNameIndex_;
738 std::vector<std::string> namespaceOrder_;
739 std::unordered_set<std::string> namespaceSet_;
743 void registerFunctionImpl_(
const std::string &fullName,
744 const std::string &leafName,
752 void unregisterClassDef(
const std::string &name);
757 void dropFileClassCtorExternal_(
const std::string &name);
762 void reregisterDerivedClasses(
const std::string &base);
764 OutputFunc outputFunc_;
765 InputProvider inputProvider_;
766 FigureManager figureManager_;
769 TimePoint ticBase_{};
770 bool ticCalled_ =
false;
774 bool clearAllCalled_ =
false;
780 std::unordered_map<std::string, Value> userConstants_;
786 std::unordered_map<std::string, UserFunction> scriptLocalUserFuncs_;
787 std::vector<std::unordered_map<std::string, UserFunction>> savedScriptLocalUserFuncs_;
790 std::vector<std::string> mPath_;
791 struct MFileCacheEntry
793 std::string fullPath;
795 std::string contentHash;
796 std::shared_ptr<const std::string> sourceCode;
798 std::unordered_map<std::string, MFileCacheEntry> mFileCache_;
803 const UserFunction *resolveMFile_(
const std::string &name);
806 std::shared_ptr<DebugObserver> debugObserver_;
807 BreakpointManager breakpointManager_;
808 std::unique_ptr<DebugController> debugController_;
821 ops::RngContext rng_;
824 void markClearAll() { clearAllCalled_ =
true; }
827 std::unique_ptr<TreeWalker> treeWalker_;
828 std::unique_ptr<Compiler> compiler_;
831 Compiler *compilerPtr() {
return compiler_.get(); }
834 std::unique_ptr<VM> vm_;
835 Backend backend_ = Backend::VM;
840 std::vector<FusionRule> fusionRules_;
841 bool fusionEnabled_ =
true;
842 size_t fusionHits_ = 0;
845 void syncVMToWorkspace();
852 void syncVMToScope(Environment *scope);
857 Value runOneChunk(
const ASTNode *ast, std::shared_ptr<const std::string> src);
859 friend class TreeWalker;
861 friend class DebugSession;