Hone logo
Hone
Problems

Implementing a Simplified Mid-level Intermediate Representation (MIR) in Rust

Compilers often use a Mid-level Intermediate Representation (MIR) to decouple the front-end (parsing and semantic analysis) from the back-end (code generation). This challenge asks you to implement a simplified version of MIR in Rust, focusing on representing basic control flow and arithmetic operations. Building a MIR allows for easier optimization and target-independent code generation.

Problem Description

You are tasked with creating a data structure and associated functions to represent a simplified MIR. This MIR will consist of a series of statements, each representing a basic operation or control flow construct. The supported statement types are:

  • Assign: Assign { target: String, value: MIRValue } - Assigns a value to a variable.
  • BinOp: BinOp { target: String, op: BinaryOperator, left: MIRValue, right: MIRValue } - Performs a binary operation (addition, subtraction, multiplication) and assigns the result to a variable.
  • If: If { condition: MIRValue, then_statements: Vec<MIRStatement>, else_statements: Vec<MIRStatement> } - Conditional execution.
  • Return: Return { value: Option<MIRValue> } - Returns a value from a function. None indicates a void return.

MIRValue can be either a constant integer (MIRInteger(i32)) or a variable name (MIRVariable(String)).

BinaryOperator is an enum with the following variants: Add, Sub, Mul.

Your implementation should include:

  1. Data Structures: Define the MIRStatement, MIRValue, and BinaryOperator enums/structs as described above.
  2. print_mir function: A function that takes a Vec<MIRStatement> (a sequence of MIR statements) as input and prints a human-readable representation of the MIR to the console. The printing format should be clear and easy to understand. Each statement should be on a new line.
  3. build_mir function: A function that takes a vector of strings representing a simple program and returns a Vec<MIRStatement> representing the MIR. This function is a simplified parser and should handle a very limited subset of instructions. Assume the input strings are already validated and well-formed. The input strings will be in the following format:
    • x = 10 (Assign)
    • y = x + 5 (BinOp)
    • z = x - y (BinOp)
    • if x > 5 then { ... } else { ... } (If - not implemented in build_mir - just ignore)
    • return x (Return)

Examples

Example 1:

Input: ["x = 10", "y = x + 5", "return y"]
Output:
x = 10
y = x + 5
return y
Explanation: The input strings are parsed and converted into MIR statements, which are then printed to the console.

Example 2:

Input: ["a = 1", "b = 2", "c = a * b", "return c"]
Output:
a = 1
b = 2
c = a * b
return c
Explanation:  A simple sequence of assignments and a return statement.

Example 3: (Edge Case - Empty Program)

Input: []
Output:
(Empty output - nothing to print)
Explanation:  Handles the case where the input vector is empty.

Constraints

  • The MIRValue only supports MIRInteger(i32) and MIRVariable(String).
  • The BinaryOperator only supports Add, Sub, and Mul.
  • The build_mir function should only handle the assignment, binary operation, and return statements as described above. If statements should be ignored.
  • Variable names are assumed to be valid Rust identifiers (alphanumeric characters and underscores, starting with a letter or underscore).
  • Input strings in build_mir are guaranteed to be well-formed and follow the specified format. No error handling for invalid input is required.
  • The print_mir function should produce a clear and readable output.

Notes

  • Focus on the core data structures and the print_mir function. The build_mir function is a simplified parser and doesn't need to be robust.
  • Consider using Rust's enum and struct features to represent the MIR components effectively.
  • The print_mir function is the primary way to verify your implementation. Ensure the output is correct and easy to understand.
  • This is a simplified MIR. Real-world MIRs are significantly more complex. This exercise aims to provide a basic understanding of the concept.
  • Error handling and more sophisticated parsing are beyond the scope of this challenge.
Loading editor...
rust