Definitions

The data items to be used in a User Language Program must be defined before they can be used. There are three kinds of definitions:

The scope of a constant or variable definition goes from the line in which it has been defined to the end of the current block, or to the end of the User Language Program, if the definition appeared outside any block.

The scope of a function definition goes from the closing brace (}) of the function body to the end of the User Language Program.

Constant Definitions

Constants are defined using the keyword enum, as in

enum { a, b, c };

which would define the three constants a, b and c, giving them the values 0, 1 and 2, respectively.

Constants can also be initialized to specific values, like

enum { a, b = 5, c };

where a would be 0, b would be 5 and c would be 6.

Variable Definitions

The general syntax of a variable definition is

[numeric] type identifier [= initializer][, ...];

where type is one of the data or object types, identifier is the name of the variable, and initializer is a optional initial value.

Multiple variable definitions of the same type are separated by commas (,).

If identifier is followed by a pair of brackets ([ ]), this defines an array of variables of the given type. The size of an array is automatically adjusted at runtime.

The optional keyword numeric can be used with string arrays to have them sorted alphanumerically by the sort() function.

By default (if no initializer is present), data variables are set to 0 (or "", in case of a string), and object variables are "invalid".

Examples

   
int i; defines an int variable named i
string s = "Hello"; defines a string variable named s and initializes it to "Hello"
real a, b = 1.0, c; defines three real variables named a, b and c, initializing b to the value 1.0
int n[] = { 1, 2, 3 }; defines an array of int, initializing the first three elements to 1, 2 and 3
numeric string names[]; defines a string array that can be sorted alphanumerically
UL_WIRE w; defines a UL_WIRE object named w
The members of array elements of object types can't be accessed directly:
UL_SIGNAL signals[];
...
UL_SIGNAL s = signals[0];
printf("%s", s.name);

Function Definitions

You can write your own User Language functions and call them just like the Builtin Functions. The general syntax of a function definition is

type identifier(parameters)
{
  statements
}

where type is one of the data or object types, identifier is the name of the function, parameters is a list of comma separated parameter definitions, and statements is a sequence of statements. Functions that do not return a value have the type void.

A function must be defined before it can be called, and function calls cannot be recursive (a function cannot call itself).

The statements in the function body may modify the values of the parameters, but this will not have any effect on the arguments of the function call.

Execution of a function can be terminated by the return statement. Without any return statement the function body is executed until it's closing brace (}).

A call to the exit() function will terminate the entire User Language Program.

The special function main()

If your User Language Program contains a function called main(), that function will be explicitly called as the main function, and it's return value will be the return value of the program.

Command line arguments are available to the program through the global Builtin Variables argc and argv.

Example
int CountDots(string s)
{
  int dots = 0;
  for (int i = 0; s[i]; ++i)
      if (s[i] == '.')
         ++dots;
  return dots;
}
string dotted = "This.has.dots...";
output("test") {
  printf("Number of dots: %d\n",
                 CountDots(dotted));
  }