The Smrti Guide

Welcome to the official documentation for the Smrti Programming Language. Smrti is a systems language that honors the precision of Sanskrit grammar ("Panini Syntax") while delivering the raw performance of x86_64 assembly.

ℹ️ Note

Smrti is currently in active research development. APIs may change.

Installation

Smrti is currently a research language. To run it, you will need the Rust toolchain and NASM (Netwide Assembler) installed on a Linux x86_64 system.

Prerequisites

# Arch Linux
sudo pacman -S rust nasm binutils

# Ubuntu / Debian
sudo apt install rustc cargo nasm binutils

Build from Source

git clone https://github.com/revanthnemtoor/smrti_lang.git
cd smrti_lang
cargo run examples/mandelbrot/mandel_opt.smrti
./build_asm.sh
./hello_world

Hello World

Every Smrti program begins with a sutra Mukhyam(). This is equivalent to main() in C.

sutra Mukhyam() {
    "Namaste World!" vada;
}

Breakdown:

  • sutra: Defines a function (thread/aphorism).
  • Mukhyam: The entry point name.
  • vada: The command to print (speak) the preceding string.

Variables & Types

Variables are declared using the man keyword. Smrti is statically typed.

⚠️ Important

Smrti enforces strict type checking. You cannot assign an Ank to a Dashansh without casting.

sutra Mukhyam() {
    // Integer (64-bit signed)
    man age: Ank = 25;

    // Float (64-bit)
    man pi: Dashansh = 3.14159;

    // String
    man greeting: Sutra = "Hari Om";

    // Boolean
    man is_valid: Bool = satyam; // satyam (true) / mithya (false)
}

Type Reference

  • Ank: Integer (`i64`)
  • Dashansh: Float (`f64`)
  • Sutra: String (`&str`)
  • Bool: Boolean

Input / Output

Smrti provides simple commands for printing to the console and handling files.

Console Output

Use vada (speak) to print a value to standard output.

"Hello" vada;
123 vada;

File I/O

Smrti wraps Linux system calls for file operations.

ℹ️ Note

File operations use raw file descriptors (Ank).

// Open file (filename, flags, mode)
man fd: Ank = file_open("output.txt", 577, 420);

// Write to file
file_write(fd, "Data", 4);

// Close file
file_close(fd);

Arithmetic

Standard arithmetic operations are supported for Ank (Integer) and Dashansh (Float).

man a: Ank = 10;
man b: Ank = 20;

man sum: Ank = a + b;
man diff: Ank = a - b;
man prod: Ank = a * b;
man quot: Ank = b / a;

Comparisons

Used in yadi (if) statements.

  • = : Equals
  • > : Greater than
  • < : Less than

Conditionals

Use yadi (if) and anyatha (else) for branching logic.

man score: Ank = 85;

yadi score > 90 {
    "Excellent" vada;
} anyatha {
    "Good" vada;
}

Loops

The standard yavat loop works like while.

man i: Ank = 0;
yavat i < 5 {
    i vada;
    i = i + 1;
}

Range Loops (Vibhakti)

Smrti introduces a unique syntax based on Sanskrit grammar cases for ranges. This feature allows concise iteration.

Use -tah (from/ablative) and -paryantam (up to/limit).

// Iterate from 1 up to 10
1-tah 10-paryantam {
    "Looping..." vada;
}

// With loop variable capture
i: 0-tah 5-paryantam {
    i vada; // Prints 0, 1, 2, 3, 4
}

Functions

Functions (`sutra`) can take arguments and return values (`pratyaya`).

sutra add(a: Ank, b: Ank) -> Ank {
    man result: Ank = a + b;
    result pratyaya;
}

sutra Mukhyam() {
    man sum: Ank = add(10, 5);
    sum vada;
}

Structs

Define custom data types using sanrachana.

sanrachana Point {
    x: Ank,
    y: Ank
}

sutra Mukhyam() {
    man p: Point = Point { x: 10, y: 20 };
    p.x vada;
}

Concurrency

Smrti supports lightweight thread spawning using the saha (together) keyword block.

                task2();
    iti;
}

Code Examples

Real-world examples demonstrating the power of Smrti.

1. Fibonacci (Recursion)

A simple recursive implementation to calculate the 40th Fibonacci number.

