npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

unfuck

v0.3.0

Published

A brainfuck to Javascript compiler with optimizations.

Downloads

67

Readme

Unf*ck. Build Status codecov

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

Installation

$ npm install --save unfuck
var uf = require('unfuck');

API

uf.compiler({ Settings Object })

Returns a compiler object preloaded with the settings provided.

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

type

Takes: An array constructor Default: Uint8Array Dictates the type of the array representing the 'tape'. I suggest using typed arrays 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 Default: 10240 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) Default: String 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 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) Default: String 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
  • If it's set to Number, the function will return the numerical value of the cell on the tape.

target

Takes: String Default: 'simple-es6' 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])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)=>{  getLine('Number?')}, (x)=>{  console.log(x)}) |


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:

// 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.

var uf = require('unfuck');

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

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

Which outputs the following:

{
    "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('');})"
}