<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yassine Jemi</title>
    <description>The latest articles on DEV Community by Yassine Jemi (@yassine_jemi_01).</description>
    <link>https://dev.to/yassine_jemi_01</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4223061%2F086f14bf-7e56-4c59-8401-be0f898ee6d2.jpg</url>
      <title>DEV Community: Yassine Jemi</title>
      <link>https://dev.to/yassine_jemi_01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yassine_jemi_01"/>
    <language>en</language>
    <item>
      <title>I Built My Own Compiled Programming Language. Here's What I Learned.</title>
      <dc:creator>Yassine Jemi</dc:creator>
      <pubDate>Mon, 02 Nov 2026 20:34:28 +0000</pubDate>
      <link>https://dev.to/yassine_jemi_01/i-built-my-own-compiled-programming-language-heres-what-i-learned-8hn</link>
      <guid>https://dev.to/yassine_jemi_01/i-built-my-own-compiled-programming-language-heres-what-i-learned-8hn</guid>
      <description>&lt;p&gt;Most developers use programming languages.&lt;/p&gt;

&lt;p&gt;Some build applications with Python. Others use Rust, C, Go, or Java.&lt;/p&gt;

&lt;p&gt;But at some point, I became interested in a different question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does it actually take to build a programming language?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of just learning how existing languages work, I decided to build one myself.&lt;/p&gt;

&lt;p&gt;That project became &lt;strong&gt;YLang&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Today, YLang is an open-source compiled programming language with its own compiler, documentation, development tools, and an evolving ecosystem.&lt;/p&gt;

&lt;p&gt;This is the story of the project and what I have learned while developing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why build another programming language?
&lt;/h2&gt;

&lt;p&gt;There are already hundreds of programming languages.&lt;/p&gt;

&lt;p&gt;C is powerful. Rust focuses on memory safety. Go emphasizes simplicity and practical software development. Python makes many programming tasks accessible.&lt;/p&gt;

&lt;p&gt;So why create another one?&lt;/p&gt;

&lt;p&gt;I wanted to explore language design while building something with a few specific goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Readable and explicit syntax.&lt;/li&gt;
&lt;li&gt;Static typing.&lt;/li&gt;
&lt;li&gt;Native executable output.&lt;/li&gt;
&lt;li&gt;A compiler that provides useful diagnostics.&lt;/li&gt;
&lt;li&gt;A foundation for desktop applications and general-purpose software.&lt;/li&gt;
&lt;li&gt;A language that can evolve without hiding its technical limitations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want to create a language that was different just for the sake of being different.&lt;/p&gt;

&lt;p&gt;I wanted to understand what goes into building a real compiler.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the compiler
&lt;/h2&gt;

&lt;p&gt;One of the biggest lessons was that a programming language is much more than its syntax.&lt;/p&gt;

&lt;p&gt;A compiler needs several components working together.&lt;/p&gt;

&lt;p&gt;YLang's compiler is written in C17.&lt;/p&gt;

&lt;p&gt;Its established compilation pipeline looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YLang source (.yl)
        |
        v
      Lexer
        |
        v
      Parser
        |
        v
       AST
        |
        v
Semantic Analysis
        |
        v
    C Codegen
        |
        v
    GCC / Clang
        |
        v
 Native executable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each stage has a different responsibility.&lt;/p&gt;

&lt;p&gt;The lexer converts source text into tokens.&lt;/p&gt;

&lt;p&gt;The parser builds an abstract syntax tree.&lt;/p&gt;

&lt;p&gt;Semantic analysis checks types, names, initialization, and other language rules.&lt;/p&gt;

&lt;p&gt;Finally, the compiler generates C code and invokes GCC or Clang to produce a native executable.&lt;/p&gt;

&lt;p&gt;Building this pipeline taught me that accepting valid syntax is the easy part.&lt;/p&gt;

&lt;p&gt;Making sure that accepted programs actually behave correctly is much harder.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does YLang look like?
&lt;/h2&gt;

&lt;p&gt;Here is a small example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let const int MAX = 100;
let int count = 0;

function add(int a, int b) -&amp;gt; int {
    return a + b;
}

