vextoly/website
Initial
Commit f5b1267 · niklas · 2026-11-03T00:41:42+01:00
Comments
No comments yet.
Diff
diff --git a/cryn/index.php b/cryn/index.php
new file mode 100644
index 0000000..339d51f
--- /dev/null
+++ b/cryn/index.php
@@ -0,0 +1,79 @@
+<?php
+declare(strict_types=1);
+$year = date('Y');
+?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Cryn · vextoly</title>
+<meta name="description" content="Cryn: a compiled, statically typed systems language with a tiny core.">
+<meta name="color-scheme" content="dark">
+<meta name="theme-color" content="#000000">
+<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%3E%3Ccircle%20cx='32'%20cy='32'%20r='29'%20fill='%23000'%20stroke='%23fff'%20stroke-width='6'/%3E%3Ccircle%20cx='32'%20cy='19'%20r='5'%20fill='%23fff'/%3E%3Crect%20x='27'%20y='29'%20width='10'%20height='26'%20rx='5'%20fill='%23fff'/%3E%3C/svg%3E">
+<link rel="stylesheet" href="/styles.css">
+</head>
+<body>
+<div class="pride" aria-hidden="true"></div>
+<header class="site-header">
+ <div class="wrap">
+ <a class="wordmark" href="/">vextoly</a>
+ </div>
+</header>
+<main class="wrap doc">
+ <h1>Cryn</h1>
+ <p class="intro">
+ A compiled, statically typed systems language with a tiny core.
+ The machine has cells, connections, focus, one working value, and a value stack.
+ 37 English commands. No symbolic operators, no semicolons, no braces.
+ Whitespace and indentation have no meaning.
+ Static types with defined behavior: fixed-width integers, IEEE floats, overflow wraps, division by zero aborts, float-to-int saturates, indexing is bounds-checked.
+ Files are first-class handles with read, write, both, and append modes.
+ </p>
+
+ <h2>Example</h2>
+ <pre><code>define main
+ set 10
+ push
+ set 20
+ add
+ output
+ return
+end</code></pre>
+
+ <h2>The machine</h2>
+ <ul>
+ <li><strong>Cells and connections</strong> are a graph of typed memory cells. A cell holds one value and connects to other cells by name or by an index. Arrays are indexed connections. Linked lists are stored as addresses in cells. There is no separate struct keyword. The world is the collection of all cells.</li>
+ <li><strong>Focus</strong> identifies the currently selected cell. move navigates by name or index and anchors the focus. back returns to the previous focus. home returns to the frame root. The focus is a stack of cell references, with the frame root at the bottom.</li>
+ <li><strong>Working value</strong> is one typed value that commands read, write, and compute on. It is the only immediate value in the machine. It is also the return value of a transformation.</li>
+ <li><strong>Value stack</strong> saves values while the working value does something else. It is also used for passing arguments to calls. Push, pop, swap. The stack must be empty at return. The checker enforces this at every program point.</li>
+ <li><strong>Control flow</strong> uses compare to set a condition, then jump label or jump label when less or greater or equal. mark defines labels. Loops are backward jumps. There is no if, while, or for. The checker tracks the working value type, focus, and stack shape at every label. All paths reaching a label must agree.</li>
+ <li><strong>Threads</strong> use spawn to start a zero-parameter transformation in a new thread, and wait to join all spawned threads and synchronize memory. Communication is through shared world cells and heap blocks. A race on an aligned cell of eight bytes or less yields an unspecified value of the cell's type and never tears. exchange is an atomic swap of the working value with the focused cell, the only ordering primitive besides wait, and enough to build locks.</li>
+ </ul>
+
+ <h2>Compiler</h2>
+ <p>
+ The bootstrap compiler is portable ISO C11 with no dependencies beyond a C compiler and pthreads.
+ It lowers Cryn source through a typed IR to readable C, then invokes the host C compiler to produce a native executable.
+ Both GCC and Clang are supported as host compilers.
+ No runtime is needed after compilation. The generated program is a normal executable with no graph overhead, no garbage collector, and no VM.
+ </p>
+
+ <h2>Get it</h2>
+ <p>
+ <a href="https://git.disroot.org/Vextoly/Cryn">Repository</a> ·
+ <a href="https://git.disroot.org/Vextoly/Cryn/wiki/Learning-Cryn">Tutorial</a> ·
+ <a href="https://git.disroot.org/Vextoly/Cryn/wiki/Language-Reference">Language reference</a> ·
+ <a href="https://git.disroot.org/Vextoly/Cryn/wiki/Architecture">Architecture</a>
+ </p>
+
+</main>
+<footer class="colophon">
+ <div class="wrap footer-inner">
+ <p>© <?php echo $year; ?> vextoly</p>
+ <p><a href="/privacy.php">privacy</a></p>
+ </div>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..792d0c2
--- /dev/null
+++ b/index.php
@@ -0,0 +1,91 @@
+<?php
+declare(strict_types=1);
+date_default_timezone_set('Europe/Berlin');
+$localTime = date('H:i');
+$utcOffset = date('P');
+$year = date('Y');
+?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Home · vextoly</title>
+<meta name="description" content="Personal homepage of Niklas, also known as vextoly.">
+<meta property="og:type" content="profile">
+<meta property="og:site_name" content="vextoly">
+<meta property="og:title" content="vextoly · Niklas">
+<meta property="og:description" content="Personal homepage of Niklas, also known as vextoly.">
+<meta property="og:url" content="https://vextoly.lgbt.sh/">
+<meta name="twitter:card" content="summary">
+<script type="application/ld+json">
+{
+ "@context": "https://schema.org",
+ "@type": "Person",
+ "name": "Niklas",
+ "alternateName": "vextoly",
+ "email": "mailto:[email protected]",
+ "url": "https://vextoly.lgbt.sh/",
+ "sameAs": [
+ "https://git.disroot.org/Vextoly",
+ "https://www.youtube.com/@Vextoly",
+ "https://twitch.tv/vextoly",
+ "https://tiktok.com/@vextoly",
+ ]
+}
+</script>
+<meta name="color-scheme" content="dark">
+<meta name="theme-color" content="#000000">
+<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%3E%3Ccircle%20cx='32'%20cy='32'%20r='29'%20fill='%23000'%20stroke='%23fff'%20stroke-width='6'/%3E%3Ccircle%20cx='32'%20cy='19'%20r='5'%20fill='%23fff'/%3E%3Crect%20x='27'%20y='29'%20width='10'%20height='26'%20rx='5'%20fill='%23fff'/%3E%3C/svg%3E">
+<link rel="stylesheet" href="/styles.css">
+</head>
+<body>
+<div class="pride" aria-hidden="true"></div>
+<header class="site-header">
+ <div class="wrap">
+ <a class="wordmark" href="/">vextoly</a>
+ </div>
+</header>
+<main class="wrap">
+ <h1>Niklas</h1>
+ <p class="meta">/ˈnɪk.las/ · it/its</p>
+ <p class="lede">Be kind pls, the world is loud enough already.</p>
+<!-- <p class="about">suff</p> -->
+ <p class="time">It's <button type="button" class="clock" aria-pressed="false"><?php echo $localTime; ?></button> where I am (UTC<?php echo $utcOffset; ?>).</p>
+ <h2>Elsewhere</h2>
+ <nav class="chips" aria-label="Elsewhere">
+ <a href="https://git.disroot.org/Vextoly"><svg viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M13.09 23.549a1.54 1.54 0 0 1-2.18 0L.451 13.089a1.54 1.54 0 0 1 0-2.179l7.191-7.19 2.733 2.733a1.85 1.85 0 0 0 .964 2.326v6.66a1.849 1.849 0 1 0 1.54 0V8.957l2.508 2.508a1.85 1.85 0 1 0 1.09-1.09l-2.634-2.634a1.85 1.85 0 0 0-2.378-2.377L8.73 2.63 10.91.451a1.54 1.54 0 0 1 2.179 0l10.459 10.46a1.54 1.54 0 0 1 0 2.179z"/></svg>Projects</a>
+ <a href="https://vextoly.lgbt.sh/cryn/"><svg viewBox="0 0 16 16" aria-hidden="true" fill="currentColor"><path d="M10.478 1.647a.5.5 0 1 0-.956-.294l-4 13a.5.5 0 0 0 .956.294zM4.854 4.146a.5.5 0 0 1 0 .708L1.707 8l3.147 3.146a.5.5 0 0 1-.708.708l-3.5-3.5a.5.5 0 0 1 0-.708l3.5-3.5a.5.5 0 0 1 .708 0m6.292 0a.5.5 0 0 0 0 .708L14.293 8l-3.147 3.146a.5.5 0 0 0 .708.708l3.5-3.5a.5.5 0 0 0 0-.708l-3.5-3.5a.5.5 0 0 0-.708 0"/></svg>The Cryn Language</a>
+ <a href="mailto:[email protected]"><svg viewBox="0 0 16 16" aria-hidden="true" fill="currentColor"><path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/></svg>[email protected]</a>
+ <a href="https://www.youtube.com/@Vextoly"><svg viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>YouTube</a>
+ <a href="https://twitch.tv/vextoly"><svg viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>Twitch</a>
+ <a href="https://tiktok.com/@vextoly"><svg viewBox="0 0 24 24" aria-hidden="true" fill="currentColor"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/></svg>TikTok</a>
+ </nav>
+</main>
+<footer class="colophon">
+ <div class="wrap footer-inner">
+ <p>© <?php echo $year; ?> vextoly</p>
+ <p><a href="/privacy.php">privacy</a></p>
+ </div>
+</footer>
+<script>
+(function () {
+ var clock = document.querySelector('.clock');
+ if (!clock || !window.Intl) return;
+ var use12 = false;
+ var fmt24 = new Intl.DateTimeFormat('en-GB', { timeZone: 'Europe/Berlin', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' });
+ var fmt12 = new Intl.DateTimeFormat('en-US', { timeZone: 'Europe/Berlin', hour: '2-digit', minute: '2-digit', hour12: true });
+ function render() {
+ clock.textContent = (use12 ? fmt12 : fmt24).format(new Date());
+ }
+ clock.addEventListener('click', function () {
+ use12 = !use12;
+ clock.setAttribute('aria-pressed', String(use12));
+ render();
+ });
+ render();
+ setInterval(render, 1000);
+})();
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/privacy.php b/privacy.php
new file mode 100644
index 0000000..e3fb7c4
--- /dev/null
+++ b/privacy.php
@@ -0,0 +1,37 @@
+<?php
+$year = date('Y');
+?>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Privacy · vextoly</title>
+<meta name="description" content="Privacy policy of vextoly.lgbt.sh: nothing is collected or sold.">
+<meta name="color-scheme" content="dark">
+<meta name="theme-color" content="#000000">
+<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%3E%3Ccircle%20cx='32'%20cy='32'%20r='29'%20fill='%23000'%20stroke='%23fff'%20stroke-width='6'/%3E%3Ccircle%20cx='32'%20cy='19'%20r='5'%20fill='%23fff'/%3E%3Crect%20x='27'%20y='29'%20width='10'%20height='26'%20rx='5'%20fill='%23fff'/%3E%3C/svg%3E">
+<link rel="stylesheet" href="/styles.css">
+</head>
+<body>
+<div class="pride" aria-hidden="true"></div>
+<header class="site-header">
+ <div class="wrap">
+ <a class="wordmark" href="/">vextoly</a>
+ </div>
+</header>
+<main class="wrap">
+ <h1>Privacy</h1>
+ <div class="prose">
+ <p>Nothing is sold or shared, because there is nothing to sell or share.</p>
+ <p>Like every web server, the machine hosting this site keeps short-lived access logs, which include your IP address, the request, and a timestamp. Those logs exist to keep the site online and to block abuse.</p>
+ <p>Questions? Write to <a href="mailto:[email protected]">[email protected]</a>.</p>
+ </div>
+</main>
+<footer class="colophon">
+ <div class="wrap">
+ <p>© <?php echo $year; ?> vextoly</p>
+ </div>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/styles.css b/styles.css
new file mode 100644
index 0000000..7dea28e
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,221 @@
+:root {
+ --paper: #000000;
+ --ink: #ffffff;
+ --body: #b3b3b3;
+ --muted: #999999;
+ --chip: #333333;
+ --press: #e2e2e2;
+ --pre-bg: #161616;
+ --pre-border: #262626;
+}
+
+*,
+*::before,
+*::after { box-sizing: border-box; }
+* { margin: 0; }
+html { -webkit-text-size-adjust: 100%; }
+body {
+ font-family: system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ color: var(--ink);
+ background: var(--paper);
+ min-height: 100vh;
+ min-height: 100svh;
+ display: flex;
+ flex-direction: column;
+}
+a { cursor: pointer; }
+a { color: var(--ink); text-decoration: none; }
+a:hover { text-decoration: underline; }
+strong { color: var(--ink); font-weight: 700; }
+li::marker { color: var(--muted); }
+
+.pride {
+ height: 4px;
+ flex-shrink: 0;
+ background: linear-gradient(90deg,
+ #e40303 0 16.66%,
+ #ff8c00 16.66% 33.33%,
+ #ffed00 33.33% 50%,
+ #008026 50% 66.66%,
+ #24408e 66.66% 83.33%,
+ #732982 83.33% 100%);
+}
+.wrap {
+ width: 100%;
+ max-width: 42rem;
+ margin-inline: auto;
+ padding-inline: 24px;
+}
+:is(a, button):focus-visible {
+ outline: 2px solid var(--ink);
+ outline-offset: 2px;
+}
+
+.site-header { padding-block: 24px; }
+.wordmark {
+ font-size: 1.125rem;
+ font-weight: 700;
+ color: var(--ink);
+ text-decoration: none;
+}
+.wordmark:hover { text-decoration: underline; }
+
+main {
+ flex: 1;
+ padding-block: clamp(3rem, 9vh, 5.5rem) clamp(3rem, 8vh, 5rem);
+}
+h1 {
+ font-size: clamp(2.75rem, 9vw, 3.25rem);
+ line-height: 1.23;
+ font-weight: 700;
+}
+h2 {
+ margin-top: clamp(3rem, 8vh, 4.5rem);
+ font-size: 1.25rem;
+ line-height: 1.4;
+ font-weight: 700;
+}
+
+.meta {
+ margin-top: 12px;
+ font-size: 1rem;
+ color: var(--body);
+}
+.lede {
+ margin-top: 32px;
+ font-size: 1.25rem;
+ line-height: 1.4;
+ max-width: 34ch;
+}
+.about {
+ margin-top: 12px;
+ font-size: 1rem;
+ color: var(--body);
+ max-width: 44ch;
+}
+.time {
+ margin-top: 12px;
+ font-size: 0.875rem;
+ color: var(--muted);
+}
+.clock {
+ font: inherit;
+ color: inherit;
+ background: none;
+ border: 0;
+ padding: 0 0.1em;
+ cursor: pointer;
+}
+
+.chips {
+ margin-top: 16px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+.chips a {
+ display: inline-flex;
+ align-items: center;
+ padding: 14px 16px;
+ border-radius: 999px;
+ background: var(--chip);
+ color: var(--ink);
+ font-size: 1rem;
+ font-weight: 500;
+ text-decoration: none;
+ gap: 10px;
+}
+.chips svg {
+ width: 18px;
+ height: 18px;
+ flex-shrink: 0;
+}
+.chips a:hover {
+ background: var(--ink);
+ color: var(--paper);
+ text-decoration: none;
+}
+.chips a:active {
+ background: var(--press);
+ color: var(--paper);
+}
+@media (prefers-reduced-motion: no-preference) {
+ .chips a {
+ transition: background-color 150ms ease, color 150ms ease;
+ }
+}
+
+.prose {
+ margin-top: 24px;
+ max-width: 52ch;
+ color: var(--body);
+ font-size: 1rem;
+}
+.prose p + p { margin-top: 1em; }
+.prose a { color: var(--ink); }
+
+.intro {
+ margin-top: 24px;
+ color: var(--body);
+ max-width: 60ch;
+}
+.doc p, .doc ul {
+ margin-top: 0.75rem;
+ color: var(--body);
+}
+.doc ul { padding-left: 1.5rem; }
+.doc li { margin-bottom: 0.6rem; }
+
+code, pre {
+ font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
+ font-size: 0.9em;
+}
+code {
+ background: #1f1f1f;
+ padding: 0.1em 0.3em;
+ border-radius: 3px;
+ color: var(--ink);
+}
+pre {
+ background: var(--pre-bg);
+ border: 1px solid var(--pre-border);
+ padding: 0.8rem;
+ border-radius: 8px;
+ overflow-x: auto;
+ line-height: 1.5;
+ margin-top: 0.75rem;
+ color: var(--ink);
+}
+pre code { background: none; padding: 0; color: inherit; }
+hr {
+ border: none;
+ border-top: 1px solid var(--pre-border);
+ margin: 2.5rem 0;
+}
+.small { font-size: 0.85rem; color: var(--muted); }
+
+.colophon {
+ padding-block: 1.5rem 2.5rem;
+ font-size: 0.875rem;
+ color: var(--muted);
+}
+.footer-inner {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: center;
+ gap: 12px 24px;
+}
+.colophon a {
+ color: var(--muted);
+ text-decoration: none;
+}
+.colophon a:hover {
+ color: var(--ink);
+ text-decoration: underline;
+}
+
+@media (max-width: 30rem) {
+ .lede { font-size: 1.125rem; }
+}