Skip to main content

IRx

Project description

IRx

IRx is a Python library that lowers ARXLang ASTx nodes to LLVM IR using llvmlite. It provides a visitor-based codegen pipeline and a small builder API that can translate ASTs to LLVM IR text or produce runnable executables via clang.

Status: early but functional. Arithmetic, variables, functions, returns, basic control flow, and a few system-level expressions (e.g. PrintExpr) are supported.

Features

  • ASTx → LLVM IR via multiple-dispatch visitors (plum).

  • Back end: IR construction and object emission with llvmlite.

  • Native build: links with clang to produce an executable.

  • PIE-friendly objects: emits PIC-compatible objects by default to work with modern PIE-default linkers.

  • Supported nodes (subset; exact ASTx class names):

    • Literals: LiteralInt16, LiteralInt32, LiteralString
    • Variables: Variable, VariableDeclaration, InlineVariableDeclaration
    • Ops: UnaryOp (++, --), BinaryOp (+ - * / < >) with simple type promotion
    • Flow: IfStmt, ForCountLoopStmt, ForRangeLoopStmt
    • Functions: FunctionPrototype, Function, FunctionReturn, FunctionCall
    • System: system.PrintExpr (string printing)
  • Built-ins: putchar, putchard (emitted as IR); puts declaration when needed.

Quick Start

Requirements

  • Python 3.10 – 3.13.
  • A recent LLVM/Clang toolchain available on PATH.
  • A working C standard library (e.g., system libc) for linking calls like puts.
  • Python deps: llvmlite, pytest, etc. (see pyproject.toml / requirements.txt).
    • Note: llvmlite has specific Python/LLVM compatibility windows; see its docs.

Install (dev)

git clone https://github.com/arxlang/irx.git
cd irx
conda env create --file conda/dev.yaml
conda activate irx
poetry install

You can also install it from PyPI: pip install pyirx.

More details: https://irx.arxlang.org/installation/

Minimal Examples

1) Translate to LLVM IR (no linking)

import astx
from irx.builders.llvmliteir import LLVMLiteIR

builder = LLVMLiteIR()
module = builder.module()

# int main() { return 0; }
proto = astx.FunctionPrototype("main", astx.Arguments(), astx.Int32())
body = astx.Block()
body.append(astx.FunctionReturn(astx.LiteralInt32(0)))
module.block.append(astx.Function(prototype=proto, body=body))

ir_text = builder.translate(module)
print(ir_text)  # LLVM IR text (str)

translate returns a str with LLVM IR. It does not produce an object file or binary; use it for inspection, tests, or feeding another tool.

2) Build and run a tiny program that prints and returns 0

import astx
from irx.builders.llvmliteir import LLVMLiteIR
from irx.system import PrintExpr

builder = LLVMLiteIR()
module = builder.module()

# int main() { print("Hello, IRx!"); return 0; }
main_proto = astx.FunctionPrototype("main", astx.Arguments(), astx.Int32())
body = astx.Block()
body.append(PrintExpr(astx.LiteralString("Hello, IRx!")))
body.append(astx.FunctionReturn(astx.LiteralInt32(0)))
module.block.append(astx.Function(prototype=main_proto, body=body))

builder.build(module, "hello")  # emits object + links with clang
builder.run()                   # executes ./hello (or hello.exe on Windows)

How It Works

Builders & Visitors

  • LLVMLiteIR (public API)

    • translate(ast) -> str — generate LLVM IR text.
    • build(ast, output_path) — emit object via llvmlite and link with clang.
    • run() — execute the produced binary.
  • LLVMLiteIRVisitor (codegen)

    • Uses @dispatch to visit each ASTx node type.
    • Maintains a value stack (result_stack) and symbol table (named_values).
    • Emits LLVM IR with llvmlite.ir.IRBuilder.

System Printing

PrintExpr is an astx.Expr holding a LiteralString. Its lowering:

  1. Create a global constant for the string (with \0).
  2. GEP to an i8* pointer.
  3. Declare (or reuse) i32 @puts(i8*).
  4. Call puts.

Testing

pytest -vv

Example style (simplified):

