Basic Library Version: 11

GDL Style Guide 1.0


  1. Introduction
  2. Naming conventions
    1. Variable names
    2. Capitalization
  3. Expressions
  4. Control flow statements
    1. if - else - endif
    2. for - next, do - while
  5. Subroutines
  6. Writing comments
  7. Script structure

1. Introduction

This document contains the GDL coding standard of Graphisoft, which mainly sets the formal requirements for writing source code. It also describes a few rules and recommendations for the content. You have to obey these rules; by default every declarative or imperative sentence is a rule, except where 'recommendation' (or avoidable, optional, etc.) is explicitly stated.

This document was created to establish a common format of GDL scripting. Since the GDL language is insensitive of the character case and much of the word and line spacing, lots of coding practices and standards exist. This gets intolerable, when such practices meet in the same project or organization. The following sections describe the Graphisoft company-standard, which remains purely a recommendation for non-Graphisoft related developers. The supposed format will not be included in the GDL language's constraints ever.

2. Naming conventions

2.1. Variable names

Variable and parameter names should be related with the function of the parameter.

Starts with a lowercase letter; every new word should also start with an uppercase letter. E.g.: size, bRotAngle180, upperLeftCorner

Don't use one or two letter variable names, no one will know what you meant.

You should use a prefix in generally used variable names to denote general categories. This can spare time when someone needs to find out the type of a variable or parameter. Don't forget to replace the prefix if you change the meaning of a variable.

Variable name prefixes
Prefix Meaning Example
i general integer value / integer index iRiser
n integer value - amount of something nRiser
b Boolean value bHandrail
x X coordinate of a point xRailPos
y Y coordinate of a point yRailPos
pen Pen color penContour
lt Linetype ltContour
fill Fill type fillMainBody
mat Material type matCover

Using underscores (_) is not forbidden, but please avoid it if possible. It cannot be used as the first or last character of a name.

2.2. Capitalization

3. Expressions

4. Control flow statements

4.1. if - else - endif

Avoid using the one line form of conditional expressions.

For tabulation of code blocks use the following examples as suggestion:

if condition1 then statement1 ... statementn else statementn+1 ... statementn+m endif if condition2 then if condition3 then ... else ... endif if condition4 then ... endif else ... endif

4.2. for - next, do - while, while - endwhile, repeat - until

For tabulation of code blocks use the following examples as suggestion:

for i = initialValue to endValue statement1 ... statementn next i do ... for i = initialValue to endValue statement1 ... statementn next i ... bCondition = ... ... while bCondition

5. Subroutines

Style (italic texts should be replaced implicitly):

! ==============================================================================! ========================================================================= ! Short description of the functionality ! ------------------------------------------------------------------------------! ------------------------------------------------------------------------- ! Input Parameters: ! par1: short description (type) ! par2: short description (type) ! ... ! Output: ! par1: short description ! ... ! Remark: ! Remarks for the caller ! Description of key points of the implementation ! ==============================================================================! ========================================================================= subrutine_title: ! body return

You should write the body of the subroutine indented by one tabulator field to the right.

You should leave two empty lines behind the closing 'return' of the subroutine.

You should write one statement per line.

Subroutines shouldn't be longer than 1-2 screens (about 80 lines) if possible.

Check all incoming parameters for validity and/or declare the restriction in comment

The call and parameters keywords are lowercase.

From ArchiCAD 10 you should use text labels to increase transparency in coding.

6. Writing comments

The language of the comments should be English; avoid bad words.

The initials of developers are registered and can be found in a separate file (not included here). You can freely choose yours when you register, but after that you should always write it the same way. The length of the initial should be minimum 2, maximum 6 characters (letter, space, dot or underscore).

You should use the following style for comments:

Script header

!<contact person initials> ! ==============================================================================! ========================================================================= ! One sentence description of the purpose of the script ! ------------------------------------------------------------------------------! ------------------------------------------------------------------------- ! Input Parameters: ! par1: description of the parameter (integer) ! par2: description of the parameter (1 / -1) ! par3: description of the parameter (0 / 1) ! ... ! Output: [if a macro returns values] ! [1]: description of the value (type) ! [2]: description of the value (type) ! [ ... NSP]: original stack elements ! Remark: ! Longer description. ! Note for the caller ! ==============================================================================! =========================================================================

