angad basandrai
< back

/home/angad/blogs/word-turing-complete.md

Game of Life in MS Word

Abstract :O

Yes, MS Word can run almost any code. I hope to make, and see others make cool stuff inside it soon. The basics are, field codes are the processor, the rows of the data source are the clock, and memory is well, the memory. Of course it is very slow and there are quite a few things it cannot do. With that out of the way let's get into the full journey:

Why I ended up here

Ans: Minecraft

I was doomscrolling on YouTube when mattbatwings' videos showed up on my home page. As is my duty, I started watching them and decided to implement something similar in Minecraft, but digging more into it I realised there was nothing new for me to do. Everyone had done everything.

So second best thing, I decided to try Terraria, then I realised I absolutely do not enjoy playing Terraria (I said what I said). Then I looked into the OG SimCity (Micropolis). I thought maybe like the power grid could somehow be used like wires and I could use logic using capacity of the plants. But well firstly, every change to the map (fire, road etc.) is random and there is no memory or clock.

Tired I sort of gave up because my end-sem exams are looming. Decided to study, opened a file and started studying then got hit with a plan.

In search of gold, we found silver

The file I was studying from was a '.docx', jokingly I thought might as well try to see if Word could work. So I found Word has a small programming language inside it, Field Codes. SET sets a value, REF gets a value, IF is a conditional, and = is for mathematical operations. But you might be wondering that is not enough to run a computer.

How can we run it then?

Two words: Mail Merge

Vanilla Word is "great" for computation, but it cannot loop. It's just F9 and everything runs. Stuff ran through SET does stick around so we can just assume F9 to be one cycle of the clock. But of course it requires human input. In comes Mail Merge, it simulates F9 once for every row in the data source. So every row is a clock cycle, give it enough cycles and it is technically 'Turing Complete'.

Side note: I had no clue Mail Merge was even thing before today, I still don't know it's actual use.

But theory is great for theorists, I had to try it, so I wrote a very basic Python script to make Word files filled with loops and conditionals.

The good news first:

  • Values survive between rows, a SET in row 2 can see what row 1 stored. So, we have a clock.
  • Strings can grow forever, {SET s "{REF s}1"} just adds a character every row.
  • IF can do wildcards, and the pattern can be built while it runs. {IF "{REF L}" = "{REF P}1*" ...} basically asks "does L start with P and then a 1?". This ended up being the whole trick.

But some issues were clear:

  • We dont have variables, per se, I can't really use SET to update an existing field, 50 SET calls mean 50 memory cells. So, no arrays.
  • Numbers are just doubles, exact up to about 14 digits, so I can't hide infinite memory inside one giant number either.
  • There is no substring function. I can add to a string and check it against a pattern, but I can't take anything out of it. Thanks, Word.

How disappointing to find Word was not built to hold arrays, typical Microsoft.

Turing Machine?

A Turing machine is just a tape, a head that reads and writes one cell at a time, and a few rules. So I needed three things out of Word.

The tape: two strings, one for everything left of the head and one for everything right of it.

Reading: easy, a wildcard check. {IF "{REF R}" = "1*" ...} literally asks "does the right side start with a 1?".

Moving the head: this is where Word fought back. Moving means taking a character off one of the strings, and as we found out, Word can't take anything out of a string. So I rebuild it instead. Every row, Word copies one more character into a new string, and stops once the copy is exactly one character shorter. Painfully slow, but there's no limit on how far it can go, and that's all Turing completeness cares about.

To check it actually works, I ran busy beavers (tiny machines famous for running as long as possible before stopping) and compared every single step with a normal Python version. The 3-state one stopped after 14 steps with 6 ones on the tape, in 26 seconds. The 4-state one took 107 steps, left 13 ones and needed about 6 minutes. Both matched Python exactly so yay me.

Here's my small justification for why needing "enough" rows isn't "cheating". The rows are just the numbers 1, 2, 3 and so on, and nobody touches anything while it runs. It's a time limit, and every real computer has one of those too.

Yes this doesn't "prove" that it is indeed Turing Complete, but read more

Coding with Word

Next up, after I convinced (gaslit) myself into believing it's Turing Complete, I tried to run python.

What am I talking about you may be wondering, good question.

I wrote a small script that can take a limited subset of Python and convert it into the relevant Word code, and also builds the data file with the number of rows needed.

For example, a = b becomes { SET va { IF { REF pc } = 1 { = ({ REF vb }+0) \# 0 } { REF va } } }. Yes. You read that right.

Word runs fields top to bottom, so jumping forward happens in the same row, and jumping back (a loop) waits for the next row. One row is roughly one loop iteration.

It can run conditionals, loops, printing and even tuple assignment. What it cannot do is functions or lists.

And before you ask, it is PAINFULLY slow. A small printing with 2 conditions takes like 10 seconds. 25 Fibonacci numbers took a similar time.

BUT IT WORKS!

Word Apple?

Yes it can run Bad Apple.

The data file is the video: 1,314 frames at 6 fps, each shrunk to 32 by 24 black and white pixels. Every row of pixels is stored as two numbers, so one frame is one row of 48 numbers. The Word document is the player. It has one field per pixel (768 per frame) that pulls that pixel's bit out with MOD and INT and draws ██ or a blank. This is achieved with { IF { = MOD(INT({ MERGEFIELD r5a }/1024),2) } = 1 "██" " " }. Dont even joke about it, lad.

Every frame = 1 page. Oh and TIL: according to word INT(4294967294/2) = -1. VERY Logical.

Each frame took me about 3 seconds to render. The whole song about 75 minutes. But now was the real problem.

Word Media Player?

I'll be honest, I don't know how to do it, except:
A) holding PageDown and zooming past pages to see a flipbook style animation.
B) exporting the frames to a PDF, stitch to a GIF and see that.

So yes, disappointing and anti-climactic, I know, but that's life.

Conway's Game of Word

Since Bad Apple can't actually "play", I decided to make something that does actually "play" inside Word.

The Board: each cell is a bookmark, C_4_5 and so on. The board wraps around the edges.

Update: The whole update is only single formula {= ABS(2*S+c-6)<=1}. Hey, no one said Word Code is clean and understandable.

The Clock: Ctrl+A, then F9. That's the whole clock. Word recalculates every field once, top to bottom, and anything stored with SET sticks around, so the board from the last press is the input for the next one. One press, one generation.

Custom Boards: Under the board there's a grid of . and #, each row a plain bookmark you can type over. Every press, Word reads it with wildcards ({IF "{REF p_3}" = "|????#*" 1 0} means "is the 5th cell a #?") and compares it with what it saw last press. If you changed anything, the board loads your drawing instead of stepping. The | on each end keep your typing inside the bookmark.

Quill

Earlier I was using python code, but that made me have to think what can and can't work in Word. So meet Quill

let n = arg(1)
let a = 0
let b = 1
while n > 0 {
    print a
    let t = a + b
    a = b
    b = t
    n -= 1
}

Whole numbers, if, while, print and command line arguments. No functions or arrays, because Word can't do those either. The compiler is one 520 KB Rust exe, and quill run fib.ql 10 opens Word in the background, runs the merge and prints the answer. It even has proper error messages, and catches anything Word would choke on before Word ever opens.

Do they know?

I looked everywhere I could: gwern's list of surprisingly Turing-complete things, the "Accidentally Turing-Complete" list, SIGBOVIK, esolangs, GitHub, and the Word expert forums. People have done PowerPoint, Excel formulas and even Jira. For Word, the only thing I found is a lone Hacker News comment saying "Word itself is turing complete", with nothing to back it up. So I am reasonably confident people haven't looked into this deep enough...

Sources

quill