Introduction

SPIDER is a lightweight, security-focused programming language designed for high-performance scripting, networking, cryptographic operations, and system-level automation.

It features a clean syntax, predictable behavior, strong built-in functions, and a fast Rust-based interpreter.

Language Basics

SPIDER’s syntax is intentionally minimal. If you’ve used Rust, C, or JavaScript, the structure will feel familiar. Blocks use braces, statements end with semicolons, and functions use a clean func keyword.

Comments

SPIDER supports the following comment styles:

// Single-line comment

/* 
   Multi-line comment
*/

""" 
Multi-line string literal (not a comment).
Use this when you want to embed large blocks of text.
"""

Variables

Variables in SPIDER are declared with let. Values are immutable by default unless marked mut.

Immutable Variable

let x = 10;

Mutable Variable

let mut counter = 0;
counter = counter + 1;

Type Inference

Types are inferred unless explicitly stated.

let a = 42;          // int
let b = 3.14;        // float
let c = "hello";     // str

Explicit Types

let x: int = 10;
let y: float = 2.5;
let id: uint = 1000;

Types

SPIDER includes a set of core built-in types, as well as system-oriented ones for bytes, pointers, and results.

TypeDescription
intSigned 64-bit integer
uintUnsigned 64-bit integer
float64-bit floating point value
booltrue or false
strUTF-8 string
bytesRaw byte array
ptrRaw memory pointer (unsafe)
arrayDynamic array type
mapHash map / dictionary
ResultUsed for error handling (Ok, Err)
voidNo return value

Literals

42              // int
3.14            // float
true            // bool
"hello"         // string
b"ABC"          // byte literal
"""big text"""  // multi-line string

Operators

OperatorDescription
+Addition
-Subtraction
*Multiplication
/Division
%Modulo
==Equal
!=Not equal
<Less than
>Greater than
<=Less than or equal
>=Greater than or equal
&&Logical AND
||Logical OR
!Logical NOT
..Range
..=Inclusive range
+= -= *= /=Compound assignment

Control Flow

If / Else

if x > 10 {
    println("large");
} else {
    println("small");
}

While Loop

let mut i = 0;

while i < 5 {
    println(i);
    i += 1;
}

For Loop

for n in 0..5 {
    println(n);
}

Loop + Break

loop {
    println("running");
    break;
}

Match

match code {
    200 => println("OK"),
    404 => println("Not found"),
    _   => println("Unknown"),
}

Functions

Functions are declared using func. Parameters may be typed or inferred.

Basic Function

func greet(name: str) {
    println("Hello, " + name);
}

Function With Return Value

func add(a: int, b: int) -> int {
    return a + b;
}

Implicit Return

The final expression is returned automatically if return is omitted.

func square(n: int) -> int {
    n * n
}

Void Function

func log_message(msg: str) -> void {
    println(msg);
}

Calling a Function

let result = add(10, 20);
println(result);


Structs

Structs define custom data types with named fields. They are lightweight and ideal for representing structured data.

Defining a Struct

struct User {
    id: int,
    name: str,
    active: bool,
}

Creating an Instance

let u = User { 
    id: 1, 
    name: "Alice",
    active: true,
};

Accessing Fields

println(u.name);
println(u.id);

Mutating Fields

let mut u = User { id: 1, name: "Alice", active: true };
u.active = false;

Enums

Enums allow you to define a type that can be one of several variants.

Basic Enum

enum Status {
    Online,
    Offline,
    Busy,
}

Enum with Data

enum Message {
    Text(str),
    Ping(int),
    Error(str),
}

Creating Enum Values

let s = Status::Online;

let m = Message::Text("hello");

Pattern Matching

match allows exhaustive branching based on values, including enums.

Matching an Enum

match m {
    Message::Text(t) => println("text: " + t),
    Message::Ping(n) => println("ping: " + n),
    Message::Error(e) => println("error: " + e),
}

Matching Primitive Values

match code {
    200 => println("OK"),
    403 => println("Forbidden"),
    404 => println("Not Found"),
    _   => println("Unknown"),
}

Arrays

Arrays are dynamic and can grow or shrink.

Creating an Array

let nums = [1, 2, 3, 4, 5];

Indexing

println(nums[0]);     // 1
println(nums[3]);     // 4

Appending

nums.push(6);

Iteration

for n in nums {
    println(n);
}

Maps

Maps (hash tables) store key/value pairs.

Create a Map

let m = map_new();

Insert Values

map_set(m, "name", "Alice");
map_set(m, "score", 42);

Retrieve Values

let n = map_get(m, "name");
println(n);

Map Contains

if map_has(m, "score") {
    println("found score");
}

Error Handling

SPIDER uses a Result type, containing either Ok(value) or Err(error).

Returning a Result

func divide(a: int, b: int) -> Result {
    if b == 0 {
        return Err("divide by zero");
    }
    return Ok(a / b);
}

Using Match for Error Handling

let res = divide(10, 2);

match res {
    Ok(v)  => println("value: " + v),
    Err(e) => println("error: " + e),
}

Automatic Unwrap

You can unwrap a Result when you're sure it won't fail.

let value = unwrap(divide(10, 2));

If the function returns Err, the program terminates with an error.

Option-Like Behavior

SPIDER does not have a formal Option type but treats null-style values via Err or map_has patterns.

let m = map_new();
map_set(m, "x", 10);

if map_has(m, "x") {
    let value = map_get(m, "x");
    println(value);
}


TCP Networking

SPIDER offers a simple but powerful TCP API for client-side communication. Each TCP connection is represented internally by a socket handle.

tcp_connect(host: str, port: int) -> Result

Opens a TCP connection and returns a socket handle.

let sock = unwrap(tcp_connect("example.com", 80));

tcp_send(socket, data: str or bytes) -> int

Sends data over the TCP connection.

tcp_send(sock, "GET / HTTP/1.1\r\n\r\n");

tcp_recv(socket, max_bytes: int) -> bytes

let response = tcp_recv(sock, 4096);
println(response);

tcp_close(socket)

tcp_close(sock);

Example: Simple HTTP Request

let sock = unwrap(tcp_connect("example.com", 80));

tcp_send(sock, 
    "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"
);

let res = tcp_recv(sock, 8192);
println(res);

