painless-operators-general.asciidoc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. [[painless-operators-general]]
  2. === Operators: General
  3. [[precedence-operator]]
  4. ==== Precedence
  5. Use the `precedence operator '()'` to guarantee the order of evaluation for an
  6. expression. An expression encapsulated by the precedence operator (enclosed in
  7. parentheses) overrides existing precedence relationships between operators and
  8. is evaluated prior to other expressions in inward-to-outward order.
  9. *Grammar*
  10. [source,ANTLR4]
  11. ----
  12. precedence: '(' expression ')';
  13. ----
  14. *Examples*
  15. * Precedence with numeric operators.
  16. +
  17. [source,Painless]
  18. ----
  19. <1> int x = (5+4)*6;
  20. <2> int y = 12/(x-50);
  21. ----
  22. +
  23. <1> declare `int x`;
  24. add `int 5` and `int 4` -> `int 9`;
  25. multiply `int 9` and `int 6` -> `int 54`;
  26. store `int 54` to `x`;
  27. (note the add is evaluated before the multiply due to the precedence
  28. operator)
  29. <2> declare `int y`;
  30. load from `x` -> `int 54`;
  31. subtract `int 50` from `int 54` -> `int 4`;
  32. divide `int 12` by `int 4` -> `int 3`;
  33. store `int 3` to `y`;
  34. (note the subtract is evaluated before the divide due to the precedence
  35. operator)
  36. [[function-call-operator]]
  37. ==== Function Call
  38. Use the `function call operator ()` to call an existing function. A
  39. <<painless-functions, function call>> is defined within a script.
  40. *Grammar*
  41. [source,ANTLR4]
  42. ----
  43. function_call: ID '(' ( expression (',' expression)* )? ')'';
  44. ----
  45. *Examples*
  46. * A function call.
  47. +
  48. [source,Painless]
  49. ----
  50. <1> int add(int x, int y) {
  51. return x + y;
  52. }
  53. <2> int z = add(1, 2);
  54. ----
  55. +
  56. <1> define function `add` that returns `int` and has parameters (`int x`,
  57. `int y`)
  58. <2> declare `int z`;
  59. call `add` with arguments (`int 1`, `int 2`) -> `int 3`;
  60. store `int 3` to `z`
  61. [[cast-operator]]
  62. ==== Cast
  63. An explicit cast converts the value of an original type to the equivalent value
  64. of a target type forcefully as an operation. Use the `cast operator '()'` to
  65. specify an explicit cast. Refer to <<painless-casting, casting>> for more
  66. information.
  67. [[conditional-operator]]
  68. ==== Conditional
  69. A conditional consists of three expressions. The first expression is evaluated
  70. with an expected boolean result type. If the first expression evaluates to true
  71. then the second expression will be evaluated. If the first expression evaluates
  72. to false then the third expression will be evaluated. The second and third
  73. expressions will be <<promotion, promoted>> if the evaluated values are not the
  74. same type. Use the `conditional operator '? :'` as a shortcut to avoid the need
  75. for a full if/else branch in certain expressions.
  76. *Errors*
  77. * If the first expression does not evaluate to a boolean type value.
  78. * If the values for the second and third expressions cannot be promoted.
  79. *Grammar*
  80. [source,ANTLR4]
  81. ----
  82. conditional: expression '?' expression ':' expression;
  83. ----
  84. *Promotion*
  85. [cols="<1,^1,^1,^1,^1,^1,^1,^1,^1,^1"]
  86. |====
  87. | | byte | short | char | int | long | float | double | Reference | def
  88. | byte | int | int | int | int | long | float | double | - | def
  89. | short | int | int | int | int | long | float | double | - | def
  90. | char | int | int | int | int | long | float | double | - | def
  91. | int | int | int | int | int | long | float | double | - | def
  92. | long | long | long | long | long | long | float | double | - | def
  93. | float | float | float | float | float | float | float | double | - | def
  94. | double | double | double | double | double | double | double | double | - | def
  95. | Reference | - | - | - | - | - | - | - | Object @ | def
  96. | def | def | def | def | def | def | def | def | def | def
  97. |====
  98. @ If the two reference type values are the same then this promotion will not
  99. occur.
  100. *Examples*
  101. * Evaluation of conditionals.
  102. +
  103. [source,Painless]
  104. ----
  105. <1> boolean b = true;
  106. <2> int x = b ? 1 : 2;
  107. <3> List y = x > 1 ? new ArrayList() : null;
  108. <4> def z = x < 2 ? x : 2.0;
  109. ----
  110. +
  111. <1> declare `boolean b`;
  112. store `boolean true` to `b`
  113. <2> declare `int x`;
  114. load from `b` -> `boolean true`
  115. evaluate 1st expression: `int 1` -> `int 1`;
  116. store `int 1` to `x`
  117. <3> declare `List y`;
  118. load from `x` -> `int 1`;
  119. `int 1` greater than `int 1` -> `boolean false`;
  120. evaluate 2nd expression: `null` -> `null`;
  121. store `null` to `y`;
  122. <4> declare `def z`;
  123. load from `x` -> `int 1`;
  124. `int 1` less than `int 2` -> `boolean true`;
  125. evaluate 1st expression: load from `x` -> `int 1`;
  126. promote `int 1` and `double 2.0`: result `double`;
  127. implicit cast `int 1` to `double 1.0` -> `double 1.0`;
  128. implicit cast `double 1.0` to `def` -> `def`;
  129. store `def` to `z`;
  130. [[assignment-operator]]
  131. ==== Assignment
  132. Use the `assignment operator '='` to store a value in a variable or reference
  133. type member field for use in subsequent operations. Any operation that produces
  134. a value can be assigned to any variable/field as long as the
  135. <<painless-types, types>> are the same or the resultant type can be
  136. <<painless-casting, implicitly cast>> to the variable/field type.
  137. See <<variable-assignment, variable assignment>> for examples using variables.
  138. *Errors*
  139. * If the type of value is unable to match the type of variable or field.
  140. *Grammar*
  141. [source,ANTLR4]
  142. ----
  143. assignment: field '=' expression
  144. ----
  145. *Examples*
  146. The examples use the following reference type definition:
  147. [source,Painless]
  148. ----
  149. name:
  150. Example
  151. non-static member fields:
  152. * int x
  153. * def y
  154. * List z
  155. ----
  156. * Field assignments of different type values.
  157. +
  158. [source,Painless]
  159. ----
  160. <1> Example example = new Example();
  161. <2> example.x = 1;
  162. <3> example.y = 2.0;
  163. <4> example.z = new ArrayList();
  164. ----
  165. +
  166. <1> declare `Example example`;
  167. allocate `Example` instance -> `Example reference`;
  168. store `Example reference` to `example`
  169. <2> load from `example` -> `Example reference`;
  170. store `int 1` to `x` of `Example reference`
  171. <3> load from `example` -> `Example reference`;
  172. implicit cast `double 2.0` to `def` -> `def`;
  173. store `def` to `y` of `Example reference`
  174. <4> load from `example` -> `Example reference`;
  175. allocate `ArrayList` instance -> `ArrayList reference`;
  176. implicit cast `ArrayList reference` to `List reference` -> `List reference`;
  177. store `List reference` to `z` of `Example reference`
  178. +
  179. * A field assignment from a field access.
  180. +
  181. [source,Painless]
  182. ----
  183. <1> Example example = new Example();
  184. <2> example.x = 1;
  185. <3> example.y = example.x;
  186. ----
  187. +
  188. <1> declare `Example example`;
  189. allocate `Example` instance -> `Example reference`;
  190. store `Example reference` to `example`
  191. <2> load from `example` -> `Example reference`;
  192. store `int 1` to `x` of `Example reference`
  193. <3> load from `example` -> `Example reference @0`;
  194. load from `example` -> `Example reference @1`;
  195. load from `x` of `Example reference @1` -> `int 1`;
  196. implicit cast `int 1` to `def` -> `def`;
  197. store `def` to `y` of `Example reference @0`;
  198. (note `Example reference @0` and `Example reference @1` are the same)
  199. [[compound-assignment-operator]]
  200. ==== Compound Assignment
  201. Use the `compound assignment operator '$='` as a shortcut for an assignment
  202. where a binary operation would occur between the variable/field as the
  203. left-hand side expression and a separate right-hand side expression.
  204. A compound assignment is equivalent to the expression below where V is the
  205. variable/field and T is the type of variable/member.
  206. [source,Painless]
  207. ----
  208. V = (T)(V op expression);
  209. ----
  210. *Operators*
  211. The table below shows the available operators for use in a compound assignment.
  212. Each operator follows the casting/promotion rules according to their regular
  213. definition. For numeric operations there is an extra implicit cast when
  214. necessary to return the promoted numeric type value to the original numeric type
  215. value of the variable/field and can result in data loss.
  216. |====
  217. |Operator|Compound Symbol
  218. |Multiplication|*=
  219. |Division|/=
  220. |Remainder|%=
  221. |Addition|+=
  222. |Subtraction|-=
  223. |Left Shift|<<=
  224. |Right Shift|>>=
  225. |Unsigned Right Shift|>>>=
  226. |Bitwise And|&=
  227. |Boolean And|&=
  228. |Bitwise Xor|^=
  229. |Boolean Xor|^=
  230. |Bitwise Or|\|=
  231. |Boolean Or|\|=
  232. |String Concatenation|+=
  233. |====
  234. *Errors*
  235. * If the type of value is unable to match the type of variable or field.
  236. *Grammar*
  237. [source,ANTLR4]
  238. ----
  239. compound_assignment: ( ID | field ) '$=' expression;
  240. ----
  241. Note the use of the `$=` represents the use of any of the possible binary
  242. operators.
  243. *Examples*
  244. * Compound assignment for each numeric operator.
  245. +
  246. [source,Painless]
  247. ----
  248. <1> int i = 10;
  249. <2> i *= 2;
  250. <3> i /= 5;
  251. <4> i %= 3;
  252. <5> i += 5;
  253. <6> i -= 5;
  254. <7> i <<= 2;
  255. <8> i >>= 1;
  256. <9> i >>>= 1;
  257. <10> i &= 15;
  258. <11> i ^= 12;
  259. <12> i |= 2;
  260. ----
  261. +
  262. <1> declare `int i`;
  263. store `int 10` to `i`
  264. <2> load from `i` -> `int 10`;
  265. multiply `int 10` and `int 2` -> `int 20`;
  266. store `int 20` to `i`;
  267. (note this is equivalent to `i = i*2`)
  268. <3> load from `i` -> `int 20`;
  269. divide `int 20` by `int 5` -> `int 4`;
  270. store `int 4` to `i`;
  271. (note this is equivalent to `i = i/5`)
  272. <4> load from `i` -> `int 4`;
  273. remainder `int 4` by `int 3` -> `int 1`;
  274. store `int 1` to `i`;
  275. (note this is equivalent to `i = i%3`)
  276. <5> load from `i` -> `int 1`;
  277. add `int 1` and `int 5` -> `int 6`;
  278. store `int 6` to `i`;
  279. (note this is equivalent to `i = i+5`)
  280. <6> load from `i` -> `int 6`;
  281. subtract `int 5` from `int 6` -> `int 1`;
  282. store `int 1` to `i`;
  283. (note this is equivalent to `i = i-5`)
  284. <7> load from `i` -> `int 1`;
  285. left shift `int 1` by `int 2` -> `int 4`;
  286. store `int 4` to `i`;
  287. (note this is equivalent to `i = i<<2`)
  288. <8> load from `i` -> `int 4`;
  289. right shift `int 4` by `int 1` -> `int 2`;
  290. store `int 2` to `i`;
  291. (note this is equivalent to `i = i>>1`)
  292. <9> load from `i` -> `int 2`;
  293. unsigned right shift `int 2` by `int 1` -> `int 1`;
  294. store `int 1` to `i`;
  295. (note this is equivalent to `i = i>>>1`)
  296. <10> load from `i` -> `int 1`;
  297. bitwise and `int 1` and `int 15` -> `int 1`;
  298. store `int 1` to `i`;
  299. (note this is equivalent to `i = i&2`)
  300. <11> load from `i` -> `int 1`;
  301. bitwise xor `int 1` and `int 12` -> `int 13`;
  302. store `int 13` to `i`;
  303. (note this is equivalent to `i = i^2`)
  304. <12> load from `i` -> `int 13`;
  305. bitwise or `int 13` and `int 2` -> `int 15`;
  306. store `int 15` to `i`;
  307. (note this is equivalent to `i = i|2`)
  308. +
  309. * Compound assignment for each boolean operator.
  310. +
  311. [source,Painless]
  312. ----
  313. <1> boolean b = true;
  314. <2> b &= false;
  315. <3> b ^= false;
  316. <4> b |= true;
  317. ----
  318. +
  319. <1> declare `boolean b`;
  320. store `boolean true` in `b`;
  321. <2> load from `b` -> `boolean true`;
  322. boolean and `boolean true` and `boolean false` -> `boolean false`;
  323. store `boolean false` to `b`;
  324. (note this is equivalent to `b = b && false`)
  325. <3> load from `b` -> `boolean false`;
  326. boolean xor `boolean false` and `boolean false` -> `boolean false`;
  327. store `boolean false` to `b`;
  328. (note this is equivalent to `b = b ^ false`)
  329. <4> load from `b` -> `boolean true`;
  330. boolean or `boolean false` and `boolean true` -> `boolean true`;
  331. store `boolean true` to `b`;
  332. (note this is equivalent to `b = b || true`)
  333. +
  334. * A compound assignment with the string concatenation operator.
  335. +
  336. [source,Painless]
  337. ----
  338. <1> String s = 'compound';
  339. <2> s += ' assignment';
  340. ----
  341. <1> declare `String s`;
  342. store `String 'compound'` to `s`;
  343. <2> load from `s` -> `String 'compound'`;
  344. string concat `String 'compound'` and `String ' assignment''`
  345. -> `String 'compound assignment'`;
  346. store `String 'compound assignment'` to `s`;
  347. (note this is equivalent to `s = s + ' assignment'`)
  348. +
  349. * A compound assignment with the `def` type.
  350. +
  351. [source,Painless]
  352. ----
  353. <1> def x = 1;
  354. <2> x += 2;
  355. ----
  356. <1> declare `def x`;
  357. implicit cast `int 1` to `def`;
  358. store `def` to `x`;
  359. <2> load from `x` -> `def`;
  360. implicit cast `def` to `int 1` -> `int 1`;
  361. add `int 1` and `int 2` -> `int 3`;
  362. implicit cast `int 3` to `def` -> `def`;
  363. store `def` to `x`;
  364. (note this is equivalent to `x = x+2`)
  365. +
  366. * A compound assignment with an extra implicit cast.
  367. +
  368. [source,Painless]
  369. ----
  370. <1> byte b = 1;
  371. <2> b += 2;
  372. ----
  373. <1> declare `byte b`;
  374. store `byte 1` to `x`;
  375. <2> load from `x` -> `byte 1`;
  376. implicit cast `byte 1 to `int 1` -> `int 1`;
  377. add `int 1` and `int 2` -> `int 3`;
  378. implicit cast `int 3` to `byte 3` -> `byte 3`;
  379. store `byte 3` to `b`;
  380. (note this is equivalent to `b = b+2`)