Introduction S-Lang (pronounced ``sssslang'') is a simple stack based language interpreter which may be easily embedded into another application making it extensible. Although the language is stack based, it has many features found in higher level languages. This includes both global variables and local variables, branching, looping constructs, as well as functions. In many ways it resembles postscript which is also stack based. The syntax of the language is quite simple. To keep the parsing stage simple and fast, Reverse Polish Notation (RPN) is used throughout. It is perhaps easiest to explain the syntax of the language by analogy with other popular languages. I will choose C because C has influenced the look of S-Lang. ------------------------------------------------------------ C-Like language | S-Lang ------------------------------------------------------------ Global_Variable_List | [global variables] | function(parameter_list) | ( { | [parameter list] local_variable_list | [local variables] | statement1 | statement1 . | . . | . statementn | statementn } | ) function | ------------------------------------------------------------ Here is an actual example. This example computes the sum of the first n integers and returns it. int compute_sum(int n) | ( [n] =n { | int sum, i; | [sum i] | sum = 0; | 0 =sum for (i = 1; i <= n; i = i + 1) | 1 n 1 { | { =i sum = sum + i; | i sum + =sum } | } for | return (sum); | sum } | ) compute_sum The similarities of the program should be obvious. Experienced Slang programmers would never write this program as I have done above. I have chosen to write it this way for pedagogical purposes. A much better way would be to do: ( [n sum] =n 0 =sum 1 n 1 { sum + =sum } for sum ) compute_sum The important thing to realize is that all variables must be declared before they can be used. This is done by enclosing them in brackets. Also note that [n sum] is equivalent to [n] [sum]. Variables declared within a function are considered local variables and hide the definition of global variables of the same name. In C, one would call the function compute_sum with parameter 100 and assign it to a variable y as: y = compute_sum(100); In should be apparant that to perform this same task in S-Lang, one writes: 100 compute_sum =y Please note that there can be no space between the equals sign `=' and the variable upon which it performs the assignment. Arithmetic operators. The arithmetic operators `+', `-', `*', `/' operate on integers. They are defined: x y + --> x + y x y - --> x - y x y * --> x * y x y / --> x / y These operators remove the top two values from the stack and put the result of the operation on the stack. Binary Operations. The binary Boolean operators act on two integers and return an integer. An integer is considered TRUE if it is non-zero otherwise it is FALSE. These operators are x y == ;; TRUE if x equals y x y != ;; TRUE if x is not equal to y x y > ;; TRUE if x is greater than y x y >= ;; TRUE if x is greater than or equal to y x y < ;; TRUE if x is less than y x y <= ;; TRUE if x is less than or equal to y x y or ;; TRUE if either x or y are TRUE x y and ;; TRUE if both x and y are TRUE Here the operator ``pops'' the two variable off the stack and replaces it by the value of the result, TRUE or FALSE (non-zero or zero). Stack Operators The use of local variables greatly simplifies the task of maintaining the stack stack. Nevertheless, S-Lang is a stack based language and there are times when they are useful. pop ;; removes the top object fro the stack dup ;; duplicates the top object on the stack exch ;; exchanges the top two objects of the stack n exchn ;; exchanges the nth object on the stack with top These operators work on all data types--- they are not limited to integers. Block Operators A Block is a sequence of valid executable S-Lang code. As such, a block may contain other blocks. However, a block cannot include function declarations; function declarations must take place at top level. The statements that comprise a block must be enclosed in curly brackets `{}'. Blocks are used for looping and branching. Hence, block operators are `while', `for', `if', etc.... n {block} if ;; executes block if n is TRUE n {block} !if ;; executes block if n is FALSE n {block1} {block2} else ;; block1 if n is TRUE else block2 n {bock} loop ;; executes block n times if n is positive The other block operations are more complex and require explanation. Starting with the simplest... {block} while ;; pops the top value of the stack and if it is TRUE, ;; it pushes it back on the stack and executes the ;; block. It repeats this process until the top value ;; is FALSE (0) first last step ;; pops top three values from the stack as step, last {block} for ;; and first, in that order. If first is less than or ;; equal to last, it pushes first onto the stack and ;; executes the block. It then increments first by ;; step and repeats the process. {block1} ... {blockn} ;; The orelse operator operates on a series of 1 or orelse ;; more blocks. It executes the first block then tests ;; the top of the stack. If it is FALSE, it executes ;; the second block. It continues to do so until one ;; of the blocks returns TRUE. It is important to note ;; that it does not pop the top element from the stack ;; to perfor the test. The stack gets propagated ;; through the blocks so that one block can use the ;; results of the previous one. {block1} ... {blockn} ;; The andelse is just like the orelse except that it andelse ;; continues to execute the blocks until one returns ;; FALSE. String Operators The previous operators act upon integers and blocks. The operators in this section act on character strings. s strlen ;; pops string and returns its length s1 s2 strcat ;; concatenates strings to s1s2 popping s1 and s2 s1 s2 strcmp ;; returns 0 if s1 and s2 are the same, a negative ;; number if s1 is lexically greater, otherwise it ;; returns a positive non-zero integer (s1 ``>''s2) Array Operations s n1 n2 .. nd d create_array ;; creates d dimensional array[n1, n2, ... nd] of ;; type s. Here s (string) is one of ;; "i" integer ;; "s" string ;; "f" float ;; It returns pointer to array on stack. a free_array ;; frees previously created array pointed to by a n1 n2 ... nd a aget ;; returns array element a[n1, n2,...nd] to stack x n1 n2 ... nd a aput ;; assigns x to array element a[n1, n2,...nd] Since the array may be hard to understand, here is an example routine to compute trace of an nxn matrix of integers ( [n a] =a ;; assumes array a on stack as well as size [sum i] 0 =sum 1 n 1 ;; array elements always start at 1 { =i i a aget sum + } for sum ) trace ;;; this routine creates a 10x10 array and sets it diagonal elements to 5 [a] "i" 10 10 2 create_array =a 1 10 1 { =i 5 i i a aput } for Transfer Functions These operators convert data from one type to another. n string ;; converts integer n to its string equivalent. n char ;; converts integer to a string of length 1 whose first ;; character has ascii value n s int ;; returns the ascii value of the first character in ;; the string Miscellaneous Functions s isdigit ;; returns TRUE if the first character of string s is ;; a digit (0-9) s eval ;; evaluates string s as S-Lang code. s defined? ;; returns TRUE if string s is the name of a variable ;; or function The operations described above are the only ones intrinsic to the S-Lang language. However, S-Lang is meant to be embedded into an application which would then add new intrinsic operations to the language (e.g., the JED editor). It is impossible to say more about these functions without explicit reference to the application.