tcp_close(sock);

UDP Networking

UDP is connectionless, meaning packets are sent without establishing a session.

udp_send(host: str, port: int, data: bytes or str)

udp_send("8.8.8.8", 53, "payload");

udp_recv(port: int, max_bytes: int) -> bytes

let incoming = udp_recv(9000, 1024);
println(incoming);

Broadcast Example

udp_send("255.255.255.255", 9999, "DISCOVER");

DNS Lookup

dns_lookup(domain: str) -> str

let ip = dns_lookup("google.com");
println(ip);

Returns the first resolved IPv4 address.

HTTP / HTTPS

SPIDER includes built-in HTTPS with automatic TLS.

https_get(url: str) -> str

let body = https_get("https://httpbin.org/get");
println(body);

https_post(url: str, data: str or bytes) -> str

let resp = https_post(
    "https://httpbin.org/post",
    "username=admin&password=1234"
);

https_post_json(url: str, map_object) -> str

let body = https_post_json(
    "https://api.site.com/update",
    { "score": 42, "user": "test" }
);

Port Scanning

scan_port(ip: str, port: int) -> bool

Returns true if port is open, otherwise false.

if scan_port("192.168.1.1", 80) {
    println("Port open");
}

Example: Scan a Range

for p in 1..1024 {
    if scan_port("192.168.1.1", p) {
        println("Open: " + p);
    }
}

Packet API

SPIDER v3 provides minimal raw packet functionality (intended for learning and non-destructive research).

packet_create(proto: str, fields: map) -> bytes

let ip_header = {
    "src": "192.168.0.2",
    "dst": "192.168.0.3",
    "ttl": 64,
};

let pkt = packet_create("ipv4", ip_header);

packet_send(interface: str, bytes)

packet_send("eth0", pkt);

Example: Custom Packet

let hdr = {
    "src": "10.0.0.2",
    "dst": "10.0.0.10",
    "flags": 2
};

let pkt = packet_create("tcp", hdr);
packet_send("eth0", pkt);


Cryptography

SPIDER includes a full cryptographic toolkit built directly into the runtime. All functions are pure, stateless, and safe to call repeatedly.


Hash Functions

Supported algorithms:

md5(data: str) -> str

let h = md5("hello");
println(h);

sha256(data: str) -> str

let h = sha256("password123");
println(h);

sha512(data: str) -> str

let h = sha512("top_secret");
println(h);

Base64 Encoding / Decoding

encode_base64(data: bytes or str) -> str

let out = encode_base64("Hello!");
println(out);

decode_base64(text: str) -> bytes

let bytes = decode_base64(out);
println(bytes);

XOR Cipher

Symmetric reversible cipher. Recommended for obfuscation, NOT strong encryption.

xor_cipher(data: str or bytes, key: str) -> bytes

let enc = xor_cipher("Secret Message", "KEY123");
let dec = xor_cipher(enc, "KEY123");  // reversible
println(dec);

AES-256 Encryption

SPIDER v3 implements AES-256 in two modes:

Both require: - 32-byte key - 16-byte IV (CBC) - 12-byte nonce (GCM) ---

AES-256-CBC

aes256_cbc_encrypt(data: bytes, key: bytes, iv: bytes) -> bytes

aes256_cbc_decrypt(data: bytes, key: bytes, iv: bytes) -> bytes

let key = random_bytes(32);
let iv  = random_bytes(16);

let ciphertext = aes256_cbc_encrypt("HELLO", key, iv);
let plaintext  = aes256_cbc_decrypt(ciphertext, key, iv);

println(plaintext);

AES-256-GCM (Authenticated)

aes256_gcm_encrypt(data: bytes, key: bytes, nonce: bytes) -> map

Returns:

aes256_gcm_decrypt(ciphertext, key, nonce, tag) -> bytes

let key   = random_bytes(32);
let nonce = random_bytes(12);

let enc = aes256_gcm_encrypt("HELLO", key, nonce);

let dec = aes256_gcm_decrypt(
    enc["ciphertext"],
    key,
    nonce,
    enc["tag"]
);

println(dec);

If authentication fails, decrypt throws a runtime error.


Key Derivation (PBKDF2-like)

Used to turn passwords into real cryptographic keys.

kdf_derive(password: str, salt: bytes, rounds: int, key_len: int) -> bytes

let salt = random_bytes(16);
let key  = kdf_derive("mypassword", salt, 600000, 32);

println(encode_base64(key));

Random Generation

random_bytes(len: int) -> bytes

let b = random_bytes(32);
println(b);

random_int(min: int, max: int) -> int

let n = random_int(1, 10);
println(n);

UUID Generation

generate_uuid() -> str

let id = generate_uuid();
println(id);   // "bd19a670-f912-4c6d-a810-98b5c2e012fe"



File System Operations

The SPIDER standard library includes full cross-platform file & directory support. All file operations return booleans or throw errors on failure.


Reading Files

read_file(path: str) -> str

let content = read_file("data.txt");
println(content);

read_bytes(path: str) -> bytes

let binary = read_bytes("image.bin");
println(binary);

Writing Files

write_file(path: str, data: str or bytes) -> bool

Overwrites existing file.
write_file("output.txt", "Hello World!");

append_file(path: str, data: str or bytes) -> bool

append_file("log.txt", "New Entry\n");

create_file(path: str) -> bool

create_file("empty.txt");

File Operations

file_exists(path: str) -> bool

if file_exists("config.sp") {
    println("config exists");
}

delete_file(path: str) -> bool

delete_file("temp.bin");

copy_file(src: str, dst: str) -> bool

copy_file("a.txt", "b.txt");

move_file(src: str, dst: str) -> bool

move_file("old.txt", "archive/old.txt");

get_file_size(path: str) -> int

let size = get_file_size("video.mp4");
println(format("Size: {} bytes", size));

get_file_modified(path: str) -> int

Returns UNIX timestamp.
let ts = get_file_modified("notes.txt");
println(ts);

get_file_created(path: str) -> int

let ts = get_file_created("notes.txt");
println(ts);

Directory Operations

list_dir(path: str) -> list

let items = list_dir(".");
for item in items {
    println(item);
}

create_dir(path: str) -> bool

create_dir("logs");

