runtime

package
v0.14.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CallEntrypoint

func CallEntrypoint(rt *ModuleRuntime, inst *ModuleInstance, name string, args []eval.Value) (eval.Value, error)

CallEntrypoint calls an exported entrypoint function from a module

This method handles function invocation for module entrypoints, supporting both 0-arg and multi-arg functions. The function is executed with a properly configured evaluator that can resolve cross-module references.

Parameters:

  • rt: The ModuleRuntime instance
  • inst: The module instance containing the entrypoint
  • name: The name of the entrypoint function
  • args: The arguments to pass to the function (can be empty for 0-arg)

Returns:

  • The result value from executing the function
  • An error if the entrypoint doesn't exist, isn't a function, or execution fails

Example:

result, err := CallEntrypoint(rt, inst, "main", []eval.Value{})
if err != nil {
    return err
}
fmt.Println(result.String())

func GetArity

func GetArity(val eval.Value) (int, error)

getArity returns the arity (number of parameters) of a value

Parameters:

  • val: The value to check (should be a FunctionValue)

Returns:

  • The number of parameters the function takes
  • An error if the value is not a function

func GetExportNames

func GetExportNames(inst *ModuleInstance) []string

GetExportNames returns a sorted list of export names from a module instance

This is a helper function for error messages.

Parameters:

  • inst: The module instance

Returns:

  • A slice of export names

Types

type BuiltinOnlyResolver

type BuiltinOnlyResolver struct {
	Builtins *BuiltinRegistry
}

BuiltinOnlyResolver resolves builtin functions for non-module execution

This resolver is used in the legacy pipeline execution path (non-module files) to provide access to the builtin registry. It only resolves:

  • References to the synthetic $builtin module
  • Names starting with underscore (e.g., _io_print)

It does NOT resolve user bindings or module imports, as those are handled by the module runtime's moduleGlobalResolver.

Thread-safety: Safe for concurrent use as it only reads from the registry.

func NewBuiltinOnlyResolver

func NewBuiltinOnlyResolver(builtins *BuiltinRegistry) *BuiltinOnlyResolver

NewBuiltinOnlyResolver creates a new builtin-only resolver

This is a convenience constructor for creating resolvers with a cleaner API.

Parameters:

  • builtins: The BuiltinRegistry to use for lookups

Returns:

  • A new BuiltinOnlyResolver ready to use

func (*BuiltinOnlyResolver) ResolveValue

func (r *BuiltinOnlyResolver) ResolveValue(ref core.GlobalRef) (eval.Value, error)

ResolveValue attempts to resolve a global reference to a builtin function

Resolution logic:

  1. Check if it's a builtin reference (module="$builtin" or name starts with "_")
  2. Look up the builtin in the registry
  3. Return nil if not found (allows fallback to other resolution mechanisms)

Parameters:

  • ref: The global reference to resolve

Returns:

  • The builtin Value if found
  • nil, nil if not a builtin (NOT an error - allows chaining resolvers)

Example:

resolver := &BuiltinOnlyResolver{Builtins: registry}
val, err := resolver.ResolveValue(core.GlobalRef{Module: "$builtin", Name: "add_Int"})

type BuiltinRegistry

type BuiltinRegistry struct {
	// contains filtered or unexported fields
}

BuiltinRegistry holds native Go implementations of builtin functions

Builtins are functions implemented in Go that can be called from AILANG modules. They are identified by names starting with underscore (e.g., _io_print).

The registry provides:

  • Type-safe function implementations routed through the effect system
  • Runtime access via GetBuiltin()
  • Automatic registration of stdlib functions

Thread-safety: The registry is initialized once and read-only after that, so it is safe to use concurrently.

func NewBuiltinRegistry

func NewBuiltinRegistry(evaluator *eval.CoreEvaluator) *BuiltinRegistry

NewBuiltinRegistry creates a new builtin registry with all stdlib functions registered

Parameters:

  • evaluator: The evaluator (needed to access EffContext during builtin calls)

Returns:

  • A fully-initialized BuiltinRegistry

func (*BuiltinRegistry) ClearGoroutineEvaluator

