Angelscript/docs/manual/doc_expressions.html

347 lines
22 KiB
HTML
Raw Permalink Normal View History

2021-04-12 18:25:02 +00:00
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Expressions</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">AngelScript
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('doc_expressions.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<div class="PageDoc"><div class="header">
<div class="headertitle">
<div class="title">Expressions </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><ul>
<li><a class="el" href="doc_expressions.html#assignment">Assignments</a></li>
<li><a class="el" href="doc_expressions.html#function">Function call</a></li>
<li><a class="el" href="doc_expressions.html#math">Math operators</a></li>
<li><a class="el" href="doc_expressions.html#bits">Bitwise operators</a></li>
<li><a class="el" href="doc_expressions.html#compound">Compound assignments</a></li>
<li><a class="el" href="doc_expressions.html#logic">Logic operators</a></li>
<li><a class="el" href="doc_expressions.html#equal">Equality comparison operators</a></li>
<li><a class="el" href="doc_expressions.html#relation">Relational comparison operators</a></li>
<li><a class="el" href="doc_expressions.html#identity">Identity comparison operators</a></li>
<li><a class="el" href="doc_expressions.html#increment">Increment operators</a></li>
<li><a class="el" href="doc_expressions.html#opindex">Indexing operator</a></li>
<li><a class="el" href="doc_expressions.html#condition">Conditional expression</a></li>
<li><a class="el" href="doc_expressions.html#member">Member access</a></li>
<li><a class="el" href="doc_expressions.html#handle">Handle-of</a></li>
<li><a class="el" href="doc_expressions.html#parenthesis">Parenthesis</a></li>
<li><a class="el" href="doc_expressions.html#scope">Scope resolution</a></li>
<li><a class="el" href="doc_expressions.html#conversion">Type conversions</a></li>
<li><a class="el" href="doc_expressions.html#anonobj">Anonymous objects</a></li>
</ul>
<h1><a class="anchor" id="assignment"></a>
Assignments</h1>
<pre> lvalue = rvalue;</pre><p><code>lvalue</code> must be an expression that evaluates to a memory location where the expression value can be stored, e.g. a variable. An assignment evaluates to the same value and type of the data stored. The right hand expression is always computed before the left.</p>
<h1><a class="anchor" id="function"></a>
Function call</h1>
<pre>
func();
func(arg);
func(arg1, arg2);
lvalue = func();
</pre><p>Functions are called to perform an action, and possibly return a value that can be used in further operations. If a function takes more than one argument, the argument expressions are evaluated in the reverse order, i.e. the last argument is evaluated first.</p>
<p>Some functions are declared with output reference parameters to return multiple values. When calling such functions the output parameter must be given as an expression that can be assigned with the returned value. If the additional output value won't be used use the special argument 'void' to tell the compiler that.</p>
<pre>
// This function returns a value in the output parameter
void func(int &amp;out outputValue)
{
outputValue = 42;
}</pre><pre> // Call the function with a valid lvalue expression to receive the output value
int value;
func(value);</pre><pre> // Call the function with 'void' argument to ignore the output value
func(void);
</pre><p>Arguments can also be named and passed to a specific argument independent of the order the parameters were declared in. No positional arguments may follow any named arguments.</p>
<pre>
void func(int flagA = false, int flagB = false, int flagC = false) {}</pre><pre> // Call the function, setting only a subset of its parameters
func(flagC: true);
func(flagB: true, flagA: true);
</pre><h1><a class="anchor" id="math"></a>
Math operators</h1>
<pre>
c = -(a + b);
</pre><table cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="70" valign="top"><b>operator</b></td><td width="100" valign="top"><b>description</b></td><td width="80" valign="top"><b>left hand</b></td><td width="80" valign="top"><b>right hand</b></td><td width="80" valign="top"><b>result</b> </td></tr>
<tr>
<td width="70" valign="top"><code>+</code> </td><td width="100" valign="top">unary positive </td><td width="80" valign="top">&#160; </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>-</code> </td><td width="100" valign="top">unary negative </td><td width="80" valign="top">&#160; </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>+</code> </td><td width="100" valign="top">addition </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>-</code> </td><td width="100" valign="top">subtraction </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>*</code> </td><td width="100" valign="top">multiplication </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>/</code> </td><td width="100" valign="top">division </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>%</code> </td><td width="100" valign="top">modulos </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>**</code> </td><td width="100" valign="top">exponent </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
</table>
<p>Plus and minus can be used as unary operators as well. NUM can be exchanged for any numeric type, e.g. <code>int</code> or <code>float</code>. Both terms of the dual operations will be implicitly converted to have the same type. The result is always the same type as the original terms. One exception is unary negative which is not available for <code>uint</code>.</p>
<h1><a class="anchor" id="bits"></a>
Bitwise operators</h1>
<pre>
c = ~(a | b);
</pre><table cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="70" valign="top"><b>operator</b> </td><td width="130" valign="top"><b>description</b> </td><td width="80" valign="top"><b>left hand</b></td><td width="80" valign="top"><b>right hand</b></td><td width="80" valign="top"><b>result</b> </td></tr>
<tr>
<td width="70" valign="top"><code>~</code> </td><td width="130" valign="top">bitwise complement </td><td width="80" valign="top">&#160; </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>&amp;</code> </td><td width="130" valign="top">bitwise and </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>|</code> </td><td width="130" valign="top">bitwise or </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>^</code> </td><td width="130" valign="top">bitwise xor </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>&lt;&lt;</code> </td><td width="130" valign="top">left shift </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>&gt;&gt;</code> </td><td width="130" valign="top">right shift </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
<tr>
<td width="70" valign="top"><code>&gt;&gt;&gt;</code></td><td width="130" valign="top">arithmetic right shift</td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td><td width="80" valign="top"><em>NUM</em> </td></tr>
</table>
<p>All except <code>~</code> are dual operators.</p>
<p>Both operands will be converted to integers while keeping the sign of the original type before the operation. The resulting type will be the same as the left hand operand.</p>
<h1><a class="anchor" id="compound"></a>
Compound assignments</h1>
<pre>
lvalue += rvalue;
lvalue = lvalue + rvalue;
</pre><p>A compound assignment is a combination of an operator followed by the assignment. The two expressions above means practically the same thing. Except that first one is more efficient in that the lvalue is only evaluated once, which can make a difference if the lvalue is complex expression in itself.</p>
<p>Available operators: <code>+= -= *= /= %= **= &amp;= |= ^= &lt;&lt;= &gt;&gt;= &gt;&gt;&gt;=</code></p>
<h1><a class="anchor" id="logic"></a>
Logic operators</h1>
<pre>
if( a and b or not c )
{
// ... do something
}
</pre><table cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="70" valign="top"><b>operator</b> </td><td width="130" valign="top"><b>description</b> </td><td width="80" valign="top"><b>left hand</b> </td><td width="80" valign="top"><b>right hand</b></td><td width="80" valign="top"><b>result</b> </td></tr>
<tr>
<td width="70" valign="top"><code>not</code></td><td width="130" valign="top">logical not </td><td width="80" valign="top">&#160; </td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code> </td></tr>
<tr>
<td width="70" valign="top"><code>and</code></td><td width="130" valign="top">logical and </td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code> </td></tr>
<tr>
<td width="70" valign="top"><code>or</code> </td><td width="130" valign="top">logical or </td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code> </td></tr>
<tr>
<td width="70" valign="top"><code>xor</code></td><td width="130" valign="top">logical exclusive or</td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code></td><td width="80" valign="top"><code>bool</code> </td></tr>
</table>
<p>Boolean operators only evaluate necessary terms. For example in expression <code>a and b</code>, <code>b</code> is only evaluated if <code>a</code> is <code>true</code>.</p>
<p>Each of the logic operators can be written as symbols as well, i.e. <code>||</code> for <code>or</code>, <code>&amp;&amp;</code> for <code>and</code>, <code>^^</code> for <code>xor</code>, and <code>!</code> for <code>not</code>.</p>
<h1><a class="anchor" id="equal"></a>
Equality comparison operators</h1>
<pre>
if( a == b )
{
// ... do something
}
</pre><p>The operators <code>==</code> and <code>!=</code> are used to compare two values to determine if they are equal or not equal, respectively. The result of this operation is always a boolean value.</p>
<h1><a class="anchor" id="relation"></a>
Relational comparison operators</h1>
<pre>
if( a &gt; b )
{
// ... do something
}
</pre><p>The operators <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>, and <code>&gt;=</code> are used to compare two values to determine their relationship. The result is always a boolean value.</p>
<h1><a class="anchor" id="identity"></a>
Identity comparison operators</h1>
<pre>
if( a is null )
{
// ... do something
}
else if( a is b )
{
// ... do something
}
</pre><p>The operators <code>is</code> and <code>!is</code> are used to compare the identity of two objects, i.e. to determine if the two are the same object or not. These operators are only valid for reference types as they compare the address of two objects. The result is always a boolean value.</p>
<h1><a class="anchor" id="increment"></a>
Increment operators</h1>
<pre>
// The following means a = i; i = i + 1;
a = i++;</pre><pre> // The following means i = i - 1; b = i;
b = --i;
</pre><p>These operators can be placed either before or after an lvalue to increment/decrement its value either before or after the value is used in the expression. The value is always incremented or decremented with 1.</p>
<h1><a class="anchor" id="opindex"></a>
Indexing operator</h1>
<pre>
arr[i] = 1;
</pre><p>This operator is used to access an element contained within the object. Depending on the object type, the expression between the <code>[]</code> needs to be of different types.</p>
<h1><a class="anchor" id="condition"></a>
Conditional expression</h1>
<pre>
choose ? a : b;
</pre><p>If the value of <code>choose</code> is <code>true</code> then the expression returns <code>a</code> otherwise it will return <code>b</code>. Both <code>a</code> and <code>b</code> must be of the same type.</p>
<p>If they are not of the same type the compiler will attempt an implicit conversion using the following rules. If the <code>a</code> expression is 0 or null, then the compiler will attempt to convert it to the type of <code>b</code>, otherwise it will attempt to convert <code>b</code> to the type of <code>a</code>.</p>
<p>If the conversion doesn't work, then the compiler will give an error.</p>
<p>The conditional expression can be used as an lvalue, i.e. on the left value of an assignment expression, if both <code>a</code> and <code>b</code> are lvalues of the same type.</p>
<pre>
int a, b;
(expr ? a : b) = 42;
</pre><h1><a class="anchor" id="member"></a>
Member access</h1>
<pre>
object.property = 1;
object.method();
</pre><p><code>object</code> must be an expression resulting in a data type that have members. <code>property</code> is the name of a member variable that can be read/set directly. <code>method</code> is the name of a member method that can be called on the object.</p>
<h1><a class="anchor" id="handle"></a>
Handle-of</h1>
<pre>
// Make handle reference the object instance
@handle = @object;</pre><pre> // Clear the handle and release the object it references
@handle = null;
</pre><p>Object handles are references to an object. More than one handle can reference the same object, and only when no more handles reference an object is the object destroyed.</p>
<p>The members of the object that the handle references are accessed the same way through the handle as if accessed directly through the object variable, i.e. with <code>.</code> operator.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_script_handle.html">Object handles</a></dd></dl>
<h1><a class="anchor" id="parenthesis"></a>
Parenthesis</h1>
<pre>
a = c * (a + b);
if( (a or b) and c )
{
// ... do something
}
</pre><p>Parenthesis are used to group expressions when the <a class="el" href="doc_operator_precedence.html">operator precedence</a> does not give the desired order of evaluation.</p>
<h1><a class="anchor" id="scope"></a>
Scope resolution</h1>
<pre>
int value;
void function()
{
int value; // local variable overloads the global variable
::value = value; // use scope resolution operator to refer to the global variable
}
</pre><p>The scope resolution operator <code>::</code> can be used to access variables or functions from another scope when the name is overloaded by a local variable or function. Write the scope name on the left (or blank for the global scope) and the name of the variable/function on the right.</p>
<dl class="section see"><dt>See also</dt><dd><a class="el" href="doc_global_namespace.html">Namespaces</a></dd></dl>
<h1><a class="anchor" id="conversion"></a>
Type conversions</h1>
<pre>
// implicitly convert the clss handle to a intf handle
intf @a = @clss();</pre><pre> // explicitly convert the intf handle to a clss handle
clss @b = cast&lt;clss&gt;(a);
</pre><p>Object handles can be converted to other object handles with the cast operator. If the cast is valid, i.e. the true object implements the class or interface being requested, the operator returns a valid handle. If the cast is not valid, the cast returns a null handle.</p>
<p>The above is called a reference cast, and only works for types that support object handles. In this case the handle still refers to the same object, it is just exposed through a different interface.</p>
<p>Types that do not support object handles can be converted with a value cast instead. In this case a new value is constructed, or in case of objects a new instance of the object is created.</p>
<pre>
// implicit value cast
int a = 1.0f;</pre><pre> // explicit value cast
float b = float(a)/2;
</pre><p>In most cases an explicit cast is not necessary for primitive types, however, as the compiler is usually able to do an implicit cast to the correct type.</p>
<h1><a class="anchor" id="anonobj"></a>
Anonymous objects</h1>
<p>Anonymous objects, i.e. objects that are created without being declared as variables, can be instantiated in expressions by calling invoking the object's constructor as if it was a function. Both reference types and value types can be created like this.</p>
<pre>
// Call the function with a new object of the type MyClass
func(MyClass(1,2,3));
</pre><p>For types that support it, the anonymous objects can also be initialized with initialization lists.</p>
<pre>
// Call the function with a dictionary, explicitly informing the type of the initialization list
func(dictionary = {{'banana',1}, {'apple',2}, {'orange',3}});</pre><pre> // When there is only one possible type that support initialization lists it is possible
// to omit the type and let the compiler implicitly determine it based on the use
funcExpectsAnArrayOfInts({1,2,3,4});
</pre> </div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Generated on Sat Dec 5 2020 23:20:24 for AngelScript by
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.18 </li>
</ul>
</div>
</body>
</html>