delete_dir(path: str) -> bool

Deletes directory **and all contents**.
delete_dir("old_data");

dir_exists(path: str) -> bool

if dir_exists("src") {
    println("src folder present");
}

current_dir() -> str

println(current_dir());

change_dir(path: str) -> bool

change_dir("docs");

Path Utilities

path_join(a, b, ...)

Joins components into safe platform-correct path.
let p = path_join("folder", "sub", "file.txt");
println(p);

path_basename(path: str) -> str

println(path_basename("/usr/local/bin/file"));

path_dirname(path: str) -> str

println(path_dirname("/usr/local/bin/file"));

path_extension(path: str) -> str

println(path_extension("photo.jpeg"));  // ".jpeg"

path_normalize(path: str) -> str

Resolves `../`, `./`, duplicate slashes.
let cleaned = path_normalize("/home/user/../docs//file.txt");
println(cleaned);

is_absolute(path: str) -> bool

println(is_absolute("/usr/bin"));

is_relative(path: str) -> bool

println(is_relative("src/main.sp"));

Examples

Example: Log Rotator

if file_exists("log.txt") {
    let ts = get_timestamp();
    move_file("log.txt", format("logs/log_{}.txt", ts));
}

write_file("log.txt", "New session\n");

Example: Directory Scanner

let items = list_dir(".");
for x in items {
    if file_exists(x) {
        println(format("FILE: {}", x));
    } else {
        println(format("DIR:  {}", x));
    }
}

Example: Save Binary Data

let raw = random_bytes(64);
write_file("key.bin", raw);
println("saved 64 bytes");


Control Flow

SPIDER provides simple but powerful flow constructs inspired by C, Rust, and Python. All keywords shown below are built into the parser and compiler.


If / Else

Syntax

if condition {
    // block
} else if condition {
    // block
} else {
    // block
}

Example

let age = 17;

if age >= 18 {
    println("Adult");
} else if age >= 13 {
    println("Teen");
} else {
    println("Child");
}

Boolean Expressions

Supported operators:

if x == 10 && y != 5 {
    println("Match!");
}

Pattern Matching

match is SPIDER’s powerful branching tool. It behaves similarly to Rust’s match or a more strict switch.

Syntax

match value {
    case pattern1 {
        ...
    }
    case pattern2 {
        ...
    }
    default {
        ...
    }
}

Supported patterns:

Example

let x = 4;

match x {
    case 1 {
        println("one");
    }
    case 2,3 {
        println("two or three");
    }
    case 4..10 {
        println("between 4 and 10");
    }
    default {
        println("something else");
    }
}

Looping

SPIDER supports: Also available: - break - continue ---

loop {} (infinite)

loop {
    println("Running");
}

break keyword

loop {
    break;
}

continue keyword

for i in [1,2,3,4,5] {
    if i == 3 {
        continue;
    }
    println(i);
}
---

while condition {}

let x = 0;

while x < 5 {
    println(x);
    x = x + 1;
}
---

for value in collection {}

SPIDER’s for-in works on arrays, strings, and maps.

let arr = [10, 20, 30];

for item in arr {
    println(item);
}
---

Iterating maps

let m = map_new();
m = map_set(m, "a", 1);
m = map_set(m, "b", 2);

for key in map_keys(m) {
    println(format("{} = {}", key, m[key]));
}

Error Handling

SPIDER includes structured error handling using try/catch blocks.

Basic Syntax

try {
    // Code that might fail
} catch err {
    println(err);
}

Example

try {
    let data = read_file("missing.txt");
    println(data);
} catch e {
    println("File error: " + e);
}

panic(message: str)

Panic immediately stops execution and prints an error message.

panic("Critical failure!");

throw(message: str)

Throw a runtime error that can be caught by a surrounding catch block.

func div(a: int, b: int) -> int {
    if b == 0 {
        throw("divide by zero");
    }
    return a / b;
}

Runtime Exceptions

The following SPIDER API calls naturally generate catchable errors:

Example catching builtin exception

try {
    let arr = [1,2,3];
    println(arr[10]);  // invalid index
} catch err {
    println("Caught: " + err);
}

Examples

Example: Countdown Loop

let x = 5;

while x > 0 {
    println(x);
    x = x - 1;
}

println("Done!");

Example: Menu System

loop {
    println("1. Hash");
    println("2. Exit");

    let choice = input("> ");

    match choice {
        case "1" {
            let text = input("Text: ");
            println(sha256(text));
        }
        case "2" {
            break;
        }
        default {
            println("Invalid");
        }
    }
}

Example: Exception-safe File Reader

func safe_read(path: str) -> str {
    try {
        return read_file(path);
    } catch err {
        return "ERR: " + err;
    }
}

println(safe_read("maybe.txt"));


Functions

Functions are a core part of SPIDER. SPIDER supports:


Basic Function

func greet() {
    println("Hello!");
}
Call it:
greet();
---

Function With Parameters

func add(a: int, b: int) -> int {
    return a + b;
}

println(add(4, 7));   // 11
---

Optional Type Annotations

SPIDER allows untyped params (dynamic dispatch):

func shout(text) {
    println(upper(text));
}
---

Default Parameter Values

func welcome(name: str = "guest") {
    println("Welcome " + name);
}

welcome();           // Welcome guest
welcome("KCdev");    // Welcome KCdev

Returning Values

SPIDER requires an explicit return when using -> type.

func cube(x: int) -> int {
    return x * x * x;
}
You may also return early:
func check(n: int) -> str {
    if n == 0 {
        return "zero";
    }
    return "non-zero";
}

Void Return Type (unit)

func log(msg: str) -> void {
    println(msg);
}

export keyword

Used by module systems and the compiler to allow external usage.

export func hash_user(name: str) -> str {
    return sha256(name);
}
Used by importing files:
dep "crypto.spdi";

println(hash_user("admin"));

dep keyword

Imports another SPIDER script.

dep "math.spdi";
dep "utils/crypto.spdi";

println(square(9));
The compiler auto-resolves relative paths.

Recursive Functions

func factorial(n: int) -> int {
    if n <= 1 {
        return 1;
    }
    return n * factorial(n - 1);
}

println(factorial(5));   // 120
---

Tail recursion

