scriptling

package module
v0.0.0-...-ce6e6e9 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2026 License: MIT Imports: 14 Imported by: 0

README

Scriptling

GitHub License

Scriptling - Python-like Scripting Language for Go

A minimal, sandboxed interpreter for LLM agents to execute code and interact with REST APIs. Python-inspired syntax designed for embedding in Go applications.

Features

  • Python-like syntax with indentation-based blocks
  • Core types: integers, floats, strings, booleans, lists, dictionaries
  • Control flow: if/elif/else, while, for loops, break, continue
  • Object-oriented: Classes with single inheritance, methods, and constructors
  • Advanced features: functions, lambda, list comprehensions, error handling
  • Libraries: including json, regex, math, time, requests, subprocess (load on demand)
  • Go integration: Register functions, exchange variables
  • Fast: Lightweight interpreter, only loads what you need

Differences from Python

While Scriptling is inspired by Python, it has some key differences:

  • Single Inheritance Only: Classes support single inheritance (e.g., class Dog(Animal):), but not multiple inheritance.
  • No Nested Classes: Classes cannot be defined within other classes.
  • Simplified Scope: nonlocal and global keywords work slightly differently.
  • Go Integration: Designed primarily for embedding in Go, with direct type mapping.
  • Sandboxed: No direct access to filesystem or network unless explicitly enabled via libraries.

Installation

go get github.com/paularlott/scriptling

Quick Start

package main

import (
    "fmt"
    "github.com/paularlott/scriptling"
    "github.com/paularlott/scriptling/stdlib"
)

func main() {
    // Create interpreter
    p := scriptling.New()

    // Register all standard libraries
    stdlib.RegisterAll(p)

    // Execute Scriptling code
    result, err := p.Eval(`
# Variables and types
x = 42
name = "Alice"
numbers = [1, 2, 3]

# Functions
def greet(n):
    return "Hello " + n

# Output
print(greet(name))
print("Sum:", x + len(numbers))
`)
    if err != nil {
        fmt.Println("Error:", err)
    }
}

CLI Tool

Scriptling includes a command-line interface for running scripts directly:

# Install Task (build tool)
brew install go-task/tap/go-task

# Build CLI for current platform
task build

# Run scripts
./bin/scriptling script.py
echo 'print("Hello")' | ./bin/scriptling
./bin/scriptling --interactive

# Build for all platforms
task build-all

See scriptling-cli/README.md for details.

Go API

Basic Usage
import (
    "github.com/paularlott/scriptling"
    "github.com/paularlott/scriptling/stdlib"
)

p := scriptling.New()

// Register libraries as needed
stdlib.RegisterAll(p)  // Register all standard libraries
// Or register individual libraries:
// p.RegisterLibrary(stdlib.JSONLibraryName, stdlib.JSONLibrary)
// p.RegisterLibrary(stdlib.MathLibraryName, stdlib.MathLibrary)

// Execute code
result, err := p.Eval("x = 5 + 3")

// Exchange variables
p.SetVar("name", "Alice")
value, objErr := p.GetVarAsString("name")

// Register Go functions
p.RegisterFunc("custom", func(ctx context.Context, kwargs map[string]object.Object, args ...object.Object) object.Object {
    return &object.String{Value: "result"}
})

// Register Scriptling functions
p.RegisterScriptFunc("my_func", `
def my_func(x):
    return x * 2
my_func
`)

// Register Scriptling libraries
p.RegisterScriptLibrary("mylib", `
def add(a, b):
    return a + b
PI = 3.14159
`)

// Set on-demand library callback for dynamic loading
p.SetOnDemandLibraryCallback(func(p *Scriptling, libName string) bool {
    if libName == "disklib" {
        // Load library from disk and register it
        script, err := loadLibraryFromDisk(libName)
        if err != nil {
            return false
        }
        return p.RegisterScriptLibrary(libName, script) == nil
    }
    return false
})
Libraries
import (
    "github.com/paularlott/scriptling"
    "github.com/paularlott/scriptling/stdlib"
    "github.com/paularlott/scriptling/extlibs"
)

