Misty Programming Language:

Operators

Expression

expression paren_expression suffix literal suffix name suffix '@' suffix

Expressions are made up of names and literals, fortified by infix (or binary), suffix, and ternary operators. The Misty language does not have prefix operators, using functions instead

Parentheses can be used to explicitly control the order of evaluation of expressions.

Parenthesized Expressions

paren_expression '(' paren_filler ')'

paren_filler expression indent expression ternary outdent

ternary "" then_else

then_else linebreak "then " expression linebreak "else " expression

Expressions can be wrapped in parentheses to clarify or alter the order of evaluation.

A parenthesized expression can also contain a short-circuiting ternary operation. If the first operand is true, then the second operand is evaluated. If the first operand is false, then the third operand is evaluated. If the first operand is neither true nor false, then it fails.

Suffix Operators

suffix "" selection suffix subscript suffix invocation suffix space infix_operator space expression

Refinement

.dot

selection '.' name

Selection. This identifies a field in a value. It is mostly used with records.

stooge.last_name     # "Howard"
stooge.first_name    # "Curly"

Selection is a short form of subscription. If the thing being selected is a text that is a valid identifier, then the selection is an alias.

stooge.last_name = stooge["last_name"]    # true

[ ]brackets

subscript '[' subscript_filler ']'

subscript_filler "" indent expression outdent expression

Subscription. The expression in the brackets selects a field of a record or an element of an array, or a character of a text.

object type subscript type
record text or stone record
array non-negative integer
text non-negative integer

On retrieval, if the record does not contain the key, then null will be returned. On storage, it fails if the record is immutable. On storage to a mutable array, if the key is not a number or if the key violates the bounds of the array, or if the key is not the correct type, then it fails.

stooge["first_name"][4]    # "y"
null["foo"]                # null

Mutable arrays can also retrieve and delete the last element of an array with the empty subscript.

def my_array: ["a", "b"]
my_array[]    # "b"
my_array[]    # "a"
my_array[]    # null

Function Invocation

( )parens

invocation '(' argument_list ')'

argument_list "" spreadable_expression closed_arguments indent expression opener outdent

spreadable_expression expression spreadable

spreadable "" "..."

closed_arguments "" ',' space expression spreadable closed_arguments

opener then_else spreadable open_arguments

open_arguments "" linebreak expression spreadable open_arguments

Invocation. The ( ) suffix operator invokes a function value.

function_value(arguments)

If the value is not function, it fails.

If a function is invoked with too few arguments, the missing arguments are null. If a function is invoked with too many arguments, it fails.

Infix Operators

infix_operator '*' '/' '÷' '%' '+' '-' ">>>" "<<<" '~' '≈' '=' '≠' '<' '≤' '>' '≥' "/\" "\/" '|'

Multiplicitive Operators

*asterisk

Multiplication. If it can be determined at compile time that either operand is zero, the other operand might not be evaluated.

3 * 4        # 12
0.10 * 20    # 2
0 * null     # 0

/solidus

Division.

3 / 4       # 0.75
5 / 4       # 1.25
16 / 4      # 4
0 / 0       # 0
3 / 0       # null
0 / null    # 0
1 / null    # null
null / 4    # null

÷obelus

Integer division.

3 ÷ 4     # 0
5 ÷ 4     # 1
16 ÷ 4    # 4
0 ÷ 0     # 0
3 ÷ 0     # null

%percent

Modulo. The result of

a % b

is

a - (b * floor(a / b))

If a is 0, then the result is 0. If b is 0, or if either operand is not a number, then the result is null. a and b are not required to be integers. The result will have the same sign as b.

3 % 4       # 3
13 % 4      # 1
0 % null    # 0
1 % null    # null
null % 4    # null
1 % 0       # null
0 % 0       # 0

Additive Operators

These operators work only for numbers. If either operand is not a number, or if the operation creates a value that is too majestic to be contained in a Misty number, then the result is null.

+

Addition. If either operand is not a number, the result is null.

3 + 4       # 7
3 + null    # null
null + 0    # null

-

Subtraction. If either operand is not a number, the result is null.

3 - 4       # -1
3 - null    # null

>>>

Maximum. The result is the larger of the two operands. If either operand is not a number, the result is null.

3 >>> 4          # 4

>>> can be used with <<< to constrain values within an acceptable range.

2 >>> 3 <<< 7     # 3
4 >>> 3 <<< 7     # 4
5 >>> 3 <<< 7     # 5
1 >>> null        # null
null >>> 1        # null

To determine if a value lies between two other values, uses relational operators.

if 3 ≤ value ≤ 7
    ...
fi

<<<

Minimum. The result is the smaller of the two operands. If either operand is not a number, the result is null.

3 <<< 4    # 3

Concatenation Operators

~tilde

Concatenation. Make a new text that combines the two texts. If an operand is a number, convert it to text. If after this conversion either operand is not text, then it fails.

3 ~ 4                          # "34"
"beginning" ~ "and" ~ "end"    # "beginningandend"
"" ~ "ok"                      # "ok"
null ~ "ok"                    # fail
"" ~ null                      # fail

double tilde

Concatenation with a space. If the two operands are not texts after number conversion, then it fails. Make a new text that combines the two texts with a space between. If the first operand is "", then the result is the second operand. If the second operand is "", then the result is the first operand.

3 ≈ 4                            # "3 4"
"beginning" ≈ "and" ≈ "end"      # "beginning and end"
"" ≈ "ok"                        # "ok"
null ≈ "ok"                      # fail
"" ≈ null                        # fail
"brillig" ≈ ""                   # "brillig"

Relational Operators

Relational operators can be strung together in useful ways, so that

a = b = c = d

has a similar result to

a = b /\ b = c /\ c = d

=

Equal. If the operands are the same then the result is true.

Examples:

if a = b = null                   # compute result if a and b are both null
    let result: 10 = "10"         # result is false

Not equal. If the operands are not the same, then the result is false.

<

Less than.

If the operands both numbers or both texts, then if the left operand is less than the right operand, then the result is true. If the left operand is greater than or equal to the right operand the result is false.

Less than or equal.

>

Greater than.

Greater than or equal.

Logical Operators

/\

Short-circuit And. If the left operand is false, then the result is false and the right operand will not be evaluated. If the left operand is true and the right operand is false, then the result is false. If the left operand is true and the right operand is true, then the result is true.

If the left operand is true and the right operand is not false or true, then fail. If the left operand is not false or true, then it fails.

3 < 4 /\ 5 < 6    # true

\/

Short-circuit Or. If the left operand is true, then the result is true and the right operand is not evaluated. If the left operand is false and the right operand is false, then the result is false. If the left operand is false and the right operand is true, then the result is true.

If the left operand is not a logical, then it fails. If the left operand is false and the right operand is not a logical, then it fails.

3 < 4 \/ 6 < 5    # true

Default Operator

|

Short-circuit Default. If the left operand is not null, then the result is the left operand. Otherwise, the result is the right operand.

var foo: null    # foo is null
foo | 0          # 0

Operator Precedence

Operator Precedence
highest .   [ ]   ( )
  |
  *   /   ÷   %
  +   -   >>>   <<<
  ~   ≈
  =   ≠   <   >   ≤   ≥
  /\   \/
lowest ( then else )

Operators group left to right. The selection, subscript, and invocation operators have the highest precedence (tightest). The ternary operator has the lowest precedence. Grouping can be made explicit with parens.

"$" ~ 3 + 4    // "$7"