Complete Language Reference

Sansqrit DSL — Complete Syntax

The definitive, exhaustive reference for every capability of the Sansqrit Domain-Specific Language. This page documents 33 keywords, 22 operators, 8 data types, 25 statement types, 80+ built-in functions including 46 quantum gates, 19 algorithms, 17 circuits, 15 math functions, 12 collection functions, 7 string methods, 5 I/O functions, and 5 physical constants. Every entry includes syntax, parameters, return type, and a runnable example. Source: github.com/sansqrit/sansqritR

Language Mindmap

This infographic shows the complete structure of the Sansqrit DSL. Every node is a capability documented on this page. The language is organized into three layers: classical computing (variables, control flow, functions), quantum computing (gates, algorithms, circuits), and domain packages (chemistry, biology, ML).

SANSQRIT DSL v0.1.0 CLASSICAL 33 keywords Variableslet, const Control Flowif,for,while,match Functionsfn, lambda, return Classesclass, struct 8 Data Typesint,float,str,bool,list,dict,set,None 22 Operators+ - * / ** % == != |> QUANTUM 82 functions 46 GatesH,X,Y,Z,CNOT,Toffoli... 19 AlgorithmsGrover,Shor,VQE,QAOA... 17 CircuitsBell,GHZ,W,QFT,QEC... Measurementmeasure,probabilities EngineDense/Sparse/Chunked BUILT-INS 39 functions 15 Mathsqrt,sin,cos,log,exp... 12 Collectionslen,range,map,filter... 7 Stringupper,lower,split... 5 I/Oprint,read_csv,write... PACKAGES 8 domains ChemistryVQE, PES, Trotter BiologyDNA, protein folding MedicalDrug screening PhysicsIsing, Heisenberg ML / Genetics / MathQNN, GWAS, Shor EXPORT 5 backends OpenQASM 2/3 · IBM JSON · IonQ · Cirq · Braket

Quick Start — Your First Program

Sansqrit programs are saved as .sq files and executed with cargo run --bin sansqrit -- run program.sq. The language is Python-like in appearance but quantum-native: gate functions and measurement are first-class operations, not library calls. Here is a complete program that creates a Bell state, measures it 1000 times, and prints the results:

-- bell.sq — A complete Sansqrit program
print("Creating a Bell state...")

simulate {
    let q = quantum_register(2)     -- allocate 2 qubits
    H(q[0])                          -- Hadamard on qubit 0
    CNOT(q[0], q[1])                -- entangle qubits 0 and 1
    let result = measure_all(q, shots=1000)
    print(f"Results: {result}")       -- {"00": ~500, "11": ~500}
    print(f"⟨Z₀⟩ = {expectation_z(q[0]):.4f}")
}

print("Done!")

How the lexer processes this: The lexer reads each character and produces tokens: KW_PRINT, LPAREN, STRING("Creating..."), RPAREN, NEWLINE, KW_SIMULATE, LBRACE, etc. The parser then builds an AST with a Simulate statement containing a body of LetDecl, ExprStmt (gate calls), and LetDecl (measurement). The interpreter executes these sequentially, dispatching gate calls to the QuantumEngine.

Keywords (33)

Reserved words that cannot be used as variable names. These are recognized by the lexer and have special meaning in the parser. The complete list:

KeywordPurposeExample
letDeclare a mutable variablelet x = 42
constDeclare an immutable constantconst N = 100
fnDefine a functionfn add(a, b) { return a + b }
returnReturn value from functionreturn result
classDefine a class with methodsclass Qubit { ... }
structDefine a data structurestruct Point { x, y }
extendsClass inheritanceclass Cat extends Animal { }
ifConditional branchif x > 0 { ... }
elseAlternative branchelse { ... }
forIterate over a range or collectionfor i in range(10) { ... }
whileLoop with conditionwhile x < 100 { x += 1 }
loopInfinite loop (use break to exit)loop { if done { break } }
breakExit a loopbreak
continueSkip to next iterationcontinue
matchPattern matchingmatch x { 1 => "one", _ => "other" }
inMembership test / for-in iterationif "a" in list { ... }
andLogical ANDif a and b { ... }
orLogical ORif a or b { ... }
notLogical NOTif not done { ... }
trueBoolean true literallet flag = true
falseBoolean false literallet flag = false
NoneNull/nothing valuelet result = None
importImport a module or packageimport chemistry
asAlias for importsimport chemistry as chem
simulateOpen a quantum simulation blocksimulate { ... }
quantumQuantum hardware block (future)quantum { ... }
classicalClassical computation blockclassical { ... }
circuitDefine a reusable quantum circuitcircuit MyCircuit(n) { ... }
moleculeDefine a molecular systemmolecule H2 { ... }
tryBegin error handling blocktry { risky() }
catchCatch an errorcatch e { print(e) }
finallyAlways-execute cleanupfinally { cleanup() }
raiseThrow an errorraise "invalid input"
yieldGenerator yield (future)yield value

