TTM (programming language)

Last updated

TTM
Paradigm general-purpose macro processor
Designed by Steven M. Caine and E. Kent Gordon
First appeared1968
Stable release
1.0
License MIT
Major implementations
Unidata TTM
Influenced by
GAP, GPM, TRAC

TTM is a string oriented, general purpose macro processing programming language developed in 1968 by Steven Caine and E. Kent Gordon at the California Institute of Technology.

Contents

Description

The following description is taken from the original TTM reference manual [1] and the subsequent batch processing extension. [2]

TTM is a recursive, interpretive language designed primarily for string manipulation, text editing, macro definition and expansion, and other applications generally classified as systems programming. It is derived from GAP [3] and GPM. [4]

Initially, TTM was planned as the macro processing portion of an assembler for the IBM System/360 and was designed to overcome the restrictions and inconsistencies which existed in the standard assemblers for that system. [5] [6]

TTM was designed to have all of the power possessed by earlier general macro assemblers but with the unfortunate syntactic and semantic difficulties removed. [7] [8] [9] [10]

During the development of TTM, it became apparent that applications other than assembler macro processing were possible. These include data editing, text manipulation, expression compiling, and macro processing for language processors other than assemblers.

The initial version of TTM was implemented to run in a conversational manner under the Caltech Basic Time Sharing System for the IBM System/360 Model 50. [11] Other versions have been written to run in the batch processing environment of OS/360 and to operate in front of or in conjunction with various language processors.

Syntax and Semantics

The reference implementation assumes that TTM is given a text file containing some combination of ordinary text and TTM function calls (i.e. invocations). The text is scanned character by character. Any ordinary text is passed to the output unchanged (except for escapes). If a TTM function is encountered, it is collected and executed.

The general form of a TTM function call looks like this:

#<functionname;arg1;arg2;...;argn> 

where the function name and the arguments are arbitrary character strings not containing characters of significance: '#', '<', '>', and ';'. The function is invoked with the specified arguments and the resulting text is inserted into the original text in place of the function call. If the function call was prefixed by a single '#' character, then scanning will resume just before the inserted text from the function call.

This is called active invocation.

If the function call was prefixed by two '#' characters, then scanning resumes just after the inserted text. This is called passive invocation.

During the collection of a function call, additional function calls may be encountered, for example, this:

#<functionname;arg1;#<f2;arg;...>;...;argn> 

The nested function call will be invoked when encountered and the result inserted into the text of the outer function call and scanning of the outer function call resumes at the place indicated by the number of '#' characters preceding the nested call.

If a function takes, for example, 2 arguments, any extras are ignored. For user defined functions, if too few arguments are provided, additional one are added with the value of the empty string (""). A function may have a maximum of 62 arguments.

As with other applicative programming languages, a TTM function may be recursive and may be defined as the result of the invocation of a sequence of other function calls.

Functions are either built-in or user defined. A large number of built-in functions exist and are defined in the TTM reference manual [1]

Function definition

User defined functions are created using the following two built-in functions.

The first function, ds for "define string", defines a named string in the TTM dictionary. The name is "name" and its value is "text". Invoking this named string will cause its invocation to be replaced by the value (i.e. "text").

The second function, ss for "segment string", scans the text of a previously defined string looking for occurrences of its arguments: text1, text2, ... textn. When an occurrence is found, it is replaced with a segment mark. All occurrences of each argument are replaced by the same segment mark.

When a segmented string is invoked, each argument to the call is substituted for the corresponding segment mark. Consider this example.

[01] #<ds;F;abcxxdefyy> [02] #<ss;F;xx;yy> [03] #<F;11;22> 

The string F is defined (line 1) and its body "abcxxdefyy" is segmented on the two strings "xx" and "yy" (line2). When invoked (line 3), it will return the value "abc11def22". In effect, we have a user defined function F with two arguments.

Escaping

It is possible to escape one or more characters using either of two conventions.

  1. <...> escape multiple characters.
  2. @ escape a single character

If a string is enclosed in <...>, then it is scanned but not interpreted by TTM. In the scanning process, the outer < and > brackets are removed. If there are nested occurrences of <...>, then they are scanned but the < and > are not removed. The brackets must balance: the number of '<' characters must equal the number of '>' characters.

The '@' escape convention causes the interpreter to pass as-is the character after the '@'. The leading '@' is left if it within a <...> escape sequence, otherwise it is removed. One use is to allow unbalanced occurrences of '<' or '>' characters.

Examples

Example 1: Function Definition

The most basic example involves defining a function that is useful for defining additional functions. This "meta" function is called def. It is written as:

#<ds;def;<##<ds;name;<text>>;##<ss;name;subs>>> #<ss;def;name;subs;text> 

We can, for example, use def to define the string XX as 12345 and then segment XX on 34 by writing this.

#<def;XX;34;12345> 

The call

#<XX;0000> 

will then produce the string "1200005".

The def function operates by invoking ds to define the function name and initial text in the TTM dictionary – XX in our example.

Then the text of the dictionary entry of XX is segmented with respect to any specified arguments: "34" in this case.

When XX is invoked, its argument is substituted for the segment mark.

Example 2: Factorial

