<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://josh.tools/feed.xml" rel="self" type="application/atom+xml" /><link href="http://josh.tools/" rel="alternate" type="text/html" /><updated>2026-01-28T01:16:25+00:00</updated><id>http://josh.tools/feed.xml</id><title type="html">machinamentum</title><author><name>Josh Huelsman</name></author><entry><title type="html">A New C Programming Environment</title><link href="http://josh.tools/A_New_C_Programming_Environment/" rel="alternate" type="text/html" title="A New C Programming Environment" /><published>2024-11-15T00:00:00+00:00</published><updated>2024-11-15T00:00:00+00:00</updated><id>http://josh.tools/A_New_C_Programming_Environment</id><content type="html" xml:base="http://josh.tools/A_New_C_Programming_Environment/"><![CDATA[<p>In April, I had left my role as a compiler, VM, and game engine, engineer at Roblox. I had decided to not <em>actively</em> seek other jobs; instead I’ve been focusing a few new projects of my own: a C compiler, a break-through CPU emulator, and an IDE.</p>

<h2 id="a-c-compiler-a-cpu-emulator-an-ide">A C compiler, a CPU emulator, an IDE…</h2>

<p>…are you getting it? They’re one project.</p>

<p>The two devices I have been most excited about in many years are iPad Pro and Vision Pro. However, the software support for writing systems software on these devices have historically been lack luster: many programming apps either only support traditional scripting languages (such as Lua, Python, or JavaScript), require an internet connection to phone home to a server that performs compilation and execution, or even opt to embed the entirety of Clang and LLVM in interpreter mode. The most competent attempt at meeting the needs and wants of engineers I have seen so far is Swift Playgrounds, with its ability to publish iPad apps directly from the app itself, and providing access to lower level frameworks. However, it still only supports compiling Swift.</p>

<p>So I have set out to build a suitable environment to write low-level systems programs directly on these platforms.</p>

<h2 id="ide">IDE</h2>

<p><img src="/assets/2024-11-15-IDE-App.png" alt="iPad C VM IDE" /></p>

<p>On the surface, the IDE app is fairly bare bones: there is a single “tab” for editing just one open file, a file tree, and an output window.</p>

<h3 id="errors">Errors</h3>

<p>Code is being compiled and checked for errors on a continual basis. The IDE integrates deeply with the compiler to provide an error list window, and clicking on an error sets the editor’s selection to the <em>token</em> where the error was found. The editor also underlines all tokens where errors are currently being encountered.</p>

<p><video playsinline="" autoplay="" loop="" style="border-radius: 5px;">
  <source src="/assets/2024-11-15-IDE-Errors.mp4" type="video/mp4" />
</video></p>

<h3 id="environment">Environment</h3>

<p>What makes the IDE special is the runtime environment. Vertical integration with the CPU emulator enables user code to call special API functions in the IDE to do things such as rendering 3D graphics.</p>

<p><video playsinline="" autoplay="" loop="" style="border-radius: 5px;">
  <source src="/assets/2024-11-15-IDE-Graphics-Demo.mp4" type="video/mp4" />
</video></p>

<p>Sample code: <a href="https://gist.github.com/machinamentum/0c0c12c973915e9bbf45e16fd22eaf08">https://gist.github.com/machinamentum/0c0c12c973915e9bbf45e16fd22eaf08</a></p>

<p>In the future, one can imagine even extending the editor via plugins writen in C via an API exposed in this way.</p>

<h2 id="cpu-emulator">CPU Emulator</h2>

<p>The intepreter engine emulates a RISC-style CPU with 16 integer registers, and 16 float registers.</p>

<p>Special built-in functions enable the emulated program to call standard C API’s, or call virtual machine functions that call into the app frontend. These mechanisms are not dlopen/dlsym wrappers, the runtime implements standard C API functionality, implementing checks and managing resources to prevent errors and leaks.
<em>printf</em>, for example, is entirely implemented within the interpreter engine, including parsing the format string, and formatting the arguments (which are retrieved from VM registers); the app frontend need only provide a single <em>putchar</em> callback for the engine to report output characters to.</p>

<p><em>VM functions</em> (those provided by the app frontend) are registed with the interpreter engine and called via a hash lookup of the name of the function. This is done in user code by calling a built-in function, <em>call_vm_function</em>, that takes the name of the VM function and performs a hash lookup to find the frontend callback to call.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[[</span><span class="n">builtinfn</span><span class="p">(</span><span class="s">"call_vm_function"</span><span class="p">)]]</span> <span class="kt">void</span> <span class="nf">call_vm_func</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">,</span> <span class="p">...);</span>

<span class="kt">int</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
	<span class="c1">// Call the open_window VM function with the given title "My App Title"</span>
	<span class="n">call_vm_func</span><span class="p">(</span><span class="s">"open_window"</span><span class="p">,</span> <span class="s">"My App Title"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The attribute <code class="language-plaintext highlighter-rouge">[[vmfn("name_of_function_here")]]</code> may be declared on a function declaration; this tells the code generator to call <em>call_vm_function</em> and to pass the given name as the first argument.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[[</span><span class="n">vmfn</span><span class="p">(</span><span class="s">"open_window"</span><span class="p">)]]</span> <span class="kt">void</span> <span class="nf">openWindow</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">title</span><span class="p">);</span>

<span class="kt">int</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
	<span class="c1">// Call the open_window VM function with the given title "My App Title"</span>
	<span class="n">openWindow</span><span class="p">(</span><span class="s">"My App Title"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Note that in either case, the identifier of the declaration does not need to match the registered name of the VM function being called.</p>

<p>Memory is entirely sandboxed: the program sees “virtual addresses” that the emulator translates and bounds checks on loads and stores, catching memory access errors in the process. Under the hood, the interpreter manages regions of system memory with an assigned virtual address range, and access permissions. When the user program accesses memory, the virtual address, and size of the access, are checked against the ranges of the mananged memory regions; thus it is impossible for the user program to read/write memory outside of the sandbox.</p>

<h2 id="c-compiler">C Compiler</h2>

<p>The C compiler is entirely new; this is not another consumer of clang. Compilation speed is critical in this project; compilation, and execution, should always feel instantanous (even a simple Hello, World compiled with clang takes too long to compile and execute). As a poor example, a file containing 1 million printf calls takes 0.7 seconds (O2, 1.5ish in debug) to both compile and execute in this system, clang takes 7.6 seconds just to compile the file (M2 MB Air, plugged in to power).</p>

<p>The C compiler currently supports many foundational C language constructs including trickier-to-implement elements such as <em>typedef</em> and macros (with arguments). However, there is still a very long way to go to support compiling large and complex C programs.</p>

<h3 id="on-clang-and-llvm">On Clang and LLVM</h3>

<p>Many projects opt to embed Clang to compile C code; sometimes utilizing Clang to parse C and translating the Clang AST into a format native to the project; sometimes embedding LLVM to compile and execute code. Why build a new C compiler? Weight, Velocity, and Fun.</p>

<p>For reference, the following LLVM build has been configued with <code class="language-plaintext highlighter-rouge">cmake -S llvm -B build -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="AArch64;ARM" -DLLVM_ENABLE_PROJECTS="clang"</code>. AFAICT, this is a best-case scenario for these tools.</p>

<p>Running <code class="language-plaintext highlighter-rouge">ls -l</code> in the LLVM 18 build directory in Release configuration, we can see that the clang binary is 110 megabytes, and the lli interpreter is 36 megabytes. It is unclear to me how much of the bloat can be stripped if one just wants the clang compiler and the LLVM interpreter in one binary, but I think it is safe to assume it would be on the order of 10s or 100s of megabytes. That’s far too large, by default.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>machinamentum@Joshuas-MacBook-Air build % ls -l bin/clang-18 bin/lli
-rwxr-xr-x  1 machinamentum  staff  110452360 May 20 01:06 bin/clang-18
-rwxr-xr-x  1 machinamentum  staff   36207360 May 20 00:56 bin/lli
machinamentum@Joshuas-MacBook-Air build % 
</code></pre></div></div>

<p>In comparison, the current size of the new compiler and interpreter is 206 <em>kilo</em>bytes. That’s several orders of magnitude smaller, and I don’t expect the code size to increase by more than one order of magnitude by the time the project is in a shippable state.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>machinamentum@Joshuas-MacBook-Air cvm % ls -l cvm
-rwxr-xr-x  1 machinamentum  staff  206096 Nov 15 00:28 cvm
machinamentum@Joshuas-MacBook-Air cvm % 
</code></pre></div></div>

<p>So, what is an acceptable size budget for our tools? How long should they take to download and install? How long should it take to build the tools from source? In an ideal world, the answer to these things would be small enough to download, build, and install <em>instantaneously</em>; however, a reasonable metric I now use is the time it takes to make a cup of coffee using a modern pod coffee system. Timing myself as I am writing this article, it takes just under 3 minutes to go to the kitchen, brew 3oz of coffee through an overpacked 3rd party pod (Nespresso Original Line style), and return to my desk. With an official pod that is packed properly, it would likely take closer to 2 minutes in total. The 2-3 minute range should be plenty of time for any toolchain to download+build+install on a modern computer. So how long does it take to build Clang + LLVM in the configuration mentioned above?</p>

<p>It takes 30 seconds just to configure the project:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cmake -S llvm -B build -DCMAKE_BUILD_TYPE=Release    12.30s user 13.84s system 88% cpu 29.592 total
</code></pre></div></div>

<p>And another 16 <em>minutes</em> to compile the tools on a modern, fast machine (a M2 MacBook Air with 8GB of RAM, not a ridiculously powerful machine, but not an unreasonably low end machine either). This isn’t actually <em>that</em> bad; I’ve experienced <em>many</em> times in my life having to wait in excess of 30 minutes for an LLVM build.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cmake --build build -j8  7885.73s user 449.68s system 718% cpu 19:20.42 total
</code></pre></div></div>

<p>To build the new project, it takes just <em>3 tenths</em> of a second.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>machinamentum@Joshuas-MacBook-Air cvm % time ./build.sh
./build.sh  0.22s user 0.08s system 104% cpu 0.287 total
machinamentum@Joshuas-MacBook-Air cvm % 
</code></pre></div></div>]]></content><author><name>Josh Huelsman</name></author><category term="vm" /><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[In April, I had left my role as a compiler, VM, and game engine, engineer at Roblox. I had decided to not actively seek other jobs; instead I’ve been focusing a few new projects of my own: a C compiler, a break-through CPU emulator, and an IDE.]]></summary></entry><entry><title type="html">Jiyu Update - March 2020</title><link href="http://josh.tools/Jiyu-Update-March-2020/" rel="alternate" type="text/html" title="Jiyu Update - March 2020" /><published>2020-03-02T00:00:00+00:00</published><updated>2020-03-02T00:00:00+00:00</updated><id>http://josh.tools/Jiyu-Update-March-2020</id><content type="html" xml:base="http://josh.tools/Jiyu-Update-March-2020/"><![CDATA[<p>February has been a bit of a slow month, but we’ve managed to add a few interesting features.</p>