SPIDER supports it but the compiler *may* optimize depending on platform:
func sum(n: int, acc: int = 0) -> int {
    if n == 0 {
        return acc;
    }
    return sum(n - 1, acc + n);
}

Closures (Anonymous Functions)

let double = func(x: int) -> int {
    return x * 2;
};

println(double(10));     // 20
---

Lambdas (Short Syntax)

let square = |x| x * x;

println(square(6));  // 36
Functions may be passed as arguments:
func apply_twice(f, value) {
    return f(f(value));
}

println(apply_twice(|x| x + 1, 5));  // 7

Built-in higher-order usage

Example: mapping over arrays:
let nums = [1,2,3,4];

let doubled = array_map(nums, |x| x * 2);

println(doubled);   // [2,4,6,8]

Async Functions

SPIDER supports asynchronous functions for networking, timers, and concurrent operations.

Syntax:
async func fetch(url: str) -> str {
    return https_get(url);
}

func main() -> int {
    let html = await fetch("https://example.com");
    println(html);
    return 0;
}
---

Parallel async example

async func get_a() -> str {
    sleep(200);
    return "A";
}

async func get_b() -> str {
    sleep(100);
    return "B";
}

func main() -> int {
    let a = await get_a();
    let b = await get_b();

    println(a + " " + b);
    return 0;
}

Unsafe Blocks

Used for system-level memory ops, raw pointers, and special host APIs. Syntax:
unsafe {
    let ptr = alloc_bytes(16);
    write_ptr(ptr, 0x41);
    free_ptr(ptr);
}
Examples: ### Direct memory access
unsafe {
    let buf = alloc_bytes(1024);
    fill_bytes(buf, 0xFF);
}
--- ### Unsafe Function Definition
unsafe func zero_mem(buf: ptr, size: int) {
    memset(buf, 0, size);
}
---

Why unsafe?


Function Overloading

SPIDER allows functions with the same name but different signatures.
func show(x: int) {
    println("int");
}

func show(x: str) {
    println("string");
}

show(10);     // int
show("hi");   // string
The compiler resolves the correct version.

Complete Examples

Example 1 — Hash Wrapper

export func secure_hash(data: str) -> str {
    return sha512(data);
}
---

Example 2 — Functional Style Map

func filter_even(arr) {
    return array_filter(arr, |x| x % 2 == 0);
}

println(filter_even([1,2,3,4,5,6]));  
---

Example 3 — Async Web Downloader

async func download(url: str) -> void {
    let html = await https_get(url);
    write_file("page.html", html);
}

func main() -> int {
    await download("https://kernelcore.dev");
    return 0;
}
---

Example 4 — Unsafe Memory Viewer

unsafe func dump(ptr: ptr, size: int) {
    for i in 0..size {
        println(hex(read_ptr(ptr + i)));
    }
}
---

Example 5 — Recursion + Pattern Matching

func describe(n: int) -> str {
    match n {
        case 0 { return "zero"; }
        case 1 { return "one"; }
        case 2..5 { return "small"; }
        default { return "large"; }
    }
}


Structs

Structs are custom data types that store fields. They behave like lightweight objects with optional attached methods.

Basic Struct Definition

struct User {
    name: str,
    age: int,
    admin: bool
}
---

Creating Struct Instances

let u = User {
    name: "KCdev",
    age: 16,
    admin: true
};
---

Accessing & Modifying Fields

println(u.name);      // KCdev
println(u.age);       // 16

u.age = 17;
println(u.age);       // 17
---

Struct Constructor Function

Since SPIDER doesn’t automatically generate constructor functions, you usually write one manually:

func new_user(name: str, age: int) -> User {
    return User { name: name, age: age, admin: false };
}

let u = new_user("bob", 18);
---

Structs With Default Values

struct Config {
    host: str = "127.0.0.1",
    port: int = 8080,
    https: bool = false
}

let cfg = Config {};
println(cfg.port);    // 8080
---

Inline Struct Literal Use

println(User { name: "Alice", age: 20, admin: false }.name);

Methods

SPIDER supports instance methods and static methods (associated functions). Methods are defined using:

func StructName.methodName(self, ...)
---

Instance Methods

struct Point {
    x: int,
    y: int
}

func Point.move(self, dx: int, dy: int) {
    self.x = self.x + dx;
    self.y = self.y + dy;
}

let p = Point { x: 2, y: 5 };
p.move(3, -2);

println(p.x);   // 5
println(p.y);   // 3
---

Methods With Return Types

func Point.len(self) -> float {
    return sqrt((self.x*self.x) + (self.y*self.y));
}
---

Associated Functions (Static Methods)

func Point.origin() -> Point {
    return Point { x: 0, y: 0 };
}

let p = Point.origin();

Enums

SPIDER enums allow variants with optional data. Similar to Rust enums.

---

Basic Enum

enum Status {
    Online,
    Offline,
    Busy
}
---

Enum With Data

enum Response {
    Ok(str),
    Err(str)
}
---

Using Enums

let s = Status.Online;

match s {
    case Online {
        println("User online");
    }
    case Offline {
        println("User offline");
    }
    case Busy {
        println("User busy");
    }
}
---

Enum With Data Example

let r = Response.Ok("Success");

match r {
    case Ok(msg) {
        println("OK: " + msg);
    }
    case Err(e) {
        println("ERROR: " + e);
    }
}

Result, Ok, Err

Result is built into the lexer: Result, Ok, Err

Used for fallible operations. ---

Returning Result

func read_safe(path: str) -> Result {
    try {
        let data = read_file(path);
        return Ok(data);
    } catch err {
        return Err(err);
    }
}
---

Using Result

let res = read_safe("config.json");

match res {
    case Ok(data) {
        println("Loaded!");
    }
    case Err(e) {
        println("Failed: " + e);
    }
}
---

Helper pattern

func divide(a: int, b: int) -> Result {
    if b == 0 {
        return Err("divide by zero");
    }
    return Ok(a / b);
}

Pattern Destructuring

SPIDER supports pattern binding inside match for structs and enums.

---

Destructuring Structs

struct User {
    name: str,
    age: int
}

let u = User { name: "Eve", age: 19 };

match u {
    case User { name, age } {
        println(name);
        println(age);
    }
}
---

Partial Struct Bind

