Concepts
This section describes some
of the internal workings of DataCAD.
Angles
All angles in DCAL (and
therefore internal to DataCAD), are expressed in radians
starting at 0 to the right (east). Angles increase
counterclockwise.
NOTE: The internal
representation has no effect on how DataCAD displays angles
to the user.
Coordinate System
Internally DataCAD stores
all distances and coordinates as 1 unit = 1/32 inch. This is
also true for metric units.
When converting distances
to strings or strings to distances, the current scaling type
(feet-inches-fractions, meters, decimal feet, etc.)
determines the format of distance strings. This does not,
however, affect the way that DataCAD maintains distances
internally.
Entities
Every primitive graphic
shape that DataCAD understands is called an entity.
Currently supported entities include:
- 3D arc
- ellipse
- 3D line
- line
- arc
- point
- associative dimension
- polygon
- bezier
- skew box
- bezier surface
- slab
- bspline
- symbol
- circle
- text string
- cone
- torus
- cylinder
- truncated cone
- dome
Each entity has certain
information associated with it such as which layer it is on,
color, line type, line spacing, line weight, overshoot
factor, and an attribute (integer). Each entity also has an
address associated with it which is a handle to the entity
in the drawing file. The address of an entity does not
change, either during an editing session or between editing
sessions.
Keyboard
A DataCAD macro perceives
the keyboard differently from other programs. To simplify
writing macros, all keys are returned from the keyboard as
integers, not as characters. This allows DataCAD to
represent the entire 256 extended ASCII character set, as
well as any 'special' key. 'Special' keys return escape
codes.
A special key is any key
that has a macro- interpretable function. For instance, the
function keys are special keys, as are the arrow keys, (Ins)
and (Del). Some keys are special keys only some of the time.
For instance, (q) returns an escape code under some
circumstances which causes DataCAD to increment the current
line type, and at other times (while reading a string)
returns a normal key code.
Several of the DCAL
routines return a result that tells you how they were
exited. These result codes are res_normal for a normal
finish and res_escape for an interruption because an escape
code was read. A result of res_escape typically means that
the user pressed a function key while the macro was
requesting some type of input. The escape code that was
pressed returns from these routines as an integer.
Layers
Each entity is on a layer.
Each layer is scanned during any search of DataCAD's
database. When a layer is not searched, every entity on that
layer is ignored. Ignoring certain layers (for instance
layers that are off) or confining a search to a specific
layer or set of layers improves search speed.
Selection Sets
DataCAD supports 16
selection sets. A selection set is a collection of entities.
Every entity can be a member of some, none, or all of the
selection sets. Selection sets are convenient ways of
grouping entities so you can act upon them together.
Selection sets also provide an alternative to using layers
to group entities. The first eight selection sets are
available to you and DCAL, while the other eight are
reserved for DataCAD's internal use.
Selection sets exist across
uses of a drawing file. That is, you can set up and
manipulate a selection set. If the drawing is exited and
then reentered, the selection set still exists. In this
respect, selection sets are similar to layers as a way to
group entities.
Local Variables
Routines can declare local
variables. These variables can only be used inside this
routine or any routine local to it. They are pushed on the
stack and exist only during the lifetime of the routine.
Symbols
A symbol is similar to any
other DataCAD entity. However, a symbol is a reference to a
group of other entities that are drawn where the symbol is
inserted. A symbol, as created at the DataCAD template menu,
is referenced by its file name (including the path). With a
symbol defined by a macro, however, all you need is a unique
symbol name.
Symbols are instanced, that
is, their geometry exists only once in the database. They
can be globally updated, but no longer individually edited.
Basics
DCAL is a block-structured
language similar to Pascal and Modula-2. DCAL supports
recursive procedures and functions, as well as nested
routines, local variables and constants, reference and value
parameters, and conformant arrays.
Case Sensitivity
The functions and
procedures in DCAL can be entered in either upper- or
lower-case characters. DCAL is not case sensitive,
therefore, ABC, abC, and AbC are all the same to DCAL.
Comments
A comment is text that
prints within the code of a macro, but is ignored by the
macro. DCAL allows two different types of comments:
* Comments that start with
a left brace ({) and end with a right brace (}).
* The other type of comment
is the comment until end of line. This starts with an
exclamation mark (!) and continues until the end of the
current line. Comments cannot be nested, and cannot appear
within a string.
Identifiers
DCAL macros are composed of
identifiers, both pre-defined and user-defined. Examples
are: variable names, procedure names, and procedure
parameters.
Valid DCAL identifiers
begin with a letter, and are followed by letters, numbers,
and underscores. Identifiers may be up to 20 characters
long. Identifiers longer than 20 characters result in
compile time errors. Therefore, these are valid identifiers:
test
proc_1
alphabet
These, however, are not
valid identifiers:
123test Starts with a
number.
_hello Starts with an
underscore.
abcdefghijklmnopqrstuvwxyz More than 20 letters.
ab$de $ is an invalid
character.
DCAL identifiers are not
case sensitive, therefore, ABC, abC, and AbC are all the
same identifier to DCAL.
Keywords
A keyword is a word that is
part of the DCAL language. Keywords are reserved and cannot
be used for any other purpose. A complete list of keywords
follows:
- and
- of
- array
- off
- begin
- on
- by
- or
- const
- out
- do
- procedure
- else
- program
- elsif
- public
- end
- record
- external
- repeat
- false
- return
- for
- string
- function
- then
- if
- to
- in
- true
- include
- type
- message
- until
- mod
- var
- module
- while
- not
White Space
White space is ignored by
the compiler. White space consists of spaces, newlines, and
tabs that are not in a string or character literal.
Program Layout
Macro Header
There are two types of
macro headers, depending on whether the .dcs file contains a
program or a module:
Programs
As the sample macro spiral
shows, DCAL program macros begin with the keyword program
followed by the name of the macro, followed by a semicolon.
Modules
DCAL modules begin with the
keyword module, followed by the name of the module, followed
by a semicolon. Modules have no body, and thus no
corresponding begin keyword. However, they do have an end
followed by the module name and a period. The sample module
wrtutl.dcs is an example of a module.
Constant
The Constant section, if
present, starts with the keyword const. Following it are the
constant identifier, an equal sign (=), followed by the
value of the constant. Finally, a semicolon terminates each
constant.
DCAL recognizes two types
of constants, integers, and reals. The following is a valid
constant section:
CONST
delta = 23.43; {real
constant}
max_count = 45;
{integer constant}
Type
The Type section, when
present, comes after the Constant section. It begins with
the keyword type, followed by the type name, followed by the
type definition.
Scalar Types
Scalar types consist of the
DCAL built-in simple types which are described in the "Data
Types" chapter. These simple types are indivisible: a DCAL
macro cannot directly examine these variables to any greater
degree.
Array Types
Array types are used by
DCAL to group data together. To declare an array, use the
keyword array, followed by a left bracket ([), followed by
the lower bound, followed by two periods (..), followed by
the upper bound, followed by a right bracket (]), followed
by the keyword of, followed by the type of the element that
the array is comprised of.
Notice that arrays can be made up of arrays. For instance:
TYPE
x = ARRAY [0..9] OF
ARRAY [3..5] OF integer;
A shorthand notation for
this is:
TYPE
x = ARRAY [0..9, 3..5]
OF integer;
Records
Records are the other way
DCAL groups data together. DCAL records are similar to
Pascal records, including the use of the case variant
record. The only distinctions are that in a DCAL case
variant record, the case selector (tag) must be an integer,
and no explicit tag variable is allowed. For example, the
following are valid record descriptors:
TYPE
rec1 = RECORD
a : integer;
b : real;
END;
rec2 = RECORD
a : integer;
CASE integer OF
0 : (r : real);
1 : (b : boolean);
END;
Variables
Next comes the optional
variables section. It begins with the keyword var, followed
by a list of identifiers, each followed by a colon, then the
type of variable, followed by a semicolon. For example:
VAR
i : integer;
x, y : real;
dis_Array : dis_Type;
{ a user defined type }
Notice that, unlike
constants, more than one variable can be given the same
type, as long as they are separated by commas.
Subprograms
A subprogram, or routine,
is a procedure or function. A function is identical to a
procedure except that it returns a value and can be used in
an expression, if its type is appropriate for the
expression. In this manual, the terms subprogram and routine
mean either procedure or function.
Procedures
Procedures are declared by
the keyword procedure, followed by the procedure name,
followed by an optional parameter list. After that, a
procedure may declare local constants, types, variables, and
other routines. A procedure ends with control falling
through to the final end statement, or by using the return
statement.
Functions
Functions are similar to
procedures, except they return a value of a certain type.
Functions are declared with the keyword function, followed
by the function name, an optional parameter list, a colon,
and the type of variable the function returns. A function
may declare local constants, types, variables, and other
routines. In the body of the function, the return value is
returned in the return statement. The returned value follows
the keyword return. If control falls through to the final
end in a function without encountering a return statement, a
fatal runtime error occurs. Functions may only return scalar
types.
NOTE:
In this manual, the
function or procedure is listed with a description, followed
by the parameters, with descriptions of the parameters
concluding the section.
Passing Parameters
Parameters are passed to
routines in one of three ways: IN mode, OUT mode, and IN OUT
mode. You can specify the usage of the parameter; and the
compiler determines whether to pass the parameter by
reference or value.
Valid routine declarations
with parameters are:
PROCEDURE calc (x, y :
real; x1, y1 : OUT real);
FUNCTION dist (x1, y1,
x2, y2 : real) : real;
PROCEDURE readint (i :
IN OUT integer);
IN Mode
An in mode parameter may be
read from, but not written to. When no mode is assigned to a
parameter, in is the default. You can substitute an
expression for an in parameter; therefore, both (3) and (3 *
i) are valid in parameters.
OUT Mode
An out mode parameter can
be written to, but cannot be read. An example is a procedure
that returns several results in out parameters.
PROCEDURE average (data
: ARRAY OF integer; mean : OUT integer;
sumation : OUT integer;
median : OUT integer);
IN OUT Mode
in out parameters can be
both read from and written to. These parameters typically
have an initial value with a final value returned from the
routine.
Open Array Parameters
DCAL supports open array
parameters to procedures. An open array (also called a
conformant array) is an array that does not have specified
bounds, for example, a procedure that sorts an array of
integers. The procedure can sort an array of any size. The
declaration is:
PROCEDURE sort (i :
ARRAY OF integer);
The functions low and high
(described later) are used by the procedure to determine the
actual bounds of the array parameter.
Expressions and Logical
Operators
This section discusses type
compatibility issues. It also discusses mathematical
operators that are valid in DCAL.
Type Compatibility
DCAL features strong type
checking. Any operation may be performed on a variable as
long as the operation is appropriate to the base type of
that variable. However, variables and expressions must be
the same type to operate or appear together in assignment
statements.
For instance, if you
declare:
TYPE
count = integer;
VAR
a, b, c : count;
x, y, z : integer;
Then you can legally write:
a := b + c;
because a, b, and c are
declared as identical types and the + operator is
appropriate to the base type of count, which is integer.
However, you could not write:
a := b + x;
because b and x are not of
the same type.
You can escape the type
checking through type casting. For example:
a := b + count (x);
Here, the type name is used
to relax the type checking. For this to work, the base type
of x must be the same as the base type of the type count, as
it is in this example (both are integers). You can use type
casting to convert any type to any other type, as long as
they are the same size in computer memory.
Operators
The mathematical operators
*, /, +, and - are used for multiplication, division,
addition, and subtraction, respectively. Use these operators
with both real numbers and integer numbers. Both operands
must be of the same type; with results of the same type.
The routines float, round,
and trunc may be used within an expression in which both
integer and real variables are mixed.
The operator mod is used
only with integer operands and returns the integer remainder
of division of the two numbers or variables.
Here are some
examples of these operators:
VAR
rl1, rl2, : real;
int1, int2, :
integer;
rlResult: real;
intResult :
integer;
BEGIN
rlResult := (rl1 +
rl2) / 2.0;
intResult := (int1
- int2) * 2;
rlResult := float
(int1) * 34.75;
intResult := 7 mod
3; { this gives intResult = 1 }
intResult := 7 /
3; { this gives intResult = 2 }
intResult := round
(rl1) / 4;
intResult := trunc
(rl2) * 6;
END XXX.
Statements
This section describes the
statements that make up DCAL.
Assignment Statement
The assignment statement is
the statement DCAL uses to assign values to variables. Its
use is identical to the Pascal assignment statement:
variable := expression;
The variable gets the value
returned by the expression. The expression must evaluate to
the same type as the variable (integers must be assigned to
integer variables, reals to real variables, etc). The
expression itself may be a variable.
IF Statement
The IF statement is used
for testing Boolean conditions and branching based on the
result. Several valid IF statements are:
IF f AND g THEN
dofirst;
ELSE
dosecond (f);
END;
IF apple + orange <
pineapple THEN
error1;
ELSIF i >= j THEN
deleteFile;
ELSE
formatDisk;
END;
IF today = monday THEN
getOutOfBed (late);
goToWork (late);
END;
Conditional Expressions
Follow the keyword IF with
an expression which returns a Boolean result. When the
result is true, the code following the THEN keyword is
executed. When the result is false, the code following the
ELSE keyword is executed.
THEN Statements
The statements between the
THEN and the following END, ELSE, or ELSIF are executed when
the Boolean expression evaluates to true.
ELSE Statements
The statements between the
ELSE and the corresponding END or ELSIF are executed when
the Boolean test expression evaluates to false. The ELSE
section is optional. When the ELSE section is not present
and the test expression evaluates to false, no action is
taken and control falls through to the next statement
following the corresponding END of the IF statement.
ELSIF
Use the keyword ELSIF to
shorten the number of lines needed for multiple IF
statements. The following code:
IF key = 1 THEN
code_for_1;
ELSE
IF key = 2 THEN
code_for_2;
ELSE
IF key = 3 THEN
code_for_3;
ELSE
other_code;
END;
END;
END;
using ELSIF could be
written as:
IF key = 1 THEN
code_for_1;
ELSIF key = 2 THEN
code_for_2;
ELSIF key = 3 THEN
code_for_3;
ELSE
other_code;
END;
Using ELSIF in this way can
be a substitute for the Pascal CASE statement, which DCAL
lacks.
Procedure Call Statement
With the procedure call
statement you can execute procedures you have written or
procedures that are built into DCAL and DataCAD. To call a
procedure, simply use the procedure's name, followed by its
parameters, if any. Example procedure calls are:
wrterr ('Unable to open
file.');write_prompt; { call proc. w/o parameters }
lblson;
add (x, y);
testit (3 + 4, a);
RETURN Statement
The RETURN statement occurs
in two slightly different forms depending on whether it is
used in a procedure or in a function. Both procedures and
functions may have any number of RETURN statements.
RETURN Used in Procedures
When used in a procedure,
the keyword RETURN appears by itself. It causes the
execution of the procedure to terminate and control to
return to the calling routine. There is an implicit RETURN
statement at the end of every procedure.
RETURN Used in Functions
When used in a function,
the keyword RETURN is followed by the expression that is
returned as the value of the function. If control falls
through to the final END of a function, a run- time error
occurs. The value that follows a RETURN statement is
returned to the calling routine.
WHILE Statement
The WHILE statement
implements a loop. The keyword WHILE is followed by a
Boolean expression, followed by the keyword DO. Following
this are one or more statements, followed by END. The
expression is evaluated at the top of the loop. When the
statement is true, the statements in the loop are executed.
The expression is then re-evaluated and the loop is rerun
until the Boolean expression evaluates to false.
Notice that a loop can be
executed zero times when the expression evaluates to false
the first time it is tested.
A valid WHILE statement is:
i := 1; { initialize
counter }
done := false;
WHILE NOT done DO
IF test (i) THEN;
i := i + 1; {
increment counter }
ELSE
done := true;
END;
END;
REPEAT Statement
The REPEAT statement is
another looping structure in DCAL. Unlike the WHILE loop,
the body of the REPEAT statement is executed at least one
time. The REPEAT loop consists of the keyword REPEAT,
followed by the statements that make up the body of the
loop, followed by the keyword UNTIL, followed by a Boolean
expression. Every time control passes to the UNTIL
statement, the Boolean expression is evaluated. When the
expression evaluates to true, control passes through to the
statement following UNTIL. When the expression is false,
control goes back to the statement following the REPEAT
statement.
A valid REPEAT statement
is:
i := 10;
REPEAT
write_file (i);
i := i - 1;
UNTIL i = 0;
FOR Statement
The FOR statement is used
to loop a specified number of times. The syntax of a FOR
statement is:
FOR <ivar> :=
<startval> TO <endval> | BY <iconst> | DO <stmts> END;
The index variable (<ivar>)
must be an integer variable that can be assigned. The
optional BY is followed by an integer constant. This is the
step size used in the FOR statement which may be positive or
negative. When the BY section is not included, the step size
is one (1). The <stmts> are executed until the value of
<ivar> is greater than <endval>. <endval> is only evaluated
once, when the loop is entered. When <startval> is greater
than <endval> (and the step size is positive), the <stmts>
are never executed. |