4.0 KiB
4.0 KiB
Embedding Bob: Public API Guide
This document explains how to embed the Bob interpreter in your C++ application, register custom modules, and control sandbox policies.
Quick Start
#include "cli/bob.h"
#include "ModuleRegistry.h"
int main() {
Bob bob;
// Optional: configure policies or modules before first use
bob.setBuiltinModulePolicy(true); // allow builtin modules (default)
bob.setBuiltinModuleDenyList({/* e.g., "sys" */});
// Register a custom builtin module called "demo"
bob.registerModule("demo", [](ModuleRegistry::ModuleBuilder& m) {
m.fn("hello", [](std::vector<Value> args, int, int) -> Value {
std::string who = (args.size() >= 1 && args[0].isString()) ? args[0].asString() : "world";
return Value(std::string("hello ") + who);
});
m.val("meaning", Value(42.0));
});
// Evaluate code from a string
bob.evalString("import demo; print(demo.hello(\"Bob\"));", "<host>");
// Evaluate a file (imports inside resolve relative to the file's directory)
bob.evalFile("script.bob");
}
API Overview
Bob exposes a single high-level object with a minimal, consistent API. It self-manages an internal interpreter and applies configuration on first use.
-
Program execution
bool evalString(const std::string& code, const std::string& filename = "<eval>")bool evalFile(const std::string& path)void runFile(const std::string& path)(CLI convenience – delegates toevalFile)void runPrompt()(interactive CLI – delegates each line toevalString)
-
Module registration and sandboxing
void registerModule(const std::string& name, std::function<void(ModuleRegistry::ModuleBuilder&)> init)void setBuiltinModulePolicy(bool allow)void setBuiltinModuleAllowList(const std::vector<std::string>& allowed)void setBuiltinModuleDenyList(const std::vector<std::string>& denied)
-
Global environment helpers
bool defineGlobal(const std::string& name, const Value& value)bool tryGetGlobal(const std::string& name, Value& out) const
All configuration calls are safe to use before any evaluation – they are queued and applied automatically when the interpreter is first created.
Registering Custom Builtin Modules
Use the builder convenience to create a module:
bob.registerModule("raylib", [](ModuleRegistry::ModuleBuilder& m) {
m.fn("init", [](std::vector<Value> args, int line, int col) -> Value {
// call into your library here; validate args, return Value
return NONE_VALUE;
});
m.val("VERSION", Value(std::string("5.0")));
});
At runtime:
import raylib;
raylib.init();
print(raylib.VERSION);
Notes
- Modules are immutable, first-class objects.
type(module)is "module" andtoString(module)prints<module 'name'>. - Reassigning a module binding or setting module properties throws an error.
Builtin Modules and Sandboxing
- Builtin modules (e.g.,
sys) are registered during interpreter construction. - File imports are always resolved relative to the importing file's directory.
- Policies:
setBuiltinModulePolicy(bool allow)– enable/disable all builtin modules.setBuiltinModuleAllowList(vector<string>)– allow only listed modules (deny others).setBuiltinModuleDenyList(vector<string>)– explicitly deny listed modules.
- Denied/disabled modules are cloaked:
import namereports "Module not found".
Error Reporting
evalString/evalFileset file context for error reporting so line/column references point to the real source.- Both return
trueon success andfalseif execution failed (errors are reported via the internal error reporter).
CLI vs Embedding
- CLI builds include
main.cpp(entry point), which usesBob::runFileorBob::runPrompt. - Embedded hosts do not use
main.cpp; instead they instantiateBoband callevalString/evalFiledirectly.