match u {
    case User { name } {
        println(name);
    }
}
---

Destructuring Enums (Variants With Data)

enum Message {
    Text(str),
    Ping,
    Error(int, str)
}

let m = Message.Error(404, "Not Found");

match m {
    case Text(t) {
        println("msg: " + t);
    }
    case Ping {
        println("ping received");
    }
    case Error(code, msg) {
        println(format("ERR {}: {}", code, msg));
    }
}

Type System Overview

SPIDER has the following primitive types:
TypeDescription
intSigned 64-bit integer
uintUnsigned 64-bit integer
float64-bit floating point
booltrue / false
strUTF-8 string
bytesRaw byte array
ptrPointer (unsafe)
voidNo return
---

Collections

---

Custom Types

---

Type Inference

let a = 10;       // int
let b = 4.2;      // float
let c = "hi";     // str
let d = [1,2,3];  // array[int]
---

Type Mismatch Errors

let x = 10;
x = "hello";     // ERROR: cannot assign str to int
---

Explicit Casting

let x = to_float(10);
let n = to_int("42");

Complete Examples

Example 1: Struct + Method

struct Counter {
    val: int
}

func Counter.inc(self) {
    self.val = self.val + 1;
}

func main() -> int {
    let c = Counter { val: 0 };
    c.inc();
    println(c.val);
    return 0;
}
---

Example 2: Enum State Machine

enum State {
    Idle,
    Working(int),
    Error(str)
}

func describe(s: State) -> str {
    match s {
        case Idle { return "idle"; }
        case Working(x) { return format("working: {}", x); }
        case Error(e) { return "error: " + e; }
    }
}
---

Example 3: Result + Struct

struct Creds {
    user: str,
    pass: str
}

func load_creds(path: str) -> Result {
    try {
        let txt = read_file(path);
        let parts = split(txt, ":");
        return Ok(Creds { user: parts[0], pass: parts[1] });
    } catch err {
        return Err(err);
    }
}
---

Example 4: Struct With Embedded Enum

enum Mode {
    Debug,
    Release
}

struct BuildConfig {
    name: str,
    mode: Mode
}

let cfg = BuildConfig {
    name: "SPIDER",
    mode: Mode.Debug
};


SPIDER Memory Model

SPIDER uses a simple but powerful memory model designed for:

---

Stack vs Heap

LocationStored Types
StackPrimitives (int, float, bool) + local references
Heapstr, bytes, array, map, struct, enum
Each heap object has: - **Header**: type tag, length, refcount - **Body**: real data ---

Value semantics

Primitive values are copied:
let a = 10;
let b = a;
b = 20;   // does NOT change a
Heap values are reference-counted:
let a = [1,2,3];
let b = a;
b.push(4);

println(a);   // [1,2,3,4]
**SPIDER uses implicit shared references unless cloned.** ---

clone()

let a = [1,2,3];
let b = clone(a);

b.push(99);
println(a); // [1,2,3]
println(b); // [1,2,3,99]
---

Refcounting Notes

- Strings, arrays, maps share pointers by default. - When mutated, SPIDER performs **copy-on-write**. - Structs behave similarly: fields reference heap objects until mutation. ---

Pointers

SPIDER includes an explicit pointer type due to the `` token. It is part of the **unsafe** system. ---

Pointer Basics

let x = 10;
let p: ptr = &x;
---

Dereferencing

Requires unsafe:
unsafe {
    println(*p);
}
---

Mutating Through Pointer

let x = 5;
let p = &x;

unsafe {
    *p = 999;
}

println(x);    // 999
---

Raw Pointer From Address

Useful for exploit dev:
let p: ptr = ptr_from_uint(0x7fffdeadbeef);
---

Pointer Arithmetic

SPIDER supports:
unsafe {
    let q = p + 4;  // move forward 4 bytes
}
Only allowed inside `unsafe`. ---

Null Pointer

let p: ptr = null;
---

unsafe { ... }

Unsafe blocks allow: - pointer dereference - raw memory writes - bypassing bounds checks - direct buffer access - manual address manipulation Example:
unsafe {
    let p = &x;
    *p = 1337;
}
---

Fused Pointer + Bytes Model

You can cast arrays/bytes into pointers:
let buf = bytes("AAAA");
let p = &buf[0];

unsafe {
    *p = 0x42;    // replace first byte with 'B'
}
---

ptr → bytes

let slice = bytes_from_ptr(p, len=16);
---

Why unsafe is needed?

You designed SPIDER for: - shellcode building - ROP payload generation - memory scanners - exploit writing So yes — giving devs raw memory access **fits your language’s purpose.** ---

Bytes & Memory Buffers

SPIDER has a built-in bytes type and BytesLit literal. ---

Byte Literal

let buf = b"hello";
println(buf);        // [68, 65, 6C, 6C, 6F]
---

Pushing bytes

buf.push(0x41);
---

Index Access

println(buf[0]);  // 0x68
---

Slice

let part = buf[0..2];
---

bytes → string

let s = to_string(buf);
---

string → bytes

let b = to_bytes("ABC");
---

Zero-copy conversions

SPIDER can convert between: - `str` - `bytes` - `array[uint8]` WITHOUT reallocating. Because the internal representation is: ``` [header | fat pointer | data pointer | length | capacity] ``` Same for all three. ---

Internal Values Representation

Your runtime (based on lexer assumptions) uses type-tagged heap blocks. ---

Primitives

| Type | Storage | |------|---------| | int | 8 bytes | | uint | 8 bytes | | float | 8 bytes | | bool | 1 byte | Stored directly on stack or struct fields. ---

Strings

Layout: ``` struct String { refcount: uint len: uint capacity: uint ptr: *u8 } ``` ---

Arrays

``` struct Array { refcount: uint len: uint capacity: uint ptr: *Value } ``` ---

Maps

Hashmap with pointer to key/value heap buckets. ---

Struct

A struct is a compact heap object: ``` refcount field0 field1 field2 ... ``` ---

Enums

Representation: ``` tag: uint payload: union { ... } ``` Equivalent to Rust, zig, etc. ---

FULL UNSAFE EXAMPLES

Example 1: Manual Shellcode Writer

let buf = alloc(64);

