This section provides small programming examples in order to introduce the most important elements of the
Bartels User Language. The purpose thereby is to demonstrate - without entering into formal details or describing exceptions - the basic methods of developing
User Language programs.
2.1.1 The first User Language Program
The only way to learn how to use the
User Language is by doing it, i.e., write
User Language programs, and compile and execute them. The first
User Language program to be implemented should print a message, and then wait for an interactive keyboard input to abort the program (this is a frequently required programming feature). As already mentioned in the introduction, an
User Language program must at least contain a
main function. What we need in this
main function are instructions for printing the desired message and for activating the requested user query. Both of these instructions can be realized by calling corresponding
User Language system functions
(printf and
askstr). These system functions are known to the
User Language Compiler, and they are bound to the
Bartels User Language Interpreter. The programmer just has to know, how these functions are to be called, and what they do (this information can be taken from
appendix C of this manual). You should now use your editor for preparing a file named
ulprog.ulc with the following
User Language source code (the
.ulc file name extension is used by the
User Language Compiler for
User Language source code file recognition):
main()
{
printf("User Language Program");
askstr("Press ENTER to continue ",1);
}
The above listed
User Language program does just contain the definition of the function
main . Parentheses are required after the function name. Usually, formal function parameters are listed inside these parentheses. To distinguish function names from variable names, the parentheses are required even if (as in the example above) no function parameter exists at all. Within the braces the function block is defined. The function block is composed of the statements to be executed by the function. Each statement must be delimited by a semicolon
(; ). The first statement of the
main function is the call to the
printf function (to be recognized by the opening parenthesis after the function name). The parameter which is passed to the
printf function is a constant string (enclosed by double quotes). This string is the message, which the program will print to the screen when executed after faultless compilation. The second statement is a call to the function
askstr. This function issues the prompt string, which is specified with the first function parameter, and waits for an interactive string input. The user interaction takes place in the status line of the
Bartels AutoEngineer, and the second
askstr parameter indicates the maximum permissible input string length. The
askstr call is the last statement to be processed by the program, i.e., the program finishes after executing the
askstr call. Once the program source code is edited and stored to
ulprog.ulc , it can be translated with the following
User Language Compiler call:
ulc ulprog
The
User Language Compiler issues the following message, if no compilation error occurred:
==============================
BARTELS USER LANGUAGE COMPILER
==============================
Compiling source code file "ulprog.ulc"...
Program 'ulprog' successfully created.
Source code file "ulprog.ulc" successfully compiled.
No errors, no warnings.
User Language Compilation successfully done.
Once the
User Language Compiler program source code has been translated, and the corresponding machine program named
ulprog has been stored to the
ulcprog.vdb file of the
Bartels AutoEngineer programs directory, the program can be executed by the
Bartels User Language Interpreter. This can be applied e.g., by starting the
Bartels AutoEngineer
Schematic Editor and by activating the
function from the
menu. The program name
(ulprog ) must be specified to the corresponding query:
File | |
Run User Script | |
Program Name ? | ulprog |
After starting the program, the BAE graphic workspace is switched to text output mode, and the
User Language Program message is printed to the screen. Subsequently, the
Press ENTER to continue prompt is displayed in the BAE input window. Return key input terminates the
User Language program and restores the graphic workspace.
2.1.2 Variables, Arithmetic and Functions
The next example illustrates a series of further specific
User Language characteristics. The following
User Language program examines some circles (specified by center point and radius) to check whether they overlap (drill data test?!), and issues corresponding messages:
// Circle Test Program
double tol=0.254*5; // Tolerance
struct pos { // Position descriptor
double x; // X coordinate
double y; // Y coordinate
};
struct circle { // Circle descriptor
double rad; // Circle radius
struct pos c; // Circle position
};
// Main program
main()
{
// Define three circles
struct circle c1 = { 4.5, { 19.4, 28.3} };
struct circle c2 = { 17.0, { 37.6, 9.71} };
struct circle c3 = { 1.5E01, { 25, 0.2e2} };
// Perform circle test
printf("Circle 1 - 2 overlap : %d\n",circletest(c1,c2));
printf("Circle 1 - 3 overlap : %d\n",circletest(c1,c3));
printf("Circle 2 - 3 overlap : %d\n",circletest(c2,c3));
// Prompt for continue
askstr("Press ENTER to continue ",1);
}
int circletest(c1,c2)
// Circle test function
// Returns: nonzero if overlapping or zero else
struct circle c1,c2 /* Test circles 1 and 2 */;
{
double d /* Distance value */;
// Get circle center point distances
d=distance(c1.c,c2.c);
// Error tolerant check distance against radius sum
return(d<=(c1.rad+c2.rad+tol));
}
double distance(p1,p2)
// Get distance between two points
// Returns: distance length value
struct pos p1 /* Point 1 */;
struct pos p2 /* Point 2 */;
{
double xd=p2.x-p1.x /* X distance */;
double yd=p2.y-p1.y /* Y distance */;
// Calculate and return distance
return(sqrt(xd*xd+yd*yd));
}
The above listed program source code contains a series of comments enclosed by
/* and
*/ ; such comments can extend over several lines, but they must not nest. Another type of comment starts with
// and extents to the end of line. Since comments can keep the program source code well understandable, it is recommended to use such inline documentation to simplify
User Language software maintenance.
The program above also contains a series of variable definitions. All variables must be declared before use. A variable declaration determines the name and the data type of the variable.
Bartels User Language distinguishes between global variables, local variables and function parameters. Global variables are valid throughout the entire program text. Local variables are valid in the function where they are defined. Function parameters are used for passing values to functions. In the example above,
tol is the only global variable (with data type
double ). Local variables are, e.g.,
xd and
yd (data type
double ) in the
distance function. Function parameters are, e.g.,
c1 and
c2 in the
circletest function; these two parameters are of the specially defined combined
struct
circle data type. Variable declarations can contain variable value initializations (see the global variable
tol or the local variables
xd and
yd in the
distance function). Combined data type variables can be initialized (see the local
struct variables
c1 ,
c2 and
c3 in the
main function). A list of variable names can be specified at the declaration of variables (see the declaration of the parameters
c1 and
c2 in the
circletest function).
Values are calculated within expressions. The equals sign
(= ) can be used for assigning the resulting expression value to a variable.
A data type must be specified at the definition of functions. In the example above, the
distance function is of type
double , and the
circletest function is of type
int . The function data type is set to
int if the function data type specification is omitted (as with the
main function in the example above). A special function data type is
void . Each function - except for the
void functions - returns a value compatible to the corresponding function data type. The function return value is passed back to the caller of the function with the
return statement, which is coincidentally the last instruction to be executed by the function.
2.1.3 Arrays and Control Structures
The following example shows how to use arrays and control structures. A list of integer values are transformed into strings, and a report of the transformations is printed:
// Integer list
int intary[]={ 0,17,-12013,629,0770,0xFF,-16*4+12 };
// Main program
main()
{
int i /* Loop control variable */;
// Set last integer value
intary[10]=(-1);
// Loop through integer list
for (i=0;i<=10;i++)
// Print integer and integer string
printf("%8d : \"%s\"\n",intary[i],inttostr(intary[i]));
// Prompt for continue
askstr("Press ENTER to continue ",1);
}
string inttostr(int intval)
// Convert integer value to a string
// Returns: resulting string
{
string resstr="" /* Result string */;
int n=intval,i=0 /* Integer value, loop counter */;
char sign /* Sign character */;
// Test for negative integer value
if (n==0)
// Return zero integer string
return("0");
else if (n>0)
// Set sign to plus character
sign='+';
else {
// Make integer value positive
n=-n;
// Set sign to minus character
sign='-';
}
// Build result string
do { // Get and append next character
resstr[i++]=n%10+'0';
} while ((n/=10)!=0);
// Append zeros
while (i++<15)
resstr+='0';
// Append sign character
resstr+=sign;
// Reverse string
strreverse(resstr);
// Return string result
return(resstr);
}
In the example above, an integer array (global
int variable
intary ) is declared and (partially) initialized. The bracket pair after the variable name
intary defines an one-dimensional
int vector. Multiple vector dimensions can be specified by appending further bracket pairs to the declaration
(intary[][]...[] ). Since the
User Language provides powerful in-build features for dynamically managing arrays, it is not necessary, to define array length limits; i.e., both the
User Language Compiler and the
Bartels User Language Interpreter require just the information about the dimension of an array and/or vector. Nevertheless some checks are applied in order to prevent from accessing non-existent array elements (which would cause memory protection faults); the Compiler is able to check for constant negative (i.e., invalid) array indices, and the Interpreter is able to check whether an array index refers to an array element outside the currently engaged array field range. The array index value 0 always refers to the first array element.
The
string data type corresponds to an one-dimensional array of type
char .
User Language provides in-build features for the direct assignment of arrays and/or vectors with corresponding data type and equal dimension. These features have been utilized at the initialization of
resstr (local
string variable of the
inttostr function) as well as with the assignment of the
return value of the
inttostr function. The add operator can also be applied to
string values, with the result of the add operation corresponding to a string catenation.
The example above contains some control structures. A
for loop for processing the elements of the
intary array variable is applied in the
main function. The
inttostr function uses a
while loop and a
do-while loop for manipulating the
resstr
string variable. The
inttostr function utilizes an
if control structure to process dependent program blocks according to the current value of local variable
n .
Introducing User Language Programming © 1985-2024 Oliver Bartels F+E • Updated: 26 January 2007, 17:23 [UTC]
|