GithubHelp home page GithubHelp logo

haakonnessjoen / bfcompile Goto Github PK

View Code? Open in Web Editor NEW
0.0 1.0 0.0 86 KB

An experiment creating a brainfuck compiler in go, using qbe IL

License: MIT License

Makefile 0.50% Brainfuck 58.92% Go 40.58%

bfcompile's Introduction

Brainfuck compiler

This project parses brainfuck files, optimizes it, and generates QBE IL, C code, Javascript or Brainfuck output. If you output QBE IL, you can use the qbe tool to generate assembly that can be compiled with llvm, se examples below.

The idea came when I saw the Youtuber tsoding try out QBE, and the language looked very simple, so I thought it should be simple to use it to compile brainfuck.

Features

If you enable optimization, it optimizes the token tree (or array really) before it generates code with the following optimalizations, output is explained with C for simplicity:

  • Memory size (default 30KB) and cell size (32,16 or 8 bit) is configurable

  • Multiple equal operations are aggregated, for example ++++ would generate *p += 4 in C

  • Opposing operations cancel eachother out. For example +++-- would generate *p++ in C

  • If opposing operations "overflow" they swap operation, so ++--- would change the initial + operation that is being handeled into a - operation, so the resulting C in this case would be *p--

  • Optimalization is re-run until no more optimization is possible, so that for example ++-->+->+->+- would be optimized down to just *p += 3

  • Second level optimalization; convert simple loops that only do maths, to multiplication instructions. For example; ++[>+++>++<<-] would optimize to the following C code: p[0] = 2; p[1] += *p * 3; p[2] += *p * 2;. It also handles when the iterator is more than 1; for example: ++[>>+++>++<<--] would generate p[0] = 2; p[0] =/ 2; p[2] += *p * 3; p[3] += *p * 2;, so that the result would be half the last example. This optimization cannot be used with Brainfuck output of course.

  • Added an if before the multiplication operations, in case the operation should not be done at all.

  • Just after a loop, we know that *p is 0, so if there is a ADD/SUB operation just after that, we can set it directly. For example [-]++ would translate to *p = 2instead of*p = 0; *p += 2;

  • For C output, there are a few extra optimalizations, one where [>] will use stdlib call memchr() which on some standard libraries are optimized to check 4 bytes at a time. And a second one, that converts [.>] to p += fputs(p, stdout) as it will both increase the pointer, and let the standard library ouput the string the most optimal way. These optimizations are probably not very noticable in most brainfuck programs though.

  • If a loop variable is cleared before the loop ends, convert it to a if statement instead. (This will also handle loops that contains ex-loops that has been converted to multiplications)

Fun fact: It can also output Brainfuck, so you can use it to optimize your brainfuck (only level 1). For example output from this "C" to bf compiler can often be optimized quite a bit, as it does a lot of operations that would cancel eachother out.

Prerequisites

If you are using qbe output format you need qbe. On mac you can just do brew install qbe.

Cross compilation of brainfuck code on mac

On a mac you can cross compile to arm64 and/or amd64 binaries doing the following:

Specify AMD64 output

./bfcompile -c -o brainfuck/tictactoe.bf > brainfuck/tictactoe.ssa
qbe -t amd64_apple -o brainfuck/tictactoe.s brainfuck/tictactoe.ssa
cc brainfuck/tictactoe.s -target x86_64-apple-darwin-macho -o tictactoe_amd64

Specify ARM64 output

./bfcompile -c -o brainfuck/tictactoe.bf > brainfuck/tictactoe.ssa
qbe -t arm64_apple -o brainfuck/tictactoe.s brainfuck/tictactoe.ssa
cc brainfuck/tictactoe.s -target arm64-apple-darwin-macho -o tictactoe_arm64

bfcompile's People

Contributors

haakonnessjoen avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.