Skip to content

Code style

Florine W. Dekker edited this page Oct 15, 2024 · 13 revisions

The scripts used to generate the dumps are written in a special form of Object Pascal, and a Python wrapper manages the post-processing. This article details the style guide used for these scripts.

Python

See PEP 8 and the Black Code Style.

To correctly format Python code, use Black. To install Black, activate your venv (see Generating dumps), and run pip install .[contribute]. After Black has been installed, run black . to fix formatting in all Python files.

Pascal

Line length

  • Lines must be at most 120 columns long.
  • Files must end with a trailing newline.

Capitalisation

  • Units and types must be written in Pascal case (e.g. PascalCase).
    • This includes Integer, String, and Boolean.
  • Functions/procedures must be written in dromedary case (e.g. dromedaryCase).
  • Variables and parameters must be written in dromedary case (e.g. dromedaryCase).
  • Keywords (e.g. result, break, and, true, false) must be written in lowercase.
    • Exception: NULL must be written in uppercase.

Documentation and comments

  • Documentation blocks ((** ... *))

    • must be placed above each function/procedure.
    • must start with a one-sentence description of the function/procedure.
    • may contain more detailed prose after the first sentence.
    • may describe parameters in more detail with @param tags.
    • must align parameter descriptions horizontally.
    • must separate parameter name from parameter description by at least two spaces.
    • may describe the output in more detail with a @return tag.
    • must use a line containing only an indented * to separate (1) first line, (2) prose, and (3) tags.
    • must not separate tags with any lines.
    Examples
    • Bad: (starts with (*, is broken by empty line, does not align parameter descriptions)
      (*
       * Returns the sum of [number] and [anotherNumber].
      
       * @param number the number to sum
       * @param anotherNumber the other number to sum
       * @return the sum of [number] and [anotherNumber]
       *)
      function sum(number: Integer; anotherNumber: Integer): Integer;
    • Bad: (does not separate first line from prose, and adds line between tags)
      (**
       * Returns the sum of [number] and [anotherNumber].
       * The inputs are integers, and so is the output.
       *
       * @param number         the number to sum
       * @param anotherNumber  the other number to sum
       *
       * @return the sum of [number] and [anotherNumber]
       *)
      function sum(number: Integer; anotherNumber: Integer): Integer;
    • Good: (though excessively verbose)
      (**
       * Returns the sum of [number] and [anotherNumber].
       *
       * @param number         the number to sum
       * @param anotherNumber  the other number to sum
       * @return the sum of [number] and [anotherNumber]
       *)
      function sum(number: Integer; anotherNumber: Integer): Integer;
  • Comments

    • Super-block comments ((*** ... **)) may be used to separate large groups of functions/procedures.
    • Block comments ((* ... *)) should be avoided, except to document function/procedure signatures.
    • Inline comments must be preceded by exactly two spaces.
    • Inline comments must not be terminated by a period.
      • Exception: Inline comments spanning multiple lines may be terminated by a period if it contains multiple proper sentences.

Indentation

  • Lines must be indented in increments of 4 spaces.

  • Lines must use a continuation indent of 4 spaces, except when no ambiguity exists.

    Examples
    • Bad:
      foo(
      bar
      );
    • Bad:
      foo(
          bar,
          baz +
          qux
      );
    • Good:
      foo(
          bar
      );
    • Good:
      foo(
          bar,
          baz +
              qux
      );
    • Good: (no ambiguity)
      foo(
          baz +
          qux
      );
  • When a statement is split at an operator, the operator must be placed at the end of the first line.

    Examples
    • Bad:
      result :=
         foo()
         + bar();
    • Good:
      result :=
         foo() +
         bar();

Spacing

  • Operators must be surrounded by whitespace on both ends.
  • Symbols : and , must not be preceded by whitespace.
  • Symbols : and , must be followed by whitespace.

Statements

  • Lines must not contain multiple statements.
  • The first variable of a function/procedure must be placed on the same line as the var keyword.
  • Conditions must not be surrounded by unnecessary parentheses.
    • Bad: if (foo = 'bar') then begin baz(); end
    • Good: if foo = 'bar' then begin baz(); end
  • if, for, while, repeats, case, and try must always use compound blocks (begin ... end).
    • Bad: if condition then foo();
    • Good: if condition then begin foo(); end;
  • The last statement in a compound statement must be followed by a semicolon.
  • The begin keyword must be placed on the same line as the condition.
  • The begin keyword must not be followed directly by a semicolon.
  • The else keyword must be placed on the same line as the preceding if's end.
  • An if-then-else chain must be terminated by a semicolon.
  • if blocks may be written as a one-liner when its contents are short and simple and there is no else block. A one-line if block must still use a compound block.

Parentheses

Procedure definitions and invocations must use parentheses, even if there are no arguments.

Global variables

  • Global variables should be avoided whenever possible.
  • Global variables must be prefixed with the originating unit's name and an underscore.