unsafe {
    let p = &buf[0];
    *p       = 0x48;   // mov rax, 1
    *(p + 1) = 0x31;
    *(p + 2) = 0xC0;
}

exec(buf);
---

Example 2: Pointer Scan

func memscan(start: ptr, end: ptr, target: int) {
    unsafe {
        let p = start;
        while p < end {
            if *p == target {
                println(format("FOUND AT {}", ptr_to_uint(p)));
            }
            p = p + 1;
        }
    }
}
---

Example 3: Struct Packed Buffer

struct Header {
    id: uint,
    size: uint,
    flags: uint
}

let h = Header { id: 1, size: 40, flags: 0xFF };

unsafe {
    let p = &h;
    println(ptr_to_uint(p));
}
---

Example 4: Manual Object Construction

unsafe {
    let mem = alloc_raw(32);
    let p: ptr = mem;

    *(p+0) = 0x41;
    *(p+1) = 0x42;
    *(p+2) = 0x43;

    println(bytes_from_ptr(p, 3)); // ABC
}
---

Example 5: Breaking Out of Bounds (intentional)

let arr = [1,2,3];

unsafe {
    let p = &arr[0];
    *(p + 10) = 999;    // OOB write
}
Yes, SPIDER lets you do this. That’s why **unsafe** exists. ---

Example 6: Casting ptr → struct

let mem = alloc_raw(sizeof(Header));
let p = mem;

let h: Header = from_ptr(p);
---

Example 7: Casting ptr → function

unsafe {
    let fnptr: func() = from_ptr(0x401000);
    fnptr();
}
*(Your VM may or may not allow execution. This is for doc spec completeness.)* ---

SPIDER STANDARD LIBRARY — FULL DOCS

The SPIDER runtime ships with a powerful standard library designed for:


Crypto Module

SPIDER includes built-in AES-256, XOR streams, hash functions, and Base64. ---

AES-256

encrypt(data: bytes or str, key: bytes) -> bytes

decrypt(data: bytes, key: bytes) -> bytes

let ciphertext = encrypt("hello", b"supersecretkeysupersecretkey!!");
let plaintext  = decrypt(ciphertext, b"supersecretkeysupersecretkey!!");
Key must be **32 bytes**. ---

XOR

let out = xor("HELLO", "KEY");
println(out);
---

Hashing

hash(data: bytes or str, algo: str = "SHA256") -> str

Supports: `MD5`, `SHA1`, `SHA256`, `SHA512`.
println(hash("test"));
---

Base64

base64_encode(data) -> str

base64_decode(str) -> bytes

let e = base64_encode("spider");
println(e);
println(base64_decode(e));

Networking Module

Supports full TCP/UDP sockets & packet-level operations. ---

Create Socket

let s = socket("tcp");
s.connect("127.0.0.1", 8080);
s.send("hello");
let r = s.recv(1024);
s.close();
---

UDP

let u = socket("udp");
u.send_to("hi", "8.8.8.8", 53);
---

Packet Builder

let pkt = packet();
pkt.write_u8(0x41);
pkt.write_u16(80);
pkt.write_str("HTTP");
send_raw(pkt);
---

HTTP(S) Simple Requests

let data = http_get("https://example.com");
println(data);
---

Listener

let server = socket("tcp");
server.bind("0.0.0.0", 4444);
server.listen(10);

while true {
    let client = server.accept();
    client.send("connected\n");
}
---

Scan API

scan("127.0.0.1", ports=[22,80,443]);
---

Exploit API

exploit("CVE-TEST-OVERFLOW", target="127.0.0.1");
*(This is your language’s internal mechanism, you define what exploits exist.)* ---

Threads

spawn(func() { ... }) -> Thread

let t = spawn(|| {
    println("Thread running");
});
t.join();
---

Sleep

sleep(1000); // 1 second
---

Locks

let lock = mutex();

spawn(|| {
    lock.acquire();
    println("A");
    lock.release();
});
---

Atomic Integers

let a = atomic(0);
a.inc();
println(a.get());
---

Process Module

Shell Execution

let out = shell("whoami");
println(out);
---

spawn_process

let p = process("ping 8.8.8.8");
p.read_line();
p.kill();
---

Memory / Exploit Functions

These APIs pair with `unsafe` from Chunk 10. ---

alloc(size: int) -> bytes

Allocates a mutable buffer.
let buf = alloc(64);
---

alloc_raw(size: int) -> ptr

let p = alloc_raw(32);
---

memcpy(dst: ptr, src: ptr, len: int)

memset(ptr: ptr, value: int, len: int)

---

find_pattern(haystack: bytes, pattern: bytes) -> int?

---

inject(pid: int, payload: bytes)

User-defined; SPIDER provides a call entry but implementation is up to the runtime. ---

hook(address: ptr, detour: ptr)

Low-level:
unsafe {
    hook(0x401000, my_hook_ptr);
}
---

process_memory(pid: int) -> MemoryView

let mem = process_memory(1337);
let bytes = mem.read(0x7ffdf000, 64);
---

Filesystem Summary

(*See Chunk 6 for full docs.*) Key functions: - read_file / read_bytes - write_file / append_file - list_dir - path tools - file metadata API ---

Time Module

now() -> int

UNIX timestamp.

format_time(ts: int) -> str

println(format_time(now()));

sleep(ms: int)

---

Random

random_int(min, max)

random_bytes(len)

let key = random_bytes(32);
---

Encoding Utilities

hex_encode / hex_decode

println(hex_encode(b"ABC"));
println(hex_decode("414243"));

url_encode / url_decode

---

Reflection

type_of(value) -> str

fields(struct_instance) -> array[str]

methods(obj) -> array[str]

---

Debug Tools

dump(value)

Pretty prints a value with full internal structure.
dump(my_struct);

assert(expr)

---

Error Tools

panic(msg: str)

Halts execution.

recover()

Returns current error (if in catch). ---

String Utilities

split(str, sep) -> array[str]

join(array, sep) -> str

replace(str, from, to) -> str

trim(str)

---

Math

abs(x)

floor(x)

ceil(x)

sqrt(x)

pow(a,b)

sin/cos/tan

---


SPIDER Module System

SPIDER provides a lightweight but powerful module system built around two keywords:

The system is designed to be:


