add blog posts in HTML format

This commit is contained in:
2026-04-09 03:23:27 -06:00
parent 55c35942c1
commit 339774e097
2 changed files with 993 additions and 0 deletions

551
blog-instrucciones.html Normal file
View File

@@ -0,0 +1,551 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Implementing Spider VM Instructions — Diego López</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,600;1,400&family=Fraunces:ital,opsz,wght@0,9..144,300;0,9..144,700;1,9..144,300&display=swap" rel="stylesheet">
<style>
:root {
--bg: #faf8f4;
--surface: #f2ede4;
--border: #ddd8ce;
--accent: #c44b2b;
--accent2: #2563a8;
--text: #1a1714;
--muted: #8a8278;
--code-bg: #1c1917;
--code-text: #d4cfca;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
color: var(--text);
font-family: 'Fraunces', serif;
line-height: 1.75;
}
/* ── Header ── */
header {
background: var(--text);
color: var(--bg);
padding: 4rem 2rem 3rem;
position: relative;
overflow: hidden;
}
header::after {
content: '0x068→0x079';
position: absolute;
bottom: -1.5rem;
right: 2rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 6rem;
color: rgba(255,255,255,0.04);
line-height: 1;
pointer-events: none;
letter-spacing: -0.05em;
}
.header-inner {
max-width: 800px;
margin: 0 auto;
}
.tag {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: var(--accent);
text-transform: uppercase;
letter-spacing: 0.15em;
margin-bottom: 1.5rem;
display: block;
}
h1 {
font-size: clamp(2.2rem, 5vw, 3.5rem);
font-weight: 700;
line-height: 1.1;
letter-spacing: -0.02em;
margin-bottom: 1.2rem;
}
.subtitle {
font-size: 1.1rem;
font-weight: 300;
font-style: italic;
color: rgba(250,248,244,0.65);
max-width: 520px;
}
.meta {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: rgba(250,248,244,0.4);
margin-top: 2rem;
letter-spacing: 0.05em;
}
/* ── Main ── */
main {
max-width: 800px;
margin: 0 auto;
padding: 4rem 2rem 6rem;
}
section {
margin-bottom: 4rem;
}
h2 {
font-size: 1.6rem;
font-weight: 700;
letter-spacing: -0.01em;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--border);
}
h2 span {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
color: var(--accent);
font-style: normal;
vertical-align: middle;
margin-left: 0.8rem;
}
p {
color: #3d3830;
margin-bottom: 1rem;
}
/* ── Instruction table ── */
.instr-group {
margin: 1.5rem 0;
}
.group-label {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.68rem;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 0.5rem;
}
.instr-list {
border: 1px solid var(--border);
overflow: hidden;
}
.instr-row {
display: grid;
grid-template-columns: 6rem 5rem 1fr;
border-bottom: 1px solid var(--border);
}
.instr-row:last-child { border-bottom: none; }
.instr-row:hover { background: var(--surface); }
.instr-op {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.75rem;
color: var(--accent);
padding: 0.65rem 1rem;
background: var(--surface);
border-right: 1px solid var(--border);
display: flex;
align-items: center;
}
.instr-name {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8rem;
font-weight: 600;
padding: 0.65rem 1rem;
border-right: 1px solid var(--border);
display: flex;
align-items: center;
color: var(--text);
}
.instr-desc {
font-size: 0.85rem;
padding: 0.65rem 1rem;
color: #5a5248;
display: flex;
align-items: center;
}
/* ── Code block ── */
pre {
background: var(--code-bg);
color: var(--code-text);
padding: 1.4rem 1.6rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
line-height: 1.85;
overflow-x: auto;
margin: 1.2rem 0;
}
pre .kw { color: #e06c75; }
pre .fn { color: #61afef; }
pre .cmt { color: #4d4540; font-style: italic; }
pre .val { color: #98c379; }
pre .type { color: #e5c07b; }
/* ── Pattern box ── */
.pattern {
background: var(--surface);
border: 1px solid var(--border);
border-left: 3px solid var(--accent2);
padding: 1.2rem 1.5rem;
margin: 1.5rem 0;
}
.pattern-label {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.65rem;
color: var(--accent2);
text-transform: uppercase;
letter-spacing: 0.12em;
margin-bottom: 0.5rem;
}
.pattern pre {
background: transparent;
padding: 0;
margin: 0;
color: #3d3830;
font-size: 0.82rem;
}
.pattern pre .fn { color: var(--accent2); }
.pattern pre .cmt { color: var(--muted); }
/* ── Test results ── */
.test-results {
background: var(--code-bg);
padding: 1.5rem 2rem;
margin: 2rem 0;
position: relative;
}
.test-results::before {
content: 'TEST OUTPUT — 15/15 PASS';
font-family: 'IBM Plex Mono', monospace;
font-size: 0.65rem;
color: #4ade80;
letter-spacing: 0.12em;
display: block;
margin-bottom: 1rem;
}
.test-line {
font-family: 'IBM Plex Mono', monospace;
font-size: 0.78rem;
line-height: 1.9;
color: #6b7280;
}
.test-line .pass { color: #4ade80; }
.test-line .section { color: #e5c07b; margin-top: 0.5rem; display: block; }
/* ── Note ── */
.note {
border: 1px solid var(--border);
padding: 1rem 1.4rem;
margin: 1.5rem 0;
font-size: 0.88rem;
color: #5a5248;
font-style: italic;
}
.note strong { color: var(--text); font-style: normal; }
/* ── Footer ── */
footer {
background: var(--text);
color: rgba(250,248,244,0.4);
text-align: center;
padding: 2rem;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.7rem;
letter-spacing: 0.05em;
}
/* ── Animations ── */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
section {
animation: fadeIn 0.6s ease both;
}
section:nth-child(1) { animation-delay: 0.05s; }
section:nth-child(2) { animation-delay: 0.12s; }
section:nth-child(3) { animation-delay: 0.19s; }
section:nth-child(4) { animation-delay: 0.26s; }
section:nth-child(5) { animation-delay: 0.33s; }
</style>
</head>
<body>
<header>
<div class="header-inner">
<span class="tag">Spider VM · Instruction Set Implementation · 2026</span>
<h1>Implementing<br>Spider VM Instructions</h1>
<p class="subtitle">Cast conversions, trigonometric and exponential functions for the Spider Virtual Machine — opcodes 0x068 through 0x079.</p>
<div class="meta">Diego Alberto López &nbsp;·&nbsp; spider-runtime &nbsp;·&nbsp; April 2026</div>
</div>
</header>
<main>
<!-- Context -->
<section>
<h2>Context <span>background</span></h2>
<p>
The Spider VM instruction set is organized in a 9-bit opcode space (512 slots),
divided among team members. My assigned range covers 15 instructions:
two type cast conversions and thirteen math functions.
</p>
<p>
Instructions are defined in <code style="font-family:'IBM Plex Mono',monospace;font-size:0.9em;color:var(--accent)">Instr_060-07F.cpp</code>,
which already contained the previous range (0x0600x067) implemented by another team member.
My work begins at 0x068.
</p>
</section>
<!-- Instruction list -->
<section>
<h2>Assigned Instructions <span>0x068 → 0x079</span></h2>
<div class="instr-group">
<div class="group-label">Cast Conversions</div>
<div class="instr-list">
<div class="instr-row">
<div class="instr-op">0x068</div>
<div class="instr-name">D2I</div>
<div class="instr-desc">Double (f64) → Integer (i32), truncates toward zero</div>
</div>
<div class="instr-row">
<div class="instr-op">0x069</div>
<div class="instr-name">D2L</div>
<div class="instr-desc">Double (f64) → Long (i64), truncates toward zero</div>
</div>
</div>
</div>
<div class="instr-group">
<div class="group-label">Trigonometric</div>
<div class="instr-list">
<div class="instr-row">
<div class="instr-op">0x06C</div>
<div class="instr-name">SIN</div>
<div class="instr-desc">Sine — sin(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x06D</div>
<div class="instr-name">COS</div>
<div class="instr-desc">Cosine — cos(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x06E</div>
<div class="instr-name">TAN</div>
<div class="instr-desc">Tangent — tan(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x06F</div>
<div class="instr-name">ASIN</div>
<div class="instr-desc">Arc sine — asin(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x070</div>
<div class="instr-name">ACOS</div>
<div class="instr-desc">Arc cosine — acos(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x071</div>
<div class="instr-name">ATAN</div>
<div class="instr-desc">Arc tangent — atan(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x072</div>
<div class="instr-name">ATAN2</div>
<div class="instr-desc">Arc tangent 2-argument — atan2(Dst, Src) → Dst</div>
</div>
</div>
</div>
<div class="instr-group">
<div class="group-label">Exponential</div>
<div class="instr-list">
<div class="instr-row">
<div class="instr-op">0x074</div>
<div class="instr-name">EXP</div>
<div class="instr-desc">Natural exponential — eˣ → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x075</div>
<div class="instr-name">LOG</div>
<div class="instr-desc">Natural logarithm — ln(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x076</div>
<div class="instr-name">LOGAB</div>
<div class="instr-desc">Logarithm base A of B — log_Src(Dst) → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x077</div>
<div class="instr-name">POW</div>
<div class="instr-desc">Power — Dst^Src → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x078</div>
<div class="instr-name">SQRT</div>
<div class="instr-desc">Square root — √Dst → Dst</div>
</div>
<div class="instr-row">
<div class="instr-op">0x079</div>
<div class="instr-name">ROOT</div>
<div class="instr-desc">General root — Dst^(1/Src) → Dst</div>
</div>
</div>
</div>
</section>
<!-- Implementation pattern -->
<section>
<h2>Implementation Pattern <span>how it works</span></h2>
<p>
Every instruction in the Spider VM follows the same three-step pattern:
fetch the operand(s), perform the operation, and call the post-execution hook.
</p>
<div class="pattern">
<div class="pattern-label">Single-operand pattern</div>
<pre><span class="fn">fetchOperDst</span>(); <span class="cmt">// points _dst to the destination register</span>
_dst->_f64 = std::<span class="fn">sin</span>(_dst->_f64);
(this->*_post)(); <span class="cmt">// post-execution hook (write-back if needed)</span></pre>
</div>
<div class="pattern">
<div class="pattern-label">Two-operand pattern (ATAN2, LOGAB, POW, ROOT)</div>
<pre><span class="fn">fetchOperDst</span>(); <span class="cmt">// _dst ← destination</span>
<span class="fn">fetchOperSrc</span>(); <span class="cmt">// _src ← source</span>
_dst->_f64 = std::<span class="fn">atan2</span>(_dst->_f64, _src->_f64);
(this->*_post)();</pre>
</div>
<p>
The <code style="font-family:'IBM Plex Mono',monospace;font-size:0.9em;color:var(--accent)">register_t</code> union
allows each register to be read as any type (<code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">_f64</code>,
<code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">_u32</code>,
<code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">_u64</code>, etc.)
without casting overhead. The type modifier in the instruction header determines
which field is active.
</p>
<p>Notable special cases:</p>
<p>
<strong>LOGAB</strong> uses the change-of-base formula:
log<sub>a</sub>(b) = ln(b) / ln(a), where Dst is b and Src is a.
</p>
<p>
<strong>ROOT</strong> uses the identity: ⁿ√x = x^(1/n),
implemented as <code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">std::pow(dst, 1.0 / src)</code>.
</p>
<p>The full implementation in C++20:</p>
<pre><span class="kw">void</span> <span class="type">CPU</span>::<span class="fn">D2I</span>() {
<span class="fn">fetchOperDst</span>();
_dst->_u32 = <span class="kw">static_cast</span>&lt;<span class="type">u32</span>&gt;(_dst->_f64);
(this->*_post)();
}
<span class="kw">void</span> <span class="type">CPU</span>::<span class="fn">SIN</span>() {
<span class="fn">fetchOperDst</span>();
_dst->_f64 = std::<span class="fn">sin</span>(_dst->_f64);
(this->*_post)();
}
<span class="kw">void</span> <span class="type">CPU</span>::<span class="fn">LOGAB</span>() {
<span class="fn">fetchOperDst</span>();
<span class="fn">fetchOperSrc</span>();
_dst->_f64 = std::<span class="fn">log</span>(_dst->_f64) / std::<span class="fn">log</span>(_src->_f64);
(this->*_post)();
}
<span class="kw">void</span> <span class="type">CPU</span>::<span class="fn">ROOT</span>() {
<span class="fn">fetchOperDst</span>();
<span class="fn">fetchOperSrc</span>();
_dst->_f64 = std::<span class="fn">pow</span>(_dst->_f64, <span class="val">1.0</span> / _src->_f64);
(this->*_post)();
}</pre>
</section>
<!-- Testing -->
<section>
<h2>Verification <span>test results</span></h2>
<p>
A test program was written to call each instruction directly on the CPU
and verify the output against mathematically known values.
Since <code style="font-family:'IBM Plex Mono',monospace;font-size:0.9em;color:var(--accent)">fetchInstr()</code>
and <code style="font-family:'IBM Plex Mono',monospace;font-size:0.9em;color:var(--accent)">execute()</code>
are not yet implemented in the Runtime, operands are set manually before each call.
</p>
<div class="test-results">
<div class="test-line">
<span class="section">-- Cast Instructions --</span>
<span class="pass">[PASS]</span> D2I (3.9 -> 3) = 3 (expected 3)<br>
<span class="pass">[PASS]</span> D2L (1e12) = 1e+12 (expected 1e+12)
<span class="section">-- Trigonometric Instructions --</span>
<span class="pass">[PASS]</span> SIN(pi/2) = 1 (expected 1)<br>
<span class="pass">[PASS]</span> COS(0) = 1 (expected 1)<br>
<span class="pass">[PASS]</span> TAN(pi/4) = 1 (expected 1)<br>
<span class="pass">[PASS]</span> ASIN(1.0) = 1.5708 (expected 1.5708)<br>
<span class="pass">[PASS]</span> ACOS(1.0) = 0 (expected 0)<br>
<span class="pass">[PASS]</span> ATAN(1.0) = 0.785398 (expected 0.785398)<br>
<span class="pass">[PASS]</span> ATAN2(1,1) = 0.785398 (expected 0.785398)
<span class="section">-- Exponential Instructions --</span>
<span class="pass">[PASS]</span> EXP(1) = 2.71828 (expected 2.71828)<br>
<span class="pass">[PASS]</span> LOG(e) = 1 (expected 1)<br>
<span class="pass">[PASS]</span> LOGAB(100,10) = 2 (expected 2)<br>
<span class="pass">[PASS]</span> POW(2,10) = 1024 (expected 1024)<br>
<span class="pass">[PASS]</span> SQRT(9) = 3 (expected 3)<br>
<span class="pass">[PASS]</span> ROOT(27,3) = 3 (expected 3)
</div>
</div>
<div class="note">
<strong>Note on testing approach:</strong> The test program uses stub implementations
of <code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">fetchOperDst()</code>,
<code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">fetchOperSrc()</code>,
and <code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">imp()</code>
as no-ops, and sets <code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">_dst</code> and
<code style="font-family:'IBM Plex Mono',monospace;font-size:0.85em">_src</code> manually.
This isolates the instruction logic completely from the unimplemented CPU dispatch system.
</div>
</section>
</main>
<footer>
Spider Lang Internship 2026 &nbsp;·&nbsp; Diego Alberto López
</footer>
</body>
</html>