This section lists all literals available in Basic Storm. Unless otherwise noted, literals generally produce code that simply loads the literal into a machine register, and are cheap to use.


Booleans are denoted by the literal true or false in the source code. They evaluate to the type core:Bool in the standard library.


Integer literals are written using the digits 0 to 9 in base 10. Integer literals have the type core:Long by default, but they may be implicitly casted to any integer type as long as the number is small enough to fit the desired type.

Integer literals may be suffixed to explicitly determine the type of the variable. The letter of the suffix is the first letter of the corresponding built-in type, as follows:

void literals() {
    Byte b = 10b;
    Int  i = 10i;
    Nat  n = 10n;
    Long l = 10l;
    Word w = 10w;

Hexadecimal literals are also supported. In contrast to integer literals, they are treated as unsigned numbers, but they can of course be casted to signed numbers manually if desired. Similarly to integer literals, hexadecimal literals may be suffixed to indicate their desired type. However, to avoid ambiguity, an underscore is required before the suffix:

void literals() {
    Nat  any = 0x0129A;
    Byte b   = 0xFE_b;
    Nat  n   = 0xFEFF_n;
    Word w   = 0xFEFF_w;

Floating Point Numbers

Floating point numbers are written in base 10, and are written using a dot (.) as the decimal point. Scientific form is currently not supported. Floating point numbers are of the type core:Float by default, but can be implicitly casted to core:Double. Similarly to integer literals, floating point literals may be suffixed to indicate their type.

void literals() {
    Double a = 1;
    Double b = 1.2;
    Float  c = 1.2;
    Float  d = 1f;
    Float  e = 1.2f;
    Double f = 1d;
    Double g = 1.2d;


String literals are enclosed in double quotes ("). A string literal has the type core:Str. Since strings are immutable, Basic Storm creates an instance of a Str at compile time, and simply loads the same instance of the string each time the string literal is evaluated.

Characters in strings may be escaped by a backslash (\). This allows having strings that contain double quotes, or nonprintable characters. Supported escape characters are as follows:

Interpolated Strings

Basic Storm supports interpolated strings inside string literals. This makes it convenient to format values as text. Variables are embedded as follows: ${<expr>}, where <expr> is an arbitrary Basic Storm expression. Because of this, it is typically necessary to escape the $ character in string literals as well.

When a string literal contains a ${}, Basic Storm needs to create the string at runtime. As such, using interpolated strings are associated with a run time cost. Interpolated strings are automatically transformed to code that creates a string buffer (core:StrBuf), and appends the interpolated values to it. As such, while it is not free to use interpolated strings, it Basic Storm aims to make it as cheap as possible.

The syntax also supports formatting strings. Formatting can be specified by adding a comma followed by formatting options. The supported options are as follows:

Formatting options are evaluated left to right. In case some options override others, the last one will be visible.

As an example, it is possible to format strings into a table as follows:

void format(Str[] names) {
    for (k, v in names)
        print("${k,4}: ${v,10}");

Or to pad numbers with zeros like this:

Str leftPad(Int number) {
    "${number,f05}"; // returns 00123 when number = 123.

Additional options can be added by extending the rule lang:bs:SIntFmt.


Character literals are written using single quotes ('). They need to contain exactly one codepoint. The codepoint may be expressed using escape sequences, like the ones used in string literals. Character literals evaluate to the type core:Char.


Array literals are written in square brackets ([]), and with elements separated by commas. The array literals evaluate to the type core:Array<T>, where the type T is inferred automatically from the elements and the context when possible. If automatic inference is not possible, one may specify the type of the array by prepending the type before the literal followed by a colon, like: Int:[1, 2, 3].

Since arrays are not immutable, evaluating an array literal creates a new copy of the array each time.

For example, one may create an array as follows:

Int[] createArray(Int a, Int b) {
    return [a, b, 10];


Literals may be followed by a unit to convert it into an appropriate type. The units available are:

The literals are specified in the rule lang:bs:SUnit.