// Create interpreter
p := scriptling.New()

// Register all standard libraries
stdlib.RegisterAll(p)

// Or register individual standard libraries
p.RegisterLibrary(stdlib.JSONLibraryName, stdlib.JSONLibrary)
p.RegisterLibrary(stdlib.MathLibraryName, stdlib.MathLibrary)

// Register additional custom libraries
p.RegisterLibrary(extlibs.RequestsLibraryName, extlibs.RequestsLibrary)

// Register os and pathlib with security restrictions
extlibs.RegisterOSLibrary(p, []string{"/tmp", "/home/user/data"})
extlibs.RegisterPathlibLibrary(p, []string{"/tmp", "/home/user/data"})

// Import libraries programmatically (no need for import statements in scripts)
p.Import("json")

// Use in scripts
p.Eval(`
import requests
import os

response = requests.get("https://api.example.com/data")
data = json.parse(response["body"])  # json already imported via p.Import()
files = os.listdir("/tmp")
`)

Examples

See examples/ directory:

  • scripts/ - Script examples and Go integration
  • openai/scriptlingcoder/ - AI coding assistant with custom tools (inspired by nanocode)
  • mcp/ - MCP server for LLM testing

Run examples:

cd examples/scripts
go run main.go test_basics.py

# AI coding assistant (⚠️ executes AI-generated code)
cd examples/openai/scriptlingcoder
../../../bin/scriptling scriptlingcoder.py

Documentation

Testing

# Run all tests
go test ./...

# Run benchmarks
go test -bench=. -run=Benchmark

License

MIT

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromGo

func FromGo(v interface{}) object.Object

FromGo converts a Go interface{} value to a scriptling Object. It handles primitive types (nil, bool, int, float, string), nested structures (maps, slices), and falls back to JSON marshaling for unknown types.

func Get

func Get(script string) (*ast.Program, bool)

Get retrieves a cached program by script content

func Set

func Set(script string, program *ast.Program)

Set stores a program in the cache by script content

func ToGo

func ToGo(obj object.Object) interface{}

ToGo converts a scriptling Object to a Go interface{}. It returns the underlying Go value for the object type.

func ToGoError

func ToGoError(obj object.Object) error

ToGoError converts a scriptling Object to a Go error. If the object is an Error type, it returns a Go error with the error message. Otherwise, it returns nil.

Types

type Scriptling

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

func New

func New() *Scriptling

func (*Scriptling) CallFunction

func (p *Scriptling) CallFunction(name string, args ...interface{}) (object.Object, error)

CallFunction calls a registered function by name with Go arguments. Args are Go types (int, string, etc.) that will be converted to Object. Returns object.Object - use .AsInt(), .AsString(), etc. to extract value.

Works with both Go-registered functions (via RegisterFunc) and script-defined functions.

Keyword arguments can be passed as the last argument using map[string]interface{}.

Example:

p.RegisterFunc("add", addFunc)
result, err := p.CallFunction("add", 10, 32)
sum, _ := result.AsInt()

// With keyword arguments
result, err := p.CallFunction("format", "value", map[string]interface{}{"prefix": ">>"})

func (*Scriptling) CallFunctionWithContext

func (p *Scriptling) CallFunctionWithContext(ctx context.Context, name string, args ...interface{}) (object.Object, error)

CallFunctionWithContext calls a registered function by name with Go arguments and a context. The context can be used for cancellation or timeouts. Args are Go types (int, string, etc.) that will be converted to Object. Returns object.Object - use .AsInt(), .AsString(), etc. to extract value.

Works with both Go-registered functions (via RegisterFunc) and script-defined functions.

Keyword arguments can be passed as the last argument using map[string]interface{}.

Example:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
result, err := p.CallFunctionWithContext(ctx, "add", 10, 32)
sum, _ := result.AsInt()