Data Types (8)

Sansqrit is dynamically typed — variables can hold any type and types are checked at runtime. The eight fundamental data types are:

TypeLiteral SyntaxDescriptionExample
Int42, -7, 0xFF64-bit signed integerlet n = 1024
Float3.14, 1e-6, .564-bit IEEE 754 floatlet pi = 3.14159
String"hello", 'world'UTF-8 stringlet s = "quantum"
Booltrue, falseBooleanlet flag = true
List[1, 2, 3]Ordered, mutable collectionlet v = [1, 2, 3]
Dict{"a": 1}Key-value maplet d = {"x": 10}
Set{1, 2, 3}Unordered unique elementslet s = {1, 2, 3}
NoneNoneNull/absent valuelet r = None
-- Type examples
let age = 42                      -- Int
let energy = -1.137               -- Float
let name = "Sansqrit"             -- String
let active = true                 -- Bool
let primes = [2, 3, 5, 7]        -- List
let config = {"shots": 1000}     -- Dict
let unique = {1, 2, 3}           -- Set
let result = None                 -- None

-- Type checking
print(type(age))      -- "Int"
print(type(energy))   -- "Float"
print(type(primes))   -- "List"

Operators (22)

Listed from lowest to highest precedence. Operators higher in the table bind more loosely.

OperatorNamePrecedenceExampleResult
|>Pipeline1 (lowest)[3,1,2] |> sort |> print[1,2,3]
orLogical OR2a or btrue/false
andLogical AND3a and btrue/false
notLogical NOT4not xtrue/false
inMembership53 in [1,2,3]true
== !=Equality6x == 42true/false
< > <= >=Comparison7x < 10true/false
|Bitwise OR85 | 37
^Bitwise XOR95 ^ 36
&Bitwise AND105 & 31
<< >>Bit shift111 << 416
+ -Add / Subtract123 + 47
* / // %Mul / Div / IntDiv / Mod137 // 23
**Power142 ** 101024
-x ~xUnary neg / bitwise NOT15 (highest)-3-3

Assignment Operators

let x = 10     -- assign
x += 5          -- add-assign: x = 15
x -= 3          -- subtract-assign: x = 12
x *= 2          -- multiply-assign: x = 24
x /= 4          -- divide-assign: x = 6.0

Variables & Constants

Variables are declared with let (mutable) or const (immutable). Sansqrit uses lexical scoping — variables are visible in the block where they are declared and all nested blocks.

let x = 42              -- mutable: can be reassigned
x = 99                  -- OK: x is mutable
const PI_APPROX = 3.14  -- immutable: cannot be reassigned
-- PI_APPROX = 3.0     -- ERROR: cannot reassign const

-- Type annotation (optional)
let name: String = "Alice"
let count: Int = 0

-- Multiple assignments
let a = 1
let b = 2
let c = a + b  -- c = 3

Control Flow

if / else / else if

if energy < -1.0 {
    print("Ground state found!")
} else if energy < 0.0 {
    print("Bound state")
} else {
    print("Unbound")
}

for loop

-- Range iteration
for i in range(10) { print(i) }          -- 0,1,2,...,9
for i in range(2, 8) { print(i) }       -- 2,3,...,7
for x in range_step(0.0,1.0,0.1) { }   -- float stepping

-- Collection iteration
for item in ["H", "He", "Li"] { print(item) }

