S-Lang is a stack based language. One must learn how to make use of the stack, to a much greater degree than in C or C++, in order to do serious S-Lang programming. For example, exchanging values between a C program and a S-Lang script is done using the stack. To push an integer variable (e.g. ``x'') onto the stack, in S-Lang, the user stipulates the variable followed by a semi-colon: ``x;'' (Figure 1). To capture that value in a C program, the user pops the value off the stack with the ``SLang_pop_integer'' function. This works regardless of data structure type. If ``x'' is an array of 10 floats, then ``x''; pushes the 10 values on the stack.
In Figure 2, the C program pushes an integer value onto the S-Lang stack, using the ``SLang_push_integer'' function. The S-Lang program on the right, pops it off with the S-Lang ``()'' syntax. In S-Lang, ``()='' pops a data structure off the stack and discards it. ``x = ();'' pops a data structure off the stack and assigns it to the S-Lang space variable, ``x''.
In addition to exchanging values via the stack, C programmers can create and manipulate S-Lang variables directly:
// Tell S-Lang to create the variable, x, and initialize it to 42 if(-1 == SLang_load_string(``variable x = 42;'')) {......}
There are two ways a user can run the programs and scripts which exchange data. One method requires two windows: one in which the C program is run, and another with a S-Lang prompt. Alternatively, a C program can execute a S-Lang script using the ``SLang_load_file'' function.
These are the simplest methods of exchanging data; all subsequent methodologies are based upon these basic operations. The necessary C/C++ functions are found in ``slang.h''. These are the methods to be used when minimal coupling between scripts and functions is required.
S-Lang has many strengths, such as array manipulations. But for heavy mathematical processing C or C++ is a better choice than an interpreted scripting language. S-Lang provides a means to incorporate functionality best written in C, into a S-Lang script. To do this, the user casts the C function into a S-Lang intrinsic, making it just as available to the user as ``sin(x)''.
Figure 3 illustrates the method used to make and use a C++-based S-Lang intrinsic. On the left is the CIAO function ``univar''; written in C++, built as a module, and made into a S-Lang intrinsic. It is available for direct use in any S-Lang script the CIAO user wishes to write.
To make ``univar'' known to S-Lang, the user must supply the
function ``init_univar_module''. S-Lang calls the function
automatically.
``init_univar_module'' contains the key function call
which adds the intrinsic: ``SLadd_intrinsic_function''.
The S-Lang script on the right, in Figure 3, shows how a S-Lang intrinsic is used. The S-Lang programmer must first import the module, as shown. When called, the user passes in an x input (xin), an array of x breakpoints, and an array of corresponding y breakpoints (xbp, ybp). ``univar'' returns the result by pushing a status value indicating the mathematical validity of the result, and the interpolated value, onto the S-Lang stack. The S-Lang script captures the resultant values off the stack using the ``(status, yout)'' stack popping syntax, as shown in the script.
Writers of S-Lang and S-Lang/C++ scripts often need common functionality such as FITS or ASCII file operations and data structure representation. In the previous examples, S-Lang variables that are created and are to map to corresponding C++ variables, must be kept synchronized by the programmer. To simplify S-Lang/C++ integration, CIAO provides the programmer with VARMM: a library of classes and methods which is a data interface between C++ and S-Lang (S. Doe, et. al. 2000). VARMM provides classes for data representation, methods to manipulate those data structures, FITS and ASCII file operations, and a simple API. VARMM data elements can be linked to their S-Lang variable counterparts so that a change in the value of the S-Lang variable changes the value in the VARMM object. VARMM ASCII or FITS file read operations can create VARMM and S-Lang data structures containing the file input values.
For a brief illustration of how VARMM can be used, we choose a CIAO C++ application, PRISM, which is commanded to plot a histogram of a selected column of a FITS file. PRISM invokes ChIPS and commands ChIPS to forward the following statement to the S-Lang parser:
prism_data = readbintab(``pe.fits[2][cols pha]'');
``readbintab'' is a VARMM library method which opens the FITS file, pe.fits, creates the S-Lang data structure, ``prism_data'', extracts the ``pha'' column of data, and stores the data in ``prism_data''. PRISM will send a subsequent command to ChIPS to execute the S-Lang script, ``histogram'', which results in the histogram plot. ``prism_data'', a variable in S-Lang scope, is available to the ``histogram'' script as well as any other script the programmer wishes to write and execute.
This work is supported by the Chandra X-Ray Center under NASA contract (NAS8-39073).
S. Doe, M. Noble, and R. Smith 2000, Interactive Analysis and Scripting in CIAO 2.0, ADASS X, P2-41
J. E. Davis 2003, S-Lang Library C Programmer's Guide, V1.4.2