Pointers
Pointer types, address-of operator, and dereferencing in BWSL.
Pressure-test the syntax
Take the concept from this page into the playground and deliberately break a pass, binding, or type signature to see how the compiler responds.
Try a Live EditBWSL provides pointer types for indirect access to memory locations. Unlike traditional C-style pointers, BWSL uses a postfix ^ syntax that keeps pointer operations distinct from bitwise XOR.
Pointer Declaration
Declare a pointer type by appending ^ to the base type:
| Type | Description |
|---|---|
int^ | Pointer to int |
float^ | Pointer to float |
uint^ | Pointer to unsigned int |
bool^ | Pointer to bool |
int x = 42;
int^ ptr = ^x; // ptr points to x
Address-Of Operator
Use the prefix ^ operator to get the address of a variable:
int value = 100;
int^ pointer = ^value; // Get address of 'value'
float f = 3.14;
float^ fptr = ^f; // Get address of 'f'
The address-of operator creates a pointer that references the original variable's memory location.
Dereference Operator
Use the postfix ^ operator to access the value at a pointer's address:
int x = 42;
int^ ptr = ^x;
// Read through pointer
int readValue = ptr^; // readValue is 42
// Write through pointer
ptr^ = 100; // x is now 100
Notice that ^ is used as a prefix for address-of (^x) and as a postfix for dereference (ptr^). This keeps the syntax consistent: the ^ is always adjacent to what it operates on.
Reading and Writing
Pointers enable indirect reads and writes to variables:
int counter = 0;
int^ counterPtr = ^counter;
// Read-modify-write through pointer
counterPtr^ = counterPtr^ + 1; // Increment through pointer
counterPtr^ = counterPtr^ + 1;
counterPtr^ = counterPtr^ + 1;
int finalCount = counter; // finalCount is 3
This is equivalent to directly modifying counter, but allows the modification to happen indirectly.
Pointer Reassignment
Pointers can be reassigned to point to different variables:
int a = 10;
int b = 20;
int^ p = ^a;
int fromA = p^; // fromA is 10
p = ^b; // Reassign pointer to b
int fromB = p^; // fromB is 20
Ensure the pointer is reassigned to a variable of the same type. Assigning a pointer to an incompatible type will result in a compiler error.
Pointers in Expressions
Dereferenced pointers can be used anywhere a value is expected:
int val = 50;
int^ valPtr = ^val;
// Arithmetic with dereferenced values
int sum = valPtr^ + 10; // 60
int diff = valPtr^ - 5; // 45
int prod = valPtr^ * 2; // 100
// Comparison
bool isPositive = valPtr^ > 0;
Pointers vs Bitwise XOR
BWSL uses ^ for both pointers and bitwise XOR, but the context makes the meaning unambiguous:
int xorA = 0b1010;
int xorB = 0b1100;
// Bitwise XOR - binary operator between two values
int xorResult = xorA ^ xorB; // 0b0110 = 6
// Address-of - prefix unary operator
int value = 42;
int^ ptr = ^value; // Pointer to value
// Dereference - postfix unary operator
int read = ptr^; // Read through pointer
| Expression | Meaning |
|---|---|
a ^ b | Bitwise XOR of a and b |
^x | Address of variable x |
ptr^ | Dereference pointer ptr |
When in doubt, remember: prefix ^ takes an address, postfix ^ dereferences, and infix ^ is XOR.
Type Compatibility
Pointer types must match their target types exactly:
int x = 10;
float f = 3.14;
int^ intPtr = ^x; // Valid
float^ floatPtr = ^f; // Valid
// int^ wrongPtr = ^f; // Error: cannot assign float^ to int^
Common Patterns
Choosing a Target
A pointer can pick which local to update once, so the code that follows doesn't need to repeat the branch:
float nearHits = 0.0;
float farHits = 0.0;
float^ bucket = ^nearHits;
if (depth > splitDepth) {
bucket = ^farHits;
}
bucket^ = bucket^ + 1.0; // Updates nearHits or farHits
Updating an Array Element or Field
Take the address of an array element or a struct field to update it in place:
float[4] weights = {0.1, 0.2, 0.3, 0.4};
float^ w = ^weights[2];
w^ = w^ * 2.0; // weights[2] is now 0.6
Pointers and Functions
Function parameters cannot be pointers. A declaration such as swap :: (int^ a, int^ b) is rejected with Pointer-typed function parameters are not supported.
Parameters are passed by value, so assigning to a parameter never changes the caller's variable. To get results out of a helper, do one of these:
- return the value, or a struct holding several values;
- use a mutating method on a struct, which can update its receiver's fields.
struct Counter {
int total;
add :: (int value) -> void {
total = total + value;
}
}
Counter c = Counter(0);
c.add(5);
c.add(10);
// c.total is now 15
Pointer Summary
| Syntax | Name | Description |
|---|---|---|
Type^ | Pointer type | Declares a pointer to Type |
^variable | Address-of | Gets the address of a variable |
pointer^ | Dereference | Accesses the value at the pointer's address |
ptr^ = value | Write through pointer | Assigns a value to the pointed location |
ptr = ^other | Pointer reassignment | Points to a different variable |
See Also
- Operators - Arithmetic, logical, and bitwise operators
- Functions - Parameters and return values
- Language Overview - BWSL syntax and concepts