Basic Expressions

Anyone familiar with other C-like programming languages should feel right at home with Conjure’s basic expression set.

Basic Literals

Conjure supports several literal types for representing fixed values in code. Each of these literals is paired with a specific built-in type and can be found in the pages dedicated to each type.

Arithmetic Operators

Conjure supports standard arithmetic operations.

OperatorDescriptionExample
+Additiona + b
-Subtractiona - b
*Multiplicationa * b
/Divisiona / b
%Modulo (remainder)a % b
var sum       = 10 + 5  // 15
var diff      = 10 - 5  // 5
var product   = 10 * 5  // 50
var quotient  = 10 / 5  // 2
var remainder = 10 % 3  // 1

Bitwise Operators

For low-level bit manipulation.

OperatorDescriptionExample
<<Left shiftx << 2
>>Right shiftx >> 2
&Bitwise ANDa & b
``Bitwise OR
^Bitwise XORa ^ b
~Bitwise NOT~a
var flags u8  = 0b1010
var shifted   = flags << 1   // 0b10100
var masked    = flags & 0b1111 // 0b1010
var inverted  = ~flags       // 0b11110101

Comparison Operators

Comparison operators produce boolean values.

OperatorDescriptionExample
==Equal toa == b
!=Not equal toa != b
<Less thana < b
<=Less than or equala <= b
>Greater thana > b
>=Greater than or equala >= b
var x = 10
var y = 20

if x < y {
    c.printf("x is less than y\n")
}

var isEqual    = x == y  // false
var isNotEqual = x != y  // true

Logical Operators

Logical operators work with boolean values.

OperatorDescriptionExample
andLogical ANDa and b
orLogical ORa or b
notLogical NOT (prefix)not a
!Logical NOT (alternative)!a
var isReady = true
var hasPermission = false

if isReady and hasPermission {
    c.printf("Proceeding...\n")
}

if isReady or hasPermission {
    c.printf("At least one condition is true\n")
}

var isNotReady = not isReady  // false
var stillNotReady = !isReady  // false (alternative syntax)

Short-circuit evaluation: The and and or operators use short-circuit evaluation. In a and b, if a is false, b is never evaluated. In a or b, if a is true, b is never evaluated.

Operator Precedence

Operators are evaluated in the following order (highest to lowest precedence):

  1. Member access (.), indexing ([]), function calls
  2. Unary operators (-, ~, not, !)
  3. Multiplication, division, modulo (*, /, %)
  4. Addition, subtraction (+, -)
  5. Bitwise shifts (<<, >>)
  6. Bitwise AND (&)
  7. Bitwise XOR (^)
  8. Bitwise OR (|)
  9. Comparisons (==, !=, <, <=, >, >=)
  10. Logical AND (and)
  11. Logical OR (or)

Use parentheses to make precedence explicit or override the default order.

var result = (a + b) * c  // add first, then multiply
var compare = (x > 5) and (y < 10)  // clarify intent

Member Access

The . operator accesses members of structs, enums, unions, and even types themselves. Additionally, when working with pointer and reference types, the . operator automatically dereferences the pointer/reference for you.

struct Point {
    x f32
    y f32
}

var p = Point{x: 10.0, y: 20.0}
var xValue = p.x  // 10.0

var ptr = &p
var yValue = ptr.y  // automatically dereferenced, no need for ptr->y

Indexing

Arrays and slices use square brackets for indexing. For multi-dimensional arrays, you can use commas to separate indices or chain multiple brackets.

var numbers = [5]i32{10, 20, 30, 40, 50}
var first = numbers[0]   // 10
var third = numbers[2]   // 30

// Multi-dimensional arrays
var matrix = [3,3]i32{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
}
var center = matrix[1,1]  // 5

Slicing Proposed

When dealing with strings, arrays, slices, and lists, you can extract subarrays using range syntax.

var numbers = [10]i32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

var slice1 = numbers[2..5]   // elements at indices 2, 3, 4, 5
var slice2 = numbers[0...3]  // elements at indices 0, 1, 2
var slice3 = numbers[5..]    // from index 5 to end
var slice4 = numbers[..5]    // from start to index 5