sutra fib(n: Ank) -> Ank {
    yadi n < 2 {
        n pratyaya;
    }
    man n1: Ank = n - 1;
    man n2: Ank = n - 2;
    man a: Ank = fib(n1);
    man b: Ank = fib(n2);
    a + b pratyaya;
}

sutra Mukhyam() {
    man res: Ank = fib(40);
    res vada;
}

2. HTTP Server

A single-threaded, zero-dependency HTTP server using Linux syscalls directly.

ℹ️ Note

This example demonstrates low-level socket manipulation and buffer handling.

sutra Mukhyam() {
    "Starting Server on 8080..." vada;

    // 1. Create Socket (AF_INET=2, SOCK_STREAM=1, 0)
    man sockfd: Ank = net_socket(2, 1, 0);

    // 2. Bind to Port 8080
    // sockaddr_in construction (Simplified)
    man addr: khanda[Ank:2] = [0; 2];
    addr[0] = 2417950722; // Port 8080 mixed with AF_INET
    net_bind(sockfd, addr-asya, 16);

    // 3. Listen & Accept
    net_listen(sockfd, 10);
    man client: Ank = net_accept(sockfd, 0, 0);

    // 4. Send Response
    man resp: Sutra = "HTTP/1.1 200 OK\r\n\r\nNamaste from Smrti!";
    file_write(client, resp, 38);

    file_close(client);
    file_close(sockfd);
}

3. Mandelbrot Generator

High-performance image generation using manual heap allocation and float arithmetic.

sutra Mukhyam() {
    man width: Ank = 800;
    man height: Ank = 800;
    
    // Manual Heap Allocation (like malloc)
    man buffer: Reference = avyuha_navam(300); // 2400 bytes

    man y: Ank = 0;
    yavat y < height {
        man x: Ank = 0;
        yavat x < width {
            // Complex number math logic here...
            // ...
            
            // Writing raw bytes to heap buffer
            byte_write(buffer, offset, 255); 
            
            x = x + 1;
        }
        y = y + 1;
    }
    "Done!" vada;
}

4. Coin Change (Dynamic Programming)

Solving the classic Coin Change problem using recursion and memoization (arrays).

sutra min_val(a: Ank, b: Ank) -> Ank {
    yadi a < b { a pratyaya; } anyatha { b pratyaya; }
}

sutra min_coins(target: Ank, cache: khanda[Ank:100]-asya, coins: khanda[Ank:4]-asya) -> Ank {
    yadi target == 0 { 0 pratyaya; }
    yadi target < 0 { 10000 pratyaya; } // Infinity
    
    // Check Cache
    man cached: Ank = cache[target];
    yadi cached != -1 { cached pratyaya; }

    man res: Ank = 10000;
    man i: Ank = 0;
    yavat i < 4 {
        man coin: Ank = coins[i];
        man sub: Ank = min_coins(target - coin, cache, coins);
        yadi sub != 10000 {
            res = min_val(res, sub + 1);
        }
        i = i + 1;
    }
    cache[target] = res;
    res pratyaya;
}

sutra Mukhyam() {
    man coins: khanda[Ank:4] = [1, 5, 10, 25];
    man cache: khanda[Ank:100] = [-1; 100]; // Initialize with -1
    
    man result: Ank = min_coins(67, cache-asya, coins-asya);
    result vada;
}

5. Panini Grammar Features

Smrti supports Argument Shuffling based on Sanskrit grammatical cases (Vibhakti). Instead of position, arguments are identified by their suffix.

ℹ️ Note

Case suffixes: -m (Accusative/Obj), -ena (Instrumental/Tool), -at (Ablative/Source), -su (Locative/Loc).

// Function defined with 4 arguments
// By default: 0=Acc, 1=Instr, 2=Abl, 3=Loc
sutra process(obj: Ank, tool: Ank, source: Ank, loc: Ank) -> Ank {
    obj vada;
    tool vada;
    source vada;
    loc vada;
    obj + tool + source + loc pratyaya;
}

sutra Mukhyam() {
    man result: Ank = 0;
    
    // Call using Case Markers (Order doesn't matter!)
    // 40-su (Loc), 30-at (Abl), 20-ena (Instr), 10-m (Acc)
    // result-aya (Dative = Return target)
    
    40-su 30-at 20-ena 10-m result-aya process;
    
    result vada; // Prints 100
}

Documentation v1.0 • Smrti Language