<ul>
  <li>Added support for default parameters:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>

<span class="kd">func</span> <span class="nf">test</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">int32</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="n">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="s">"hello"</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"a: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">a</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"b: %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"c: %.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
<span class="p">}</span>

<span class="c1">// We don't currently error on the case that two or more functions</span>
<span class="c1">// cause an ambigous overload situation. Currently, the behavior</span>
<span class="c1">// is that the functions with fewer needed default params is prefered.</span>
<span class="c1">// This means you cannot call the above function via test(2, 3), or test(1), as</span>
<span class="c1">// the function below will be chosen instead since it requires less parameters</span>
<span class="c1">// to be filled in.</span>
<span class="kd">func</span> <span class="nf">test</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">int32</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="n">float</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Dang</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="nf">test</span><span class="p">();</span>
    <span class="nf">test</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="nf">test</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="s">"test"</span><span class="p">);</span>

    <span class="c1">// Will print "Dang"</span>
    <span class="nf">test</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Added support for binary literals, starting with the prefix <code class="language-plaintext highlighter-rouge">0b</code> or <code class="language-plaintext highlighter-rouge">0B</code>.</li>
  <li>Added support for switch-case control flow:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="cp">#import "LibC";</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>

    <span class="kd">enum</span> <span class="kt">Test</span> <span class="p">{</span>
        <span class="kt">A</span><span class="p">;</span>
        <span class="kt">B</span><span class="p">;</span>
        <span class="kt">C</span><span class="p">;</span>
        <span class="kt">D</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">var</span> <span class="nv">i</span> <span class="o">=</span> <span class="kt">Test</span><span class="o">.</span><span class="kt">D</span><span class="p">;</span>

    <span class="k">switch</span> <span class="n">i</span> <span class="p">{</span>
        <span class="k">case</span> <span class="o">.</span><span class="kt">A</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">".A</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="k">case</span> <span class="o">.</span><span class="kt">B</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">".B</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>

        <span class="k">case</span> <span class="o">.</span><span class="kt">C</span><span class="p">,</span> <span class="o">.</span><span class="kt">D</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">".C or .D</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">let</span> <span class="nv">Y</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">x</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>

    <span class="c1">// Currently only integer and enum (integer derived) types are support.</span>
    <span class="k">switch</span> <span class="n">x</span> <span class="p">{</span>

        <span class="c1">// Currently only expressions that resolve to integer literals are supported.</span>
        <span class="k">case</span> <span class="mi">1</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"1</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="c1">// Multiple case conditions can be declared per case-block.</span>
        <span class="k">case</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"2</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="k">case</span> <span class="kt">Y</span><span class="p">:</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"Y</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"Done</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Added support for overloading the array index operator <code class="language-plaintext highlighter-rouge">[]</code>, and the lvalue-assignment array index operator <code class="language-plaintext highlighter-rouge">[]=</code>:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">operator</span><span class="p">[]</span> <span class="o">&lt;</span><span class="kt">T</span><span class="p">,</span> <span class="kt">R</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">index</span><span class="p">:</span> <span class="kt">R</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="p">{</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">index</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nf">cast</span><span class="p">(</span><span class="n">int64</span><span class="p">)</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="n">count</span><span class="p">,</span> <span class="s">"Array index out of range!"</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">arr</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<span class="p">}</span>

<span class="k">operator</span><span class="p">[]</span><span class="o">=</span> <span class="o">&lt;</span><span class="kt">T</span><span class="p">,</span> <span class="kt">R</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">index</span><span class="p">:</span> <span class="kt">R</span><span class="p">,</span> <span class="nv">value</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">index</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="nf">cast</span><span class="p">(</span><span class="n">int64</span><span class="p">)</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="n">arr</span><span class="o">.</span><span class="n">count</span><span class="p">,</span> <span class="s">"Array index out of range!"</span><span class="p">);</span>
    <span class="n">arr</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span>

</code></pre></div></div>

<ul>
  <li>Added support for template structs:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>

<span class="kd">struct</span> <span class="kt">Poly</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">a</span><span class="p">:</span> <span class="kt">T</span><span class="p">;</span>

    <span class="kd">func</span> <span class="nf">do_thing</span><span class="p">(</span><span class="nv">this</span><span class="p">:</span> <span class="o">*</span><span class="kt">Poly</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="kt">T</span> <span class="o">==</span> <span class="n">int</span><span class="p">)</span>   <span class="nf">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">this</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="kt">T</span> <span class="o">==</span> <span class="n">float</span><span class="p">)</span> <span class="nf">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">this</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>

        <span class="c1">// Unfortunately, we cannot straight up do this because this is invalid when T == int or T == float</span>
        <span class="c1">// if (T == string)printf("%.*s\n", this.a.length, this.a.data);</span>

        <span class="c1">// But if we added another static-if construct like `when` in Odin then</span>
        <span class="cm">/*
            when (T == string) printf("%.*s\n", this.a.length, this.a.data);
        */</span>
        <span class="c1">// would work. I do not want to make #if this generous as #if operates directly on</span>
        <span class="c1">// the scope it is declared in, `when` on the other hand would work exactly like a</span>
        <span class="c1">// a regular `if` except the body is only evaluated when the condition is a literal</span>
        <span class="c1">// `true` (or folds to).</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">a</span><span class="p">:</span> <span class="kt">Poly</span><span class="o">&lt;</span><span class="n">int</span><span class="o">&gt;</span><span class="p">;</span>
    <span class="n">a</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="n">a</span><span class="o">.</span><span class="nf">do_thing</span><span class="p">();</span>

    <span class="k">var</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">Poly</span><span class="o">&lt;</span><span class="n">float</span><span class="o">&gt;</span><span class="p">;</span>
    <span class="n">b</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mf">1345.234</span><span class="p">;</span>
    <span class="n">b</span><span class="o">.</span><span class="nf">do_thing</span><span class="p">();</span>

    <span class="k">var</span> <span class="nv">c</span><span class="p">:</span> <span class="kt">Poly</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">;</span>
    <span class="n">c</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="s">"Hello, Pilot!"</span><span class="p">;</span>
    <span class="n">c</span><span class="o">.</span><span class="nf">do_thing</span><span class="p">();</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">a</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">c</span><span class="o">.</span><span class="n">a</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>

    <span class="c1">// We currently do not have a way to parse TypeName&lt;Typearg, Typearg2, etc&gt;</span>
    <span class="c1">// in regular expressions, so currently one cannot use templates in first-class</span>
    <span class="c1">// uses unless one uses a typealias (since the right hand side of a type alias is</span>
    <span class="c1">// always a type instantiation).</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Added an intrinsic function for inserting a debugging breakpoint in code <code class="language-plaintext highlighter-rouge">__builtin_debugtrap()</code>.</li>
  <li><a href="https://github.com/castano">castano</a> added support for filling function types in polymorphic parameters:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "Basic";</span>
<span class="cp">#import "LibC";</span>

<span class="kd">func</span> <span class="n">test</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span> <span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">comp</span><span class="p">:</span> <span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">compare</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">compare</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="n">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="n">bar</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span> <span class="p">(</span><span class="nv">foo</span><span class="p">:</span> <span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">T</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">foo</span><span class="p">();</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">zero</span> <span class="p">()</span> <span class="o">-&gt;</span> <span class="n">int</span> <span class="p">{</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">i</span> <span class="o">=</span> <span class="nf">bar</span><span class="p">(</span><span class="n">zero</span><span class="p">);</span>
    <span class="k">var</span> <span class="nv">j</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>

    <span class="k">var</span> <span class="nv">result</span> <span class="o">=</span> <span class="nf">test</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">compare</span><span class="p">);</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">result</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"result = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">result</span><span class="p">);</span>
<span class="p">}</span>


</code></pre></div></div>

<ul>
  <li><a href="https://github.com/castano">castano</a> added support for declaring float literals in scientific notation.</li>
  <li>Added support for anonymous unions and anonymous structs:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>

<span class="kd">struct</span> <span class="kt">Test</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">d</span><span class="p">:</span> <span class="n">float</span><span class="p">;</span>

    <span class="n">union</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">a</span><span class="p">:</span> <span class="n">int</span><span class="p">;</span>
        <span class="k">var</span> <span class="nv">b</span><span class="p">:</span> <span class="n">int</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">var</span> <span class="nv">c</span><span class="p">:</span> <span class="n">int</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">t</span><span class="p">:</span> <span class="kt">Test</span><span class="p">;</span>

    <span class="n">t</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="n">t</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
    <span class="n">t</span><span class="o">.</span><span class="n">d</span> <span class="o">=</span> <span class="mf">15.5</span><span class="p">;</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"t.d: %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">d</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"t.a: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"t.b: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">b</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"t.c: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">c</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Upgraded to LLVM 9. This change has been made primarily to pull in newer features from libclang inorder to properly detect and import anonymous unions/structs.</li>
</ul>

<p>Additional changes include various fixes.</p>

<h2 id="projects">Projects</h2>

<p>One of the main reasons I am building this language is to have fun programming in the language myself. In early February, I had decided to start a new project that could be built within a reasonably short amount of time, but still do something that is interesting and relatively nontrivial. I chose to build an Atari 2600 emulator since I have had previous experience building this type of emulator, and it fits within this criteria: the 6507/6502 has a relatively small instruction set and is well documented, the 2600 has a fairly small number of hardware interface registers, and thus has a small surface area to implement for each of the onboard chips, and the hardware’s behavior is fairly simple. That being said, the hardware does have a large number of minor quirks, but if you are not aimaing for 100% accuracy, then a mostly naive implementation of the hardware from the perspective of the Stella programmer’s manual is enough to get a good number of games working in a relatively small amount of time.</p>

<p>I am planning to do a separate write up on the project in the near future. The source code can be found <a href="https://github.com/machinamentum/HM2600">here</a>. I’ve uploaded a Windows binary <a href="https://github.com/machinamentum/HM2600/releases/tag/release_1">here</a>.</p>

<div class="embed-container">
  <iframe src="https://www.youtube.com/embed/a1_7y4wQZMc" width="700" height="480" frameborder="0" allowfullscreen="">
  </iframe>
</div>

<h2 id="conclusion">Conclusion</h2>

