Skip to main content

A MIPS assembly macro preprocessor made for the mipsy emulator

Project description

MIPS Macro Preprocessor

A MIPS assembly macro preprocessor made for the mipsy emulator.

This is designed with many of the same philosophies as mipsy, aiming to make code written for it easy to read and debug, and to catch many common macro mistakes.

Features

  • Macro substitution (#define)
    • Substitution is done properly (by tokenisation), not just by crude find-and-replace
  • Extensive checking of macro names and values
    • Appropriate prefixes for macro names (e.g. '$' for registers, see the usage section for details) are enforced to maintain code readability
  • Helpful warning and error messages
  • Scoped macros (#defineuntil <label>)
  • Zero dependencies (other than Python 3.8+)
  • Robust tokenisation/parsing strategy that shouldn't totally break if mipsy gains support for new features

Planned Features

  • Removal/replacement of macro comments
  • Automatic comment alignment (macro substitution misaligns comments currently)
  • Ability to use a macro in another macro
  • Editor support (maybe) - for now just use the --watch flag

Missing Features

  • Function-like macros
  • Multiline macro values
  • #undef, #ifdef etc.
  • Substitution of label names (I can't imagine why you'd ever want to do this)

Installation

Install from PyPI:

pip install mipsy-macro

This will install the package and the mipsy-macro command.

CSE Machine Notes:

If you're installing this on a CSE machine it's a bit trickier since you can't install globally. Instead, do the following:

# install into your home directory
pip install mipsy-macro --target ~/mipsy-macro
# copy and link the script so that imports work and it can run from anywhere
cp ~/mipsy-macro/bin/mipsy-macro ~/mipsy-macro/mipsy-macro
mkdir -p ~/bin
ln -s ~/mipsy-macro/mipsy-macro ~/bin/mipsy-macro

Installation Check:

If everything is installed correctly you should be able to run mipsy-macro -h and get a help message.

Usage

To use the preprocessor, run mipsy-macro <input filename> -o <output filename>. For detailed info about options, run mipsy-macro -h.

You can use the --watch flag to automatically re-process your code as it changes.

The format for a macro definition is #define <name> <value>. The preprocessor enforces the use of prefixes on macro names as follows:

1. Immediates: [none]                     e.g. #define NAME 123
2. Registers: $                           e.g. #define $NAME $sp
3. Addresses (including labels): @        e.g. #define @NAME whatever_label($t0) 
4. Directives: .                          e.g. #define .NAME .word
5. Other/raw e.g. instruction, string: !  e.g. #define !NAME move $t0, $t1

Any occurrence of the macro name (incl. prefix) as a token (i.e. as its own word) after the macro definition will be replaced with the macro value.

Scoped macros can be used as follows: #defineuntil <label> <name> <value>. Scoped macros work the same way as regular macros, but they will be undefined automatically when <label> is reached (after which they can be redefined). This can be used e.g. to define $IDX differently in different loops/functions.

Example

# Create a register macro ($ prefix). Replaces all future occurrences of $COOL_REGISTER with $s0.
#define $COOL_REGISTER $s0

# Create an address macro (@ prefix).
#define @ADDR numbers($s0)

# Create an immediate macro (no prefix). Mipsy already supports defining constants using the
# e.g. VAL = 3 + 4 * 5 syntax. You should usually use that instead of this, it's better!
#define INIT 4

# Create a directive keyword macro (. prefix). You probably won't need to use this, but it's there.
#define .DRCTV .byte

# This is a raw macro (! prefix), no sanity checking of values is performed.
# They're occasionally useful for defining full statements (instructions, directives etc.).
# Don't use these unless you really know what you're doing, things will break if you're not careful.
#define !RET jr        $ra

main:
# These are scoped macros. They are removed when their label (`main__end` in this case) is reached.
# This is particularly useful for giving names to registers used in a function.
#defineuntil main__end $X $t0
#defineuntil main__end $Y $t1

  li        $X, INIT                   # x = 4;
  li        $Y, 123                    # y = 123;
  move      $COOL_REGISTER, $X         # cool_reg = x;
  sw        $Y, @ADDR                  # numbers[cool_reg] = y;

# $X and $Y go out of scope here, so occurrences of them after this label won't be replaced,
# and they'll be able to be redefined as something else.
main__end:
  li        $v0, 0
  !RET                                 # return 0;

  .data
prompt:
  .asciiz "Enter a number: "
numbers:
  .DRCTV 0, 1, 2, 3, 4, 5, 6, 7        # char numbers[8] = { 0, 1, ... 7 };

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

mipsy_macro-0.2.0.tar.gz (49.1 kB view details)

Uploaded Source

Built Distribution

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

mipsy_macro-0.2.0-py3-none-any.whl (36.7 kB view details)

Uploaded Python 3

File details

Details for the file mipsy_macro-0.2.0.tar.gz.

File metadata

  • Download URL: mipsy_macro-0.2.0.tar.gz
  • Upload date:
  • Size: 49.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for mipsy_macro-0.2.0.tar.gz
Algorithm Hash digest
SHA256 30572d14248409191e2cd0186b0a554a4c70c32682f1f91eb7545ac9415aab2f
MD5 44556a80ffe348ee89cf0a263dbe5955
BLAKE2b-256 3220ac17cb4bb570ca10e38e9fa08383a5d56c9813795834325d2a84d5fc1548

See more details on using hashes here.

File details

Details for the file mipsy_macro-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: mipsy_macro-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for mipsy_macro-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ee5ce2c3df9eb2817ee22d2bc862d1ba2d458e70831948f645166cc31a5ccce1
MD5 f99dd053e38d693cec48b28943b2c11c
BLAKE2b-256 5532866343ecd1dfbff02225b9beb4f129c2fc6b70a132d20e3a6c8f0b04502a

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