<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<TITLE> A Guide to the S-Lang Language: Overview of the Language</TITLE>
<LINK HREF="slang-4.html" REL=next>
<LINK HREF="slang-2.html" REL=previous>
<LINK HREF="slang.html#toc3" REL=contents>
</HEAD>
<BODY>
<A HREF="slang-4.html">Next</A>
<A HREF="slang-2.html">Previous</A>
<A HREF="slang.html#toc3">Contents</A>
<HR>
<H2><A NAME="s3">3. Overview of the Language</A></H2>

<P> 
<P>This purpose of this section is to give the reader a feel for the
<B>S-Lang</B> language, its syntax, and its capabilities.  The information
and examples presented in this section should be sufficient to
provide the reader with the necessary background to understand the
rest of the document.
<P>
<H2><A NAME="ss3.1">3.1 Variables and Functions</A>
</H2>

<P> 
<P><B>S-Lang</B> is different from many other interpreted languages in the
sense that all variables and functions must be declared before they
can be used.
<P>Variables are declared using the <CODE>variable</CODE> keyword, e.g.,
<BLOCKQUOTE><CODE>
<PRE>
     variable x, y, z;
</PRE>
</CODE></BLOCKQUOTE>

declares three variables, <CODE>x</CODE>, <CODE>y</CODE>, and <CODE>z</CODE>.  Note the
semicolon at the end of the statement.  <EM>All <B>S-Lang</B> statements must
end in a semi-colon.</EM>
<P>Unlike compiled languages such as C, it is not necessary to specify
the data type of a <B>S-Lang</B> variable.  The data type of a <B>S-Lang</B>
variable is determined upon assignment.  For example, after
execution of the statements
<BLOCKQUOTE><CODE>
<PRE>
     x = 3;
     y = sin (5.6);
     z = "I think, therefore I am.";
</PRE>
</CODE></BLOCKQUOTE>

<CODE>x</CODE> will be an integer, <CODE>y</CODE> will be a
double, and <CODE>z</CODE> will be a string.  In fact, it is even possible
to re-assign <CODE>x</CODE> to a string:
<BLOCKQUOTE><CODE>
<PRE>
     x = "x was an integer, but now is a string";
</PRE>
</CODE></BLOCKQUOTE>

Finally, one can combine variable declarations and assignments in
the same statement:
<BLOCKQUOTE><CODE>
<PRE>
     variable x = 3, y = sin(5.6), z = "I think, therefore I am.";
</PRE>
</CODE></BLOCKQUOTE>
<P>Most functions are declared using the <CODE>define</CODE> keyword.  A
simple example is
<BLOCKQUOTE><CODE>
<PRE>
      define compute_average (x, y)
      {
         variable s = x + y;
         return s / 2.0;
      }
</PRE>
</CODE></BLOCKQUOTE>

which defines a function that simply computes the average of two
numbers and returns the result.  This example shows that a function
consists of three parts: the function name, a parameter list, and
the function body.
<P>The parameter list consists of a comma separated list of variable
names.  It is not necessary to declare variables within a parameter
list; they are implicitly declared.  However, all other <EM>local</EM>
variables used in the function must be declared.  If the function
takes no parameters, then the parameter list must still be present,
but empty:
<BLOCKQUOTE><CODE>
<PRE>
      define go_left_5 ()
      {
         go_left (5);
      }
</PRE>
</CODE></BLOCKQUOTE>

The last example is a function that takes no arguments and returns
no value.  Some languages such as PASCAL distinguish such objects
from functions that return values by calling these objects
<EM>procedures</EM>.  However, <B>S-Lang</B>, like C, does not make such a
distinction.
<P>The language permits <EM>recursive</EM> functions, i.e., functions that
call themselves.  The way to do this in <B>S-Lang</B> is to first declare
the function using the form:
<BLOCKQUOTE><CODE>
define <EM>function-name</EM> ();
</CODE></BLOCKQUOTE>

It is not necessary to declare a parameter list when declaring a
function in this way.
<P>The most famous example of a recursive function is the factorial
function.  Here is how to implement it using <B>S-Lang</B>:
<BLOCKQUOTE><CODE>
<PRE>
     define factorial ();   % declare it for recursion
     
     define factorial (n)
     {
        if (n &lt; 2) return 1;
        return n * factorial (n - 1);
     }
</PRE>
</CODE></BLOCKQUOTE>

