Up to this point, we've been using simple test databases where the data for each row fits within a single page. However, in the wild, it is quite common for a row to be larger than a single page (typically 4096 bytes), especially when using variable-...
The frontend part of our compiler is complete, and we can parse the source code of a pylite program into an AST. This leaves us with a final task: translating the program described by the AST into assembly code. Technically, we could generate assembl...
It has become common practice to start with a "Hello World" program when learning a new programming language. This is a simple program that outputs the text "Hello, World!" to the screen. While writing such a program is a trivial task with most prog...
Compilers are frustrating. Two decades ago, during a boring afternoon in my teenage room, I set out to discover how the software and games I spent so many hours with were made. I plunged into a Google Search rabbit hole that would yield a puzzling a...
In the previous posts, we've explored the SQLite file format and built a simple SQL parser. It's time to put these pieces together and implement a query evaluator! In this post, we'll lay the groundwork for evaluating SQL queries and build a query ev...
As we saw in the opening post, SQLite stores metadata about tables in a special "schema table" starting on page 1. We've been reading records from this table to list the tables in the current database, but before we can start evaluating SQL queries a...
After discovering the SQLite file format and implementing the .tables command in part 1 and part 2 of this series, we're ready to tackle the next big challenge: writing our own SQL parser from scratch. As the SQL dialect supported by SQLite is quite ...
In the previous post, we discovered the SQLite file format and implemented a toy version of the .tables command, allowing us to display the list of tables in a database. But our implementation has a jarring limitation: it assumes that all the data fi...
As developers, we use databases all the time. But how do they work? In this series, we'll try to answer that question by building our own SQLite-compatible database from scratch. Source code examples will be provided in Rust, but you are encouraged t...
In this episode, we'll extend our server to serve static files. We'll also refactor our code to support connection reuse, and implement a graceful shutdown mechanism. If your didn't follow the previous episode, you can find the code on GitHub. As we ...
Build a web server with Rust and tokio - Part 0: the simplest possible GET handler Welcome to this series of blog posts where we will be exploring how to build a web server from scratch using the Rust programming language. We will be taking a hands-o...
Creating a custom linter can be a great way to enforce coding standards and detect code smells. In this tutorial, we'll use Sylver, a source code query engine to build a custom Python linter in just a few lines of code. Sylver's main interface is a R...
Creating a custom linter can be a great way to enforce coding standards and detect code smells. In this tutorial, we'll use Sylver, a source code query engine to build a custom Javascript linter in just a few lines of code. Sylver's main interface is...
Creating a custom linter can be a great way to enforce coding standards and detect code smells. In this tutorial, we'll use Sylver's, a source code query engine to build a custom Golang linter in just a few lines of code. Sylver's main interface is a...
In Part1 and Part2 of the series, we learned how to build a language spec and how to use Sylver's query language to explore the parse tree of our JSON documents. While it can be insightful to explore a codebase interactively through source-code quer...
In Part 1, we used Sylver's meta language to build a specification for the JSON format. But an AST, by itself, is not of much use. In this next tutorial, we'll continue building our JSON configuration validator. To this end, we'll learn how to use Sy...
Sylver is a language agnostic platform for building custom source code analyzers (think eslint for every language). This might be a lot to unpack, so let us explore this tool by solving a real-world problem: our application's configuration is stored ...