← Back to all projects

Mao

Joke Language with Dynamically Changing Syntax Rules

Mao syntax failing

Sample of Mao getting mad at a changing syntax rule

Motivation

At my first internship, another intern on the team I was on taught me about this card game named Mao. The whole point of Mao is that you are not told any of the rules and instead are punished when you break one. At a team outing we were talking about implementing interpreters when I mentioned it would be funny to have a language like Mao - one with syntax rules that would change when you went to run the program, causing an infinite cycle of fixing syntax and breaking new syntax.

Fast forward to March of that year and I was finally getting comfortable making interpreters with recursive descent parsers. It was also conveniently close to April Fool's day, which made me realize I had an amazing opportunity: Make Mao a real language and prank my friends with it.

Implementation

Mao is implemented in Rust as a recursive descent parser with a unique twist: the syntax rules are dynamically generated based on a hash of the source code itself.

Core Architecture

The interpreter follows a traditional pipeline:

  1. Source Hashing: The interpreter computes a SHA256 hash of the source code (that excludes whitespace so you can't cheat) to create a deterministic seed
  2. Rule Generation: Using this seed, the interpreter generates random but consistent syntax rules for the current file
  3. Tokenizing: Using the generated rules, the tokenizer will properly tokenize the valid keywords for the rules, but also keep track of any identifiers that look like they belong to a different ruleset for "nice" error messages.
  4. Parsing: The parser enforces the dynamically generated grammar rules
  5. Execution: A simple treewalker executes the validated AST

Dynamic Syntax Generation

The syntax randomization covers:

Testing

Generating valid Mao is hard, very hard. Even harder as your file gets larger. As such, I created a brute forcing script to try all syntax combinations for a desired file, which fails most of the time as well.

After a lot of trial and error, a few working Mao scripts were eventually created, here is the longest valid Mao script in all it's beauty:


    if ( :( ) :
        console.log("If/Else statements are working :D");
    } then :
        console.log("It's False");
    }