Skip to content

Types

DQ is statically and strictly typed. Most conversions must be explicit, with a small number of numeric conversions provided for convenience.

For complete rules, use the reference pages for types and conversions, enums, arrays and slices, strings and characters, and anyvalue.

Primitive Types

The common primitive types are:

Type Meaning
bool Boolean value, either true or false
int, uint Signed and unsigned integer with pointer-sized width
int8, int16, int32, int64 Fixed-width signed integers
uint8, uint16, uint32, uint64 Fixed-width unsigned integers
byte Alias for uint8
float32, float64 Floating point types
float Platform-preferred floating point type
char Unsigned 8-bit byte or UTF-8 code unit
char16 Unsigned 16-bit UTF-16 code unit
wchar Unsigned 32-bit Unicode scalar value
pointer Untyped generic pointer
Object Untyped object, compatible with all objects

int and uint have the same width as a pointer. Use fixed-width integer types when binary layout or C ABI details matter.

Boolean Type

bool is distinct from numeric types. Numeric values are not implicitly used as conditions.

var n : int = 1

if n <> 0:
    // ok
endif

Numeric Conversions

Integer values may be converted to floating point values when needed. Other conversions should be written explicitly with type-call syntax.

var i : int = 3
var f : float64 = i
i = Round(f + 1)

Floating point to integer conversions should use the available conversion functions such as Round, Floor, or Ceil where appropriate.

Type Aliases

type creates an alias.

type TFloat = float64
type FCallback = function(value : int) -> int

Type Inference

Variables and constants may request restricted type inference with ? when an initializer independently determines a concrete typed pointer, structure, or object-reference type.

const registers : ? = ^SRegisters(0x40000000)

var value : SPoint = {}
var copy : ? = value
var value_ptr : ? = %value
var object_ref : ? = new OThing()

An inferred declaration always requires =. Integer and floating-point types are not inferred, even from casts or expressions that already have a specific numeric type. Null and raw pointer values also lack an eligible concrete type.

var integer : ? = int32(3) // error: integer inference is forbidden
var real : ? = 3.0         // error: floating-point inference is forbidden
var unknown : ? = null     // error: no concrete pointer type

Other type kinds are not inferred. Write the type explicitly when contextual typing or a deliberate conversion is required. Object inference preserves the initializer's exact static object type rather than selecting a base type.

The same marker is used for fixed array length inference from an array literal; this remains separate from declaration type inference.

var values : [?]int = [1, 2, 3]

Structures

struct defines a value type with fields.

struct SPoint:
    x : int
    y : int
endstruct

Struct values use contextual brace initializers. Values may be positional or named with field: value; every field is required unless a final ? deliberately defaults the unassigned fields. {} defaults the whole value.

var p : SPoint = {}
var q : SPoint = { 10, 20 }
var r : SPoint = { y: 20, x: 10 }
var s : SPoint = { x: 10, ? }

The contextual form works in assignments, calls, returns, arrays, nested structures, and constants. Use SPoint({...}) when an explicit type is needed; an uncast brace literal cannot be used with var value : ? inference. See Structures, Pointers, and Function References for the complete rules.

Struct fields are accessed with ..

p.x = 10
p.y = 20

Pointers to structs are automatically dereferenced for member access.

var pp : ^SPoint = %p
pp.x = 11      // same target as pp^.x

Structs may also have methods. Methods are declared inside the struct or defined outside with a qualified name.

Objects

object defines a reference type with fields, methods, properties, inheritance, constructors, destructors, and virtual dispatch. See Objects.

Enumerations

enum defines a distinct enumeration type.

enum NColor = (red, green, blue)
enum NState : uint8 = (idle = 0, running = 10, stopped = 20)

The storage type must be an integer type. If no storage type is specified, the compiler chooses the default enum storage type.

Enum values are strongly typed. They do not implicitly convert to or from integers, and different enum types are not interchangeable.

var c : NColor = red
var q : NColor = NColor.green

Enum values may be used without qualification when the expected enum type is known from context.

function IsGreen(color : NColor) -> bool:
    return color == green
endfunc

Enums provide ordinal conversion helpers.