<p>I want to again thank the contributors for picking up this project and helping to improve it!</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><category term="jiyu" /><summary type="html"><![CDATA[February has been a bit of a slow month, but we’ve managed to add a few interesting features.]]></summary></entry><entry><title type="html">Jiyu Update - February 2020</title><link href="http://josh.tools/Jyu-Update-February-2020/" rel="alternate" type="text/html" title="Jiyu Update - February 2020" /><published>2020-02-01T00:00:00+00:00</published><updated>2020-02-01T00:00:00+00:00</updated><id>http://josh.tools/Jyu-Update-February-2020</id><content type="html" xml:base="http://josh.tools/Jyu-Update-February-2020/"><![CDATA[<p>Progress has been a bit slow for the last few weeks because I’ve personally lost a large amount of time to playing Stardew Valley, but we’ve managed to still fit in a number of important features for this month’s update.</p>

<ul>
  <li>There is now support for harnessing LLVM’s JIT engine in user code</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "Compiler";</span>

<span class="c1">// Since metaprograms are just fully JIT-ed LLVM modules,</span>
<span class="c1">// we have been internally using the JIT-er to lookup the "main" symbol</span>
<span class="c1">// in a program and call that... We no longer do that internally.</span>
<span class="c1">// There is a legacy function in Compiler to mimick the way this worked</span>
<span class="c1">// previously, but now we allow user code to fully leverage this functionality.</span>