-- Enumerated iteration
for (i, val) in enumerate(["a","b","c"]) {
    print(f"{i}: {val}")  -- 0: a, 1: b, 2: c
}

-- Zip iteration
for (a, b) in zip([1,2], ["x","y"]) { print(a, b) }

while / loop

let n = 1
while n < 1000 { n *= 2 }
print(n)  -- 1024

loop {
    let r = measure(q[0])
    if r == 1 { break }
}

match (Pattern Matching)

match gate_name {
    "H" => print("Hadamard"),
    "X" | "Y" | "Z" => print("Pauli gate"),
    "CNOT" => print("Entangling gate"),
    _ => print(f"Unknown: {gate_name}")
}

Functions & Lambdas

-- Named function with default parameter
fn greet(name, greeting="Hello") {
    return f"{greeting}, {name}!"
}
print(greet("Alice"))             -- "Hello, Alice!"
print(greet("Bob", "Hi"))        -- "Hi, Bob!"

-- Lambda (anonymous function)
let square = fn(x) { x ** 2 }
print(square(5))                  -- 25

-- Higher-order functions
let doubled = map([1,2,3], fn(x) { x * 2 })  -- [2, 4, 6]
let evens = filter([1,2,3,4], fn(x) { x % 2 == 0 })  -- [2, 4]
let total = reduce([1,2,3,4], fn(a,b) { a + b }, 0)  -- 10

Classes & Structs

-- Struct: data-only container
struct Point { x, y }
let p = Point(3.0, 4.0)
print(p.x)  -- 3.0

-- Class: data + methods
class Particle {
    fn init(self, mass, charge) {
        self.mass = mass
        self.charge = charge
    }
    fn energy(self, velocity) {
        return 0.5 * self.mass * velocity ** 2
    }
}
let electron = Particle(9.1e-31, -1.6e-19)
print(electron.energy(1e6))

-- Inheritance
class Photon extends Particle { }

Strings & F-Strings

let s = "Hello, World"
let s2 = 'single quotes work too'

-- F-strings (formatted string literals) — embed expressions
let e = -1.137
print(f"Energy = {e:.6f} Hartree")   -- "Energy = -1.137000 Hartree"
print(f"2 + 3 = {2 + 3}")              -- "2 + 3 = 5"
print(f"Pi ≈ {PI:.4f}")                -- "Pi ≈ 3.1416"

-- String methods
print(s.upper())       -- "HELLO, WORLD"
print(s.lower())       -- "hello, world"
print(s.contains("World"))  -- true
print(s.replace("World", "Quantum"))  -- "Hello, Quantum"
print(s.split(", "))   -- ["Hello", "World"]
print(len(s))           -- 12

Collections

-- Lists
let nums = [1, 2, 3, 4, 5]
nums.append(6)           -- [1,2,3,4,5,6]
let last = nums.pop()    -- 6 (removes last element)
print(nums[0])            -- 1 (indexing)
print(nums[-1])           -- 5 (negative index)

-- List comprehensions
let squares = [x**2 for x in range(10)]  -- [0,1,4,9,...,81]

-- Dictionaries
let d = {"H": 1, "He": 2, "Li": 3}
print(d["H"])     -- 1
d["Be"] = 4       -- add entry

Pipeline Operator ( |> )

The pipeline operator passes the result of the left expression as the first argument to the right function. It enables a data-flow style of programming that is especially natural for quantum circuits.

-- Without pipeline (nested calls, hard to read):
print(sort(filter([5,2,8,1,9], fn(x) { x > 3 })))

-- With pipeline (left-to-right, readable):
[5,2,8,1,9] |> filter(fn(x) { x > 3 }) |> sort |> print
-- Output: [5, 8, 9]

Error Handling

try {
    let result = shor_factor(1)  -- might fail for N=1
} catch e {
    print(f"Error: {e}")
} finally {
    print("Cleanup complete")
}

-- Raise custom errors
fn validate_qubits(n) {
    if n < 1 { raise "Need at least 1 qubit" }
}

Import System

import chemistry           -- import entire package
import biology as bio      -- import with alias
import medical
import physics
import genetics
import ml
import math

