feat: add example scripts for argparse, bytes, dataset, html, markdown, uuid, wdantic, and web chat modules

Add comprehensive demo scripts showcasing the usage of multiple Wren modules including argument parsing, byte manipulation, in-memory dataset operations, HTML encoding/slugification, markdown-to-HTML conversion, UUID generation/validation, schema validation with wdantic, and a full web chat application with REST endpoints.
This commit is contained in:
2026-01-24 22:40:22 +00:00
parent 0a65272f80
commit 5a4054ec66
105 changed files with 23275 additions and 94 deletions
+267
View File
@@ -0,0 +1,267 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>base64 - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html" class="active">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>base64</span>
</nav>
<article>
<h1>base64</h1>
<p>The <code>base64</code> module provides Base64 encoding and decoding functionality, including URL-safe variants.</p>
<pre><code>import "base64" for Base64</code></pre>
<h2>Base64 Class</h2>
<div class="class-header">
<h3>Base64</h3>
<p>Base64 encoding and decoding utilities</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Base64.encode</span>(<span class="param">data</span>) &#8594; <span class="type">String</span>
</div>
<p>Encodes data to standard Base64.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String)</span> - Data to encode</li>
<li><span class="returns">Returns:</span> Base64-encoded string</li>
</ul>
<pre><code>var encoded = Base64.encode("Hello, World!")
System.print(encoded) // SGVsbG8sIFdvcmxkIQ==</code></pre>
<div class="method-signature">
<span class="method-name">Base64.decode</span>(<span class="param">data</span>) &#8594; <span class="type">String</span>
</div>
<p>Decodes a Base64-encoded string.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String)</span> - Base64 string to decode</li>
<li><span class="returns">Returns:</span> Decoded data as a string</li>
</ul>
<pre><code>var decoded = Base64.decode("SGVsbG8sIFdvcmxkIQ==")
System.print(decoded) // Hello, World!</code></pre>
<div class="method-signature">
<span class="method-name">Base64.encodeUrl</span>(<span class="param">data</span>) &#8594; <span class="type">String</span>
</div>
<p>Encodes data to URL-safe Base64. Replaces <code>+</code> with <code>-</code>, <code>/</code> with <code>_</code>, and removes padding.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String)</span> - Data to encode</li>
<li><span class="returns">Returns:</span> URL-safe Base64 string (no padding)</li>
</ul>
<pre><code>var encoded = Base64.encodeUrl("Hello, World!")
System.print(encoded) // SGVsbG8sIFdvcmxkIQ</code></pre>
<div class="method-signature">
<span class="method-name">Base64.decodeUrl</span>(<span class="param">data</span>) &#8594; <span class="type">String</span>
</div>
<p>Decodes a URL-safe Base64 string. Handles strings with or without padding.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String)</span> - URL-safe Base64 string to decode</li>
<li><span class="returns">Returns:</span> Decoded data as a string</li>
</ul>
<pre><code>var decoded = Base64.decodeUrl("SGVsbG8sIFdvcmxkIQ")
System.print(decoded) // Hello, World!</code></pre>
<h2>Encoding Comparison</h2>
<table>
<tr>
<th>Method</th>
<th>Alphabet</th>
<th>Padding</th>
<th>Use Case</th>
</tr>
<tr>
<td><code>encode</code></td>
<td>A-Z, a-z, 0-9, +, /</td>
<td>Yes (=)</td>
<td>General purpose, email, file storage</td>
</tr>
<tr>
<td><code>encodeUrl</code></td>
<td>A-Z, a-z, 0-9, -, _</td>
<td>No</td>
<td>URLs, filenames, JWT tokens</td>
</tr>
</table>
<h2>Examples</h2>
<h3>Basic Encoding and Decoding</h3>
<pre><code>import "base64" for Base64
var original = "The quick brown fox jumps over the lazy dog"
var encoded = Base64.encode(original)
System.print("Encoded: %(encoded)")
var decoded = Base64.decode(encoded)
System.print("Decoded: %(decoded)")
System.print("Match: %(original == decoded)")</code></pre>
<h3>Binary Data Encoding</h3>
<pre><code>import "base64" for Base64
var binaryData = String.fromCodePoint(0) +
String.fromCodePoint(1) +
String.fromCodePoint(255)
var encoded = Base64.encode(binaryData)
System.print("Encoded binary: %(encoded)")
var decoded = Base64.decode(encoded)
System.print("Byte 0: %(decoded.bytes[0])")
System.print("Byte 1: %(decoded.bytes[1])")
System.print("Byte 2: %(decoded.bytes[2])")</code></pre>
<h3>URL-Safe Encoding for Tokens</h3>
<pre><code>import "base64" for Base64
import "crypto" for Crypto, Hash
var data = "user:12345"
var token = Base64.encodeUrl(data)
System.print("Token: %(token)")
var decodedToken = Base64.decodeUrl(token)
System.print("Decoded: %(decodedToken)")</code></pre>
<h3>HTTP Basic Authentication</h3>
<pre><code>import "base64" for Base64
import "http" for Http
var username = "alice"
var password = "secret123"
var credentials = Base64.encode("%(username):%(password)")
var headers = {
"Authorization": "Basic %(credentials)"
}
var response = Http.get("https://api.example.com/protected", headers)
System.print(response.body)</code></pre>
<h3>Data URI Encoding</h3>
<pre><code>import "base64" for Base64
import "io" for File
var imageData = File.read("image.png")
var encoded = Base64.encode(imageData)
var dataUri = "data:image/png;base64,%(encoded)"
System.print(dataUri)</code></pre>
<h3>JWT-Style Token Parts</h3>
<pre><code>import "base64" for Base64
import "json" for Json
var header = {"alg": "HS256", "typ": "JWT"}
var payload = {"sub": "1234567890", "name": "John Doe"}
var headerB64 = Base64.encodeUrl(Json.stringify(header))
var payloadB64 = Base64.encodeUrl(Json.stringify(payload))
System.print("Header: %(headerB64)")
System.print("Payload: %(payloadB64)")</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Base64 encoding increases data size by approximately 33%. A 3-byte input becomes 4 Base64 characters.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>Use <code>encodeUrl</code> and <code>decodeUrl</code> when the encoded string will be used in URLs, query parameters, or filenames where <code>+</code>, <code>/</code>, and <code>=</code> characters may cause issues.</p>
</div>
</article>
<footer class="page-footer">
<a href="json.html" class="prev">json</a>
<a href="regex.html" class="next">regex</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+315
View File
@@ -0,0 +1,315 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>crypto - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html" class="active">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>crypto</span>
</nav>
<article>
<h1>crypto</h1>
<p>The <code>crypto</code> module provides cryptographic functions including secure random number generation and hash algorithms.</p>
<pre><code>import "crypto" for Crypto, Hash</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#crypto-class">Crypto Class</a></li>
<li><a href="#hash-class">Hash Class</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="crypto-class">Crypto Class</h2>
<div class="class-header">
<h3>Crypto</h3>
<p>Cryptographic random number generation</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Crypto.randomBytes</span>(<span class="param">length</span>) &#8594; <span class="type">List</span>
</div>
<p>Generates cryptographically secure random bytes.</p>
<ul class="param-list">
<li><span class="param-name">length</span> <span class="param-type">(Num)</span> - Number of bytes to generate (must be non-negative)</li>
<li><span class="returns">Returns:</span> List of random byte values (0-255)</li>
</ul>
<pre><code>var bytes = Crypto.randomBytes(16)
System.print(bytes) // [142, 55, 201, 89, ...]</code></pre>
<div class="method-signature">
<span class="method-name">Crypto.randomInt</span>(<span class="param">min</span>, <span class="param">max</span>) &#8594; <span class="type">Num</span>
</div>
<p>Generates a cryptographically secure random integer in the specified range.</p>
<ul class="param-list">
<li><span class="param-name">min</span> <span class="param-type">(Num)</span> - Minimum value (inclusive)</li>
<li><span class="param-name">max</span> <span class="param-type">(Num)</span> - Maximum value (exclusive)</li>
<li><span class="returns">Returns:</span> Random integer in range [min, max)</li>
</ul>
<pre><code>var roll = Crypto.randomInt(1, 7) // Dice roll: 1-6
System.print(roll)</code></pre>
<h2 id="hash-class">Hash Class</h2>
<div class="class-header">
<h3>Hash</h3>
<p>Cryptographic hash functions</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Hash.md5</span>(<span class="param">data</span>) &#8594; <span class="type">List</span>
</div>
<p>Computes the MD5 hash of the input data.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String|List)</span> - Data to hash (string or list of bytes)</li>
<li><span class="returns">Returns:</span> 16-byte hash as a list of bytes</li>
</ul>
<pre><code>var hash = Hash.md5("Hello, World!")
System.print(Hash.toHex(hash)) // 65a8e27d8879283831b664bd8b7f0ad4</code></pre>
<div class="method-signature">
<span class="method-name">Hash.sha1</span>(<span class="param">data</span>) &#8594; <span class="type">List</span>
</div>
<p>Computes the SHA-1 hash of the input data.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String|List)</span> - Data to hash</li>
<li><span class="returns">Returns:</span> 20-byte hash as a list of bytes</li>
</ul>
<pre><code>var hash = Hash.sha1("Hello, World!")
System.print(Hash.toHex(hash)) // 0a0a9f2a6772942557ab5355d76af442f8f65e01</code></pre>
<div class="method-signature">
<span class="method-name">Hash.sha256</span>(<span class="param">data</span>) &#8594; <span class="type">List</span>
</div>
<p>Computes the SHA-256 hash of the input data.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String|List)</span> - Data to hash</li>
<li><span class="returns">Returns:</span> 32-byte hash as a list of bytes</li>
</ul>
<pre><code>var hash = Hash.sha256("Hello, World!")
System.print(Hash.toHex(hash)) // dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f</code></pre>
<div class="method-signature">
<span class="method-name">Hash.toHex</span>(<span class="param">bytes</span>) &#8594; <span class="type">String</span>
</div>
<p>Converts a list of bytes to a hexadecimal string.</p>
<ul class="param-list">
<li><span class="param-name">bytes</span> <span class="param-type">(List)</span> - List of byte values</li>
<li><span class="returns">Returns:</span> Lowercase hexadecimal string</li>
</ul>
<pre><code>var hex = Hash.toHex([0xDE, 0xAD, 0xBE, 0xEF])
System.print(hex) // deadbeef</code></pre>
<h2>Hash Algorithm Comparison</h2>
<table>
<tr>
<th>Algorithm</th>
<th>Output Size</th>
<th>Security</th>
<th>Use Case</th>
</tr>
<tr>
<td>MD5</td>
<td>128 bits (16 bytes)</td>
<td>Broken</td>
<td>Checksums only (not for security)</td>
</tr>
<tr>
<td>SHA-1</td>
<td>160 bits (20 bytes)</td>
<td>Weak</td>
<td>Legacy compatibility only</td>
</tr>
<tr>
<td>SHA-256</td>
<td>256 bits (32 bytes)</td>
<td>Strong</td>
<td>Recommended for new applications</td>
</tr>
</table>
<h2 id="examples">Examples</h2>
<h3>Generating a Random Token</h3>
<pre><code>import "crypto" for Crypto, Hash
var bytes = Crypto.randomBytes(32)
var token = Hash.toHex(bytes)
System.print("Random token: %(token)")</code></pre>
<h3>Password Hashing</h3>
<pre><code>import "crypto" for Crypto, Hash
var password = "mysecretpassword"
var salt = Crypto.randomBytes(16)
var saltHex = Hash.toHex(salt)
var saltedPassword = saltHex + password
var hash = Hash.sha256(saltedPassword)
var hashHex = Hash.toHex(hash)
System.print("Salt: %(saltHex)")
System.print("Hash: %(hashHex)")</code></pre>
<h3>File Checksum</h3>
<pre><code>import "crypto" for Hash
import "io" for File
var content = File.read("document.txt")
var hash = Hash.sha256(content)
System.print("SHA-256: %(Hash.toHex(hash))")</code></pre>
<h3>Random Selection</h3>
<pre><code>import "crypto" for Crypto
var items = ["apple", "banana", "cherry", "date", "elderberry"]
var index = Crypto.randomInt(0, items.count)
System.print("Selected: %(items[index])")</code></pre>
<h3>Generating Random IDs</h3>
<pre><code>import "crypto" for Crypto, Hash
import "base64" for Base64
var bytes = Crypto.randomBytes(12)
var id = ""
for (b in bytes) {
id = id + String.fromCodePoint(b)
}
var encoded = Base64.encodeUrl(id)
System.print("Random ID: %(encoded)")</code></pre>
<h3>Secure Dice Roll</h3>
<pre><code>import "crypto" for Crypto
var numDice = 5
var results = []
for (i in 0...numDice) {
results.add(Crypto.randomInt(1, 7))
}
System.print("Dice rolls: %(results)")</code></pre>
<h3>Comparing Hashes</h3>
<pre><code>import "crypto" for Hash
var original = "Hello, World!"
var hash1 = Hash.sha256(original)
var hash2 = Hash.sha256(original)
var hash3 = Hash.sha256("Different text")
System.print("Same input, same hash: %(Hash.toHex(hash1) == Hash.toHex(hash2))")
System.print("Different input, different hash: %(Hash.toHex(hash1) != Hash.toHex(hash3))")</code></pre>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>MD5 and SHA-1 are cryptographically broken and should not be used for security-sensitive applications. Use SHA-256 for new applications requiring secure hashing.</p>
</div>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Hash functions accept both strings and lists of bytes. When a string is provided, it is automatically converted to its byte representation before hashing.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>For password storage, always use a salt (random bytes prepended to the password) before hashing. Store the salt alongside the hash for verification.</p>
</div>
</article>
<footer class="page-footer">
<a href="jinja.html" class="prev">jinja</a>
<a href="os.html" class="next">os</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+464
View File
@@ -0,0 +1,464 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>datetime - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html" class="active">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>datetime</span>
</nav>
<article>
<h1>datetime</h1>
<p>The <code>datetime</code> module provides date and time handling with formatting, arithmetic, and duration support.</p>
<pre><code>import "datetime" for DateTime, Duration</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#datetime-class">DateTime Class</a></li>
<li><a href="#duration-class">Duration Class</a></li>
<li><a href="#format-patterns">Format Patterns</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="datetime-class">DateTime Class</h2>
<div class="class-header">
<h3>DateTime</h3>
<p>Date and time representation</p>
</div>
<h3>Constructors</h3>
<div class="method-signature">
<span class="method-name">DateTime.now</span>() → <span class="type">DateTime</span>
</div>
<p>Creates a DateTime representing the current local time.</p>
<pre><code>var now = DateTime.now()
System.print(now) // 2024-01-15T10:30:45</code></pre>
<div class="method-signature">
<span class="method-name">DateTime.fromTimestamp</span>(<span class="param">timestamp</span>) → <span class="type">DateTime</span>
</div>
<p>Creates a DateTime from a Unix timestamp (seconds since epoch).</p>
<pre><code>var dt = DateTime.fromTimestamp(1705312245)
System.print(dt) // 2024-01-15T10:30:45</code></pre>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td><code>timestamp</code></td>
<td>Num</td>
<td>Unix timestamp (seconds since epoch)</td>
</tr>
<tr>
<td><code>year</code></td>
<td>Num</td>
<td>Year (e.g., 2024)</td>
</tr>
<tr>
<td><code>month</code></td>
<td>Num</td>
<td>Month (1-12)</td>
</tr>
<tr>
<td><code>day</code></td>
<td>Num</td>
<td>Day of month (1-31)</td>
</tr>
<tr>
<td><code>hour</code></td>
<td>Num</td>
<td>Hour (0-23)</td>
</tr>
<tr>
<td><code>minute</code></td>
<td>Num</td>
<td>Minute (0-59)</td>
</tr>
<tr>
<td><code>second</code></td>
<td>Num</td>
<td>Second (0-59)</td>
</tr>
<tr>
<td><code>dayOfWeek</code></td>
<td>Num</td>
<td>Day of week (0=Sunday, 6=Saturday)</td>
</tr>
<tr>
<td><code>dayOfYear</code></td>
<td>Num</td>
<td>Day of year (1-366)</td>
</tr>
<tr>
<td><code>isDst</code></td>
<td>Bool</td>
<td>True if daylight saving time is in effect</td>
</tr>
</table>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">format</span>(<span class="param">pattern</span>) → <span class="type">String</span>
</div>
<p>Formats the date/time using strftime-style patterns.</p>
<pre><code>var now = DateTime.now()
System.print(now.format("\%Y-\%m-\%d")) // 2024-01-15
System.print(now.format("\%H:\%M:\%S")) // 10:30:45
System.print(now.format("\%A, \%B \%d, \%Y")) // Monday, January 15, 2024</code></pre>
<div class="method-signature">
<span class="method-name">toIso8601</span><span class="type">String</span>
</div>
<p>Returns the date/time in ISO 8601 format.</p>
<pre><code>System.print(DateTime.now().toIso8601) // 2024-01-15T10:30:45</code></pre>
<h3>Operators</h3>
<div class="method-signature">
<span class="method-name">+</span>(<span class="param">duration</span>) → <span class="type">DateTime</span>
</div>
<p>Adds a Duration to the DateTime.</p>
<pre><code>var now = DateTime.now()
var later = now + Duration.fromHours(2)
System.print(later)</code></pre>
<div class="method-signature">
<span class="method-name">-</span>(<span class="param">other</span>) → <span class="type">DateTime|Duration</span>
</div>
<p>Subtracts a Duration (returns DateTime) or another DateTime (returns Duration).</p>
<pre><code>var now = DateTime.now()
var earlier = now - Duration.fromDays(1)
var start = DateTime.fromTimestamp(1705312245)
var end = DateTime.now()
var elapsed = end - start // Duration</code></pre>
<div class="method-signature">
<span class="method-name">==</span>, <span class="method-name">&lt;</span>, <span class="method-name">&gt;</span>, <span class="method-name">&lt;=</span>, <span class="method-name">&gt;=</span>
</div>
<p>Comparison operators for comparing two DateTimes.</p>
<h2 id="duration-class">Duration Class</h2>
<div class="class-header">
<h3>Duration</h3>
<p>Time duration representation</p>
</div>
<h3>Constructors</h3>
<div class="method-signature">
<span class="method-name">Duration.fromMilliseconds</span>(<span class="param">ms</span>) → <span class="type">Duration</span>
</div>
<div class="method-signature">
<span class="method-name">Duration.fromSeconds</span>(<span class="param">s</span>) → <span class="type">Duration</span>
</div>
<div class="method-signature">
<span class="method-name">Duration.fromMinutes</span>(<span class="param">m</span>) → <span class="type">Duration</span>
</div>
<div class="method-signature">
<span class="method-name">Duration.fromHours</span>(<span class="param">h</span>) → <span class="type">Duration</span>
</div>
<div class="method-signature">
<span class="method-name">Duration.fromDays</span>(<span class="param">d</span>) → <span class="type">Duration</span>
</div>
<pre><code>var oneHour = Duration.fromHours(1)
var threeMinutes = Duration.fromMinutes(3)
var twoAndHalfDays = Duration.fromDays(2.5)</code></pre>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td><code>milliseconds</code></td>
<td>Num</td>
<td>Total milliseconds</td>
</tr>
<tr>
<td><code>seconds</code></td>
<td>Num</td>
<td>Total seconds</td>
</tr>
<tr>
<td><code>minutes</code></td>
<td>Num</td>
<td>Total minutes</td>
</tr>
<tr>
<td><code>hours</code></td>
<td>Num</td>
<td>Total hours</td>
</tr>
<tr>
<td><code>days</code></td>
<td>Num</td>
<td>Total days</td>
</tr>
</table>
<h3>Operators</h3>
<div class="method-signature">
<span class="method-name">+</span>, <span class="method-name">-</span>(<span class="param">duration</span>) → <span class="type">Duration</span>
</div>
<p>Add or subtract durations.</p>
<div class="method-signature">
<span class="method-name">*</span>(<span class="param">factor</span>) → <span class="type">Duration</span>
</div>
<p>Multiply duration by a factor.</p>
<pre><code>var d1 = Duration.fromHours(2)
var d2 = Duration.fromMinutes(30)
var total = d1 + d2 // 2.5 hours
var doubled = d1 * 2 // 4 hours</code></pre>
<h2 id="format-patterns">Format Patterns</h2>
<table>
<tr>
<th>Pattern</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td><code>\%Y</code></td>
<td>4-digit year</td>
<td>2024</td>
</tr>
<tr>
<td><code>\%y</code></td>
<td>2-digit year</td>
<td>24</td>
</tr>
<tr>
<td><code>\%m</code></td>
<td>Month (01-12)</td>
<td>01</td>
</tr>
<tr>
<td><code>\%d</code></td>
<td>Day of month (01-31)</td>
<td>15</td>
</tr>
<tr>
<td><code>\%H</code></td>
<td>Hour 24h (00-23)</td>
<td>14</td>
</tr>
<tr>
<td><code>\%I</code></td>
<td>Hour 12h (01-12)</td>
<td>02</td>
</tr>
<tr>
<td><code>\%M</code></td>
<td>Minute (00-59)</td>
<td>30</td>
</tr>
<tr>
<td><code>\%S</code></td>
<td>Second (00-59)</td>
<td>45</td>
</tr>
<tr>
<td><code>\%p</code></td>
<td>AM/PM</td>
<td>PM</td>
</tr>
<tr>
<td><code>\%A</code></td>
<td>Full weekday name</td>
<td>Monday</td>
</tr>
<tr>
<td><code>\%a</code></td>
<td>Abbreviated weekday</td>
<td>Mon</td>
</tr>
<tr>
<td><code>\%B</code></td>
<td>Full month name</td>
<td>January</td>
</tr>
<tr>
<td><code>\%b</code></td>
<td>Abbreviated month</td>
<td>Jan</td>
</tr>
<tr>
<td><code>\%j</code></td>
<td>Day of year (001-366)</td>
<td>015</td>
</tr>
<tr>
<td><code>\%w</code></td>
<td>Weekday (0-6, Sun=0)</td>
<td>1</td>
</tr>
</table>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>In Wren strings, <code>%</code> starts string interpolation, so use <code>\%</code> for literal percent signs in format patterns.</p>
</div>
<h2 id="examples">Examples</h2>
<h3>Current Date and Time</h3>
<pre><code>import "datetime" for DateTime
var now = DateTime.now()
System.print("Year: %(now.year)")
System.print("Month: %(now.month)")
System.print("Day: %(now.day)")
System.print("Time: %(now.hour):%(now.minute):%(now.second)")</code></pre>
<h3>Formatting Dates</h3>
<pre><code>import "datetime" for DateTime
var now = DateTime.now()
System.print(now.format("\%Y-\%m-\%d")) // 2024-01-15
System.print(now.format("\%B \%d, \%Y")) // January 15, 2024
System.print(now.format("\%I:\%M \%p")) // 02:30 PM</code></pre>
<h3>Date Arithmetic</h3>
<pre><code>import "datetime" for DateTime, Duration
var now = DateTime.now()
var tomorrow = now + Duration.fromDays(1)
var nextWeek = now + Duration.fromDays(7)
var inTwoHours = now + Duration.fromHours(2)
System.print("Tomorrow: %(tomorrow.format("\%Y-\%m-\%d"))")
System.print("Next week: %(nextWeek.format("\%Y-\%m-\%d"))")</code></pre>
<h3>Calculating Time Differences</h3>
<pre><code>import "datetime" for DateTime
var start = DateTime.fromTimestamp(1705312245)
var end = DateTime.now()
var elapsed = end - start
System.print("Elapsed: %(elapsed.days.floor) days, %(elapsed.hours.floor \% 24) hours")</code></pre>
<h3>Comparing Dates</h3>
<pre><code>import "datetime" for DateTime, Duration
var now = DateTime.now()
var deadline = now + Duration.fromDays(7)
if (now < deadline) {
System.print("Still have time!")
}</code></pre>
</article>
<footer class="page-footer">
<a href="sqlite.html" class="prev">sqlite</a>
<a href="timer.html" class="next">timer</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+250
View File
@@ -0,0 +1,250 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dns - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html" class="active">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>dns</span>
</nav>
<article>
<h1>dns</h1>
<p>The <code>dns</code> module provides DNS resolution functionality for looking up hostnames and resolving them to IP addresses.</p>
<pre><code>import "dns" for Dns</code></pre>
<h2>Dns Class</h2>
<div class="class-header">
<h3>Dns</h3>
<p>DNS resolution utilities</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Dns.lookup</span>(<span class="param">hostname</span>) &#8594; <span class="type">String</span>
</div>
<p>Resolves a hostname to an IP address. Uses the system's default address family preference.</p>
<ul class="param-list">
<li><span class="param-name">hostname</span> <span class="param-type">(String)</span> - Hostname to resolve</li>
<li><span class="returns">Returns:</span> IP address as a string</li>
</ul>
<pre><code>var ip = Dns.lookup("example.com")
System.print(ip) // 93.184.216.34</code></pre>
<div class="method-signature">
<span class="method-name">Dns.lookup</span>(<span class="param">hostname</span>, <span class="param">family</span>) &#8594; <span class="type">String</span>
</div>
<p>Resolves a hostname to an IP address with a specific address family.</p>
<ul class="param-list">
<li><span class="param-name">hostname</span> <span class="param-type">(String)</span> - Hostname to resolve</li>
<li><span class="param-name">family</span> <span class="param-type">(Num)</span> - Address family: 0 (any), 4 (IPv4), or 6 (IPv6)</li>
<li><span class="returns">Returns:</span> IP address as a string</li>
</ul>
<pre><code>var ipv4 = Dns.lookup("example.com", 4)
System.print(ipv4) // 93.184.216.34
var ipv6 = Dns.lookup("example.com", 6)
System.print(ipv6) // 2606:2800:220:1:248:1893:25c8:1946</code></pre>
<h3>Address Family Values</h3>
<table>
<tr>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>0</code></td>
<td>Any (system default, typically prefers IPv4)</td>
</tr>
<tr>
<td><code>4</code></td>
<td>IPv4 only</td>
</tr>
<tr>
<td><code>6</code></td>
<td>IPv6 only</td>
</tr>
</table>
<h2>Examples</h2>
<h3>Basic DNS Lookup</h3>
<pre><code>import "dns" for Dns
var domains = ["example.com", "google.com", "github.com"]
for (domain in domains) {
var ip = Dns.lookup(domain)
System.print("%(domain) -> %(ip)")
}</code></pre>
<h3>IPv4 vs IPv6</h3>
<pre><code>import "dns" for Dns
var hostname = "google.com"
var ipv4 = Dns.lookup(hostname, 4)
System.print("IPv4: %(ipv4)")
var fiber = Fiber.new {
return Dns.lookup(hostname, 6)
}
var result = fiber.try()
if (fiber.error != null) {
System.print("IPv6: Not available")
} else {
System.print("IPv6: %(result)")
}</code></pre>
<h3>Using with Socket Connection</h3>
<pre><code>import "dns" for Dns
import "net" for Socket
var hostname = "httpbin.org"
var ip = Dns.lookup(hostname, 4)
System.print("Connecting to %(hostname) (%(ip))")
var socket = Socket.connect(ip, 80)
socket.write("GET /ip HTTP/1.1\r\nHost: %(hostname)\r\nConnection: close\r\n\r\n")
var response = ""
while (true) {
var data = socket.read()
if (data == null) break
response = response + data
}
socket.close()
System.print(response)</code></pre>
<h3>Using with TLS Connection</h3>
<pre><code>import "dns" for Dns
import "tls" for TlsSocket
var hostname = "example.com"
var ip = Dns.lookup(hostname, 4)
var socket = TlsSocket.connect(ip, 443, hostname)
socket.write("GET / HTTP/1.1\r\nHost: %(hostname)\r\nConnection: close\r\n\r\n")
var response = socket.read()
System.print(response)
socket.close()</code></pre>
<h3>Error Handling</h3>
<pre><code>import "dns" for Dns
var fiber = Fiber.new {
return Dns.lookup("nonexistent.invalid.domain")
}
var result = fiber.try()
if (fiber.error != null) {
System.print("DNS lookup failed: %(fiber.error)")
} else {
System.print("Resolved to: %(result)")
}</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>DNS lookups are asynchronous operations that use libuv's thread pool. The calling fiber will suspend until the lookup completes.</p>
</div>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>The hostname must be a string. Passing a non-string value will abort the fiber with an error. Similarly, the family parameter must be 0, 4, or 6.</p>
</div>
</article>
<footer class="page-footer">
<a href="net.html" class="prev">net</a>
<a href="json.html" class="next">json</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+297
View File
@@ -0,0 +1,297 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>env - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html" class="active">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>env</span>
</nav>
<article>
<h1>env</h1>
<p>The <code>env</code> module provides access to environment variables for reading, writing, and deleting values.</p>
<pre><code>import "env" for Environment</code></pre>
<h2>Environment Class</h2>
<div class="class-header">
<h3>Environment</h3>
<p>Environment variable access</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Environment.get</span>(<span class="param">name</span>) &#8594; <span class="type">String|null</span>
</div>
<p>Gets the value of an environment variable.</p>
<ul class="param-list">
<li><span class="param-name">name</span> <span class="param-type">(String)</span> - Name of the environment variable</li>
<li><span class="returns">Returns:</span> Value of the variable, or null if not set</li>
</ul>
<pre><code>var home = Environment.get("HOME")
System.print(home) // /home/alice
var missing = Environment.get("UNDEFINED_VAR")
System.print(missing) // null</code></pre>
<div class="method-signature">
<span class="method-name">Environment.set</span>(<span class="param">name</span>, <span class="param">value</span>)
</div>
<p>Sets an environment variable.</p>
<ul class="param-list">
<li><span class="param-name">name</span> <span class="param-type">(String)</span> - Name of the environment variable</li>
<li><span class="param-name">value</span> <span class="param-type">(String)</span> - Value to set</li>
</ul>
<pre><code>Environment.set("MY_APP_DEBUG", "true")
System.print(Environment.get("MY_APP_DEBUG")) // true</code></pre>
<div class="method-signature">
<span class="method-name">Environment.delete</span>(<span class="param">name</span>)
</div>
<p>Deletes an environment variable.</p>
<ul class="param-list">
<li><span class="param-name">name</span> <span class="param-type">(String)</span> - Name of the environment variable to delete</li>
</ul>
<pre><code>Environment.delete("MY_APP_DEBUG")
System.print(Environment.get("MY_APP_DEBUG")) // null</code></pre>
<h3>Static Properties</h3>
<div class="method-signature">
<span class="method-name">Environment.all</span> &#8594; <span class="type">Map</span>
</div>
<p>Returns a map of all environment variables.</p>
<pre><code>var env = Environment.all
for (entry in env) {
System.print("%(entry.key) = %(entry.value)")
}</code></pre>
<h2>Examples</h2>
<h3>Reading Configuration from Environment</h3>
<pre><code>import "env" for Environment
var host = Environment.get("APP_HOST")
if (host == null) host = "localhost"
var port = Environment.get("APP_PORT")
if (port == null) port = "8080"
var debug = Environment.get("APP_DEBUG") == "true"
System.print("Starting server on %(host):%(port)")
System.print("Debug mode: %(debug)")</code></pre>
<h3>Default Values Pattern</h3>
<pre><code>import "env" for Environment
class Config {
static get(name, defaultValue) {
var value = Environment.get(name)
return value != null ? value : defaultValue
}
static getInt(name, defaultValue) {
var value = Environment.get(name)
if (value == null) return defaultValue
return Num.fromString(value)
}
static getBool(name, defaultValue) {
var value = Environment.get(name)
if (value == null) return defaultValue
return value == "true" || value == "1"
}
}
var timeout = Config.getInt("TIMEOUT", 30)
var verbose = Config.getBool("VERBOSE", false)
var logFile = Config.get("LOG_FILE", "/var/log/app.log")
System.print("Timeout: %(timeout)s")
System.print("Verbose: %(verbose)")
System.print("Log file: %(logFile)")</code></pre>
<h3>Setting Environment for Subprocesses</h3>
<pre><code>import "env" for Environment
import "subprocess" for Subprocess
Environment.set("NODE_ENV", "production")
Environment.set("PORT", "3000")
var result = Subprocess.run("node server.js")
System.print(result.stdout)</code></pre>
<h3>Listing All Environment Variables</h3>
<pre><code>import "env" for Environment
System.print("=== Environment Variables ===")
var env = Environment.all
var keys = []
for (entry in env) {
keys.add(entry.key)
}
keys.sort()
for (key in keys) {
System.print("%(key) = %(env[key])")</code></pre>
<h3>Checking Required Environment Variables</h3>
<pre><code>import "env" for Environment
var required = ["DATABASE_URL", "API_KEY", "SECRET_KEY"]
var missing = []
for (name in required) {
if (Environment.get(name) == null) {
missing.add(name)
}
}
if (missing.count > 0) {
System.print("Missing required environment variables:")
for (name in missing) {
System.print(" - %(name)")
}
Fiber.abort("Configuration error")
}
System.print("All required environment variables are set")</code></pre>
<h3>Temporary Environment Modification</h3>
<pre><code>import "env" for Environment
var originalPath = Environment.get("PATH")
Environment.set("PATH", "/custom/bin:" + originalPath)
System.print("Modified PATH for operations...")
Environment.set("PATH", originalPath)
System.print("Restored original PATH")</code></pre>
<h3>Database Connection String from Environment</h3>
<pre><code>import "env" for Environment
var dbUrl = Environment.get("DATABASE_URL")
if (dbUrl != null) {
System.print("Using database: %(dbUrl)")
} else {
var host = Environment.get("DB_HOST")
if (host == null) host = "localhost"
var port = Environment.get("DB_PORT")
if (port == null) port = "5432"
var name = Environment.get("DB_NAME")
if (name == null) name = "myapp"
var user = Environment.get("DB_USER")
if (user == null) user = "postgres"
dbUrl = "postgres://%(user)@%(host):%(port)/%(name)"
System.print("Constructed database URL: %(dbUrl)")
}</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Environment variables modified with <code>set</code> or <code>delete</code> only affect the current process and any child processes. They do not modify the parent shell's environment.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>For configuration that may vary between environments (development, staging, production), use environment variables. This follows the twelve-factor app methodology.</p>
</div>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>Never log or print sensitive environment variables like API keys, passwords, or secrets. Use them directly in your application without exposing their values.</p>
</div>
</article>
<footer class="page-footer">
<a href="os.html" class="prev">os</a>
<a href="signal.html" class="next">signal</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+429
View File
@@ -0,0 +1,429 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>http - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html" class="active">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
<li><a href="../tutorials/database-app.html">Database App</a></li>
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
<li><a href="../tutorials/cli-tool.html">CLI Tool</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
<li><a href="../howto/file-operations.html">File Operations</a></li>
<li><a href="../howto/async-operations.html">Async Operations</a></li>
<li><a href="../howto/error-handling.html">Error Handling</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>http</span>
</nav>
<article>
<h1>http</h1>
<p>The <code>http</code> module provides an HTTP client for making requests to web servers. It supports both HTTP and HTTPS, all common HTTP methods, custom headers, and JSON handling.</p>
<pre><code>import "http" for Http, HttpResponse, Url</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#http-class">Http Class</a></li>
<li><a href="#httpresponse-class">HttpResponse Class</a></li>
<li><a href="#url-class">Url Class</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="http-class">Http Class</h2>
<p>The main class for making HTTP requests. All methods are static.</p>
<div class="class-header">
<h3>Http</h3>
<p>Static class for making HTTP requests</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Http.get</span>(<span class="param">url</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP GET request.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - The URL to request</li>
<li><span class="returns">Returns:</span> HttpResponse object</li>
</ul>
<pre><code>var response = Http.get("https://api.example.com/users")
System.print(response.body)</code></pre>
<div class="method-signature">
<span class="method-name">Http.get</span>(<span class="param">url</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP GET request with custom headers.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - The URL to request</li>
<li><span class="param-name">headers</span> <span class="param-type">(Map)</span> - Custom headers to include</li>
<li><span class="returns">Returns:</span> HttpResponse object</li>
</ul>
<pre><code>var headers = {"Authorization": "Bearer token123"}
var response = Http.get("https://api.example.com/me", headers)</code></pre>
<div class="method-signature">
<span class="method-name">Http.post</span>(<span class="param">url</span>, <span class="param">body</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP POST request with a body.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - The URL to post to</li>
<li><span class="param-name">body</span> <span class="param-type">(String|Map|List)</span> - Request body. Maps and Lists are JSON-encoded automatically.</li>
<li><span class="returns">Returns:</span> HttpResponse object</li>
</ul>
<pre><code>var data = {"name": "Alice", "email": "alice@example.com"}
var response = Http.post("https://api.example.com/users", data)</code></pre>
<div class="method-signature">
<span class="method-name">Http.post</span>(<span class="param">url</span>, <span class="param">body</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP POST request with a body and custom headers.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - The URL to post to</li>
<li><span class="param-name">body</span> <span class="param-type">(String|Map|List)</span> - Request body</li>
<li><span class="param-name">headers</span> <span class="param-type">(Map)</span> - Custom headers</li>
<li><span class="returns">Returns:</span> HttpResponse object</li>
</ul>
<div class="method-signature">
<span class="method-name">Http.put</span>(<span class="param">url</span>, <span class="param">body</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP PUT request.</p>
<div class="method-signature">
<span class="method-name">Http.put</span>(<span class="param">url</span>, <span class="param">body</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP PUT request with custom headers.</p>
<div class="method-signature">
<span class="method-name">Http.delete</span>(<span class="param">url</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP DELETE request.</p>
<div class="method-signature">
<span class="method-name">Http.delete</span>(<span class="param">url</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP DELETE request with custom headers.</p>
<div class="method-signature">
<span class="method-name">Http.patch</span>(<span class="param">url</span>, <span class="param">body</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP PATCH request.</p>
<div class="method-signature">
<span class="method-name">Http.patch</span>(<span class="param">url</span>, <span class="param">body</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs an HTTP PATCH request with custom headers.</p>
<div class="method-signature">
<span class="method-name">Http.request</span>(<span class="param">url</span>, <span class="param">method</span>, <span class="param">body</span>, <span class="param">headers</span>) → <span class="type">HttpResponse</span>
</div>
<p>Performs a custom HTTP request with full control over method, body, and headers.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - The URL to request</li>
<li><span class="param-name">method</span> <span class="param-type">(String)</span> - HTTP method (GET, POST, PUT, DELETE, PATCH, etc.)</li>
<li><span class="param-name">body</span> <span class="param-type">(String|Map|List|null)</span> - Request body or null</li>
<li><span class="param-name">headers</span> <span class="param-type">(Map)</span> - Custom headers</li>
<li><span class="returns">Returns:</span> HttpResponse object</li>
</ul>
<pre><code>var response = Http.request(
"https://api.example.com/users/1",
"OPTIONS",
null,
{}
)</code></pre>
<h2 id="httpresponse-class">HttpResponse Class</h2>
<p>Represents an HTTP response returned from a request.</p>
<div class="class-header">
<h3>HttpResponse</h3>
<p>HTTP response object with status, headers, and body</p>
</div>
<h3>Properties</h3>
<div class="method-signature">
<span class="method-name">statusCode</span><span class="type">Num</span>
</div>
<p>The HTTP status code (e.g., 200, 404, 500).</p>
<div class="method-signature">
<span class="method-name">statusText</span><span class="type">String</span>
</div>
<p>The HTTP status text (e.g., "OK", "Not Found").</p>
<div class="method-signature">
<span class="method-name">headers</span><span class="type">Map</span>
</div>
<p>A map of response headers (header name to value).</p>
<div class="method-signature">
<span class="method-name">body</span><span class="type">String</span>
</div>
<p>The response body as a string.</p>
<div class="method-signature">
<span class="method-name">ok</span><span class="type">Bool</span>
</div>
<p>True if the status code is in the 200-299 range.</p>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">header</span>(<span class="param">name</span>) → <span class="type">String|null</span>
</div>
<p>Gets a header value by name (case-insensitive).</p>
<ul class="param-list">
<li><span class="param-name">name</span> <span class="param-type">(String)</span> - Header name</li>
<li><span class="returns">Returns:</span> Header value or null if not found</li>
</ul>
<pre><code>var contentType = response.header("Content-Type")</code></pre>
<div class="method-signature">
<span class="method-name">json</span><span class="type">Map|List|null</span>
</div>
<p>Parses the response body as JSON and returns the result.</p>
<pre><code>var data = response.json
System.print(data["name"])</code></pre>
<h2 id="url-class">Url Class</h2>
<p>Utility class for parsing URLs into their components.</p>
<div class="class-header">
<h3>Url</h3>
<p>URL parser</p>
</div>
<h3>Constructor</h3>
<div class="method-signature">
<span class="method-name">Url.parse</span>(<span class="param">url</span>) → <span class="type">Url</span>
</div>
<p>Parses a URL string into its components.</p>
<pre><code>var url = Url.parse("https://example.com:8080/path?query=value")
System.print(url.scheme) // https
System.print(url.host) // example.com
System.print(url.port) // 8080
System.print(url.path) // /path
System.print(url.query) // query=value</code></pre>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td><code>scheme</code></td>
<td>String</td>
<td>URL scheme (http, https)</td>
</tr>
<tr>
<td><code>host</code></td>
<td>String</td>
<td>Hostname</td>
</tr>
<tr>
<td><code>port</code></td>
<td>Num</td>
<td>Port number (80 for http, 443 for https by default)</td>
</tr>
<tr>
<td><code>path</code></td>
<td>String</td>
<td>URL path</td>
</tr>
<tr>
<td><code>query</code></td>
<td>String</td>
<td>Query string (without leading ?)</td>
</tr>
<tr>
<td><code>fullPath</code></td>
<td>String</td>
<td>Path with query string</td>
</tr>
</table>
<h2 id="examples">Examples</h2>
<h3>Simple GET Request</h3>
<pre><code>import "http" for Http
var response = Http.get("https://httpbin.org/get")
System.print("Status: %(response.statusCode)")
System.print("Body: %(response.body)")</code></pre>
<h3>POST with JSON Body</h3>
<pre><code>import "http" for Http
var data = {
"username": "alice",
"email": "alice@example.com"
}
var response = Http.post("https://httpbin.org/post", data)
if (response.ok) {
System.print("User created!")
System.print(response.json)
} else {
System.print("Error: %(response.statusCode)")
}</code></pre>
<h3>Custom Headers with Authentication</h3>
<pre><code>import "http" for Http
var headers = {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs...",
"Accept": "application/json"
}
var response = Http.get("https://api.example.com/me", headers)
var user = response.json
System.print("Hello, %(user["name"])!")</code></pre>
<h3>Error Handling</h3>
<pre><code>import "http" for Http
var fiber = Fiber.new {
var response = Http.get("https://invalid-domain.example")
return response
}
var result = fiber.try()
if (fiber.error) {
System.print("Request failed: %(fiber.error)")
} else {
System.print("Got response: %(result.statusCode)")
}</code></pre>
<h3>Sending Form Data</h3>
<pre><code>import "http" for Http
var formData = "username=alice&password=secret"
var headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
var response = Http.post("https://example.com/login", formData, headers)</code></pre>
<h3>Checking Response Headers</h3>
<pre><code>import "http" for Http
var response = Http.get("https://example.com")
System.print("Content-Type: %(response.header("Content-Type"))")
System.print("Server: %(response.header("Server"))")
for (entry in response.headers) {
System.print("%(entry.key): %(entry.value)")
}</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>The HTTP module automatically handles HTTPS by using the TLS module. No additional configuration is needed for HTTPS URLs.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>When posting a Map or List, the module automatically sets <code>Content-Type: application/json</code> and JSON-encodes the body. For other content types, pass a string body and set the Content-Type header explicitly.</p>
</div>
</article>
<footer class="page-footer">
<a href="index.html" class="prev">API Overview</a>
<a href="websocket.html" class="next">websocket</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+328
View File
@@ -0,0 +1,328 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Reference - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html" class="active">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
<li><a href="../tutorials/database-app.html">Database App</a></li>
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
<li><a href="../tutorials/cli-tool.html">CLI Tool</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
<li><a href="../howto/file-operations.html">File Operations</a></li>
<li><a href="../howto/async-operations.html">Async Operations</a></li>
<li><a href="../howto/error-handling.html">Error Handling</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<span>API Reference</span>
</nav>
<article>
<h1>API Reference</h1>
<p>Wren-CLI provides 21 built-in modules covering networking, file I/O, data processing, system operations, and more. All modules are imported using the <code>import</code> statement.</p>
<pre><code>import "http" for Http
import "json" for Json
import "io" for File</code></pre>
<h2>Networking</h2>
<p>Modules for HTTP, WebSocket, and low-level network operations.</p>
<div class="card-grid">
<div class="card">
<h3><a href="http.html">http</a></h3>
<p>HTTP client for making GET, POST, PUT, DELETE, and PATCH requests. Supports HTTPS.</p>
</div>
<div class="card">
<h3><a href="websocket.html">websocket</a></h3>
<p>WebSocket client and server implementation with full protocol support.</p>
</div>
<div class="card">
<h3><a href="tls.html">tls</a></h3>
<p>TLS/SSL socket wrapper for encrypted connections using OpenSSL.</p>
</div>
<div class="card">
<h3><a href="net.html">net</a></h3>
<p>Low-level TCP sockets and servers for custom network protocols.</p>
</div>
<div class="card">
<h3><a href="dns.html">dns</a></h3>
<p>DNS resolution for hostname to IP address lookups.</p>
</div>
</div>
<h2>Data Processing</h2>
<p>Modules for parsing, encoding, and transforming data.</p>
<div class="card-grid">
<div class="card">
<h3><a href="json.html">json</a></h3>
<p>Parse and stringify JSON data with pretty-printing support.</p>
</div>
<div class="card">
<h3><a href="base64.html">base64</a></h3>
<p>Base64 encoding and decoding for binary-to-text conversion.</p>
</div>
<div class="card">
<h3><a href="regex.html">regex</a></h3>
<p>Regular expression matching, replacement, and splitting.</p>
</div>
<div class="card">
<h3><a href="jinja.html">jinja</a></h3>
<p>Jinja2-compatible template engine with filters, inheritance, and macros.</p>
</div>
<div class="card">
<h3><a href="crypto.html">crypto</a></h3>
<p>Cryptographic hashing (MD5, SHA-1, SHA-256) and random byte generation.</p>
</div>
</div>
<h2>System</h2>
<p>Modules for interacting with the operating system and environment.</p>
<div class="card-grid">
<div class="card">
<h3><a href="os.html">os</a></h3>
<p>Platform information, process details, and command-line arguments.</p>
</div>
<div class="card">
<h3><a href="env.html">env</a></h3>
<p>Read and write environment variables.</p>
</div>
<div class="card">
<h3><a href="signal.html">signal</a></h3>
<p>Handle Unix signals like SIGINT, SIGTERM, and SIGHUP.</p>
</div>
<div class="card">
<h3><a href="subprocess.html">subprocess</a></h3>
<p>Run external commands and capture their output.</p>
</div>
<div class="card">
<h3><a href="io.html">io</a></h3>
<p>File and directory operations, stdin/stdout handling.</p>
</div>
</div>
<h2>Data & Time</h2>
<p>Modules for databases, time, and scheduling.</p>
<div class="card-grid">
<div class="card">
<h3><a href="sqlite.html">sqlite</a></h3>
<p>SQLite database for persistent data storage with SQL queries.</p>
</div>
<div class="card">
<h3><a href="datetime.html">datetime</a></h3>
<p>Date and time manipulation with formatting and arithmetic.</p>
</div>
<div class="card">
<h3><a href="timer.html">timer</a></h3>
<p>Sleep, timeouts, and interval timers.</p>
</div>
<div class="card">
<h3><a href="math.html">math</a></h3>
<p>Mathematical functions like sqrt, sin, cos, and constants like PI.</p>
</div>
<div class="card">
<h3><a href="scheduler.html">scheduler</a></h3>
<p>Async fiber scheduling for non-blocking I/O operations.</p>
</div>
</div>
<h2>Module Summary</h2>
<table>
<tr>
<th>Module</th>
<th>Main Classes</th>
<th>Description</th>
</tr>
<tr>
<td><a href="http.html">http</a></td>
<td>Http, HttpResponse, Url</td>
<td>HTTP/HTTPS client</td>
</tr>
<tr>
<td><a href="websocket.html">websocket</a></td>
<td>WebSocket, WebSocketServer, WebSocketMessage</td>
<td>WebSocket protocol</td>
</tr>
<tr>
<td><a href="tls.html">tls</a></td>
<td>TlsSocket</td>
<td>TLS/SSL sockets</td>
</tr>
<tr>
<td><a href="net.html">net</a></td>
<td>Socket, Server</td>
<td>TCP networking</td>
</tr>
<tr>
<td><a href="dns.html">dns</a></td>
<td>Dns</td>
<td>DNS resolution</td>
</tr>
<tr>
<td><a href="json.html">json</a></td>
<td>Json</td>
<td>JSON parsing</td>
</tr>
<tr>
<td><a href="base64.html">base64</a></td>
<td>Base64</td>
<td>Base64 encoding</td>
</tr>
<tr>
<td><a href="regex.html">regex</a></td>
<td>Regex, Match</td>
<td>Regular expressions</td>
</tr>
<tr>
<td><a href="jinja.html">jinja</a></td>
<td>Environment, Template, DictLoader, FileSystemLoader</td>
<td>Template engine</td>
</tr>
<tr>
<td><a href="crypto.html">crypto</a></td>
<td>Crypto, Hash</td>
<td>Cryptography</td>
</tr>
<tr>
<td><a href="os.html">os</a></td>
<td>Process, Platform</td>
<td>OS information</td>
</tr>
<tr>
<td><a href="env.html">env</a></td>
<td>Env</td>
<td>Environment variables</td>
</tr>
<tr>
<td><a href="signal.html">signal</a></td>
<td>Signal</td>
<td>Unix signals</td>
</tr>
<tr>
<td><a href="subprocess.html">subprocess</a></td>
<td>Subprocess</td>
<td>External processes</td>
</tr>
<tr>
<td><a href="sqlite.html">sqlite</a></td>
<td>Sqlite</td>
<td>SQLite database</td>
</tr>
<tr>
<td><a href="datetime.html">datetime</a></td>
<td>DateTime, Duration</td>
<td>Date/time handling</td>
</tr>
<tr>
<td><a href="timer.html">timer</a></td>
<td>Timer</td>
<td>Timers and delays</td>
</tr>
<tr>
<td><a href="io.html">io</a></td>
<td>File, Directory, Stdin, Stdout</td>
<td>File I/O</td>
</tr>
<tr>
<td><a href="scheduler.html">scheduler</a></td>
<td>Scheduler</td>
<td>Async scheduling</td>
</tr>
<tr>
<td><a href="math.html">math</a></td>
<td>Math</td>
<td>Math functions</td>
</tr>
</table>
</article>
<footer class="page-footer">
<a href="../language/modules.html" class="prev">Modules</a>
<a href="http.html" class="next">http</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+283
View File
@@ -0,0 +1,283 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>io - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html" class="active">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>io</span>
</nav>
<article>
<h1>io</h1>
<p>The <code>io</code> module provides file and directory operations, as well as stdin/stdout handling.</p>
<pre><code>import "io" for File, Directory, Stdin, Stdout</code></pre>
<h2>File Class</h2>
<div class="class-header">
<h3>File</h3>
<p>File operations</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">File.read</span>(<span class="param">path</span>) → <span class="type">String</span>
</div>
<p>Reads the entire contents of a file.</p>
<pre><code>var content = File.read("config.txt")
System.print(content)</code></pre>
<div class="method-signature">
<span class="method-name">File.write</span>(<span class="param">path</span>, <span class="param">content</span>)
</div>
<p>Writes content to a file (creates or overwrites).</p>
<pre><code>File.write("output.txt", "Hello, World!")</code></pre>
<div class="method-signature">
<span class="method-name">File.exists</span>(<span class="param">path</span>) → <span class="type">Bool</span>
</div>
<p>Returns true if the file exists.</p>
<pre><code>if (File.exists("config.txt")) {
System.print("Config found")
}</code></pre>
<div class="method-signature">
<span class="method-name">File.delete</span>(<span class="param">path</span>)
</div>
<p>Deletes a file.</p>
<div class="method-signature">
<span class="method-name">File.size</span>(<span class="param">path</span>) → <span class="type">Num</span>
</div>
<p>Returns the size of a file in bytes.</p>
<div class="method-signature">
<span class="method-name">File.copy</span>(<span class="param">source</span>, <span class="param">dest</span>)
</div>
<p>Copies a file from source to destination.</p>
<div class="method-signature">
<span class="method-name">File.rename</span>(<span class="param">oldPath</span>, <span class="param">newPath</span>)
</div>
<p>Renames or moves a file.</p>
<h2>Directory Class</h2>
<div class="class-header">
<h3>Directory</h3>
<p>Directory operations</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Directory.list</span>(<span class="param">path</span>) → <span class="type">List</span>
</div>
<p>Lists the contents of a directory.</p>
<pre><code>var files = Directory.list(".")
for (file in files) {
System.print(file)
}</code></pre>
<div class="method-signature">
<span class="method-name">Directory.exists</span>(<span class="param">path</span>) → <span class="type">Bool</span>
</div>
<p>Returns true if the directory exists.</p>
<div class="method-signature">
<span class="method-name">Directory.create</span>(<span class="param">path</span>)
</div>
<p>Creates a directory.</p>
<div class="method-signature">
<span class="method-name">Directory.delete</span>(<span class="param">path</span>)
</div>
<p>Deletes an empty directory.</p>
<h2>Stdin Class</h2>
<div class="class-header">
<h3>Stdin</h3>
<p>Standard input</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Stdin.readLine</span>() → <span class="type">String</span>
</div>
<p>Reads a line from standard input.</p>
<pre><code>System.write("Enter your name: ")
var name = Stdin.readLine()
System.print("Hello, %(name)!")</code></pre>
<div class="method-signature">
<span class="method-name">Stdin.read</span>() → <span class="type">String</span>
</div>
<p>Reads all available data from stdin.</p>
<h2>Stdout Class</h2>
<div class="class-header">
<h3>Stdout</h3>
<p>Standard output</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Stdout.flush</span>()
</div>
<p>Flushes the stdout buffer.</p>
<h2>Examples</h2>
<h3>Reading and Writing Files</h3>
<pre><code>import "io" for File
var content = File.read("input.txt")
var processed = content.replace("old", "new")
File.write("output.txt", processed)</code></pre>
<h3>Working with JSON Files</h3>
<pre><code>import "io" for File
import "json" for Json
var config = Json.parse(File.read("config.json"))
config["updated"] = true
File.write("config.json", Json.stringify(config, 2))</code></pre>
<h3>Processing Directory Contents</h3>
<pre><code>import "io" for File, Directory
var files = Directory.list("./data")
for (file in files) {
if (file.endsWith(".txt")) {
var path = "./data/%(file)"
var size = File.size(path)
System.print("%(file): %(size) bytes")
}
}</code></pre>
<h3>Interactive Input</h3>
<pre><code>import "io" for Stdin
System.write("Username: ")
var username = Stdin.readLine()
System.write("Age: ")
var age = Num.fromString(Stdin.readLine())
System.print("Hello %(username), you are %(age) years old")</code></pre>
<h3>File Backup</h3>
<pre><code>import "io" for File
import "datetime" for DateTime
var backup = Fn.new { |path|
if (!File.exists(path)) return
var timestamp = DateTime.now().format("\%Y\%m\%d_\%H\%M\%S")
var backupPath = "%(path).%(timestamp).bak"
File.copy(path, backupPath)
System.print("Backed up to %(backupPath)")
}
backup.call("important.txt")</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>File operations are synchronous but use libuv internally for async I/O. The fiber suspends during I/O operations.</p>
</div>
</article>
<footer class="page-footer">
<a href="timer.html" class="prev">timer</a>
<a href="scheduler.html" class="next">scheduler</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
File diff suppressed because it is too large Load Diff
+255
View File
@@ -0,0 +1,255 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>json - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html" class="active">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>json</span>
</nav>
<article>
<h1>json</h1>
<p>The <code>json</code> module provides JSON parsing and stringification. It uses the cJSON library for parsing and implements stringify in Wren.</p>
<pre><code>import "json" for Json</code></pre>
<h2>Json Class</h2>
<div class="class-header">
<h3>Json</h3>
<p>JSON parsing and stringification</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Json.parse</span>(<span class="param">string</span>) → <span class="type">Map|List|String|Num|Bool|null</span>
</div>
<p>Parses a JSON string and returns the corresponding Wren value.</p>
<ul class="param-list">
<li><span class="param-name">string</span> <span class="param-type">(String)</span> - JSON string to parse</li>
<li><span class="returns">Returns:</span> Parsed value (Map, List, String, Num, Bool, or null)</li>
</ul>
<pre><code>var data = Json.parse('{"name": "Alice", "age": 30}')
System.print(data["name"]) // Alice
System.print(data["age"]) // 30
var list = Json.parse('[1, 2, 3]')
System.print(list[0]) // 1</code></pre>
<div class="method-signature">
<span class="method-name">Json.stringify</span>(<span class="param">value</span>) → <span class="type">String</span>
</div>
<p>Converts a Wren value to a JSON string (compact, no whitespace).</p>
<ul class="param-list">
<li><span class="param-name">value</span> <span class="param-type">(any)</span> - Value to stringify</li>
<li><span class="returns">Returns:</span> JSON string</li>
</ul>
<pre><code>var json = Json.stringify({"name": "Alice", "age": 30})
System.print(json) // {"name":"Alice","age":30}</code></pre>
<div class="method-signature">
<span class="method-name">Json.stringify</span>(<span class="param">value</span>, <span class="param">indent</span>) → <span class="type">String</span>
</div>
<p>Converts a Wren value to a formatted JSON string with indentation.</p>
<ul class="param-list">
<li><span class="param-name">value</span> <span class="param-type">(any)</span> - Value to stringify</li>
<li><span class="param-name">indent</span> <span class="param-type">(Num|String)</span> - Number of spaces or indent string</li>
<li><span class="returns">Returns:</span> Formatted JSON string</li>
</ul>
<pre><code>var json = Json.stringify({"name": "Alice"}, 2)
System.print(json)
// {
// "name": "Alice"
// }
var json2 = Json.stringify({"name": "Bob"}, "\t")
// Uses tab for indentation</code></pre>
<h2>Type Mapping</h2>
<table>
<tr>
<th>JSON Type</th>
<th>Wren Type</th>
</tr>
<tr>
<td>object</td>
<td>Map</td>
</tr>
<tr>
<td>array</td>
<td>List</td>
</tr>
<tr>
<td>string</td>
<td>String</td>
</tr>
<tr>
<td>number</td>
<td>Num</td>
</tr>
<tr>
<td>true/false</td>
<td>Bool</td>
</tr>
<tr>
<td>null</td>
<td>null</td>
</tr>
</table>
<h2>Examples</h2>
<h3>Parsing JSON</h3>
<pre><code>import "json" for Json
var jsonString = '{"users": [{"name": "Alice"}, {"name": "Bob"}]}'
var data = Json.parse(jsonString)
for (user in data["users"]) {
System.print("User: %(user["name"])")
}</code></pre>
<h3>Building and Stringifying</h3>
<pre><code>import "json" for Json
var data = {
"name": "Product",
"price": 29.99,
"tags": ["electronics", "sale"],
"inStock": true,
"metadata": null
}
System.print(Json.stringify(data, 2))</code></pre>
<h3>Nested Structures</h3>
<pre><code>import "json" for Json
var config = {
"server": {
"host": "localhost",
"port": 8080
},
"database": {
"url": "sqlite://data.db"
}
}
var json = Json.stringify(config)
System.print(json)
var parsed = Json.parse(json)
System.print(parsed["server"]["port"]) // 8080</code></pre>
<h3>Special Values</h3>
<pre><code>import "json" for Json
var special = {
"infinity": 1/0,
"nan": 0/0
}
System.print(Json.stringify(special))
// {"infinity":null,"nan":null}
// Infinity and NaN are converted to null</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Map keys are converted to strings in JSON output. Non-string keys will have their <code>toString</code> method called.</p>
</div>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>Invalid JSON strings will cause a runtime error. Use <code>Fiber.try()</code> to catch parsing errors.</p>
</div>
</article>
<footer class="page-footer">
<a href="dns.html" class="prev">dns</a>
<a href="base64.html" class="next">base64</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+289
View File
@@ -0,0 +1,289 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>math - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html" class="active">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>math</span>
</nav>
<article>
<h1>math</h1>
<p>The <code>math</code> module provides mathematical functions and constants.</p>
<pre><code>import "math" for Math</code></pre>
<h2>Math Class</h2>
<div class="class-header">
<h3>Math</h3>
<p>Mathematical functions and constants</p>
</div>
<h3>Constants</h3>
<table>
<tr>
<th>Constant</th>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>Math.pi</code></td>
<td>3.14159...</td>
<td>Pi</td>
</tr>
<tr>
<td><code>Math.e</code></td>
<td>2.71828...</td>
<td>Euler's number</td>
</tr>
<tr>
<td><code>Math.tau</code></td>
<td>6.28318...</td>
<td>Tau (2 * Pi)</td>
</tr>
</table>
<h3>Basic Functions</h3>
<div class="method-signature">
<span class="method-name">Math.abs</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the absolute value.</p>
<pre><code>Math.abs(-5) // 5
Math.abs(3.14) // 3.14</code></pre>
<div class="method-signature">
<span class="method-name">Math.min</span>(<span class="param">a</span>, <span class="param">b</span>) → <span class="type">Num</span>
</div>
<p>Returns the smaller of two values.</p>
<div class="method-signature">
<span class="method-name">Math.max</span>(<span class="param">a</span>, <span class="param">b</span>) → <span class="type">Num</span>
</div>
<p>Returns the larger of two values.</p>
<div class="method-signature">
<span class="method-name">Math.clamp</span>(<span class="param">value</span>, <span class="param">min</span>, <span class="param">max</span>) → <span class="type">Num</span>
</div>
<p>Clamps a value to a range.</p>
<pre><code>Math.clamp(15, 0, 10) // 10
Math.clamp(5, 0, 10) // 5
Math.clamp(-5, 0, 10) // 0</code></pre>
<h3>Rounding</h3>
<div class="method-signature">
<span class="method-name">Math.floor</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Rounds down to the nearest integer.</p>
<div class="method-signature">
<span class="method-name">Math.ceil</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Rounds up to the nearest integer.</p>
<div class="method-signature">
<span class="method-name">Math.round</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Rounds to the nearest integer.</p>
<pre><code>Math.floor(3.7) // 3
Math.ceil(3.2) // 4
Math.round(3.5) // 4</code></pre>
<h3>Powers and Roots</h3>
<div class="method-signature">
<span class="method-name">Math.sqrt</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the square root.</p>
<div class="method-signature">
<span class="method-name">Math.pow</span>(<span class="param">base</span>, <span class="param">exp</span>) → <span class="type">Num</span>
</div>
<p>Returns base raised to the power of exp.</p>
<div class="method-signature">
<span class="method-name">Math.exp</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns e raised to the power of x.</p>
<pre><code>Math.sqrt(16) // 4
Math.pow(2, 10) // 1024
Math.exp(1) // 2.71828...</code></pre>
<h3>Logarithms</h3>
<div class="method-signature">
<span class="method-name">Math.log</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the natural logarithm (base e).</p>
<div class="method-signature">
<span class="method-name">Math.log10</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the base-10 logarithm.</p>
<div class="method-signature">
<span class="method-name">Math.log2</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the base-2 logarithm.</p>
<h3>Trigonometry</h3>
<div class="method-signature">
<span class="method-name">Math.sin</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the sine (x in radians).</p>
<div class="method-signature">
<span class="method-name">Math.cos</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the cosine (x in radians).</p>
<div class="method-signature">
<span class="method-name">Math.tan</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the tangent (x in radians).</p>
<div class="method-signature">
<span class="method-name">Math.asin</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the arcsine in radians.</p>
<div class="method-signature">
<span class="method-name">Math.acos</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the arccosine in radians.</p>
<div class="method-signature">
<span class="method-name">Math.atan</span>(<span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the arctangent in radians.</p>
<div class="method-signature">
<span class="method-name">Math.atan2</span>(<span class="param">y</span>, <span class="param">x</span>) → <span class="type">Num</span>
</div>
<p>Returns the angle in radians between the positive x-axis and the point (x, y).</p>
<h2>Examples</h2>
<h3>Distance Calculation</h3>
<pre><code>import "math" for Math
var distance = Fn.new { |x1, y1, x2, y2|
var dx = x2 - x1
var dy = y2 - y1
return Math.sqrt(dx * dx + dy * dy)
}
System.print(distance.call(0, 0, 3, 4)) // 5</code></pre>
<h3>Degrees to Radians</h3>
<pre><code>import "math" for Math
var toRadians = Fn.new { |degrees| degrees * Math.pi / 180 }
var toDegrees = Fn.new { |radians| radians * 180 / Math.pi }
System.print(Math.sin(toRadians.call(90))) // 1</code></pre>
<h3>Circle Area</h3>
<pre><code>import "math" for Math
var circleArea = Fn.new { |radius|
return Math.pi * radius * radius
}
System.print(circleArea.call(5)) // 78.539...</code></pre>
</article>
<footer class="page-footer">
<a href="scheduler.html" class="prev">scheduler</a>
<a href="../tutorials/index.html" class="next">Tutorials</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+329
View File
@@ -0,0 +1,329 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>net - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html" class="active">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>net</span>
</nav>
<article>
<h1>net</h1>
<p>The <code>net</code> module provides low-level TCP socket and server functionality for network programming. All operations are asynchronous using libuv.</p>
<pre><code>import "net" for Socket, Server</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#socket-class">Socket Class</a></li>
<li><a href="#server-class">Server Class</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="socket-class">Socket Class</h2>
<div class="class-header">
<h3>Socket</h3>
<p>TCP socket for client connections</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Socket.connect</span>(<span class="param">host</span>, <span class="param">port</span>) &#8594; <span class="type">Socket</span>
</div>
<p>Establishes a TCP connection to a remote server.</p>
<ul class="param-list">
<li><span class="param-name">host</span> <span class="param-type">(String)</span> - Hostname or IP address to connect to</li>
<li><span class="param-name">port</span> <span class="param-type">(Num)</span> - Port number</li>
<li><span class="returns">Returns:</span> Connected Socket instance</li>
</ul>
<pre><code>var socket = Socket.connect("127.0.0.1", 8080)</code></pre>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">write</span>(<span class="param">data</span>) &#8594; <span class="type">Num</span>
</div>
<p>Writes data to the socket. Blocks until the data is sent.</p>
<ul class="param-list">
<li><span class="param-name">data</span> <span class="param-type">(String)</span> - Data to send</li>
<li><span class="returns">Returns:</span> Number of bytes written</li>
</ul>
<pre><code>socket.write("Hello, server!")</code></pre>
<div class="method-signature">
<span class="method-name">read</span>() &#8594; <span class="type">String|null</span>
</div>
<p>Reads data from the socket. Blocks until data is available. Returns null when the connection is closed by the remote end.</p>
<ul class="param-list">
<li><span class="returns">Returns:</span> Data received as a string, or null if connection closed</li>
</ul>
<pre><code>var data = socket.read()
if (data != null) {
System.print("Received: %(data)")
}</code></pre>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Closes the socket connection.</p>
<pre><code>socket.close()</code></pre>
<h2 id="server-class">Server Class</h2>
<div class="class-header">
<h3>Server</h3>
<p>TCP server for accepting client connections</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Server.bind</span>(<span class="param">host</span>, <span class="param">port</span>) &#8594; <span class="type">Server</span>
</div>
<p>Creates a TCP server listening on the specified host and port.</p>
<ul class="param-list">
<li><span class="param-name">host</span> <span class="param-type">(String)</span> - Host to bind to (e.g., "0.0.0.0" for all interfaces, "127.0.0.1" for localhost only)</li>
<li><span class="param-name">port</span> <span class="param-type">(Num)</span> - Port number to listen on</li>
<li><span class="returns">Returns:</span> Bound Server instance</li>
</ul>
<pre><code>var server = Server.bind("0.0.0.0", 8080)</code></pre>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">accept</span>() &#8594; <span class="type">Socket|null</span>
</div>
<p>Accepts an incoming connection. Blocks until a client connects. Returns a Socket instance for the connected client.</p>
<ul class="param-list">
<li><span class="returns">Returns:</span> Socket for the accepted connection</li>
</ul>
<pre><code>var client = server.accept()
System.print("Client connected!")</code></pre>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Stops the server and closes the listening socket.</p>
<pre><code>server.close()</code></pre>
<h2 id="examples">Examples</h2>
<h3>Simple TCP Client</h3>
<pre><code>import "net" for Socket
var socket = Socket.connect("example.com", 80)
socket.write("GET / HTTP/1.1\r\n")
socket.write("Host: example.com\r\n")
socket.write("Connection: close\r\n")
socket.write("\r\n")
var response = ""
while (true) {
var chunk = socket.read()
if (chunk == null) break
response = response + chunk
}
socket.close()
System.print(response)</code></pre>
<h3>Echo Server</h3>
<pre><code>import "net" for Server
var server = Server.bind("0.0.0.0", 8080)
System.print("Echo server listening on port 8080")
while (true) {
var client = server.accept()
System.print("Client connected")
while (true) {
var data = client.read()
if (data == null) {
System.print("Client disconnected")
break
}
System.print("Received: %(data)")
client.write(data)
}
client.close()
}</code></pre>
<h3>Line-Based Protocol Server</h3>
<pre><code>import "net" for Server
var server = Server.bind("127.0.0.1", 9000)
System.print("Chat server on port 9000")
while (true) {
var client = server.accept()
client.write("Welcome! Type messages and press Enter.\n")
var buffer = ""
while (true) {
var data = client.read()
if (data == null) break
buffer = buffer + data
while (buffer.contains("\n")) {
var lineEnd = buffer.indexOf("\n")
var line = buffer[0...lineEnd]
buffer = buffer[lineEnd + 1..-1]
if (line == "quit") {
client.write("Goodbye!\n")
client.close()
break
}
client.write("You said: %(line)\n")
}
}
}</code></pre>
<h3>Connecting with DNS Resolution</h3>
<pre><code>import "net" for Socket
import "dns" for Dns
var hostname = "httpbin.org"
var ip = Dns.lookup(hostname)
System.print("Resolved %(hostname) to %(ip)")
var socket = Socket.connect(ip, 80)
socket.write("GET /ip HTTP/1.1\r\nHost: %(hostname)\r\nConnection: close\r\n\r\n")
var response = ""
while (true) {
var data = socket.read()
if (data == null) break
response = response + data
}
socket.close()
System.print(response)</code></pre>
<h3>Simple Request-Response Client</h3>
<pre><code>import "net" for Socket
var socket = Socket.connect("127.0.0.1", 8080)
socket.write("PING\n")
var response = socket.read()
System.print("Server responded: %(response)")
socket.write("ECHO Hello World\n")
response = socket.read()
System.print("Server responded: %(response)")
socket.close()</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>The Socket class uses TCP, which is a stream-based protocol. Data may arrive in chunks that do not correspond to message boundaries. For protocols that require message framing, implement appropriate buffering and parsing logic.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>For secure connections, use the <code>tls</code> module's TlsSocket class instead of Socket. For HTTP/HTTPS requests, the higher-level <code>http</code> module handles protocol details automatically.</p>
</div>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>Both host and port arguments are validated. Providing a non-string host or non-number port will abort the fiber with an error message.</p>
</div>
</article>
<footer class="page-footer">
<a href="tls.html" class="prev">tls</a>
<a href="dns.html" class="next">dns</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+301
View File
@@ -0,0 +1,301 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>os - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html" class="active">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>os</span>
</nav>
<article>
<h1>os</h1>
<p>The <code>os</code> module provides information about the operating system, platform, and current process.</p>
<pre><code>import "os" for Platform, Process</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#platform-class">Platform Class</a></li>
<li><a href="#process-class">Process Class</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="platform-class">Platform Class</h2>
<div class="class-header">
<h3>Platform</h3>
<p>Operating system and platform information</p>
</div>
<h3>Static Properties</h3>
<div class="method-signature">
<span class="method-name">Platform.name</span> &#8594; <span class="type">String</span>
</div>
<p>The name of the operating system (e.g., "Linux", "macOS", "Windows", "FreeBSD").</p>
<pre><code>System.print(Platform.name) // Linux</code></pre>
<div class="method-signature">
<span class="method-name">Platform.isPosix</span> &#8594; <span class="type">Bool</span>
</div>
<p>True if running on a POSIX-compatible system (Linux, macOS, BSD, etc.).</p>
<pre><code>if (Platform.isPosix) {
System.print("Running on a POSIX system")
}</code></pre>
<div class="method-signature">
<span class="method-name">Platform.isWindows</span> &#8594; <span class="type">Bool</span>
</div>
<p>True if running on Windows.</p>
<pre><code>if (Platform.isWindows) {
System.print("Running on Windows")
}</code></pre>
<div class="method-signature">
<span class="method-name">Platform.homePath</span> &#8594; <span class="type">String</span>
</div>
<p>The current user's home directory path.</p>
<pre><code>System.print(Platform.homePath) // /home/alice (Linux) or C:\Users\alice (Windows)</code></pre>
<h2 id="process-class">Process Class</h2>
<div class="class-header">
<h3>Process</h3>
<p>Current process information and arguments</p>
</div>
<h3>Static Properties</h3>
<div class="method-signature">
<span class="method-name">Process.arguments</span> &#8594; <span class="type">List</span>
</div>
<p>Command-line arguments passed to the script (excludes the interpreter and script path).</p>
<pre><code>// Running: wren_cli script.wren arg1 arg2
System.print(Process.arguments) // [arg1, arg2]</code></pre>
<div class="method-signature">
<span class="method-name">Process.allArguments</span> &#8594; <span class="type">List</span>
</div>
<p>All command-line arguments including the interpreter path and script path.</p>
<pre><code>// Running: wren_cli script.wren arg1 arg2
System.print(Process.allArguments) // [wren_cli, script.wren, arg1, arg2]</code></pre>
<div class="method-signature">
<span class="method-name">Process.cwd</span> &#8594; <span class="type">String</span>
</div>
<p>The current working directory.</p>
<pre><code>System.print(Process.cwd) // /home/alice/projects</code></pre>
<div class="method-signature">
<span class="method-name">Process.pid</span> &#8594; <span class="type">Num</span>
</div>
<p>The process ID of the current process.</p>
<pre><code>System.print(Process.pid) // 12345</code></pre>
<div class="method-signature">
<span class="method-name">Process.ppid</span> &#8594; <span class="type">Num</span>
</div>
<p>The parent process ID.</p>
<pre><code>System.print(Process.ppid) // 12300</code></pre>
<div class="method-signature">
<span class="method-name">Process.version</span> &#8594; <span class="type">String</span>
</div>
<p>The version string of the Wren-CLI runtime.</p>
<pre><code>System.print(Process.version) // 0.4.0</code></pre>
<h2 id="examples">Examples</h2>
<h3>Platform-Specific Behavior</h3>
<pre><code>import "os" for Platform
var configPath
if (Platform.isWindows) {
configPath = Platform.homePath + "\\AppData\\Local\\myapp\\config.json"
} else {
configPath = Platform.homePath + "/.config/myapp/config.json"
}
System.print("Config path: %(configPath)")</code></pre>
<h3>Processing Command-Line Arguments</h3>
<pre><code>import "os" for Process
var args = Process.arguments
if (args.count == 0) {
System.print("Usage: script.wren <command> [options]")
} else {
var command = args[0]
if (command == "help") {
System.print("Available commands: help, version, run")
} else if (command == "version") {
System.print("Version 1.0.0")
} else if (command == "run") {
if (args.count > 1) {
System.print("Running: %(args[1])")
} else {
System.print("Error: run requires a file argument")
}
} else {
System.print("Unknown command: %(command)")
}
}</code></pre>
<h3>Script Information</h3>
<pre><code>import "os" for Platform, Process
System.print("=== System Information ===")
System.print("Platform: %(Platform.name)")
System.print("POSIX: %(Platform.isPosix)")
System.print("Home: %(Platform.homePath)")
System.print("")
System.print("=== Process Information ===")
System.print("PID: %(Process.pid)")
System.print("Parent PID: %(Process.ppid)")
System.print("Working Directory: %(Process.cwd)")
System.print("Wren Version: %(Process.version)")
System.print("")
System.print("=== Arguments ===")
System.print("Arguments: %(Process.arguments)")</code></pre>
<h3>Building File Paths</h3>
<pre><code>import "os" for Platform, Process
var separator = Platform.isWindows ? "\\" : "/"
var dataDir = Process.cwd + separator + "data"
var configFile = Platform.homePath + separator + ".myapprc"
System.print("Data directory: %(dataDir)")
System.print("Config file: %(configFile)")</code></pre>
<h3>Argument Parsing with Flags</h3>
<pre><code>import "os" for Process
var verbose = false
var outputFile = "output.txt"
var inputFiles = []
var i = 0
var args = Process.arguments
while (i < args.count) {
var arg = args[i]
if (arg == "-v" || arg == "--verbose") {
verbose = true
} else if (arg == "-o" || arg == "--output") {
i = i + 1
if (i < args.count) {
outputFile = args[i]
}
} else if (!arg.startsWith("-")) {
inputFiles.add(arg)
}
i = i + 1
}
System.print("Verbose: %(verbose)")
System.print("Output: %(outputFile)")
System.print("Input files: %(inputFiles)")</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p><code>Process.arguments</code> returns only the user's arguments (after the script path), while <code>Process.allArguments</code> includes the full command line including the interpreter.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>Use <code>Platform.isPosix</code> to write cross-platform code that handles path separators, shell commands, and other platform-specific differences.</p>
</div>
</article>
<footer class="page-footer">
<a href="crypto.html" class="prev">crypto</a>
<a href="env.html" class="next">env</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+353
View File
@@ -0,0 +1,353 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>regex - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html" class="active">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>regex</span>
</nav>
<article>
<h1>regex</h1>
<p>The <code>regex</code> module provides regular expression matching, replacement, and splitting using PCRE-compatible patterns.</p>
<pre><code>import "regex" for Regex, Match</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#regex-class">Regex Class</a></li>
<li><a href="#match-class">Match Class</a></li>
<li><a href="#pattern-syntax">Pattern Syntax</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="regex-class">Regex Class</h2>
<div class="class-header">
<h3>Regex</h3>
<p>Regular expression pattern</p>
</div>
<h3>Constructors</h3>
<div class="method-signature">
<span class="method-name">Regex.new</span>(<span class="param">pattern</span>) → <span class="type">Regex</span>
</div>
<p>Creates a new regex from a pattern string.</p>
<pre><code>var re = Regex.new("\\d+") // Match digits</code></pre>
<div class="method-signature">
<span class="method-name">Regex.new</span>(<span class="param">pattern</span>, <span class="param">flags</span>) → <span class="type">Regex</span>
</div>
<p>Creates a regex with flags.</p>
<ul class="param-list">
<li><span class="param-name">pattern</span> <span class="param-type">(String)</span> - Regex pattern</li>
<li><span class="param-name">flags</span> <span class="param-type">(String)</span> - Flags: "i" (case-insensitive), "m" (multiline), "s" (dotall)</li>
</ul>
<pre><code>var re = Regex.new("hello", "i") // Case-insensitive</code></pre>
<h3>Properties</h3>
<div class="method-signature">
<span class="method-name">pattern</span><span class="type">String</span>
</div>
<p>The pattern string.</p>
<div class="method-signature">
<span class="method-name">flags</span><span class="type">String</span>
</div>
<p>The flags string.</p>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">test</span>(<span class="param">string</span>) → <span class="type">Bool</span>
</div>
<p>Tests if the pattern matches anywhere in the string.</p>
<pre><code>var re = Regex.new("\\d+")
System.print(re.test("abc123")) // true
System.print(re.test("abc")) // false</code></pre>
<div class="method-signature">
<span class="method-name">match</span>(<span class="param">string</span>) → <span class="type">Match|null</span>
</div>
<p>Finds the first match in the string.</p>
<pre><code>var re = Regex.new("(\\w+)@(\\w+\\.\\w+)")
var m = re.match("email: alice@example.com")
if (m != null) {
System.print(m.text) // alice@example.com
System.print(m.group(1)) // alice
System.print(m.group(2)) // example.com
}</code></pre>
<div class="method-signature">
<span class="method-name">matchAll</span>(<span class="param">string</span>) → <span class="type">List</span>
</div>
<p>Finds all matches in the string.</p>
<pre><code>var re = Regex.new("\\d+")
var matches = re.matchAll("a1 b22 c333")
for (m in matches) {
System.print(m.text) // 1, 22, 333
}</code></pre>
<div class="method-signature">
<span class="method-name">replace</span>(<span class="param">string</span>, <span class="param">replacement</span>) → <span class="type">String</span>
</div>
<p>Replaces the first match with the replacement string.</p>
<pre><code>var re = Regex.new("\\d+")
System.print(re.replace("a1b2c3", "X")) // aXb2c3</code></pre>
<div class="method-signature">
<span class="method-name">replaceAll</span>(<span class="param">string</span>, <span class="param">replacement</span>) → <span class="type">String</span>
</div>
<p>Replaces all matches with the replacement string.</p>
<pre><code>var re = Regex.new("\\d+")
System.print(re.replaceAll("a1b2c3", "X")) // aXbXcX</code></pre>
<div class="method-signature">
<span class="method-name">split</span>(<span class="param">string</span>) → <span class="type">List</span>
</div>
<p>Splits the string by the pattern.</p>
<pre><code>var re = Regex.new("[,;\\s]+")
var parts = re.split("a, b; c d")
System.print(parts) // [a, b, c, d]</code></pre>
<h2 id="match-class">Match Class</h2>
<div class="class-header">
<h3>Match</h3>
<p>Regex match result</p>
</div>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td><code>text</code></td>
<td>String</td>
<td>The matched text</td>
</tr>
<tr>
<td><code>start</code></td>
<td>Num</td>
<td>Start index in the original string</td>
</tr>
<tr>
<td><code>end</code></td>
<td>Num</td>
<td>End index in the original string</td>
</tr>
<tr>
<td><code>groups</code></td>
<td>List</td>
<td>List of captured groups</td>
</tr>
</table>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">group</span>(<span class="param">index</span>) → <span class="type">String|null</span>
</div>
<p>Gets a captured group by index. Group 0 is the entire match.</p>
<pre><code>var re = Regex.new("(\\w+)-(\\d+)")
var m = re.match("item-42")
System.print(m.group(0)) // item-42
System.print(m.group(1)) // item
System.print(m.group(2)) // 42</code></pre>
<h2 id="pattern-syntax">Pattern Syntax</h2>
<h3>Character Classes</h3>
<table>
<tr><th>Pattern</th><th>Matches</th></tr>
<tr><td><code>.</code></td><td>Any character (except newline)</td></tr>
<tr><td><code>\d</code></td><td>Digit (0-9)</td></tr>
<tr><td><code>\D</code></td><td>Non-digit</td></tr>
<tr><td><code>\w</code></td><td>Word character (a-z, A-Z, 0-9, _)</td></tr>
<tr><td><code>\W</code></td><td>Non-word character</td></tr>
<tr><td><code>\s</code></td><td>Whitespace</td></tr>
<tr><td><code>\S</code></td><td>Non-whitespace</td></tr>
<tr><td><code>[abc]</code></td><td>Any of a, b, or c</td></tr>
<tr><td><code>[^abc]</code></td><td>Not a, b, or c</td></tr>
<tr><td><code>[a-z]</code></td><td>Range a through z</td></tr>
</table>
<h3>Quantifiers</h3>
<table>
<tr><th>Pattern</th><th>Matches</th></tr>
<tr><td><code>*</code></td><td>0 or more</td></tr>
<tr><td><code>+</code></td><td>1 or more</td></tr>
<tr><td><code>?</code></td><td>0 or 1</td></tr>
<tr><td><code>{n}</code></td><td>Exactly n times</td></tr>
<tr><td><code>{n,}</code></td><td>n or more times</td></tr>
<tr><td><code>{n,m}</code></td><td>Between n and m times</td></tr>
</table>
<h3>Anchors</h3>
<table>
<tr><th>Pattern</th><th>Matches</th></tr>
<tr><td><code>^</code></td><td>Start of string/line</td></tr>
<tr><td><code>$</code></td><td>End of string/line</td></tr>
<tr><td><code>\b</code></td><td>Word boundary</td></tr>
<tr><td><code>\B</code></td><td>Non-word boundary</td></tr>
</table>
<h3>Groups</h3>
<table>
<tr><th>Pattern</th><th>Description</th></tr>
<tr><td><code>(abc)</code></td><td>Capturing group</td></tr>
<tr><td><code>(?:abc)</code></td><td>Non-capturing group</td></tr>
<tr><td><code>a|b</code></td><td>Alternation (a or b)</td></tr>
</table>
<h2 id="examples">Examples</h2>
<h3>Email Validation</h3>
<pre><code>import "regex" for Regex
var emailRe = Regex.new("^[\\w.+-]+@[\\w-]+\\.[\\w.-]+$")
var emails = ["alice@example.com", "invalid", "bob@test.org"]
for (email in emails) {
if (emailRe.test(email)) {
System.print("%(email) is valid")
} else {
System.print("%(email) is invalid")
}
}</code></pre>
<h3>Extracting Data</h3>
<pre><code>import "regex" for Regex
var logRe = Regex.new("(\\d{4}-\\d{2}-\\d{2}) (\\w+): (.+)")
var log = "2024-01-15 ERROR: Connection failed"
var m = logRe.match(log)
if (m != null) {
System.print("Date: %(m.group(1))") // 2024-01-15
System.print("Level: %(m.group(2))") // ERROR
System.print("Message: %(m.group(3))") // Connection failed
}</code></pre>
<h3>Find and Replace</h3>
<pre><code>import "regex" for Regex
var text = "Call 555-1234 or 555-5678"
var phoneRe = Regex.new("\\d{3}-\\d{4}")
var redacted = phoneRe.replaceAll(text, "XXX-XXXX")
System.print(redacted) // Call XXX-XXXX or XXX-XXXX</code></pre>
<h3>Parsing URLs</h3>
<pre><code>import "regex" for Regex
var urlRe = Regex.new("(https?)://([^/]+)(/.*)?")
var url = "https://example.com/path/to/page"
var m = urlRe.match(url)
System.print("Scheme: %(m.group(1))") // https
System.print("Host: %(m.group(2))") // example.com
System.print("Path: %(m.group(3))") // /path/to/page</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Remember to escape backslashes in Wren strings. Use <code>\\d</code> instead of <code>\d</code>.</p>
</div>
</article>
<footer class="page-footer">
<a href="base64.html" class="prev">base64</a>
<a href="jinja.html" class="next">jinja</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+193
View File
@@ -0,0 +1,193 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>scheduler - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html" class="active">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>scheduler</span>
</nav>
<article>
<h1>scheduler</h1>
<p>The <code>scheduler</code> module manages the async event loop and fiber scheduling. It is the foundation for all async operations in Wren-CLI.</p>
<pre><code>import "scheduler" for Scheduler</code></pre>
<h2>Scheduler Class</h2>
<div class="class-header">
<h3>Scheduler</h3>
<p>Async fiber scheduler</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Scheduler.await_</span>(<span class="param">block</span>) → <span class="type">any</span>
</div>
<p>Suspends the current fiber until an async operation completes. Used internally by modules to implement async operations.</p>
<ul class="param-list">
<li><span class="param-name">block</span> <span class="param-type">(Fn)</span> - Block that initiates the async operation</li>
<li><span class="returns">Returns:</span> Result of the async operation</li>
</ul>
<pre><code>var result = Scheduler.await_ {
Timer.sleep_(1000, Fiber.current)
}</code></pre>
<div class="method-signature">
<span class="method-name">Scheduler.resume_</span>(<span class="param">fiber</span>)
</div>
<p>Resumes a suspended fiber. Used by native code to wake up fibers when async operations complete.</p>
<div class="method-signature">
<span class="method-name">Scheduler.resume_</span>(<span class="param">fiber</span>, <span class="param">value</span>)
</div>
<p>Resumes a fiber with a result value.</p>
<h2>How Async Works</h2>
<p>Wren-CLI uses an event loop (libuv) for non-blocking I/O. Here is how async operations work:</p>
<ol>
<li>A Wren fiber calls an async method (e.g., <code>Http.get</code>)</li>
<li>The method starts a native async operation and suspends the fiber</li>
<li>The event loop continues processing other events</li>
<li>When the operation completes, the fiber is resumed with the result</li>
</ol>
<h3>Under the Hood</h3>
<pre><code>// How Timer.sleep works internally
class Timer {
static sleep(ms) {
return Scheduler.await_ {
Timer.sleep_(ms, Fiber.current)
}
}
foreign static sleep_(ms, fiber)
}</code></pre>
<h2>Examples</h2>
<h3>Sequential vs Parallel</h3>
<p>Operations are sequential by default:</p>
<pre><code>import "http" for Http
// These run one after another (sequential)
var r1 = Http.get("https://api.example.com/1")
var r2 = Http.get("https://api.example.com/2")
var r3 = Http.get("https://api.example.com/3")</code></pre>
<p>For parallel operations, use multiple fibers:</p>
<pre><code>import "http" for Http
var fibers = [
Fiber.new { Http.get("https://api.example.com/1") },
Fiber.new { Http.get("https://api.example.com/2") },
Fiber.new { Http.get("https://api.example.com/3") }
]
// Start all fibers
for (f in fibers) f.call()
// Results are already available when fibers complete</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>The scheduler is used internally by modules. Most user code does not need to interact with it directly. Use higher-level modules like <code>timer</code>, <code>http</code>, and <code>io</code> instead.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>Async operations in Wren-CLI are cooperative, not preemptive. A fiber runs until it explicitly yields or calls an async operation.</p>
</div>
</article>
<footer class="page-footer">
<a href="io.html" class="prev">io</a>
<a href="math.html" class="next">math</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+349
View File
@@ -0,0 +1,349 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>signal - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html" class="active">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>signal</span>
</nav>
<article>
<h1>signal</h1>
<p>The <code>signal</code> module provides Unix signal handling capabilities, allowing scripts to trap, ignore, or reset signal handlers.</p>
<pre><code>import "signal" for Signal</code></pre>
<h2>Signal Class</h2>
<div class="class-header">
<h3>Signal</h3>
<p>Unix signal handling</p>
</div>
<h3>Signal Constants</h3>
<table>
<tr>
<th>Constant</th>
<th>Value</th>
<th>Description</th>
</tr>
<tr>
<td><code>Signal.SIGHUP</code></td>
<td>1</td>
<td>Hangup (terminal closed or controlling process ended)</td>
</tr>
<tr>
<td><code>Signal.SIGINT</code></td>
<td>2</td>
<td>Interrupt (Ctrl+C)</td>
</tr>
<tr>
<td><code>Signal.SIGQUIT</code></td>
<td>3</td>
<td>Quit (Ctrl+\)</td>
</tr>
<tr>
<td><code>Signal.SIGTERM</code></td>
<td>15</td>
<td>Termination request</td>
</tr>
<tr>
<td><code>Signal.SIGUSR1</code></td>
<td>10</td>
<td>User-defined signal 1</td>
</tr>
<tr>
<td><code>Signal.SIGUSR2</code></td>
<td>12</td>
<td>User-defined signal 2</td>
</tr>
</table>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Signal.trap</span>(<span class="param">signum</span>, <span class="param">fn</span>)
</div>
<p>Registers a handler function to be called when the signal is received. The handler will be called each time the signal is received.</p>
<ul class="param-list">
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number or constant</li>
<li><span class="param-name">fn</span> <span class="param-type">(Fn)</span> - Handler function (no arguments)</li>
</ul>
<pre><code>Signal.trap(Signal.SIGINT) {
System.print("Caught Ctrl+C!")
}</code></pre>
<div class="method-signature">
<span class="method-name">Signal.ignore</span>(<span class="param">signum</span>)
</div>
<p>Ignores the specified signal. The signal will be delivered but have no effect.</p>
<ul class="param-list">
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number to ignore</li>
</ul>
<pre><code>Signal.ignore(Signal.SIGHUP)</code></pre>
<div class="method-signature">
<span class="method-name">Signal.reset</span>(<span class="param">signum</span>)
</div>
<p>Resets the signal handler to the default behavior.</p>
<ul class="param-list">
<li><span class="param-name">signum</span> <span class="param-type">(Num)</span> - Signal number to reset</li>
</ul>
<pre><code>Signal.reset(Signal.SIGINT)</code></pre>
<h2>Examples</h2>
<h3>Graceful Shutdown</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
var running = true
Signal.trap(Signal.SIGINT) {
System.print("\nShutting down gracefully...")
running = false
}
Signal.trap(Signal.SIGTERM) {
System.print("\nReceived SIGTERM, shutting down...")
running = false
}
System.print("Server running. Press Ctrl+C to stop.")
while (running) {
Timer.sleep(1000)
}
System.print("Cleanup complete. Goodbye!")</code></pre>
<h3>Configuration Reload on SIGHUP</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
import "io" for File
var config = {}
var loadConfig = Fn.new {
System.print("Loading configuration...")
if (File.exists("config.json")) {
var content = File.read("config.json")
System.print("Config loaded: %(content)")
}
}
loadConfig.call()
Signal.trap(Signal.SIGHUP) {
System.print("Received SIGHUP, reloading config...")
loadConfig.call()
}
System.print("Running. Send SIGHUP to reload config.")
while (true) {
Timer.sleep(1000)
}</code></pre>
<h3>Custom Signal for Debug Dump</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
import "datetime" for DateTime
var requestCount = 0
var startTime = DateTime.now()
Signal.trap(Signal.SIGUSR1) {
System.print("=== Debug Dump ===")
System.print("Requests handled: %(requestCount)")
var uptime = DateTime.now() - startTime
System.print("Uptime: %(uptime.hours) hours")
System.print("==================")
}
System.print("Send SIGUSR1 for debug info (kill -USR1 pid)")
while (true) {
requestCount = requestCount + 1
Timer.sleep(100)
}</code></pre>
<h3>Ignoring Signals</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
Signal.ignore(Signal.SIGINT)
System.print("SIGINT is now ignored. Ctrl+C will not stop this script.")
System.print("Use 'kill -9 pid' to force stop.")
for (i in 1..10) {
System.print("Still running... %(i)")
Timer.sleep(1000)
}
Signal.reset(Signal.SIGINT)
System.print("SIGINT handler restored. Ctrl+C works again.")</code></pre>
<h3>Multiple Signal Handlers</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
var shutdownRequested = false
var forceShutdown = false
Signal.trap(Signal.SIGINT) {
if (shutdownRequested) {
System.print("\nForce shutdown!")
forceShutdown = true
} else {
System.print("\nGraceful shutdown requested. Press Ctrl+C again to force.")
shutdownRequested = true
}
}
Signal.trap(Signal.SIGTERM) {
System.print("\nSIGTERM received, shutting down immediately.")
forceShutdown = true
}
System.print("Running... Press Ctrl+C to stop.")
while (!forceShutdown) {
if (shutdownRequested) {
System.print("Cleaning up...")
Timer.sleep(500)
break
}
Timer.sleep(100)
}
System.print("Exited.")</code></pre>
<h3>Worker Process Control</h3>
<pre><code>import "signal" for Signal
import "timer" for Timer
var paused = false
Signal.trap(Signal.SIGUSR1) {
paused = true
System.print("Worker paused")
}
Signal.trap(Signal.SIGUSR2) {
paused = false
System.print("Worker resumed")
}
System.print("Worker running. SIGUSR1 to pause, SIGUSR2 to resume.")
var count = 0
while (true) {
if (!paused) {
count = count + 1
System.print("Working... %(count)")
}
Timer.sleep(1000)
}</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Signal handling is only available on POSIX systems (Linux, macOS, BSD). On Windows, signal support is limited.</p>
</div>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>Some signals like SIGKILL (9) and SIGSTOP (19) cannot be trapped or ignored. Attempting to do so will have no effect.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>Always implement graceful shutdown handlers for long-running services. Use SIGTERM for clean shutdowns and reserve SIGINT for interactive termination.</p>
</div>
</article>
<footer class="page-footer">
<a href="env.html" class="prev">env</a>
<a href="subprocess.html" class="next">subprocess</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+256
View File
@@ -0,0 +1,256 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>sqlite - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html" class="active">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>sqlite</span>
</nav>
<article>
<h1>sqlite</h1>
<p>The <code>sqlite</code> module provides SQLite database functionality for persistent data storage.</p>
<pre><code>import "sqlite" for Sqlite</code></pre>
<h2>Sqlite Class</h2>
<div class="class-header">
<h3>Sqlite</h3>
<p>SQLite database connection</p>
</div>
<h3>Constructors</h3>
<div class="method-signature">
<span class="method-name">Sqlite.open</span>(<span class="param">path</span>) → <span class="type">Sqlite</span>
</div>
<p>Opens or creates an SQLite database file.</p>
<ul class="param-list">
<li><span class="param-name">path</span> <span class="param-type">(String)</span> - Path to the database file</li>
<li><span class="returns">Returns:</span> Database connection</li>
</ul>
<pre><code>var db = Sqlite.open("data.db")</code></pre>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">execute</span>(<span class="param">sql</span>) → <span class="type">List</span>
</div>
<p>Executes an SQL statement and returns the results.</p>
<ul class="param-list">
<li><span class="param-name">sql</span> <span class="param-type">(String)</span> - SQL statement</li>
<li><span class="returns">Returns:</span> List of result rows (each row is a Map)</li>
</ul>
<pre><code>var rows = db.execute("SELECT * FROM users")
for (row in rows) {
System.print(row["name"])
}</code></pre>
<div class="method-signature">
<span class="method-name">execute</span>(<span class="param">sql</span>, <span class="param">params</span>) → <span class="type">List</span>
</div>
<p>Executes a parameterized SQL statement (prevents SQL injection).</p>
<ul class="param-list">
<li><span class="param-name">sql</span> <span class="param-type">(String)</span> - SQL with ? placeholders</li>
<li><span class="param-name">params</span> <span class="param-type">(List)</span> - Parameter values</li>
</ul>
<pre><code>var rows = db.execute("SELECT * FROM users WHERE age > ?", [18])</code></pre>
<div class="method-signature">
<span class="method-name">lastInsertId</span><span class="type">Num</span>
</div>
<p>Returns the row ID of the last INSERT operation.</p>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Closes the database connection.</p>
<h2>Examples</h2>
<h3>Creating Tables</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
db.execute("
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
")
db.close()</code></pre>
<h3>Inserting Data</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Alice", "alice@example.com"])
System.print("Inserted user with ID: %(db.lastInsertId)")
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Bob", "bob@example.com"])
db.close()</code></pre>
<h3>Querying Data</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
var users = db.execute("SELECT * FROM users ORDER BY name")
for (user in users) {
System.print("%(user["id"]): %(user["name"]) <%(user["email"])>")
}
var user = db.execute("SELECT * FROM users WHERE id = ?", [1])
if (user.count > 0) {
System.print("Found: %(user[0]["name"])")
}
db.close()</code></pre>
<h3>Updating Data</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
db.execute("UPDATE users SET email = ? WHERE id = ?", ["newemail@example.com", 1])
db.close()</code></pre>
<h3>Deleting Data</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
db.execute("DELETE FROM users WHERE id = ?", [2])
db.close()</code></pre>
<h3>Transactions</h3>
<pre><code>import "sqlite" for Sqlite
var db = Sqlite.open("app.db")
db.execute("BEGIN TRANSACTION")
var fiber = Fiber.new {
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Charlie", "charlie@example.com"])
db.execute("INSERT INTO users (name, email) VALUES (?, ?)", ["Diana", "diana@example.com"])
}
var error = fiber.try()
if (error) {
db.execute("ROLLBACK")
System.print("Error: %(error)")
} else {
db.execute("COMMIT")
System.print("Transaction committed")
}
db.close()</code></pre>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>Always use parameterized queries with <code>?</code> placeholders to prevent SQL injection attacks. Never concatenate user input directly into SQL strings.</p>
</div>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Use <code>":memory:"</code> as the path for an in-memory database that does not persist to disk.</p>
</div>
</article>
<footer class="page-footer">
<a href="subprocess.html" class="prev">subprocess</a>
<a href="datetime.html" class="next">datetime</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+179
View File
@@ -0,0 +1,179 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>subprocess - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html" class="active">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>subprocess</span>
</nav>
<article>
<h1>subprocess</h1>
<p>The <code>subprocess</code> module allows running external commands and capturing their output.</p>
<pre><code>import "subprocess" for Subprocess</code></pre>
<h2>Subprocess Class</h2>
<div class="class-header">
<h3>Subprocess</h3>
<p>External process execution</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Subprocess.run</span>(<span class="param">command</span>) → <span class="type">Map</span>
</div>
<p>Runs a command and waits for it to complete.</p>
<ul class="param-list">
<li><span class="param-name">command</span> <span class="param-type">(List)</span> - Command and arguments as a list</li>
<li><span class="returns">Returns:</span> Map with "stdout", "stderr", and "exitCode"</li>
</ul>
<pre><code>var result = Subprocess.run(["ls", "-la"])
System.print("Exit code: %(result["exitCode"])")
System.print("Output: %(result["stdout"])")</code></pre>
<div class="method-signature">
<span class="method-name">Subprocess.run</span>(<span class="param">command</span>, <span class="param">input</span>) → <span class="type">Map</span>
</div>
<p>Runs a command with input data provided to stdin.</p>
<ul class="param-list">
<li><span class="param-name">command</span> <span class="param-type">(List)</span> - Command and arguments</li>
<li><span class="param-name">input</span> <span class="param-type">(String)</span> - Input to send to stdin</li>
</ul>
<pre><code>var result = Subprocess.run(["cat"], "Hello, World!")
System.print(result["stdout"]) // Hello, World!</code></pre>
<h2>Examples</h2>
<h3>Running Commands</h3>
<pre><code>import "subprocess" for Subprocess
var result = Subprocess.run(["echo", "Hello"])
System.print(result["stdout"]) // Hello
var files = Subprocess.run(["ls", "-la", "/tmp"])
System.print(files["stdout"])</code></pre>
<h3>Checking Exit Codes</h3>
<pre><code>import "subprocess" for Subprocess
var result = Subprocess.run(["grep", "pattern", "file.txt"])
if (result["exitCode"] == 0) {
System.print("Found: %(result["stdout"])")
} else {
System.print("Not found or error")
}</code></pre>
<h3>Processing Data</h3>
<pre><code>import "subprocess" for Subprocess
import "json" for Json
var result = Subprocess.run(["curl", "-s", "https://api.example.com/data"])
if (result["exitCode"] == 0) {
var data = Json.parse(result["stdout"])
System.print(data)
}</code></pre>
<h3>Piping Data</h3>
<pre><code>import "subprocess" for Subprocess
var input = "line1\nline2\nline3"
var result = Subprocess.run(["wc", "-l"], input)
System.print("Lines: %(result["stdout"].trim())")</code></pre>
<div class="admonition warning">
<div class="admonition-title">Warning</div>
<p>Commands are not executed through a shell. Use explicit command and argument lists, not shell command strings.</p>
</div>
</article>
<footer class="page-footer">
<a href="signal.html" class="prev">signal</a>
<a href="sqlite.html" class="next">sqlite</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+201
View File
@@ -0,0 +1,201 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>timer - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html" class="active">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>timer</span>
</nav>
<article>
<h1>timer</h1>
<p>The <code>timer</code> module provides timing functionality for delays and intervals.</p>
<pre><code>import "timer" for Timer</code></pre>
<h2>Timer Class</h2>
<div class="class-header">
<h3>Timer</h3>
<p>Timer and delay functionality</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">Timer.sleep</span>(<span class="param">milliseconds</span>)
</div>
<p>Pauses execution for the specified duration. The fiber suspends and other operations can proceed.</p>
<ul class="param-list">
<li><span class="param-name">milliseconds</span> <span class="param-type">(Num)</span> - Duration to sleep in milliseconds</li>
</ul>
<pre><code>System.print("Starting...")
Timer.sleep(1000) // Wait 1 second
System.print("Done!")</code></pre>
<h2>Examples</h2>
<h3>Basic Delay</h3>
<pre><code>import "timer" for Timer
System.print("Starting...")
Timer.sleep(2000)
System.print("2 seconds later...")</code></pre>
<h3>Polling Loop</h3>
<pre><code>import "timer" for Timer
import "http" for Http
var checkStatus = Fn.new {
var response = Http.get("https://api.example.com/status")
return response.json["ready"]
}
while (!checkStatus.call()) {
System.print("Waiting...")
Timer.sleep(5000) // Check every 5 seconds
}
System.print("Ready!")</code></pre>
<h3>Rate Limiting</h3>
<pre><code>import "timer" for Timer
import "http" for Http
var urls = [
"https://api.example.com/1",
"https://api.example.com/2",
"https://api.example.com/3"
]
for (url in urls) {
var response = Http.get(url)
System.print("%(url): %(response.statusCode)")
Timer.sleep(1000) // 1 second between requests
}</code></pre>
<h3>Timeout Pattern</h3>
<pre><code>import "timer" for Timer
import "datetime" for DateTime, Duration
var start = DateTime.now()
var timeout = Duration.fromSeconds(30)
while (true) {
var elapsed = DateTime.now() - start
if (elapsed.seconds >= timeout.seconds) {
System.print("Timeout!")
break
}
// Do work...
Timer.sleep(100)
}</code></pre>
<h3>Animation/Progress</h3>
<pre><code>import "timer" for Timer
var frames = ["-", "\\", "|", "/"]
var i = 0
for (step in 1..20) {
System.write("\rProcessing %(frames[i]) ")
i = (i + 1) % 4
Timer.sleep(100)
}
System.print("\rDone! ")</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Timer.sleep is non-blocking at the event loop level. The current fiber suspends, but other scheduled operations can continue.</p>
</div>
</article>
<footer class="page-footer">
<a href="datetime.html" class="prev">datetime</a>
<a href="io.html" class="next">io</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+242
View File
@@ -0,0 +1,242 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tls - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html">websocket</a></li>
<li><a href="tls.html" class="active">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>tls</span>
</nav>
<article>
<h1>tls</h1>
<p>The <code>tls</code> module provides SSL/TLS socket support for secure network connections. It uses OpenSSL for encryption and is used internally by the <code>http</code> module for HTTPS connections.</p>
<pre><code>import "tls" for TlsSocket</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#tlssocket-class">TlsSocket Class</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="tlssocket-class">TlsSocket Class</h2>
<div class="class-header">
<h3>TlsSocket</h3>
<p>SSL/TLS encrypted socket connection</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">TlsSocket.connect</span>(<span class="param">host</span>, <span class="param">port</span>, <span class="param">hostname</span>) &#8594; <span class="type">TlsSocket</span>
</div>
<p>Establishes a TLS connection to a remote server.</p>
<ul class="param-list">
<li><span class="param-name">host</span> <span class="param-type">(String)</span> - IP address to connect to</li>
<li><span class="param-name">port</span> <span class="param-type">(Num)</span> - Port number (typically 443 for HTTPS)</li>
<li><span class="param-name">hostname</span> <span class="param-type">(String)</span> - Server hostname for SNI (Server Name Indication)</li>
<li><span class="returns">Returns:</span> Connected TlsSocket instance</li>
</ul>
<pre><code>var socket = TlsSocket.connect("93.184.216.34", 443, "example.com")</code></pre>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">write</span>(<span class="param">text</span>)
</div>
<p>Writes data to the TLS connection. This is an async operation that blocks until the data is sent.</p>
<ul class="param-list">
<li><span class="param-name">text</span> <span class="param-type">(String)</span> - Data to send</li>
</ul>
<pre><code>socket.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")</code></pre>
<div class="method-signature">
<span class="method-name">read</span>() &#8594; <span class="type">String|null</span>
</div>
<p>Reads data from the TLS connection. Blocks until data is available. Returns null when the connection is closed.</p>
<ul class="param-list">
<li><span class="returns">Returns:</span> Data received as a string, or null if connection closed</li>
</ul>
<pre><code>var data = socket.read()
if (data != null) {
System.print(data)
}</code></pre>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Closes the TLS connection and releases resources.</p>
<pre><code>socket.close()</code></pre>
<h2 id="examples">Examples</h2>
<h3>Basic HTTPS Request</h3>
<pre><code>import "tls" for TlsSocket
import "dns" for Dns
var host = "example.com"
var ip = Dns.lookup(host)
var socket = TlsSocket.connect(ip, 443, host)
socket.write("GET / HTTP/1.1\r\n")
socket.write("Host: %(host)\r\n")
socket.write("Connection: close\r\n")
socket.write("\r\n")
var response = ""
while (true) {
var chunk = socket.read()
if (chunk == null) break
response = response + chunk
}
socket.close()
System.print(response)</code></pre>
<h3>Reading Until Complete</h3>
<pre><code>import "tls" for TlsSocket
import "dns" for Dns
var host = "api.example.com"
var ip = Dns.lookup(host)
var socket = TlsSocket.connect(ip, 443, host)
socket.write("GET /data HTTP/1.1\r\n")
socket.write("Host: %(host)\r\n")
socket.write("Accept: application/json\r\n")
socket.write("Connection: close\r\n\r\n")
var buffer = ""
while (true) {
var data = socket.read()
if (data == null) break
buffer = buffer + data
}
socket.close()
var bodyStart = buffer.indexOf("\r\n\r\n")
if (bodyStart != -1) {
var body = buffer[bodyStart + 4..-1]
System.print("Response body: %(body)")
}</code></pre>
<h3>Using with DNS Resolution</h3>
<pre><code>import "tls" for TlsSocket
import "dns" for Dns
var hostname = "secure.example.com"
var ip = Dns.lookup(hostname, 4)
System.print("Connecting to %(ip)")
var socket = TlsSocket.connect(ip, 443, hostname)
socket.write("GET /secure-endpoint HTTP/1.1\r\nHost: %(hostname)\r\n\r\n")
var response = socket.read()
System.print(response)
socket.close()</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>The <code>hostname</code> parameter is used for SNI (Server Name Indication), which is required when connecting to servers that host multiple domains on the same IP address. It should match the domain name in the server's certificate.</p>
</div>
<div class="admonition tip">
<div class="admonition-title">Tip</div>
<p>For most use cases, consider using the higher-level <code>http</code> module which handles TLS connections, HTTP protocol details, and response parsing automatically.</p>
</div>
</article>
<footer class="page-footer">
<a href="websocket.html" class="prev">websocket</a>
<a href="net.html" class="next">net</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>
+508
View File
@@ -0,0 +1,508 @@
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>websocket - Wren-CLI Manual</title>
<link rel="stylesheet" href="../css/style.css">
</head>
<body>
<button class="mobile-menu-toggle">Menu</button>
<div class="container">
<aside class="sidebar">
<div class="sidebar-header">
<h1><a href="../index.html">Wren-CLI</a></h1>
<div class="version">v0.4.0</div>
</div>
<nav class="sidebar-nav">
<div class="section">
<span class="section-title">Getting Started</span>
<ul>
<li><a href="../getting-started/index.html">Overview</a></li>
<li><a href="../getting-started/installation.html">Installation</a></li>
<li><a href="../getting-started/first-script.html">First Script</a></li>
<li><a href="../getting-started/repl.html">Using the REPL</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Language</span>
<ul>
<li><a href="../language/index.html">Syntax Overview</a></li>
<li><a href="../language/classes.html">Classes</a></li>
<li><a href="../language/methods.html">Methods</a></li>
<li><a href="../language/control-flow.html">Control Flow</a></li>
<li><a href="../language/fibers.html">Fibers</a></li>
<li><a href="../language/modules.html">Modules</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">API Reference</span>
<ul>
<li><a href="index.html">Overview</a></li>
<li><a href="http.html">http</a></li>
<li><a href="websocket.html" class="active">websocket</a></li>
<li><a href="tls.html">tls</a></li>
<li><a href="net.html">net</a></li>
<li><a href="dns.html">dns</a></li>
<li><a href="json.html">json</a></li>
<li><a href="base64.html">base64</a></li>
<li><a href="regex.html">regex</a></li>
<li><a href="jinja.html">jinja</a></li>
<li><a href="crypto.html">crypto</a></li>
<li><a href="os.html">os</a></li>
<li><a href="env.html">env</a></li>
<li><a href="signal.html">signal</a></li>
<li><a href="subprocess.html">subprocess</a></li>
<li><a href="sqlite.html">sqlite</a></li>
<li><a href="datetime.html">datetime</a></li>
<li><a href="timer.html">timer</a></li>
<li><a href="io.html">io</a></li>
<li><a href="scheduler.html">scheduler</a></li>
<li><a href="math.html">math</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">Tutorials</span>
<ul>
<li><a href="../tutorials/index.html">Tutorial List</a></li>
<li><a href="../tutorials/http-client.html">HTTP Client</a></li>
<li><a href="../tutorials/websocket-chat.html">WebSocket Chat</a></li>
<li><a href="../tutorials/database-app.html">Database App</a></li>
<li><a href="../tutorials/template-rendering.html">Templates</a></li>
<li><a href="../tutorials/cli-tool.html">CLI Tool</a></li>
</ul>
</div>
<div class="section">
<span class="section-title">How-To Guides</span>
<ul>
<li><a href="../howto/index.html">How-To List</a></li>
<li><a href="../howto/http-requests.html">HTTP Requests</a></li>
<li><a href="../howto/json-parsing.html">JSON Parsing</a></li>
<li><a href="../howto/regex-patterns.html">Regex Patterns</a></li>
<li><a href="../howto/file-operations.html">File Operations</a></li>
<li><a href="../howto/async-operations.html">Async Operations</a></li>
<li><a href="../howto/error-handling.html">Error Handling</a></li>
</ul>
</div>
</nav>
</aside>
<main class="content">
<nav class="breadcrumb">
<a href="../index.html">Home</a>
<span class="separator">/</span>
<a href="index.html">API Reference</a>
<span class="separator">/</span>
<span>websocket</span>
</nav>
<article>
<h1>websocket</h1>
<p>The <code>websocket</code> module provides WebSocket client and server functionality implementing the RFC 6455 protocol. It supports both <code>ws://</code> and <code>wss://</code> (secure) connections.</p>
<pre><code>import "websocket" for WebSocket, WebSocketServer, WebSocketMessage</code></pre>
<div class="toc">
<h4>On This Page</h4>
<ul>
<li><a href="#websocket-class">WebSocket Class</a></li>
<li><a href="#websocketserver-class">WebSocketServer Class</a></li>
<li><a href="#websocketmessage-class">WebSocketMessage Class</a></li>
<li><a href="#opcodes">Frame Opcodes</a></li>
<li><a href="#examples">Examples</a></li>
</ul>
</div>
<h2 id="websocket-class">WebSocket Class</h2>
<p>WebSocket client for connecting to WebSocket servers.</p>
<div class="class-header">
<h3>WebSocket</h3>
<p>WebSocket client connection</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">WebSocket.connect</span>(<span class="param">url</span>) → <span class="type">WebSocket</span>
</div>
<p>Connects to a WebSocket server.</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - WebSocket URL (ws:// or wss://)</li>
<li><span class="returns">Returns:</span> Connected WebSocket instance</li>
</ul>
<pre><code>var ws = WebSocket.connect("ws://echo.websocket.org")</code></pre>
<div class="method-signature">
<span class="method-name">WebSocket.connect</span>(<span class="param">url</span>, <span class="param">headers</span>) → <span class="type">WebSocket</span>
</div>
<p>Connects with custom headers (useful for authentication).</p>
<ul class="param-list">
<li><span class="param-name">url</span> <span class="param-type">(String)</span> - WebSocket URL</li>
<li><span class="param-name">headers</span> <span class="param-type">(Map)</span> - Custom HTTP headers for handshake</li>
</ul>
<pre><code>var headers = {"Authorization": "Bearer token123"}
var ws = WebSocket.connect("wss://api.example.com/ws", headers)</code></pre>
<h3>Properties</h3>
<div class="method-signature">
<span class="method-name">url</span><span class="type">String</span>
</div>
<p>The URL this WebSocket is connected to.</p>
<div class="method-signature">
<span class="method-name">isOpen</span><span class="type">Bool</span>
</div>
<p>True if the connection is still open.</p>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">send</span>(<span class="param">text</span>)
</div>
<p>Sends a text message to the server.</p>
<ul class="param-list">
<li><span class="param-name">text</span> <span class="param-type">(String)</span> - Text message to send</li>
</ul>
<pre><code>ws.send("Hello, server!")</code></pre>
<div class="method-signature">
<span class="method-name">sendBinary</span>(<span class="param">bytes</span>)
</div>
<p>Sends a binary message to the server.</p>
<ul class="param-list">
<li><span class="param-name">bytes</span> <span class="param-type">(List)</span> - List of bytes to send</li>
</ul>
<pre><code>ws.sendBinary([0x01, 0x02, 0x03, 0x04])</code></pre>
<div class="method-signature">
<span class="method-name">receive</span>() → <span class="type">WebSocketMessage|null</span>
</div>
<p>Receives the next message from the server. Blocks until a message arrives. Returns null if the connection is closed.</p>
<pre><code>var msg = ws.receive()
if (msg != null && msg.isText) {
System.print("Got: %(msg.text)")
}</code></pre>
<div class="method-signature">
<span class="method-name">ping</span>()
</div>
<p>Sends a ping frame to the server.</p>
<div class="method-signature">
<span class="method-name">ping</span>(<span class="param">data</span>)
</div>
<p>Sends a ping frame with payload data (max 125 bytes).</p>
<div class="method-signature">
<span class="method-name">pong</span>(<span class="param">data</span>)
</div>
<p>Sends a pong frame (usually automatic in response to ping).</p>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Closes the connection with status code 1000 (normal closure).</p>
<div class="method-signature">
<span class="method-name">close</span>(<span class="param">code</span>, <span class="param">reason</span>)
</div>
<p>Closes the connection with a custom status code and reason.</p>
<ul class="param-list">
<li><span class="param-name">code</span> <span class="param-type">(Num)</span> - Close status code (1000-4999)</li>
<li><span class="param-name">reason</span> <span class="param-type">(String)</span> - Human-readable close reason</li>
</ul>
<pre><code>ws.close(1000, "Goodbye")</code></pre>
<h2 id="websocketserver-class">WebSocketServer Class</h2>
<p>WebSocket server for accepting client connections.</p>
<div class="class-header">
<h3>WebSocketServer</h3>
<p>WebSocket server</p>
</div>
<h3>Static Methods</h3>
<div class="method-signature">
<span class="method-name">WebSocketServer.bind</span>(<span class="param">host</span>, <span class="param">port</span>) → <span class="type">WebSocketServer</span>
</div>
<p>Creates a WebSocket server listening on the specified host and port.</p>
<ul class="param-list">
<li><span class="param-name">host</span> <span class="param-type">(String)</span> - Host to bind to (e.g., "0.0.0.0", "127.0.0.1")</li>
<li><span class="param-name">port</span> <span class="param-type">(Num)</span> - Port number</li>
</ul>
<pre><code>var server = WebSocketServer.bind("0.0.0.0", 8080)</code></pre>
<h3>Methods</h3>
<div class="method-signature">
<span class="method-name">accept</span>() → <span class="type">WebSocket|null</span>
</div>
<p>Accepts and upgrades an incoming connection. Blocks until a client connects. Returns a WebSocket instance for the connected client.</p>
<pre><code>var client = server.accept()
if (client != null) {
System.print("Client connected!")
}</code></pre>
<div class="method-signature">
<span class="method-name">close</span>()
</div>
<p>Stops the server and closes the listening socket.</p>
<h2 id="websocketmessage-class">WebSocketMessage Class</h2>
<p>Represents a WebSocket frame received from a connection.</p>
<div class="class-header">
<h3>WebSocketMessage</h3>
<p>WebSocket message/frame</p>
</div>
<h3>Properties</h3>
<table>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td><code>opcode</code></td>
<td>Num</td>
<td>Frame opcode (1=text, 2=binary, 8=close, 9=ping, 10=pong)</td>
</tr>
<tr>
<td><code>payload</code></td>
<td>List</td>
<td>Raw payload bytes</td>
</tr>
<tr>
<td><code>fin</code></td>
<td>Bool</td>
<td>True if this is the final fragment</td>
</tr>
<tr>
<td><code>isText</code></td>
<td>Bool</td>
<td>True if this is a text frame</td>
</tr>
<tr>
<td><code>isBinary</code></td>
<td>Bool</td>
<td>True if this is a binary frame</td>
</tr>
<tr>
<td><code>isClose</code></td>
<td>Bool</td>
<td>True if this is a close frame</td>
</tr>
<tr>
<td><code>isPing</code></td>
<td>Bool</td>
<td>True if this is a ping frame</td>
</tr>
<tr>
<td><code>isPong</code></td>
<td>Bool</td>
<td>True if this is a pong frame</td>
</tr>
<tr>
<td><code>text</code></td>
<td>String</td>
<td>Payload as string (only for text frames)</td>
</tr>
<tr>
<td><code>bytes</code></td>
<td>List</td>
<td>Payload as byte list</td>
</tr>
<tr>
<td><code>closeCode</code></td>
<td>Num</td>
<td>Close status code (only for close frames)</td>
</tr>
<tr>
<td><code>closeReason</code></td>
<td>String</td>
<td>Close reason text (only for close frames)</td>
</tr>
</table>
<h2 id="opcodes">Frame Opcodes</h2>
<table>
<tr>
<th>Opcode</th>
<th>Type</th>
<th>Description</th>
</tr>
<tr>
<td>0</td>
<td>Continuation</td>
<td>Continuation of fragmented message</td>
</tr>
<tr>
<td>1</td>
<td>Text</td>
<td>UTF-8 text data</td>
</tr>
<tr>
<td>2</td>
<td>Binary</td>
<td>Binary data</td>
</tr>
<tr>
<td>8</td>
<td>Close</td>
<td>Connection close</td>
</tr>
<tr>
<td>9</td>
<td>Ping</td>
<td>Ping (keepalive)</td>
</tr>
<tr>
<td>10</td>
<td>Pong</td>
<td>Pong response</td>
</tr>
</table>
<h3>Common Close Codes</h3>
<table>
<tr>
<th>Code</th>
<th>Meaning</th>
</tr>
<tr>
<td>1000</td>
<td>Normal closure</td>
</tr>
<tr>
<td>1001</td>
<td>Going away (server shutdown)</td>
</tr>
<tr>
<td>1002</td>
<td>Protocol error</td>
</tr>
<tr>
<td>1003</td>
<td>Unsupported data type</td>
</tr>
<tr>
<td>1005</td>
<td>No status received</td>
</tr>
<tr>
<td>1006</td>
<td>Abnormal closure</td>
</tr>
<tr>
<td>1011</td>
<td>Server error</td>
</tr>
</table>
<h2 id="examples">Examples</h2>
<h3>Echo Client</h3>
<pre><code>import "websocket" for WebSocket
var ws = WebSocket.connect("ws://echo.websocket.org")
ws.send("Hello, WebSocket!")
var msg = ws.receive()
if (msg != null && msg.isText) {
System.print("Echo: %(msg.text)")
}
ws.close()</code></pre>
<h3>Chat Client</h3>
<pre><code>import "websocket" for WebSocket
import "json" for Json
var ws = WebSocket.connect("wss://chat.example.com/socket")
ws.send(Json.stringify({
"type": "join",
"room": "general",
"username": "alice"
}))
while (ws.isOpen) {
var msg = ws.receive()
if (msg == null) break
if (msg.isClose) {
System.print("Server closed: %(msg.closeCode) %(msg.closeReason)")
break
}
if (msg.isText) {
var data = Json.parse(msg.text)
if (data["type"] == "message") {
System.print("%(data["from"]): %(data["text"])")
}
}
}
ws.close()</code></pre>
<h3>WebSocket Server</h3>
<pre><code>import "websocket" for WebSocketServer
var server = WebSocketServer.bind("0.0.0.0", 8080)
System.print("WebSocket server listening on port 8080")
while (true) {
var client = server.accept()
if (client == null) continue
System.print("Client connected")
while (client.isOpen) {
var msg = client.receive()
if (msg == null) break
if (msg.isClose) {
System.print("Client disconnected")
break
}
if (msg.isText) {
System.print("Received: %(msg.text)")
client.send("Echo: %(msg.text)")
}
}
}</code></pre>
<h3>Secure WebSocket (WSS)</h3>
<pre><code>import "websocket" for WebSocket
var ws = WebSocket.connect("wss://secure.example.com/socket")
ws.send("Secure message")
var response = ws.receive()
System.print(response.text)
ws.close()</code></pre>
<div class="admonition note">
<div class="admonition-title">Note</div>
<p>Ping frames are automatically responded to with pong frames. You typically do not need to handle ping/pong manually unless implementing custom keepalive logic.</p>
</div>
</article>
<footer class="page-footer">
<a href="http.html" class="prev">http</a>
<a href="tls.html" class="next">tls</a>
</footer>
</main>
</div>
<script src="../js/main.js"></script>
</body>
</html>