Runelang: A Summoning Circle Generator

Last time we had Runelang: A Bind Rune Generator. This time, let’s make ‘summoning circles’. Basically, we want to make a circle with stars and other circles inscribed and around the borders with various ‘mystic’ text in the mix. Something like this:

  • generate_summoning_circle
    • random chance of boder
    • random chance of one or more inscribed stars
    • random chance of recurring on the border (calling generate_summoning_circle again)
    • random chance of recurring in the middle

read more...


Runelang: A Bind Rune Generator

Continuing with my Runelang in the Browser series, I had the idea to automatically generate runes. So basically reversing the parsing step, rather than to take what I’ve written and make it look good, to write something that Runelang can parse–and still look good.

In a nutshell, I want to write a series of functions that can recursively call one another to render runes:

  • generate_bind_rune
    • n times generate_bind_rune_arm
      • m times generate bars, circles, and other decrations
      • add a fork at the end

read more...


Runelang: Evaluation

As they say, life is what happens when you’re making other plans. But I’m back, so let’s talk some more about Runelang. In the interest of not dragging on months without finishing, we’re going to go ahead and push through the rest of the project. Onward!

read more...


Runelang: The Parser (Part 2: Expressions)

Earlier this week, we started parsing, getting through groups, nodes, params, and lists. A pretty good start, but it also leaves out two very powerful things (expressions and defines), one of which we absolutely do need to start actually evaluating things: expressions. Since we use them in every param, we pretty much need to know how to parse them, so let’s do it!

read more...


Runelang: The Parser (Part 1)

I’m still here! And less sick now.

Last time(s), we described and lexed) Runelang! This time around, let’s take the lexed tokens and go one step further and parse them!

So, how do we go about this? With a recursive descent parser!

  • Start with a list/stream of tokens
  • Using the first k (in a LL(k) parser) elements of the list, identify which sort of object we are parsing (a group / identifier / literal / expression / etc)
  • Call a parsing function for that object type (parseGroup etc) that will:
    • Recursively parse the given object type (this may in turn call more parse functions)
    • Advance the token stream ‘consuming’ any tokens used in this group so the new ‘first’ element is the next object

read more...


Runelang: The Lexer

Let’s LEX!

So this is actually one of the easier parts of a programming language. In this case, we need to turn the raw text of a program into a sequence of tokens / lexemes that will be easier to parse. In this case, we want to:

  • Remove all whitespace and comments
  • Store the row and column with the token to make debugging easier

So let’s do it!

read more...


Runelang: Language Specification

Previously, I wrote a post about making a DSL in Ruby that could render magic circles/runes. It worked pretty well. I could turn things like this:

rune do
    scale 0.9 do 
        circle
        polygon 7
        star 14, 3
        star 7, 2
        children 7, scale: 1/8r, offset: 1 do |i|
            circle
            invert do
                text (0x2641 + i).chr Encoding::UTF_8
            end
        end
    end
    scale 0.15 do
        translate x: -2 do circle; moon 0.45 end
        circle
        translate x: 2 do circle; moon 0.55 end
    end
end

Into this:

But… I decided to completely rewrite it. Now it’s an entirely separate language:

Output

Source

Log (most recent messages first):

    read more...


    AoC 2021 Day 25: Cucumbinator

    Source: Sea Cucumber

    Part 1: Load a grid of empty cells (.), east movers (>), and south movers (v). Each step, move all east movers than all south movers (only if they can this iteration). Wrap east/west and north/south. How many steps does it take the movers to get stuck?

    read more...


    AoC 2021 Day 11: Octopus Flashinator

    Source: Dumbo Octopus

    Part 1: Simulate a grid of numbers such that on each tick: advance all numbers by 1, any number that increases over 9 will ‘flash’ and add 1 to all neighbors (recursively, but each cell can only flash once) and then reset to 0. Count the number of flashes in the first 100 ticks.

    read more...