Intermediate Representation (IR) Design
Purpose
The ARES Intermediate Representation (IR) is a bridging layer. It sits between your high-level code and the final program the system writes. It takes the complex tree of your logic and turns it into a simple, linear list of instructions. This is a critical step because it allows the system to optimize your code without needing to know which language it will eventually run in.
Why it exists
Directly translating a complex tree into C++ or Python is difficult and can lead to messy code. The IR exists to simplify the problem. By turning everything into a universal list of steps, the system can perform math optimizations, remove unused parts of the code, and handle complex logic like "if" statements and "loops" in a consistent way. It provides a single source of truth for the logic of your program.
How it works
The IR uses a system called Three-Address Code. This means every instruction is very simple, usually involving only two inputs and one output.
- Flattening expressions. A complex math step like
a + b * cis broken into two simple steps: first calculateb * c, then addato the result. - Using temporary bins. The system uses an infinite number of virtual bins (called "registers") like
t0andt1to store the results of these small steps. - Naming locations. For loops and skips, the system uses "labels" to mark specific lines in the code. It can then tell the computer to jump to a specific label based on a condition.
- Universal commands. Standard commands like
READ,PRINT, andJUMPare used so that the logic remains the same regardless of the final language.
Intuition
Think of the IR like a set of simplified instructions for building furniture from a complex blueprint. The blueprint shows the finished product (the Tree), but the instructions tell you exactly which two pieces to join first, where to put the next screw, and which step to skip if you already have a part assembled. The instructions are written in a simple way that anyone can follow, no matter what tools they are using.
Implementation details
The logic for creating the IR is in src/ir/lowering.ts. It goes through every part of your code tree and emits these simple instructions.
- Binary Operations: Math like addition or multiplication is turned into a
BINARY_OPinstruction. - Decisions: An
ifstatement is turned into aJUMP_IF_FALSEinstruction that points to a specific label.
Trace example
This is what happens when the system processes if x > 0 { print x }:
- Calculate if
x > 0and store the result int0. - JUMP to a label called
L0ift0is false. - Execute the PRINT command for
x. - LABEL L0: This is the point the system jumps to if the condition was false, skipping the print command.
Related Entities
03_optimizer.md: Explains how the system makes this list of instructions even faster.src/ir/lowering.ts: The actual code that generates this representation.