At the heart of TrueEntropy is QuBitLang - a proprietary quantum programming language designed and built by Interlink Digital Group. It's not a wrapper around an existing SDK. It's a complete language with its own lexer, parser, type system, semantic analyser, intermediate representation, optimiser, and code generator. This article explains how it works.
Why Build a Language?
Quantum circuit SDKs like Qiskit are powerful, but they're Python libraries - not languages. Writing quantum circuits in Qiskit means constructing objects, calling methods, and managing Python-level concerns that have nothing to do with quantum computing. For a simple 8-qubit random number generator, you might write 15–20 lines of Qiskit boilerplate.
We wanted something closer to the physics. A language where you declare qubits, apply gates, and measure - and the compiler handles everything else. QuBitLang is the result.
The Syntax
QuBitLang uses uppercase keywords for quantum operations and a clean, readable syntax. Here's the actual QRNG circuit that powers the TrueEntropy generator:
# 8-qubit QRNG - H gate creates equal superposition
QUBIT q0, q1, q2, q3, q4, q5, q6, q7
c0 = 0
c1 = 0
c2 = 0
c3 = 0
c4 = 0
c5 = 0
c6 = 0
c7 = 0
# Put all qubits into equal superposition
H(q0)
H(q1)
H(q2)
H(q3)
H(q4)
H(q5)
H(q6)
H(q7)
# Measure - quantum collapse to true random bits
MEASURE q0 -> c0
MEASURE q1 -> c1
MEASURE q2 -> c2
MEASURE q3 -> c3
MEASURE q4 -> c4
MEASURE q5 -> c5
MEASURE q6 -> c6
MEASURE q7 -> c7
Eight qubits. Eight Hadamard gates. Eight measurements. Each measurement collapses a qubit from equal superposition into a truly random 0 or 1. That's one byte of quantum entropy per circuit execution, and with 4,096 shots per job, each run produces 4 KB of raw quantum randomness.
The Compiler Pipeline
QuBitLang is a compiled language. The compiler is written in Python and consists of seven stages, each implemented as a separate module:
1. Lexer (lexer.py)
Tokenises the source code into a stream of typed tokens - keywords like QUBIT, MEASURE, and DEFINE, identifiers, operators, numeric literals, and comments. The token types are defined in tokens.py.
2. Parser (parser.py)
Consumes the token stream and builds an abstract syntax tree (AST). The parser handles qubit declarations, classical variable assignments, gate applications (single-qubit, multi-qubit, parametric), measurement operations, function definitions, control flow, and loop constructs. AST node types are defined in ast_nodes.py.
3. Semantic Analyser (semantic_analyzer.py)
Traverses the AST and enforces correctness: qubit lifecycle validation (no double-measurement), type checking via the type system in type_system.py, scope resolution through the symbol table in symbol_table.py, and verification that all quantum operations are valid for the declared qubits.
4. IR Builder (ir_builder.py)
Transforms the validated AST into a quantum intermediate representation defined in quantum_ir.py. The IR is a hardware-agnostic circuit description - a sequence of gate operations on numbered qubits with measurement instructions.
5. Optimiser (circuit_optimizer.py)
Applies optimisation passes to the IR: gate cancellation (adjacent inverse gates), and rotation merging. These reduce circuit depth and improve execution fidelity on real quantum hardware where every gate introduces noise.
6. Code Generator
Converts the optimised IR into executable Qiskit circuits. The generated circuits are transpiled to native gates using IBM's generate_preset_pass_manager before submission to quantum hardware.
7. Simulator (simulator.py)
A built-in StateVector simulator for local development and testing. This lets developers run QuBitLang circuits without quantum hardware access, producing statistically identical results for algorithms like QRNG where the output is inherently random.
The Compiler in Numbers
- 18+ source files in the compiler directory
- 7-stage pipeline from source to execution
- Full type system with quantum-specific types
- Symbol table with scope management
- Error reporter with source-location tracking
- AST printer for debugging and visualisation
- AI assistant module for interactive circuit development
Hardware Portability
QuBitLang's IR is hardware-agnostic by design. Today, the code generator targets Qiskit and IBM Quantum processors. But because the IR sits between the language and the backend, adding support for other quantum platforms - Quantinuum, Rigetti - requires only a new code generator module, not changes to the language, parser, or optimiser. Learn more about our hardware strategy on the features page.
This is the key architectural advantage of building a language rather than wrapping an SDK: the abstraction boundary is clean, and the same QuBitLang source code can target any quantum backend without modification.
From Language to Product
In TrueEntropy's production pipeline, QuBitLang circuits are compiled and executed automatically. The generate.py runner reads a .ql file, invokes the compiler pipeline, submits the resulting Qiskit circuit to IBM Quantum (or the local simulator), extracts the measurement bitstrings, and feeds them into the entropy formatter for conversion to integers, floats, bytes, and UUIDs.
QuBitLang isn't just a research project - it's the engine that powers every quantum random number TrueEntropy delivers. Read the origin story for the full journey from vision to production.