2.2. Lexical Structure

2.2.1. Identifiers

Identifiers start with an alphabetic character or an underscore (_), followed by any number of alphabetic characters, underscores, digits (09), or backticks (````). Daslang is a case-sensitive language, meaning that foo, Foo, and fOo are three distinct identifiers.

Backticks are used in system-generated identifiers (such as mangled names) and are generally not used in user code:

my_variable     // valid
_temp           // valid
player2         // valid

2.2.2. Keywords

The following words are reserved as keywords and cannot be used as identifiers:

struct

class

let

def

while

if

static_if

else

for

recover

true

false

new

typeinfo

type

in

is

as

elif

static_elif

array

return

null

break

try

options

table

expect

const

require

operator

enum

finally

delete

deref

aka

typedef

with

cast

override

abstract

upcast

iterator

var

addr

continue

where

pass

reinterpret

module

public

label

goto

implicit

shared

private

smart_ptr

generator

yield

unsafe

assume

explicit

sealed

static

inscope

fixed_array

typedecl

capture

default

uninitialized

template

The following words are reserved as built-in type names and cannot be used as identifiers:

bool

void

string

auto

int

int2

int3

int4

uint

bitfield

uint2

uint3

uint4

float

float2

float3

float4

range

urange

block

int64

uint64

double

function

lambda

int8

uint8

int16

uint16

tuple

variant

range64

urange64

Keywords and types are covered in detail in subsequent sections of this documentation. Linked keywords above lead to their relevant documentation pages.

2.2.3. Operators

Daslang recognizes the following operators:

+=

-=

/=

*=

%=

|=

^=

<<

>>

++

--

<=

<<=

>>=

>=

==

!=

->

<-

??

?.

?[

<|

|>

:=

<<<

>>>

<<<=

>>>=

=>

+

@@

-

*

/

%

&

|

^

>

<

!

~

&&

||

^^

&&=

||=

^^=

..

Notable operators unique to Daslang:

  • <- — move assignment

  • := — clone assignment

  • ?? — null coalescing

  • ?. and ?[ — null-safe navigation

  • <| and |> — pipe operators

  • @@ — function pointer / local function

  • <<< and >>> — bit rotation

  • ^^ — logical exclusive or

  • .. — interval (range creation)

  • => — tuple construction (a => b creates tuple<auto,auto>(a, b); also used in table literals)

2.2.4. Other Tokens

Other significant tokens are:

{

}

[

]

.

:

::

'

;

"

@

$

#

2.2.5. Literals

Daslang accepts integer numbers, unsigned integers, floating-point and double-precision numbers, and string literals.

2.2.5.1. Numeric Literals

34

Integer (base 10)

0xFF00A120

Unsigned integer (base 16)

075

Unsigned integer (base 8)

13l

64-bit integer (base 10)

0xFF00A120ul

64-bit unsigned integer (base 16)

32u8

8-bit unsigned integer

'a'

Character literal (integer value)

1.52

Floating-point number

1.0f

Floating-point number (explicit suffix)

1.e2

Floating-point number (scientific)

1.e-2

Floating-point number (scientific)

1.52d

Double-precision number

1.e2lf

Double-precision number

1.e-2d

Double-precision number

Integer suffixes:

  • u or U — unsigned 32-bit integer

  • l or L — signed 64-bit integer

  • ul or UL — unsigned 64-bit integer

  • u8 or U8 — unsigned 8-bit integer

Float suffixes:

  • f (or no suffix after a decimal point) — 32-bit float

  • d, lf — 64-bit double

2.2.5.2. String Literals

Strings are delimited by double quotation marks ("). They support escape sequences and string interpolation:

"I'm a string\n"

Escape sequences:

\t

Tab

\n

Newline

\r

Carriage return

\\

Backslash

\"

Double quote

\'

Single quote

\0

Null character

\a

Bell

\b

Backspace

\f

Form feed

\v

Vertical tab

\xHH

Hexadecimal byte

\uHHHH

Unicode code point (16-bit)

\UHHHHHHHH

Unicode code point (32-bit)

Multiline strings:

Strings can span multiple lines. The content includes all characters between the quotes:

let msg = "This is
    a multi-line
        string"

String interpolation:

Expressions enclosed in curly brackets {} inside a string are evaluated and their results are inserted into the string:

let name = "world"
let greeting = "Hello, {name}!"         // "Hello, world!"
let result = "2 + 2 = {2 + 2}"         // "2 + 2 = 4"

To include literal curly brackets in a string, escape them with a backslash:

print("Use \{braces\} for interpolation")   // prints: Use {braces} for interpolation

Format specifiers:

String interpolation supports optional format specifiers after a colon:

let pi = 3.14159
print("{pi:5.2f}")         // formatted output

(see String Builder for more details on string interpolation).

2.2.6. Comments

A comment is text that the compiler ignores but is useful for programmers.

Block comments start with /* and end with */. Block comments can span multiple lines and can be nested:

/*
This is a multiline comment.
/* This is a nested comment. */
These lines are all ignored by the compiler.
*/

Line comments start with // and extend to the end of the line:

// This is a single-line comment.
var x = 42  // This is also a comment.

2.2.7. Automatic Semicolons

Daslang automatically inserts semicolons at the end of lines when the code is enclosed in curly braces, unless the line is also inside parentheses or brackets:

def foo {
    var a = 0       // semicolon inserted automatically
    var b = 1;      // explicit semicolon (redundant but valid)
    var c = ( 1     // no automatic semicolon here (inside parentheses)
        + 2 ) * 3   // semicolon inserted after the closing parenthesis
}

This means that expressions can be split across multiple lines when parentheses or brackets keep them together:

let result = (
    some_long_function_name(arg1, arg2)
    + another_value
)