Difference between revisions of "Operator"

From Lazarus wiki
Jump to navigationJump to search
(Wash and clean and clarify)
m (→‎see also: update links)
 
(5 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
It can be invoked by placing keywords adjacent to suitable operands.
 
It can be invoked by placing keywords adjacent to suitable operands.
  
The word ''operator'' colloquially refers to the symbol or keyword identifying the function that implements the actual operation.
+
The word ''operator'' colloquially refers to the symbol or [[Keyword|keyword]] identifying the function that implements the actual operation.
 
<syntaxhighlight lang="pascal" inline>operator</syntaxhighlight> is also a [[Reserved word|reserved word]] that appears in the course of [[Operator overloading|operator overloading]].
 
<syntaxhighlight lang="pascal" inline>operator</syntaxhighlight> is also a [[Reserved word|reserved word]] that appears in the course of [[Operator overloading|operator overloading]].
  
Line 11: Line 11:
 
<syntaxhighlight lang="pascal">x + 5</syntaxhighlight>
 
<syntaxhighlight lang="pascal">x + 5</syntaxhighlight>
 
The plus character identifies the addition operation (Standard Pascal).
 
The plus character identifies the addition operation (Standard Pascal).
{{HL|x}} and {{HL|5}} are its operands.
+
<syntaxhighlight lang="pascal" inline>x</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>5</syntaxhighlight> are its operands.
 
This style is called infix notation.
 
This style is called infix notation.
  
Unary operators&nbsp;– those which require only one operand&nbsp;– appear in front of their operands (prefix notation), with the exception of {{HL|^}}, the de-referencing operator, which appears after its operand (postfix notation).
+
Unary operators&nbsp;– those which require only one operand&nbsp;– appear in front of their operands (prefix notation), with the exception of <syntaxhighlight lang="pascal" inline>^</syntaxhighlight>, the de-referencing operator, which appears after its operand (postfix notation).
 
Example:
 
Example:
 
<syntaxhighlight lang="pascal">-x</syntaxhighlight>
 
<syntaxhighlight lang="pascal">-x</syntaxhighlight>
 
Here, the minus character identifies the sign inversion operation (Standard Pascal).
 
Here, the minus character identifies the sign inversion operation (Standard Pascal).
Blanks between operator and operand are optional (and if used are ignored) read the section below regarding [[#operator precedence|precedence]].
+
Blanks between operator and operand do not harm, confer the following section regarding [[#operator precedence|precedence]].
However, it is common practice to place unary operator symbols immediately next to their operands.
+
However, it is common practice to place unary operator symbols back to back with their operands.
  
 
Operator symbols always appear explicitly, except the implicit typecast and enumerator operator.
 
Operator symbols always appear explicitly, except the implicit typecast and enumerator operator.
Line 32: Line 32:
 
Operands and operators are the building blocks of [[expression]]s.
 
Operands and operators are the building blocks of [[expression]]s.
 
The use of operators is a powerful notational tool, since [[LOC]]s do not get cluttered by function calls consisting of function identifiers and parentheses, but instead the operands and (ideally) a short symbol achieve the same.
 
The use of operators is a powerful notational tool, since [[LOC]]s do not get cluttered by function calls consisting of function identifiers and parentheses, but instead the operands and (ideally) a short symbol achieve the same.
Instead of, for example, {{HL|sum(x, -8)}} the expression {{HL|x - 8}} evaluates to the same value, while writing five less characters.
+
Instead of, for example, <syntaxhighlight lang="pascal" inline style="white-space: nowrap;">sum(x, -8)</syntaxhighlight> the expression <syntaxhighlight lang="pascal" inline style="white-space: nowrap;">x - 8</syntaxhighlight> evaluates to the same value, while writing five less characters.
  
 
In order to increase conciseness subexpressions of expressions propagate their intermediate result in a predefined hierarchy.
 
In order to increase conciseness subexpressions of expressions propagate their intermediate result in a predefined hierarchy.
This hierarchy can be superseded by placing parentheses {{HL|( )}} around subexpressions that are treated as ''one'' expression, so the regular precedence rules apply in the enclosed part remaining uninfluenced from the expression's rest.
+
This hierarchy can be superseded by placing parentheses <syntaxhighlight lang="pascal" inline style="white-space: nowrap;">( )</syntaxhighlight> around subexpressions that shall be treated as ''one'' expression, so the regular precedence rules apply in the enclosed part remaining uninfluenced from the expression’s rest.
 
Operators that have have higher precedence, bind to operands stronger.
 
Operators that have have higher precedence, bind to operands stronger.
  
Line 43: Line 43:
 
|-
 
|-
 
| highest<br/>(first) ||
 
| highest<br/>(first) ||
* [[Not|{{HL|not<}}]] (both, logical and bitwise variant)
+
* [[Not|<syntaxhighlight lang="pascal" inline>not</syntaxhighlight>]] (both, logical and bitwise variant)
* unary [[Plus|{{HL|+}}]] (sign identity, “positive sign”)
+
* unary [[Plus|<syntaxhighlight lang="pascal" inline>+</syntaxhighlight>]] (sign identity, “positive sign”)
* unary [[Minus|{{HL|-}}]] (sign inversion, “negative sign”)
+
* unary [[Minus|<syntaxhighlight lang="pascal" inline>-</syntaxhighlight>]] (sign inversion, “negative sign”)
* {{HLD|*}}
+
* <syntaxhighlight lang="delphi" inline>**</syntaxhighlight>
* {{HLD|pow}}
+
* <syntaxhighlight lang="delphi" inline>pow</syntaxhighlight>
* [[@|{{HL|@}}]]<sup>†</sup>
+
* [[@|<syntaxhighlight lang="pascal" inline>@</syntaxhighlight>]]<sup>†</sup>
* [[^|{{HL|^}}]]<sup>†</sup> (de-referencing operator)
+
* [[^|<syntaxhighlight lang="pascal" inline>^</syntaxhighlight>]]<sup>†</sup> (de-referencing operator)
* {{HLD|explicit}} typecasts
+
* <syntaxhighlight lang="delphi" inline>explicit</syntaxhighlight> typecasts
 
|
 
|
 
* unary operators (except<br/>destination-dependent operators)
 
* unary operators (except<br/>destination-dependent operators)
Line 56: Line 56:
 
|-
 
|-
 
| second ||
 
| second ||
* [[*|{{HL|*}}]]
+
* [[*|<syntaxhighlight lang="pascal" inline>*</syntaxhighlight>]]
* [[And|{{HL|and}}]] (both, logical and bitwise variant)
+
* [[And|<syntaxhighlight lang="pascal" inline>and</syntaxhighlight>]] (both, logical and bitwise variant)
* {{HL|and_then}}
+
* <syntaxhighlight lang="pascal" inline>and_then</syntaxhighlight>
* [[Slash|{{HL|/}}]]
+
* [[Slash|<syntaxhighlight lang="pascal" inline>/</syntaxhighlight>]]
* [[Div|{{HL|div{{HL|]]
+
* [[Div|<syntaxhighlight lang="pascal" inline>div</syntaxhighlight>]]
* [[Mod|{{HL|mod}}]]
+
* [[Mod|<syntaxhighlight lang="pascal" inline>mod</syntaxhighlight>]]
* [[shl|{{HLD|shl}}]] ({{HLD|<<}})
+
* [[shl|<syntaxhighlight lang="delphi" inline>shl</syntaxhighlight>]] (<syntaxhighlight lang="delphi" inline><<</syntaxhighlight>)
* {{HLD|shr}} ({{HLD|>>}})
+
* <syntaxhighlight lang="delphi" inline>shr</syntaxhighlight> (<syntaxhighlight lang="delphi" inline>>></syntaxhighlight>)
* {{HLD|as}}
+
* <syntaxhighlight lang="delphi" inline>as</syntaxhighlight>
 +
* <strike><syntaxhighlight lang="pascal" inline>is</syntaxhighlight> (until FPC 3.3.1, trunk revision 44266)</strike>
 
|
 
|
 
* multiplication operators
 
* multiplication operators
Line 70: Line 71:
 
|-
 
|-
 
| third ||
 
| third ||
* [[Plus|{{HL|+}}]]
+
* [[Plus|<syntaxhighlight lang="pascal" inline>+</syntaxhighlight>]]
* [[Minus|{{HL|-}}]]
+
* [[Minus|<syntaxhighlight lang="pascal" inline>-</syntaxhighlight>]]
* [[Or|{{HL|or}}]] (both, logical and bitwise variant)
+
* [[Or|<syntaxhighlight lang="pascal" inline>or</syntaxhighlight>]] (both, logical and bitwise variant)
* {{HL|or_else<}}
+
* <syntaxhighlight lang="pascal" inline>or_else</syntaxhighlight>
* [[Xor|{{HLD|xor}}]] (both, logical and bitwise variant)
+
* [[Xor|<syntaxhighlight lang="delphi" inline>xor</syntaxhighlight>]] (both, logical and bitwise variant)
 
|
 
|
 
* addition operators
 
* addition operators
Line 80: Line 81:
 
|-
 
|-
 
| fourth ||
 
| fourth ||
* [[Less than|{{HL|<<}}]]
+
* [[Less than|<syntaxhighlight lang="pascal" inline><</syntaxhighlight>]]
* [[Greater than|{{HL|>}}]]
+
* [[Greater than|<syntaxhighlight lang="pascal" inline>></syntaxhighlight>]]
* [[Equal|{{HL|=}}]]
+
* [[Equal|<syntaxhighlight lang="pascal" inline>=</syntaxhighlight>]]
* [[Not equal|{{HL|<>{{HL|]]
+
* [[Not equal|<syntaxhighlight lang="pascal" inline><></syntaxhighlight>]]
* {{HL|<=<}} (both, ⊆ as well as ≤)
+
* <syntaxhighlight lang="pascal" inline><=</syntaxhighlight> (both, ⊆ as well as ≤)
* {{HL|>=}}>
+
* <syntaxhighlight lang="pascal" inline>>=</syntaxhighlight>
* {{HL|in}}
+
* <syntaxhighlight lang="pascal" inline>in</syntaxhighlight>
* [[symmetric difference|{{HL|><}}]]
+
* [[symmetric difference|<syntaxhighlight lang="pascal" inline>><</syntaxhighlight>]]
* [[Is|{{HL|is}}]]
+
* [[Is|<syntaxhighlight lang="pascal" inline>is</syntaxhighlight>]] (since FPC 3.3.1, cf. {{MantisLink|35909}})
 
|
 
|
 
* relational operators
 
* relational operators
Line 95: Line 96:
 
| lowest<br/>(last) ||
 
| lowest<br/>(last) ||
 
* [[Becomes|<syntaxhighlight lang="pascal" inline>:=</syntaxhighlight>]] (implicit [[Typecast|typecasts]])
 
* [[Becomes|<syntaxhighlight lang="pascal" inline>:=</syntaxhighlight>]] (implicit [[Typecast|typecasts]])
* {{HLD|enumerator}} (if applicable)
+
* <syntaxhighlight lang="delphi" inline>enumerator</syntaxhighlight> (if applicable)
 
|
 
|
 
* destination-dependent conversions
 
* destination-dependent conversions
Line 101: Line 102:
 
<sup>†</sup>) This symbol does not refer to an actual operator, but is (imprecisely) called as one.
 
<sup>†</sup>) This symbol does not refer to an actual operator, but is (imprecisely) called as one.
  
[[Inc and Dec|{{HL|inc}} and {{HL|dec}}]] are pseudo operators:
+
[[Inc and Dec|<syntaxhighlight lang="pascal" inline>Inc</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>dec</syntaxhighlight>]] are pseudo operators:
 
They may be redefined via the operator overloading mechanism, but they can not appear in expressions, like any function could.
 
They may be redefined via the operator overloading mechanism, but they can not appear in expressions, like any function could.
 
Therefore their precedence is moot.
 
Therefore their precedence is moot.
  
{{HL|Include}} and {{HL|exclude}} are also not operators, but shorthand for common LOCs.
+
<syntaxhighlight lang="pascal" inline>Include</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>exclude</syntaxhighlight> are also not operators, but shorthand for common LOCs.
  
{{HL|@}} and {{HL|^}} albeit being called operators, are ''not'' operators, but rather instruct the [[Compiler|compiler]] to interpret an [[Identifier|identifier]] differently than usual.
+
<syntaxhighlight lang="pascal" inline>@</syntaxhighlight> and <syntaxhighlight lang="pascal" inline>^</syntaxhighlight> albeit being called operators, are ''not'' operators, but rather instruct the [[Compiler|compiler]] to interpret an [[Identifier|identifier]] differently than usual.
 
This is not done via any function, but compiler intrinsics.
 
This is not done via any function, but compiler intrinsics.
  
 
{{Note|
 
{{Note|
Operator precedence is slightly modified by {{HL|{$modeSwitch ISOUnaryMinus}}}, which is enabled by default in [[Mode iso|{{HL|{$mode ISO}}}]] and [[Mode extendedpascal|{{HL|{$mode extendedPascal}}}]].
+
Operator precedence is slightly modified by <syntaxhighlight lang="pascal" inline>{$modeSwitch ISOUnaryMinus}</syntaxhighlight>, which is enabled by default in [[Mode iso|<syntaxhighlight lang="pascal" inline style="white-space: nowrap;">{$mode ISO}</syntaxhighlight>]] and [[Mode extendedpascal|<syntaxhighlight lang="pascal" inline style="white-space: nowrap;">{$mode extendedPascal}</syntaxhighlight>]].
 
There, the unary minus is on the same level as other addition operators are.
 
There, the unary minus is on the same level as other addition operators are.
 
}}
 
}}
Line 126: Line 127:
 
For example:
 
For example:
 
<syntaxhighlight lang="pascal">x := foo() + bar();</syntaxhighlight>
 
<syntaxhighlight lang="pascal">x := foo() + bar();</syntaxhighlight>
The compiler may evaluate {{HL|foo()}} or {{HL|bar()}} first.
+
The compiler may evaluate <syntaxhighlight lang="pascal" inline>foo()</syntaxhighlight> or <syntaxhighlight lang="pascal" inline>bar()</syntaxhighlight> first.
If {{HL|bar()}} ought to be evaluated first at all events, the statement has to be split into two separate ones:
+
If <syntaxhighlight lang="pascal" inline>bar()</syntaxhighlight> ought to be evaluated first at all events, the statement has to be split into two separate ones:
 
<syntaxhighlight lang="pascal">x := bar();
 
<syntaxhighlight lang="pascal">x := bar();
 
x := x + foo();</syntaxhighlight>
 
x := x + foo();</syntaxhighlight>
: or
 
<syntaxhighlight lang="pascal">x := bar();
 
x += foo();</syntaxhighlight>
 
if you prefer
 
  
 
{{Note|
 
{{Note|
The [[Compiler directive|compiler directive]] {{HL|{$boolEval off}}} enables “lazy” evaluation.
+
The [[Compiler directive|compiler directive]] [[$boolEval|<syntaxhighlight lang="pascal" inline style="white-space: nowrap;">{$boolEval off}</syntaxhighlight>]] enables “lazy” evaluation.
 
Parts of expressions may not be evaluated at all.
 
Parts of expressions may not be evaluated at all.
 
}}
 
}}
  
 
== see also ==
 
== see also ==
* [https://www.freepascal.org/docs-html/ref/refse84.html “Operators”] in the FreePascal Reference Guide
+
* [https://www.freepascal.org/docs-html/ref/refse88.html “Operators”] in the FreePascal Reference Guide
* Tutorial: [[Assignment and Operations|assignment and operations]]
+
* Tutorial: [[Basic Pascal Tutorial/Chapter 1/Assignment and Operations|assignment and operations]]
* [[management operators]] – a collection of specially supported routines  
+
* [[management operators]] – a collection of specially supported routines
  
 
[[Category:Code]]
 
[[Category:Code]]
[[Category:Operators]]
 

Latest revision as of 16:37, 6 August 2022

Deutsch (de) English (en) suomi (fi)
An operator is a special kind of function. It can be invoked by placing keywords adjacent to suitable operands.

The word operator colloquially refers to the symbol or keyword identifying the function that implements the actual operation. operator is also a reserved word that appears in the course of operator overloading.

usage

Most operators are binary, that means require two operands. Binary operator symbols appear between two operands, like this:

x + 5

The plus character identifies the addition operation (Standard Pascal). x and 5 are its operands. This style is called infix notation.

Unary operators – those which require only one operand – appear in front of their operands (prefix notation), with the exception of ^, the de-referencing operator, which appears after its operand (postfix notation). Example:

-x

Here, the minus character identifies the sign inversion operation (Standard Pascal). Blanks between operator and operand do not harm, confer the following section regarding precedence. However, it is common practice to place unary operator symbols back to back with their operands.

Operator symbols always appear explicitly, except the implicit typecast and enumerator operator. Unlike in mathematics, no invisible “times” is assumed between two identifiers.

Implicit typecasts occur, where a value has to be stored in a memory location. Note, that calling a routine triggers implicit typecasts, too. In order to pass the parameters to the routine, they are stored somewhere. Implicit typecasts are not limited to run-of-the-mill assignment statements.

operator precedence

Operands and operators are the building blocks of expressions. The use of operators is a powerful notational tool, since LOCs do not get cluttered by function calls consisting of function identifiers and parentheses, but instead the operands and (ideally) a short symbol achieve the same. Instead of, for example, sum(x, -8) the expression x - 8 evaluates to the same value, while writing five less characters.

In order to increase conciseness subexpressions of expressions propagate their intermediate result in a predefined hierarchy. This hierarchy can be superseded by placing parentheses ( ) around subexpressions that shall be treated as one expression, so the regular precedence rules apply in the enclosed part remaining uninfluenced from the expression’s rest. Operators that have have higher precedence, bind to operands stronger.

operator precedence
precedence operators category
highest
(first)
  • not (both, logical and bitwise variant)
  • unary + (sign identity, “positive sign”)
  • unary - (sign inversion, “negative sign”)
  • **
  • pow
  • @
  • ^ (de-referencing operator)
  • explicit typecasts
  • unary operators (except
    destination-dependent operators)
  • power
second
  • *
  • and (both, logical and bitwise variant)
  • and_then
  • /
  • div
  • mod
  • shl (<<)
  • shr (>>)
  • as
  • is (until FPC 3.3.1, trunk revision 44266)
  • multiplication operators
  • conditional typecast
third
  • +
  • -
  • or (both, logical and bitwise variant)
  • or_else
  • xor (both, logical and bitwise variant)
  • addition operators
  • complex logical operators
fourth
  • relational operators
  • inheritance test
lowest
(last)
  • destination-dependent conversions

) This symbol does not refer to an actual operator, but is (imprecisely) called as one.

Inc and dec are pseudo operators: They may be redefined via the operator overloading mechanism, but they can not appear in expressions, like any function could. Therefore their precedence is moot.

Include and exclude are also not operators, but shorthand for common LOCs.

@ and ^ albeit being called operators, are not operators, but rather instruct the compiler to interpret an identifier differently than usual. This is not done via any function, but compiler intrinsics.

Light bulb  Note: Operator precedence is slightly modified by {$modeSwitch ISOUnaryMinus}, which is enabled by default in {$mode ISO} and {$mode extendedPascal}. There, the unary minus is on the same level as other addition operators are.

evaluation order

Light bulb  Note: Operator precedence does not infer evaluation order. The compiler may re-arrange expressions according to associative and commutative properties of operators.

No assumptions shall be made, and there is no guarantee, that expressions are evaluated from left to right (or the reverse direction). The FPC for instance, evaluates more “complex” subexpressions first before moving on to “trivial” parts (ratio: avoiding register spilling).

If a subexpression has to be evaluated first, e.g. a function triggering some side-effects, the expression has to be split up into two separate statements. For example:

x := foo() + bar();

The compiler may evaluate foo() or bar() first. If bar() ought to be evaluated first at all events, the statement has to be split into two separate ones:

x := bar();
x := x + foo();

Light bulb  Note: The compiler directive {$boolEval off} enables “lazy” evaluation. Parts of expressions may not be evaluated at all.

see also