Main Page | Modules | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

CDL Syntax and Semantics

The delimiters of the CDL are based upon C, so the language will look familiar upon first sight. However, these characters often have much different meanings within the CDL, and there are additional delimiters used within the CDL.

As the syntax of a language is often one of the most complicated parts, this document has been split up into the following sections:

Operations, Arguments, and Parameters

The most basic entity is an operation. The following are all operations.
FreeBody;         /* operation without arguments */
Block(1,1,1);     /* operations with arguments */
block(1,1,1);
Block(1,1,1) : (color="red");  // operations with parameters
Block(1,1,1) : (mass=1.0, surface="sticky");

The first line is an operation without any arguments. Most operations will require some arguments (just like function calls in C), but some do not require them. In this case, you do not need to add parentheses after the operation's name.

The second line is a plain operation, including arguments. The arguments tell the block it's size. The CDL is case-insensitive, so the example given on the third line is semantically identical to the example on the second line.

While arguments hold the required, nameless values passed to an operation, a different construct, that of parameters, is used to pass additional values. On the fourth line, delimited by a colon and surrounded by parentheses, is passed a single parameter, telling the block what color it should be. Note that unlike arguments, parameters must be named. The last line shows a similar operation, but with multiple parameters.

As seen in the example, comments can be added in either C or C++ notation.

Braces to Change Reference

Block(1,1,1) {
  Translation(0,0,5) {
    Block(2,2,2);
  }
}
Unlike in C, where braces serve as grouping operators, for instance to form functions (which are currently non-existent in the CDL as of this writing), braces in the CDL change the frame of reference for future operations.

In this example, the translation operation is performed within the reference of the first block operation. The second block is performed within the reference of the translation. You can read these operations linearly, so you apply the first block, then you apply the translation, and finally, you apply the last block.

The world always starts at (0,0,0). Subsequent operations can add objects to the world, apply rotations and translations, or define interconnections between objects. In the example above, the first block is placed at (0,0,0), while the second block is placed at (0,0,5), after the translation has moved the reference frame.

Commas as Alternative Notation

The following is semantically identical to the above code:
Block(1,1,1), Translation(0,0,5), Block(2,2,2);

This comma notation grew out of the need for a shorthand version to write many operations called linearly. Quite often when defining geometries, objects are organized as chains of operations, meaning that you would have a host of braces to close once you got to the end of your list of operations. After the semicolon at the end of the line, you are returned to the original reference frame, before the first block.

Mixing Braces with Commas

It is possible to mix notations, but you must always be careful as to what reference frame you are at. As seen in the previous section, a semicolon at the end of a comma-separated list returns you to the reference frame at the beginning of the list. How about with braces? The specialty of braces is that they allow you to place multiple operations at the same frame of reference. As long as you are within a set of braces, you will always be at that frame of reference, at least. Consider the following example (using fictitious operations for clarity).

A {
 B {
  C,D,E;
  F;
 }
 G,H;
}

A starts us out at the original reference frame. B is then performed within A's reference frame, and we are pushed to its reference frame. C, D, and E are then all performed linearly, starting from B's reference frame. The semicolon then pops us back to B's reference frame, where F is performed. You can think of F and C as being performed in parallel, from the same reference frame.

The first brace closes, popping us back to A's reference frame, in which G and H are applied, in linear order. Finally, we are popped back to the original reference frame when the last brace closes.

I say push and pop because that is exactly what the language is doing. It is constantly modifying a stack of reference frames. The push/pop paradigm is a common one in computer graphics, and is used in systems such as OpenGL and Postscript.


SimLib Reference Documentation