<span class="kd">func</span> <span class="kd">@metaprogram</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">options</span><span class="p">:</span> <span class="kt">Build_Options</span><span class="p">;</span>
    <span class="n">options</span><span class="o">.</span><span class="n">only_want_obj_file</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">compiler</span> <span class="o">=</span> <span class="nf">create_compiler_instance</span><span class="p">(</span><span class="o">*</span><span class="n">options</span><span class="p">);</span>

    <span class="k">if</span> <span class="nf">compiler_load_string</span><span class="p">(</span><span class="n">compiler</span><span class="p">,</span> <span class="kt">CODE_TO_COMPILE</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_typecheck_program</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_generate_llvm_module</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>

    <span class="c1">// New function to JIT the entire program.</span>
    <span class="k">if</span> <span class="nf">compiler_jit_program</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>

    <span class="c1">// Once compiler_jit_program passes, we can now arbitrarily query symbols</span>
    <span class="c1">// and call into them.</span>
    <span class="k">var</span> <span class="nv">do_a_thing</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">(()</span> <span class="o">-&gt;</span> <span class="n">void</span><span class="p">)</span> <span class="nf">compiler_jit_lookup_symbol</span><span class="p">(</span><span class="n">compiler</span><span class="p">,</span> <span class="s">"do_a_thing"</span><span class="p">);</span>
    <span class="nf">do_a_thing</span><span class="p">();</span>

    <span class="k">var</span> <span class="nv">do_a_thing2</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">((</span><span class="nv">p</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">void</span><span class="p">)</span> <span class="nf">compiler_jit_lookup_symbol</span><span class="p">(</span><span class="n">compiler</span><span class="p">,</span> <span class="s">"do_a_thing2"</span><span class="p">);</span>
    <span class="nf">do_a_thing2</span><span class="p">(</span><span class="s">"Howdy :)"</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">CODE_TO_COMPILE</span> <span class="o">=</span>
<span class="s">"""
#import "</span><span class="kt">LibC</span><span class="s">";

// We are using the @export tag here for the sake of demonstration, otherwise
// we would need to lookup the proper jiyu-mangled names.
func @export("</span><span class="n">do_a_thing</span><span class="s">") do_a_thing() {
    printf("</span><span class="kt">Hello</span><span class="p">,</span> <span class="kt">Sailor</span><span class="p">\</span><span class="n">n</span><span class="s">");
}

func @export("</span><span class="n">do_a_thing2</span><span class="s">") do_a_thing2(str: string) {
    printf("</span><span class="kt">Hello</span><span class="p">,</span> <span class="kt">Pilot</span><span class="o">!</span> <span class="o">%.*</span><span class="n">s</span><span class="p">\</span><span class="n">n</span><span class="s">", str.length, str.data);
}
"""</span><span class="p">;</span>
</code></pre></div></div>

<p>Additionally, we now provide a library version of the compiler that is built alongside the compiler driver program. The API is exactly the same whether the user code is running as a metaprogram or as a compiled binary. This allows users to effectively implement custom driver frontends that support arbitrary operations that the official driver does not. This also allows compiled user code to JIT-compile Jiyu code at runtime, enabling games to embed Jiyu as a robust scripting system, or enabling IDEs to embed Jiyu in environments where running external executables and toolchains is not allowed.</p>

<ul>
  <li>Support for operator overloading has been added. Currently, only <code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, and <code class="language-plaintext highlighter-rouge">/</code> can be overloaded, but support for more operators will be added in the future.</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>

<span class="kd">struct</span> <span class="kt">Vector3</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">x</span><span class="p">:</span> <span class="n">float</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">y</span><span class="p">:</span> <span class="n">float</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">z</span><span class="p">:</span> <span class="n">float</span><span class="p">;</span>

    <span class="kd">func</span> <span class="nf">make</span><span class="p">(</span><span class="nv">x</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">y</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">z</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Vector3</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">v</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">;</span>
        <span class="n">v</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="p">;</span>
        <span class="n">v</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">;</span>
        <span class="n">v</span><span class="o">.</span><span class="n">z</span> <span class="o">=</span> <span class="n">z</span><span class="p">;</span>
        <span class="k">return</span> <span class="n">v</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">operator</span><span class="o">+</span><span class="p">(</span><span class="nv">b</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">str</span><span class="p">:</span> <span class="n">string</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">float</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">b</span> <span class="o">+</span> <span class="nf">cast</span><span class="p">(</span><span class="n">float</span><span class="p">)</span> <span class="n">str</span><span class="o">.</span><span class="n">length</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">operator</span><span class="o">+</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Vector3</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kt">Vector3</span><span class="o">.</span><span class="nf">make</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">x</span><span class="o">+</span><span class="n">b</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">y</span><span class="o">+</span><span class="n">b</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">z</span><span class="o">+</span><span class="n">b</span><span class="o">.</span><span class="n">z</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">operator</span><span class="o">-</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Vector3</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kt">Vector3</span><span class="o">.</span><span class="nf">make</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">x</span><span class="o">-</span><span class="n">b</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">y</span><span class="o">-</span><span class="n">b</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">z</span><span class="o">-</span><span class="n">b</span><span class="o">.</span><span class="n">z</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">print_vector</span><span class="p">(</span><span class="nv">v</span><span class="p">:</span> <span class="kt">Vector3</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"vector3: %f, %f, %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">v</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">v</span><span class="o">.</span><span class="n">z</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="kd">@metaprogram</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">a</span> <span class="o">=</span> <span class="kt">Vector3</span><span class="o">.</span><span class="nf">make</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
    <span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="kt">Vector3</span><span class="o">.</span><span class="nf">make</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">);</span>

    <span class="k">var</span> <span class="nv">c</span> <span class="o">=</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">d</span> <span class="o">=</span> <span class="n">b</span> <span class="o">-</span> <span class="n">a</span><span class="p">;</span>

    <span class="nf">print_vector</span><span class="p">(</span><span class="n">a</span><span class="p">);</span>
    <span class="nf">print_vector</span><span class="p">(</span><span class="n">b</span><span class="p">);</span>
    <span class="nf">print_vector</span><span class="p">(</span><span class="n">c</span><span class="p">);</span>
    <span class="nf">print_vector</span><span class="p">(</span><span class="n">d</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"1.0 + </span><span class="se">\"</span><span class="s">Hello</span><span class="se">\"</span><span class="s">: %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="mf">1.0</span> <span class="o">+</span> <span class="s">"Hello"</span><span class="p">);</span>
<span class="p">}</span>

</code></pre></div></div>

<ul>
  <li>
    <p><a href="https://github.com/castano">castano</a> has implemented support for <code class="language-plaintext highlighter-rouge">typeof()</code> operator that resolves to the type of an input declaration.</p>
  </li>
  <li>
    <p><a href="https://github.com/castano">castano</a> has implemented support for enums:</p>
  </li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>
<span class="cp">#import "Basic";</span>


<span class="kd">enum</span> <span class="kt">Day</span> <span class="p">:</span> <span class="n">uint</span> <span class="p">{</span>
    <span class="kt">Monday</span><span class="p">;</span>
    <span class="kt">Tuesday</span> <span class="o">=</span> <span class="kt">Monday</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
    <span class="kt">Wednesday</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>

    <span class="kt">Thursday</span><span class="p">;</span>
    <span class="kt">Friday</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">+</span> <span class="kt">Thursday</span><span class="p">;</span>

    <span class="kt">Saturday</span><span class="p">;</span>
    <span class="kt">Sunday</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">WeekendDay</span> <span class="p">{</span>
    <span class="kt">Saturday</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">(</span><span class="kt">WeekendDay</span><span class="p">)</span><span class="kt">Day</span><span class="o">.</span><span class="kt">Saturday</span><span class="p">;</span>   <span class="c1">// This should require a cast. Do not allow implicit cast from one enum to another.</span>
    <span class="kt">Sunday</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">Bool</span> <span class="p">:</span> <span class="n">uint8</span> <span class="p">{</span> <span class="kt">False</span><span class="p">;</span> <span class="kt">True</span><span class="p">;</span> <span class="p">}</span>

<span class="kd">typealias</span> <span class="kt">DAY</span> <span class="o">=</span> <span class="kt">Day</span><span class="p">;</span>

<span class="k">var</span> <span class="nv">another_day</span> <span class="p">:</span> <span class="kt">DAY</span> <span class="o">=</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">;</span>

<span class="k">var</span> <span class="nv">monday</span> <span class="o">=</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">;</span>
<span class="k">var</span> <span class="nv">tuesday</span> <span class="p">:</span> <span class="kt">Day</span> <span class="o">=</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Tuesday</span><span class="p">;</span>
<span class="k">var</span> <span class="nv">sunday</span> <span class="p">:</span> <span class="kt">Day</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">(</span><span class="kt">Day</span><span class="p">)</span><span class="kt">WeekendDay</span><span class="o">.</span><span class="kt">Sunday</span><span class="p">;</span>
<span class="k">var</span> <span class="nv">my_day</span> <span class="p">:</span> <span class="kt">Day</span><span class="p">;</span>

<span class="kd">func</span> <span class="nf">test</span><span class="p">(</span><span class="nv">day</span> <span class="p">:</span> <span class="kt">Day</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span> <span class="p">{</span>
    <span class="k">return</span> <span class="nf">cast</span><span class="p">(</span><span class="n">int</span><span class="p">)</span><span class="n">day</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="p">{</span>
        <span class="k">var</span> <span class="nv">day</span> <span class="p">:</span> <span class="kt">Day</span><span class="p">;</span>

        <span class="k">let</span> <span class="nv">Monday</span> <span class="o">=</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">;</span>
        <span class="k">let</span> <span class="nv">Tuesday</span> <span class="o">=</span> <span class="kt">Monday</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
        <span class="nf">assert</span><span class="p">(</span><span class="nf">typeof</span><span class="p">(</span><span class="kt">Monday</span><span class="p">)</span> <span class="o">==</span> <span class="kt">Day</span><span class="p">);</span>

        <span class="k">let</span> <span class="nv">MONDAY</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">(</span><span class="n">int</span><span class="p">)</span><span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">;</span>   <span class="c1">// Type of MONDAY is int</span>
        <span class="nf">assert</span><span class="p">(</span><span class="nf">typeof</span><span class="p">(</span><span class="kt">MONDAY</span><span class="p">)</span> <span class="o">==</span> <span class="n">int</span><span class="p">);</span>
    <span class="p">}</span>
  
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Monday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Tuesday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Tuesday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Wednesday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Wednesday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Thursday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Thursday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Friday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Friday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Saturday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Saturday</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"Sunday = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Day</span><span class="o">.</span><span class="kt">Sunday</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"test(Day.Monday) = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="nf">test</span><span class="p">(</span><span class="kt">Day</span><span class="o">.</span><span class="kt">Monday</span><span class="p">));</span>

    <span class="c1">// Implicit calls from integer to enum:</span>
    <span class="c1">// Currently these are only allowed when the expression is a mutable literal.</span>
    <span class="p">{</span>
        <span class="k">var</span> <span class="nv">day</span> <span class="p">:</span> <span class="kt">Day</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="nf">printf</span><span class="p">(</span><span class="s">"test(0) = %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="nf">test</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
    <span class="p">}</span>
    

    <span class="c1">//printf("Whatever = %d\n", Day.Whatever); // This should trigger an error.</span>
    <span class="p">{</span>
        <span class="k">var</span> <span class="nv">day</span> <span class="p">:</span> <span class="kt">Day</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Monday</span><span class="p">;</span>
        <span class="nf">test</span><span class="p">(</span><span class="o">.</span><span class="kt">Tuesday</span><span class="p">);</span>
        <span class="k">if</span> <span class="n">day</span> <span class="o">==</span> <span class="o">.</span><span class="kt">Wednesday</span> <span class="p">{</span>
            <span class="n">day</span> <span class="o">=</span> <span class="o">.</span><span class="kt">Sunday</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">if</span> <span class="o">.</span><span class="kt">Wednesday</span> <span class="o">&gt;</span> <span class="n">day</span> <span class="p">{</span>
            <span class="c1">// test(1 + .Tuesday); // This produces an error, as expected.        </span>
        <span class="p">}</span>
        
    <span class="p">}</span>
    
<span class="p">}</span>

</code></pre></div></div>

<p>Additionally, support for enum bit-flags is also available:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>
<span class="cp">#import "Basic";</span>

<span class="kd">enum</span> <span class="kd">@flags</span> <span class="kt">Entity_Flags</span> <span class="p">{</span>
    <span class="kt">Invisible</span><span class="p">;</span>
    <span class="kt">Solid</span><span class="p">;</span>
    <span class="kt">Cast_Shadows</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span> <span class="p">()</span> <span class="p">{</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="kt">Entity_Flags</span><span class="o">.</span><span class="kt">Invisible</span> <span class="o">|</span> <span class="o">.</span><span class="kt">Solid</span> <span class="o">|</span> <span class="o">.</span><span class="kt">Cast_Shadows</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Tuples are now part of the language:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>

<span class="kd">func</span> <span class="nf">test</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// arguments in tuple-expressions are automatically inferred</span>
    <span class="c1">// according to the fields of the tuple being assigned, returned, or passed to.</span>
    <span class="nf">return</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">test3</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="nv">c</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">d</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">return</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">test2</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">int</span><span class="p">,</span> <span class="nv">b</span><span class="p">:</span> <span class="n">float</span><span class="p">))</span> <span class="p">{</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"T2: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"T2: %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">a</span><span class="o">.</span><span class="n">b</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">t</span> <span class="o">=</span> <span class="nf">test</span><span class="p">();</span>
    <span class="k">var</span> <span class="nv">t3</span> <span class="o">=</span> <span class="nf">test3</span><span class="p">();</span>

    <span class="c1">// t and t3 are the same type as far as the type system is concerned,</span>
    <span class="c1">// their tuples will share the same type information in the RTTI system,</span>
    <span class="c1">// and internally, they will have the same type table index,</span>
    <span class="c1">// however, since the semantic analysis system assigns types in-place,</span>
    <span class="c1">// t and t3 have distinct fields.</span>

    <span class="c1">// t.c = t3.a; // this fails</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">b</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t3</span><span class="o">.</span><span class="n">c</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t3</span><span class="o">.</span><span class="n">d</span><span class="p">);</span>

    <span class="n">t</span> <span class="o">=</span> <span class="n">t3</span><span class="p">;</span>

    <span class="n">t</span> <span class="o">=</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">a</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">b</span><span class="p">);</span>

    <span class="nf">test2</span><span class="p">(</span><span class="n">t</span><span class="p">);</span>
    <span class="nf">test2</span><span class="p">((</span><span class="mi">6</span><span class="p">,</span> <span class="mi">9</span><span class="p">));</span>

    <span class="k">var</span> <span class="nv">n</span><span class="p">:</span> <span class="n">int</span><span class="p">;</span>
    <span class="k">var</span> <span class="nv">m</span><span class="p">:</span> <span class="n">float</span><span class="p">;</span>

    <span class="c1">// In the event that a tuple-expression is on the left-hand-side</span>
    <span class="c1">// of an assignment, the type of the tuple is directly determined by</span>
    <span class="c1">// the types of its arguments, regardless of the type of the tuple</span>
    <span class="c1">// on the right-hand-side.</span>
    <span class="c1">// Each field of the tuple on the right-hand-side is unpacked into</span>
    <span class="c1">// the individual arguments of the tuple-expression on the left-hand-</span>
    <span class="c1">// side.</span>
    <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="o">=</span> <span class="nf">test</span><span class="p">();</span>

    <span class="c1">// Like other types of assignments, you cannot try to use a literal</span>
    <span class="c1">// in a tuple expression on the left-hand-side of an assignment.</span>
    <span class="c1">// (n, 1) = test(); // does not work.</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"n: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">n</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"m: %f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">m</span><span class="p">);</span>

    <span class="c1">// These do not work yet, but are planned to be available eventually.</span>
    <span class="cm">/*
    var (i, j) = test();
    var (i: int, j: float) = test();
    */</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Additional changes include improved support for C interfaces on various platforms, improved support for trivial-constant-folding, and various fixes.</p>

<p>I want to again thank the contributors for picking up this project and helping to improve it!</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[Progress has been a bit slow for the last few weeks because I’ve personally lost a large amount of time to playing Stardew Valley, but we’ve managed to still fit in a number of important features for this month’s update.]]></summary></entry><entry><title type="html">Jiyu Update - January 2020</title><link href="http://josh.tools/Jyu-Update-January-2020/" rel="alternate" type="text/html" title="Jiyu Update - January 2020" /><published>2020-01-01T00:00:00+00:00</published><updated>2020-01-01T00:00:00+00:00</updated><id>http://josh.tools/Jyu-Update-January-2020</id><content type="html" xml:base="http://josh.tools/Jyu-Update-January-2020/"><![CDATA[<p>Progress has been going pretty strong this past monthly-ish period.</p>

<ul>
  <li>There is now a #clang_import directive. This allows importing declarations from C header files directly into Jiyu scopes. Example:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="cp">#clang_import "#include &lt;stdio.h&gt;";</span>
 
 <span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
     <span class="nf">printf</span><span class="p">(</span><span class="s">"Hello, Moonman!</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
 <span class="p">}</span>
</code></pre></div></div>

<p>The string following the directive can contain arbitrary C code. This works for a number of C declaration types, including structs, unions, enums, functions, and typedefs. Do note however, that only importing bindings for declarations is supported, there is no support for compiling C function bodies, and there are no plans for Jiyu to replace a C compiler. I have been using this for awhile on Windows, and have even gotten the <a href="https://twitter.com/machinamentum/status/1211501147808247808">nuklear imgui library working without needing to manually write bindings</a>, but this may not work well on Mac/Linux yet if you need to import system headers.</p>

<ul>
  <li>There is now a mechanism to enable member-function-call syntax for arrays. I have documented this in this demo below:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "LibC";</span>
<span class="cp">#import "Array";</span>

<span class="c1">// Array module defines:</span>
<span class="c1">// __array_add&lt;T&gt;(arr: *[..] T, item: T)</span>
<span class="c1">// __array_reset&lt;T&gt;(arr: *[..] T)</span>
<span class="c1">// __array_reserve&lt;T&gt;(arr: *[..] T)</span>
<span class="c1">// __array_resize&lt;T&gt;(array: *[..] T, _amount: int)</span>
<span class="c1">// __array_pop&lt;T&gt;(array: *[..] T) -&gt; T</span>
<span class="c1">// __array_contains&lt;T&gt;(array: *[..] T, item: T) -&gt; bool</span>
<span class="c1">// __array_add_if_unique&lt;T&gt;(array: *[..] T, item: T) -&gt; bool</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// When the compiler sees &lt;array&gt;.func(...), it will attempt to transform this sequence into</span>
    <span class="c1">// __array_func(&lt;array&gt;, ...) or __array_func(*&lt;array&gt;, ...).</span>
    <span class="k">var</span> <span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="n">int64</span><span class="p">;</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add_if_unique</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add_if_unique</span><span class="p">(</span><span class="mi">4</span><span class="p">);</span>

    <span class="k">for</span> <span class="n">arr</span> <span class="nf">printf</span><span class="p">(</span><span class="s">"Value: %lld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">it</span><span class="p">);</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"Popped value: %lld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">arr</span><span class="o">.</span><span class="nf">pop</span><span class="p">());</span>

    <span class="k">for</span> <span class="n">arr</span> <span class="nf">printf</span><span class="p">(</span><span class="s">"Remaining Value: %lld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">it</span><span class="p">);</span>

    <span class="n">arr</span><span class="o">.</span><span class="nf">reset</span><span class="p">();</span>
    <span class="k">for</span> <span class="n">arr</span> <span class="nf">printf</span><span class="p">(</span><span class="s">"Remaining Value ????: %lld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">it</span><span class="p">);</span> <span class="c1">// This should not output anything!</span>

    <span class="nf">locally_scoped_functions</span><span class="p">();</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">locally_scoped_functions</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Since this special syntax turns into a scope-lookup,</span>
    <span class="c1">// we can override the defaults defined in the Array module.</span>
    <span class="kd">func</span> <span class="n">__array_add</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">array</span><span class="p">:</span> <span class="o">*</span><span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">item</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">printf</span><span class="p">(</span><span class="s">"Hello, Sailor!"</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">var</span> <span class="nv">arr</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="n">int64</span><span class="p">;</span>
    <span class="n">arr</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="k">for</span> <span class="n">arr</span> <span class="nf">printf</span><span class="p">(</span><span class="s">"Remaining Value ????: %lld</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">it</span><span class="p">);</span> <span class="c1">// should not print anything!</span>
<span class="p">}</span>

</code></pre></div></div>

<ul>
  <li>There is now a <code class="language-plaintext highlighter-rouge">-emit-llvm</code> flag to dump generated LLVM IR to a file.</li>
  <li>Unions are now available, simply use the <code class="language-plaintext highlighter-rouge">union</code> keyword in place of <code class="language-plaintext highlighter-rouge">struct</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">break</code> and <code class="language-plaintext highlighter-rouge">continue</code> now work for while-loops.</li>
  <li><code class="language-plaintext highlighter-rouge">os()</code> now checks against LLVM’s support operating system types and the target triple of the compilation. See <a href="https://llvm.org/doxygen/Triple_8cpp_source.html#l00175">Triple::getOSTypeName</a> for a list of valid inputs. The input is case-insensitive.</li>
  <li>Raspberry Pi 4 is now officially supported. <a href="https://twitter.com/machinamentum/status/1206056214028787712">Relevant tweet</a>.</li>
  <li>Diagnostic-esque information is no longer printed to the terminal by default. There is now a <code class="language-plaintext highlighter-rouge">-v</code> flag to print out this information for debugging. There’s also a <code class="language-plaintext highlighter-rouge">verbose_diagnostics</code> Build_Option available to get this information out of a compilation through a metaprogram.</li>
  <li>while-loop conditions now coerce-to-bool.</li>
  <li>There are now built-in typealiases to reference the types for &lt;string&gt;.length and &lt;array&gt;.count fields. They are <code class="language-plaintext highlighter-rouge">__builtin_string_length_type</code> and <code class="language-plaintext highlighter-rouge">__builtin_array_count_type</code>.</li>
  <li>Global variable structs are now properly default-initialized based on the default initializations of their fields.</li>
  <li><a href="https://github.com/castano">castano</a> has added support for referencing let-constants declared within structs.</li>
  <li><a href="https://github.com/castano">castano</a> has added a Sublime Text highlighting extension.</li>
  <li><a href="https://github.com/castano">castano</a> has added support for multiline string literals similar to how they are implemented in Swift:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 
<span class="cp">#import "Basic";</span>
<span class="cp">#import "LibC";</span>

<span class="k">let</span> <span class="nv">singleLineString</span> <span class="o">=</span> <span class="s">"These are the same."</span><span class="p">;</span>

<span class="k">let</span> <span class="nv">multilineString</span> <span class="o">=</span> <span class="s">"""
These are the same.
"""</span><span class="p">;</span>

<span class="k">let</span> <span class="nv">multilineString2</span> <span class="o">=</span> <span class="s">"""These are the same."""</span><span class="p">;</span>

<span class="k">let</span> <span class="nv">multilineString3</span> <span class="o">=</span> <span class="s">"""
    These are the same.
    """</span><span class="p">;</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="c1">// Multi-line string equivalency.</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">singleLineString</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">singleLineString</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">multilineString</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">multilineString</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">multilineString2</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">multilineString2</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">multilineString3</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">multilineString3</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">singleLineString</span> <span class="o">==</span> <span class="n">multilineString</span><span class="p">);</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">singleLineString</span> <span class="o">==</span> <span class="n">multilineString2</span><span class="p">);</span>
    <span class="nf">assert</span><span class="p">(</span><span class="n">singleLineString</span> <span class="o">==</span> <span class="n">multilineString3</span><span class="p">);</span>

    <span class="k">let</span> <span class="nv">indentation</span> <span class="o">=</span> <span class="s">"""
        This text has indentation.
        And that is fine.
        """</span><span class="p">;</span>

    <span class="nf">printf</span><span class="p">(</span><span class="s">"%.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">indentation</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">indentation</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>

<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li>Support for passing and returning structs to/from C has been improved.</li>
  <li>There are now <code class="language-plaintext highlighter-rouge">strideof()</code> and <code class="language-plaintext highlighter-rouge">alignof()</code> operators. These return the stride and alignment of any input type. Unlike C, the the size of a struct is the amount of space required to store the struct, the stride is the amount of space needed to store the struct with padding to its alignment.</li>
  <li>There is now support for unary <code class="language-plaintext highlighter-rouge">!</code> and unary <code class="language-plaintext highlighter-rouge">~</code>.</li>
  <li>There is now support for a rudimentary level of struct inheritance:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">func</span> <span class="nf">test_inheritance</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">struct</span> <span class="kt">Node</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">i</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>

        <span class="kd">func</span> <span class="nf">do_a_thing</span><span class="p">()</span> <span class="p">{</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"Node do_a_thing()</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        <span class="p">}</span>

        <span class="kd">func</span> <span class="nf">do_a_thing2</span><span class="p">(</span><span class="nv">n</span><span class="p">:</span> <span class="o">*</span><span class="kt">Node</span><span class="p">)</span> <span class="p">{</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"Node.i: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">n</span><span class="o">.</span><span class="n">i</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">struct</span> <span class="kt">Node_Child</span> <span class="p">:</span> <span class="kt">Node</span> <span class="p">{</span>
        <span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="s">"test"</span><span class="p">;</span>

        <span class="kd">func</span> <span class="nf">do_a_thing3</span><span class="p">(</span><span class="nv">n</span><span class="p">:</span> <span class="o">*</span><span class="kt">Node_Child</span><span class="p">)</span> <span class="p">{</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"Node_Child.i: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">n</span><span class="o">.</span><span class="n">i</span><span class="p">);</span>
            <span class="nf">printf</span><span class="p">(</span><span class="s">"Node_Child.b: %.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">n</span><span class="o">.</span><span class="n">b</span><span class="o">.</span><span class="n">length</span><span class="p">,</span> <span class="n">n</span><span class="o">.</span><span class="n">b</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">var</span> <span class="nv">child</span><span class="p">:</span> <span class="kt">Node_Child</span><span class="p">;</span>
    <span class="n">child</span><span class="o">.</span><span class="nf">do_a_thing2</span><span class="p">();</span>
    <span class="n">child</span><span class="o">.</span><span class="nf">do_a_thing3</span><span class="p">();</span>

    <span class="kt">Node_Child</span><span class="o">.</span><span class="nf">do_a_thing</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>I want to again thank the contributors for picking up this project and helping to improve it!</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[Progress has been going pretty strong this past monthly-ish period.]]></summary></entry><entry><title type="html">Jiyu Update - November 2019</title><link href="http://josh.tools/Jiyu-Update-November-2019/" rel="alternate" type="text/html" title="Jiyu Update - November 2019" /><published>2019-11-29T00:00:00+00:00</published><updated>2019-11-29T00:00:00+00:00</updated><id>http://josh.tools/Jiyu-Update-November-2019</id><content type="html" xml:base="http://josh.tools/Jiyu-Update-November-2019/"><![CDATA[<p>It has been a awhile seen I’ve written one of these. I had taken some time off from working on the compiler to focus my free time on learning some traditional arts. That being said, there’s a number of changes to talk about so let’s get into it.</p>

<ul>
  <li>There is now a psuedo-test-suite program located at &lt;jiyu&gt;/tests.jyu. This automatically compiles the test programs in &lt;jiyu&gt;/tests. This is a way to quickly verify that changes to the compiler don’t break some basic features.</li>
  <li>String-literals can be implicitly cast to *uint8 and *int8. This is a convinience for passing string-literals to C functions.</li>
  <li>Added compiler_run_metaprogram(). This function allows metaprograms to compile and run other programs at compile-time.</li>
  <li>There’s now support for loading libraries that the user has specified with the <em>library</em> keyword into metaprograms. This is a seemless operation, so there is no extra work required of the user. This may not entirely work with user-installed libraries on Linux/Mac at the moment, but this will be improved over time.</li>
  <li>The compiler now accepts the “-c” switch to end compilation at generating an object file.</li>
  <li>The compiler now accepts the “-o” switch to specify the target file/executable name to output to.</li>
  <li>The switch “-triple” is now “-target”.</li>
  <li><a href="https://github.com/ahmadrosid">ahmadrosid</a> has added some missing functionality on Linux and the compiler should work on Linux now.</li>
  <li>Control-flow statements <em>break</em> and <em>continue</em> are now available and working.</li>
  <li>There is now a version of <em>for</em> that gives a pointer to array elements instead of a const-copy of the elements. The syntax is “for * &lt;array_typed_expression&gt; { … }”.</li>
  <li><a href="https://github.com/castano/">castano</a> has added an open-half version of <em>for</em>, which excludes the value of the upper-bound expression of the <em>for</em> range. Example: “for 0 ..&lt; 2 { … }”, would be equivalent of “for { int it = 0; it &lt; 2; it += 1) { … }” in C.</li>
  <li><em>if</em>-conditions now have coerce-to-bool. Integer, float, and pointer-types are now automatically compared to literal-0, string is automatically compared to empty-string.</li>
  <li>There is now syntax for calling member-functions of structs with more ease:</li>
</ul>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">My_Struct</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">i</span><span class="p">:</span> <span class="n">int</span><span class="p">;</span>
	<span class="c1">// You can overload between a reference and a pointer.</span>
	<span class="kd">func</span> <span class="nf">do_something</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="kt">My_Struct</span><span class="p">)</span> <span class="p">{</span> <span class="o">....</span> <span class="p">}</span>
	<span class="kd">func</span> <span class="nf">do_something</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="o">*</span><span class="kt">My_Struct</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
	
	<span class="kd">func</span> <span class="nf">do_something2</span><span class="p">(</span><span class="nv">data</span><span class="p">:</span> <span class="o">*</span><span class="kt">My_Struct</span><span class="p">)</span> <span class="p">{</span> <span class="o">...</span> <span class="p">}</span>
	
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">my_func</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">data</span><span class="p">:</span> <span class="kt">My_Struct</span><span class="p">;</span>
	<span class="n">data</span><span class="o">.</span><span class="nf">do_something</span><span class="p">();</span> <span class="c1">// _data_ is implicitly passed to My_Struct.do_something(data: My_Struct);</span>
	<span class="k">var</span> <span class="nv">data_ptr</span> <span class="o">=</span> <span class="o">*</span><span class="n">data</span><span class="p">;</span>
	<span class="n">data_ptr</span><span class="o">.</span><span class="nf">do_something</span><span class="p">();</span> <span class="c1">// _data_ptr_ is implicitly passed to My_Struct.do_something(data: *My_Struct);</span>
	<span class="n">data</span><span class="o">.</span><span class="nf">do_something2</span><span class="p">();</span> <span class="c1">// A pointer is taken of _data_ and passed to My_Struct.do_something2();</span>
	
	<span class="c1">// You can still call these functions the traditional way, too</span>
	<span class="kt">My_Struct</span><span class="o">.</span><span class="nf">do_something</span><span class="p">(</span><span class="n">data</span><span class="p">);</span>
	<span class="kt">My_Struct</span><span class="o">.</span><span class="nf">do_something</span><span class="p">(</span><span class="o">*</span><span class="n">data</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<ul>
  <li><a href="https://github.com/castano/">castano</a> has added compiler_load_string(), exposing previously internal functionality to directly compile code from strings, in metaprograms.</li>
  <li>Cross-compilation support has been improved. I have demonstrated <a href="https://twitter.com/machinamentum/status/1195569426105536512?s=20">running Jiyu code on an iOS device</a>, and <a href="https://twitter.com/machinamentum/status/1193671625771769856?s=20">running Jiyu code bare-metal under Qemu</a>.</li>
</ul>

<p>Additionally, there have been a number of fixes and changes to improve the compiler, by myself and others.</p>

<p>There’s currently work being done to import C-headers directly into Jiyu code without any external tools. I will write another post documenting that once it is working well.</p>

<p>I want to again thank the contributors for picking up this project and helping to improve it!</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[It has been a awhile seen I’ve written one of these. I had taken some time off from working on the compiler to focus my free time on learning some traditional arts. That being said, there’s a number of changes to talk about so let’s get into it.]]></summary></entry><entry><title type="html">Jiyu Update - August 2019</title><link href="http://josh.tools/Jiyu-Update-August-2019/" rel="alternate" type="text/html" title="Jiyu Update - August 2019" /><published>2019-08-18T00:00:00+00:00</published><updated>2019-08-18T00:00:00+00:00</updated><id>http://josh.tools/Jiyu-Update-August-2019</id><content type="html" xml:base="http://josh.tools/Jiyu-Update-August-2019/"><![CDATA[<p>It has been about a month since I <a href="/Jiyu-A-Programming-Language/">last wrote about my new programming-language project, Jiyu</a>, so I’m going to briefly talk about the changes that have happened since.</p>

<h2 id="libraries">Libraries</h2>

<p>Libraries and macOS frameworks can now be specified using the declarators <code class="language-plaintext highlighter-rouge">library</code> and <code class="language-plaintext highlighter-rouge">framework</code>, respectively.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#if os(Windows) {</span>
	<span class="n">library</span> <span class="s">"msvcrt"</span><span class="p">;</span>
	<span class="n">library</span> <span class="s">"opengl32"</span><span class="p">;</span>
<span class="p">}</span>

<span class="cp">#if os(MacOSX) {</span>
	<span class="n">library</span> <span class="s">"c"</span><span class="p">;</span>
	<span class="n">framework</span> <span class="s">"OpenGL"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>These inform the built-in linker command on what libraries to link, and will eventually inform the LLVM JIT on what libraries to load.</p>

<h2 id="modules">Modules</h2>

<p>The compiler now looks for module-libraries in the <code class="language-plaintext highlighter-rouge">jiyu/modules</code> folder. The folder is located by searching up the directory tree from the executable’s path for a folder named <code class="language-plaintext highlighter-rouge">jiyu</code>, then <code class="language-plaintext highlighter-rouge">modules</code> is appended to the path. This will likely change as the compiler matures, but it currently makes working with modules easy. There is a new <code class="language-plaintext highlighter-rouge">#import</code> directive to reference a module from the scope that the directive is declared in. Since modules are intended to be referenced from many parts of a program, they exist in a scope-bubble of their own and cannot see declarations in the program’s global scope. Due to this, modules must also import other modules that they depend on.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#import "Array";</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">array</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="n">uint8</span><span class="p">;</span>
	<span class="nf">array_add</span><span class="p">(</span><span class="o">*</span><span class="n">array</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="compiler">Compiler</h2>

<p>There is now a <code class="language-plaintext highlighter-rouge">Build_Options</code> struct for specifying compilation options. Currently, only the output executable name and target-triple can be specified. Consequently, <code class="language-plaintext highlighter-rouge">create_compiler_instance() -&gt; *Compiler</code> now accepts a <code class="language-plaintext highlighter-rouge">*Builder_Options</code> parameter. Build options for a compiler instance can not be changed after <code class="language-plaintext highlighter-rouge">create_compiler_instance()</code> is called.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Build_Options</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">executable_name</span><span class="p">:</span> <span class="n">string</span><span class="p">;</span>
	<span class="k">var</span> <span class="nv">target_triple</span><span class="p">:</span> <span class="n">string</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// ...</span>

<span class="cp">#import "Compiler";</span>

<span class="kd">func</span> <span class="kd">@metaprogram</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">options</span><span class="p">:</span> <span class="kt">Build_Options</span><span class="p">;</span>
	<span class="n">options</span><span class="o">.</span><span class="n">executable_name</span> <span class="o">=</span> <span class="s">"my_cool_program"</span><span class="p">;</span>
	<span class="n">options</span><span class="o">.</span><span class="n">target_triple</span>   <span class="o">=</span> <span class="s">"arm-none-elf-eabi"</span><span class="p">;</span>
	
	<span class="k">var</span> <span class="nv">compiler</span> <span class="o">=</span> <span class="nf">create_compiler_instance</span><span class="p">(</span><span class="o">*</span><span class="n">options</span><span class="p">);</span>
	
	<span class="c1">// ...</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="llvm">LLVM</h2>

<ul>
  <li>Jiyu programs can now be debugged in your favorite debugger!</li>
</ul>

<p><img src="/assets/2019-8-18-Jiyu-Update-August-2019_MSVC_debugging.PNG" alt="Jiyu Program in MSVC debugger" /></p>

<ul>
  <li>Aggregate types are now passed via an invisible reference.</li>
  <li>As mentioned previously, one can now specify a target triple to the compiler. LLVM will honor this, enabling cross-compilation.</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>With these few changes, the compiler and language should be a bit more practical to use. I plan to post updates on a monthly basis, granted there’s enough changes, or a big enough change, that’s worth talking about.</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[It has been about a month since I last wrote about my new programming-language project, Jiyu, so I’m going to briefly talk about the changes that have happened since. Libraries]]></summary></entry><entry><title type="html">Jiyu - A Programming Language</title><link href="http://josh.tools/Jiyu-A-Programming-Language/" rel="alternate" type="text/html" title="Jiyu - A Programming Language" /><published>2019-07-22T00:00:00+00:00</published><updated>2019-07-22T00:00:00+00:00</updated><id>http://josh.tools/Jiyu-A-Programming-Language</id><content type="html" xml:base="http://josh.tools/Jiyu-A-Programming-Language/"><![CDATA[<p>Every so often, I am introduced to a new programming language or compiler project that, at the surface level, seems interesting, but leaves a lot, for me, to be desired. Several of these include relatively new, currently-used-in-production languages, such as Swift, where ideological constraints on the language design have made it difficult to write general purpose programs that exist outside the scope of the language’s primary, intended use. Additionally, I have some reservations about the language and compiler I work on professionally. I still yearn for something to meet my needs as a programmer. I still need to write programs that manually manage memory; I still need to write code that runs at CPU boot-time; I still need a lot of C++’s convenience.</p>

<p>Back in 2015, I had started a compiler project, called <a href="https://github.com/machinamentum/htn">htn</a>, with just the goal of being able to compile code, interact with C-code, and output to a handful of assembly-language targets, including 6502, 32-bit ARM, and 32-bit x86. I’ve since dropped the project due to other projects and my day-job at-the-time consuming much more of my free-time. I had been thinking about this project often over the years as I had enjoyed the work I was doing on it. Unfortunately, the code isn’t maintainable for me anymore, I have grown considerably as a programmer since and am unwilling to change substantial portions of the code just to get it to a point of maintainability. Doing so would require nearly starting over again; so I started over, again.</p>

<h2 id="jiyu">Jiyu</h2>

<p>This time around, I’ve built an LLVM-based compiler with an out-of-order compilation model not unlike any modern language created in the last 5 or so years. My initial goals are quite simple: implement an appealing syntax that reduces friction and enables ease of refactoring, have the ability to just drop the compiler and its dependencies into existing toolchains for cross-compiling, and be able to manipulate memory unencumbered. Fortunately for me, the former and latter-most issues have largely been solved by other projects in this space. I really, <em>really</em>, enjoy Swift’s syntax, but I despise its type system as the design of it makes writing code, that needs to read and write unmanaged memory, difficult. I also really like Jai’s type system; it is reminiscent of C’s, but with built-in array, and string, types, and less confusion. I’ve opted to adopt both these things, let’s look at some code:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="kd">@c_function</span> <span class="nf">printf</span><span class="p">(</span><span class="nv">fmt</span><span class="p">:</span> <span class="o">*</span><span class="n">uint8</span><span class="p">,</span> <span class="n">temporary_c_vararg</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span><span class="p">;</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="nf">cool_function</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
	<span class="nf">printf</span><span class="p">(</span><span class="err">“</span><span class="kt">Value</span> <span class="n">of</span> <span class="nv">b</span><span class="p">:</span> <span class="o">%</span><span class="n">f</span><span class="p">\</span><span class="n">n</span><span class="err">”</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">cool_function</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">float</span> <span class="p">{</span>
	<span class="k">return</span> <span class="n">a</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Most of the syntax here should be familiar to anyone who’s done even a light amount of Swift programming, with a few notable exceptions. The tag, <code class="language-plaintext highlighter-rouge">@c_function</code>, informs the compiler that we’re declaring a function that is external C-code, and to take care in calling this function correctly. <code class="language-plaintext highlighter-rouge">temporary_c_vararg</code> is fancy placeholder for the <code class="language-plaintext highlighter-rouge">...</code> syntax for a C-variable-argument function. Since strings are represented by a small struct containing the length of the string and a point to its data, we must dereference the data pointer before we can pass it to <code class="language-plaintext highlighter-rouge">printf</code>.</p>

<h2 id="user-types">User-types</h2>

<p>For user-types, the language currently supports type-aliasing and structs:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">typealias</span> <span class="n">c_string</span> <span class="o">=</span> <span class="o">*</span><span class="n">uint8</span><span class="p">;</span>

<span class="kd">func</span> <span class="kd">@c_function</span> <span class="nf">printf</span><span class="p">(</span><span class="nv">fmt</span><span class="p">:</span> <span class="n">c_string</span><span class="p">,</span> <span class="n">temporary_c_vararg</span><span class="p">);</span>

<span class="kd">typealias</span> <span class="kt">FILE</span> <span class="o">=</span> <span class="n">void</span><span class="p">;</span>
<span class="kd">func</span> <span class="kd">@c_function</span> <span class="nf">fopen</span><span class="p">(</span><span class="nv">path</span><span class="p">:</span> <span class="n">c_string</span><span class="p">,</span> <span class="nv">mode</span><span class="p">:</span> <span class="n">c_string</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="o">*</span><span class="kt">FILE</span><span class="p">;</span>
<span class="kd">func</span> <span class="kd">@c_function</span> <span class="nf">fclose</span><span class="p">(</span><span class="nv">file</span><span class="p">:</span> <span class="o">*</span><span class="kt">FILE</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int32</span><span class="p">;</span>

<span class="kd">struct</span> <span class="kt">Matrix</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">data</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span><span class="p">][</span><span class="mi">4</span><span class="p">]</span> <span class="n">float</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">identity_matrix</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Matrix</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">m</span><span class="p">:</span> <span class="kt">Matrix</span><span class="p">;</span>
	
	<span class="n">m</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="n">m</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="n">m</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="n">m</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	
	<span class="k">return</span> <span class="n">m</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Variables are zero-initialized by default in this language. There’s currently no way to declare an uninitialized variable, but that is on the list of things to do.
Structs may be populated by any other type of declaration, including functions. There’s currently no notion of member-functions, however, that’s another thing to come in the future.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Matrix</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">data</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span><span class="p">][</span><span class="mi">4</span><span class="p">]</span> <span class="n">float</span><span class="p">;</span>
	
	<span class="k">let</span> <span class="nv">SIZE</span> <span class="o">=</span> <span class="mi">16</span><span class="p">;</span>
	
	<span class="kd">func</span> <span class="nf">ortho</span><span class="p">(</span><span class="nv">left</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">right</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">top</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">bottom</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">near</span><span class="p">:</span> <span class="n">float</span><span class="p">,</span> <span class="nv">far</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Matrix</span> <span class="p">{</span>
		<span class="c1">// ...</span>
	<span class="p">}</span>
	
	<span class="kd">func</span> <span class="nf">identity</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Matrix</span> <span class="p">{</span>
		<span class="c1">// ...</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">matrix</span> <span class="o">=</span> <span class="kt">Matrix</span><span class="o">.</span><span class="nf">identity</span><span class="p">();</span>
	<span class="c1">// ...</span>
	<span class="k">var</span> <span class="nv">size</span> <span class="o">=</span> <span class="kt">Matrix</span><span class="o">.</span><span class="kt">SIZE</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="static-if">Static-if</h2>
<p>Another borrowed feature from Jai, is a scope-aware static-if:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="cp">#if os(MacOSX) {</span>
		<span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="cp">#if os(Windows) {</span>
		<span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
	<span class="p">}</span>
	<span class="n">b</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The usefulness of this is that whenever code in a disabled static-if block is changed, it is still being parsed, enabling syntax-specific errors to still fire. <code class="language-plaintext highlighter-rouge">os()</code> is a special construct that checks the input for a known operating-system name, then resolves to a Boolean literal if that operating system happens to be the target platform. This is not too dissimilar to how <code class="language-plaintext highlighter-rouge">sizeof()</code> works, except, in this case, “MacOSX” and “Windows” are special identifiers that <code class="language-plaintext highlighter-rouge">os()</code> recognizes. Due to the complexity of allowing arbitrary expressions in the <code class="language-plaintext highlighter-rouge">#if</code> condition, I’ve specifically disallowed arbitrary expressions. Only expressions that specifically fold or resolves to literal values may appear here; otherwise, even just allowing <code class="language-plaintext highlighter-rouge">let</code> constants in the condition causes a number of dependency issues relating to when that <code class="language-plaintext highlighter-rouge">let</code> exists in a scope that the <code class="language-plaintext highlighter-rouge">#if</code> can see. We cannot have <code class="language-plaintext highlighter-rouge">#if</code> depend on information that only exists after another <code class="language-plaintext highlighter-rouge">#if</code> or <code class="language-plaintext highlighter-rouge">#load</code> has resolved in order to maintain simplicity in the out-of-order compilation system.</p>

<h2 id="templates">Templates</h2>

<p>There’s currently limited support for function-templates. Struct-templates will will be on their way, eventually. Template declaration and resolution rules are similar to Swift’s: template argument names are declared between <code class="language-plaintext highlighter-rouge">&lt;</code> and <code class="language-plaintext highlighter-rouge">&gt;</code>, the type of the template arguments are deduced by arguments passed to the template function.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="nv">NEW_MEM_CHUNK_ELEMENT_COUNT</span> <span class="o">=</span> <span class="mi">16</span><span class="p">;</span>

<span class="kd">func</span> <span class="n">array_reserve</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">array</span><span class="p">:</span> <span class="o">*</span><span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">_amount</span><span class="p">:</span> <span class="n">int</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">amount</span> <span class="o">=</span> <span class="n">_amount</span><span class="p">;</span>
    <span class="k">if</span> <span class="n">amount</span> <span class="o">&lt;=</span> <span class="mi">0</span>
        <span class="n">amount</span> <span class="o">=</span> <span class="kt">NEW_MEM_CHUNK_ELEMENT_COUNT</span><span class="p">;</span>

    <span class="k">var</span> <span class="nv">new_mem</span> <span class="o">=</span> <span class="nf">cast</span><span class="p">(</span><span class="o">*</span><span class="kt">T</span><span class="p">)</span> <span class="nf">malloc</span><span class="p">(</span><span class="n">amount</span> <span class="o">*</span> <span class="nf">sizeof</span><span class="p">(</span><span class="kt">T</span><span class="p">));</span>

    <span class="k">if</span> <span class="n">array</span><span class="o">.</span><span class="n">data</span> <span class="o">!=</span> <span class="n">null</span> <span class="p">{</span>
        <span class="nf">memcpy</span><span class="p">(</span><span class="n">new_mem</span><span class="p">,</span> <span class="n">array</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="nf">cast</span><span class="p">(</span><span class="n">size_t</span><span class="p">)</span> <span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">count</span> <span class="o">*</span> <span class="nf">sizeof</span><span class="p">(</span><span class="kt">T</span><span class="p">))</span> <span class="p">);</span>
        <span class="nf">free</span><span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="n">array</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">new_mem</span><span class="p">;</span>
    <span class="n">array</span><span class="o">.</span><span class="n">allocated</span> <span class="o">=</span> <span class="n">amount</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="n">array_resize</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">array</span><span class="p">:</span> <span class="o">*</span><span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">_amount</span><span class="p">:</span> <span class="n">int</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">array_reserve</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="n">_amount</span><span class="p">);</span>
    <span class="n">array</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">_amount</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="n">array_add</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">array</span><span class="p">:</span> <span class="o">*</span><span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">,</span> <span class="nv">item</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">count</span><span class="o">+</span><span class="mi">1</span> <span class="o">&gt;=</span> <span class="n">array</span><span class="o">.</span><span class="n">allocated</span><span class="p">)</span> <span class="nf">array_reserve</span><span class="p">(</span><span class="n">array</span><span class="p">,</span> <span class="nf">cast</span><span class="p">(</span><span class="n">int</span><span class="p">)</span> 
    
    <span class="n">array</span><span class="o">.</span><span class="n">allocated</span> <span class="o">+</span> <span class="kt">NEW_MEM_CHUNK_ELEMENT_COUNT</span><span class="p">);</span>

    <span class="n">array</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">array</span><span class="o">.</span><span class="n">count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">(</span><span class="o">&lt;&lt;</span><span class="n">array</span><span class="p">)[</span><span class="n">array</span><span class="o">.</span><span class="n">count</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">item</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="n">array_reset</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nv">array</span><span class="p">:</span> <span class="o">*</span><span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">array</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="n">array</span><span class="o">.</span><span class="n">allocated</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

    <span class="k">if</span> <span class="n">array</span><span class="o">.</span><span class="n">data</span> <span class="o">!=</span> <span class="n">null</span> <span class="nf">free</span><span class="p">(</span><span class="n">array</span><span class="o">.</span><span class="n">data</span><span class="p">);</span>
    <span class="n">array</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">null</span><span class="p">;</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">data</span><span class="p">:</span> <span class="p">[</span><span class="o">..</span><span class="p">]</span> <span class="n">float</span><span class="p">;</span>
	
	<span class="nf">array_add</span><span class="p">(</span><span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">);</span>
	<span class="nf">array_add</span><span class="p">(</span><span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="mf">2.0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="compile-time-function-execution">Compile-Time Function Execution</h2>

<p>There’s rudimentary support for CTFE. One may run any program at compile-time by invoking the <code class="language-plaintext highlighter-rouge">-meta</code> flag on the command line: <code class="language-plaintext highlighter-rouge">jiyu -meta build.jyu</code>. Additionally, the <code class="language-plaintext highlighter-rouge">main</code> function may be marked by the tag <code class="language-plaintext highlighter-rouge">@metaprogram</code> to force the compiler to always run that program at compile-time. Just a small change to our first code example will cause the program to always be executed at compile-time:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="kd">@c_function</span> <span class="nf">printf</span><span class="p">(</span><span class="nv">fmt</span><span class="p">:</span> <span class="o">*</span><span class="n">uint8</span><span class="p">,</span> <span class="n">temporary_c_vararg</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">int</span><span class="p">;</span>

<span class="kd">func</span> <span class="kd">@metaprogram</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="k">var</span> <span class="nv">b</span> <span class="o">=</span> <span class="nf">cool_function</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
	<span class="nf">printf</span><span class="p">(</span><span class="err">“</span><span class="kt">Value</span> <span class="n">of</span> <span class="nv">b</span><span class="p">:</span> <span class="o">%</span><span class="n">f</span><span class="p">\</span><span class="n">n</span><span class="err">”</span><span class="o">.</span><span class="n">data</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">func</span> <span class="nf">cool_function</span><span class="p">(</span><span class="nv">a</span><span class="p">:</span> <span class="n">float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">float</span> <span class="p">{</span>
	<span class="k">return</span> <span class="n">a</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Compile-time code may also harness the compiler’s main driver functions to compile, or run, other code. I won’t delve too deeply into that, but here is a code sample:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#load "Compiler.jyu";</span>

<span class="kd">func</span> <span class="kd">@metaprogram</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">compiler</span> <span class="o">=</span> <span class="nf">create_compiler_instance</span><span class="p">();</span>
    <span class="n">compiler</span><span class="o">.</span><span class="n">executable_name</span> <span class="o">=</span> <span class="s">"run_tree/game"</span><span class="p">;</span>
    
    <span class="k">if</span> <span class="nf">compiler_load_file</span><span class="p">(</span><span class="n">compiler</span><span class="p">,</span> <span class="s">"src/main.jyu"</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_typecheck_program</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_generate_llvm_module</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_emit_object_file</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
    <span class="k">if</span> <span class="nf">compiler_run_default_link_command</span><span class="p">(</span><span class="n">compiler</span><span class="p">)</span> <span class="o">!=</span> <span class="kc">true</span> <span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="conclusion">Conclusion</h2>

<p>This has been a brief look at the language. There are still a number of small issues to tackle (like specifying libraries the code depended on; currently the compiler has the linker command baked-in), but I plan to fix these within the coming weeks. Please see the <a href="https://github.com/machinamentum/jiyu_game">jiyu_game</a> project for more in-depth use of the language.</p>

<p>The code for the compiler can be found at: <a href="https://github.com/machinamentum/jiyu">jiyu</a>.
Pull requests, feature requests, and issue reports are all welcome.</p>]]></content><author><name>Josh Huelsman</name></author><category term="compilers" /><category term="programming" /><summary type="html"><![CDATA[Every so often, I am introduced to a new programming language or compiler project that, at the surface level, seems interesting, but leaves a lot, for me, to be desired. Several of these include relatively new, currently-used-in-production languages, such as Swift, where ideological constraints on the language design have made it difficult to write general purpose programs that exist outside the scope of the language’s primary, intended use. Additionally, I have some reservations about the language and compiler I work on professionally. I still yearn for something to meet my needs as a programmer. I still need to write programs that manually manage memory; I still need to write code that runs at CPU boot-time; I still need a lot of C++’s convenience.]]></summary></entry><entry><title type="html">Proposition for a better OS</title><link href="http://josh.tools/Proposition-for-a-better-OS/" rel="alternate" type="text/html" title="Proposition for a better OS" /><published>2016-07-18T00:00:00+00:00</published><updated>2016-07-18T00:00:00+00:00</updated><id>http://josh.tools/Proposition-for-a-better-OS</id><content type="html" xml:base="http://josh.tools/Proposition-for-a-better-OS/"><![CDATA[<h2 id="introduction">Introduction</h2>
<p>Over the past few years I’ve been increasingly losing interest in interacting with major operating systems for my day-to-day needs. Major operating systems have become largely bloatware that is more intrusive to the user’s experience than it is useful. I will try to outline the surface features at this time. Features that are non-user facing (within the kernel, programming interface, etc..) will be outlined at a later time.</p>

<p>These are the basic philosophies for designing this new OS:</p>
<ol>
  <li>Operating systems should be designed to help the user get from point A to point B or perform task XYZ with as little friction as possible.</li>
  <li>A design choice should not compromise philosophy(1), or philosophy(2).</li>
  <li>The OS should be stripped of all bloatware.</li>
  <li>The OS should be as unintrusive to the user as possible.</li>
  <li>Upgrading the OS should improve the user’s experience, not degrade it.</li>
  <li>The OS should be as easy and as accessible as possible; it should support multiple points of interaction by default. Whether the user wants to use a keyboard and mouse, a touch screen, or even a gamepad, the OS should be agnostic to these common points of interaction and should provide a pleasant experience.</li>
</ol>

<h2 id="the-terminal">The Terminal</h2>
<p>Currently, command terminals support basic IO, command execution, and simple text rendering (coloring, italics, bold face, etc..). These aren’t bad features at all, this small feature set is what makes interacting with consoles still a pretty good experience. However, this limiting feature set induces poor implementation choices of software that uses the console as a primary user interface. A prime example of a such program is the GNU debugger. GDB is an otherwise good debugger, but it’s console-based user interface makes even the most trivial of debugging tasks impossible to efficiently get done. We could do better.</p>

<h4 id="bitmap-rendering">Bitmap rendering</h4>
<p>I first heard about this idea from Gary Bernhardt of Destroy All Software in his talk <a href="https://www.destroyallsoftware.com/talks/a-whole-new-world">A Whole New World</a>. Although Gary mentions a few interesting uses for terminal raster graphics, there’s much wider implications of what this feature would be capable of. This enables full-featured UI’s from within a terminal. A terminal app could render a webpage, draw game graphics, or display a powerpoint. Typically, a terminal app like (for example) <a href="http://gource.io/">gource</a> would have to open a separate window to draw its output. The user then has to exit the newly opened window the click back into the terminal. This is unneeded friction that does nothing but waste the user’s time.</p>

<h4 id="mouseagnostic-pointer-input">Mouse/agnostic pointer input</h4>
<p>Since we have to support philosophy(6). The terminal should be able to do more with a pointer device than just copy-paste. As a natural, harmonious progression with bitmap rendering, a terminal app should be able to capture basic pointer input like position and clicking/tapping.</p>

<h4 id="scripting-language">Scripting language</h4>
<p>The terminal should support a robust scripting language to allow the user to automate tasks or interact with the system. Although this is a current feature of most terminals, many terminal languages are designed to do most of their work in the form of executing other terminal programs. Scripts in this language should be native to the system; they should be able to work like any other program without having to invoke other terminal programs to perform a task.</p>

<h2 id="windowing-system">Windowing system</h2>
<p>Although the features proposed in <em>The Terminal</em> would make windowing obsolete, there’s still a major use for apps exclusively designed around a window system. The terminal is typically thought of as a power-user-y interface; it inherently requires a keyboard and a bit of learning to effectively use it. A windowing system still provides a smaller amount of friction than the terminal.</p>

<p>iOS and Window’s MetroUI are forward-thinking systems. They maximize simplicity while minimizing (or trying to) friction. A simple tile-based UI would be an ideal solution to support philosophy(6). It would allow the user to use a keyboard and mouse, a touch screen, a gamepad, or any other abstract input devices without any compromises. This could be further extended to allow navigating the entirety of the filesystem from this interface.</p>

<p>If well-executed, we could do away with desktop environments. Although they’re highly preferred now on desktop PC’s, I believe power-users will become accustomed to these low-friction systems.</p>

<h2 id="developer-tools">Developer Tools</h2>
<p>Developer tools for many OS’ tend to be bloated and not very user friendly. Although we can’t strictly avoid legacy toolchains, we can at least provide a better user-experience for developers as part of the OS ecosystem.</p>

<h4 id="debugger">Debugger</h4>
<p>One of the things Windows does right that Unix-based OS’ do wrong is that Windows provides debugging utilities as part of the kernel. Anyone wishing to implement a custom debugger can simply link against the kernel’s public interface library and can get language-agnostic debugging callbacks that any user program can easily interpret and manipulate. We can take this core idea of the debugger being a part of the OS a little further by having executable object parsing, op-code disassembling, and symbol information loading being shipped as part of the debugging API. User-built debuggers don’t have to rely on these OS provided utilities, but the advantage to having a standard API for these is that anyone trying to implement a reasonable debugger without large dependencies, can just depend on the OS provided libraries and they should just work.</p>

<h4 id="api-deprecation">API deprecation</h4>
<p>Some API designers tend to believe that deprecation is “mark for removal”. I don’t agree with this idea. A deprecated API should remain available as long as there is software to depend on it. If the API in question breaks one of the core philosophies, it may be justifiable to remove the API from the core OS, but it must still be accessible to any user who wishes to use it through some other means (such as a compatibility package).</p>

<h2 id="adoption">Adoption</h2>
<p>This will probably be the trickiest part to execute. If we look at Steam’s <a href="http://store.steampowered.com/hwsurvey">hardware survey</a> alone, Windows dominates the market at 95% of users. Although this is just based on gamers, I’m sure these numbers tip even more in favor of Windows for casual PC users and business users. I don’t believe Mac OSX is a real competitor in this space since the target for this OS would be PC users (where Mac OSX is solely designed for Mac devices). Although Linux is somewhat popular in the open source space, I don’t think it is a direct competitor. Adoption for Linux is still very small and still suffers from some of the problems I’ll outline below.</p>

<h4 id="gpu-drivers-and-games">GPU drivers and games</h4>
<p>This will be one of the most important aspects of the OS to get the gaming space to adopt. Unfortunately, the main issue here is a chicken and egg problem. In order to get GPU vendors to implement drivers for our OS we need to have a significant standing in the gaming space by having games and users. In order to have games and users, we need to have good driver support to get developers to even consider porting their games. Fortunately, we can still get the process started by implementing our own drivers for a subset of hardware (Intel’s integrated graphics for example have <a href="https://www.x.org/docs/intel/">open specifications</a>. Although this is less than ideal, this would be a step in the right direction.</p>

<h4 id="pre-installed-on-devices">Pre-installed on devices</h4>
<p>This would be a goal to reach much farther in development, but it is very important to get the OS established as software that is pre-installed on machines. This is one of the main aspects of Linux that causes its low adoption rate (although Ubuntu tried this for awhile and failed).</p>

<p>I’ll explain the importance of this with an analogy. When users purchase an Android device for example, most do not buy the device with the intention of side-loading a different flavor of Android. Most users purchase an Android phone and use the pre-installed version of Android because it is just there and there’s no friction involved in having to set it up. Likewise, if Android phones only shipped with vanilla versions of Android with the option of installing manufacturer versions, the install base for manufacturer-based versions (i.e., Samsung’s TouchWiz or HTC’s Sense) would be much lower, perhaps even near non-existent. To further expand on this thought, CyanogenMod (arguably the largest non-OEM Android version, which isn’t typically pre-installed to devices) claimed in <a href="https://www.instagram.com/p/6IUuRVNH_b/">August 2015 to have 50M+ users</a>. According to <a href="http://www.theverge.com/2015/8/20/9181269/gartner-q2-2015-smartphone-sales">The Verge</a>, Android phone sales had hit ~271M units <em>in just the quarter leading up to</em> August 2015. The number of Android devices with pre-installed versions far, <em>far</em> out weigh the number with custom OS versions installed.</p>]]></content><author><name>Josh Huelsman</name></author><category term="OS" /><summary type="html"><![CDATA[Introduction Over the past few years I’ve been increasingly losing interest in interacting with major operating systems for my day-to-day needs. Major operating systems have become largely bloatware that is more intrusive to the user’s experience than it is useful. I will try to outline the surface features at this time. Features that are non-user facing (within the kernel, programming interface, etc..) will be outlined at a later time.]]></summary></entry></feed>