SML PROGRAMMING

What is SML?

(See also Customizing PC ARC/INFO 3.5.X for a brief introduction to SML.)

At its simplest, SML may be thought of as a script for PC ARC/INFO: just as the WordPerfect[1] macro language is used to emulate frequently used sets of keystrokes, SML may be used to emulate frequently used PC ARC/INFO command dialogs. For example, if you were to work on the coverage TOPO in ARCEDIT over an extended period of time, you might use a text editor to create an ASCII file named startup.sml containing the following lines:

   DISP 4
   EDITC TOPO
   EDITF ARC
   EDITD 10
   SNAPD 10
   SNAPT CLOSEST
   GRAIN 1
   WEED 1
   DRAWE ARC NODE DANGLE TIC IDS
   SEL ALL
   CALC $SYMBOL = LINETYPE
   COO DIG
   MAPE *
   DRAW
Then, whenever you need to initialize your ARCEDIT session, you merely type "arcedit startup" (or "arceditw startup") at the ARC prompt.

SML, however, can go beyond that: it is an actual programming language. You can create menus, retrieve and store data, evaluate expressions, and use logical statements to determine what dialog commands will be passed on and how they are to be structured. For example, if in your previous session you saved your mapextent values to a single-line text file named mape.dat, you could add the following lines to startup.sml to replace the "MAPE *" statement (the line numbers are not part of the actual text; they are there merely for reference):

1   &goto fail &if &nf mape.dat
2   &open mape.dat ioerror
3   &read 1 eof
4   MAPE %1
5   &goto end
6   &label ioerror
7      &type "Error attempting to read file!!!!"
8      &goto fail
9   &label eof
10     &type "File is empty!!!!"
11  &label fail
12     &rem **** the following line is executed in all cases of failure ****
13     MAPE *
14  &label end
15  &close
In the above example, the statements beginning with "&" are SML commands, which notify the SML processor that they are not to be passed on to ARCEDIT's command processor as literal dialog commands; rather, they direct the SML processor to determine what should be passed on.

[NOTE: The convention which I will follow in all examples is to write SML commands in lower case and actual dialog commands in upper case.]

Line 1 tells the SML processor to jump ahead to the location "fail" if the file mape.dat is not found; if that were the case, the SML processor would search through the program file until it encountered line 11, which defines the location using the "&label" command.

Line 2 tells the SML processor to open the file mape.dat in "read" mode, and jump to "ioerror" if the operation fails.

Line 3 tells the SML processor to read a line of text from the file and assign it to variable 1; if the end-of-file mark is encountered instead, the SML processor will jump to "eof."

Line 4 tells the SML processor to pass the text "MAPE %1" to ARCEDIT's command processor, substituting the contents of variable 1 for "%1."

Line 5 tells the SML processor to jump unconditionally to "end."

Line 7 tells the SML processor to write the message "Error attempting to read file!!!!" to the text window: the command processor doesn't "see" the text as a command to execute.

Line 12 tells the SML processor that the text on this line is a remark and should be ignored (the &rem directive is generally used to provide program-related information to anyone examining the code).

Line 15 tells the SML processor to close the data file; otherwise, you will not be able rewrite it at the end of your ARCEDIT session.

The upshot is that if the data may be read successfully, the mapextent will be set to that which was saved at the end of the last session; otherwise, the user must define the mapextent from the digitizer. (Note that there is no "&goto fail" statement after line 10, because the destination desired is the very next line.) SML statements may also be added to ask you if, in fact, you wish to use the previously saved mapextent.

All of the above concepts (and many more!) will be discussed in greater detail in future articles.

Running SML Programs

The SML processor is an interpreter: that is, it reads code from a program file (a.k.a. "SML macro") line by line and acts on the contents of each line. As it reads each line, it subsitutes the contents of variables for variable references (indicated by "%," as in the above example) and the resulting text is evaluated: SML commands are processed internally, while all other lines are passed on to the host application's command processor.

It is important to note that blank lines are also passed on to the command processor; usually they are ignored, but in certain cases they are significant (e.g. terminating an expression in the RESELECT command).

Leading spaces are generally ignored; this is useful for indenting blocks of code to clarify program structure. Do not use the TAB character (^I) for indenting code!

There are four ways to execute an SML program:

1) Give the name of an SML program as an argument when issuing an ARC command; if you type "GENERATE BOUNDARY genbound," GENERATE will run the program genbound.sml immediately upon initialization. This is the required method when a program at the ARC level calls a routine to be executed within ARCEDIT, ARCPLOT, TABLES, FREQUENCY, etc., because each command processor has its own SML processor, and one SML processor cannot "inherit" programs and memory-resident variables from another. More will be said about that in the next article.

[TIP: If you have an SML program arcedit.sml in your current or search directory (see below), it will automatically be executed when you run ARCEDIT (or ARCEDITW); no argument is necessary. The same is true for ARCPLOT, TABLES, etc. This is especially handy for defining function keys in ARCEDIT or redefining screen colors in ARCPLOT to match the hardware colors of your plotter.][2]

2) Use the SML &run directive; if you type "&run setup" at a command prompt, setup.sml will be executed.

3) Use the "@" character; if you were to type "@setup" at a command prompt, it would be treated the same as if you had typed "&run setup."

4) Use the SML &r directive; if you type "&r setup" at a command prompt, setup.sml will be executed. (The difference between &run and &r will be discussed in the next article.)

In all four cases, when a filename is given without an extension, the SML compiler will look first for the filename with a .cml extension (indicating a "compiled" SML—CML files will be discussed under The SML Compiler), then for the filename with a .sml extension.[3] If not found in the local directory, the SML processor will then look in the default search directory %ARC%\UTOOL.

[TIP: You may use the ARC command SMLDIR to set a different search directory.]

SML programs may also be called from another SML program; all of the above three methods may be used. Control is passed back up to the previous program level when the end of the program is reached or when the program issues a &return directive. However, if the SML called was given as an argument to an ARC command, it must issue whatever command(s) necessary to quit the application in order to return control to the previous program level; otherwise, the normal command prompt will appear and you won't return until you quit the application yourself. The SML processor supports up to nine levels of &run nesting, i.e. a program calling a program which in turn calls a program....

SML may also "call" the command prompt through the &tty directive, thereby allowing you to enter commands. You then return control to the program by typing "&return."

Finally, most SML commands may also be typed individually at the command prompt. For example, if in a TABLES session you wish to capture a LIST to a text file named list.txt, you would type the following lines:

   &openw list.txt
   LIST
   &closew

Next: Numbers and Strings


[1]WordPerfect is a registered trademark of Corel Corporation Limited.

[2]CML files are ignored. Also, SML programs passed as arguments take total precedence, in which case the "default" SML is ignored entirely.

[3]SML program files may have any extension, as long as it is declared.


Return to ArcTips page