1. Using dep

Syntax:
dep "path/to/module.sp";
Example:
// main.sp
dep "crypto.sp";
dep "utils/math.sp";

println(add(10, 20));
println(aes_encrypt("hi", KEY));
SPIDER resolves imports **relative to the current file**, unless absolute pathing is used. ---

Import once rule

SPIDER guarantees that each module is executed **only once**, even if imported multiple times:
dep "a.sp";
dep "a.sp"; // ignored second time
---

Import namespace behavior

By default, imported symbols become available in the current namespace **only if exported**:
// crypto.sp
export func aes_encrypt(data, key) {
    ...
}
---

Namespace override

SPIDER allows optional local namespace assignment:
dep "crypto.sp" as crypto;

crypto.aes_encrypt("data", key);
---

Importing directories (module trees)

If "utils/" is a folder:
dep "utils";
This loads: - utils/index.sp (preferred if exists) - OR all `.sp` files inside utils/ ---

2. Using export

A module exports values explicitly:
export let PI = 3.141;

export func add(a,b) {
    return a+b;
}

export struct Vec2 {
    x: float,
    y: float
}
Everything **not** marked `export` is private. This makes SPIDER modules clean and safe — avoids symbol pollution. ---

Re-exporting

export from "math/base.sp";
This exposes all exports from base.sp as part of the current module. ---

3. Module Resolution Rules

When you write:
dep "crypto";
SPIDER tries the following in order: 1. `crypto.sp` (same directory) 2. `crypto/index.sp` 3. `/crypto.sp` 4. `/crypto/index.sp` 5. `stdlib/crypto.sp` (built-in module) 6. Error if not found ---

Absolute imports

Start with `/`:
dep "/home/user/scripts/exploit.sp";
Works on Linux and Windows (`C:\path\to\module.sp` also supported). ---

Module caching

SPIDER keeps a global cache: ``` loaded_modules = { "crypto.sp": { exports }, "utils/math.sp": { exports } } ``` So repeated imports cost **zero runtime**. ---

4. Circular Imports

SPIDER *allows* circular imports **as long as exported values are not required before definition.** Example:
// a.sp
dep "b.sp";
export func A() { println("A"); }

// b.sp
dep "a.sp";
export func B() { println("B"); }
SPIDER resolves them lazily: - Loads module A - Reads its export table - Loads module B - Links both But this fails:
// a.sp
dep "b.sp";
export func A() { B(); }   // ERROR: B not fully defined yet

// b.sp
dep "a.sp";
export func B() { A(); }
SPIDER reports **circular dependency resolution error**. ---

5. Organizing Larger SPIDER Projects

Recommended layout: ``` /myproject /src main.sp crypto.sp net.sp utils/ math.sp strings.sp /tests math_test.sp ``` ---

main.sp example

dep "crypto.sp";
dep "net.sp";
dep "utils/math.sp";

println(add(5, 5));
println(hash("hi"));
connect_and_scan("192.168.1.1");
---

6. SPIDER Standard Library Modules

crypto Hashing, AES256, XOR, Base64 net Sockets, packets, HTTP, scanners fs File IO, directory tools, paths sys System info, runtime, exec, env vars thread Concurrency, mutex, atomics process Process control, spawn, kill, pipes memory Unsafe buffers, pointers, scanning math Core math operations string Format, split, join, replace time now(), sleep(), timers debug dump(), assert(), profile() ---

A full import example:

dep "std/net" as net;
dep "std/crypto" as crypto;

let data = net.http_get("https://kernelcore.dev");
let h = crypto.hash(data);

println(h);
---

7. Module Introspection

SPIDER allows introspecting imported modules:
let m = module_info("crypto");

println(m.name);
println(m.exports); // list of exported symbols
---

8. Examples

Example A — Crypto Toolkit

crypto.sp
export func encrypt_file(path, key) {
    let data = read_file(path);
    let enc = encrypt(data, key);
    write_file(path + ".enc", enc);
}
main.sp
dep "crypto.sp";