// With keyword arguments
result, err := p.CallFunctionWithContext(ctx, "format", "value", map[string]interface{}{"prefix": ">>"})

func (*Scriptling) EnableOutputCapture

func (p *Scriptling) EnableOutputCapture()

EnableOutputCapture enables capturing print output instead of sending to stdout

func (*Scriptling) Eval

func (p *Scriptling) Eval(input string) (object.Object, error)

Eval executes script without timeout (backwards compatible)

func (*Scriptling) EvalWithContext

func (p *Scriptling) EvalWithContext(ctx context.Context, input string) (object.Object, error)

EvalWithContext executes script with context for timeout/cancellation

func (*Scriptling) EvalWithTimeout

func (p *Scriptling) EvalWithTimeout(timeout time.Duration, input string) (object.Object, error)

EvalWithTimeout executes script with timeout

func (*Scriptling) GetOutput

func (p *Scriptling) GetOutput() string

GetOutput returns captured output and clears the buffer

func (*Scriptling) GetVar

func (p *Scriptling) GetVar(name string) (interface{}, object.Object)

func (*Scriptling) GetVarAsBool

func (p *Scriptling) GetVarAsBool(name string) (bool, object.Object)

func (*Scriptling) GetVarAsDict

func (p *Scriptling) GetVarAsDict(name string) (map[string]object.Object, object.Object)

func (*Scriptling) GetVarAsFloat

func (p *Scriptling) GetVarAsFloat(name string) (float64, object.Object)

func (*Scriptling) GetVarAsInt

func (p *Scriptling) GetVarAsInt(name string) (int64, object.Object)

func (*Scriptling) GetVarAsList

func (p *Scriptling) GetVarAsList(name string) ([]object.Object, object.Object)

func (*Scriptling) GetVarAsString

func (p *Scriptling) GetVarAsString(name string) (string, object.Object)

Convenience methods for type-safe variable access

func (*Scriptling) Import

func (p *Scriptling) Import(names interface{}) error

Import imports a library into the current environment, making it available for use without needing an import statement in scripts

func (*Scriptling) RegisterFunc

func (p *Scriptling) RegisterFunc(name string, fn func(ctx context.Context, kwargs object.Kwargs, args ...object.Object) object.Object, helpText ...string)

func (*Scriptling) RegisterLibrary

func (p *Scriptling) RegisterLibrary(name string, lib *object.Library)

RegisterLibrary registers a new library that can be imported by scripts

func (*Scriptling) RegisterScriptFunc

func (p *Scriptling) RegisterScriptFunc(name string, script string) error

RegisterScriptFunc registers a function written in Scriptling The script should define a function and this method will extract it and register it by name

func (*Scriptling) RegisterScriptLibrary

func (p *Scriptling) RegisterScriptLibrary(name string, script string) error

RegisterScriptLibrary registers a library written in Scriptling The script should define functions/values that will be available when the library is imported

func (*Scriptling) SetObjectVar

func (p *Scriptling) SetObjectVar(name string, obj object.Object) error

SetObjectVar sets a variable in the environment from a scriptling Object. This is useful when you already have a scriptling object (like an Instance) and want to set it directly without converting from Go types.

func (*Scriptling) SetOnDemandLibraryCallback

func (p *Scriptling) SetOnDemandLibraryCallback(callback func(*Scriptling, string) bool)

SetOnDemandLibraryCallback sets a callback that is called when a library import fails The callback receives the Scriptling instance and the library name, and should return true if it successfully registered the library using RegisterLibrary or RegisterScriptLibrary

func (*Scriptling) SetVar

func (p *Scriptling) SetVar(name string, value interface{}) error

Directories

Path Synopsis
Package build contains build-time version information for Scriptling
Package build contains build-time version information for Scriptling
examples
logging command
openai/instance command
openai/shared command
Package extlibs provides external libraries that need explicit registration
Package extlibs provides external libraries that need explicit registration
ai
mcp
tools
getversion command

Jump to

Keyboard shortcuts

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