This example also shows how to mix comments with code.  <B>S-Lang</B> uses
the `<CODE>%</CODE>' character to start a comment and all characters from
the comment character to the end of the line are ignored.
<P>
<P>
<H2><A NAME="ss3.2">3.2 Strings</A>
</H2>

<P> 
<P>Perhaps the most appealing feature of any interpreted language is
that it frees the user from the responsibility of memory management.
This is particularly evident when contrasting how
<B>S-Lang</B> handles string variables with a lower level language such as
C.  Consider a function that concatenates three strings.  An
example in <B>S-Lang</B> is:
<BLOCKQUOTE><CODE>
<PRE>
     define concat_3_strings (a, b, c)
     {
        return strcat (a, strcat (b, c));
     }
</PRE>
</CODE></BLOCKQUOTE>

This function uses the built-in
<CODE>strcat</CODE> function for concatenating two strings.  In C, the
simplest such function would look like:
<BLOCKQUOTE><CODE>
<PRE>
     char *concat_3_strings (char *a, char *b, char *c)
     {
        unsigned int len;
        char *result;
        len = strlen (a) + strlen (b) + strlen (c);
        if (NULL == (result = (char *) malloc (len + 1)))
          exit (1);
        strcpy (result, a);
        strcat (result, b);
        strcat (result, c);
        return result;
     }
</PRE>
</CODE></BLOCKQUOTE>

Even this C example is misleading since none of the issues of memory
management of the strings has been dealt with.  The <B>S-Lang</B> language
hides all these issues from the user.
<P>Binary operators have been defined to work with the string data
type.  In particular the <CODE>+</CODE> operator may be used to perform
string concatenation.  That is, one can use the
<CODE>+</CODE> operator as an alternative to <CODE>strcat</CODE>:
<BLOCKQUOTE><CODE>
<PRE>
      define concat_3_strings (a, b, c)
      {
         return a + b + c;
      }
</PRE>
</CODE></BLOCKQUOTE>

See section ??? for more information about string variables.
<P>
<P>
<H2><A NAME="ss3.3">3.3 Referencing and Dereferencing</A>
</H2>

<P> 
The unary prefix operator, <CODE>&amp;</CODE>, may be used to create a
<EM>reference</EM> to an object, which is similar to a pointer
in other languages.  References are commonly used as a mechanism to
pass a function as an argument to another function as the following
example illustrates:
<BLOCKQUOTE><CODE>
<PRE>
       define compute_functional_sum (funct)
       {
          variable i, sum;

          sum = 0;
          for (i = 0; i &lt; 10; i++)
           {
              sum += @funct (i);
           }
          return sum;
       }
       
       variable sin_sum = compute_functional_sum (&amp;sin);
       variable cos_sum = compute_functional_sum (&amp;cos);
</PRE>
</CODE></BLOCKQUOTE>

Here, the function <CODE>compute_functional_sum</CODE> applies the
function specified by the parameter <CODE>funct</CODE> to the first
<CODE>10</CODE> integers and returns the sum.  The two statements
following the function definition show how the <CODE>sin</CODE> and
<CODE>cos</CODE> functions may be used.
<P>Note the <CODE>@</CODE> operator in the definition of
<CODE>compute_functional_sum</CODE>.  It is known as the <EM>dereference</EM>
operator and is the inverse of the reference operator.
<P>Another use of the reference operator is in the context of the
<CODE>fgets</CODE> function.  For example,
<BLOCKQUOTE><CODE>
<PRE>
      define read_nth_line (file, n)
      {
         variable fp, line;
         fp = fopen (file, "r");
           
         while (n &gt; 0)
           {
              if (-1 == fgets (&amp;line, fp))
                return NULL;
              n--;
           }
         return line;
      }
</PRE>
</CODE></BLOCKQUOTE>

uses the <CODE>fgets</CODE> function to read the nth line of a file.
In particular, a reference to the local variable <CODE>line</CODE> is
passed to <CODE>fgets</CODE>, and upon return <CODE>line</CODE> will be set to
the character string read by <CODE>fgets</CODE>.
<P>Finally, references may be used as an alternative to multiple
return values by passing information back via the parameter list.
The example involving <CODE>fgets</CODE> presented above provided an
illustration of this.  Another example is
<BLOCKQUOTE><CODE>
<PRE>
       define set_xyz (x, y, z)
       {
          @x = 1;
          @y = 2;
          @z = 3;
       }
       variable X, Y, Z;
       set_xyz (&amp;X, &amp;Y, &amp;Z);
</PRE>
</CODE></BLOCKQUOTE>

which, after execution, results in <CODE>X</CODE> set to <CODE>1</CODE>, <CODE>Y</CODE>
set to <CODE>2</CODE>, and <CODE>Z</CODE> set to <CODE>3</CODE>.  A C programmer will
note the similarity of <CODE>set_xyz</CODE> to the following C
implementation:
<BLOCKQUOTE><CODE>
<PRE>
      void set_xyz (int *x, int *y, int *z)
      {
         *x = 1;
         *y = 2;
         *z = 3;
      }
</PRE>
</CODE></BLOCKQUOTE>
<P>
<H2><A NAME="ss3.4">3.4 Arrays</A>
</H2>

<P> 
The <B>S-Lang</B> language supports multi-dimensional arrays of all
datatypes.  For example, one can define arrays of references to
functions as well as arrays of arrays.  Here are a few examples of
creating arrays:
<BLOCKQUOTE><CODE>
<PRE>
       variable A = Integer_Type [10];  
       variable B = Integer_Type [10, 3];
       variable C = [1, 3, 5, 7, 9];
</PRE>
</CODE></BLOCKQUOTE>

The first example creates an array of <CODE>10</CODE> integers and assigns
it to the variable <CODE>A</CODE>.  The second example creates a 2-d array
of <CODE>30</CODE> integers arranged in <CODE>10</CODE> rows and <CODE>3</CODE> columns
and assigns the result to <CODE>B</CODE>.  In the last example, an array
of <CODE>5</CODE> integers is assigned to the variable <CODE>C</CODE>.  However,
in this case the elements of the array are initialized to the
values specified.  This is known as an <EM>inline-array</EM>.
<P><B>S-Lang</B> also supports something called an
<EM>range-array</EM>.  An example of such an array is
<BLOCKQUOTE><CODE>
<PRE>
      variable C = [1:9:2];
</PRE>
</CODE></BLOCKQUOTE>

This will produce an array of 5 integers running from <CODE>1</CODE>
through <CODE>9</CODE> in increments of <CODE>2</CODE>.
<P>Arrays are passed by reference to functions and never by value.
This permits one to write functions which can initialize arrays.
For example,
<BLOCKQUOTE><CODE>
<PRE>
      define init_array (a)
      {
         variable i, imax;
         
         imax = length (a);
         for (i = 0; i &lt; imax; i++)
           { 
              a[i] = 7;
           }
      }
      
      variable A = Integer_Type [10];
      init_array (A);
</PRE>
</CODE></BLOCKQUOTE>

creates an array of <CODE>10</CODE> integers and initializes all its
elements to <CODE>7</CODE>.  
<P>There are more concise ways of accomplishing the result of the
previous example.  These include:
<BLOCKQUOTE><CODE>
<PRE>
      variable A = [7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
      variable A = Integer_Type [10];  A[[0:9]] = 7;
      variable A = Integer_Type [10];  A[*] = 7;
</PRE>
</CODE></BLOCKQUOTE>

The second and third methods use an array of indices to index the array
<CODE>A</CODE>.  In the second, the range of indices has been explicitly
specified, whereas the third example uses a wildcard form.  See
section ??? for more information about array indexing.
<P>Although the examples have pertained to integer arrays, the fact is
that <B>S-Lang</B> arrays can be of any type, e.g.,
<BLOCKQUOTE><CODE>
<PRE>
       variable A = Double_Type [10];
       variable B = Complex_Type [10];
       variable C = String_Type [10];
       variable D = Ref_Type [10];
</PRE>
</CODE></BLOCKQUOTE>

create <CODE>10</CODE> element arrays of double, complex, string, and
reference types, respectively.  The last example may be used to
create an array of functions, e.g.,
<BLOCKQUOTE><CODE>
<PRE>
      D[0] = &amp;sin;
      D[1] = &amp;cos;
</PRE>
</CODE></BLOCKQUOTE>
<P>The language also defines unary, binary, and mathematical
operations on arrays.  For example, if <CODE>A</CODE> and <CODE>B</CODE> are
integer arrays, then <CODE>A + B</CODE> is an array whose elements are
the sum of the elements of <CODE>A</CODE> and <CODE>B</CODE>.  A trivial example
that illustrates the power of this capability is
<BLOCKQUOTE><CODE>
<PRE>
        variable X, Y;
        X = [0:2*PI:0.01];
        Y = 20 * sin (X);
</PRE>
</CODE></BLOCKQUOTE>

which is equivalent to the highly simplified C code:
<BLOCKQUOTE><CODE>
<PRE>
        double *X, *Y;
        unsigned int i, n;
        
        n = (2 * PI) / 0.01 + 1;
        X = (double *) malloc (n * sizeof (double));
        Y = (double *) malloc (n * sizeof (double));
        for (i = 0; i &lt; n; i++)
          {
            X[i] = i * 0.01;
            Y[i] = 20 * sin (X[i]);
          }
</PRE>
</CODE></BLOCKQUOTE>
<P>
<P>
<P>
<H2><A NAME="ss3.5">3.5 Structures and User-Defined Types</A>
</H2>

<P> 
<P>A <EM>structure</EM> is similar to an array in the sense that it is a
container object.  However, the elements of an array must all be of
the same type (or of <CODE>Any_Type</CODE>), whereas a structure is
heterogeneous.  As an example, consider
<BLOCKQUOTE><CODE>
<PRE>
      variable person = struct 
      {
         first_name, last_name, age
      };
      variable bill = @person;
      bill.first_name = "Bill";
      bill.last_name = "Clinton";
      bill.age = 51;
</PRE>
</CODE></BLOCKQUOTE>

In this example a structure consisting of the three fields has been
created and assigned to the variable <CODE>person</CODE>.  Then an
<EM>instance</EM> of this structure has been created using the
dereference operator and assigned to <CODE>bill</CODE>.  Finally, the
individual fields of <CODE>bill</CODE> were initialized.  This is an
example of an <EM>anonymous</EM> structure.
<P>A <EM>named</EM> structure is really a new data type and may be created
using the <CODE>typedef</CODE> keyword:
<BLOCKQUOTE><CODE>
<PRE>
      typedef struct
      {
         first_name, last_name, age
      }
      Person_Type;
      
      variable bill = @Person_Type;
      bill.first_name = "Bill";
      bill.last_name = "Clinton";
      bill.age = 51;
</PRE>
</CODE></BLOCKQUOTE>

The big advantage of creating a new type is that one can go on to
create arrays of the data type
<BLOCKQUOTE><CODE>
<PRE>
      variable People = Person_Type [100];
      People[0].first_name = "Bill";
      People[1].first_name = "Hillary";
</PRE>
</CODE></BLOCKQUOTE>
<P>The creation and initialization of a structure may be facilitated
by a function such as
<BLOCKQUOTE><CODE>
<PRE>
      define create_person (first, last, age)
      {
          variable person = @Person_Type;
          person.first_name = first;
          person.last_name = last;
          person.age = age;
          return person;
      }
      variable Bill = create_person ("Bill", "Clinton", 51);
</PRE>
</CODE></BLOCKQUOTE>
<P>Other common uses of structures is the creation of linked lists,
binary trees, etc.  For more information about these and other
features of structures, see section ???.
<P>
<P>
<P>
<H2><A NAME="ss3.6">3.6 Namespaces</A>
</H2>

<P>
<P>In addition to the global namespace, each compilation unit (e.g., a
file) is given a private namespace.  A variable or function name
that is declared using the <CODE>static</CODE> keyword will be placed in
the private namespace associated with compilation unit.  For
example, 
<BLOCKQUOTE><CODE>
<PRE>
       variable i;
       static variable i;
</PRE>
</CODE></BLOCKQUOTE>

defines two variables called <CODE>i</CODE>.  The first declaration
defines <CODE>i</CODE> in the global namespace, but the second declaration
defines <CODE>i</CODE> in the private namespace.
<P>The <CODE>-&gt;</CODE> operator may be used in conjunction with the name of
the namespace to access objects in the name space.  In the above
example, to access the variable <CODE>i</CODE> in the global namespace,
one would use <CODE>Global-&gt;i</CODE>.  Unless otherwise specified, a
private namespace has no name and its objects may not be accessed
from outside the compilation unit.  However, the <CODE>implements</CODE>
function may be used give the private namespace a name, allowing
access to its objects.  For example, if the file <CODE>t.sl</CODE> contains
<BLOCKQUOTE><CODE>
<PRE>
      implements ("A");
      static variable i;
</PRE>
</CODE></BLOCKQUOTE>

then another file may access the variable <CODE>i</CODE> via <CODE>A-&gt;i</CODE>.
<P>
<P>
<HR>
<A HREF="slang-4.html">Next</A>
<A HREF="slang-2.html">Previous</A>
<A HREF="slang.html#toc3">Contents</A>
</BODY>
</HTML>