Any code can come only after this.

Section divide

! ==============================================================================! ========================================================================= ! Section name ! ==============================================================================! =========================================================================

The length of the full comment line is 80 characters.

For the subroutines you should always explain the meaning of non-trivial parameters and the return value. E.g. for indices always indicate the range (starts from 0 or 1, any special values, etc.). Example:

! ==============================================================================! ========================================================================= ! Short description of the functionality ! ------------------------------------------------------------------------------! ------------------------------------------------------------------------- ! Input Parameters: ! par1: short description (type) ! par2: short description (type) ! ... ! Output: ! par1: short description ! ... ! Remark: ! Remarks for the caller ! Description of key points of the implementation ! ==============================================================================! ========================================================================= 100: ! body return

You should always indicate with three exclamation marks if you leave something unfinished:
n = 5 !!! initials; it will be computed from the length

You can also put optional section descriptions in between the lines of the source code, beginning at the current tab depth. You can also add short explanations to the end of the source line by adding a tab at the end; or, if there are more of those, you can align them with tabs.

You should always add comments:

Optional (others will be thankful) if it helps in any way.
Do not let the comments break the rhythm of the code, or the merits of the code.

Then commenting a coherent code block, you may use the following format:

! == code block name ===[ statement1 ... statementn ! ]=== code block name ===

This faciliates the isolation of the block by the look plus some editors support the search for the matching bracket by a shortcut (f.ex.: ctrl + ] in Microsoft Visual Studio)

Comment the end of 'if' statements if there are many code lines between if and endif as follows:

if condition1 then ... if condition2 then ... ! many statements ... endif ! if condition2 endif ! if condition1

7. Script structure

Set your editor to use 4 character wide tabs. Don't replace them with spaces at the start of the lines. In contrast, use spaces instead of tabs to adjust expressions to each other inside the lines.

The maximum length of the lines is 120 characters. Statements shouldn't even get close to this number.

File names are case sensitive, and use the extensions .xml and .gsm accordingly. The file names should be given case sensitive in all references (call).

Use end at the end of each script.

Values - which are used many times - are calculated directly before the block of use if the usage can be well localized or at the beginning of the script otherwise. There is no compromise. Calculate complex values only once to spare calculation time and store them in variables (but do not waste variables unnecessary) or in the transformation stack (add, rot, etc.).

The scripts of the object are of linear structure which makes them clearer. Subroutines are only used when a calculation or model generation segment is needed more than one time. For only one call no subroutine is needed, use comments for clarity. It is an important principle to avoid coding the same thing twice. Redundancy will make the later changes much more difficult. If you make big choice branches, you can't avoid this situation. Try to prepare the data for a calculation or generation command in smaller choices, where you can avoid redundancy easier.

Bad Solution

if onHomeStorey then line_type ltContour fill gs_fill_type poly2_b 5, 3, gs_fill_pen, gs_back_pen, left, 0, 1, left, -depth, 1, right, -depth, 1, right, 0, 0, left, 0, -1 endif if (onUpperStorey or onAboveUpper) and bDrawContBB then line_type ltBelow fill fillTypeBelow poly2_b 5, 3, fillPenBelow, fillBackBelow, left, 0, 1, left, -depth, 1, right, -depth, 1, right, 0, 0, left, 0, -1 endif

The definition of geometry is duplicated! It could be even worse if the distance between the identical commands were bigger.

Good Solution

if onHomeStorey then bPolygon = 1 line_type ltContour fill gs_fill_type fillPen = gs_fill_pen fillBGPen = gs_back_pen endif if (onUpperStorey or onAboveUpper) and bDrawContBB then bPolygon = 1 line_type ltBelow fill fillTypeBelow fillPen = fillPenBelow fillBGPen = fillBackBelow endif if bPolygon then poly2_b 5, 3, fillPen, fillBGPen, left, 0, 1, left, -depth, 1, right, -depth, 1, right, 0, 0, left, 0, -1 endif

Prepare your scripts for localization.
Use "asdf" for non-localized strings (f.ex. macro calls) and `adsf` for localized strings (f.ex. string constants, parameter values).