Syntax Restriction

Risor allows you to restrict which language constructs a script can use. This is useful when embedding Risor as an expression evaluator, a configuration language, or a sandboxed scripting environment where certain features should be disallowed.

Presets

Risor includes three built-in syntax presets, from most restrictive to least.

ExpressionOnly

Allows only expressions. No variable declarations, assignments, function definitions, or control flow. Good for evaluating formulas, template expressions, and computed fields.

result, err := risor.Eval(ctx, "price * 1.1",
    risor.WithEnv(map[string]any{"price": 100.0}),
    risor.WithSyntax(risor.ExpressionOnly),
)
// result: 110.0

Scripts that attempt to use statements will fail at compile time:

// This will return a compile error
_, err := risor.Eval(ctx, "let x = 10",
    risor.WithSyntax(risor.ExpressionOnly),
)

BasicScripting

Allows expressions, variable declarations, assignments, and conditionals, but disallows function definitions and other advanced constructs. Good for simple configuration scripts and rule evaluation.

result, err := risor.Eval(ctx, source,
    risor.WithEnv(risor.Builtins()),
    risor.WithSyntax(risor.BasicScripting),
)

FullLanguage

Allows the complete Risor language with no restrictions. This is the default when no WithSyntax option is provided.

result, err := risor.Eval(ctx, source,
    risor.WithEnv(risor.Builtins()),
    risor.WithSyntax(risor.FullLanguage),
)

Custom Validators

For more fine-grained control, use WithValidator to provide a custom AST validator. The validator receives the parsed AST and can reject scripts that contain disallowed constructs.

result, err := risor.Eval(ctx, source,
    risor.WithValidator(myValidator),
)

Validators run after parsing but before compilation. If the validator returns an error, the script is not compiled or executed.

Custom Transformers

Use WithTransform to provide a custom AST transformer. Transformers can modify the AST after parsing and validation, enabling use cases like automatic instrumentation, macro expansion, or syntax desugaring.

result, err := risor.Eval(ctx, source,
    risor.WithTransform(myTransformer),
)

Combining with Resource Limits

Syntax restriction pairs well with resource limits. For example, an expression evaluator might use ExpressionOnly for safety and a modest step limit as a belt-and-suspenders safeguard:

result, err := risor.Eval(ctx, expr,
    risor.WithEnv(env),
    risor.WithSyntax(risor.ExpressionOnly),
    risor.WithMaxSteps(10000),
    risor.WithTimeout(time.Second),
)

Risor © 2026 Deep Noodle