Component Interpreter

A Scripting Pattern

Problem

How can you avoid polluting the implementation of a component written in a low-level language with code that provides scripting support for the component?

Context

You want to use an existing software component from within a scripting language.

Forces

Solution

  1. Define a binary API to the new component (this might not be necessary if the component already exists).
  2. Implement a separate class, the Component Interpreter, that translates script commands into invocations upon the binary API of a component instance.
  3. Implement a scripting command that:
    1. Instantiates a new component and a Component Interpreter for the component.
    2. Associates the Component Interpreter with the component instance.
    3. Makes commands implemented by the Component Interpreter available in the script interpreter.

Structure

Consequences

The code that interprets script commands is separated from the code that implements the functionality of the component. The implementation of one can be modified without impacting on the implementation of the other.

You can write Component Interpreters for multiple scripting languages without changing the implementation of the component itself.

Existing components which are not scriptable can be given scripting interfaces without modification of their code.

The binary API between the component and the Component Interpreter can be exposed to other components and used for Configuration Scripting.

If the interface to the component is changed, any Component Interpreters must also be changed.

If the component has some structure that must be navigated (for example, a tree of widgets), and the subcomponents must also be scriptable, then this structure must be mirrored by the Component Interpreter which must provide also provide a way for the scripting language to represent and manipulate sub-components (this is usually done by maintaining a mapping between opaque handles that are manipulated by scripts and sub-component references). The Component Interpreter must intercept all calls that change the component's structure and update its own structures as well.

Known Uses

SWIG is a tool that translates C or C++ header files into Component Interpreters for various popular scripting languages.

Related Patterns

A Component Interpreter is an Adaptor between the interface expected by the scripting language and the binary interface exposed by the component.

The Component Interpreter pattern can be thought of as a Bridge in reverse. Where a Bridge separates interface from implementation to allow the implementation to be easily changed, a Component Interpreter separates interface from implementation to allow the interface to be easily changed.