X39 – User talk

From Bohemia Interactive Community
Jump to navigation Jump to search
m (link fix)
(Cleared as content was merged with SQF_syntax)
Line 1: Line 1:
__TOC__
'''Status Quo Function''' is the successor of '''[[SQS_syntax|Status Quo Script]]''' which is deprecated since [[Armed Assault]].
SQF was first introduced in [[Operation_Flashpoint:_Resistance_Introduction|Operation Flashpoint: Resistance]].


An SQF expression has to be terminated via either {{Inline code|;}} or {{Inline code|,}}.
Example:
_num = 10;
_num = _num + 20; [[systemChat]] _num;
In the above example, there are three expressions.
# {{Inline code|_num {{=}} 10}}
# {{Inline code|_num {{=}} _num + 20}}
# {{Inline code|[[systemChat]] _num}}
All get separated, not via a new line but the {{Inline code|;}}.
SQF also allows [[Array|arrays]] and [[Block|codeblocks]] to have expressions inside of them.
An [[Array|array]] will always start with {{Inline code|[}} and ends with {{Inline code|]}}. The [[Array|array]] may contain another [[Data_Types|value type]] including other [[Array|arrays]].
A [[Block|codeblock]] is a separate [[Data_Types|value type]] containing numerous SQF expressions. It will be executed when used with eg. [[call]] and can be assigned to a [[Variables|variable]] just like any other [[Data_Types|value type]]. [[Block|Codeblocks]] start with {{Inline code|<nowiki>{</nowiki>}} and end with {{Inline code|<nowiki>}</nowiki>}}
== Language Structure ==
The SQF Language is fairly simple in how it is built.
In fact: there are barely any actual language structures at all.
The functionality is provided via so called ''[[:Category:Scripting_Commands_Arma_3|operators]]'' (or more commonly known [[:Category:Scripting_Commands_Arma_3|scripting commands]]).
Those [[:Category:Scripting_Commands_Arma_3|operators]] are one of the following types: [[#nular|Nular]], [[#unary|Unary]],  or [[#binary|Binary]].
=== Comments ===
A comment is additional text that gets ignored when a script is parsed.
They exists they exist for the to allow you, the coder, to add additional info to your code so that if somebody else (including your future you) is looking into the code can understand what you did there.
In SQF, there are two kind of comments:
{{codecomment|// In-line comment that ends on new line}}
{{codecomment|/* Block Comment that can span above multiple lines and ends on the following character combination: */}}
A comment can occur anywhere but inside a [[String|string]].
For example, the following would be valid:
1 + {{codecomment|/* Some random comment in an expression. */}} 1
It should be mentioned that there is a [[comment]] unary [[:Category:Scripting_Commands_Arma_3|operator]] that should not be used as it will actually be executed (thus taking time to execute) but does nothing besides consuming a [[String|string]].
There is no benefit in using it and the reason it exists is solely for backward Compatibility.
Another way to make a ''comment'' that way, is to just place a [[String|string]]: {{Inline code|[...]; "i can be considered as a comment but should not be used"; [...]}}
''Comments are removed during the [[PreProcessor_Commands|preprocessing]] phase.'' This is important to know as that prevents usage in eg. a [[String|string]] that gets compiled using the [[compile]] unary [[:Category:Scripting_Commands_Arma_3|operator]] or when only using [[loadFile]].
=== <span id="nular">Nular Operators</span> ===
A nular operator is more or less a computed [Variables|variable]]. Each time accessed, it will return the current state of something.
It is tempting to think of a nular [[:Category:Scripting_Commands_Arma_3|operator]] as nothing more but a magic [[Variables|global variable]], but it is important to differentiate!
Consider following example in a mission with eg. 5 units:
{{codecomment|// Put the result of [[allUnits]] into a [[Variables|variable]].}}
_unitsArray = [[allUnits]];
{{codecomment|// Display the current [[Array|array]] size using [[systemChat]].}}
[[systemChat]] [[str]] [[count]] _unitsArray;
{{codecomment|// Create a new unit in the player group.}}
[[group]] [[player]] [[createUnit]] ["B_RangeMaster_F", [[position]] [[player]], [], 0, "FORM"];
{{codecomment|// Output the [[Array|array]] size again}}
[[systemChat]] [[str]] [[count]] _unitsArray;
{{codecomment|// Output the size of [[allUnits]]}}
[[systemChat]] [[str]] [[count]] [[allUnits]];
Now, what would the output of this look like?
System: 5
System: 5
System: 6
As you can see, {{Inline code|_unitsArray}} was not automatically updated as it would have been if it was not generated each time. If [[allUnits]] was just a [[Variables|global variable]], our private [Variables|variable]] should have had reflected the change as [[Data_Types|value types]] are passed by reference.
The reason for this is because [[allUnits]] and other nular operators just return the current state of something and do not return a reference to eg. an [[Array|array]] containing all units.
It is generated each time, which is why some of theese operators are more expensive to run then ''just'' using a [Variables|variable]].
=== <span id="unary">Unary Operators</span> ===
The unary [[:Category:Scripting_Commands_Arma_3|operators]] are [[:Category:Scripting_Commands_Arma_3|operators]] that expect an argument on their right side ({{Inline code|unary &lt;argument&gt;}}). They always will take the first argument that occurs.
A common mistake would be the following:
{{codecomment|// Create some [[Array|array]] containing three arrays.}}
_arr = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2]];
{{codecomment|// Wrongly use the [[select]] operator to get the count of the third array.}}
[[count]] _arr [[select]] 2; <span style="color: Red;">// Error</span>
Now, what went wrong?
Let's put some brackets in the right places to make the mistake understandable:
([[count]] _arr) [[select]] 2; <span style="color: Red;">// Error</span>
Due to the nature of Unary [[:Category:Scripting_Commands_Arma_3|operators]], count instantly consumes our [[Variables|variable]] ''_arr'' and returns the number ''3''.
The ''3'' then is passed to [[select]] which does not knows what to do with a number as left argument and thus errors out.
To do it correctly, one would have to put the {{Inline code|_arr select 2}} in brackets.
The correct code thus would be:
{{codecomment|// Create an [[Array|array]] containing three [[Array|arrays]].}}
_arr = [[1, 2, 3, 4, 5], [1, 2, 3, 4], [1, 2]];
{{codecomment|// Use Brackets to correctly get count of the third [[Array|array]].}}
[[count]] (_arr [[select]] 2); {{codecomment|// Good :) will evaluate to 2}}
=== <span id="binary">Binary Operators</span> ===
Binary [[:Category:Scripting_Commands_Arma_3|operators]] expect two arguments ({{Inline code|&lt;1st argument&gt; binary &lt;2nd argument&gt;}}) and are executed according to their [[#precedence|precedence]]. If their [[#precedence|precedence]] is equal, they are executed left to right.
As example, we will look into the following expression:
{{codecomment|// Create a nested [[Array|array]] with 5 levels.}}
_arr = [[[[[1]]]]];
{{codecomment|// Receive the nested number with some random math expressions.}}
_arr [[select]] 0 [[select]] 1 [[a_minus_b|-]] 1 [[select]] 15 [[a_/_b|/]]  3 [[a_minus_b|-]] 5 [[select]] 0 [[select]] 10 [[a_*_b|*]] 10 [[a_plus_b|+]] 4 [[a_*_b|*]] 0 [[a_minus_b|-]] 100{{codecomment|// Evaluates to 1.}}
Now, let us analyze why this is happening for the first few expressions:
# _arr is loaded
# 0 is loaded
# [[select]] is executed with the result of 1. & 2.
# 1 is loaded
# 1 is loaded
# [[a_minus_b|-]] is executed with the result of 4. & 5.
# [[select]] is executed with the result of 3. & 6.
# ...
If we now would put brackets at the correct spots, the expression will get clearer:
((((_arr [[select]] 0) [[select]] (1 [[a_minus_b|-]] 1)) [[select]] ((15 [[a_/_b|/]]  3) [[a_minus_b|-]] 5)) [[select]] 0) [[select]] (((10 [[a_*_b|*]] 10) [[a_plus_b|+]] (4 [[a_*_b|*]] 0)) [[a_minus_b|-]] 100)
As you can see the [[a_*_b|*]] and [[a_/_b|/]] are executed first which matches their [[#precedence|precedence]]. Afterwards, the [[a_plus_b|+]] and [[a_minus_b|-]] [[:Category:Scripting_Commands_Arma_3|operators]] will get executed followed by our [[select]] operator, which are executed from the left to the right.
== <span id="precedence">Rules Of Precedence</span> ==
{|
|11 '''Highest Precedence'''
|''ALL NULAR OPERATORS, VARIABLES, VALUES OR BRACED EXPRESSIONS''
|-
|10
|''ALL UNARY OPERATORS''
|-
|9
|<code>[[select|#]]</code>
|-
|8
|<code>[[a_^_b|^]]</code>
|-
|7
|<code>[[a_*_b|*]] [[a_/_b|/]] [[mod|%]] [[mod]] [[atan2]]</code>
|-
|6
|<code>[[a_plus_b|+]] [[a_minus_b|-]] [[max]] [[min]]</code>
|-
|5
|<code>[[else]]</code>
|-
|4
|''ALL BINARY OPERATORS''
|-
|3
|<code>[[==]] [[!=]] [[a_greater_b|&gt;]] [[a_less_b|&lt;]] [[a_less=_b|&gt;=]] [[a_less=_b|&lt;=]] [[config_greater_greater_name|&gt;&gt;]]</code>
|-
|2
|<code>[[and|&&]] [[and]]</code>
|-
|1 '''Lowest Precedence'''
|<code>[[a or b|<nowiki>||</nowiki>]] [[a or b|or]]</code>
|}
== See also ==
* [[Control Structures]]
* [[SQS syntax]]
* [[Function]]
* [[Statement]]
* [[Block]]
* [[Missions#Locations_of_Mission_Files|Location of script files]]
* [[SQS to SQF conversion]]
<!-- [[Category: Syntax]] [[Category:Scripting Topics]] -->

Revision as of 16:06, 23 April 2018