func (br *BuiltinRegistry) ClearGoroutineEvaluator()

ClearGoroutineEvaluator removes the goroutine-local evaluator override.

func (*BuiltinRegistry) Get

func (br *BuiltinRegistry) Get(name string) (eval.Value, bool)

Get looks up a builtin function by name

Parameters:

  • name: The builtin function name (e.g., "_io_print")

Returns:

  • The builtin function value if found
  • A boolean indicating whether the builtin was found

func (*BuiltinRegistry) SetGoroutineEvaluator

func (br *BuiltinRegistry) SetGoroutineEvaluator(e *eval.CoreEvaluator)

SetGoroutineEvaluator registers a forked evaluator for the current goroutine. Builtins will use this evaluator's EffContext instead of the shared one. Must be paired with ClearGoroutineEvaluator when the request completes.

type ModuleInstance

type ModuleInstance struct {
	// Identity
	Path string // Module path (e.g., "stdlib/std/io")

	// Static Information (from type-checking)
	Iface  *iface.Iface  // Module interface (exports, types)
	Core   *core.Program // Compiled Core AST
	CoreTI interface{}   // Type info for Core expressions (types.CoreTypeInfo, interface{} to avoid import cycle)

	// Runtime State
	Bindings map[string]eval.Value      // All top-level bindings
	Exports  map[string]eval.Value      // Exported bindings only
	Imports  map[string]*ModuleInstance // Imported modules
	// contains filtered or unexported fields
}

ModuleInstance represents a runtime module with evaluated bindings

A ModuleInstance is created from a LoadedModule after type-checking and contains the runtime state of the module, including:

  • All top-level bindings (both exported and private)
  • Exported bindings only (for cross-module access)
  • Links to imported module instances

Thread-safety: Initialization is protected by sync.Once to ensure each module is evaluated exactly once, even with concurrent access.

func NewModuleInstance

func NewModuleInstance(loaded *loader.LoadedModule) *ModuleInstance

NewModuleInstance creates a new module instance from a loaded module

The instance is created with empty Bindings and Exports maps, which will be populated during evaluation. The Iface and Core are copied from the LoadedModule.

Parameters:

  • loaded: A LoadedModule containing the parsed, type-checked module

Returns:

  • A new ModuleInstance ready for evaluation

func (*ModuleInstance) GetBinding

func (mi *ModuleInstance) GetBinding(name string) (eval.Value, error)

GetBinding retrieves a binding by name (exported or private)

This method is used for internal module access during evaluation. Unlike GetExport, it can access private (non-exported) bindings.

Parameters:

  • name: The name of the binding

Returns:

  • The binding value if found
  • An error if the binding does not exist

func (*ModuleInstance) GetEvaluationError

func (mi *ModuleInstance) GetEvaluationError() error

GetEvaluationError returns the error from evaluation, if any

Returns:

  • The evaluation error if evaluation failed
  • nil if evaluation succeeded or hasn't been attempted

func (*ModuleInstance) GetExport

func (mi *ModuleInstance) GetExport(name string) (eval.Value, error)

GetExport retrieves an exported value by name

This method is used for cross-module access to ensure encapsulation: only exported bindings are accessible from other modules.

Parameters:

  • name: The name of the exported binding

Returns:

  • The exported value if found
  • An error if the export does not exist

Example:

val, err := moduleInst.GetExport("main")
if err != nil {
    // Export "main" not found
}

func (*ModuleInstance) HasExport

func (mi *ModuleInstance) HasExport(name string) bool

HasExport checks if a module exports a given name

Parameters:

  • name: The name to check

Returns:

  • true if the module exports the name, false otherwise

func (*ModuleInstance) IsEvaluated

func (mi *ModuleInstance) IsEvaluated() bool

IsEvaluated returns whether the module has been evaluated

Returns:

  • true if evaluation completed (successfully or with error)
  • false if evaluation has not been attempted

func (*ModuleInstance) ListExports

func (mi *ModuleInstance) ListExports() []string

ListExports returns a sorted list of export names

This is useful for error messages and debugging.

Returns:

  • A slice of export names in the order they were added

type ModuleRuntime

