Operators
Dewy is a 100% expression-based language, meaning everything is formed from small pieces combined together with operators. Dewy has 3 types of operators:
- unary prefix: come before the expression
- binary infix: come between two expressions
- unary postfix: come after the expression
Binary Operators
(TODO: this is missing several operators, and may have some extra ones that are no longer planned)
Basic Math Operations
+
plus-
minus*
multiply/
divide%
modulus^
exponent
logical and bitwise operations
Note: these are logical if both operands are boolean, otherwise they are bitwise and operate on as many bits as the size of the largest operand
and
both are trueor
either are truexor
exactly one is truenot
invert (unary)nand
either is falsenor
both are falsexnor
both are false or both are true
bit-shift operations
<<!
rotate left through carry bit!>>
rotate right through carry bit<<<
rotate left no carry bit>>>
rotate right no carry bit<<
shift left (arithmetic and logical are the same for left-shift)>>
shift right (arithmetic vs logical determined by whether signed or unsigned)
boolean returning operations
=?
equal>?
greater than>=?
greater than or equal<?
less than<=?
less than or equalin?
is a member of
colon operator
:
apply a type annotation
dictionary pointers
->
indicates the left expression points to the right expression in the dictionary
<->
indicates that left is inserted as a key that points to right, and right is inserted as a key that points to left
Function pointer
=>
used for declaring a function literal
handle operator
@
return a handle to the function or variable@?
(probably) check if two references are point to the same thing
Assignment operators
=
binds the righthand expression to the lefthand identifier as a statement (i.e. nothing is returned):=
(walrus operator) same as normal assignment operator, but also returns the righthand side as an expression available for use.
Juxtaposition
(TODO: explain how juxtaposition works)
Unary Prefix Operators
(TODO: prefix operators)
Unary Postfix Operators
(TODO: postfix operators)
In-place Assignment
any of the logical/bitwise operators, as well as the boolean returning operators can be preceeded by not
which will then cause the inverse of the operation to be returned. e.g. not and
is equivalent to nand
, not <?
is equivalent to >=?
, etc.
most binary operators can be appended with an =
sign to make them into an assignment
e.g.
(TODO: This should also probably be able to be combined with element-wise/vectorized .
operations where each element in the list is updated according to the operation (can be done in parallel))
Elementwise Operations
the elementwise operator .
can be prepended to most binary operators to make it be performed on each element in a array or sequence
e.g.
This works if either the either first operand is a list, or the second is a list, or both are lists with the exact same shape
Precedence
Every operator has a precedence level, and an associativity. The precedence level determines the order in which operators in a compound expression are evaluated. Associativity determines the order of evaluation when multiple operators of the same precedence level are present in a compound expression. Associativity can be:
- left-to-right
- right-to-left
- prefix
- postfix
- none (typically these expressions generate a single node in the AST)
- fail (i.e. the expression is invalid if multiple operators of the same precedence level are present)
(TODO: some way of populating this table with the current full precedence table in the code)
(TODO: this table is missing several operators)
Precedence | Symbol | Name | Associativity |
---|---|---|---|
14 | @ | reference | prefix |
13 | . juxtapose juxtapose | access jux-call jux-index | left |
12 | ^ | power | right |
11 | juxtapose | jux-multiply | left |
10 | * / % | multiply divide modulus | left |
9 | + - | add subtract | left |
8 | << >> <<< >>> <<! !>> | left shift right shift rotate right no carry rotate left no carry rotate left with carry rotate right with carry | left |
# | in | in | fail |
7 | =? >? <? >=? <=? | equal greater than less than greater than or equal less than or equal | left |
6 | and nand & | and nand and | left |
5 | xor xnor | xor xnor | left |
4 | or nor | | or nor or | left |
3 | comma | comma | none |
# | juxtapose | jux-range | none |
2 | => | function arrow | right |
1 | = | bind | fail |
0 | else | flow alternate | none |
-1 | space | space | left |
TBD | as | as | TBD |
TBD | transmute | transmute | TBD |
TBD | |> | pipe | TBD |
TBD | <| | reverse pipe | TBD |
TBD | -> | right-pointer | TBD |
TBD | <-> | bi-pointer | TBD |
TBD | <- | left-pointer | TBD |
TBD | : | type annotation | TBD |
multi-operators e.g. 100^/2
for sqrt, or 5+-1
, etc. have a precedence at the level of the first operator in the chain (i.e. all following operators have no effect on the precedence).
Also any instances of elementwise operators (e.g. .+
.=
.xor
etc.) are at the level of precedence as the operator they're attached to. Assignment operators on the other hand are all at the same level, regardless of the type of operator they're attached to (e.g. +=
<?=
<<=
nand=
etc.)