Literals

Literals are fixed values written directly in source code – such as numbers, strings, or booleans.

Bool

True, False are Bool,
uppercase as they are constants (as in Python).

Integer

123 is an integer literal of arbitrary precision.

Typical integer literals like 123456 are interpreted as Int, in case of type inferring, parameter overloading and template matching.

Big integer literals are interpreted as Int64, Int128, Int256, BigInt, if required due to the size.

Integer literals can automatically be converted to other sizes than Int64, but only if the converted-to-type can contain the value of the literal (i.e. as long as there is no loss of information).

So positive integer literals up to a certain size can implicitly be used as Int8/16/32/64/128/256 (i.e. signed):

Negative integer literals down to a certain size can implicitly be used as Int8/16/32/64/128/256:

Positive integer literals up to a certain size can implicitly be used as UInt8/16/32/64/128/256:

Examples:

Storage
Constexpr constructor that accepts an arbitrary precision integer literal and can store that in ROM. Should be stored as array of Int/UInt.

Suffixes/postfixes to write integer literals of a certain size:

Hex, Octal, Binary

Hexadecimal, octal, and binary literals are unsigned integers (e.g. UInt), as usually you want to describe flags, bit masks, hardware registers, hardware addresses, or color values, where signed integer doesn’t fit.

As unsigned integer literals up to a certain size can implicitly be converted to Int (i.e. signed), usually it is also possible to give a hex literal as an Int argument:

Otherwise you have to explicitly cast it like
Int mostNegativeInt = Int(0x8000000000000000).

Int vs. Bool

Int a = True is an error,

Bool a = 1 is an error,

Floating-Point

1.0 is a floating-point literal.

A plain float literal like 1.0 is a Float (AKA Float64). This way the precision is the same as in C++, but there 1.0 is called a double and 1.0f is called a single float.

A floating-point literal can be implicitly converted to a smaller floating-point type if and only if the conversion is exact/lossless.
This is surely true for integers up to a certain size (but not limited to those):

Note
0.1 as Float64 has the significand 1001100110011001100110011001100110011001100110011010, so this can not implicitly be converted to Float32 or Float16.

Floating-point literals are interpreted according to the size/precision requirements. Counting the significant digits plus the trailing zeros after them (including those after the decimal point), the rules are:

So to explicitly write float literals with a certain precision (e.g. Float128/Float256/BigFloat), you may add trailing zeros: 0.1000000000000000…
Or use postfixes:
0.1f16, 0.1f32, 0.1f64, 0.1f128, 0.1f256 (as in Rust)

To reduce the precision, you need to downcast explicitly:

Float   pi64 = 3.1415926535897
Float16 pi16 = Float16(pi)

Storage
Constexpr constructor that accepts an arbitrary precision float literal and can store that in ROM. Store the mantissa as arbitrary precision integer (i.e. array of Int), plus the exponent as arbitrary precision integer (i.e. array of Int, most always only a single Int)

Infinity/-Infinity is a Float literal for infinity values, that can be converted to any float type.

NaN is a Float literal for NaN (“not a number”) values, that can be converted to any float type.

String

"Text" is a StringView with UTF-8 encoding.

Without null termination. If necessary use "Text"sz, "Text\0", or convert using StringZ("Text").

Data is typically stored in read-only data segments (“.rodata”) or ROM.

A Cilia-to-C++-transpiler would translate every string literal to a C++ string_view-literal:
"Text" -> u8"Text"sv
("..."sv as to avoid null termination, and u8"..." as to have UTF-8 encoding.)

Multiline String Literal

Use triple double-quotes """ to start and end the literal.
Similar to Swift, Julia, Java 15, C# 11, …

"""
First line
Second line
"""

Also as single line string literal with very few restrictions, good for RegEx:
"""(.* )whatever(.*)"""

If the opening """ is followed by a newline, that newline is not part of the string content. This allows the content to start cleanly on the next line.

The position of the closing """ defines the indentation guide. If the closing """ is on its own line:

Trailing whitespace at the end of lines is preserved.

To include """ within the string content, the literal can be opened and closed with more than three double-quotes (e.g., """"). The closing delimiter must match the number of quotes used for the opening delimiter. This eliminates the need for escape backslashes within the literal, ensuring truly “raw” content.

Interpolated Strings

Like f-strings in Python:
f"M[{i},{j}] = {M[i, j]}"

Curly braces ({}) are used in std::format already.
f as in format.

TODO
Any reason to use/prefer any other syntax?
Maybe $"M[{i},{j}] = {M[i, j]}" like in C#?

Alternative String Literals

Prefixes as in C++:

No u8"..." and no u8'...' for UTF-8, as that is the default in Cilia.

Maybe a"..." for ASCII and l"..." for Latin-1.

User defined string suffixes as in C++:

No "..."sv for std::string_view, as that is the default in Cilia.

"..."sz for null terminated strings. Type of "..."sz is Char*, while "...\0" is a StringView of a zero terminated string.

All these available for multiline string literals and interpolated strings, too.

TODO
Any reason, not to?

Char

' ' is a character literal.

Array

[1, 2, 3] is an array (here an Int[3]),
all elements have the same type.

Initialization List

{1, "Text", 3.0} is an initialization list, e.g. for Tuple or Pair.

Associative Array

[ 1: "one", 2: "two", 3: "three", 4: "four" ] is a String[Int] (AKA Map<Int, String>).

String[Int] keywords = [
    1: "one"
    2: "two"
    3: "three"
    4: "four"
]
ContactInfo[String] contactInfoForID = [
    "John Doe": {"John", "Doe", "03465 452634"}
    "Jane Doe": {"Jane", "Doe", "03245 687534"}
]

Misc

NullPtr is the null pointer,
it is of the type NullPtrType,
explicit cast necessary to convert any pointer to Int.

User Defined Literals with the same rules as in C++.