interpreted systems programming language

  • Roscoe, Timothy "CLANGER: an interpreted systems programming language" view details Abstract: Clanger is a powerful, yet simple, command language for the Nemesis operating system. It uses runtime type information to interface directly with operating system components. Clanger is a combination of command-line interpreter, scripting language, debugger and prototyping tool. This paper describes why such a language is possible, how it is being implemented, and outlines the language as it currently stands.

    DOI Extract: Background
    Nemesis is the operating system being developed as part of the Pegasus ESPRIT Project [3]. It is based on a Quality of Service (QOS) paradigm for resource management which locates as much operating system functionality as possible in the application, thereby reducing QOS crosstalk between application domains. This is achieved using a structure and linkage mechanism based on the notion of interfaces, described in [8]. An interface is the point at which a service is offered. It is implemented as a closure, i.e. a pair of pointers: one to a state record opaque to the client, and one to an array of function pointers called a method suite. The number and signatures of the functions in the method suite make up the type of the interface, and interface types are defined in an interface definition language (IDL) called MIDDL. Invocation between protection domains and between address spaces is performed through surrogate interfaces.

    Interfaces are the basic linkage mechanism in Nemesis. The operating system code is composed of a set of modules, whose only externally visible symbols are a small number of closure addresses. To give an idea of the size of modules (and thus the granularity of linkage units), the system as it stands for Digital Alpha/AXP machines comprises about 25 modules, with sizes ranging from about 100 to 2,500 lines of C source. Most modules are about 300-400 lines long.

    At a level above virtual addresses, all computational objects in Nemesis can be named in a way modelled on [9]. An interface of type Context provides a flat name space in which textual strings can be bound to objects of arbitrary types. Naming graphs can be built by binding names in One Context to other Contexts. Name spaces can also be composed in an ordered way in the manner of Plan 9's "union directories" [7]. Interfaces conforming to type Context are used extensively within Nemesis.

    Nemesis also provides a module called TypeSystem. This component of the system encapsulates data structures representing every interface type known to the system together with all operation signatures and concrete types defined within each interface. The information is presented as a collection of inter- faces. The Type System is analogous to the Cedar Abstract Machine [10] or the CORBA Interface Repository [4]. In addition, the Type System provides a tagged Any type plus associated runtime type checking and narrowing. It is this Any type to which textual names are mapped by Context'interfaces.

    These two facilties make CLANGER possible: ubiquitous typing within the operating system (coupled with a means to interrogate the type system at run- time), and a uniform naming model based on pathnames, ~tat name spaces and runtime typing. Given an object and its type, an instance of the interpreter can perform any legal operation on it in a typesafe manner without any prior knowledge of its structure. Any linkage-level interface in the operating system can potentially be manipulated from the command line. CLANGER can perform any non-time-critical operation that a piece of C code can. Extract: Background
    Variables in CLANGER
    All variable names in CLANGER are Nemesis pathnames, and all values axe Anys. An instance of the interpreter is associated with a root naming context. This context is used to resolve any variable name. It is also the context in which a new name is bound when a variable is encountered for the first time. New variables are created simply by assigning to them, and their type is inferred from the type of the value they receive. Since variables are nothing more than entries in some naming Context, any value in any name space reachable by a pathname from the interpreter's root is a CLANGER variable.

    For manipulating instances of MIDDL'S concrete types (integers, records, etc.) CLANGER has a full set of operators modelled on C and providing essentially the same functionality. Since each variable carries its own type around with it as part of its value, any operation on a concrete type can be typechecked at invocation time. Similarly, a CLANGER value which is a pointer to an interface closure (also known as an interface reference) can have any valid method invoked on it.

    This embedding of the command language within the operating system's linkage structures gives the language its expressiveness and power. It also results in a very simple base language. For instance, unlike many embedded interpreters, CLANGER does not provide an associative array type. There are plenty of these in the operating system, indeed the most commonly used one is Context, which is the very mechanism used for variable binding anyway. Using associative arrays in CLANGER is just like using any other part of the operating system.

    This also permits an interpreter to be embedded in almost any application with next to no effort--certainly without the need for the ad-hoc C wrappers required for languages such as Python [11] or Tcl [5]. ~rthermore, when a new type is introduced to the system, CLANGER will be able to manipulate its values with no new code whatsoever.
          in ACM SIGOPS Operating Systems Review 29(2) April 1995 view details