Tuesday, June 3, 2008

Simulation Control Language (SCL)

Simulation Control Lanugage (SCL) is the runtime language used in QUEST for defining logics. It's pretty similar to Visual Basic and Pascal as far as I can tell, in terms of syntax. It's a fairly high level language allowing easy manipulation of files, and even execution of Windows API functions.

SCL is not only used for defining logics in a model (init, process, route, etc), but can also be used to build QUEST macros that you run using custom buttons or even remote execution through QUEST's Batch Control Lanugage (BCL). The possibilities with SCL aren't necessarily limitless, but it's a very robust language and it takes a lot of effort to run into its limitations.

SCL files are stored in text files and are not embedded within a simulation model like some other simulation packages do. This makes it easy to apply SCL code to different models, but it also means you can destroy the functionality of any number of models just by modifying a single logic file to fit a single case.

To get you started with SCL, I'll go with the old standby and just create a simple "Hello World" program to illustrate some basic SCL concepts.

To start, you first need to open a text editor and start your scl file. You can use notepad or any text editor. I prefer to use RJ-TextEd (See here) because it allows code folding and syntax highlighting; so if you have a large number of subroutines in a file you can more easily navigate the file than using notepad.

With your text editor of choice open, first create a new subroutine by defining it:

procedure hello_world()

The word "procedure" tells the scl compiler that this is a subroutine that does not return anything. If you want to return a value you replace the word "procedure" with "routine". I'll cover routines in more detail at a later time. You're also able to pass in different arguments to subroutines, but we don't need to worry about that just yet. We just want to display "hello world" in QUEST.

With your procedure name defined, we can finish defining the procedure by defining the start and end of the program:

procedure hello_world()
Begin

End

All code that you execute must fall between the Begin and End lines of the subroutine you're using. Each line of code represents one command (unless you use the line continuation character, "\").

QUEST has some decent documentation on SCL built in subroutines. From this documentation under the I/O Routines section we can find a procedure called "write" that will let us print a message to the QUEST user screen. The syntax is:

WRITE ( #unit_no, pr_expr [ , pr_expr,... ] )

where "#unit_no" is an optional argument which can specify a file or window or tcp/ip stream to write to. Disregard this for now. "pr_expr" is the message we want to write, which can be a variable of just about any type (although some types just print their memory address), though we should stick to printing simple data types( String , Real , Integer ). So the "[ , pr_expr ]" means we can specify any number of variables we want.

We don't need to pass a variable to the "write" procedure; we can pass literal strings or integer/double values as well. To write "hello world" in QUEST, we'd simply call:

write( 'hello world' , cr )

where cr is a built in QUEST variable that is basically a carriage return and line feed.

You can see I used a single quote to define a literal string, "hello world". This is the SCL compiler's preferred way of defining a literal string, but you can use double quotes if you want, as long as you are consistent in a single string definition (you can't say "hello world').

The finished procedure reads as follows:

procedure hello_world()
Begin
write( 'hello world' , cr )
End

Save your scl file into the "SCLMACROS" folder of any QUEST library you have appended. You can save with a txt or scl extension, it really doesn't matter. As long as the information is present in ASCII text the SCL compiler won't care.

We don't need to create a user button to run this macro, and so it'll probably be easier for now to just compile and run the file using BCL. To execute BCL go to File->BCL. You will be given a BCL prompt where you can type or paste a command to execute. The first line of BCL to execute is:

SCL_COMPILE 'hello_world.scl' 0

Replace 'hello_world.scl' with whatever you named your file. Don't worry about the full file path; as long as it's in an "SCLMACROS" folder QUEST should be able to find it. If the file is not found, make sure the library it's in is appended.

The next line of BCL will read:

SCL_EXEC hello_world

This line will execute the hello_world procedure stored in memory after compiling your logic file. When you run this a window should pop up in QUEST that says "hello world".

That was a bit long winded for a hello world type subroutine, but hopefully it explains how you need to define subroutines for QUEST SCL files.

No comments: