Refactoring expr_binding_powerThe right-hand side of the let lhs = ... in expr_binding_power is getting quite long, so let’s extract it to its own function:// expr.rs use super::marker::CompletedMarker; use super::Parser; use crate::lexer::...
I’m not a fan of how, currently, all the submodules of crate::parser can access the internals of our parser. This access makes sense for marker.rs, but not for, say, expr.rs. These other modules should have to go through the parser’s API. W...
So far, our parser has only concerned itself with input that is correct. In a world of IDEs and language servers, however, the input to our parser will be wrong more often than not. Therefore, it is important that our parser can:recover gra...
The first thing we need to do is teach the lexer to recognise comments. We’ll begin with a test:// lexer.rs #[cfg(test)] mod tests { // snip #[test] fn lex_comment() { check("# foo", SyntaxKind::Comment); } } Here’s the implementation:pub(c...
A ‘marker’ is an abstraction over Rowan that makes working with it nicer, and also allows for some fancier parsing techniques. You can think of them as a fancy version of the checkpoints we’ve been using up to this point. Here’s a rough ske...
The simple but annoying approachWe could check for the presence of whitespace after every token:// do some stuff if p.peek() == Some(SyntaxKind::Whitespace) { p.bump(); } // do some more stuff It gets annoying to type that out each time, so...
In Part Nine I described the reasons for switching to Rowan and a lexer over the current lexerless parsing system we’ve developed in crate::utils. Read that before reading on here.Wiping the projectSadly, the moment has arrived. It’s time t...
We’ve got a number of topics to cover this time, so let’s get started.A bug fixu/mozjag pointed out on Reddit that the regex we’re using to lex identifiers mandates that they have a length of two, when we could also allow identifiers with a...
As we did last time, we need to choose a syntax, this time for function calls.// Rust syntax f(a, b, c); no_params(); Again, as I said in the previous part, parentheses and commas are annoying. Hence, Eldiro will use a different syntax in t...
First, we need to decide on a syntax. Let’s start with Rust’s syntax:fn frobnicate(foo: String, bar: String) -> Vec<Bar> { ... } Eldiro doesn’t have types (yet), so we need to remove those:1fn frobnicate(foo, bar) { ... } Parentheses and co...
In this part of the series we’ll start with the goal of allowing Exprs to be numbers. In case you’ve forgotten, at the moment Exprs have to be mathematical operations, making simple things like let x = 5 impossible.Let’s start by hopping ov...
After Part Four, the longest so far, this will be a relatively short post: we’ll be adding support for binding usages. Here’s the syntax we’re after:let a = 10 let b = a where a is a binding usage.ParsingLet’s begin with the parser. Add pub...
By the end of this post, Eldiro will have blocks. By block, I mean the Rust meaning, not one from any other programming language.1What is a block, anyway?In Rust (and Eldiro, once they are implemented), blocks are a way to group a bunch of...
In case you aren’t familiar with the concept, a read-eval-print-loop, or REPL, is a program that lets you interactively use a programming language. Here’s a hypothetical session with an Eldiro REPL:$ eldiro → 5 5 → 10 - 7 3 → let one = 1 →...
Welcome back! This time, we’ll parse and evaluate variable definitions.ParsingBefore we can begin writing a parser, we need to decide on a syntax. Since we like Rust, we’ll go for a similar syntax:let a = 5 To start off, Eldiro will only in...
Let’s create a new Rust project:$ cargo new --lib error: The following required arguments were not provided: <path> USAGE: cargo new <path> --lib For more information try --help Oh, yeah, we need a name. Hmmm. Let’s open the thesaurus and s...
The most fundamental part of any language is the parser1 – a piece of software whose purpose is to take a flat structure (usually text in some form) and convert it into a tree structure. In this post, we’ll make a parser for mathematical ex...
Last time, we made a parser for simple unnested mathematical expressions, such as 1+1 or 3*4. In this post, we’ll add support for whitespace (so that users of Eldiro will be able to use 2 + 2 instead of 2+2).We can achieve this by creating...