-- Available packages:
-- chemistry : VQE, PES, Trotter, molecular Hamiltonians
-- biology   : DNA/RNA, protein folding, alignment
-- medical   : drug screening, vaccine design, binding energy
-- physics   : Ising model, Heisenberg chain, time evolution
-- genetics  : CRISPR guide design, GWAS, variant calling
-- ml        : QNN, QSVM, QPCA, variational classifiers
-- math      : Shor factoring, Grover search, HHL solver

Simulate Block

The simulate block is where quantum operations happen. It creates a QuantumEngine instance, executes the body, and captures measurement results. You can specify the engine tier explicitly or let Sansqrit auto-select based on qubit count.

-- Auto-select engine (default)
simulate {
    let q = quantum_register(4)
    H(q[0])
    print(measure_all(q, shots=1000))
}

-- Force chunked engine for large circuits
simulate(engine="Chunked") {
    let q = quantum_register(100)
    H(q[0])
    for i in range(99) { CNOT(q[i], q[i+1]) }
    print(measure_all(q, shots=100))
}

-- Force sparse engine
simulate(engine="Sparse") { /* ... */ }

-- Force dense engine
simulate(engine="Dense") { /* ... */ }

Quantum Operations — Complete Reference

quantum_register(n) → Qubit Array

Allocates n qubits, all initialized to |0⟩. Returns an array-like object that supports indexing with q[i].

let q = quantum_register(8)  -- 8 qubits, all |0⟩
print(n_qubits())             -- 8

All 46 Gate Functions

Every gate is called as a function inside a simulate block. Single-qubit gates take one qubit argument. Parametric gates take a qubit and angle(s). Two-qubit gates take two qubits. Three-qubit gates take three qubits. Multi-qubit gates take lists.

CategoryGateSyntaxParameters
Single (18)IdentityI(q[0])none
Pauli X/Y/ZX(q[0]), Y(q[0]), Z(q[0])none
HadamardH(q[0])none
S / S†S(q[0]), Sdg(q[0])none
T / T†T(q[0]), Tdg(q[0])none
√X / √X†SX(q[0]), SXdg(q[0])none
Rx / Ry / RzRx(q[0], θ)θ: rotation angle
Phase / U1Phase(q[0], θ), U1(q[0], λ)θ or λ
U2U2(q[0], φ, λ)φ, λ
U3U3(q[0], θ, φ, λ)θ, φ, λ
BatchH_all(q), Rx_all(q, θ), Ry_all(q, θ)optional θ
Two (21)CNOT / CZ / CYCNOT(q[0],q[1])none
CH / CSXCH(q[0],q[1])none
SWAP variantsSWAP(a,b), iSWAP(a,b), SqrtSWAP(a,b), fSWAP(a,b), DCX(a,b)none
CRx / CRy / CRzCRx(c, t, θ)θ
CPCP(c, t, θ)θ
CUCU(c, t, θ, φ, λ)θ, φ, λ
RXX / RYY / RZZ / RZXRZZ(q[0], q[1], θ)θ
ECR / MSECR(q[0],q[1]), MS(q[0],q[1])none
Three (3)Toffoli / CCXToffoli(c0,c1,target)none
Fredkin / CSWAP / CCZCCZ(q[0],q[1],q[2])none
Multi (4)MCX / MCZ / C3X / C4XMCX([c0,c1,...],target)none

Measurement Functions

FunctionSyntaxReturnsDescription
measuremeasure(q[i])0 or 1Collapse qubit, return classical bit
measure_allmeasure_all(q, shots=N)Dict of bitstring→countSample N times without collapse
probabilitiesprobabilities(q)List of (bitstring, prob)Get exact probability distribution
expectation_zexpectation_z(q[i])Float in [-1, 1]⟨Z⟩ on single qubit
expectation_zzexpectation_zz(q[i], q[j])Float in [-1, 1]⟨Z⊗Z⟩ on two qubits
engine_nnzengine_nnz()IntCount non-zero amplitudes
n_qubitsn_qubits()IntTotal qubit count

Circuit Constructor Functions (17)

