expression
paren_expression suffix
literal suffix
name suffix
'@'
suffix
open_expression
paren_expression open_suffix
literal open_suffix
name open_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 intrinsic functions instead.
Parentheses can be used to explicitly control the order of evaluation of expressions.
paren_expression
'('
paren_filler ')'
paren_filler expression indent open_expression optional_ternary outdent
optional_ternary
""
ternary
ternary
linebreak "then"
space expression linebreak "else"
space 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 disrupts. Expressions that are indented within parens may contain line breaks before an infix operator. Ternary operation is not allowed if a variable is in scope named then
or else
.
suffix
""
selection suffix
subscript suffix
invocation suffix
space infix_operator space expression
open_suffix
""
selection open_suffix
subscript open_suffix
invocation open_suffix
separation infix_operator space open_expression
separation space linebreak
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
subscript
'['
subscript_filler ']'
subscript_filler
""
expression
indent open_expression outdent
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 disrupts 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 disrupts.
stooge["first_name"][4] # "y" null["foo"] # null "foo"[0] # "f" "foo"[3] # null
invocation argument_list record_literal
argument_list
'('
arguments ')'
arguments
""
expression closed_arguments
indent open_expression arguments_or_ternary outdent
closed_arguments
""
','
space expression closed_arguments
arguments_or_ternary ternary open_arguments
open_arguments
""
open_expression open_arguments
Invocation. The ()
suffix operator invokes a function value.
function_value
(
arguments)
If the value is not function, it disrupts.
If a function is invoked with too few arguments, the missing arguments are null
.
If a function is invoked with excess arguments, there is a distruption.
A function invocation can pass at most 4 arguments. If you need more, consider passing a single record literal instead.
If a function is used only for its side effects, use the call
statement.
infix_operator
'*'
'/'
'÷'
'+'
'-'
'~'
'≈'
'='
'<>'
'<'
'<='
'>'
'>='
'/'
optional_backslash
'\'
'/'
'|'
optional_backslash
""
'\'
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
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
Integer division.
3 ÷ 4 # 0 5 ÷ 4 # 1 16 ÷ 4 # 4 0 ÷ 0 # 0 0 ÷ null # 0 3 ÷ 0 # null
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
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 disrupts.
3 ~ 4 # "34" "beginning" ~ "and" ~ "end" # "beginningandend" "" ~ "ok" # "ok" null ~ "ok" # disrupt "" ~ null # disrupt
Concatenation with a space. If the two operands are not texts after number conversion, then it disrupts. 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" # disrupt "" ≈ null # disrupt "brillig" ≈ "" # "brillig"
The relational operators compare two values and return either true
or false
.
The =
equal and <>
not equal operators can take values of all types. Objects are equal only if they are the same object. Texts containing the same characters in the same order are equal.
The <
less than<=
less than or equal >
greater than >=
greater than or equal operators only work on a pair of numbers or a pair of texts.
In all other cases they disrupt.
Equal. If the operands are the same then the result is true
.
Examples:
if variable = "cat" # compute result if the variable is "cat" assign result: 10 = "10" # result is false fi
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.
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 disrupt.
If the left operand is not false
or true
, then it disrupts.
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 disrupts. If the left operand is false
and the right operand is not a logical, then it disrupts.
3 < 4 \/ 6 < 5 # true
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
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"