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