FunctionSyntaxDescription
bell_statebell_state(q[0], q[1])(|00⟩+|11⟩)/√2
ghz_stateghz_state(q)(|00...0⟩+|11...1⟩)/√2
w_statew_state(q)Equal superposition: exactly one |1⟩
cluster_statecluster_state(q)Graph state for MBQC
dicke_statedicke_state(q, k=2)D(n,k): C(n,k) terms
cat_statecat_state(q)Schrödinger cat = GHZ alias
qftqft(q)Quantum Fourier Transform
iqftiqft(q)Inverse QFT
draper_qft_adderdraper_qft_adder(a, b)A = A + B using QFT
quantum_multiplierquantum_multiplier(a,b,result)result = a × b
amplitude_encodingamplitude_encoding(q, data)Encode vector into amplitudes
angle_encodingangle_encoding(q, data)Encode data as Ry angles
basis_encodingbasis_encoding(q, value)Encode integer as basis state
random_circuitrandom_circuit(q, depth, seed)Benchmarking circuit
bit_flip_encodebit_flip_encode(d, a1, a2)3-qubit X error correction
phase_flip_encodephase_flip_encode(d, a1, a2)3-qubit Z error correction
shor_9qubit_encodeshor_9qubit_encode(q[0..9])Full QEC

Algorithm Functions (19)

FunctionSyntaxReturns
grover_searchgrover_search(n_qubits, target, shots)GroverResult {solution, probability, n_queries, histogram}
grover_search_multigrover_search_multi(n_qubits, targets, shots)GroverResult
shor_factorshor_factor(N)ShorResult {factors, period, success}
vqevqe(n_qubits, hamiltonian, layers, max_iter, tol)VqeResult {energy, params, converged, history}
vqe_h2vqe_h2(bond_length, max_iter)VqeResult
qaoa_maxcutqaoa_maxcut(edges, n_nodes, layers, shots)QaoaResult {best_bitstring, best_cost}
quantum_phase_estimationestimate_phase(n_counting_bits, unitary_angle)QpeResult {phase, phase_bits}
hhl_solvehhl_solve(A, b)HhlResult {solution, condition_number}
bernstein_vaziranibernstein_vazirani(n_bits, oracle_secret)List of bits
simon_algorithmsimon_algorithm(n_bits, secret)List of bits
deutsch_jozsadeutsch_jozsa(n_bits, oracle_type)"constant" or "balanced"
quantum_walk_linequantum_walk_line(n_positions, n_steps, shots)MeasurementResult
quantum_countingquantum_counting(search_bits, counting_bits, solutions)QaeResult {count_estimate}
swap_testswap_test(engine1, engine2, shots)Float (overlap)
teleportteleport(engine)(bit0, bit1)
superdense_codingsuperdense_coding(bit0, bit1)(received0, received1)
bb84_qkdbb84_qkd(key_length)(alice_key, bob_key, error_rate)
amplitude_estimationamplitude_estimation(n_qubits, eval_bits, target)QaeResult
variational_classifiervariational_classifier(features, data, layers, epochs, lr)(params, accuracy)

Math Functions (15)

FunctionSyntaxDescriptionExample
sqrtsqrt(x)Square rootsqrt(16) → 4.0
absabs(x)Absolute valueabs(-5) → 5
sinsin(x)Sine (radians)sin(PI/2) → 1.0
coscos(x)Cosine (radians)cos(0) → 1.0
tantan(x)Tangent (radians)tan(PI/4) → 1.0
loglog(x)Natural logarithm (ln)log(E) → 1.0
expexp(x)e^xexp(1) → 2.718...
powpow(x, y)x raised to power ypow(2, 10) → 1024
floorfloor(x)Round down to intfloor(3.7) → 3
ceilceil(x)Round up to intceil(3.2) → 4
roundround(x) or round(x, n)Round to n decimal placesround(3.456, 2) → 3.46
sumsum(list)Sum of all elementssum([1,2,3]) → 6
meanmean(list)Arithmetic meanmean([2,4,6]) → 4.0
minmin(list) or min(a,b)Minimum valuemin([5,1,3]) → 1
maxmax(list) or max(a,b)Maximum valuemax([5,1,3]) → 5

