Bartels :: Bartels AutoEngineer :: BAE Documentation :: User Language Programmer's Guide :: Language Description :: Introducing User Language Programming |
Bartels User Language - Programmer's Guide2.1 Introducing User Language Programming |
![]() |
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.
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 and restores the graphic workspace.
message is printed to the screen. Subsequently, the prompt is displayed in the BAE input window. Return key input terminates theThe 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.
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
.
Bartels :: Bartels AutoEngineer :: BAE Documentation :: User Language Programmer's Guide :: Language Description :: Introducing User Language Programming |
Introducing User Language Programming
© 1985-2025 Oliver Bartels F+E