type ModuleRuntime struct {
	// contains filtered or unexported fields
}

ModuleRuntime manages module instances and orchestrates evaluation

The ModuleRuntime is responsible for:

  • Loading modules via the ModuleLoader
  • Creating ModuleInstance objects
  • Caching evaluated modules
  • Evaluating modules in dependency order (topological sort)
  • Linking imported modules
  • Detecting circular imports
  • Providing builtin function registry

Thread-safety: The runtime uses sync.Once within each ModuleInstance to ensure each module is evaluated exactly once.

func NewModuleRuntime

func NewModuleRuntime(basePath string) *ModuleRuntime

NewModuleRuntime creates a new module runtime

The runtime is initialized with a base path for module resolution and creates a fresh module loader and core evaluator.

Parameters:

  • basePath: The directory to use as the root for module resolution

Returns:

  • A new ModuleRuntime ready to load and evaluate modules

Example:

rt := NewModuleRuntime("/path/to/project")
inst, err := rt.LoadAndEvaluate("examples/demo")

func (*ModuleRuntime) DeleteInstance

func (rt *ModuleRuntime) DeleteInstance(modulePath string)

DeleteInstance removes a cached module instance, forcing re-evaluation on next load. This is used by hot reload to invalidate stale modules.

func (*ModuleRuntime) GetEvaluator

func (rt *ModuleRuntime) GetEvaluator() *eval.CoreEvaluator

GetInstance retrieves a module instance from the cache

This is useful for debugging and testing.

Parameters:

  • modulePath: The module path to look up

Returns:

  • The cached ModuleInstance if found
  • nil if not found

GetEvaluator returns the runtime's evaluator

This allows external code to access the evaluator for setting the effect context or other configuration.

Returns:

  • The CoreEvaluator used by this runtime

func (*ModuleRuntime) GetInstance

func (rt *ModuleRuntime) GetInstance(modulePath string) *ModuleInstance

func (*ModuleRuntime) GetLoader

func (rt *ModuleRuntime) GetLoader() *loader.ModuleLoader

GetLoader returns the module loader for cache management.

func (*ModuleRuntime) HasInstance

func (rt *ModuleRuntime) HasInstance(modulePath string) bool

HasInstance checks if a module instance is cached

Parameters:

  • modulePath: The module path to check

Returns:

  • true if the module is cached, false otherwise

func (*ModuleRuntime) ListInstances

func (rt *ModuleRuntime) ListInstances() []string

ListInstances returns a list of all cached module paths

This is useful for debugging and testing.

Returns:

  • A slice of module paths in the cache

func (*ModuleRuntime) LoadAndEvaluate

func (rt *ModuleRuntime) LoadAndEvaluate(modulePath string) (*ModuleInstance, error)

LoadAndEvaluate loads a module and all its dependencies, then evaluates them

This is the main entry point for module execution. It performs the following steps:

  1. Check cache for already-evaluated modules
  2. Load the module (parse, type-check, build interface)
  3. Create a ModuleInstance
  4. Recursively load and evaluate dependencies (topological sort)
  5. Evaluate this module (populate bindings and exports)

The evaluation order is deterministic: dependencies are evaluated before dependents (depth-first search).

Parameters:

  • modulePath: The module path to load (e.g., "stdlib/std/io")

Returns:

  • The evaluated ModuleInstance
  • An error if loading or evaluation fails

Example:

inst, err := rt.LoadAndEvaluate("examples/hello")
if err != nil {
    log.Fatal("Failed to evaluate module:", err)
}
main, _ := inst.GetExport("main")

func (*ModuleRuntime) PreloadModule

func (rt *ModuleRuntime) PreloadModule(path string, loaded *loader.LoadedModule)

PreloadModule adds a pre-loaded module to the loader's cache

This is used to inject modules that were already loaded and elaborated by the pipeline, avoiding redundant loading and elaboration.

Parameters:

  • path: The module path
  • loaded: The LoadedModule with Core AST already populated

Directories

Path Synopsis
Package argdecode converts JSON arguments to AILANG eval.Value types
Package argdecode converts JSON arguments to AILANG eval.Value types

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL