Skip to content

Commit

Permalink
Update code style document
Browse files Browse the repository at this point in the history
  • Loading branch information
ErykMroczek committed Feb 18, 2024
1 parent 0ed91f8 commit eb0d4fa
Showing 1 changed file with 158 additions and 104 deletions.
262 changes: 158 additions & 104 deletions code-style.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,61 @@ There is no line length limit. There are plenty of limits already.

## Horizontal spacing

Single space is used as a horizontal separator.
### Spaces

**mofmt** uses a single space as a horizontal separator between tokens.

Spaces are not inserted before:

- semicolons (`;`), except when preceded by `within`
- commas (`,`)
- parentheses and brackets (`()[]{}`)
- dots (`.`) in type specifiers and names

Spaces are not inserted after:

- dots (`.`) in type specifiers and names
- opening brackets (`([{`)

##### Example

```modelica
parameter Real Foo(start = 0); // Comment
parameter .Foo.Bar[10] Baz(start = 0, max = 100);
```
### Operators

### Binary operators
#### Unary

All binary operators are surrounded with spaces.
Two kinds of Modelica unary operators are treated differently:

- `not` operator is always followed by a space
- `+`, `-`, `.+`, `.-` are not followed by a space

##### Example

```modelica
2 * (3 - 1.76)
a <= b or x
1 : 10
-4
.-A
not is_off
```

### Unary operators
#### Binary

`not` operator is followed by a space. Unary addition or subtraction,
including element-wise, are not.
All binary operators are surrounded with spaces.

##### Example

```modelica
-4
.-(A .+ B)
not isOff
(-2) * (3 - 1.76)
a <= b or x
1 : 10
```

### Assignments and equalities

`:=` and `=` tokens are surrounded with spaces.
Exception occurs when equality or assignment is
followed by a multiline if-expression. In such case the symbol is only
preceeded with a space.

##### Example

```modelica
foo = bar * 2
Expand All @@ -49,80 +71,119 @@ foo := bar(x)
foo := if x < 2 then bar else baz
```

But:
### Arrays, modifications, function calls, expression lists

Every comma (`,`) and semicolon (`;`) is followed by a space. This includes
discarded slots in *output-expression-list*.

##### Example

```modelica
foo :=
if x < 2 then
bar
else
baz
{1.0, 2.0, 3.0}
(foo, , bar) := baz(x, y)
[x, y; a, b]
```

### Arrays, modifications, function calls, expression lists
## Vertical spacing

If there is no line wrap every comma and semicolon is followed by a
space. This includes discarded slots in *output-expression-list*.
### Indentation

```modelica
{1.0, 2.0, 3.0} // Array
enthalpy_pT(p, T) // Function call
(foo, , bar, baz) // Output expression list with a discared second element
[x, y; a, b] // Matrix
```
Indentation is two spaces per level.

## Indentation
### Automatic wrapping

Indentation is 2 spaces per level.
Line is automatically wrapped before every:

Modelica doesn't use indentation to define the scope, but it is
nonetheless useful to use it to enhance readability. Descriptions and
annotations are good examples. Overall, indentation is increased at:
- class definition
- element
- equation
- statement
- description string
- annotation
- constraining clause
- enumeration item

* descriptions and annotations
* constraining clauses
* elements, equations, statements and external function calls
* enumeration items
* inside loops and if blocks
In case of:

### Descriptions, annotations and constraining clauses
- class definition
- element
- equation
- statement

Indentation is increased only one time per element.
wrap can be doubled so there is a single blank line instead.

```modelica
replaceable package Medium = Modelica.Media.R134a.R134a_ph
constrainedby Modelica.Media.Interfaces.PartialMedium
"Fluid medium"
annotation(Dialog(tab = "General", group = "Medium"));
```
#### Automatic blank lines

### Element, statement and equation lists
Section keywords:

Indentation is increased once per section.
- `public`
- `protected`
- `equation`
- `algorithm`
- `external`

