Phase 8: Const Evaluation
Priority: 8 | Duration: ~5 hours (was: 3-4 weeks) | Risk: High
Compile-time computation enables powerful metaprogramming and eliminates runtime overhead. Status: NEARLY COMPLETE — Const declarations, static_assert, const evaluator (all ops), @cImport integration, const functions, const conditionals, and generic struct semantics (G2) all done. Only const generics (G3) and const-in-array-sizes remain.
Prelude: Standards
We accept only world-class solutions.
Const evaluation is a significant undertaking. The implementation must:
- Evaluate expressions at compile time
- Support arithmetic, logic, and function calls
- Provide clear errors for non-const operations
Before writing any code:
- Study Zig’s comptime extensively
- Define clear boundaries for what’s evaluable
- Write tests for each supported operation
- Run
rake quartz:validateafter changes
Rationale
The Problem
Currently, no compile-time computation exists:
# Can't do this
const BUFFER_SIZE = 1024 * 4
const PI = 3.14159265358979
# Can't do this
type Buffer = Array<U8, BUFFER_SIZE>
# Can't do this
const fn is_power_of_two(n: Int): Bool = (n & (n - 1)) == 0
The Benefit
const HEADER_SIZE = 20
const PAYLOAD_SIZE = 1480
const PACKET_SIZE = HEADER_SIZE + PAYLOAD_SIZE # Evaluated at compile time
# Array with compile-time size
type Packet = Array<U8, PACKET_SIZE>
# Compile-time validation
static_assert(PACKET_SIZE <= 1500, "Packet too large for MTU")
Design
Const Declarations
const MAX_SIZE = 1024
const PI = 3.14159
const MESSAGE = "Hello"
Const Functions
const def square(n: Int): Int = n * n
const def is_even(n: Int): Bool = n % 2 == 0
Const Blocks
const {
SIZE = calculate_size()
OFFSET = SIZE + 4
}
Evaluation Rules
| Expression | Const-Evaluable |
|---|---|
| Integer literals | Yes |
| Float literals | Yes |
| String literals | Yes |
| Arithmetic operations | Yes |
| Comparison operations | Yes |
| Logical operations | Yes |
| Const function calls | Yes |
| Conditionals (if/match) | Yes |
| Loops | Yes (bounded) |
| Heap allocation | No |
| I/O operations | No |
| Runtime-only intrinsics | No |
Tasks
8.1 Const Declarations
8.1.1 Parser Support
File: quartz-bootstrap/src/parser.c
const NAME = expression
- Parse
constkeyword before binding - Store is_const flag in binding AST
8.1.2 Type System
- Mark const bindings as compile-time
- Const bindings cannot be reassigned (already const-by-default)
- Const bindings must have const-evaluable initializers
8.2 Const Evaluator
8.2.1 Interpreter Implementation
File: quartz-bootstrap/src/const_eval.c (new file)
Create a compile-time expression evaluator:
typedef struct {
enum { CONST_INT, CONST_FLOAT, CONST_STRING, CONST_BOOL } kind;
union {
int64_t int_val;
double float_val;
const char* string_val;
bool bool_val;
};
} ConstValue;
ConstValue const_eval(Expr* expr);
- Evaluate integer literals
- Evaluate float literals
- Evaluate string literals
- Evaluate boolean literals
8.2.2 Arithmetic Operations
case EXPR_ADD:
ConstValue left = const_eval(expr->left);
ConstValue right = const_eval(expr->right);
return (ConstValue){ .kind = CONST_INT, .int_val = left.int_val + right.int_val };
- Implement add, sub, mul, div, mod
- Implement negation
- Handle overflow (wrap like runtime)
8.2.3 Comparison Operations
- Implement eq, ne, lt, le, gt, ge
- Return CONST_BOOL
8.2.4 Logical Operations
- Implement and, or, not
- Short-circuit evaluation
8.2.5 Conditional Expressions (COMPLETE)
const X = if A > B then A else B
- Evaluate condition at compile time
- Evaluate selected branch only
8.3 Const Functions (COMPLETE)
8.3.1 Const Function Syntax
const def max(a: Int, b: Int): Int
if a > b
return a
else
return b
end
end
- Parse
const defas const function - Store in function registry with const flag
8.3.2 Const Function Calls
- Only const functions can be called at const time
- All arguments must be const-evaluable
- Result is folded into the caller
8.3.3 Const Function Body Evaluation
- Execute function body in const evaluator
- Handle return statements
- Handle local variables (compile-time stack)
8.4 Loops in Const Context (COMPLETE)
8.4.1 Bounded Loops
const def factorial(n: Int): Int
var result = 1
for i in 1..n+1
result = result * i
end
return result
end
- Track iteration count (1M iteration limit for while, range-based for)
- Error if exceeds limit
- Prevent infinite loops
8.5 Static Assertions
8.5.1 static_assert Intrinsic
static_assert(SIZE <= 1024, "Size too large")
static_assert(is_power_of_two(BUFFER_SIZE), "Buffer size must be power of 2")
- Evaluate condition at compile time
- Error with message if condition is false
8.6 Const Generics (Future)
struct Array<T, const N: Int>
data: Ptr<T>
const def len(): Int = N
end
type Buffer = Array<U8, 1024>
- Mark as future extension
- Document design direction
8.7 Self-Hosted Implementation
- Add const parser support
- Implement const evaluator
- Add const function support
8.8 Test Suite
8.8.1 Basic Const Evaluation
describe "const evaluation" do
it "evaluates const arithmetic" do
result = compile_and_run(<<~QZ)
const X = 10 + 20
def main(): Int = X
QZ
expect(result).to eq(30)
end
it "evaluates const expressions with parens" do
result = compile_and_run(<<~QZ)
const X = (3 + 4) * 2
def main(): Int = X
QZ
expect(result).to eq(14)
end
end
8.8.2 Const Functions
it "evaluates const function calls" do
result = compile_and_run(<<~QZ)
const def square(n: Int): Int = n * n
const SIZE = square(8)
def main(): Int = SIZE
QZ
expect(result).to eq(64)
end
8.8.3 Static Assertions
it "passes static assertions" do
result = compile_and_run(<<~QZ)
const SIZE = 100
static_assert(SIZE < 1000, "too big")
def main(): Int = 0
QZ
expect(result).to eq(0)
end
it "fails static assertions" do
result = compile_only(<<~QZ)
const SIZE = 2000
static_assert(SIZE < 1000, "too big")
QZ
expect(result.stderr).to include("too big")
end
- Test const arithmetic
- Test const functions
- Test const conditionals
- Test static_assert pass/fail
- Test error on non-const expression
8.9 Documentation
File: ref.md
### Const Evaluation
Compile-time constants:
```quartz
const SIZE = 1024
const PI = 3.14159
const NAME = "Quartz"
Const functions:
const def square(n: Int): Int = n * n
const AREA = square(10) # 100, computed at compile time
Static assertions:
static_assert(SIZE <= 4096, "Buffer too large")
Const-evaluable expressions:
- Literals
- Arithmetic (+, -, *, /, %)
- Comparisons (==, !=, <, <=, >, >=)
- Logic (and, or, not)
- Const function calls
- Conditionals (if/match)
- Bounded loops
- [x] Add const evaluation section
- [x] Document const functions
- [x] Document static_assert
- [x] Document limitations
---
## Verification
```bash
rake test
rake quartz:validate
Success Criteria
-
constdeclarations work - Const arithmetic evaluated at compile time
- Const functions work
-
static_assertworks - Clear errors for non-const operations
- Tests pass
- Fixpoint validates
Next Phase
After completing Phase 8, proceed to Phase 9: Inline Assembly Improvements.