def test_binary_op_basic():
    builder = LLVMLiteIR()
    module = builder.module()

    decl_a = astx.VariableDeclaration("a", astx.Int32(), astx.LiteralInt32(1))
    decl_b = astx.VariableDeclaration("b", astx.Int32(), astx.LiteralInt32(2))

    a, b = astx.Variable("a"), astx.Variable("b")
    expr = astx.LiteralInt32(1) + b - a * b / a

    proto = astx.FunctionPrototype("main", astx.Arguments(), astx.Int32())
    block = astx.Block()
    block.append(decl_a); block.append(decl_b)
    block.append(astx.FunctionReturn(expr))
    module.block.append(astx.Function(proto, block))

    ir_text = builder.translate(module)
    assert "add" in ir_text

Troubleshooting

macOS: ld: library 'System' not found

  • Ensure Xcode Command Line Tools are installed: xcode-select --install.

  • Verify clang --version works.

  • If needed:

    export SDKROOT="$(xcrun --sdk macosx --show-sdk-path)"
    
  • CI note: macOS jobs currently run on Python 3.12 only.

Non-zero exit when function returns void

  • Define main to return Int32 and emit return 0. Falling off the end or returning void can yield an arbitrary exit code.

plum.resolver.NotFoundLookupError

  • A visitor is missing @dispatch or is typed against a different class than the one instantiated. Ensure signatures match the exact runtime class (e.g., visit(self, node: PrintExpr)).

Linker or clang not found

  • Install a recent LLVM/Clang. On Linux, use distro packages.
  • On macOS, install Xcode CLT.
  • On Windows, ensure LLVM’s bin directory is on PATH.

PIE mismatch (R_X86_64_32 ... can not be used when making a PIE object)

  • This usually means your linker is enforcing PIE while the object was compiled with non-PIE relocations.

  • Current IRx defaults to PIC-compatible object emission, which should work with PIE-default linkers.

  • If you are using an older ARX/IRX stack, update first.

  • If you must link externally as a workaround, use:

    clang -no-pie file.o -o program
    

Platform Notes

  • Linux & macOS: supported and used in CI.
  • Windows: expected to work with a proper LLVM/Clang setup; consider it experimental. builder.run() will execute hello.exe.

Roadmap

  • More ASTx coverage (booleans, arrays, structs, varargs/options).
  • Richer stdlib bindings (I/O, math).
  • Optimization toggles/passes.
  • Alternative backends and/or JIT runner.
  • Better diagnostics and source locations in IR.
  • Integration with Apache Arrow.

Contributing

Please see the contributing guide. Add tests for new features and keep visitors isolated (avoid special-casing derived nodes inside generic visitors).

Acknowledgments

  • LLVM and llvmlite for the IR infrastructure.
  • ASTx / ARXLang for the front-end AST.
  • Contributors and users experimenting with IRx.

License

License: BSD-3-Clause. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyirx-1.8.0.tar.gz (28.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyirx-1.8.0-py3-none-any.whl (26.9 kB view details)

Uploaded Python 3

File details

Details for the file pyirx-1.8.0.tar.gz.

File metadata

  • Download URL: pyirx-1.8.0.tar.gz
  • Upload date:
  • Size: 28.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.1 CPython/3.10.20 Linux/6.14.0-1017-azure

File hashes

Hashes for pyirx-1.8.0.tar.gz
Algorithm Hash digest
SHA256 9956584c3f3bc49c9e8ccb6e7991aa3686df78ae4cc1b2f228ed9f516929f95d
MD5 2d66fa42cd64103d5a08f920a02a4646
BLAKE2b-256 19b2be158d10bd8402562f49cd552e5945ee53c1e07911326b1c851ea49a756c

See more details on using hashes here.

File details

Details for the file pyirx-1.8.0-py3-none-any.whl.

File metadata

  • Download URL: pyirx-1.8.0-py3-none-any.whl
  • Upload date:
  • Size: 26.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.1 CPython/3.10.20 Linux/6.14.0-1017-azure

File hashes

Hashes for pyirx-1.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f7c1ca103a4be2d4a94ffa9096feaf73e11e62104cd6c0ef8674b1578b30d301
MD5 cbde49b99d1fa780a2760a8d25630298
BLAKE2b-256 7247729c9a09dca56e9c51dab5bf4ebfd222aaf27dd553d2f0d3e5c0ce5239f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page