Documentation
¶
Overview ¶
Package vibes is the embedder API for the Vibescript scripting language. Hosts compile a .vibe source into a Script and invoke its functions through an Engine:
engine, _ := vibes.NewEngine(vibes.Config{StepQuota: 50_000})
script, _ := engine.Compile(source)
result, _ := script.Call(
ctx,
"greet",
[]value.Value{value.NewString("world")},
vibes.CallOptions{},
)
Runtime values live in github.com/mgomes/vibescript/vibes/value. Host-provided capability contracts live under github.com/mgomes/vibescript/vibes/capability. This package provides the Engine/Script execution surface, capability adapter constructors, runtime errors, and the per-call Execution handle that builtins receive. Engine execution is bounded by Config (step and memory quotas, recursion limit, strict-effects mode, module allow/deny policies).
See ../README.md for the language reference and ../docs/architecture.md for the runtime design. The stability tiers of the embedding API — which exported symbols are supported and which are internal plumbing with no compatibility promise — are declared in ../docs/embedding-api-stability.md.
Example (SimpleScript) ¶
Example_simpleScript shows the full compile-and-call cycle a host embedder uses to drive a Vibescript program.
package main
import (
"context"
"fmt"
"github.com/mgomes/vibescript/vibes"
"github.com/mgomes/vibescript/vibes/value"
)
func main() {
engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
script, err := engine.Compile(`def greet(name)
"hello " + name
end`)
if err != nil {
panic(err)
}
result, err := script.Call(
context.Background(),
"greet",
[]value.Value{value.NewString("world")},
vibes.CallOptions{},
)
if err != nil {
panic(err)
}
fmt.Println(result.String())
}
Output: hello world
Index ¶
- Constants
- Variables
- func DeclareNonMutating(v value.Value) value.Value
- func DeclareNonRetaining(v value.Value) value.Value
- func MemberCompletionNames() map[string][]string
- func NewAutoBuiltin(name string, fn BuiltinFunc) value.Value
- func NewBuiltin(name string, fn BuiltinFunc) value.Value
- func NewTypedBuiltin(name string, fn BuiltinFunc, sig Signature) (value.Value, error)
- func QuotaProfileNames() []string
- type Builtin
- type BuiltinFunc
- type Builtins
- type CallOptions
- type CapabilityAdapter
- func MustNewContextCapability(name string, resolver contextcap.Resolver) CapabilityAdapter
- func MustNewDBCapability(name string, impl db.Database) CapabilityAdapter
- func MustNewEventsCapability(name string, publisher events.Publisher) CapabilityAdapter
- func MustNewJobQueueCapability(name string, impl jobqueue.JobQueue) CapabilityAdapter
- func NewContextCapability(name string, resolver contextcap.Resolver) (CapabilityAdapter, error)
- func NewDBCapability(name string, impl db.Database) (CapabilityAdapter, error)
- func NewEventsCapability(name string, publisher events.Publisher) (CapabilityAdapter, error)
- func NewJobQueueCapability(name string, impl jobqueue.JobQueue) (CapabilityAdapter, error)
- type CapabilityBinding
- type CapabilityContractProvider
- type CapabilityMethodContract
- type CheckWarning
- type Config
- type Engine
- type Execution
- type MemberContract
- type MemberParam
- type ParamKind
- type ParseIssue
- type Position
- type QuotaProfile
- type RuntimeError
- type Script
- type Signature
- type SignatureParam
- type StackFrame
Examples ¶
Constants ¶
const ( // ParamNormal is an ordinary positional parameter (def f(a)). ParamNormal = runtime.ParamNormal // ParamKeyword is a keyword parameter (def f(a:)), filled from // CallOptions.Keywords or a script-side keyword argument. ParamKeyword = runtime.ParamKeyword // ParamRest is a splat parameter (def f(*rest)) that collects the // remaining positional arguments into an array. ParamRest = runtime.ParamRest // ParamKeywordRest is a double-splat parameter (def f(**opts)) that // collects the remaining keyword arguments into a hash. ParamKeywordRest = runtime.ParamKeywordRest )
const Unlimited = runtime.Unlimited
Unlimited disables a quota when supplied as a Config quota value. It is distinct from a zero value, which selects the built-in default.
Variables ¶
var ( ProfileLow = runtime.ProfileLow ProfileMedium = runtime.ProfileMedium ProfileHigh = runtime.ProfileHigh ProfileXHigh = runtime.ProfileXHigh )
The named quota profiles, in ascending order of generosity. The lower rungs model a constrained sandbox budget; xhigh runs a script like a normal interpreter (unlimited steps and memory, a high but finite recursion cap).
Functions ¶
func DeclareNonMutating ¶ added in v0.60.0
DeclareNonMutating records a builtin's promise that no invocation of it writes to any container reachable from its receiver, arguments, keyword arguments, block, or from any execution's roots, and returns it. Allocating a container and filling it in is not such a write: the promise covers only state something else can already reach, so building a result and returning it keeps it. Script code the builtin drives through a block is not covered and does not need to be.
This is a safety promise, not a performance hint. The runtime stops invalidating its memoized memory-estimator walk around calls to a builtin that makes it, so a declaration that is not true leaves an execution accounting for less memory than it actually holds, and that execution then allocates past the MemoryQuotaBytes it was configured with. A builtin that declares nothing keeps the existing conservative behavior, which is slower and correct; omission costs speed, never correctness.
The promise is between an embedder and itself rather than between the sandbox and untrusted script. A host builtin already runs arbitrary Go in the embedding process and can allocate without bound and ignore every quota today, so declaring grants no capability a host lacked, and script code can neither observe the declaration nor reach it. It widens no sandbox boundary. What it does is switch off a backstop the host then has to honor itself.
Apply it to a builtin whose whole body is known, and re-check it when that body changes.
func DeclareNonRetaining ¶ added in v0.60.0
DeclareNonRetaining records a builtin's promise that no invocation of it stores, anywhere that outlives the invocation, a reference to any Value it receives (receiver, arguments, keyword arguments, block) or returns, or to any container reachable from one -- and, symmetrically, that no value it returns or yields shares storage the host already holds (a wrapper built over a package-level map or an adapter field is a retained reference even though the invocation itself stored nothing). It returns the value. Package-level variables, fields on the adapter, closure captures, channels, caches and anything handed to another goroutine all count as outliving the invocation. So does keeping a container reached through an argument rather than the argument itself.
The boundary consults this promise (#1210): a declaring builtin's inputs skip the retention marking, its return skips the detach copy, and blocks it drives through Execution.CallBlock exchange values without boundary copies -- which is exactly why an untrue declaration is a live aliasing channel, not just an accounting error. A later change will also use it to scope the memory estimator's walk memo across a host call (#1199).
It is stated as a safety promise rather than a hint because of what it will mean once consulted: an execution calling a builtin that makes it keeps accounting for memory privately, so an untrue declaration would let a container the host kept be mutated afterwards without that execution observing the change, and its quota would then admit allocations it should have refused. Declare it only where that is true, not on the reasoning that it currently costs nothing.
It is a separate promise from DeclareNonMutating and neither implies the other. A builtin that only reads its arguments but files one away for later is non-mutating and not non-retaining; one that overwrites a slot in its receiver and keeps nothing is the reverse.
func MemberCompletionNames ¶ added in v0.50.0
MemberCompletionNames returns the builtin member-method names per receiver type (string, array, hash, int, float, money, duration, time), for editor tooling such as LSP completion.
func NewAutoBuiltin ¶
func NewAutoBuiltin(name string, fn BuiltinFunc) value.Value
NewAutoBuiltin returns a builtin function Value that auto-invokes without parentheses.
Example ¶
package main
import (
"context"
"fmt"
"github.com/mgomes/vibescript/vibes"
"github.com/mgomes/vibescript/vibes/value"
)
func main() {
engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
script, err := engine.Compile(`def run()
tenant
end`)
if err != nil {
panic(err)
}
tenant := vibes.NewAutoBuiltin("tenant", func(_ *vibes.Execution, _ value.Value, _ []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
return value.NewString("acme"), nil
})
result, err := script.Call(
context.Background(),
"run",
nil,
vibes.CallOptions{
Globals: map[string]value.Value{"tenant": tenant},
},
)
if err != nil {
panic(err)
}
fmt.Println(result.String())
}
Output: acme
func NewBuiltin ¶
func NewBuiltin(name string, fn BuiltinFunc) value.Value
NewBuiltin returns a builtin function Value.
Example ¶
package main
import (
"context"
"fmt"
"strings"
"github.com/mgomes/vibescript/vibes"
"github.com/mgomes/vibescript/vibes/value"
)
func main() {
engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
script, err := engine.Compile(`def shout(word)
upcase(word)
end`)
if err != nil {
panic(err)
}
upcase := vibes.NewBuiltin("upcase", func(_ *vibes.Execution, _ value.Value, args []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
return value.NewString(strings.ToUpper(args[0].String())), nil
})
result, err := script.Call(
context.Background(),
"shout",
[]value.Value{value.NewString("hi")},
vibes.CallOptions{
Globals: map[string]value.Value{"upcase": upcase},
},
)
if err != nil {
panic(err)
}
fmt.Println(result.String())
}
Output: HI
func NewTypedBuiltin ¶ added in v0.60.0
NewTypedBuiltin returns a builtin function Value that publishes sig to the checker and validates calls against it at runtime. The value can be registered as an engine builtin, passed as a call-option global, or exposed as a capability method.
func QuotaProfileNames ¶ added in v0.60.0
func QuotaProfileNames() []string
QuotaProfileNames returns the profile names in ascending order of generosity.
Types ¶
type BuiltinFunc ¶
type BuiltinFunc = runtime.BuiltinFunc
BuiltinFunc is the Go function signature for built-in Vibescript functions.
type Builtins ¶ added in v0.29.0
Builtins maps builtin function names to their Value implementations.
type CallOptions ¶
type CallOptions = runtime.CallOptions
CallOptions configures globals, capabilities, and other settings for a script invocation.
type CapabilityAdapter ¶
type CapabilityAdapter = runtime.CapabilityAdapter
CapabilityAdapter binds host capabilities into a script invocation.
func MustNewContextCapability ¶ added in v0.15.0
func MustNewContextCapability(name string, resolver contextcap.Resolver) CapabilityAdapter
MustNewContextCapability constructs a context CapabilityAdapter or panics when name is empty or resolver is a nil implementation.
func MustNewDBCapability ¶ added in v0.15.0
func MustNewDBCapability(name string, impl db.Database) CapabilityAdapter
MustNewDBCapability constructs a database CapabilityAdapter or panics when name is empty or impl is a nil implementation.
func MustNewEventsCapability ¶ added in v0.15.0
func MustNewEventsCapability(name string, publisher events.Publisher) CapabilityAdapter
MustNewEventsCapability constructs an events CapabilityAdapter or panics when name is empty or publisher is a nil implementation.
func MustNewJobQueueCapability ¶ added in v0.6.0
func MustNewJobQueueCapability(name string, impl jobqueue.JobQueue) CapabilityAdapter
MustNewJobQueueCapability constructs a job-queue CapabilityAdapter or panics when name is empty or impl is a nil implementation.
func NewContextCapability ¶ added in v0.15.0
func NewContextCapability(name string, resolver contextcap.Resolver) (CapabilityAdapter, error)
NewContextCapability constructs a data-only context CapabilityAdapter from the provided resolver. The adapter exposes the resolved attributes as a global on each script invocation.
func NewDBCapability ¶ added in v0.15.0
func NewDBCapability(name string, impl db.Database) (CapabilityAdapter, error)
NewDBCapability constructs a database CapabilityAdapter bound to the provided script-facing name. The adapter wraps a *db.Capability built from impl and dispatches the db.find/query/update/sum/each builtins. Use db.NewCapability directly when you only need the per-method dispatchers and intend to build a custom adapter.
func NewEventsCapability ¶ added in v0.15.0
func NewEventsCapability(name string, publisher events.Publisher) (CapabilityAdapter, error)
NewEventsCapability constructs an events CapabilityAdapter bound to the provided script-facing name. The adapter wraps an *events.Capability built from publisher and dispatches the publish builtin.
func NewJobQueueCapability ¶
func NewJobQueueCapability(name string, impl jobqueue.JobQueue) (CapabilityAdapter, error)
NewJobQueueCapability constructs a job-queue CapabilityAdapter bound to the provided script-facing name. The adapter wraps a *jobqueue.Capability built from impl and dispatches the enqueue builtin (and the retry builtin when impl satisfies jobqueue.JobQueueWithRetry).
type CapabilityBinding ¶
type CapabilityBinding = runtime.CapabilityBinding
CapabilityBinding provides execution context for adapters during binding.
type CapabilityContractProvider ¶ added in v0.13.0
type CapabilityContractProvider = runtime.CapabilityContractProvider
CapabilityContractProvider exposes per-method contracts for capability adapters.
type CapabilityMethodContract ¶ added in v0.13.0
type CapabilityMethodContract = runtime.CapabilityMethodContract
CapabilityMethodContract validates capability method calls at the boundary.
type CheckWarning ¶ added in v0.60.0
type CheckWarning = runtime.CheckWarning
CheckWarning is a statically detected contract issue reported by the checker (see Script.CheckWarnings and the docs/typing.md gradual-typing contract). It is the stable public name for the diagnostic type: Function names the containing function, Pos carries the source position, Message is the human-readable diagnostic, and Source is the file path of the required module the warning originates in (empty for the checked script itself).
The type is an alias for the internal checker representation, so values returned by Script.CheckWarnings, CheckWarningsWithOptions, and CheckWarningsForFunction can be stored and named through this type without importing implementation packages.
type Config ¶
Config controls interpreter execution bounds and enforcement modes.
Example (StrictEffects) ¶
ExampleConfig_strictEffects shows that strict-effects mode rejects callable globals so hosts can be sure side effects flow through declared capabilities.
package main
import (
"context"
"fmt"
"strings"
"github.com/mgomes/vibescript/vibes"
"github.com/mgomes/vibescript/vibes/value"
)
func main() {
engine := vibes.MustNewEngine(vibes.Config{StrictEffects: true})
script, err := engine.Compile(`def run()
notify("hi")
end`)
if err != nil {
panic(err)
}
_, err = script.Call(
context.Background(),
"run",
nil,
vibes.CallOptions{
Globals: map[string]value.Value{
"notify": vibes.NewBuiltin("notify", func(_ *vibes.Execution, _ value.Value, _ []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
return value.NewNil(), nil
}),
},
},
)
if err == nil {
fmt.Println("expected strict-effects rejection")
return
}
if strings.Contains(err.Error(), "strict effects") {
fmt.Println("rejected callable global")
return
}
fmt.Println("unexpected error:", err)
}
Output: rejected callable global
type Engine ¶
Engine executes Vibescript programs with deterministic limits.
func MustNewEngine ¶ added in v0.6.0
MustNewEngine is like NewEngine but panics if cfg is invalid. Intended for package-level variable initialization and tests where invalid input is a programmer error and recovery is not meaningful. In production code prefer NewEngine and handle the error.
Example ¶
package main
import (
"fmt"
"github.com/mgomes/vibescript/vibes"
)
func main() {
engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
_ = engine
fmt.Println("engine ready")
}
Output: engine ready
func NewEngine ¶
NewEngine constructs an Engine with sane defaults and registers built-ins.
Example ¶
package main
import (
"fmt"
"github.com/mgomes/vibescript/vibes"
)
func main() {
engine, err := vibes.NewEngine(vibes.Config{StepQuota: 50_000})
if err != nil {
panic(err)
}
_ = engine
fmt.Println("engine ready")
}
Output: engine ready
type Execution ¶
Execution holds the runtime state for a single script evaluation. It is the per-call handle passed to builtin functions and capability adapters. Embedders should not rely on its internal shape; treat it as opaque and use the exported methods (Context, Step, CallBlock).
type MemberContract ¶ added in v0.60.0
type MemberContract = runtime.MemberContract
MemberContract is the registered contract of one builtin member method: receiver kind, name and aliases, call shape, and effect metadata.
func MemberContracts ¶ added in v0.60.0
func MemberContracts() []MemberContract
MemberContracts returns the registered builtin member contracts, for editor tooling such as LSP completion. The runtime registry backing it also drives the static checker's member call validation.
type MemberParam ¶ added in v0.60.0
type MemberParam = runtime.MemberParam
MemberParam is one positional parameter of a builtin member contract.
type ParseIssue ¶ added in v0.50.0
type ParseIssue = runtime.ParseIssue
ParseIssue is one structured parse failure extracted from an Engine.Compile error. Pos is the 1-indexed start position; End is the exclusive end of the offending token, or the zero Position when the parser could not determine a span.
func ParseIssues ¶ added in v0.50.0
func ParseIssues(err error) []ParseIssue
ParseIssues extracts the structured parse failures carried by a Compile error, in source order. It returns nil when err is nil or carries no parse positions, so callers can fall back to err.Error() for non-parse compile failures.
type Position ¶
Position is the public source-location type exposed on RuntimeError and related public surfaces. It is an alias for source.Position so the AST (in internal/ast) and the public error surface share a single definition without forcing AST consumers to import vibes.
type QuotaProfile ¶ added in v0.60.0
type QuotaProfile = runtime.QuotaProfile
QuotaProfile is a named bundle of the step, memory, and recursion quotas. ApplyTo writes every one of them, so a host layering its own override on a profile must set it after applying, not before.
func QuotaProfileByName ¶ added in v0.60.0
func QuotaProfileByName(name string) (QuotaProfile, bool)
QuotaProfileByName returns the profile with the given name, matched case-insensitively, and reports whether one was found.
type RuntimeError ¶
type RuntimeError = runtime.RuntimeError
RuntimeError describes a script-level error raised during execution.
type Signature ¶ added in v0.60.0
Signature is the opt-in static contract a host callable publishes to the checker; the same contract is enforced at runtime. See NewTypedBuiltin and Engine.RegisterBuiltinWithSignature.
type SignatureParam ¶ added in v0.60.0
type SignatureParam = runtime.SignatureParam
SignatureParam declares one positional parameter of a host callable's published Signature.
type StackFrame ¶
type StackFrame = runtime.StackFrame
StackFrame describes a single frame in a RuntimeError stack trace.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
capability
|
|
|
contextcap
Package contextcap provides a data-only capability adapter that resolves call-scoped context values into a script-visible hash or object.
|
Package contextcap provides a data-only capability adapter that resolves call-scoped context values into a script-visible hash or object. |
|
db
Package db provides the host-side database capability adapter for Vibescript.
|
Package db provides the host-side database capability adapter for Vibescript. |
|
events
Package events defines the host-facing contract for the events capability that Vibescript exposes to scripts.
|
Package events defines the host-facing contract for the events capability that Vibescript exposes to scripts. |
|
jobqueue
Package jobqueue defines the host-facing contract for the job-queue capability that Vibescript exposes to scripts.
|
Package jobqueue defines the host-facing contract for the job-queue capability that Vibescript exposes to scripts. |
|
internal
|
|
|
capabilitycontract
Package capabilitycontract centralizes the helper utilities shared by the carved vibes/capability/* subpackages.
|
Package capabilitycontract centralizes the helper utilities shared by the carved vibes/capability/* subpackages. |
|
Package source contains stable source-location types shared between the AST (internal) and the public error surface.
|
Package source contains stable source-location types shared between the AST (internal) and the public error surface. |
|
Package value defines the runtime Value type and its supporting domain-shaped types (Money, Duration, Range, time helpers) used throughout Vibescript.
|
Package value defines the runtime Value type and its supporting domain-shaped types (Money, Duration, Range, time helpers) used throughout Vibescript. |