```modelica
model Model
"Some model"
are always preceded and followed by a blank line. Those keywords are placed
without indentation.

Blank lines are also inserted:

import FooPackage;
import Modelica.Constants.inf;
- at the beginning and end of the *composition* rule
- before the "lass-wide annotation in the *composition* rule

// SNAP
##### Example

```modelica
within SomePackage;
final model Foo
// AUTO BLANK
Real x;
Real y;
// AUTO BLANK
protected
// AUTO BLANK
Real z;
// AUTO BLANK
equation
// AUTO BLANK
x + y = z;
x * 2 = y;
// OPTIONAL BLANK
z = 3 ^ 2;
// AUTO BLANK
annotation ();
// AUTO BLANK
end foo;
// OPTIONAL BLANK
partial record Bar
// AUTO BLANK
parameter Boolean is_off = false;
// AUTO BLANK
end Bar;
```

parameter FooPackage foo
"foo parameter";
#### Descriptions, annotations and constraining clauses

equation
Indentation is increased only one per element.

// SNAP
foo = bar;
##### Example

end Model;
```modelica
replaceable package Medium = Modelica.Media.R134a.R134a_ph
constrainedby Modelica.Media.Interfaces.PartialMedium
"Fluid medium"
annotation(Dialog(tab = "General", group = "Medium"));
```

### Enumeration items
But not:

```modelica
replaceable package Medium = Modelica.Media.R134a.R134a_ph
constrainedby Modelica.Media.Interfaces.PartialMedium
"Fluid medium"
annotation(Dialog(tab = "General", group = "Medium"));
```

#### Enumeration items

Indentation is increased inside `enumeration()` and at every
description.
Expand All @@ -136,44 +197,42 @@ type BoundaryType = enumeration(
"Enumeration of possible boundary types";
```

### Loops and ifs
#### Loops and ifs

Indentation is increased once per block.

##### Example

```modelica
if foo == bar then
baz := bark;
bam := bem;
else
baz := 0;
bam := 1;
if some_condition then
baz := 0;
bam := 1;
else
baz := bam;
end if;
end if;
```

## Vertical spacing

Beside indented elements described in the previous section, a newline or
two are inserted after every element, statement or equation.

Additionally, a single blank is inserted:

* before and after section keywords like `equation` or `protected`
* before and after the *composition* production
* before class-wide annotation in the *long-class-specifier*

## Line wrapping
### Manual wrapping

### Function calls, arrays, matrices, modifications, lists
#### Function calls, arrays, matrices, modifications, lists

The main rule here is: be consistent. The following approach is applied:

1. If line is wrapped at any argument, then wrap at every argument.
2. If line is wrapped inside a nested construct, then wrap at every
argument in every outer construct.
1. If a line was originally wrapped at any argument in the specific construct,
then wrap at every argument in this construct.
2. If a line was originally wrapped inside a nested construct, then wrap at
every argument in every outer construct.

Indentation is increased accordingly to help visually identify the
scope.

##### Example

```Modelica
// No wrap is fine
h = enthalpy_pT(p, T)
Expand Down Expand Up @@ -201,39 +260,34 @@ cp_b = specificHeat_pT(
a[i] * b[i]
for i in 1 : n}
// Output expression lists
(
foo,
bar) := baz(x, y)
// Import lists
import Modelica.Constants.{
pi,
inf};
```

### Expressions
#### Expressions

Expressions like arithmetic, logical etc. are handled in a different way,
because **mofmt** doesn't apply autowrapping when it detects a wrap in the
original file. Original wraps are preserved, and indentation is adjusted.
Indentation is increased only once per expression.

Other difference is that instead of commas line may be wrapped before binary
operators.

Expressions (arithmetic, logical etc.) are handled in a very same way as
function calls and arrays. The difference is that instead of commas line
is wrapped before binary operators. Wrapping is applied to all operators
of the same precedence (as defined by the grammar). If wrap occured
inside higher precedence (inner) part, lower precedence (outer) parts
are wrapped as well.
##### Example

```Modelica
// No wrap
foo = bar + baz
foo := 2 * (bar - baz) / 5
// Outer rule wrapped
// Single wrap
foo := 2
* (bar - baz) / 5
// Two wraps
foo := 2
* (bar - baz)
/ 5
// Some inner rule wrapped
foo := -2
+ bam
/ baz ^ 2
* bark
- 33
```

0 comments on commit eb0d4fa

Please sign in to comment.