# Operators PetaPerl implements the full set of Perl 5 operators with identical semantics. All operators maintain Perl's context sensitivity and precedence rules. ## Binary Operators ### Arithmetic | Operator | Operation | Example | |----------|-----------|---------| | `+` | Addition | `$a + $b` | | `-` | Subtraction | `$a - $b` | | `*` | Multiplication | `$a * $b` | | `/` | Division | `$a / $b` | | `%` | Modulus | `$a % $b` | | `**` | Exponentiation | `$a ** $b` | All arithmetic operators coerce operands to numeric context. Division by zero produces a warning and returns infinity or NaN. ```perl my $x = 5 + 3; # 8 my $y = 10 / 3; # 3.333... my $z = 2 ** 10; # 1024 my $m = 17 % 5; # 2 ``` ### String | Operator | Operation | Example | |----------|-----------|---------| | `.` | Concatenation | `$a . $b` | | `x` | Repetition | `$str x $count` | String operators coerce operands to string context. ```perl my $str = "Hello" . " " . "World"; # "Hello World" my $rep = "X" x 5; # "XXXXX" my $pad = " " x 10; # 10 spaces ``` ### Numeric Comparison | Operator | Operation | Returns | |----------|-----------|---------| | `==` | Equal | True if equal | | `!=` | Not equal | True if not equal | | `<` | Less than | True if less | | `>` | Greater than | True if greater | | `<=` | Less or equal | True if ≤ | | `>=` | Greater or equal | True if ≥ | | `<=>` | Three-way compare | -1, 0, or 1 | Numeric comparisons coerce operands to numbers. ```perl if ($age >= 18) { ... } my $cmp = $a <=> $b; # -1 if $a < $b, 0 if equal, 1 if $a > $b ``` ### String Comparison | Operator | Operation | Returns | |----------|-----------|---------| | `eq` | Equal | True if equal | | `ne` | Not equal | True if not equal | | `lt` | Less than | True if less | | `gt` | Greater than | True if greater | | `le` | Less or equal | True if ≤ | | `ge` | Greater or equal | True if ≥ | | `cmp` | Three-way compare | -1, 0, or 1 | String comparisons use lexicographic (dictionary) ordering. ```perl if ($name eq "John") { ... } my $cmp = $a cmp $b; # -1, 0, or 1 ``` ### Logical | Operator | Operation | Short-circuits | Precedence | |----------|-----------|----------------|------------| | `&&` | And | Yes | High | | `||` | Or | Yes | High | | `//` | Defined-or | Yes | High | | `and` | And | Yes | Low | | `or` | Or | Yes | Low | | `xor` | Exclusive or | No | Low | Logical operators return the last evaluated value, not just true/false. ```perl my $result = $x && $y; # Returns $y if $x true, else $x my $default = $user || "guest"; # Returns "guest" if $user false my $value = $config // 0; # Returns 0 only if $config undefined ``` **Defined-or (`//`)**: Unlike `||`, this only checks if the left side is **defined**, not just true. `0` and `""` are both false but defined. ```perl my $x = 0; my $a = $x || 10; # 10 (0 is false) my $b = $x // 10; # 0 (0 is defined) ``` ### Bitwise | Operator | Operation | Example | |----------|-----------|---------| | `&` | Bitwise AND | `$a & $b` | | `|` | Bitwise OR | `$a | $b` | | `^` | Bitwise XOR | `$a ^ $b` | | `<<` | Left shift | `$a << $n` | | `>>` | Right shift | `$a >> $n` | Bitwise operators work on integers. Operands are converted to unsigned integers. ```perl my $mask = 0xFF & $value; my $flags = $READ | $WRITE; my $double = $x << 1; ``` ### Range | Operator | Operation | Context | |----------|-----------|---------| | `..` | Inclusive range | List context creates list | | `...` | Flip-flop | Scalar context is stateful | ```perl my @digits = (0..9); # (0, 1, 2, ..., 9) my @letters = ('a'..'z'); # ('a', 'b', ..., 'z') for my $i (1..100) { ... } # Loop 1 to 100 ``` In scalar context, `..` and `...` are flip-flop operators (stateful boolean range). ### Binding | Operator | Operation | Example | |----------|-----------|---------| | `=~` | Match | `$str =~ /pattern/` | | `!~` | Not match | `$str !~ /pattern/` | Binding operators connect strings with regex operations. ```perl if ($email =~ /\@/) { ... } # Contains @ if ($name !~ /^\d/) { ... } # Doesn't start with digit ``` ## Unary Operators ### Arithmetic | Operator | Operation | Example | |----------|-----------|---------| | `-` | Negation | `-$x` | | `+` | Unary plus | `+$x` | ```perl my $neg = -5; my $pos = +$x; # Numeric context ``` ### Logical | Operator | Operation | Example | |----------|-----------|---------| | `!` | Not | `!$x` | | `not` | Not (low precedence) | `not $x` | ```perl if (!$error) { ... } die "Failed" if not $ok; ``` ### Bitwise | Operator | Operation | Example | |----------|-----------|---------| | `~` | Bitwise complement | `~$x` | ```perl my $inverted = ~$bits; ``` ### Reference | Operator | Operation | Example | |----------|-----------|---------| | `\` | Create reference | `\$x`, `\@arr`, `\%hash` | ```perl my $scalar_ref = \$value; my $array_ref = \@data; my $hash_ref = \%config; ``` ### Increment/Decrement | Operator | Operation | When evaluated | |----------|-----------|----------------| | `++$x` | Pre-increment | After increment | | `--$x` | Pre-decrement | After decrement | | `$x++` | Post-increment | Before increment | | `$x--` | Post-decrement | Before decrement | ```perl my $x = 5; my $a = ++$x; # $x is 6, $a is 6 my $b = $x++; # $x is 7, $b is 6 ``` **String increment**: `++` on strings performs "magic increment" (Perl-style). ```perl my $s = "aa"; $s++; # "ab" $s++; # "ac" ``` ### File Test Operators File test operators check properties of files and filehandles. All return true/false except `-s` which returns file size. | Operator | Test | Returns | |----------|------|---------| | `-e` | Exists | Boolean | | `-r` | Readable | Boolean | | `-w` | Writable | Boolean | | `-x` | Executable | Boolean | | `-o` | Owned by effective UID | Boolean | | `-R` | Readable by real UID | Boolean | | `-W` | Writable by real UID | Boolean | | `-X` | Executable by real UID | Boolean | | `-O` | Owned by real UID | Boolean | | `-z` | Zero size | Boolean | | `-s` | Non-zero size | Size in bytes or false | | `-f` | Regular file | Boolean | | `-d` | Directory | Boolean | | `-l` | Symbolic link | Boolean | | `-p` | Named pipe (FIFO) | Boolean | | `-S` | Socket | Boolean | | `-b` | Block special file | Boolean | | `-c` | Character special file | Boolean | | `-t` | TTY (terminal) | Boolean | | `-u` | Setuid bit set | Boolean | | `-g` | Setgid bit set | Boolean | | `-k` | Sticky bit set | Boolean | | `-T` | Text file | Boolean | | `-B` | Binary file | Boolean | | `-M` | Modification time (days) | Number | | `-A` | Access time (days) | Number | | `-C` | Inode change time (days) | Number | ```perl if (-e $file) { ... } # File exists if (-f $path && -r $path) { ... } # Regular file and readable my $size = -s $file; # Size in bytes if (-d $path) { ... } # Is directory ``` **Stacked file tests**: `-f -w -r $file` checks all three conditions. ### Other Unary Operators | Operator | Operation | Example | |----------|-----------|---------| | `defined` | Check if defined | `defined $x` | ```perl if (defined $value) { ... } ``` ## Assignment Operators ### Simple Assignment | Operator | Operation | Example | |----------|-----------|---------| | `=` | Assignment | `$x = 5` | ```perl my $x = 10; my ($a, $b, $c) = (1, 2, 3); # List assignment ``` ### Compound Assignment All binary operators have compound assignment forms: | Operator | Equivalent | Example | |----------|------------|---------| | `+=` | `$x = $x + $y` | `$x += 5` | | `-=` | `$x = $x - $y` | `$x -= 3` | | `*=` | `$x = $x * $y` | `$x *= 2` | | `/=` | `$x = $x / $y` | `$x /= 10` | | `%=` | `$x = $x % $y` | `$x %= 7` | | `**=` | `$x = $x ** $y` | `$x **= 2` | | `.=` | `$x = $x . $y` | `$str .= "more"` | | `x=` | `$x = $x x $y` | `$str x= 3` | | `&=` | `$x = $x & $y` | `$bits &= $mask` | | `|=` | `$x = $x | $y` | `$flags |= $BIT` | | `^=` | `$x = $x ^ $y` | `$x ^= $y` | | `<<=` | `$x = $x << $y` | `$x <<= 2` | | `>>=` | `$x = $x >> $y` | `$x >>= 1` | | `&&=` | `$x = $x && $y` | `$x &&= $default` | | `||=` | `$x = $x || $y` | `$cache ||= compute()` | | `//=` | `$x = $x // $y` | `$x //= 0` | ```perl my $count = 10; $count += 5; # 15 $count *= 2; # 30 my $path = "/home"; $path .= "/user"; # "/home/user" $cache ||= load_data(); # Only load if $cache is false $config //= {}; # Only assign if $config is undef ``` ## Ternary Operator | Operator | Syntax | Example | |----------|--------|---------| | `? :` | Conditional | `$cond ? $then : $else` | ```perl my $result = $x > 0 ? "positive" : "non-positive"; my $max = $a > $b ? $a : $b; ``` **Ternary as lvalue**: The ternary operator can be used as an assignment target. ```perl ($x > 0 ? $pos : $neg) = 10; # Assigns to $pos or $neg ``` ## Array/Hash Subscripts | Syntax | Operation | Example | |--------|-----------|---------| | `$arr[index]` | Array element access | `$arr[0]` | | `$hash{key}` | Hash element access | `$hash{name}` | | `@arr[indices]` | Array slice | `@arr[1, 3, 5]` | | `@hash{keys}` | Hash slice | `@hash{qw(a b c)}` | ```perl my $first = $arr[0]; my $value = $hash{key}; my @subset = @arr[0, 2, 4]; # Elements 0, 2, 4 my @values = @hash{'a', 'b'}; # Values for keys 'a', 'b' ``` ## Arrow Operator | Syntax | Operation | Example | |--------|-----------|---------| | `->[]` | Array deref subscript | `$aref->[0]` | | `->{}` | Hash deref subscript | `$href->{key}` | | `->()` | Method call | `$obj->method()` | ```perl my $element = $array_ref->[5]; my $value = $hash_ref->{name}; my $result = $object->method(@args); ``` ## Comma Operators | Operator | Operation | Use | |----------|-----------|-----| | `,` | List separator | `(1, 2, 3)` | | `=>` | Fat comma | `key => value` | The fat comma (`=>`) autoquotes barewords on its left side. ```perl my %hash = ( name => "John", # 'name' autoquoted age => 30, ); ``` ## Operator Precedence Highest to lowest precedence (same as Perl 5): 1. Terms and list operators (left) 2. `->` (left) 3. `++` `--` (none) 4. `**` (right) 5. `!` `~` `\` unary `+` unary `-` (right) 6. `=~` `!~` (left) 7. `*` `/` `%` `x` (left) 8. `+` `-` `.` (left) 9. `<<` `>>` (left) 10. Named unary operators 11. `<` `>` `<=` `>=` `lt` `gt` `le` `ge` (none) 12. `==` `!=` `<=>` `eq` `ne` `cmp` `~~` (none) — `~~` smart match is partial 13. `&` (left) 14. `|` `^` (left) 15. `&&` (left) 16. `||` `//` (left) 17. `..` `...` (none) 18. `?:` (right) 19. `=` `+=` `-=` etc. (right) 20. `,` `=>` (left) 21. List operators (right) 22. `not` (right) 23. `and` (left) 24. `or` `xor` (left) Use parentheses when precedence is unclear. ### Named unary operators Row 10 above ("named unary operators") refers to built-ins that take **exactly one argument** and sit at a specific precedence: tighter than the comparison operators (`<`, `>=`, `==`, `eq`, …) but looser than the arithmetic and shift operators. The practical consequence is the parsing rule > a named unary operator grabs its **one** argument greedily, and > anything that would need more than one argument is not part of it. So `defined $x + 1` parses as `defined($x) + 1`, not as `defined($x + 1)`. This distinguishes them from **list operators** (`print`, `sort`, `push`, …), which are at row 1/21 and slurp the rest of the expression. The named unary operators include `defined`, `exists`, `ref`, `scalar`, `length`, `uc`, `lc`, `ucfirst`, `lcfirst`, `chr`, `ord`, `hex`, `oct`, `int`, `abs`, `sqrt`, `sin`, `cos`, `log`, `exp`, `rand`, `srand`, `alarm`, `sleep`, `caller`, `wantarray`, `chroot`, `readlink`, `umask`, `lstat`, `stat` (when given one argument), and all the file test operators (`-e`, `-r`, `-f`, `-d`, …). ```perl defined $x + 1 # ( defined($x) ) + 1 — NOT defined($x+1) length $s > 3 # ( length($s) ) > 3 -e $f && -r _ # both file tests take one arg; `&&` combines them print "n=", $n # `print` is a list operator — slurps everything ``` When in doubt, write parentheses: `defined($x + 1)` is unambiguous. ## PetaPerl-Specific Notes ### Parallelization Operators execute sequentially by default. PetaPerl's parallelization applies at the loop/map/grep level, not individual operators. ### Performance - Bitwise operations compile to native machine instructions - String concatenation may allocate new memory (use `.=` for efficiency) - Numeric operations are optimized for integers and floats separately