The factorial function can be defined (using the above ##<def> function) as follows.

#<def;n!;N;<#<lt;N;2;1;<#<mu;N;#<n!;#<su;N;1>>>>>>> 

Notice that the inner computation (#<mu...) is escaped so it will only be evaluated after the #<lt... functions is executed and returns that nested computation as its result.

An example call would look like this.

#<n!;3> 

and would return the string 6.

See also

The exact relationship between TTM and TRAC is unknown. The TTM documentation indicates that it was derived from GAP [3] and GPM. [4] In any case, the description of the characteristics of TRAC also apply to TTM. However, by removing the syntactic distinction between built-in and user-defined function, TTM would appear to be a much cleaner language.

Notes

  1. 1 2 Caine, S. H.; Gordon, E.K. (1968). "TTM: An Experimental Interpretive Language" (PDF). California Institute of Technology, Willis H. Booth Computing Center, Programming Report No. 7.PD-icon.svg This article incorporates text from this source, which is in the public domain .
  2. Caine, S. H.; Gordon, E. K. (May 1969). "TTM: A Macro Language for Batch Processing" (PDF). California Institute of Technology, Willis H. Booth Computing Center, Programming Report No. 8.PD-icon.svg This article incorporates text from this source, which is in the public domain .
  3. 1 2 Farber, D. J., 635 Assembly System - GAP. Bell Telephone Laboratories Computation Center (1964).
  4. 1 2 Strachey, C., A General Purpose Macro Generator. Comput J 8, 3(1965), pp. 225-241.
  5. IBM, System/360 Assembler Language, C28-6514-4, (1967).
  6. Caine, S.H. et al., Report of the Systems Objectives and Requirements Committee, SHARE, 1965, pp. 29-40.
  7. Eastwood, D.E. and McIlroy, M.D., Macro Compiler Modification of SAP. Bell Telephone Laboratories omputation Center, 1959.
  8. McClure, R.M., Description of CODAPT Assembler, 1960.
  9. Caine, S.H., Reference Manual for CIT 7090/7040 Experimental Macro Assembly Program (XMAP). California Institute of Technology, Willis H. Booth Computing Center (1964).
  10. McIlroy, M.D., Macro Instruction Extensions of Compiler Languages. CACM 3, No. 4 (1960), 214-220.
  11. Caine, S.H., et al., An Operating Environment for Programming Research. California Institute of Technology, Willis H. Booth Computing Center Programming Report No. 1, 1967.

Related Research Articles

<span class="mw-page-title-main">Macro (computer science)</span> Rule for substituting a set input with a set output

In computer programming, a macro is a rule or pattern that specifies how a certain input should be mapped to a replacement output. Applying a macro to an input is known as macro expansion. The input and output may be a sequence of lexical tokens or characters, or a syntax tree. Character macros are supported in software applications to make it easy to invoke common command sequences. Token and tree macros are supported in some programming languages to enable code reuse or to extend the language, sometimes for domain-specific languages.

SNOBOL is a series of programming languages developed between 1962 and 1967 at AT&T Bell Laboratories by David J. Farber, Ralph E. Griswold and Ivan P. Polonsky, culminating in SNOBOL4. It was one of a number of text-string-oriented languages developed during the 1950s and 1960s; others included COMIT and TRAC.

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.

In computing, inline expansion, or inlining, is a manual or compiler optimization that replaces a function call site with the body of the called function. Inline expansion is similar to macro expansion, but occurs during compilation, without changing the source code, while macro expansion occurs prior to compilation, and results in different text that is then processed by the compiler.

The C preprocessor is the macro preprocessor for several computer programming languages, such as C, Objective-C, C++, and a variety of Fortran languages. The preprocessor provides inclusion of header files, macro expansions, conditional compilation, and line control.

In computer programming, a parameter or a formal argument is a special kind of variable used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are the values of the arguments with which the subroutine is going to be called/invoked. An ordered list of parameters is usually included in the definition of a subroutine, so that, each time the subroutine is called, its arguments for that call are evaluated, and the resulting values can be assigned to the corresponding parameters.

TRACLanguage is a programming language developed between 1959–1964 by Calvin Mooers and first implemented on the PDP-1 in 1964 by L. Peter Deutsch. It was one of three "first languages" recommended by Ted Nelson in Computer Lib. TRAC T64 was used until at least 1984, when Mooers updated it to TRAC T84.

printf is a C standard library function that formats text and writes it to standard output.

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

m4 is a general-purpose macro processor included in most Unix-like operating systems, and is a component of the POSIX standard.

High Level Assembly (HLA) is a language developed by Randall Hyde that allows the use of higher-level language constructs to aid both beginners and advanced assembly developers. It fully supports advanced data types and object-oriented programming. It uses a syntax loosely based on several high-level programming languages (HLLs), such as Pascal, Ada, Modula-2, and C++, to allow the creation of readable assembly language programs, and to allow HLL programmers to learn HLA as fast as possible.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

In computer programming, a one-pass compiler is a compiler that passes through the parts of each compilation unit only once, immediately translating each part into its final machine code. This is in contrast to a multi-pass compiler which converts the program into one or more intermediate representations in steps between source code and machine code, and which reprocesses the entire compilation unit in each sequential pass.

The uniform access principle of computer programming was put forth by Bertrand Meyer. It states "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation." This principle applies generally to the syntax of object-oriented programming languages. In simpler form, it states that there should be no syntactical difference between working with an attribute, pre-computed property, or method/query of an object.

scanf, short for scan formatted, is a C standard library function that reads and parses text from standard input.

In 1979, Honeywell Information Systems announced a new programming language for their time-sharing service named TEX, an acronym for the Text Executive text processing system. TEX was a first-generation scripting language developed around the time of AWK and used by Honeywell initially as an in-house system test automation tool.

Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented, aspect-oriented, reflective and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.

In computer programming, string interpolation is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple template processing or, in formal terms, a form of quasi-quotation. The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current context.

The PL/I preprocessor is the preprocessor for the PL/I computer programming language. The preprocessor interprets a subset of the full PL/I language to perform source file inclusion, conditional compilation, and macro expansion.

References