encrypt_file("secrets.txt", b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
---

Example B — Scanner Tool

scan.sp
export func scan_host(host) {
    for p in 1..1024 {
        if port_open(host, p) {
            println(format("{} open", p));
        }
    }
}
main.sp
dep "scan.sp";

scan_host("127.0.0.1");
---

Example C — Shared Struct Between Modules

models/user.sp
export struct User {
    id: int,
    name: str
}
main.sp
dep "models/user.sp";

let u = User { id: 1, name: "KCdev" };
println(u.name);
---

SPIDER Virtual Machine (SPVM)

The SPVM is a register-based bytecode interpreter designed to run SPIDER programs efficiently and safely (unless unsafe blocks are used). It executes instructions produced by the compiler after parsing + semantic analysis.

---

VM Architecture Overview

  • Register-based (16 general purpose registers)
  • Dedicated pointer registers
  • Separate Call Stack & Value Heap
  • Reference-counted heap objects
  • Native function interface (C ABI)
  • Optional JIT backend
---

Register Layout

RegisterDescription
R0–R15General-purpose registers for values
FPFrame pointer
SPStack pointer
IPInstruction pointer
HPHeap top pointer
ERRError flag register
PTR0–PTR3Raw pointer registers for unsafe ops
---

Value Representation

A value in SPVM is: ``` struct Value { tag: u8 // type tag payload: 8 bytes } ``` Type tags: - 0x01 int - 0x02 uint - 0x03 float - 0x04 bool - 0x10 str (heap ref) - 0x11 bytes - 0x12 array - 0x13 map - 0x20 ptr - 0x30 struct instance - 0x40 enum variant ---

Bytecode Format

Instruction Layout (Fixed 1-byte opcode)

``` [ OPCODE | ARG1 | ARG2 | ARG3 / IMM ] ``` Examples: - `ADD R1, R2, R3` → R1 = R2 + R3 - `LOADK R1, #123` → R1 = constant 123 - `CALL func_id, argc` Arguments are encoded depending on instruction type. ---

Function Bytecode Object

``` Function { constants: [Value] locals: u32 regs: u8 instructions: [u8] debug_info: optional } ``` Modules simply export functions. ---

SPIDER Bytecode Instruction Set

Below is the **full opcode table**. --- ## **Category 1 — Constants & Moves** | Opcode | Mnemonic | Description | |--------|----------|-------------| | 0x01 | MOV A,B | A = B | | 0x02 | LOADK A, const_id | load constant from table | | 0x03 | LOADI A, imm64 | load integer | | 0x04 | LOADF A, imm64 | load float | | 0x05 | LOADI1 A, imm8 | low-cost small-int load | Example: ``` LOADI R1, #100 ``` --- ## **Category 2 — Arithmetic** | Opcode | Operation | |--------|------------| | 0x10 | ADD A,B,C | | 0x11 | SUB A,B,C | | 0x12 | MUL A,B,C | | 0x13 | DIV A,B,C | | 0x14 | MOD A,B,C | | 0x15 | POW A,B,C | --- ## **Category 3 — Logical Operations** | Opcode | Description | |--------|-------------| | 0x20 | AND A,B,C | | 0x21 | OR A,B,C | | 0x22 | XOR A,B,C | | 0x23 | NOT A,B | | 0x24 | CMP A,B → flags | --- ## **Category 4 — Branching & Jumps** | Opcode | Meaning | |--------|---------| | 0x30 | JMP target | | 0x31 | JMPT reg, target | | 0x32 | JMPF reg, target | | 0x33 | SWITCH reg, table_id | Switch-table is resolved at compile time. --- ## **Category 5 — Function Calls** | Opcode | Meaning | |--------|---------| | 0x40 | CALL func_id, argc | | 0x41 | RET reg | | 0x42 | TAILCALL func_id | --- Next: Function call frame layout: ``` [ previous FP ] [ return address ] [ locals... ] [ registers... ] ``` `FP` and `SP` track this. --- ## **Category 6 — Heap Operations** | Opcode | Meaning | |--------|---------| | 0x50 | NEWSTR A,len | | 0x51 | NEWBYTES A,len | | 0x52 | NEWARRAY A,len | | 0x53 | NEWMAP A | | 0x54 | REFCOUNT_INC A | | 0x55 | REFCOUNT_DEC A | | 0x56 | CLONE A,B | Strings, arrays, maps are heap pointers. --- ## **Category 7 — Array & Map Ops** | Opcode | Description | |--------|-------------| | 0x60 | ARR_GET A, arr, idx | | 0x61 | ARR_SET arr, idx, val | | 0x62 | ARR_PUSH arr, val | | 0x63 | ARR_LEN A, arr | | 0x64 | MAP_GET A, map, key | | 0x65 | MAP_SET map, key, val | | 0x66 | MAP_HAS A,map,key | --- ## **Category 8 — Strings / Bytes** | Opcode | Description | |--------|-------------| | 0x70 | STR_CONCAT A,B,C | | 0x71 | STR_SLICE A,B,C | | 0x72 | STR_LEN A,B | | 0x73 | BYTES_SLICE A,B,C | | 0x74 | BYTES_SET arr, idx, val | --- ## **Category 9 — System Calls (SysOps)** These opcodes call out of the VM into native code: | Opcode | Description | |--------|-------------| | 0x80 | SYS_FS (filesystem API) | | 0x81 | SYS_NET (networking API) | | 0x82 | SYS_CRYPTO | | 0x83 | SYS_PROCESS | | 0x84 | SYS_THREAD | | 0x85 | SYS_TIME | | 0x86 | SYS_RANDOM | | 0x87 | SYS_DEBUG | Example: ``` SYS_NET SEND R1,R2,R3 ``` --- ## **Category 10 — Error Handling** | Opcode | Description | |--------|-------------| | 0x90 | THROW reg | | 0x91 | SET_TRY handler_offset | | 0x92 | CLEAR_TRY | This powers SPIDER’s `try/catch`. --- ## **Category 11 — Unsafe / Pointer Ops** (Allowed **only within unsafe blocks**) | Opcode | Meaning | |--------|---------| | 0xA0 | PTR_LOAD A, ptr_reg | | 0xA1 | PTR_STORE ptr_reg, value | | 0xA2 | PTR_ADD ptr_reg, imm | | 0xA3 | PTR_SUB ptr_reg, imm | | 0xA4 | PTR_CAST A, ptr_reg | | 0xA5 | PTR_FROM_UINT A, imm64 | | 0xA6 | PTR_TO_UINT A, ptr_reg | | 0xA7 | MEMCPY dst,src,len | | 0xA8 | MEMSET dst,val,len | These directly manipulate memory — exactly what exploit dev needed. --- ## **Category 12 — Structs & Enums** | Opcode | Description | |--------|-------------| | 0xB0 | NEWSTRUCT A,type_id | | 0xB1 | STRUCT_GET A, obj, field_id | | 0xB2 | STRUCT_SET obj, field_id, val | | 0xB3 | NEWENUM A,tag,payload | --- ## **Category 13 — VM Internal / Control** | Opcode | Description | |--------|-------------| | 0xC0 | NOP | | 0xC1 | HALT | | 0xC2 | DEBUG_BREAK | ---
# **VM EXECUTION CYCLE** Pseudo-code: ``` loop: instr = bytecode[IP] switch instr.opcode: case ADD: R[A] = R[B] + R[C] case CALL: push_frame(...) IP = func.entry case RET: pop_frame(...) IP = return_addr ... IP++ ``` ---
# **CALL STACK FRAME FORMAT** Each call pushes: ``` [ return_address ] [ previous FP ] [ locals ] [ registers ] ``` On return, VM restores FP and IP. ---
# **MODULE LOADING IN VM** When `dep "file.sp"` is encountered: 1. Loader hashes path 2. Checks module cache 3. If new: - Parse file - Compile to bytecode - Create function objects - Register symbols 4. Return module export table Modules never re-execute. ---
# **DEBUGGER HOOKS** The VM supports optional debugger mode. Breakpoint instruction: ``` DEBUG_BREAK ``` Debugger can inspect: - registers - stack - heap objects - pointer registers - bytecode disassembly ---
# **EXAMPLE: COMPILED BYTECODE DUMP** Source: ``` let x = 10; let y = x + 20; println(y); ``` Bytecode: ``` LOADI R1, #10 LOADI R2, #20 ADD R3,R1,R2 SYS_DEBUG PRINT R3 HALT ``` ---