# unfuck

> A brainfuck to Javascript compiler with optimizations.

Latest version **0.3.0** (published 2017-05-06) · ISC license · 0 weekly downloads

## Install

```sh
npm install unfuck
pnpm add unfuck
yarn add unfuck
bun add unfuck
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.3.0 |
| Published | 2017-05-06 |
| First published | 2016-08-20 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 14 |
| Author | Toish |
| Maintainers | toish |
| Keywords | brainfuck, compiler, ast, abstract syntax tree, esolang |

## Links

- npm: https://www.npmjs.com/package/unfuck
- Repository: https://github.com/toish/unfuck
- Homepage: https://github.com/toish/unfuck#readme
- Issues: https://github.com/toish/unfuck/issues
- npm.io page: https://npm.io/package/unfuck

## Alternatives

- [update-check](https://npm.io/package/update-check.md) — 4.0M weekly downloads
- [react-native-onesignal](https://npm.io/package/react-native-onesignal.md) — 134.5K weekly downloads
- [react-redux-toastr](https://npm.io/package/react-redux-toastr.md) — 33.7K weekly downloads
- [@nocobase/plugin-notification-manager](https://npm.io/package/@nocobase/plugin-notification-manager.md) — 2.0K weekly downloads
- [react-simple-toasts](https://npm.io/package/react-simple-toasts.md) — 1.9K weekly downloads

## Recent versions

- 0.3.0 (latest) — 2017-05-06
- 0.2.7 — 2017-03-11
- 0.2.6 — 2017-03-10
- 0.2.5 — 2017-02-12
- 0.2.4 — 2017-02-07
- 0.2.3 — 2017-02-07
- 0.2.2 — 2017-02-06
- 0.2.1 — 2017-02-06
- 0.1.3 — 2017-02-05
- 0.1.2 — 2016-12-17
- 0.1.1 — 2016-09-01
- 0.1.0 — 2016-08-21
- 0.0.2 — 2016-08-20
- 0.0.1 — 2016-08-20

## README

# Unf*ck. [![Build Status](https://travis-ci.org/toish/unfuck.svg?branch=master)](https://travis-ci.org/toish/unfuck) [![codecov](https://codecov.io/gh/toish/unfuck/branch/master/graph/badge.svg)](https://codecov.io/gh/toish/unfuck)

This module exposes a simple API to convert Brainf*ck to a Javascript function.

## Installation
```bash
$ npm install --save unfuck
```

```javascript
var uf = require('unfuck');
```

## API
`uf.compiler({ Settings Object })`

Returns a compiler object preloaded with the settings provided.

```javascript
{
	type: <Uint8Array | Uint16Array | Int8Array ... etc>,
	width: <Any Integer>,
	in: <Number | String>,
	out: <Number | String>,
	target: <'simple-es6' | 'interactive-es6'>,
}
```

### type
**Takes:** An array constructor<br>
**Default:** `Uint8Array`<br>
Dictates the type of the array representing the 'tape'. I suggest using [typed arrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#TypedArray_objects) because most versions of Brainfuck require some kind of bounded integer, but you can use the `Array` constructor as a value here for full 64bit integers. (Uint8Array is the most common, this bounds the values in the tape between 0 and 254)

### width
**Takes:** `Number`<br>
**Default:** `10240`<br>
The length of the 'tape'. Values at cells beyond this number, or less than 0, result in a error. You'll want this to be high, but not too high, as all cells are initiated with the value `0`, so 10240 8bit cells uses 10kB of memory at start-up. *(The size of each cell is determined by the type setting)*

### in
**Takes:** A type constructor (`String` or `Number`)<br>
**Default:** `String`<br>
The type of data the resulting javascript function will take as input. (The target option determines the source of input.)

* If it's set to `String`, the function will insert each [charCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt) sequentially when `,` is used.
* If it's set to `Number`, the function will insert the number supplied as input sequentially when `,` is used.

### out
**Takes:** A type constructor (`String` or `Number`)<br>
**Default:** `String`<br>
The type of data the resulting javascript function will return or include in it's output callback. (The target option determines the mode of output.)

* If it's set to `String`, the function will convert the number on the tape to a character via [fromCharCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode)
* If it's set to `Number`, the function will return the numerical value of the cell on the tape.

### target
**Takes:** `String`<br>
**Default:** `'simple-es6'`<br>
Unfuck comes with a couple different compilation targets which affect how the outputted javascript can be used.

| Name | Description | Example Usage |
| :--: | ----------- | ------------- |
| `'simple-es6'` | Input is taken as an `Array` or `String` *(depending input type, `Number` and `String` respectively)* in the first and only parameter of the outputted javascript function. Each instance of `,` in Brainfuck will take the first element off of this array and insert it onto the tape. Output is the returned value of the function.| `c.use(',-.')([4,3])`<br>`c.use(',-.')('abc')` |
| `'interactive-es6'` | Input is received synchronously from the first parameter to the outputted javascript function, it should be a function which can take the current cell value as it's first parameter. The output is also processed synchronously by the second parameter which should be a function that takes the current cell as it's first parameter. | `c.use(',-.')((x)=>{`<br>&nbsp;&nbsp;`getLine('Number?')`<br>`}, (x)=>{`<br>&nbsp;&nbsp;`console.log(x)`<br>`})` |

---

`compiler.compile( Brainfuck String )`

Returns an object containing the sanitized brainfuck code, a copy of the Abstract Syntax Tree, and the outputted compiled code in a string. See example below for example output of this function.

---

`compiler.use( Brainfuck String )`

Returns a real Javascript function which takes input as it's only parameter and returns output, both in the type specified by the compiler object.

---

`compiler.run( Brainfuck String, Input )`

Executes the brainfuck function with input. Input should be pre-formatted to the compilers specs. (I.E. Number => [Int], String => "String")


## Examples

### Basic Use
If you just want to test out the compiler, you can run a simple hello world program using this:

```javascript
// Import Unfuck module.
var uf = require('unfuck');

// Create a compiler using the default configuration.
var compiler = uf.compiler();

// Output 'Hello World!' to the console. 
console.log(
	compiler.run( // Runs the compiled JS function right after compiling.
		'++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.', // The brainfuck program itself.
		'' // This is for program input, which the hello world program doesn't utilize
	)
);
```

### Compilation output with Abstract Syntax Tree
Using the `.compile()` method lets you access a copy of the generated AST, for whatever reason you need it for.


```javascript
var uf = require('unfuck');

var compiler = uf.compiler({
	type: Uint16Array,
	in: Number,
	out: String,
	width: 9999
});

console.log( compiler.compile('++++++[>++++++++++<-]>+++++.') );
```

Which outputs the following:

```javascript
{
    "bf": "++++++[>++++++++++<-]>+++++.",
    "ast": [
        {
            "is": "SFT",
            "body": 6
        },
        {
            "is": "MUL",
            "body": {
                "factors": [
                    {
                        "move": 1,
                        "factor": 10
                    }
                ]
            }
        },
        {
            "is": "RELSFT",
            "body": {
                "value": 5,
                "move": 1
            }
        },
        {
            "is": "MOV",
            "body": 1
        },
        {
            "is": "OUT"
        }
    ],
    "out": "(function(i){var i=i.split('').map(x=>x.charCodeAt())||[];var o=[];var t=new Uint8Array(30000);var p=0;t[p]+=6;t[p+1]+=t[p]*10;t[p]=0;t[p+1]+=5;p+=1;o.push(t[p]);return o.map(x=>String.fromCharCode(x)).join('');})"
}
```

---
_Source: https://npm.io/package/unfuck · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