var s : NState = NState.FromOrd(10)
var fallback : NState = NState.FromOrd(11, idle)

var out : NState = idle
if NState.TryFromOrd(20, out):
    // out was assigned
endif

FromOrd(value) raises a runtime error if the ordinal is invalid. The overload with a fallback returns the fallback for invalid values. TryFromOrd returns a boolean success flag and writes the output argument when valid.

Fixed Arrays

Fixed arrays are value types with a compile-time length.

var values : [3]int = [1, 2, 3]
var inferred : [?]int = [10, 20, 30]

[?]T infers the fixed array length from the array literal.

Fixed arrays expose a .length property and support indexing and slicing.

Array Literals

Array literals are written with square brackets.

var static_values : [?]int = [1, 2, 3]
var dynamic_values : [*]int = [1, 2, 3]

The expected type determines whether the literal initializes a fixed array, dynamic array, array slice-compatible value, or another supported array-like target.

Dynamic Arrays

Dynamic arrays are written as [*]T.

var values : [*]int = [1, 2, 3]
values.Append(4)

Dynamic arrays expose .length and .capacity, support indexing and slicing, and provide mutation methods such as Append, Prepend, Insert, Delete, Pop, PopFirst, SetLength, SetCapacity, Reserve, Compact, and Clear.

Array Views

Function parameters often use view-style array types such as []T.

function Sum(values : []int) -> int:
    var i : int = 0
    while i < values.length:
        result += values[i]
        i += 1
    endwhile
endfunc

Slices produce view values.

var a : [*]int = [1, 2, 3, 4]
Sum(a[1:3])
Sum(a[:])

Strings

DQ has several text-related types:

Type Meaning
str Dynamic heap-managed string
strview Non-owning string view
cstring(n) Fixed-size zero-terminated C-style string storage
cstring C-style string argument type
^char Pointer to byte-oriented C string data

String and Character Literals

Double-quoted literals are text. Single quotes can also delimit text. Character literals are Unicode scalar values with type wchar; assignment to char is accepted only when the literal value is less than 256.

var text1 : str = "hello"
var text2 : str = 'hello'
var slash_text : str = "/"
var slash_wchar : wchar = '/'
var slash_byte : char = '/'
var euro : wchar = '€'

This matters when comparing text. "/" is a string literal, while '/' is a character literal.

if url == "/":
    // ok: compares text with text
endif

if url == '/':
    // wrong: '/' is wchar, not str/strview/cstring text
endif

Use double quotes for one-character strings when the value is text. Use single quotes for character values. Use char(...) or IntToChar(...) when a byte value is required.

if url[0] == '/':
    // ok when '/' fits in char; string indexing returns char bytes
endif

str is copy-on-write. Assigning a string value shares storage until a value is mutated.

var a : str = "abc"
var b : str = a
b[0] = 'X'      // a remains "abc"

Dynamic strings expose .length and .capacity and provide mutation methods such as Append, Prepend, Insert, Delete, SetLength, Truncate, Pop, PopFirst, Reserve, Compact, Clear, and Clone.

str is a byte string with a hidden trailing zero. .length, indexing, and slicing are byte-based:

var b : char = text[0]
var bytes : str = text[1:4]

Unicode scalar processing is explicit and uses wchar:

var count : int = text.wclen
var wc : wchar = text.wchar[0]
var wchars : [*]wchar = text.ToWchars()
var utf16 : [*]char16 = text.ToUtf16()

Use Ord(ch) to convert char, char16, or wchar values to integers. Integer-to-character casts use char(value), char16(value), or wchar(value). The checked helpers IntToChar(...) and IntToWchar(...) validate runtime values before returning a character value.

Anyvalue

anyvalue can hold values for generic formatting and variable argument style APIs.

var v : anyvalue = 123
var s : str = v.AsStr("")

Arrays of anyvalue are commonly used with formatting functions.

Print("{}: {}", ["answer", 42])

Function Reference Types

Function references are declared with function(...).

type FUnary = function(value : int) -> int

function Inc(value : int) -> int:
    return value + 1
endfunc

var cb : FUnary = Inc
var result : int = cb(10)

Function references can be compared with null.

Object method references use of object.

type FObjText = function(msg : cstring) of object