function main() -&amp;gt; int {
    let string language = "YLang";

    print("Welcome to", language);
    print("Sum:", add(10, 20));

    loop() {
        count = count + 1;

        if (count &amp;gt;= 3) {
            break;
        }
    }

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The language uses explicit types and structured control flow.&lt;/p&gt;

&lt;p&gt;It also has arrays, functions, string utilities, file operations, numeric conversions, and runtime checks for certain unsafe arithmetic operations.&lt;/p&gt;

&lt;p&gt;The goal is to make programs understandable while keeping the compiler responsible for checking important language rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond basic syntax
&lt;/h2&gt;

&lt;p&gt;As the project grew, I started experimenting with more advanced features.&lt;/p&gt;

&lt;p&gt;Some examples include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structs and enums&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;YLang supports experimental value-oriented structures and typed enums with matching.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Programs can import named functions and global variables from other source files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NASM backend&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is an experimental Linux x86-64 backend that can generate NASM assembly for a restricted subset of the language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GUI and Game2D&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;YLang has optional SDL2-backed functionality for basic graphical applications and 2D development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTTP and API requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The stable 2.2 release includes HTTP requests through libcurl, response inspection, and an initial asynchronous HTTP-task API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An initial native debugging workflow uses GDB on Linux and LLDB on macOS.&lt;/p&gt;

&lt;p&gt;These features have different maturity levels. Some are experimental and are not covered by the stable core compatibility guarantee.&lt;/p&gt;

&lt;p&gt;I consider documenting those limitations just as important as documenting what works.&lt;/p&gt;

&lt;h2&gt;
  
  
  One of the hardest problems: Memory ownership
&lt;/h2&gt;

&lt;p&gt;At some point, I realized that building more language features was not enough.&lt;/p&gt;

&lt;p&gt;Memory management needed more attention.&lt;/p&gt;

&lt;p&gt;A programming language must have clear rules about who owns allocated memory and when that memory should be released.&lt;/p&gt;

&lt;p&gt;Consider a use-after-free problem.&lt;/p&gt;

&lt;p&gt;A value is allocated, its memory is released, and another part of the program continues using it.&lt;/p&gt;

&lt;p&gt;That can lead to crashes, corrupted data, or security problems.&lt;/p&gt;

&lt;p&gt;This led to work on experimental ownership features in YLang.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let owned_string source = string.own("YLang");
let owned_string destination = move(source);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is that ownership is transferred rather than silently copied.&lt;/p&gt;

&lt;p&gt;The original binding becomes unavailable until it is properly reinitialized.&lt;/p&gt;

&lt;p&gt;There is also an experimental &lt;code&gt;borrowed_string&lt;/code&gt; type for restricted immutable function parameters.&lt;/p&gt;

&lt;p&gt;However, this is not a complete Rust-style borrow checker.&lt;/p&gt;

&lt;p&gt;General &lt;code&gt;&amp;amp;T&lt;/code&gt; and &lt;code&gt;&amp;amp;mut T&lt;/code&gt; support, comprehensive lifetime analysis, and general alias checking are still development goals.&lt;/p&gt;

&lt;p&gt;I would rather document these limitations honestly than claim memory safety that the compiler cannot guarantee.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why YLang 3.0 is a major step
&lt;/h2&gt;

&lt;p&gt;The current development branch is focused on changing the compiler's internal architecture.&lt;/p&gt;

&lt;p&gt;One of the biggest changes is introducing a typed, backend-neutral intermediate representation.&lt;/p&gt;

&lt;p&gt;The intended direction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;         YLang Source
               |
               v
          Parser / AST
               |
               v
          Typed IR
               |
        +------+------+
        |      |      |
        v      v      v
        C    LLVM   NASM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is to avoid tying the entire compiler to one code-generation backend.&lt;/p&gt;

&lt;p&gt;The project now has an IR verifier, AST-to-IR lowering, an initial IR-to-C emitter, and several scalar optimization passes.&lt;/p&gt;

&lt;p&gt;The old AST-to-C path is being retained as a reference while the new pipeline is tested.&lt;/p&gt;

&lt;p&gt;This makes it possible to compare generated programs and check whether the new pipeline preserves observable behavior.&lt;/p&gt;

&lt;p&gt;LLVM and the expanded NASM backend are development goals, not completed features.&lt;/p&gt;

&lt;p&gt;YLang 3.0 is not a stable release.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned from building a programming language
&lt;/h2&gt;

&lt;p&gt;The biggest lessons were not about syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Compiler correctness is more important than adding features.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A language with fewer features that work correctly is more useful than one with many features that behave unpredictably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Memory management is difficult.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ownership and borrowing affect the parser, semantic analysis, control flow, code generation, and runtime behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Testing is part of compiler development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A successful compilation does not prove that the generated executable is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Architecture matters.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A simple design can be enough at the beginning, but growing a compiler requires clear boundaries between its components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Documentation is part of the language.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A programming language is difficult to use when its behavior and limitations are not documented.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where is YLang today?
&lt;/h2&gt;

&lt;p&gt;YLang 2.2.0 is the latest stable release.&lt;/p&gt;

&lt;p&gt;The 3.0 development branch is actively evolving and focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compiler architecture.&lt;/li&gt;
&lt;li&gt;Typed intermediate representation.&lt;/li&gt;
&lt;li&gt;IR verification and optimization.&lt;/li&gt;
&lt;li&gt;Ownership and borrowing.&lt;/li&gt;
&lt;li&gt;Backend development.&lt;/li&gt;
&lt;li&gt;Cross-platform support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is open source, and development continues in the public repository.&lt;/p&gt;

&lt;p&gt;I am not claiming that YLang is better than Rust, C++, Go, or Python.&lt;/p&gt;

&lt;p&gt;It is an independent project with its own goals, limitations, and engineering challenges.&lt;/p&gt;

&lt;p&gt;There is still a lot to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try YLang
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Yassine-Jemi01/ylang" rel="noopener noreferrer"&gt;https://github.com/Yassine-Jemi01/ylang&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Official website: &lt;a href="https://yassine-jemi01.github.io/ylang/index.html" rel="noopener noreferrer"&gt;https://yassine-jemi01.github.io/ylang/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The YLang Book: &lt;a href="https://yassine-jemi01.github.io/ylang/learn/index.html" rel="noopener noreferrer"&gt;https://yassine-jemi01.github.io/ylang/learn/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contributions, technical feedback, bug reports, and discussions are welcome.&lt;/p&gt;

&lt;p&gt;If you have experience with compiler design, intermediate representations, memory safety, or language implementation, I would especially appreciate your perspective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building a programming language is a much bigger challenge than I initially expected. And that is exactly what makes this project interesting.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>programming</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