Collection Functions (12)

FunctionSyntaxDescriptionExample
lenlen(x)Length of string, list, or dictlen([1,2,3]) → 3
rangerange(n) or range(start,end)Generate integer rangerange(5) → [0,1,2,3,4]
range_steprange_step(start, end, step)Float range with steprange_step(0,1,0.2) → [0,0.2,0.4,0.6,0.8]
enumerateenumerate(list)Index + value pairsenumerate(["a","b"]) → [(0,"a"),(1,"b")]
zipzip(a, b)Pair elements from two listszip([1,2],[3,4]) → [(1,3),(2,4)]
mapmap(list, fn)Apply function to each elementmap([1,2,3], fn(x){x*2}) → [2,4,6]
filterfilter(list, fn)Keep elements where fn returns truefilter([1,2,3,4], fn(x){x>2}) → [3,4]
reducereduce(list, fn, init)Fold list into single valuereduce([1,2,3], fn(a,b){a+b}, 0) → 6
sortsort(list)Sort ascendingsort([3,1,2]) → [1,2,3]
appendlist.append(val)Add element to end[1,2].append(3) → [1,2,3]
poplist.pop()Remove and return last[1,2,3].pop() → 3
top_ktop_k(result, k)Top k measurement resultstop_k(histogram, 3)

String Methods (7)

MethodSyntaxReturnsExample
uppers.upper()Uppercase string"hello".upper() → "HELLO"
lowers.lower()Lowercase string"HELLO".lower() → "hello"
containss.contains(sub)Bool"quantum".contains("ant") → true
replaces.replace(old, new)New string"ab".replace("a","x") → "xb"
splits.split(delim)List of strings"a,b,c".split(",") → ["a","b","c"]
joindelim.join(list)Joined string", ".join(["a","b"]) → "a, b"
lenlen(s)Intlen("hello") → 5

I/O Functions (5)

FunctionSyntaxDescription
printprint(value, ...)Print values to stdout, space-separated
read_csvread_csv("file.csv")Read CSV file into list of dicts
write_csvwrite_csv("out.csv", data)Write list of dicts to CSV
read_jsonread_json("file.json")Read JSON file into dict
read_fileread_file("file.txt")Read entire text file as string

Type Conversion Functions (5)

FunctionSyntaxExample
intint(x)int(3.7) → 3, int("42") → 42
floatfloat(x)float(3) → 3.0, float("3.14") → 3.14
strstr(x)str(42) → "42"
boolbool(x)bool(0) → false, bool(1) → true
typetype(x)type(42) → "Int", type([]) → "List"

Built-in Constants

ConstantValueDescription
PI3.141592653589793π — fundamental to all rotation gates
E2.718281828459045Euler's number — natural logarithm base
PLANCK6.62607015 × 10⁻³⁴Planck's constant (J·s)
BOLTZMANN1.380649 × 10⁻²³Boltzmann's constant (J/K)
AVOGADRO6.02214076 × 10²³Avogadro's number (mol⁻¹)

Molecule Declaration

molecule H2 {
    atoms: [H, H],
    bond_length: 0.74,
    basis_set: "STO-3G"
}

molecule LiH {
    atoms: [Li, H],
    bond_length: 1.6,
    basis_set: "STO-3G"
}

-- Use in VQE:
simulate {
    let r = vqe(H2)
    print(f"H₂ energy: {r.energy:.6f} Ha")
}

Circuit Declaration

circuit BellPair(q0, q1) {
    H(q0)
    CNOT(q0, q1)
}

circuit QFTCircuit(qubits) {
    for i in range(len(qubits)) {
        H(qubits[i])
        for j in range(i+1, len(qubits)) {
            CP(qubits[j], qubits[i], PI / (1 << (j-i)))
        }
    }
}

simulate {
    let q = quantum_register(4)
    BellPair(q[0], q[1])
    QFTCircuit(q)
    print(measure_all(q, shots=1000))
}

Comments

-- Single-line comment (double-dash)
# Single-line comment (hash)
/* Multi-line
   comment */
/// Documentation comment
Gates (46) → Algorithms (19) → 220+ Programs → GitHub