mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-15 13:55:02 +01:00
Compare commits
No commits in common. "master" and "v0.1.1" have entirely different histories.
81 changed files with 930 additions and 18720 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
*.bf linguist-vendored
|
|
||||||
*.b linguist-vendored
|
|
||||||
12
README.md
12
README.md
|
|
@ -1,17 +1,15 @@
|
||||||
# brainfuck
|
# brainfuck
|
||||||
Brainfuck interpreters in different languages
|
Brainfuck interpreters in different languages
|
||||||
|
|
||||||
Get the releases!
|
|
||||||
|
|
||||||
Rust: CLI binary, in the release tab
|
|
||||||
Typescript: [react website](https://nilstrieb.github.io/brainfuck/)
|
|
||||||
|
|
||||||
Finished:
|
Finished:
|
||||||
- Rust
|
- Rust
|
||||||
|
- Rust o1
|
||||||
- Java
|
- Java
|
||||||
- Interactive TypeScript
|
|
||||||
|
|
||||||
WIP:
|
WIP:
|
||||||
|
- Rust o2
|
||||||
|
|
||||||
To-Do:
|
To-Do:
|
||||||
- Idris
|
- Haskell
|
||||||
|
- TypeScript
|
||||||
|
- (JavaScript)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ public class Brainfuck {
|
||||||
|
|
||||||
public List<Character> minify(String program) {
|
public List<Character> minify(String program) {
|
||||||
List<Character> chars = List.of('>', '<', '+', '-', '.', ',', '[', ']');
|
List<Character> chars = List.of('>', '<', '+', '-', '.', ',', '[', ']');
|
||||||
return program.chars().parallel()
|
return program.chars()
|
||||||
.mapToObj(c -> (char) c)
|
.mapToObj(c -> (char) c)
|
||||||
.filter(chars::contains)
|
.filter(chars::contains)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
|
||||||
2
bfi-rust/.gitignore
vendored
2
bfi-rust/.gitignore
vendored
|
|
@ -1,3 +1,5 @@
|
||||||
/target
|
/target
|
||||||
.idea
|
.idea
|
||||||
# brainfuck testing code, get your own
|
# brainfuck testing code, get your own
|
||||||
|
*.b
|
||||||
|
*.bf
|
||||||
2
bfi-rust/Cargo.lock
generated
2
bfi-rust/Cargo.lock
generated
|
|
@ -2,4 +2,4 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bfinterpreter"
|
name = "bfinterpreter"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bfinterpreter"
|
name = "bfinterpreter"
|
||||||
version = "0.1.1"
|
version = "0.1.0"
|
||||||
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|
@ -8,8 +8,6 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
debug = true
|
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 437 KiB |
23
ibfi-ts/.gitignore
vendored
23
ibfi-ts/.gitignore
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/node_modules
|
|
||||||
/.pnp
|
|
||||||
.pnp.js
|
|
||||||
|
|
||||||
# testing
|
|
||||||
/coverage
|
|
||||||
|
|
||||||
# production
|
|
||||||
/build
|
|
||||||
|
|
||||||
# misc
|
|
||||||
.DS_Store
|
|
||||||
.env.local
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Interactive Brainfuck Interpreter in React TS
|
|
||||||
|
|
||||||
This is an interactive interpreter for the brainfuck programming language.
|
|
||||||
It provides simple brainfuck execution, along with a view of the memory, the memory pointer, the current state of the
|
|
||||||
code and more.
|
|
||||||
|
|
||||||
It is great for debugging brainfuck programs, including a memory view, program view, the location of the pointers, the
|
|
||||||
ability to directly edit memory.
|
|
||||||
You can step manually through the program, or set the execution speed to whatever speed fits best.
|
|
||||||
This interpreter also has the ability to set breakpoints using the • symbol. This means you can let your code run fast and
|
|
||||||
stopping it at any point in your program to see what went wrong.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
* brainfuck execution including IO
|
|
||||||
* memory view
|
|
||||||
* code state view
|
|
||||||
* manual stepping
|
|
||||||
* breakpoints
|
|
||||||
* error messages
|
|
||||||
* seeing ASCII characters in memory
|
|
||||||
* manual code input
|
|
||||||
* fast excecution mode (no debugging info)
|
|
||||||
|
|
||||||
### Future features
|
|
||||||
* none-blocking fast excecution mode
|
|
||||||
* better speed control
|
|
||||||
* (limited) backstepping
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
{
|
|
||||||
"name": "ibfi-ts",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"homepage": "https://nilstrieb.github.io/brainfuck",
|
|
||||||
"private": false,
|
|
||||||
"dependencies": {
|
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
|
||||||
"@testing-library/react": "^11.1.0",
|
|
||||||
"@testing-library/user-event": "^12.1.10",
|
|
||||||
"@types/jest": "^26.0.15",
|
|
||||||
"@types/node": "^12.0.0",
|
|
||||||
"@types/react": "^17.0.0",
|
|
||||||
"@types/react-dom": "^17.0.0",
|
|
||||||
"node-sass": "^6.0.0",
|
|
||||||
"react": "^17.0.2",
|
|
||||||
"react-dom": "^17.0.2",
|
|
||||||
"react-scripts": "4.0.3",
|
|
||||||
"sass": "^1.35.1",
|
|
||||||
"typescript": "^4.1.2",
|
|
||||||
"web-vitals": "^1.0.1"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"start": "react-scripts start",
|
|
||||||
"build": "react-scripts build",
|
|
||||||
"test": "react-scripts test",
|
|
||||||
"eject": "react-scripts eject",
|
|
||||||
"deploy": "yarn build && gh-pages -d build"
|
|
||||||
},
|
|
||||||
"eslintConfig": {
|
|
||||||
"extends": [
|
|
||||||
"react-app",
|
|
||||||
"react-app/jest"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browserslist": {
|
|
||||||
"production": [
|
|
||||||
">0.2%",
|
|
||||||
"not dead",
|
|
||||||
"not op_mini all"
|
|
||||||
],
|
|
||||||
"development": [
|
|
||||||
"last 1 chrome version",
|
|
||||||
"last 1 firefox version",
|
|
||||||
"last 1 safari version"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"gh-pages": "^3.2.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB |
|
|
@ -1,43 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="Interactive Brainfuck Interpreter"
|
|
||||||
/>
|
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<title>Brainfuck Interpreter</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"short_name": "React App",
|
|
||||||
"name": "Create React App Sample",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "favicon.ico",
|
|
||||||
"sizes": "64x64 32x32 24x24 16x16",
|
|
||||||
"type": "image/x-icon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo192.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "192x192"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo512.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "512x512"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"theme_color": "#000000",
|
|
||||||
"background_color": "#ffffff"
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# https://www.robotstxt.org/robotstxt.html
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
||||||
|
|
@ -1,128 +0,0 @@
|
||||||
$main-color: #282c34;
|
|
||||||
$main-color-brighter: #323942;
|
|
||||||
$light-color: ghostwhite;
|
|
||||||
$medium-color: #78787f;
|
|
||||||
|
|
||||||
.App {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
height: 40vmin;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: $main-color;
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: calc(10px + 2vmin);
|
|
||||||
color: $light-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-link {
|
|
||||||
color: #61dafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bf-input {
|
|
||||||
.code-input {
|
|
||||||
resize: none;
|
|
||||||
width: 80vw;
|
|
||||||
height: 400px;
|
|
||||||
font-size: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-options-wrapper > * {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.code-display-wrapper {
|
|
||||||
max-width: 80vw;
|
|
||||||
font-family: monospace;
|
|
||||||
|
|
||||||
span {
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.memory-display-table {
|
|
||||||
$border: 1px solid $light-color;
|
|
||||||
|
|
||||||
th, .cell {
|
|
||||||
border: $border;
|
|
||||||
}
|
|
||||||
|
|
||||||
th, td {
|
|
||||||
min-width: 60px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.array-set-value-field {
|
|
||||||
min-width: 50px;
|
|
||||||
max-width: 100px;
|
|
||||||
height: 40px;
|
|
||||||
color: $light-color;
|
|
||||||
font-size: 30px;
|
|
||||||
background-color: $main-color-brighter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.run-button {
|
|
||||||
height: 50px;
|
|
||||||
width: 200px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.bf-run {
|
|
||||||
margin: 20px;
|
|
||||||
|
|
||||||
|
|
||||||
.speed-control-wrapper > * {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.small-speed-button {
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.program-input-area {
|
|
||||||
resize: none;
|
|
||||||
width: 80vw;
|
|
||||||
height: 50px;
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info {
|
|
||||||
background-color: #579ca7;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bf-output {
|
|
||||||
.output-area {
|
|
||||||
resize: none;
|
|
||||||
width: 80vw;
|
|
||||||
height: 200px;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
background-color: $main-color-brighter;
|
|
||||||
color: $light-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background-color: $medium-color;
|
|
||||||
font-size: 20px;
|
|
||||||
border: 1px solid $main-color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: $light-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
import {CodeOptions} from "../components/CodeInput";
|
|
||||||
|
|
||||||
type InHandler = (() => number);
|
|
||||||
type OutHandler = ((char: number) => void);
|
|
||||||
|
|
||||||
export default class Interpreter {
|
|
||||||
private readonly _array: Uint8Array;
|
|
||||||
private _pointer: number;
|
|
||||||
private readonly _code: string;
|
|
||||||
private _programCounter: number;
|
|
||||||
|
|
||||||
private readonly _inHandler: InHandler;
|
|
||||||
private readonly _outHandler: OutHandler;
|
|
||||||
|
|
||||||
private readonly _options: CodeOptions;
|
|
||||||
|
|
||||||
constructor(input: [string, CodeOptions], outHandler: OutHandler, inHandler: InHandler) {
|
|
||||||
const buf = new ArrayBuffer(32000);
|
|
||||||
this._array = new Uint8Array(buf);
|
|
||||||
this._pointer = 0;
|
|
||||||
|
|
||||||
this._options = input[1];
|
|
||||||
if (input[1].minify) {
|
|
||||||
this._code = this.minify(input[0])
|
|
||||||
} else {
|
|
||||||
this._code = input[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
this._programCounter = 0;
|
|
||||||
this._inHandler = inHandler;
|
|
||||||
this._outHandler = outHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public next() {
|
|
||||||
this.execute(this._code[this._programCounter++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public execute(char: string) {
|
|
||||||
switch (char) {
|
|
||||||
case '+':
|
|
||||||
this._array[this._pointer]++;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
this._array[this._pointer]--;
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
this._pointer++;
|
|
||||||
break;
|
|
||||||
case '<':
|
|
||||||
if (this._pointer === 0) {
|
|
||||||
throw new Error("Cannot wrap left");
|
|
||||||
}
|
|
||||||
this._pointer--;
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
this._outHandler(this.value);
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
this.input();
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
this.loopForwards();
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
this.loopBackwards();
|
|
||||||
break;
|
|
||||||
case '•':
|
|
||||||
if (this._options.enableBreakpoints) {
|
|
||||||
throw new Error("Breakpoint reached");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case undefined:
|
|
||||||
this._programCounter = this._code.length;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private loopForwards() {
|
|
||||||
if (this.value === 0) {
|
|
||||||
let level = 0;
|
|
||||||
while (this.lastInstruction !== ']' || level > -1) {
|
|
||||||
this._programCounter++;
|
|
||||||
if (this._programCounter > this._code.length) {
|
|
||||||
throw new Error("Reached end of code while searching ']'");
|
|
||||||
}
|
|
||||||
if (this.lastInstruction === '[') level++;
|
|
||||||
else if (this.lastInstruction === ']') level--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private loopBackwards() {
|
|
||||||
if (this.value !== 0) {
|
|
||||||
let level = 0;
|
|
||||||
while (this.lastInstruction !== '[' || level > -1) {
|
|
||||||
this._programCounter--;
|
|
||||||
if (this._programCounter < 0) {
|
|
||||||
throw new Error("Reached start of code while searching '['");
|
|
||||||
}
|
|
||||||
if (this.lastInstruction === '[') level--;
|
|
||||||
else if (this.lastInstruction === ']') level++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private input() {
|
|
||||||
try {
|
|
||||||
this._array[this._pointer] = this._inHandler();
|
|
||||||
} catch {
|
|
||||||
this._programCounter--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get reachedEnd(): boolean {
|
|
||||||
return this._programCounter === this._code.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
get lastInstruction(): string {
|
|
||||||
return this._code[this._programCounter - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
get value(): number {
|
|
||||||
return this._array[this._pointer];
|
|
||||||
}
|
|
||||||
|
|
||||||
get array(): Uint8Array {
|
|
||||||
return this._array;
|
|
||||||
}
|
|
||||||
|
|
||||||
get pointer(): number {
|
|
||||||
return this._pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
get code(): string {
|
|
||||||
return this._code;
|
|
||||||
}
|
|
||||||
|
|
||||||
get programCounter(): number {
|
|
||||||
return this._programCounter;
|
|
||||||
}
|
|
||||||
|
|
||||||
private minify(code: string): string {
|
|
||||||
const CHARS = ['+', '-', '<', '>', '.', ',', '[', ']'];
|
|
||||||
if (this._options.enableBreakpoints) {
|
|
||||||
CHARS.push('•');
|
|
||||||
}
|
|
||||||
|
|
||||||
return code.split("")
|
|
||||||
.filter(c => CHARS.includes(c))
|
|
||||||
.join("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
import '../App.scss';
|
|
||||||
import CodeInput, {CodeOptions} from "./CodeInput";
|
|
||||||
import ProgramOutput from "./ProgramOutput";
|
|
||||||
import React, {useCallback, useState} from "react";
|
|
||||||
import Runner from "./Runner";
|
|
||||||
|
|
||||||
export const OptionContext = React.createContext<CodeOptions>({});
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const [out, setOut] = useState("");
|
|
||||||
const [input, setInput] = useState<[string, CodeOptions]>(["", {}]);
|
|
||||||
const [running, setRunning] = useState(false);
|
|
||||||
|
|
||||||
const outHandler = useCallback((char: number) => {
|
|
||||||
setOut(oldOut => oldOut + String.fromCharCode(char))
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const runHandler = (run: boolean) => {
|
|
||||||
setRunning(run);
|
|
||||||
if (!run) {
|
|
||||||
setOut("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputHandler = (code: string, options: CodeOptions) => setInput([code, options]);
|
|
||||||
return (
|
|
||||||
<div className="App-header">
|
|
||||||
<OptionContext.Provider value={input[1]}>
|
|
||||||
{
|
|
||||||
!running && <CodeInput input={input} setInput={inputHandler}/>
|
|
||||||
}
|
|
||||||
<Runner running={running} setRunning={runHandler} code={input[0]} outHandler={outHandler}/>
|
|
||||||
{
|
|
||||||
running && <ProgramOutput text={out}/>
|
|
||||||
}
|
|
||||||
</OptionContext.Provider>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
interface CodeDisplayProps {
|
|
||||||
code: string,
|
|
||||||
index: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
const CodeDisplay = ({code, index}: CodeDisplayProps) => {
|
|
||||||
|
|
||||||
const firstCodePart = code.substr(0, index);
|
|
||||||
const secondCodePart = code.substr(index + 1, code.length - index + 1);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="code-display-wrapper">
|
|
||||||
<code>{firstCodePart}</code>
|
|
||||||
<code style={{backgroundColor: "red"}}>{code[index] || " "}</code>
|
|
||||||
<code>{secondCodePart}</code>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CodeDisplay;
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
import React, {ChangeEvent, useState} from 'react';
|
|
||||||
import presets from "../presets.json";
|
|
||||||
|
|
||||||
export interface CodeOptions {
|
|
||||||
minify?: boolean,
|
|
||||||
directStart?: boolean,
|
|
||||||
startSuperSpeed?: boolean,
|
|
||||||
enableBreakpoints?: boolean
|
|
||||||
asciiView?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CodeInputProps {
|
|
||||||
setInput: ((code: string, options: CodeOptions) => void),
|
|
||||||
input: [string, CodeOptions]
|
|
||||||
}
|
|
||||||
|
|
||||||
const codeOptions: Array<[string, keyof CodeOptions]> = [
|
|
||||||
["Minify Code", "minify"],
|
|
||||||
["Start directly", "directStart"],
|
|
||||||
["Start in blocking mode", "startSuperSpeed"],
|
|
||||||
["Breakpoints (•)", "enableBreakpoints"],
|
|
||||||
["Show ASCII in memory", "asciiView"]
|
|
||||||
]
|
|
||||||
|
|
||||||
const CodeInput = ({input: [code, options], setInput}: CodeInputProps) => {
|
|
||||||
const [fontSize, setFontSize] = useState(40);
|
|
||||||
|
|
||||||
const setPreset = (name: keyof typeof presets) => () => {
|
|
||||||
setInput(presets[name], options);
|
|
||||||
}
|
|
||||||
|
|
||||||
const changeHandler = (name: keyof CodeOptions) => (event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
setInput(code, {...options, [name]: event.target.checked})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bf-input">
|
|
||||||
<div className="code-options-wrapper">
|
|
||||||
<div>
|
|
||||||
<label htmlFor="bf-input-fontsize-range">Font Size</label>
|
|
||||||
<input type="range" id="bf-input-fontsize-range" onChange={v => setFontSize(+v.target.value)}/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{codeOptions.map(([display, id]) =>
|
|
||||||
<CodeOption displayName={display} name={id} options={options} onChange={changeHandler}/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<textarea value={code} onChange={e => setInput(e.target.value, options)} style={{fontSize}}
|
|
||||||
className="code-input"
|
|
||||||
placeholder="Input your code here..."/>
|
|
||||||
<div>
|
|
||||||
<div>Presets</div>
|
|
||||||
<div>
|
|
||||||
<button onClick={setPreset("helloworld")}>Hello World</button>
|
|
||||||
<button onClick={setPreset("hanoi")}>Towers of Hanoi</button>
|
|
||||||
<button onClick={setPreset("quine")}>Quine</button>
|
|
||||||
<button onClick={setPreset("gameoflife")}>Game Of Life</button>
|
|
||||||
<button onClick={setPreset("benchmark")}>Benchmark</button>
|
|
||||||
<button onClick={setPreset("fizzbuzz")}>Fizzbuzz</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface CodeOptionProps {
|
|
||||||
displayName: string,
|
|
||||||
name: keyof CodeOptions,
|
|
||||||
options: CodeOptions,
|
|
||||||
onChange: (name: keyof CodeOptions) => (event: ChangeEvent<HTMLInputElement>) => void,
|
|
||||||
}
|
|
||||||
|
|
||||||
const CodeOption = ({displayName, name, options, onChange}: CodeOptionProps) => (
|
|
||||||
<span>
|
|
||||||
<input type="checkbox" checked={options[name]} id={`input-options-${name}`}
|
|
||||||
onChange={onChange(name)}/>
|
|
||||||
<label htmlFor={`input-options-${name}`}>{displayName}</label>
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
export default CodeInput;
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
interface ProgramOutputProps {
|
|
||||||
text: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const ProgramOutput = ({text}: ProgramOutputProps) => {
|
|
||||||
return (
|
|
||||||
<div className="bf-output">
|
|
||||||
<textarea readOnly className="output-area" value={text}/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProgramOutput;
|
|
||||||
|
|
@ -1,118 +0,0 @@
|
||||||
import React, {useContext, useRef, useState} from 'react';
|
|
||||||
import Interpreter from "../brainfuck/Interpreter";
|
|
||||||
import {OptionContext} from "./App";
|
|
||||||
|
|
||||||
const MAX_TABLE_COLUMNS = 20;
|
|
||||||
|
|
||||||
interface RunDisplayProps {
|
|
||||||
interpreter: Interpreter,
|
|
||||||
}
|
|
||||||
|
|
||||||
const RunDisplay = ({interpreter}: RunDisplayProps) => {
|
|
||||||
const options = useContext(OptionContext);
|
|
||||||
|
|
||||||
const index = interpreter.pointer;
|
|
||||||
|
|
||||||
let offset: number;
|
|
||||||
|
|
||||||
if (index < MAX_TABLE_COLUMNS / 2) {
|
|
||||||
offset = 0;
|
|
||||||
} else {
|
|
||||||
offset = index - MAX_TABLE_COLUMNS / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrayWithIndex = Array(MAX_TABLE_COLUMNS).fill(0)
|
|
||||||
.map((_, i) => i + offset);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<table className="memory-display-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
{
|
|
||||||
arrayWithIndex.map((n => <th key={n}>{n}</th>))
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
{
|
|
||||||
arrayWithIndex.map((n) => <MemoryCell key={n} index={n} interpreter={interpreter}/>)
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
{
|
|
||||||
options.asciiView &&
|
|
||||||
<tr>
|
|
||||||
{
|
|
||||||
arrayWithIndex.map((n) => <MemoryCell key={n} index={n} interpreter={interpreter} ascii/>)
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
}
|
|
||||||
<tr>
|
|
||||||
{
|
|
||||||
arrayWithIndex.map((n) => <td className="pointer"
|
|
||||||
key={n}>{interpreter.pointer === n && "^"}</td>)
|
|
||||||
}
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface MemoryCellProps {
|
|
||||||
index: number,
|
|
||||||
interpreter: Interpreter,
|
|
||||||
ascii?: boolean,
|
|
||||||
}
|
|
||||||
|
|
||||||
const MemoryCell = ({index, interpreter, ascii}: MemoryCellProps) => {
|
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
|
||||||
const [input, setInput] = useState(interpreter.array[index] + "");
|
|
||||||
|
|
||||||
const inputField = useRef<HTMLInputElement>(null);
|
|
||||||
|
|
||||||
const saveAndQuit = () => {
|
|
||||||
interpreter.array[index] = +(input);
|
|
||||||
setIsEditing(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const click = () => {
|
|
||||||
setIsEditing(true);
|
|
||||||
inputField.current?.select();
|
|
||||||
}
|
|
||||||
|
|
||||||
const keyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
|
||||||
console.log("key", e.key);
|
|
||||||
if (e.key === "Escape") {
|
|
||||||
setIsEditing(false);
|
|
||||||
} else if (e.key === "Enter") {
|
|
||||||
saveAndQuit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const content = ascii ?
|
|
||||||
String.fromCharCode(interpreter.array[index])
|
|
||||||
:
|
|
||||||
interpreter.array[index];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<td onClick={click} className="cell">
|
|
||||||
{
|
|
||||||
isEditing && !ascii ?
|
|
||||||
<input onKeyDown={keyDown}
|
|
||||||
className="array-set-value-field"
|
|
||||||
ref={inputField}
|
|
||||||
onChange={e => setInput(e.target.value)}
|
|
||||||
value={input}
|
|
||||||
onBlur={saveAndQuit}
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
content
|
|
||||||
}
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default RunDisplay;
|
|
||||||
|
|
@ -1,189 +0,0 @@
|
||||||
import React, {useCallback, useContext, useEffect, useRef, useState} from 'react';
|
|
||||||
import Interpreter from "../brainfuck/Interpreter";
|
|
||||||
import CodeDisplay from "./CodeDisplay";
|
|
||||||
import RunDisplay from "./RunDisplay";
|
|
||||||
import {OptionContext} from "./App";
|
|
||||||
|
|
||||||
|
|
||||||
interface RunInfoProps {
|
|
||||||
running: boolean,
|
|
||||||
setRunning: (running: boolean) => void,
|
|
||||||
code: string,
|
|
||||||
outHandler: (char: number) => void,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Runner = ({setRunning, running, outHandler, code}: RunInfoProps) => {
|
|
||||||
const [speed, setSpeed] = useState(0);
|
|
||||||
const [interpreter, setInterpreter] = useState<Interpreter | null>(null);
|
|
||||||
const [info, setInfo] = useState<string | null>(null);
|
|
||||||
const [startTime, setStartTime] = useState(0);
|
|
||||||
|
|
||||||
const [, setRerenderNumber] = useState(0);
|
|
||||||
const rerender = () => setRerenderNumber(n => n + 1);
|
|
||||||
|
|
||||||
const options = useContext(OptionContext);
|
|
||||||
|
|
||||||
const inputArea = useRef<HTMLTextAreaElement>(null);
|
|
||||||
|
|
||||||
const inputHandler = () => {
|
|
||||||
if (!inputArea.current) {
|
|
||||||
throw new Error("Could not read input")
|
|
||||||
}
|
|
||||||
const value = inputArea.current.value;
|
|
||||||
if (value.length < 1) {
|
|
||||||
throw new Error("No input found");
|
|
||||||
}
|
|
||||||
const char = value.charCodeAt(0);
|
|
||||||
inputArea.current.value = value.substr(1);
|
|
||||||
return char;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startHandler = useCallback(() => {
|
|
||||||
if (options.directStart) {
|
|
||||||
if (options.startSuperSpeed) {
|
|
||||||
setSpeed(-1);
|
|
||||||
} else {
|
|
||||||
setSpeed(100);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setSpeed(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
setStartTime(Date.now);
|
|
||||||
setInterpreter(new Interpreter([code, options], outHandler, inputHandler));
|
|
||||||
setRunning(false);
|
|
||||||
setRunning(true);
|
|
||||||
}, [options, code, outHandler, setRunning]);
|
|
||||||
|
|
||||||
const stopHandler = () => {
|
|
||||||
setRunning(false);
|
|
||||||
setInfo(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextHandler = useCallback(() => {
|
|
||||||
setInfo(null);
|
|
||||||
try {
|
|
||||||
interpreter?.next();
|
|
||||||
} catch (e) {
|
|
||||||
setInfo(e.message);
|
|
||||||
setSpeed(0);
|
|
||||||
}
|
|
||||||
if (interpreter?.reachedEnd) {
|
|
||||||
setSpeed(0);
|
|
||||||
setInfo(`Finished Execution. Took ${(Date.now() - startTime) / 1000}s`)
|
|
||||||
}
|
|
||||||
rerender();
|
|
||||||
}, [interpreter, startTime]);
|
|
||||||
|
|
||||||
const runBlocking = useCallback(() => {
|
|
||||||
try {
|
|
||||||
while (speed === -1 && !interpreter?.reachedEnd) {
|
|
||||||
interpreter?.next();
|
|
||||||
}
|
|
||||||
setSpeed(0);
|
|
||||||
setInfo(`Finished Execution. Took ${(Date.now() - startTime) / 1000}s`)
|
|
||||||
} catch (e) {
|
|
||||||
setInfo(e.message);
|
|
||||||
setSpeed(0);
|
|
||||||
}
|
|
||||||
}, [speed, interpreter, startTime]);
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (running) {
|
|
||||||
if (speed === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (speed > 0) {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
nextHandler();
|
|
||||||
}, 1000 / (speed * 10));
|
|
||||||
return () => clearInterval(interval);
|
|
||||||
}
|
|
||||||
runBlocking();
|
|
||||||
}
|
|
||||||
}, [runBlocking, running, nextHandler, speed]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="bf-run">
|
|
||||||
{
|
|
||||||
running && interpreter && <>
|
|
||||||
<CodeDisplay code={interpreter.code} index={interpreter.programCounter}/>
|
|
||||||
<RunDisplay interpreter={interpreter}/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
<div>
|
|
||||||
{running && <button className="run-button" onClick={stopHandler}>Back</button>}
|
|
||||||
<button className="run-button" onClick={startHandler}>{running ? "Restart" : "Start"}</button>
|
|
||||||
{running && <button className="run-button" onClick={nextHandler}>Next</button>}
|
|
||||||
</div>
|
|
||||||
{
|
|
||||||
running && interpreter &&
|
|
||||||
<>
|
|
||||||
<SpeedControl speed={speed} setSpeed={setSpeed}/>
|
|
||||||
<ManualControlButtons interpreter={interpreter} rerender={rerender}/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
{info && <div className="info">{info}</div>}
|
|
||||||
{
|
|
||||||
running && <div>
|
|
||||||
<div>Input:</div>
|
|
||||||
<textarea className="program-input-area" ref={inputArea}/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface SpeedControlProps {
|
|
||||||
speed: number,
|
|
||||||
setSpeed: React.Dispatch<React.SetStateAction<number>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SpeedControl = ({speed, setSpeed}: SpeedControlProps) => {
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="speed-control-wrapper">
|
|
||||||
<label htmlFor="run-info-speed-range">Speed</label>
|
|
||||||
<input type="range" id="run-info-speed-range" value={speed}
|
|
||||||
onChange={e => setSpeed(+e.target.value)}/>
|
|
||||||
<span> {speed}</span>
|
|
||||||
<span>
|
|
||||||
<button onClick={() => setSpeed(s => s === 0 ? 0 : s - 1)}
|
|
||||||
className="small-speed-button">-</button>
|
|
||||||
<button onClick={() => setSpeed(0)}
|
|
||||||
className="small-speed-button">0</button>
|
|
||||||
<button onClick={() => setSpeed(s => s === 100 ? 100 : s + 1)}
|
|
||||||
className="small-speed-button">+</button>
|
|
||||||
</span>
|
|
||||||
<span>
|
|
||||||
<label>Superspeed Mode (blocking)</label>
|
|
||||||
<input id="superspeed-mode-check" type="checkbox" checked={speed === -1} onChange={() => setSpeed(-1)}/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ManualControlButtons = ({interpreter, rerender}: { interpreter: Interpreter, rerender: (() => void) }) => {
|
|
||||||
|
|
||||||
const run = (char: string) => {
|
|
||||||
try {
|
|
||||||
interpreter.execute(char);
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
rerender();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<button onClick={() => run('<')} className="small-speed-button"><</button>
|
|
||||||
<button onClick={() => run('>')} className="small-speed-button">></button>
|
|
||||||
<button onClick={() => run('-')} className="small-speed-button">-</button>
|
|
||||||
<button onClick={() => run('+')} className="small-speed-button">+</button>
|
|
||||||
<button onClick={() => run('.')} className="small-speed-button">.</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Runner;
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
|
||||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
|
||||||
sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
|
||||||
monospace;
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import './index.css';
|
|
||||||
import App from './components/App';
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
File diff suppressed because one or more lines are too long
1
ibfi-ts/src/react-app-env.d.ts
vendored
1
ibfi-ts/src/react-app-env.d.ts
vendored
|
|
@ -1 +0,0 @@
|
||||||
/// <reference types="react-scripts" />
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es5",
|
|
||||||
"lib": [
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"allowJs": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"strict": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"isolatedModules": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"jsx": "react-jsx"
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
11965
ibfi-ts/yarn.lock
11965
ibfi-ts/yarn.lock
File diff suppressed because it is too large
Load diff
2
js/.gitignore
vendored
2
js/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
node_modules
|
|
||||||
.idea
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"singleQuote": true,
|
|
||||||
"printWidth": 100
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
hello...[[].]]
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
{
|
|
||||||
"name": "brainfuck",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "src/index.js",
|
|
||||||
"license": "MIT",
|
|
||||||
"type": "module",
|
|
||||||
"devDependencies": {
|
|
||||||
"prettier": "^2.6.2"
|
|
||||||
},
|
|
||||||
"dependencies": {}
|
|
||||||
}
|
|
||||||
113
js/src/index.js
113
js/src/index.js
|
|
@ -1,113 +0,0 @@
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
const RED = '\x1B[1;31m';
|
|
||||||
const RESET = '\x1B[1;0m';
|
|
||||||
|
|
||||||
function lex(string) {
|
|
||||||
const tokens = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < string.length; i++) {
|
|
||||||
const char = string[i];
|
|
||||||
if (['+', '-', '>', '<', '.', ',', '[', ']'].includes(char)) {
|
|
||||||
tokens.push({
|
|
||||||
char,
|
|
||||||
span: i,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
function ParseError(message, span) {
|
|
||||||
this.message = message;
|
|
||||||
this.span = span;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Parser(tokens) {
|
|
||||||
this.tokens = tokens;
|
|
||||||
this.position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parser.prototype.next = function () {
|
|
||||||
const token = this.tokens[this.position];
|
|
||||||
this.position++;
|
|
||||||
return token;
|
|
||||||
};
|
|
||||||
|
|
||||||
Parser.prototype.parse = function (isLoop) {
|
|
||||||
const body = [];
|
|
||||||
let nextToken;
|
|
||||||
while ((nextToken = this.next()) !== undefined) {
|
|
||||||
switch (nextToken.char) {
|
|
||||||
case '[': {
|
|
||||||
const loopBody = this.parse(true);
|
|
||||||
body.push(loopBody);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ']': {
|
|
||||||
if (isLoop) {
|
|
||||||
return body;
|
|
||||||
} else {
|
|
||||||
throw new ParseError('No matching `[` found', nextToken.span);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
body.push(nextToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isLoop) {
|
|
||||||
throw new ParseError('No matching `]` found', this.tokens[this.tokens.length - 1].span);
|
|
||||||
} else {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function reportError(source, message, span) {
|
|
||||||
let lineIdx = 0;
|
|
||||||
let lastNewlineIdx = 0;
|
|
||||||
for (let i = 0; i < source.length; i++) {
|
|
||||||
const char = source[i];
|
|
||||||
if (i === span) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (char === '\n') {
|
|
||||||
lineIdx++;
|
|
||||||
lastNewlineIdx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const lines = source.split('\n');
|
|
||||||
const line = lines[lineIdx];
|
|
||||||
const lineNumber = String(lineIdx + 1);
|
|
||||||
|
|
||||||
const linePrefix = `${lineNumber} | `;
|
|
||||||
const lineSpan = span - lastNewlineIdx;
|
|
||||||
|
|
||||||
console.error(`${RED}error: ${message}${RESET}`);
|
|
||||||
console.error(`${linePrefix}${line}`);
|
|
||||||
console.error(`${' '.repeat(linePrefix.length + lineSpan)}${RED}^${RESET}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = process.argv[2];
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
console.error('Usage: [filename]');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const source = fs.readFileSync(file, 'utf-8');
|
|
||||||
const tokens = lex(source);
|
|
||||||
|
|
||||||
const parser = new Parser(tokens);
|
|
||||||
try {
|
|
||||||
const ast = parser.parse(false);
|
|
||||||
console.log(ast);
|
|
||||||
} catch (parseError) {
|
|
||||||
if (!(parseError instanceof ParseError)) {
|
|
||||||
throw parseError;
|
|
||||||
}
|
|
||||||
reportError(source, parseError.message, parseError.span);
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
||||||
# yarn lockfile v1
|
|
||||||
|
|
||||||
|
|
||||||
prettier@^2.6.2:
|
|
||||||
version "2.6.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032"
|
|
||||||
integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==
|
|
||||||
2
rust2/.gitignore
vendored
2
rust2/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
target
|
|
||||||
.idea
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
imports_granularity = "Crate"
|
|
||||||
newline_style = "Unix"
|
|
||||||
group_imports = "StdExternalCrate"
|
|
||||||
1238
rust2/Cargo.lock
generated
1238
rust2/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,29 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "brainfuck"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
bumpalo = { version = "3.9.1", features = ["allocator_api"] }
|
|
||||||
clap = { version = "3.1.9", features = ["derive"] }
|
|
||||||
dbg-pls = { version = "0.3.2", features = ["colors", "derive"] }
|
|
||||||
owo-colors = "3.3.0"
|
|
||||||
rand = "0.8.5"
|
|
||||||
tracing = "0.1.34"
|
|
||||||
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
criterion = "0.3.5"
|
|
||||||
insta = "1.14.0"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
debug = true
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
opt-level = 3
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "opts"
|
|
||||||
harness = false
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
Benchmark brainf*ck program
|
|
||||||
>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
|
|
||||||
[>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
|
|
||||||
++++++++[>++++++++++[>++++++++++[>++++++++++[>+
|
|
||||||
+++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++.
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>
|
|
||||||
[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<
|
|
||||||
-]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<
|
|
||||||
[>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++
|
|
||||||
+++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-
|
|
||||||
]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+
|
|
||||||
++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>
|
|
||||||
>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++
|
|
||||||
+>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------
|
|
||||||
---->-]<.>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++
|
|
||||||
++[<---------->-]<--.>+++++++++[<+++++++++>-]<--.-.>++++++++
|
|
||||||
[<---------->-]<++.>++++++++[<++++++++++>-]<++++.-----------
|
|
||||||
-.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-.
|
|
||||||
>++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<
|
|
||||||
-----.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>+++
|
|
||||||
+[<++++++>-]<--.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.
|
|
||||||
><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++
|
|
||||||
++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<++
|
|
||||||
+++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++
|
|
||||||
+++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]<
|
|
||||||
-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++.
|
|
||||||
------.>+++++++[<---------->-]<+.>++++++++[<++++++++++>-]<-.
|
|
||||||
-.---------.>+++++++[<---------->-]<+.>+++++++[<++++++++++>-
|
|
||||||
]<--.+++++++++++.++++++++.---------.>++++++++[<---------->-]
|
|
||||||
<++.>+++++[<+++++++++++++>-]<.+++++++++++++.----------.>++++
|
|
||||||
+++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<----->
|
|
||||||
-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<
|
|
||||||
++++++++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++
|
|
||||||
.>+++++[<+++++++++++++>-]<.>+++[<++++++>-]<-.---.++++++.----
|
|
||||||
---.----------.>++++++++[<----------->-]<+.---.[-]<<<->[-]>[
|
|
||||||
-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]
|
|
||||||
>[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-]>>+>[<[-]<
|
|
||||||
<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<
|
|
||||||
<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+
|
|
||||||
<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>
|
|
||||||
-]<.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..---
|
|
||||||
-----.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++
|
|
||||||
.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<-
|
|
||||||
-.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-]
|
|
||||||
<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[
|
|
||||||
<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++
|
|
||||||
++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+.
|
|
||||||
>++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++
|
|
||||||
..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
++++++++++[>++++++++++<-]>>++++++++++>->>>>>>>>>>>>>>>>-->+++++++[->++\n++++++++<]>[->+>+>+>+<<<<]+++>>+++>>>++++++++[-<
|
|
||||||
++++<++++<++++>>>]++++\n+[-<++++<++++>>]>>-->++++++[->+++++++++++<]>[->+>+>+>+<<<<]+++++>>+>++\n++++>++++++>++++++++[-<+
|
|
||||||
+++<++++<++++>>>]++++++[-<+++<+++<+++>>>]>>-->\n---+[-<+]-<[+[->+]-<<->>>+>[-]++[-->++]-->+++[---++[--<++]---->>-<+>[+\n
|
|
||||||
+++[----<++++]--[>]++[-->++]--<]>++[--+[-<+]->>[-]+++++[---->++++]-->[\n->+<]>>[.>]++[-->++]]-->+++]---+[-<+]->>-[+>>>+[
|
|
||||||
-<+]->>>++++++++++<<[-\n>+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>\n+>>]<<<<<]>[-]>>[>++++++
|
|
||||||
[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->+++\n+++++<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]+[-<+]->>]+[-]<<<.>>>+[\n
|
|
||||||
-<+]-<<]
|
|
||||||
|
|
@ -1,709 +0,0 @@
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>[-]>[-]+++++++++++++++++++++++++++.++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++.-------------------.-------
|
|
||||||
--------------------------------------.+++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++++.-----------------------------------------.++++++
|
|
||||||
++++++++++++++++++.[-]+++++++++++++++++++++++++++.++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++.-------------------------------------
|
|
||||||
----.+++++++++.---------.+++++.+++++++++++++++++.++++++++++++.++++++++++++++
|
|
||||||
+++++++++++++.++++++++.------------------.+++++++++++++.+.------------------
|
|
||||||
-----------------------------------------------------------------.++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------
|
|
||||||
---.----------------------------------------------------------------------.+
|
|
||||||
+++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++.++++++++++
|
|
||||||
+++.+.------.---------------------------------------------------------------
|
|
||||||
----------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++.+++++.-------------------------------------------------------------
|
|
||||||
-----------------.++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++.-----------------.++++++++.+++++.--------.--------
|
|
||||||
----------------------------------------------------.+++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++.++++++++.[-]+++++++++++++++++++++++++++.+
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------------
|
|
||||||
----------------------------.++++++++.----------.++++.+++++++++++++++++++.++
|
|
||||||
+++++++++++++.+++++++++++++++++++++++++++.---------.+++++++++++..-----------
|
|
||||||
----.+++++++++.-------------------------------------------------------------
|
|
||||||
-----------------.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++.+++++++++++++++++++++++.-------------------------------------------
|
|
||||||
----------------------------------------------.+++++++++++++++++++++++++++++
|
|
||||||
++++++.+++++++++++++++++++++++++++++++++++++++++.---.---..+++++++++.+++.----
|
|
||||||
----------.-----------------------------------------------------------------
|
|
||||||
---.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++
|
|
||||||
++++++++.---.------.--------------------------------------------------------
|
|
||||||
--------------.++++++++++++++++++++++++++++.++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++.++++++++++++..----.--------------------------------------------
|
|
||||||
----------.-----------..++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++...-----------------------------------------------------
|
|
||||||
--------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++.+
|
|
||||||
++++++++.---.---..+++++++++.+++.--------------.-----------------------------
|
|
||||||
-------------------------.++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+.+++++++++++++++++++.------------------------------------------------------
|
|
||||||
---------------.+++++++++++++++++++++++++++++++++++++++++++++++++++.++++.---
|
|
||||||
.+++++++++++++.+++++.-------------------------------------------------------
|
|
||||||
---------------.+++++++++++++++.[-]>[-]+++++++++>[-]+++>>[-]>[-]<<<<<[->>>>>
|
|
||||||
+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<
|
|
||||||
<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]
|
|
||||||
>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-
|
|
||||||
<<+>>]<<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<[>[-]++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++>[-]<<<<<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]<+++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++>]<<<[>>>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<<
|
|
||||||
->>>][-]++++++++++++++++>[-]++++++++++++++>>>>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<
|
|
||||||
<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[
|
|
||||||
[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+
|
|
||||||
<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>
|
|
||||||
>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<+++++>>>>]>[-]>[-
|
|
||||||
]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]+<<[-]+>>
|
|
||||||
>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
|
||||||
]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
|
||||||
[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<
|
|
||||||
[[-]<<<++++++++++>>>][-]>[-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<+<<<<<<<+
|
|
||||||
>>>>>>>>][-]+++++++++++++++++++++++++<<<[-]>>[>>[-]<[->+<]>[-<+<<<+>>>>]<<-]
|
|
||||||
[-]<<[->>+<<]>>[-<<+<<+>>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<<<<<<<
|
|
||||||
<+>>>>->>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>->>>>]>[-]
|
|
||||||
>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]++<<[-
|
|
||||||
]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+
|
|
||||||
>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>
|
|
||||||
>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>
|
|
||||||
]<<<[[-]<<<<----->>>>][-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<
|
|
||||||
+>>>>>>->>>][-]+++++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++.>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>
|
|
||||||
>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[
|
|
||||||
-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->
|
|
||||||
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<
|
|
||||||
+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]
|
|
||||||
>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<
|
|
||||||
<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>
|
|
||||||
+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>
|
|
||||||
>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[
|
|
||||||
-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>
|
|
||||||
]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+
|
|
||||||
+++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-
|
|
||||||
<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->
|
|
||||||
>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<
|
|
||||||
[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>
|
|
||||||
]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>
|
|
||||||
>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]
|
|
||||||
<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[
|
|
||||||
[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>
|
|
||||||
[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<
|
|
||||||
<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>
|
|
||||||
>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->
|
|
||||||
[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
|
||||||
+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[
|
|
||||||
-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<
|
|
||||||
<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>
|
|
||||||
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<
|
|
||||||
<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[-
|
|
||||||
>>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<+++
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<
|
|
||||||
]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<+++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.
|
|
||||||
>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]
|
|
||||||
<<]<<<<<<--------------------------------.>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>
|
|
||||||
>>[-<+<<<<<+>>>>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+++++
|
|
||||||
+++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<
|
|
||||||
+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+
|
|
||||||
<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]
|
|
||||||
>>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>
|
|
||||||
>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>
|
|
||||||
>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[
|
|
||||||
-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>
|
|
||||||
>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]
|
|
||||||
>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<
|
|
||||||
+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->
|
|
||||||
>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>
|
|
||||||
->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[
|
|
||||||
-]+>>]<]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>
|
|
||||||
>>]<<[-<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+++++
|
|
||||||
+++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[
|
|
||||||
[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[
|
|
||||||
->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+
|
|
||||||
>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+
|
|
||||||
<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>]
|
|
||||||
[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
|
||||||
+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>
|
|
||||||
[[-<<<+>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-
|
|
||||||
<<<+<<+>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>]
|
|
||||||
[-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<
|
|
||||||
<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>
|
|
||||||
[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]
|
|
||||||
<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>
|
|
||||||
[-]+<[[-<+>]<++++++++++++++++++++++++++++++++++++++++++++++++.<+++++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<+++++++
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++.>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++.>>>>>>]<<]<<<<<<+++++++++++++.>[-]>[-]<<<<<<<[->>>>>>>+<<<<<<<]>>>>
|
|
||||||
>>>[-<+<<<<<<+>>>>>>>][-]+++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
|
||||||
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>
|
|
||||||
>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<
|
|
||||||
+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<[-]<<<<<<<<[->>>>>>>>+<<<
|
|
||||||
<<<<<]>>>>>>[-]>>[-<<<<<<<<+>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..
|
|
||||||
>>>-]<<<.>>>>>[-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>[-]>>[-<<<<<<<<+>>>>>>+>>
|
|
||||||
][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]>>>[-]>[-]<<<<<<<[->>>>>>>+<<<<<
|
|
||||||
<<]>>>>>>>[-<+<<<<<<+>>>>>>>][-]++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>
|
|
||||||
[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>
|
|
||||||
+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]
|
|
||||||
>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]+++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<<<<<<<<]>>>[-]<<<<
|
|
||||||
<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]<<<<<<<[-]<[-]<[-]>>>>>>>>>>[-]<<<<<[->>>
|
|
||||||
>>+<<<<<]>>>>>[-<<<<<+<<<+>>>>>>>>][-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>]<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-
|
|
||||||
[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<[->>>>>+<<<<
|
|
||||||
<]>>>>>[[-<<<<<+>>>>>]<<<<<->>>>>]<]<<<<<+>>[-]+>>[-]>[-]<<<<<[->>>>>+<<<<<]
|
|
||||||
>>>>>[-<+<<<<+>>>>>][-]++++++++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>
|
|
||||||
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<
|
|
||||||
<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<
|
|
||||||
<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<]<<<[-]>[-]+>[-]++>[-]++++++++>[-]
|
|
||||||
+>[-]+[>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++<<[-]>>>[-]>[
|
|
||||||
-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<-
|
|
||||||
>->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>
|
|
||||||
]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<[>[-
|
|
||||||
]<<<<<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]>[-]>[-]>[-]>>[-]>[-]<<<<<<<<<<[->>>
|
|
||||||
>>>>>>>+<<<<<<<<<<]>>>>>>>>>>[-<+<<<<<<<<<+>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<
|
|
||||||
<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[
|
|
||||||
-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
|
||||||
][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<[-]
|
|
||||||
+>[-]+>>]>[-]>[-]<<<<<<<<<<[->>>>>>>>>>+<<<<<<<<<<]>>>>>>>>>>[-<+<<<<<<<<<+>
|
|
||||||
>>>>>>>>>][-]+++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]
|
|
||||||
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[-
|
|
||||||
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->
|
|
||||||
+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<[-]+>>[-]+>][-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-
|
|
||||||
]>>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>[-]>[-<
|
|
||||||
<<<<<<<<<<<<<<+>>>>>>>>>>>>>>+>]<[<+>-]>[-]<<<<<<<<<<<<<<[->>>>>>>>>>>>>>+<<
|
|
||||||
<<<<<<<<<<<<]>>>>>>>>>>>>>[-]>[-<<<<<<<<<<<<<<+>>>>>>>>>>>>>+>]<[<+++>-]>[-]
|
|
||||||
<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>[-]>[-<<<<<<<<<<<<<+>
|
|
||||||
>>>>>>>>>>>+>]<[<+++++++++>-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<[->>+<<]>>[-<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<
|
|
||||||
<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>
|
|
||||||
>-]<<[>>>>]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>[-]<<<<<<<<<<<<[->>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>>>>>>>[-<
|
|
||||||
<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<
|
|
||||||
<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<+<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]
|
|
||||||
<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<
|
|
||||||
<<]>>>>>>>>>>>[-<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<
|
|
||||||
<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<
|
|
||||||
<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<
|
|
||||||
<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>+>>>>>>>>>>>>>][-]<<[->>+<<]>>[[-<<+>>]>[-]<<<<<<<<<<<<[->>>>
|
|
||||||
>>>>>>>>+<<<<<<<<<<<<]>>>>>[-]>>>>>>>[-<<<<<<<<<<<<+>>>>>+>>>>>>>][-]<<<<<<<
|
|
||||||
<<<<[->>>>>>>>>>>+<<<<<<<<<<<]<[-]>>>>>>>>>>>>[-<<<<<<<<<<<+<+>>>>>>>>>>>>][
|
|
||||||
-]<<<<<<<[->>>>>>>+<<<<<<<]<<<<[-]>>>>>>>>>>>[-<<<<<<<+<<<<+>>>>>>>>>>>]<<<<
|
|
||||||
<<<<<<->[-]>+>>>>>>>][-]<[->+<]>[[-<+>]>[-]<<<<<<<<<<<<[->>>>>>>>>>>>+<<<<<<
|
|
||||||
<<<<<<]>>>>>[-]>>>>>>>[-<<<<<<<<<<<<+>>>>>+>>>>>>>][-]<<<<<<<<<<<<<[->>>>>>>
|
|
||||||
>>>>>>+<<<<<<<<<<<<<]>[-]>>>>>>>>>>>>[-<<<<<<<<<<<<<+>+>>>>>>>>>>>>][-]<<<<<
|
|
||||||
<<[->>>>>>>+<<<<<<<]<<<<<<[-]>>>>>>>>>>>>>[-<<<<<<<+<<<<<<+>>>>>>>>>>>>>]<<<
|
|
||||||
<<<<<<<->[-]>+>>>>>>>]<<<<]>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<+<<<<<+>>>
|
|
||||||
>>>][-]++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<
|
|
||||||
<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<
|
|
||||||
]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-
|
|
||||||
<+>]<<<[-]>>>]<<<[[-]>>>>[-]++>>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<
|
|
||||||
<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]<<[-]+>>>[-
|
|
||||||
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[
|
|
||||||
<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
|
||||||
+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-
|
|
||||||
]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]>[-]<<<<<<<<<<<<<<<[-
|
|
||||||
>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>
|
|
||||||
>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
|
||||||
<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<
|
|
||||||
<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[
|
|
||||||
-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<
|
|
||||||
<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]++<<[-]+>>
|
|
||||||
>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
|
||||||
]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
|
||||||
[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<
|
|
||||||
[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]
|
|
||||||
>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<
|
|
||||||
<<<<<<<<<<+>>>>>>>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-
|
|
||||||
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<
|
|
||||||
+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<
|
|
||||||
[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>
|
|
||||||
>>>>>>>>>>[-]>>>>>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<
|
|
||||||
<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+
|
|
||||||
<<<<]<<>>>>]>>[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<
|
|
||||||
<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>
|
|
||||||
>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>
|
|
||||||
>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->
|
|
||||||
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+
|
|
||||||
<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>[-]>>>>>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]
|
|
||||||
<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>
|
|
||||||
>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]++<<[
|
|
||||||
-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
|
||||||
+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
|
||||||
>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>
|
|
||||||
>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-
|
|
||||||
]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>[-]<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]<<<<]<<
|
|
||||||
[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<
|
|
||||||
<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>
|
|
||||||
>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
|
||||||
>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>
|
|
||||||
[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]
|
|
||||||
<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>[-]<<<<<[->>>>>
|
|
||||||
+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<+>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>
|
|
||||||
>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+
|
|
||||||
>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<
|
|
||||||
<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>
|
|
||||||
][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
|
||||||
>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>
|
|
||||||
[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]
|
|
||||||
<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]
|
|
||||||
<<<<<[->>>>>+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<
|
|
||||||
]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<[
|
|
||||||
->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]
|
|
||||||
++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
|
||||||
<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
|
||||||
<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<
|
|
||||||
[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-
|
|
||||||
]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<[->>
|
|
||||||
>>>+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<
|
|
||||||
<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>
|
|
||||||
>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
|
||||||
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>
|
|
||||||
>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<
|
|
||||||
+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>+>>>]<]>[-]>[-]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>
|
|
||||||
>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>
|
|
||||||
>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->
|
|
||||||
>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<
|
|
||||||
<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>]<]>[-]>[-]
|
|
||||||
<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>
|
|
||||||
>>>>>>>>>>][-]++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]
|
|
||||||
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[-
|
|
||||||
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->
|
|
||||||
+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>+>>>]<]<[->>>>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]>>[-]<<
|
|
||||||
<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>[-]>>>>
|
|
||||||
>[-<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>+>>>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>
|
|
||||||
>[-]>>>>[-<<<<<<<<+>>>>+>>>>]<<<[-]++++++++++++++++++++++++++++++++>>-<]>[[-
|
|
||||||
]>[-]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>[-]>>>>>
|
|
||||||
[-<<<<<<<<<<<<<<<<+>>>>>>>>>>>+>>>>>][-]<<<<<<<[->>>>>>>+<<<<<<<]>>>[-]>>>>[
|
|
||||||
-<<<<<<<+>>>+>>>>]<<<[-]++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++>>]<[-]++++++++++++++++>[-]+++++++++++++
|
|
||||||
+>>>>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][
|
|
||||||
-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
|
||||||
<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
|
||||||
<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<
|
|
||||||
[-]>>>]<<<[[-]<<<<+++++>>>>]>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>
|
|
||||||
[-<+<<<<<<<<+>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<
|
|
||||||
<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>
|
|
||||||
>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]
|
|
||||||
>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<++++++++++>>>][-]>[-]<<<<<<<<[->>>
|
|
||||||
>>>>>+<<<<<<<<]>>>>>>>>[-<+<<<<<<<+>>>>>>>>][-]+++++++++++++++++++++++++<<<[
|
|
||||||
-]>>[>>[-]<[->+<]>[-<+<<<+>>>>]<<-][-]<<[->>+<<]>>[-<<+<<+>>>>][-]<<<<<<<<<<
|
|
||||||
<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>[-<<<<<<<<<<<+>>>>>>>->>>>][-]<<<<<<<<
|
|
||||||
<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>[-<<<<<<<<<<<+>>>>>>>->>>>]>[-]>[-]<
|
|
||||||
<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]++<<[-]+>>>
|
|
||||||
[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]
|
|
||||||
<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[
|
|
||||||
-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[
|
|
||||||
[-]<<<<----->>>>][-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<<<<<<+>>>->>>][-]++++++++
|
|
||||||
+++++++++++++++++++.++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++.>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>]>>>[-]>[-]<<<<<[->>>
|
|
||||||
>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>
|
|
||||||
+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
|
||||||
[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]
|
|
||||||
>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<
|
|
||||||
<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>
|
|
||||||
[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[
|
|
||||||
-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
|
||||||
]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<
|
|
||||||
<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<
|
|
||||||
<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<
|
|
||||||
<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+
|
|
||||||
<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
|
||||||
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<
|
|
||||||
+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>
|
|
||||||
>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>
|
|
||||||
[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
|
||||||
>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>
|
|
||||||
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<
|
|
||||||
<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++
|
|
||||||
>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>
|
|
||||||
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]
|
|
||||||
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]
|
|
||||||
<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<
|
|
||||||
<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+
|
|
||||||
<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>
|
|
||||||
>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-
|
|
||||||
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]
|
|
||||||
<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.<++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<
|
|
||||||
<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>-<]>[[-]<<<<<<+++
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]<<]<<<<<<--------------
|
|
||||||
------------------.>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<+<<<<<+>>>>>>]>>>[
|
|
||||||
-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->
|
|
||||||
>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]
|
|
||||||
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>
|
|
||||||
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]>[[-<+>
|
|
||||||
]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<<<<<[->
|
|
||||||
>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-
|
|
||||||
]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<
|
|
||||||
<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[-
|
|
||||||
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<
|
|
||||||
<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++
|
|
||||||
++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
|
||||||
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<
|
|
||||||
<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<[-]>>>>
|
|
||||||
>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>]>]<<<[
|
|
||||||
-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-
|
|
||||||
]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>
|
|
||||||
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+
|
|
||||||
>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>
|
|
||||||
>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>
|
|
||||||
>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]
|
|
||||||
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]
|
|
||||||
<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
|
||||||
]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[-<<<->>
|
|
||||||
>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>
|
|
||||||
>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-
|
|
||||||
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>
|
|
||||||
[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>
|
|
||||||
>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<]>[[-]>
|
|
||||||
[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>-
|
|
||||||
<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]<<]<<<<
|
|
||||||
<<+++++++++++++.>[-]>[-]<<<<<<<[->>>>>>>+<<<<<<<]>>>>>>>[-<+<<<<<<+>>>>>>>][
|
|
||||||
-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>
|
|
||||||
>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>
|
|
||||||
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<
|
|
||||||
]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]+++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++.<-<]>[[-]<<<<<<.>>>>>>]<[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>
|
|
||||||
>[-]>>[-<<<<<<<<<<<+>>>>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]
|
|
||||||
<<<.>>>>>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>[-]>>[-<<<<<<<<<<<
|
|
||||||
+>>>>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]>>>[-]>[-]<<<<<<<[-
|
|
||||||
>>>>>>>+<<<<<<<]>>>>>>>[-<+<<<<<<+>>>>>>>][-]+++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<
|
|
||||||
[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-
|
|
||||||
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]
|
|
||||||
[-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[
|
|
||||||
-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<<<<<<
|
|
||||||
<<<]>[-]++++++++++.[-]+>[-]+>[-]+++++++++++++++++++++++++++.++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++.>[-]>[-]<<<[->>>+<<<]>>>[-<
|
|
||||||
+<<+>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<
|
|
||||||
[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<
|
|
||||||
<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[
|
|
||||||
-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[
|
|
||||||
->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]
|
|
||||||
>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<
|
|
||||||
<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+
|
|
||||||
<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
|
||||||
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]
|
|
||||||
<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>
|
|
||||||
][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>
|
|
||||||
>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<
|
|
||||||
<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<
|
|
||||||
<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<
|
|
||||||
->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[
|
|
||||||
-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>
|
|
||||||
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]
|
|
||||||
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+
|
|
||||||
<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>
|
|
||||||
[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<
|
|
||||||
[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<
|
|
||||||
->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
|
||||||
<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>
|
|
||||||
>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++
|
|
||||||
++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<
|
|
||||||
<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>
|
|
||||||
>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-
|
|
||||||
]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>
|
|
||||||
]<++++++++++++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>
|
|
||||||
>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++.>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>
|
|
||||||
>>>>]<<]<<<<<<--------------------------------.>[-]>[-]<<<<[->>>>+<<<<]>>>>[
|
|
||||||
-<+<<<+>>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[
|
|
||||||
-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>
|
|
||||||
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>
|
|
||||||
>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[
|
|
||||||
-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<
|
|
||||||
<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>
|
|
||||||
[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[-
|
|
||||||
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<
|
|
||||||
<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<
|
|
||||||
+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>
|
|
||||||
>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<
|
|
||||||
<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[
|
|
||||||
-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
|
||||||
]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-
|
|
||||||
<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<
|
|
||||||
<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+
|
|
||||||
>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<
|
|
||||||
<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[
|
|
||||||
->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>
|
|
||||||
>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]
|
|
||||||
<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
|
||||||
[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
|
||||||
>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+
|
|
||||||
>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++
|
|
||||||
++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>
|
|
||||||
[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<
|
|
||||||
[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]
|
|
||||||
+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[
|
|
||||||
-<+>]<++++++++++++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++.>>>>>>-<]>[[-]<<<<<<+++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+.>>>>>>]<<]<<<<<<+++++++++++++.<<[-]+++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++[>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[>[-]+++++++++
|
|
||||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
+++++++++++++++[-]<-]<-]<<<<<]<<<<+>>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<
|
|
||||||
<<+>>>>>][-]++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>
|
|
||||||
>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->
|
|
||||||
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]+>>>][-]<[->
|
|
||||||
+<]>[[-<+>]<<<[-]+>>>]<<<]<<->>[-]<<[->>+<<]>>[[-<<+>>]<<<<<<<<-<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>
|
|
||||||
>>>>>>>>[-<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>
|
|
||||||
>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>[-]>>>>>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<+<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>
|
|
||||||
-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-
|
|
||||||
]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>[-]<<<<<<<<<[
|
|
||||||
->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>
|
|
||||||
>>-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
[-]>[-]>>>>>>>[-]++++++++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>
|
|
||||||
>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>
|
|
||||||
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<
|
|
||||||
<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[->+<]>[[-<+>]<<<[-]+
|
|
||||||
>>>]<<<[<<<<<<<<--------->>+>>>>>>>[-]++++++++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>
|
|
||||||
>>+<<<<<<<<<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>
|
|
||||||
>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-
|
|
||||||
]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<
|
|
||||||
[->+<]>[[-<+>]<<<[-]+>>>]<<<]>[-]++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<
|
|
||||||
<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[
|
|
||||||
-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<
|
|
||||||
<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[->+<]>[[-<
|
|
||||||
+>]<<<[-]+>>>]<<<[<<<<<<<<--->+>>>>>>>>[-]++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>
|
|
||||||
+<<<<<<<<<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+
|
|
||||||
<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<
|
|
||||||
<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[-
|
|
||||||
>+<]>[[-<+>]<<<[-]+>>>]<<<]<<<<+>>>]<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
|
|
@ -1,212 +0,0 @@
|
||||||
A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
|
|
||||||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++
|
|
||||||
+++++++-[[>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[
|
|
||||||
-]<<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+<<<<<<<<>+++++<>[<>-
|
|
||||||
<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>>+<<<<<<<<>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>[<<<>>>
|
|
||||||
>>>>>>[>>>>>>>[-]<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[-]+<<<<<<<
|
|
||||||
>++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<>++
|
|
||||||
+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<<<<
|
|
||||||
<<<<<<[<<<<<<<<<]>>>[<<<>>>[-]<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<
|
|
||||||
<<<<<>[-<>>>>>>>+<<<<<<<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<
|
|
||||||
]>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>
|
|
||||||
>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[<<<<<<<>>>>>>
|
|
||||||
>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>+++++++++
|
|
||||||
+++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<
|
|
||||||
<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>
|
|
||||||
>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+<<
|
|
||||||
>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<
|
|
||||||
<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>
|
|
||||||
>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->
|
|
||||||
>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[
|
|
||||||
<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>
|
|
||||||
>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>>>
|
|
||||||
]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>
|
|
||||||
>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<
|
|
||||||
<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>>>
|
|
||||||
+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<
|
|
||||||
>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[-
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>
|
|
||||||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-<<
|
|
||||||
<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>
|
|
||||||
>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<
|
|
||||||
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
|
||||||
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++
|
|
||||||
+++++++++++++++++++++<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>[-]<<]>>[<<<<<<<
|
|
||||||
+<[-<+>>>>+<<[-]]>[-><<<[->+>>>-<<<<]>>>]>>>>>>>>>>>>>[>>[-]<<>>>[-]<<<>
|
|
||||||
>>>[-]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>>>>>>[>>>>>[-<<<<<>
|
|
||||||
+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>
|
|
||||||
>>>[>>[-<<<<<<<<<+>>>>>>>>>]<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++
|
|
||||||
+++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<
|
|
||||||
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<
|
|
||||||
<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>[-<<+
|
|
||||||
>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>
|
|
||||||
>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<
|
|
||||||
<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<
|
|
||||||
<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<[->+<]>>>]<<<
|
|
||||||
>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>
|
|
||||||
>>>>>+<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>
|
|
||||||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>
|
|
||||||
>>+<<<<<<[->>[-<<+>>]<<[->>+<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]
|
|
||||||
<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>
|
|
||||||
>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>
|
|
||||||
>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<
|
|
||||||
<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[
|
|
||||||
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<<<<
|
|
||||||
<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<
|
|
||||||
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]
|
|
||||||
<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>
|
|
||||||
>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>
|
|
||||||
>>>-<<<<<>>>>-<<<<+>>>>>]<<<<<>>>>>>[<<<<<<>>>>>>-<<<<<<[->>>>>+<<<<<>>>
|
|
||||||
>+<<<<>>>>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>
|
|
||||||
>>>>]<<<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>+<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]>
|
|
||||||
>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>[-<<->>]+<<
|
|
||||||
[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[
|
|
||||||
>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+>>]<<[->>+<<<<<<<<<<<[<
|
|
||||||
<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<
|
|
||||||
<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>
|
|
||||||
>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>
|
|
||||||
+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>>+<<<<<<>>>]
|
|
||||||
<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>>
|
|
||||||
+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>
|
|
||||||
>>>+<<<<<<>>>]<<<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>
|
|
||||||
>[>+<>>[-<<>-<>>]<<>[-<>>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>+<<<<<<>
|
|
||||||
>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>[-<<>>>>>>+<<<<<<>>]<<>>>]<<<
|
|
||||||
>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>]<>>>[-<<<>>>>>>+<<<<<<>>[
|
|
||||||
-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>>>]<<<>>[-<<>>>>>>+<<<<<<>>]<
|
|
||||||
<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>>>>>
|
|
||||||
>>>>]<<<<<<<<<[>[-<>>>>>>+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><
|
|
||||||
>>>[-<<<>>>>>>+<<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>
|
|
||||||
>><>>>]<<<>]<>>[-<<>>>>>>+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>
|
|
||||||
><>>>]<<<>>]<<>>>[-<<<>>>>>>+<<<<<<>>>]<<<<<<<<<<<<]]>[-]<>>>[-]<<<>>>>[
|
|
||||||
-]<<<<>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[
|
|
||||||
>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<
|
|
||||||
<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[
|
|
||||||
-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>
|
|
||||||
>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<
|
|
||||||
<<<<[->>[-<<+>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>
|
|
||||||
>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<
|
|
||||||
<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>
|
|
||||||
>>>>>]<<<<<<<<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<
|
|
||||||
[->+<]>>>]<<<>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<
|
|
||||||
<<<<<<<[<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<
|
|
||||||
<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[-+>>>[-<<<->>>
|
|
||||||
]+<<<[->>>-<<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]
|
|
||||||
+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+
|
|
||||||
>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<
|
|
||||||
]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>
|
|
||||||
]<<<[->>>+<<<>>>>>>>>>[>+<>>>>[-<<<<>-<>>>>]<<<<>[-<>>>>+<<<<>]<>>>>>>>>
|
|
||||||
>]<<<<<<<<<>+<[>[-<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>[-<<<<>>+<
|
|
||||||
<>>>>]<<<<>>>]<<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>]<>>>[-<<
|
|
||||||
<>>+<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>>>]<<<>>>>[-<<<<>>+<
|
|
||||||
<>>>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<
|
|
||||||
<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>+<<>>>>[-<<<<>>-<<
|
|
||||||
><<<<<<<<<+>>>>>>>>><>>>[-<<<>>+<<>>>]<<<>>>>]<<<<>>>[-<<<>>-<<><<<<<<<<
|
|
||||||
<+>>>>>>>>><>>>]<<<>]<>>>>[-<<<<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>
|
|
||||||
>>]<<<>>>>]<<<<>>>[-<<<>>+<<>>>]<<<<<<<<<<<<]>>>>>+<<<<<]>>>>>>>>>[>>>[-
|
|
||||||
]<<<>>>>[-]<<<<>>>>>[-]<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>[
|
|
||||||
-]<<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<>>>
|
|
||||||
+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>
|
|
||||||
-<<<<+>>>>>]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<[->>>>>+<<<<<>>>>+<<<<>>>
|
|
||||||
>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>>>>>>]<<<
|
|
||||||
<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]+>>>>[
|
|
||||||
-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+
|
|
||||||
>>]<<[->>+<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>
|
|
||||||
[-<<->>]+<<[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<
|
|
||||||
<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<
|
|
||||||
<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>>[>+<>>[-<<>-<>>]<<>[-<>
|
|
||||||
>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<
|
|
||||||
<<+>>>>>>>>><>>[-<<>>>>>+<<<<<>>]<<>>>]<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>
|
|
||||||
>>>>>>><>>]<<>]<>>>[-<<<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>>
|
|
||||||
<>>]<<>>>]<<<>>[-<<>>>>>+<<<<<>>]<<<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>[<<<<<<
|
|
||||||
<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]]>>>>[-<<<<
|
|
||||||
+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>
|
|
||||||
>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>
|
|
||||||
>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>
|
|
||||||
]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>
|
|
||||||
>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>>>]<<<
|
|
||||||
<[->>>>+<<<<>>>>>[-]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[
|
|
||||||
->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-<>>>>>+<<<<
|
|
||||||
<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>
|
|
||||||
>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<
|
|
||||||
<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<
|
|
||||||
<<<<<<<<]]>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]
|
|
||||||
<<<>>>>[-]<<<<>>>>>>>>>[>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]
|
|
||||||
<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>
|
|
||||||
[-<>>>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++
|
|
||||||
+++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<
|
|
||||||
<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>
|
|
||||||
>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+
|
|
||||||
<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<
|
|
||||||
<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>
|
|
||||||
>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<
|
|
||||||
->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<
|
|
||||||
>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]
|
|
||||||
>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>
|
|
||||||
>>]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[
|
|
||||||
>>>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<
|
|
||||||
<<<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>
|
|
||||||
>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<
|
|
||||||
<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>
|
|
||||||
[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>
|
|
||||||
>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-
|
|
||||||
<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>
|
|
||||||
>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<
|
|
||||||
<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<
|
|
||||||
<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>-<<>>>>[-<<<<+>>>>]<<<<[->>>>+
|
|
||||||
<<<<>>[-]<<]>>]<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[<<<<>>>>-<<
|
|
||||||
<<<<<.>>>>>>>]<<<<>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<>>>>>>>>>[>[-]>[-]>[-]>[
|
|
||||||
-]>[-]>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]<<<<<>>>
|
|
||||||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<
|
|
||||||
>]<>>>>>>>>>>]<>>>>>+<<<<<>>>>>>>>>>>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>
|
|
||||||
>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>[-]<<<<<<<>>>>>>>>>[>>
|
|
||||||
>>>>>>>]<<<<<<<<<[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<[
|
|
||||||
<<<<<<<<<]>>>>>>>[-]+<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>[-<<<<<<<+>>>>
|
|
||||||
>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>>>[>+<>>>>>[-<<<<<>-<>>>>>]<<<<<>[-<>
|
|
||||||
>>>>+<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>+<<<<<<<[>>>>>[<<<<<>>>>>-<<<<<>>
|
|
||||||
>>>>>+<<<<<<<>>>>>]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<->>
|
|
||||||
>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>>]<
|
|
||||||
[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>>>>>>>-<<<<<<<>
|
|
||||||
>>[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>>>>>[>
|
|
||||||
>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<
|
|
||||||
->>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>
|
|
||||||
>]<[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<
|
|
||||||
>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>+<<<<<[<<<<<<<<<]>>>>>>>>
|
|
||||||
>[-+>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>-<<<<<>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<
|
|
||||||
<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>
|
|
||||||
+<]]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>[-<<<<<+>>>>
|
|
||||||
>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[
|
|
||||||
-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<
|
|
||||||
<<<>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>-<<<<<[<<
|
|
||||||
<<<<<<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<
|
|
||||||
<]>+++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<
|
|
||||||
<<>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]
|
|
||||||
<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>[-]<<<<<<<<>>>>>>>>>[>>>>>>>>>]<<<<<<
|
|
||||||
<<<[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<[<<<<<<<<
|
|
||||||
<]>>>>>>>>[-]+<<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<<<<+>>>>>>>>
|
|
||||||
]<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>>[>+<>>>>>>[-<<<<<<>-<>>>>>>]<<<<<<>
|
|
||||||
[-<>>>>>>+<<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>>+<<<<<<<<[>>>>>>[<<<<<<>>>
|
|
||||||
>>>-<<<<<<>>>>>>>>+<<<<<<<<>>>>>>]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<
|
|
||||||
<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>
|
|
||||||
>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<<<>[<>-<>>>>>>>>+<<<<<<<<>]<+
|
|
||||||
<<<<<<<<<]>>>>>>>>-<<<<<<<<>>>[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
|
||||||
<<<<[->>>>>>>>-<<<<<<<<>>>>>>>>>[>>>>>>[<<<<<<>>>>>>-<<<<<<>>>>>>>>+<<<<
|
|
||||||
<<<<>>>>>>]<<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<
|
|
||||||
<<<<<+>[<->-<<<<<<<<<<>>>>>>>>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<
|
|
||||||
<<>[<>-<>>>>>>>>+<<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<
|
|
||||||
<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
|
||||||
<<<[<<<<<<<<<]>>>>>>>>>[-+>>>>>>[-<<<<<<->>>>>>]+<<<<<<[->>>>>>-<<<<<<>>
|
|
||||||
>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<
|
|
||||||
]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
|
||||||
<<<<[->>>>>>>>-<<<<<<<<>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<
|
|
||||||
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
|
||||||
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<<>+++++<>[<>-<>[<>-<>>>>
|
|
||||||
>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>-<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>-<<<<<<[<<<<<<<<<]]>>>]<<<
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
use criterion::{black_box, criterion_main, Criterion};
|
|
||||||
|
|
||||||
struct MockReadWrite;
|
|
||||||
|
|
||||||
impl Read for MockReadWrite {
|
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
|
||||||
buf.fill(b'A');
|
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Write for MockReadWrite {
|
|
||||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
|
||||||
Ok(buf.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_bf(bf: &str) {
|
|
||||||
let bump = Bump::new();
|
|
||||||
let ast = brainfuck::parse::parse(&bump, bf.bytes().enumerate()).unwrap();
|
|
||||||
let hir = brainfuck::hir::optimized_hir(&bump, &ast);
|
|
||||||
let lir = brainfuck::lir::generate(&bump, &hir);
|
|
||||||
brainfuck::lir::interpreter::run(&lir, MockReadWrite, MockReadWrite, |_| {});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn optimized(c: &mut Criterion) {
|
|
||||||
let fizzbuzz = include_str!("fizzbuzz.bf");
|
|
||||||
let bench = include_str!("bench.bf");
|
|
||||||
let twinkle = include_str!("twinkle.bf");
|
|
||||||
let bottles = include_str!("bottles.bf");
|
|
||||||
let mandelbrot = include_str!("mandelbrot.bf");
|
|
||||||
let hanoi = include_str!("hanoi.bf");
|
|
||||||
|
|
||||||
c.bench_function("fizzbuzz", |b| b.iter(|| run_bf(black_box(fizzbuzz))));
|
|
||||||
c.bench_function("bench", |b| b.iter(|| run_bf(black_box(bench))));
|
|
||||||
c.bench_function("twinkle", |b| b.iter(|| run_bf(black_box(twinkle))));
|
|
||||||
c.bench_function("bottles", |b| b.iter(|| run_bf(black_box(bottles))));
|
|
||||||
c.bench_function("mandelbrot", |b| b.iter(|| run_bf(black_box(mandelbrot))));
|
|
||||||
c.bench_function("hanoi", |b| b.iter(|| run_bf(black_box(hanoi))));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn benches() {
|
|
||||||
// we need such a low sample size because the benches take ages otherwise
|
|
||||||
let mut c = Criterion::default().configure_from_args().sample_size(30);
|
|
||||||
optimized(&mut c);
|
|
||||||
}
|
|
||||||
|
|
||||||
criterion_main!(benches);
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1,212 +0,0 @@
|
||||||
A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
|
|
||||||
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++
|
|
||||||
+++++++-[[>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[
|
|
||||||
-]<<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+<<<<<<<<>+++++<>[<>-
|
|
||||||
<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>>+<<<<<<<<>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>[<<<>>>
|
|
||||||
>>>>>>[>>>>>>>[-]<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[-]+<<<<<<<
|
|
||||||
>++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<>++
|
|
||||||
+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<<<<
|
|
||||||
<<<<<<[<<<<<<<<<]>>>[<<<>>>[-]<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<
|
|
||||||
<<<<<>[-<>>>>>>>+<<<<<<<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<
|
|
||||||
]>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>
|
|
||||||
>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[<<<<<<<>>>>>>
|
|
||||||
>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>+++++++++
|
|
||||||
+++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<
|
|
||||||
<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>
|
|
||||||
>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+<<
|
|
||||||
>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<
|
|
||||||
<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>
|
|
||||||
>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->
|
|
||||||
>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[
|
|
||||||
<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>
|
|
||||||
>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>>>
|
|
||||||
]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>
|
|
||||||
>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<
|
|
||||||
<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>>>
|
|
||||||
+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<
|
|
||||||
>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[-
|
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>
|
|
||||||
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-<<
|
|
||||||
<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>
|
|
||||||
>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<
|
|
||||||
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
|
||||||
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++
|
|
||||||
+++++++++++++++++++++<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>[-]<<]>>[<<<<<<<
|
|
||||||
+<[-<+>>>>+<<[-]]>[-><<<[->+>>>-<<<<]>>>]>>>>>>>>>>>>>[>>[-]<<>>>[-]<<<>
|
|
||||||
>>>[-]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>>>>>>[>>>>>[-<<<<<>
|
|
||||||
+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>
|
|
||||||
>>>[>>[-<<<<<<<<<+>>>>>>>>>]<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++
|
|
||||||
+++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<
|
|
||||||
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<
|
|
||||||
<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>[-<<+
|
|
||||||
>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>
|
|
||||||
>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<
|
|
||||||
<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<
|
|
||||||
<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<[->+<]>>>]<<<
|
|
||||||
>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>
|
|
||||||
>>>>>+<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>
|
|
||||||
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>
|
|
||||||
>>+<<<<<<[->>[-<<+>>]<<[->>+<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]
|
|
||||||
<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>
|
|
||||||
>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>
|
|
||||||
>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<
|
|
||||||
<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[
|
|
||||||
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<<<<
|
|
||||||
<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<
|
|
||||||
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]
|
|
||||||
<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>
|
|
||||||
>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>
|
|
||||||
>>>-<<<<<>>>>-<<<<+>>>>>]<<<<<>>>>>>[<<<<<<>>>>>>-<<<<<<[->>>>>+<<<<<>>>
|
|
||||||
>+<<<<>>>>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>
|
|
||||||
>>>>]<<<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>+<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]>
|
|
||||||
>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>[-<<->>]+<<
|
|
||||||
[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[
|
|
||||||
>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+>>]<<[->>+<<<<<<<<<<<[<
|
|
||||||
<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<
|
|
||||||
<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>
|
|
||||||
>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>
|
|
||||||
+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>>+<<<<<<>>>]
|
|
||||||
<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>>
|
|
||||||
+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>
|
|
||||||
>>>+<<<<<<>>>]<<<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>
|
|
||||||
>[>+<>>[-<<>-<>>]<<>[-<>>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>+<<<<<<>
|
|
||||||
>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>[-<<>>>>>>+<<<<<<>>]<<>>>]<<<
|
|
||||||
>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>]<>>>[-<<<>>>>>>+<<<<<<>>[
|
|
||||||
-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>>>]<<<>>[-<<>>>>>>+<<<<<<>>]<
|
|
||||||
<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>>>>>
|
|
||||||
>>>>]<<<<<<<<<[>[-<>>>>>>+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><
|
|
||||||
>>>[-<<<>>>>>>+<<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>
|
|
||||||
>><>>>]<<<>]<>>[-<<>>>>>>+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>
|
|
||||||
><>>>]<<<>>]<<>>>[-<<<>>>>>>+<<<<<<>>>]<<<<<<<<<<<<]]>[-]<>>>[-]<<<>>>>[
|
|
||||||
-]<<<<>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[
|
|
||||||
>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<
|
|
||||||
<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[
|
|
||||||
-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>
|
|
||||||
>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<
|
|
||||||
<<<<[->>[-<<+>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>
|
|
||||||
>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<
|
|
||||||
<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>
|
|
||||||
>>>>>]<<<<<<<<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<
|
|
||||||
[->+<]>>>]<<<>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<
|
|
||||||
<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<
|
|
||||||
<<<<<<<[<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<
|
|
||||||
<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[-+>>>[-<<<->>>
|
|
||||||
]+<<<[->>>-<<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]
|
|
||||||
+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+
|
|
||||||
>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<
|
|
||||||
]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>
|
|
||||||
]<<<[->>>+<<<>>>>>>>>>[>+<>>>>[-<<<<>-<>>>>]<<<<>[-<>>>>+<<<<>]<>>>>>>>>
|
|
||||||
>]<<<<<<<<<>+<[>[-<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>[-<<<<>>+<
|
|
||||||
<>>>>]<<<<>>>]<<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>]<>>>[-<<
|
|
||||||
<>>+<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>>>]<<<>>>>[-<<<<>>+<
|
|
||||||
<>>>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<
|
|
||||||
<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>+<<>>>>[-<<<<>>-<<
|
|
||||||
><<<<<<<<<+>>>>>>>>><>>>[-<<<>>+<<>>>]<<<>>>>]<<<<>>>[-<<<>>-<<><<<<<<<<
|
|
||||||
<+>>>>>>>>><>>>]<<<>]<>>>>[-<<<<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>
|
|
||||||
>>]<<<>>>>]<<<<>>>[-<<<>>+<<>>>]<<<<<<<<<<<<]>>>>>+<<<<<]>>>>>>>>>[>>>[-
|
|
||||||
]<<<>>>>[-]<<<<>>>>>[-]<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>[
|
|
||||||
-]<<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<>>>
|
|
||||||
+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>
|
|
||||||
-<<<<+>>>>>]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<[->>>>>+<<<<<>>>>+<<<<>>>
|
|
||||||
>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>>>>>>]<<<
|
|
||||||
<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]+>>>>[
|
|
||||||
-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+
|
|
||||||
>>]<<[->>+<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>
|
|
||||||
[-<<->>]+<<[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<
|
|
||||||
<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<
|
|
||||||
<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>>[>+<>>[-<<>-<>>]<<>[-<>
|
|
||||||
>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<
|
|
||||||
<<+>>>>>>>>><>>[-<<>>>>>+<<<<<>>]<<>>>]<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>
|
|
||||||
>>>>>>><>>]<<>]<>>>[-<<<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>>
|
|
||||||
<>>]<<>>>]<<<>>[-<<>>>>>+<<<<<>>]<<<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>[<<<<<<
|
|
||||||
<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]]>>>>[-<<<<
|
|
||||||
+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>
|
|
||||||
>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>
|
|
||||||
>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>
|
|
||||||
]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>
|
|
||||||
>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>>>]<<<
|
|
||||||
<[->>>>+<<<<>>>>>[-]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[
|
|
||||||
->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-<>>>>>+<<<<
|
|
||||||
<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>
|
|
||||||
>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<
|
|
||||||
<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<
|
|
||||||
<<<<<<<<]]>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]
|
|
||||||
<<<>>>>[-]<<<<>>>>>>>>>[>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]
|
|
||||||
<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>
|
|
||||||
[-<>>>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++
|
|
||||||
+++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<
|
|
||||||
<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>
|
|
||||||
>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+
|
|
||||||
<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<
|
|
||||||
<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>
|
|
||||||
>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<
|
|
||||||
->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<
|
|
||||||
>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]
|
|
||||||
>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>
|
|
||||||
>>]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[
|
|
||||||
>>>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<
|
|
||||||
<<<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>
|
|
||||||
>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<
|
|
||||||
<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>
|
|
||||||
[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>
|
|
||||||
>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-
|
|
||||||
<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>
|
|
||||||
>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<
|
|
||||||
<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<
|
|
||||||
<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>-<<>>>>[-<<<<+>>>>]<<<<[->>>>+
|
|
||||||
<<<<>>[-]<<]>>]<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[<<<<>>>>-<<
|
|
||||||
<<<<<.>>>>>>>]<<<<>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<>>>>>>>>>[>[-]>[-]>[-]>[
|
|
||||||
-]>[-]>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]<<<<<>>>
|
|
||||||
>>>>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<
|
|
||||||
>]<>>>>>>>>>>]<>>>>>+<<<<<>>>>>>>>>>>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>
|
|
||||||
>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>[-]<<<<<<<>>>>>>>>>[>>
|
|
||||||
>>>>>>>]<<<<<<<<<[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<[
|
|
||||||
<<<<<<<<<]>>>>>>>[-]+<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>[-<<<<<<<+>>>>
|
|
||||||
>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>>>[>+<>>>>>[-<<<<<>-<>>>>>]<<<<<>[-<>
|
|
||||||
>>>>+<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>+<<<<<<<[>>>>>[<<<<<>>>>>-<<<<<>>
|
|
||||||
>>>>>+<<<<<<<>>>>>]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<->>
|
|
||||||
>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>>]<
|
|
||||||
[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>>>>>>>-<<<<<<<>
|
|
||||||
>>[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>>>>>[>
|
|
||||||
>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<
|
|
||||||
->>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>
|
|
||||||
>]<[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<
|
|
||||||
>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>+<<<<<[<<<<<<<<<]>>>>>>>>
|
|
||||||
>[-+>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>-<<<<<>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<
|
|
||||||
<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>
|
|
||||||
+<]]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>[-<<<<<+>>>>
|
|
||||||
>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[
|
|
||||||
-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<
|
|
||||||
<<<>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>-<<<<<[<<
|
|
||||||
<<<<<<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<
|
|
||||||
<]>+++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<
|
|
||||||
<<>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]
|
|
||||||
<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>[-]<<<<<<<<>>>>>>>>>[>>>>>>>>>]<<<<<<
|
|
||||||
<<<[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<[<<<<<<<<
|
|
||||||
<]>>>>>>>>[-]+<<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<<<<+>>>>>>>>
|
|
||||||
]<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>>[>+<>>>>>>[-<<<<<<>-<>>>>>>]<<<<<<>
|
|
||||||
[-<>>>>>>+<<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>>+<<<<<<<<[>>>>>>[<<<<<<>>>
|
|
||||||
>>>-<<<<<<>>>>>>>>+<<<<<<<<>>>>>>]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<
|
|
||||||
<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>
|
|
||||||
>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<<<>[<>-<>>>>>>>>+<<<<<<<<>]<+
|
|
||||||
<<<<<<<<<]>>>>>>>>-<<<<<<<<>>>[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
|
||||||
<<<<[->>>>>>>>-<<<<<<<<>>>>>>>>>[>>>>>>[<<<<<<>>>>>>-<<<<<<>>>>>>>>+<<<<
|
|
||||||
<<<<>>>>>>]<<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<
|
|
||||||
<<<<<+>[<->-<<<<<<<<<<>>>>>>>>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<
|
|
||||||
<<>[<>-<>>>>>>>>+<<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<
|
|
||||||
<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
|
||||||
<<<[<<<<<<<<<]>>>>>>>>>[-+>>>>>>[-<<<<<<->>>>>>]+<<<<<<[->>>>>>-<<<<<<>>
|
|
||||||
>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<
|
|
||||||
]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
|
||||||
<<<<[->>>>>>>>-<<<<<<<<>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<
|
|
||||||
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
|
||||||
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<<>+++++<>[<>-<>[<>-<>>>>
|
|
||||||
>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>-<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
||||||
>>>>>>-<<<<<<[<<<<<<<<<]]>>>]<<<
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
[toolchain]
|
|
||||||
channel = "nightly-2022-04-17"
|
|
||||||
|
|
@ -1,102 +0,0 @@
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
use dbg_pls::DebugPls;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
parse::{Ast, Instr, Span},
|
|
||||||
BumpVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod opts;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Hir<'hir> {
|
|
||||||
pub stmts: BumpVec<'hir, Stmt<'hir>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Hir<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
Debug::fmt(&self.stmts, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DebugPls for Hir<'_> {
|
|
||||||
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
|
|
||||||
DebugPls::fmt(&self.stmts.iter().collect::<Vec<_>>(), f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Stmt<'hir> {
|
|
||||||
pub kind: StmtKind<'hir>,
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'hir> Stmt<'hir> {
|
|
||||||
fn new(kind: StmtKind<'hir>, span: Span) -> Stmt<'hir> {
|
|
||||||
Self { kind, span }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(&self) -> &StmtKind<'hir> {
|
|
||||||
&self.kind
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Stmt<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
Debug::fmt(&self.kind, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DebugPls for Stmt<'_> {
|
|
||||||
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
|
|
||||||
DebugPls::fmt(&self.kind, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, DebugPls)]
|
|
||||||
pub enum StmtKind<'hir> {
|
|
||||||
Add(i32, u8),
|
|
||||||
Sub(i32, u8),
|
|
||||||
/// Sets the current cell to 0 and adds that value of the cell to another cell at `offset`
|
|
||||||
MoveAddTo {
|
|
||||||
offset: i32,
|
|
||||||
},
|
|
||||||
Right(usize),
|
|
||||||
Left(usize),
|
|
||||||
Loop(Hir<'hir>),
|
|
||||||
Out,
|
|
||||||
In,
|
|
||||||
SetN(u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ast_to_ir<'hir>(alloc: &'hir Bump, ast: &Ast<'_>) -> Hir<'hir> {
|
|
||||||
let mut stmts = Vec::new_in(alloc);
|
|
||||||
|
|
||||||
let stmts_iter = ast.iter().map(|(instr, span)| {
|
|
||||||
let kind = match instr {
|
|
||||||
Instr::Add => StmtKind::Add(0, 1),
|
|
||||||
Instr::Sub => StmtKind::Sub(0, 1),
|
|
||||||
Instr::Right => StmtKind::Right(1),
|
|
||||||
Instr::Left => StmtKind::Left(1),
|
|
||||||
Instr::Out => StmtKind::Out,
|
|
||||||
Instr::In => StmtKind::In,
|
|
||||||
Instr::Loop(body) => {
|
|
||||||
let ir_body = ast_to_ir(alloc, body);
|
|
||||||
StmtKind::Loop(ir_body)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Stmt::new(kind, *span)
|
|
||||||
});
|
|
||||||
|
|
||||||
stmts.extend(stmts_iter);
|
|
||||||
|
|
||||||
Hir { stmts }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn optimized_hir<'hir>(alloc: &'hir Bump, ast: &Ast<'_>) -> Hir<'hir> {
|
|
||||||
let mut hir = ast_to_ir(alloc, ast);
|
|
||||||
opts::optimize(alloc, &mut hir);
|
|
||||||
hir
|
|
||||||
}
|
|
||||||
|
|
@ -1,321 +0,0 @@
|
||||||
use std::cmp::Ordering;
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
use tracing::trace;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
hir::{Hir, Stmt, StmtKind},
|
|
||||||
BumpVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn optimize<'hir>(alloc: &'hir Bump, hir: &mut Hir<'hir>) {
|
|
||||||
pass_group(alloc, hir);
|
|
||||||
pass_find_set_null(hir);
|
|
||||||
pass_set_n(hir);
|
|
||||||
pass_cancel_left_right_add_sub(hir);
|
|
||||||
pass_add_sub_offset(hir);
|
|
||||||
pass_move_add_to(hir);
|
|
||||||
// pass_unroll_loops(hir);
|
|
||||||
// pass_cancel_left_right_add_sub(hir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces things like `Sub(1) Sub(1)` with `Sub(2)`
|
|
||||||
// TODO: This pass is really slow, speed it up please
|
|
||||||
#[tracing::instrument(skip(alloc, ir_param))]
|
|
||||||
fn pass_group<'hir>(alloc: &'hir Bump, ir_param: &mut Hir<'hir>) {
|
|
||||||
let empty_ir = Hir {
|
|
||||||
stmts: Vec::new_in(alloc),
|
|
||||||
};
|
|
||||||
|
|
||||||
let ir = std::mem::replace(ir_param, empty_ir);
|
|
||||||
|
|
||||||
let new_stmts = Vec::new_in(alloc);
|
|
||||||
let stmts =
|
|
||||||
ir.stmts
|
|
||||||
.into_iter()
|
|
||||||
.fold(new_stmts, |mut stmts: BumpVec<'hir, Stmt<'hir>>, next| {
|
|
||||||
let Some(old) = stmts.last_mut() else {
|
|
||||||
if let StmtKind::Loop(mut body) = next.kind {
|
|
||||||
pass_group(alloc, &mut body);
|
|
||||||
stmts.push(Stmt::new(
|
|
||||||
StmtKind::Loop(body),
|
|
||||||
next.span,
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
stmts.push(next);
|
|
||||||
}
|
|
||||||
return stmts;
|
|
||||||
};
|
|
||||||
|
|
||||||
match (&mut old.kind, next.kind) {
|
|
||||||
(StmtKind::Add(offset_a, a), StmtKind::Add(offset_b, b))
|
|
||||||
if *a < 255 && *offset_a == offset_b =>
|
|
||||||
{
|
|
||||||
old.span = old.span.merge(next.span);
|
|
||||||
*a += b;
|
|
||||||
}
|
|
||||||
(StmtKind::Sub(offset_a, a), StmtKind::Sub(offset_b, b))
|
|
||||||
if *a < 255 && *offset_a == offset_b =>
|
|
||||||
{
|
|
||||||
old.span = old.span.merge(next.span);
|
|
||||||
*a += b;
|
|
||||||
}
|
|
||||||
(StmtKind::Right(a), StmtKind::Right(b)) if *a < 255 => {
|
|
||||||
old.span = old.span.merge(next.span);
|
|
||||||
*a += b;
|
|
||||||
}
|
|
||||||
(StmtKind::Left(a), StmtKind::Left(b)) if *a < 255 => {
|
|
||||||
old.span = old.span.merge(next.span);
|
|
||||||
*a += b;
|
|
||||||
}
|
|
||||||
(_, StmtKind::Loop(mut body)) => {
|
|
||||||
pass_group(alloc, &mut body);
|
|
||||||
stmts.push(Stmt {
|
|
||||||
span: next.span,
|
|
||||||
kind: StmtKind::Loop(body),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
(_, kind) => {
|
|
||||||
stmts.push(Stmt::new(kind, next.span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stmts
|
|
||||||
});
|
|
||||||
|
|
||||||
*ir_param = Hir { stmts };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces `Loop([Sub(_)])` to `SetNull`
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_find_set_null(ir: &mut Hir<'_>) {
|
|
||||||
pass_find_set_null_inner(ir)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pass_find_set_null_inner(ir: &mut Hir<'_>) {
|
|
||||||
for stmt in &mut ir.stmts {
|
|
||||||
if let Stmt {
|
|
||||||
kind: StmtKind::Loop(body),
|
|
||||||
span,
|
|
||||||
} = stmt
|
|
||||||
{
|
|
||||||
if let [Stmt {
|
|
||||||
kind: StmtKind::Sub(0, _),
|
|
||||||
..
|
|
||||||
}] = body.stmts.as_slice()
|
|
||||||
{
|
|
||||||
trace!(?span, "Replacing Statement with SetNull");
|
|
||||||
*stmt = Stmt::new(StmtKind::SetN(0), *span);
|
|
||||||
} else {
|
|
||||||
pass_find_set_null_inner(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces `SetN(n) Add(m)` with `SetN(n + m)`
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_set_n(ir: &mut Hir<'_>) {
|
|
||||||
pass_set_n_inner(ir)
|
|
||||||
}
|
|
||||||
fn pass_set_n_inner(ir: &mut Hir<'_>) {
|
|
||||||
window_pass(ir, pass_set_n_inner, |[a, b]| {
|
|
||||||
if let StmtKind::SetN(before) = a.kind() {
|
|
||||||
let new = match b.kind() {
|
|
||||||
StmtKind::Add(0, n) => StmtKind::SetN(before.wrapping_add(*n)),
|
|
||||||
StmtKind::Sub(0, n) => StmtKind::SetN(before.wrapping_sub(*n)),
|
|
||||||
_ => {
|
|
||||||
return WindowPassAction::None;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return WindowPassAction::Merge(new);
|
|
||||||
}
|
|
||||||
WindowPassAction::None
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces `Left(5) Right(3)` with `Left(2)`
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_cancel_left_right_add_sub(ir: &mut Hir<'_>) {
|
|
||||||
pass_cancel_left_right_add_sub_inner(ir)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pass_cancel_left_right_add_sub_inner(ir: &mut Hir<'_>) {
|
|
||||||
window_pass(ir, pass_cancel_left_right_add_sub_inner, |[a, b]| {
|
|
||||||
match (a.kind(), b.kind()) {
|
|
||||||
(StmtKind::Right(r), StmtKind::Left(l)) | (StmtKind::Left(l), StmtKind::Right(r)) => {
|
|
||||||
let new = match r.cmp(l) {
|
|
||||||
Ordering::Equal => {
|
|
||||||
return WindowPassAction::RemoveAll;
|
|
||||||
}
|
|
||||||
Ordering::Less => StmtKind::Left(l - r),
|
|
||||||
Ordering::Greater => StmtKind::Right(r - l),
|
|
||||||
};
|
|
||||||
|
|
||||||
WindowPassAction::Merge(new)
|
|
||||||
}
|
|
||||||
(StmtKind::Add(offset_a, r), StmtKind::Sub(offset_b, l))
|
|
||||||
| (StmtKind::Sub(offset_a, l), StmtKind::Add(offset_b, r))
|
|
||||||
if offset_a == offset_b =>
|
|
||||||
{
|
|
||||||
let new = match r.cmp(l) {
|
|
||||||
Ordering::Equal => return WindowPassAction::RemoveAll,
|
|
||||||
Ordering::Less => StmtKind::Sub(*offset_a, l - r),
|
|
||||||
Ordering::Greater => StmtKind::Add(*offset_a, r - l),
|
|
||||||
};
|
|
||||||
|
|
||||||
WindowPassAction::Merge(new)
|
|
||||||
}
|
|
||||||
_ => WindowPassAction::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces `Right(9) Add(5) Left(9)` with `AddOffset(9, 5)`
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_add_sub_offset(ir: &mut Hir<'_>) {
|
|
||||||
pass_add_sub_offset_inner(ir)
|
|
||||||
}
|
|
||||||
fn pass_add_sub_offset_inner(ir: &mut Hir<'_>) {
|
|
||||||
window_pass(ir, pass_add_sub_offset_inner, |[a, b, c]| {
|
|
||||||
match (a.kind(), b.kind(), c.kind()) {
|
|
||||||
(StmtKind::Right(r), StmtKind::Add(0, n), StmtKind::Left(l)) if r == l => {
|
|
||||||
WindowPassAction::Merge(StmtKind::Add(i32::try_from(*r).unwrap(), *n))
|
|
||||||
}
|
|
||||||
(StmtKind::Left(l), StmtKind::Add(0, n), StmtKind::Right(r)) if r == l => {
|
|
||||||
WindowPassAction::Merge(StmtKind::Add(-i32::try_from(*r).unwrap(), *n))
|
|
||||||
}
|
|
||||||
(StmtKind::Right(r), StmtKind::Sub(0, n), StmtKind::Left(l)) if r == l => {
|
|
||||||
WindowPassAction::Merge(StmtKind::Sub(i32::try_from(*r).unwrap(), *n))
|
|
||||||
}
|
|
||||||
(StmtKind::Left(l), StmtKind::Sub(0, n), StmtKind::Right(r)) if r == l => {
|
|
||||||
WindowPassAction::Merge(StmtKind::Sub(-i32::try_from(*r).unwrap(), *n))
|
|
||||||
}
|
|
||||||
_ => WindowPassAction::None,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// pass that replaces `Loop([Sub(1) AddOffset(o, 1)])` with `MoveAddTo(o)`
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_move_add_to(ir: &mut Hir<'_>) {
|
|
||||||
pass_move_add_to_inner(ir)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pass_move_add_to_inner(ir: &mut Hir<'_>) {
|
|
||||||
for stmt in &mut ir.stmts {
|
|
||||||
if let Stmt {
|
|
||||||
kind: StmtKind::Loop(body),
|
|
||||||
span,
|
|
||||||
} = stmt
|
|
||||||
{
|
|
||||||
if let [Stmt {
|
|
||||||
kind: StmtKind::Sub(0, 1),
|
|
||||||
..
|
|
||||||
}, Stmt {
|
|
||||||
kind: StmtKind::Add(offset, 1),
|
|
||||||
..
|
|
||||||
}]
|
|
||||||
| [Stmt {
|
|
||||||
kind: StmtKind::Add(offset, 1),
|
|
||||||
..
|
|
||||||
}, Stmt {
|
|
||||||
kind: StmtKind::Sub(0, 1),
|
|
||||||
..
|
|
||||||
}] = body.stmts.as_slice()
|
|
||||||
{
|
|
||||||
trace!(?span, ?offset, "Replacing Statement with MoveAddTo");
|
|
||||||
*stmt = Stmt::new(StmtKind::MoveAddTo { offset: *offset }, *span);
|
|
||||||
} else {
|
|
||||||
pass_move_add_to_inner(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(ir))]
|
|
||||||
fn pass_unroll_loops(ir: &mut Hir<'_>) {
|
|
||||||
let alloc = Bump::new();
|
|
||||||
pass_unroll_loops_inner(&alloc, ir);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pass_unroll_loops_inner(alloc: &Bump, ir: &mut Hir<'_>) {
|
|
||||||
window_pass(ir, pass_unroll_loops, |[a, b]| {
|
|
||||||
if let (StmtKind::SetN(n), StmtKind::Loop(body)) = (a.kind(), b.kind()) {
|
|
||||||
let mut stmts_vec = BumpVec::new_in(alloc);
|
|
||||||
|
|
||||||
let stmts = std::iter::repeat(body.stmts.iter())
|
|
||||||
.take(usize::from(*n))
|
|
||||||
.flatten()
|
|
||||||
.cloned();
|
|
||||||
stmts_vec.extend(stmts);
|
|
||||||
|
|
||||||
WindowPassAction::MergeMany(stmts_vec)
|
|
||||||
} else {
|
|
||||||
WindowPassAction::None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
enum WindowPassAction<'hir, 'pass> {
|
|
||||||
None,
|
|
||||||
Merge(StmtKind<'hir>),
|
|
||||||
MergeMany(BumpVec<'pass, Stmt<'hir>>),
|
|
||||||
RemoveAll,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn window_pass<'hir, 'pass, P, F, const N: usize>(ir: &mut Hir<'hir>, pass_recur: P, action: F)
|
|
||||||
where
|
|
||||||
P: Fn(&mut Hir<'hir>),
|
|
||||||
F: Fn([&Stmt<'hir>; N]) -> WindowPassAction<'hir, 'pass>,
|
|
||||||
{
|
|
||||||
assert!(N > 0);
|
|
||||||
|
|
||||||
let stmts = &mut ir.stmts;
|
|
||||||
let mut i = 0;
|
|
||||||
while i < stmts.len() {
|
|
||||||
let a = &mut stmts[i];
|
|
||||||
if let StmtKind::Loop(body) = &mut a.kind {
|
|
||||||
pass_recur(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
if i + N > stmts.len() {
|
|
||||||
break; // there aren't N elements left
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut elements = stmts[i..][..N].iter();
|
|
||||||
let elements = [(); N].map(|()| elements.next().unwrap());
|
|
||||||
|
|
||||||
let merged_span = elements[0].span.merge(elements.last().unwrap().span);
|
|
||||||
let result = action(elements);
|
|
||||||
|
|
||||||
match result {
|
|
||||||
WindowPassAction::None => {
|
|
||||||
// only increment i if we haven't removed anything
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
WindowPassAction::RemoveAll => {
|
|
||||||
trace!(?elements, "Removing all statements");
|
|
||||||
for _ in 0..N {
|
|
||||||
stmts.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WindowPassAction::Merge(new) => {
|
|
||||||
trace!(?elements, ?new, "Merging statements");
|
|
||||||
for _ in 1..N {
|
|
||||||
stmts.remove(i);
|
|
||||||
}
|
|
||||||
stmts[i] = Stmt::new(new, merged_span);
|
|
||||||
}
|
|
||||||
WindowPassAction::MergeMany(new) => {
|
|
||||||
trace!(?elements, ?new, "Merging many");
|
|
||||||
for _ in 0..N {
|
|
||||||
stmts.remove(i);
|
|
||||||
}
|
|
||||||
for stmt in new.into_iter().rev() {
|
|
||||||
stmts.insert(i, stmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
185
rust2/src/lib.rs
185
rust2/src/lib.rs
|
|
@ -1,185 +0,0 @@
|
||||||
#![feature(allocator_api, let_else)]
|
|
||||||
#![feature(nonzero_ops)]
|
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
|
||||||
#![warn(rust_2018_idioms)]
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
fmt::Display,
|
|
||||||
io::{Read, Write},
|
|
||||||
path::PathBuf,
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
use owo_colors::OwoColorize;
|
|
||||||
|
|
||||||
use crate::parse::ParseError;
|
|
||||||
|
|
||||||
pub mod hir;
|
|
||||||
pub mod lir;
|
|
||||||
mod mir;
|
|
||||||
pub mod parse;
|
|
||||||
|
|
||||||
#[derive(clap::Parser, Default)]
|
|
||||||
#[clap(author, about)]
|
|
||||||
pub struct Args {
|
|
||||||
/// Print colored source code depending on how often it was run.
|
|
||||||
/// Makes the interpreter ~30% slower.
|
|
||||||
#[clap(short, long)]
|
|
||||||
pub profile: bool,
|
|
||||||
/// Dump the IR info (ast, hir, mir, lir)
|
|
||||||
#[clap(long)]
|
|
||||||
pub dump: Option<DumpKind>,
|
|
||||||
/// Use experimental mid-level IR
|
|
||||||
#[clap(long)]
|
|
||||||
pub mir: bool,
|
|
||||||
/// The file to run
|
|
||||||
pub file: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
pub enum DumpKind {
|
|
||||||
Ast,
|
|
||||||
Hir,
|
|
||||||
Mir,
|
|
||||||
Lir,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for DumpKind {
|
|
||||||
type Err = String;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
match s {
|
|
||||||
"ast" => Ok(Self::Ast),
|
|
||||||
"hir" => Ok(Self::Hir),
|
|
||||||
"mir" => Ok(Self::Mir),
|
|
||||||
"lir" => Ok(Self::Lir),
|
|
||||||
other => Err(format!("Invalid IR level: '{other}'")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type BumpVec<'a, T> = Vec<T, &'a Bump>;
|
|
||||||
|
|
||||||
pub enum UseProfile {
|
|
||||||
Yes,
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run<R, W>(src: &str, stdout: W, stdin: R, config: &Args) -> Result<(), ParseError>
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
R: Read,
|
|
||||||
{
|
|
||||||
let ast_alloc = Bump::new();
|
|
||||||
|
|
||||||
let parsed = parse::parse(&ast_alloc, src.bytes().enumerate())?;
|
|
||||||
|
|
||||||
if let Some(DumpKind::Ast) = config.dump {
|
|
||||||
println!("{parsed:#?}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let hir_alloc = Bump::new();
|
|
||||||
|
|
||||||
let optimized_hir = hir::optimized_hir(&hir_alloc, &parsed);
|
|
||||||
|
|
||||||
if let Some(DumpKind::Hir) = config.dump {
|
|
||||||
println!("{}", dbg_pls::color(&optimized_hir));
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(parsed);
|
|
||||||
drop(ast_alloc);
|
|
||||||
|
|
||||||
if config.dump == Some(DumpKind::Mir) || config.mir {
|
|
||||||
let mir_alloc = Bump::new();
|
|
||||||
let mir = mir::optimized_mir(&mir_alloc, &optimized_hir);
|
|
||||||
if config.dump == Some(DumpKind::Mir) {
|
|
||||||
println!("{mir:#?}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let cg_alloc = Bump::new();
|
|
||||||
|
|
||||||
let lir = lir::generate(&cg_alloc, &optimized_hir);
|
|
||||||
|
|
||||||
if let Some(DumpKind::Lir) = config.dump {
|
|
||||||
println!("{lir:#?}");
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(optimized_hir);
|
|
||||||
drop(hir_alloc);
|
|
||||||
|
|
||||||
match config.profile {
|
|
||||||
true => {
|
|
||||||
let mut code_profile_count = vec![0; lir.debug().len()];
|
|
||||||
|
|
||||||
lir::interpreter::run(&lir, stdout, stdin, |ip| unsafe {
|
|
||||||
*code_profile_count.get_unchecked_mut(ip) += 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut src_profile_count = vec![0u64; src.len()];
|
|
||||||
|
|
||||||
for (stmt_span, stmt_count) in lir.debug().iter().zip(&code_profile_count) {
|
|
||||||
for i in &mut src_profile_count[stmt_span.start()..stmt_span.end()] {
|
|
||||||
*i += stmt_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let max = src_profile_count.iter().max().copied().unwrap_or(0);
|
|
||||||
println!("\n\n---------------- Profile ----------------");
|
|
||||||
for (char, value) in src.bytes().zip(src_profile_count) {
|
|
||||||
print!("{}", color_by_profile(char as char, value, max));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false => {
|
|
||||||
lir::interpreter::run(&lir, stdout, stdin, |_| {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn color_by_profile(char: char, value: u64, max: u64) -> impl Display {
|
|
||||||
let max = max as f64;
|
|
||||||
let value = value as f64;
|
|
||||||
let ratio = value / max;
|
|
||||||
let logged = -ratio.log10();
|
|
||||||
let logged = (logged * 100.) as u64;
|
|
||||||
|
|
||||||
match logged {
|
|
||||||
0..=15 => char.bright_red().to_string(),
|
|
||||||
16..=70 => char.yellow().to_string(),
|
|
||||||
71..=300 => char.green().to_string(),
|
|
||||||
_ => char.default_color().to_string(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::Args;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn fizzbuzz() {
|
|
||||||
let str = include_str!("../benches/fizzbuzz.bf");
|
|
||||||
let mut stdout = Vec::new();
|
|
||||||
let stdin = [];
|
|
||||||
|
|
||||||
super::run(str, &mut stdout, stdin.as_slice(), &Args::default()).unwrap();
|
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(String::from_utf8(stdout));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mandelbrot() {
|
|
||||||
let str = include_str!("../benches/mandelbrot.bf");
|
|
||||||
let mut stdout = Vec::new();
|
|
||||||
let stdin = [];
|
|
||||||
|
|
||||||
super::run(str, &mut stdout, stdin.as_slice(), &Args::default()).unwrap();
|
|
||||||
|
|
||||||
insta::assert_debug_snapshot!(String::from_utf8(stdout));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
use std::{
|
|
||||||
io::{Read, Write},
|
|
||||||
num::Wrapping,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::lir::{Lir, Stmt};
|
|
||||||
|
|
||||||
const MEM_SIZE: usize = 32_000;
|
|
||||||
|
|
||||||
type Memory = [Wrapping<u8>; MEM_SIZE];
|
|
||||||
|
|
||||||
// `repr(C)` to make sure rustc never reorders the fields weirdly
|
|
||||||
// maybe useless, but seems to give tiny wins
|
|
||||||
#[repr(C)]
|
|
||||||
struct Interpreter<'lir, W, R, P> {
|
|
||||||
code: &'lir Lir<'lir>,
|
|
||||||
profile_collector: P,
|
|
||||||
ip: usize,
|
|
||||||
ptr: usize,
|
|
||||||
mem: Memory,
|
|
||||||
stdout: W,
|
|
||||||
stdin: R,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run<W, R, P>(code: &Lir<'_>, stdout: W, stdin: R, profile_collector: P)
|
|
||||||
where
|
|
||||||
W: Write,
|
|
||||||
R: Read,
|
|
||||||
P: FnMut(usize),
|
|
||||||
{
|
|
||||||
let mut interpreter = Interpreter {
|
|
||||||
code,
|
|
||||||
ip: 0,
|
|
||||||
ptr: 0,
|
|
||||||
stdout,
|
|
||||||
stdin,
|
|
||||||
mem: [Wrapping(0u8); MEM_SIZE],
|
|
||||||
profile_collector,
|
|
||||||
};
|
|
||||||
|
|
||||||
// SAFETY: `Lir` can only be produced by the `crate::lir` module, which is trusted to not
|
|
||||||
// produce out of bounds jumps and put the `End` at the end
|
|
||||||
unsafe {
|
|
||||||
interpreter.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'c, W: Write, R: Read, P> Interpreter<'c, W, R, P>
|
|
||||||
where
|
|
||||||
P: FnMut(usize),
|
|
||||||
{
|
|
||||||
unsafe fn execute(&mut self) {
|
|
||||||
let stmts = self.code.stmts();
|
|
||||||
loop {
|
|
||||||
// SAFETY: If the code ends with an `End` and there are no out of bounds jumps,
|
|
||||||
// `self.ip` will never be out of bounds
|
|
||||||
// Removing this bounds check speeds up execution by about 40%
|
|
||||||
debug_assert!(self.ip < stmts.len());
|
|
||||||
let instr = unsafe { *stmts.get_unchecked(self.ip) };
|
|
||||||
self.ip += 1;
|
|
||||||
match instr {
|
|
||||||
Stmt::Add(n) => {
|
|
||||||
*self.elem_mut() += n;
|
|
||||||
}
|
|
||||||
Stmt::Sub(n) => {
|
|
||||||
*self.elem_mut() -= n;
|
|
||||||
}
|
|
||||||
Stmt::AddOffset { offset, n } => *self.elem_mut_offset(offset) += n,
|
|
||||||
Stmt::SubOffset { offset, n } => *self.elem_mut_offset(offset) -= n,
|
|
||||||
Stmt::MoveAddTo { offset } => {
|
|
||||||
let value = self.elem();
|
|
||||||
*self.elem_mut() = Wrapping(0);
|
|
||||||
*self.elem_mut_offset(offset) += value;
|
|
||||||
}
|
|
||||||
Stmt::Right(n) => {
|
|
||||||
self.ptr += n as usize;
|
|
||||||
if self.ptr >= MEM_SIZE {
|
|
||||||
self.ptr = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stmt::Left(n) => {
|
|
||||||
if self.ptr < n as usize {
|
|
||||||
let diff = n as usize - self.ptr;
|
|
||||||
self.ptr = MEM_SIZE - 1 - diff;
|
|
||||||
} else {
|
|
||||||
self.ptr -= n as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stmt::Out => {
|
|
||||||
let char = self.elem() as char;
|
|
||||||
write!(self.stdout, "{char}").unwrap();
|
|
||||||
self.stdout.flush().unwrap();
|
|
||||||
}
|
|
||||||
Stmt::In => {
|
|
||||||
let mut buf = [0; 1];
|
|
||||||
self.stdin.read_exact(&mut buf).unwrap();
|
|
||||||
*self.elem_mut() = Wrapping(buf[0]);
|
|
||||||
}
|
|
||||||
Stmt::SetN(n) => {
|
|
||||||
*self.elem_mut() = Wrapping(n);
|
|
||||||
}
|
|
||||||
Stmt::JmpIfZero(pos) => {
|
|
||||||
if self.elem() == 0 {
|
|
||||||
self.ip = pos as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stmt::JmpIfNonZero(pos) => {
|
|
||||||
if self.elem() != 0 {
|
|
||||||
self.ip = pos as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stmt::End => break,
|
|
||||||
}
|
|
||||||
|
|
||||||
// this should be a no-op if `profile_collector` is does nothing
|
|
||||||
(self.profile_collector)(self.ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn elem_mut_offset(&mut self, offset: i32) -> &mut Wrapping<u8> {
|
|
||||||
let ptr = self.ptr as isize;
|
|
||||||
let offset = offset as isize;
|
|
||||||
// SAFETY: `self.ptr` is never out of bounds
|
|
||||||
debug_assert!(self.ptr < self.mem.len());
|
|
||||||
unsafe { self.mem.get_unchecked_mut((ptr + offset) as usize) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn elem_mut(&mut self) -> &mut Wrapping<u8> {
|
|
||||||
// SAFETY: `self.ptr` is never out of bounds
|
|
||||||
debug_assert!(self.ptr < self.mem.len());
|
|
||||||
unsafe { self.mem.get_unchecked_mut(self.ptr) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn elem(&self) -> u8 {
|
|
||||||
// SAFETY: `self.ptr` is never out of bounds
|
|
||||||
debug_assert!(self.ptr < self.mem.len());
|
|
||||||
unsafe { self.mem.get_unchecked(self.ptr).0 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,137 +0,0 @@
|
||||||
//! codegen to flat code
|
|
||||||
//!
|
|
||||||
//! ```bf
|
|
||||||
//! ++[-].
|
|
||||||
//! ```
|
|
||||||
//! compiles down to
|
|
||||||
//! ```text
|
|
||||||
//! Add | Add | JmpIfZero | Sub | JumpIfNotZero | Out | End
|
|
||||||
//! | ^ | ^
|
|
||||||
//! +-------|-----------|---------|
|
|
||||||
//! +-----------+
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! technically, the `JumpIfNotZero` would be an unconditional Jmp to the `JmpIfZero`, but that's
|
|
||||||
//! a needless indirection.
|
|
||||||
//!
|
|
||||||
//! this module must not produce out of bounds jumps and always put the `End` instruction at the
|
|
||||||
//! end
|
|
||||||
|
|
||||||
pub mod interpreter;
|
|
||||||
|
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
hir::{Hir, Stmt as HirStmt, StmtKind as HirStmtKind},
|
|
||||||
parse::Span,
|
|
||||||
BumpVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Stmt {
|
|
||||||
Add(u8),
|
|
||||||
Sub(u8),
|
|
||||||
AddOffset { offset: i32, n: u8 },
|
|
||||||
SubOffset { offset: i32, n: u8 },
|
|
||||||
MoveAddTo { offset: i32 },
|
|
||||||
Right(u32),
|
|
||||||
Left(u32),
|
|
||||||
Out,
|
|
||||||
In,
|
|
||||||
SetN(u8),
|
|
||||||
JmpIfZero(u32),
|
|
||||||
JmpIfNonZero(u32),
|
|
||||||
End,
|
|
||||||
}
|
|
||||||
|
|
||||||
const _: [(); 8] = [(); std::mem::size_of::<Stmt>()];
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Lir<'lir> {
|
|
||||||
stmts: BumpVec<'lir, Stmt>,
|
|
||||||
debug: BumpVec<'lir, Span>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Lir<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.stmts.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Lir<'_> {
|
|
||||||
pub fn stmts(&self) -> &[Stmt] {
|
|
||||||
&self.stmts
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn debug(&self) -> &[Span] {
|
|
||||||
&self.debug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate<'lir>(alloc: &'lir Bump, ir: &Hir<'_>) -> Lir<'lir> {
|
|
||||||
let stmts = Vec::new_in(alloc);
|
|
||||||
let debug = Vec::new_in(alloc);
|
|
||||||
let mut lir = Lir { stmts, debug };
|
|
||||||
|
|
||||||
hir_to_lir(&mut lir, &ir.stmts);
|
|
||||||
lir.stmts.push(Stmt::End);
|
|
||||||
lir.debug.push(Span::default());
|
|
||||||
|
|
||||||
assert_eq!(lir.stmts.len(), lir.debug.len());
|
|
||||||
|
|
||||||
lir
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hir_to_lir<'lir>(lir: &mut Lir<'lir>, ir: &[HirStmt<'_>]) {
|
|
||||||
for ir_stmt in ir {
|
|
||||||
hir_stmt_to_lir_stmt(lir, ir_stmt);
|
|
||||||
}
|
|
||||||
debug_assert_eq!(lir.stmts.len(), lir.debug.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn hir_stmt_to_lir_stmt<'lir>(lir: &mut Lir<'lir>, ir_stmt: &HirStmt<'_>) {
|
|
||||||
let stmt = match &ir_stmt.kind {
|
|
||||||
HirStmtKind::Add(0, n) => Stmt::Add(*n),
|
|
||||||
HirStmtKind::Sub(0, n) => Stmt::Sub(*n),
|
|
||||||
HirStmtKind::Add(offset, n) => Stmt::AddOffset {
|
|
||||||
offset: *offset,
|
|
||||||
n: *n,
|
|
||||||
},
|
|
||||||
HirStmtKind::Sub(offset, n) => Stmt::SubOffset {
|
|
||||||
offset: *offset,
|
|
||||||
n: *n,
|
|
||||||
},
|
|
||||||
HirStmtKind::MoveAddTo { offset } => Stmt::MoveAddTo { offset: *offset },
|
|
||||||
HirStmtKind::Right(n) => Stmt::Right(u32::try_from(*n).unwrap()),
|
|
||||||
HirStmtKind::Left(n) => Stmt::Left(u32::try_from(*n).unwrap()),
|
|
||||||
HirStmtKind::Out => Stmt::Out,
|
|
||||||
HirStmtKind::In => Stmt::In,
|
|
||||||
HirStmtKind::SetN(n) => Stmt::SetN(*n),
|
|
||||||
HirStmtKind::Loop(instr) => {
|
|
||||||
let skip_jmp_idx = lir.stmts.len();
|
|
||||||
lir.stmts.push(Stmt::JmpIfZero(0)); // placeholder
|
|
||||||
lir.debug.push(ir_stmt.span);
|
|
||||||
|
|
||||||
// compile the loop body now
|
|
||||||
hir_to_lir(lir, &instr.stmts);
|
|
||||||
// if the loop body is empty, we jmp to ourselves, which is an infinite loop - as expected
|
|
||||||
let first_loop_body_idx = skip_jmp_idx + 1;
|
|
||||||
lir.stmts
|
|
||||||
.push(Stmt::JmpIfNonZero(first_loop_body_idx.try_into().unwrap()));
|
|
||||||
lir.debug.push(ir_stmt.span);
|
|
||||||
|
|
||||||
// there will always at least be an `End` instruction after the loop
|
|
||||||
let after_loop_idx = lir.stmts.len();
|
|
||||||
|
|
||||||
// fix the placeholder with the actual index
|
|
||||||
lir.stmts[skip_jmp_idx] = Stmt::JmpIfZero(after_loop_idx.try_into().unwrap());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
lir.stmts.push(stmt);
|
|
||||||
lir.debug.push(ir_stmt.span);
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#![feature(allocator_api, let_else)]
|
|
||||||
#![warn(rust_2018_idioms)]
|
|
||||||
|
|
||||||
use std::{fs, io, process};
|
|
||||||
|
|
||||||
use brainfuck::Args;
|
|
||||||
use clap::Parser;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let stdout = io::stdout();
|
|
||||||
let stdout = stdout.lock();
|
|
||||||
let stdin = io::stdin();
|
|
||||||
let stdin = stdin.lock();
|
|
||||||
|
|
||||||
let args = Args::parse();
|
|
||||||
|
|
||||||
tracing_subscriber::fmt()
|
|
||||||
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
|
|
||||||
.without_time()
|
|
||||||
.init();
|
|
||||||
|
|
||||||
let src = fs::read_to_string(&args.file).unwrap_or_else(|err| {
|
|
||||||
eprintln!("error: Failed to read file: {err}");
|
|
||||||
process::exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
brainfuck::run(&src, stdout, stdin, &args).unwrap_or_else(|_| {
|
|
||||||
eprintln!("error: Failed to parse brainfuck code");
|
|
||||||
process::exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -1,120 +0,0 @@
|
||||||
//! an experimental MIR (mid-level-ir)
|
|
||||||
//!
|
|
||||||
//! The MIR consists of two parts. First, there are instructions (`Stmt`). These instructions
|
|
||||||
//! can be seen as an extended version of the default brainfuck instruction set `+-<>,.[]`.
|
|
||||||
//! These instructions modify the classic tape. What MIR does is that it attaches an abstract
|
|
||||||
//! `MemoryState` to *each* statement. This state contains all facts known about the state of the
|
|
||||||
//! tape at the point of execution of the statement.
|
|
||||||
//!
|
|
||||||
//! For example, for the code `++.`, the `MemoryState` for the `.` instruction contains a single
|
|
||||||
//! fact: "The current cell was written to, by the instruction before and with the value 2". MIR
|
|
||||||
//! tracks as much of the reads/writes to determine their dependencies and eliminate as many
|
|
||||||
//! of them as possible.
|
|
||||||
//!
|
|
||||||
//! Note that MIR is always pessimized, so if it can't determine for sure that something is true,
|
|
||||||
//! it will not act on it.
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
mod opts;
|
|
||||||
mod state;
|
|
||||||
|
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
hir::{Hir, StmtKind as HirStmtKind},
|
|
||||||
mir::state::{MemoryState, Store},
|
|
||||||
parse::Span,
|
|
||||||
BumpVec,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Mir<'mir> {
|
|
||||||
stmts: BumpVec<'mir, Stmt<'mir>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Stmt<'mir> {
|
|
||||||
kind: StmtKind<'mir>,
|
|
||||||
state: MemoryState<'mir>,
|
|
||||||
span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Stmt<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
f.debug_struct("Stmt")
|
|
||||||
.field("kind", &self.kind)
|
|
||||||
.field("state", &self.state)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Offset = i32;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum StmtKind<'mir> {
|
|
||||||
/// Add or sub, the value has the valid range -255..=255
|
|
||||||
AddSub {
|
|
||||||
offset: Offset,
|
|
||||||
n: i16,
|
|
||||||
store: Store,
|
|
||||||
},
|
|
||||||
/// Sets the current cell to 0 and adds that value of the cell to another cell at `offset`
|
|
||||||
MoveAddTo {
|
|
||||||
offset: Offset,
|
|
||||||
store_set_null: Store,
|
|
||||||
store_move: Store,
|
|
||||||
},
|
|
||||||
/// Left or Right pointer move (`<>`)
|
|
||||||
PointerMove(Offset),
|
|
||||||
Loop(Mir<'mir>),
|
|
||||||
Out,
|
|
||||||
In(Store),
|
|
||||||
SetN(u8, Store),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(alloc, hir))]
|
|
||||||
pub fn optimized_mir<'mir>(alloc: &'mir Bump, hir: &Hir<'_>) -> Mir<'mir> {
|
|
||||||
let mut mir = hir_to_mir(alloc, hir);
|
|
||||||
opts::passes(alloc, &mut mir);
|
|
||||||
mir
|
|
||||||
}
|
|
||||||
|
|
||||||
/// compiles hir down to a minimal mir
|
|
||||||
fn hir_to_mir<'mir>(alloc: &'mir Bump, hir: &Hir<'_>) -> Mir<'mir> {
|
|
||||||
let mut stmts = Vec::new_in(alloc);
|
|
||||||
let iter = hir.stmts.iter().map(|hir_stmt| {
|
|
||||||
let kind = match *hir_stmt.kind() {
|
|
||||||
HirStmtKind::Add(offset, n) => StmtKind::AddSub {
|
|
||||||
offset,
|
|
||||||
n: i16::from(n),
|
|
||||||
store: Store::dead(),
|
|
||||||
},
|
|
||||||
HirStmtKind::Sub(offset, n) => StmtKind::AddSub {
|
|
||||||
offset,
|
|
||||||
n: -i16::from(n),
|
|
||||||
store: Store::dead(),
|
|
||||||
},
|
|
||||||
HirStmtKind::MoveAddTo { offset } => StmtKind::MoveAddTo {
|
|
||||||
offset,
|
|
||||||
store_set_null: Store::dead(),
|
|
||||||
store_move: Store::dead(),
|
|
||||||
},
|
|
||||||
HirStmtKind::Right(n) => StmtKind::PointerMove(i32::try_from(n).unwrap()),
|
|
||||||
HirStmtKind::Left(n) => StmtKind::PointerMove(-i32::try_from(n).unwrap()),
|
|
||||||
HirStmtKind::Loop(ref body) => StmtKind::Loop(hir_to_mir(alloc, body)),
|
|
||||||
HirStmtKind::Out => StmtKind::Out,
|
|
||||||
HirStmtKind::In => StmtKind::In(Store::dead()),
|
|
||||||
HirStmtKind::SetN(n) => StmtKind::SetN(n, Store::dead()),
|
|
||||||
};
|
|
||||||
Stmt {
|
|
||||||
kind,
|
|
||||||
span: hir_stmt.span,
|
|
||||||
state: MemoryState::empty(alloc),
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stmts.extend(iter);
|
|
||||||
|
|
||||||
Mir { stmts }
|
|
||||||
}
|
|
||||||
|
|
@ -1,215 +0,0 @@
|
||||||
use std::collections::{hash_map::Entry, HashMap};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
use crate::mir::{
|
|
||||||
state::{CellState, MemoryState, MemoryStateChange, Store},
|
|
||||||
Mir, Offset, StmtKind,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// this pass fills out as much state info for all statements as possible
|
|
||||||
#[tracing::instrument(skip(alloc, mir))]
|
|
||||||
pub fn passes<'mir>(alloc: &'mir Bump, mir: &mut Mir<'mir>) {
|
|
||||||
pass_fill_state_info(alloc, mir);
|
|
||||||
pass_const_propagation(mir);
|
|
||||||
pass_dead_store_elimination(mir);
|
|
||||||
}
|
|
||||||
/// this pass fills out as much state info for all statements as possible
|
|
||||||
#[tracing::instrument(skip(alloc, mir))]
|
|
||||||
pub fn pass_fill_state_info<'mir>(alloc: &'mir Bump, mir: &mut Mir<'mir>) {
|
|
||||||
let empty_state = MemoryState::empty(alloc);
|
|
||||||
pass_fill_state_info_inner(alloc, mir, empty_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: this whole thing is unsound because it doesn't consider that stores inside a loop
|
|
||||||
// could be loaded from after the loop
|
|
||||||
fn pass_fill_state_info_inner<'mir>(
|
|
||||||
alloc: &'mir Bump,
|
|
||||||
mir: &mut Mir<'mir>,
|
|
||||||
mut outer: MemoryState<'mir>,
|
|
||||||
) {
|
|
||||||
for stmt in &mut mir.stmts {
|
|
||||||
let state = match &mut stmt.kind {
|
|
||||||
StmtKind::AddSub { offset, n, store } => {
|
|
||||||
let prev_state = outer.state_for_offset(*offset);
|
|
||||||
let new_state = match prev_state {
|
|
||||||
CellState::WrittenToKnown(_, prev_n) => {
|
|
||||||
let n = i16::from(prev_n).wrapping_add(*n);
|
|
||||||
let n = u8::try_from(n).unwrap();
|
|
||||||
CellState::WrittenToKnown(store.clone(), n)
|
|
||||||
}
|
|
||||||
_ => CellState::WrittenToUnknown(store.clone()),
|
|
||||||
};
|
|
||||||
MemoryState::single(
|
|
||||||
alloc,
|
|
||||||
outer,
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: *offset,
|
|
||||||
new_state,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
StmtKind::MoveAddTo {
|
|
||||||
offset,
|
|
||||||
store_set_null,
|
|
||||||
store_move,
|
|
||||||
} => MemoryState::double(
|
|
||||||
alloc,
|
|
||||||
outer,
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: 0,
|
|
||||||
new_state: CellState::WrittenToKnown(store_set_null.clone(), 0),
|
|
||||||
},
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: *offset,
|
|
||||||
new_state: CellState::WrittenToUnknown(store_move.clone()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
StmtKind::PointerMove(n) => {
|
|
||||||
MemoryState::single(alloc, outer, MemoryStateChange::Move(*n))
|
|
||||||
}
|
|
||||||
StmtKind::Loop(body) => {
|
|
||||||
// TODO: we can get a lot smarter here and get huge benefits; we don't yet
|
|
||||||
pass_fill_state_info_inner(alloc, body, MemoryState::empty(alloc));
|
|
||||||
MemoryState::double(
|
|
||||||
alloc,
|
|
||||||
outer,
|
|
||||||
// forget all knowledge, the opaque loop might have touched it all
|
|
||||||
MemoryStateChange::Forget,
|
|
||||||
// we certainly know that the current cell is zero, since the loop exited
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: 0,
|
|
||||||
new_state: CellState::LoopNull,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
StmtKind::Out => outer,
|
|
||||||
StmtKind::In(store) => MemoryState::single(
|
|
||||||
alloc,
|
|
||||||
outer,
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: 0,
|
|
||||||
new_state: CellState::WrittenToUnknown(store.clone()),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
StmtKind::SetN(value, store) => MemoryState::single(
|
|
||||||
alloc,
|
|
||||||
outer,
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: 0,
|
|
||||||
new_state: CellState::WrittenToKnown(store.clone(), *value),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
};
|
|
||||||
stmt.state = state.clone();
|
|
||||||
outer = state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This pass eliminates dead stores. It should probably be run multiple times between other passes
|
|
||||||
/// for cleanup
|
|
||||||
#[tracing::instrument(skip(mir))]
|
|
||||||
fn pass_dead_store_elimination(mir: &mut Mir<'_>) {
|
|
||||||
pass_dead_store_elimination_mark_dead_stores(mir)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tracing::instrument(skip(mir))]
|
|
||||||
fn pass_dead_store_elimination_mark_dead_stores(mir: &Mir<'_>) {
|
|
||||||
fn mark_store(
|
|
||||||
potential_dead_stores: &mut HashMap<Offset, Store>,
|
|
||||||
offset: Offset,
|
|
||||||
store: &Store,
|
|
||||||
) {
|
|
||||||
match potential_dead_stores.entry(offset) {
|
|
||||||
Entry::Occupied(mut entry) => {
|
|
||||||
let old = entry.insert(store.clone());
|
|
||||||
if old.is_maybe_dead() {
|
|
||||||
// it's certainly dead
|
|
||||||
info!("We have a dead one!!!");
|
|
||||||
old.mark_dead();
|
|
||||||
} else {
|
|
||||||
// it's alive and well, drop it and keep it marked alive
|
|
||||||
drop(old);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Entry::Vacant(entry) => {
|
|
||||||
entry.insert(store.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut potential_dead_stores = HashMap::new();
|
|
||||||
let mut current_offset = 0;
|
|
||||||
|
|
||||||
for stmt in &mir.stmts {
|
|
||||||
match &stmt.kind {
|
|
||||||
StmtKind::AddSub { store, offset, .. } => {
|
|
||||||
mark_store(&mut potential_dead_stores, current_offset + offset, store);
|
|
||||||
}
|
|
||||||
StmtKind::MoveAddTo {
|
|
||||||
offset,
|
|
||||||
store_move,
|
|
||||||
store_set_null,
|
|
||||||
} => {
|
|
||||||
mark_store(&mut potential_dead_stores, current_offset, store_set_null);
|
|
||||||
mark_store(
|
|
||||||
&mut potential_dead_stores,
|
|
||||||
current_offset + offset,
|
|
||||||
store_move,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
StmtKind::PointerMove(offset) => {
|
|
||||||
current_offset += offset; // ???
|
|
||||||
}
|
|
||||||
StmtKind::Loop(body) => {
|
|
||||||
let store = potential_dead_stores.get(¤t_offset);
|
|
||||||
if let Some(store) = store {
|
|
||||||
store.add_load();
|
|
||||||
}
|
|
||||||
|
|
||||||
pass_dead_store_elimination_mark_dead_stores(body);
|
|
||||||
}
|
|
||||||
StmtKind::Out => {
|
|
||||||
let store = potential_dead_stores.get(¤t_offset);
|
|
||||||
if let Some(store) = store {
|
|
||||||
store.add_load();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StmtKind::In(store) | StmtKind::SetN(_, store) => {
|
|
||||||
mark_store(&mut potential_dead_stores, current_offset, store);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if stmt.state.has_forget_delta() {
|
|
||||||
// they might all have loads now
|
|
||||||
potential_dead_stores.values().for_each(Store::clobber);
|
|
||||||
}
|
|
||||||
info!(?potential_dead_stores, ?current_offset, "stores");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// test pass
|
|
||||||
#[tracing::instrument(skip(mir))]
|
|
||||||
fn pass_const_propagation(mir: &mut Mir<'_>) {
|
|
||||||
pass_const_propagation_inner(mir)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pass_const_propagation_inner(mir: &mut Mir<'_>) {
|
|
||||||
for stmt in &mut mir.stmts {
|
|
||||||
match &mut stmt.kind {
|
|
||||||
StmtKind::Out => {
|
|
||||||
let _state = stmt.state.state_for_offset(0);
|
|
||||||
// we could now insert a `SetN` before the `Out`, to mark the previous store
|
|
||||||
// as dead.
|
|
||||||
}
|
|
||||||
StmtKind::Loop(body) => {
|
|
||||||
let _state = stmt.state.state_for_offset(0);
|
|
||||||
// we could now insert a `SetN` before the `Loop`, to mark the previous store
|
|
||||||
// as dead.
|
|
||||||
pass_const_propagation_inner(body);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
// todo: we're gonna leak `Rc`s here aren't we?
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
cell::{Cell, RefCell},
|
|
||||||
fmt::{Debug, Formatter},
|
|
||||||
num::NonZeroU32,
|
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
|
|
||||||
use crate::{mir::Offset, BumpVec};
|
|
||||||
|
|
||||||
/// The known state of a cell in the MIR
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum CellState {
|
|
||||||
/// The state of this cell is completely unknown and could be anything, for example after `,`
|
|
||||||
Unknown,
|
|
||||||
/// This cell is guaranteed to be `0` because a loop just terminated on it
|
|
||||||
LoopNull,
|
|
||||||
/// Some value was written to this cell classified by the `Store`, but we do not know the value
|
|
||||||
WrittenToUnknown(Store),
|
|
||||||
/// A known value was written to this cell
|
|
||||||
WrittenToKnown(Store, u8),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A change in the known state of the memory caused by a single instruction
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum MemoryStateChange {
|
|
||||||
/// A cell value was changed to a new state.
|
|
||||||
Change {
|
|
||||||
offset: Offset,
|
|
||||||
new_state: CellState,
|
|
||||||
},
|
|
||||||
/// The pointer was moved. This affects the `offset` calculations from previous states.
|
|
||||||
Move(Offset),
|
|
||||||
/// Forget everything about the memory state. This currently happens after each loop, since
|
|
||||||
/// the loop is opaque and might clobber everything.
|
|
||||||
Forget,
|
|
||||||
/// Load a value from memory. This is not a direct change of the memory itself, but it does
|
|
||||||
/// change the state in that it marks the corresponding store, if any, as alive. Loads should
|
|
||||||
/// be eliminated whenever possible, to remove as many dead stores as possible.
|
|
||||||
Load { offset: Offset },
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The known state of memory at a specific instance in the instruction sequence
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct MemoryState<'mir>(Rc<RefCell<MemoryStateInner<'mir>>>);
|
|
||||||
|
|
||||||
impl<'mir> MemoryState<'mir> {
|
|
||||||
pub fn empty(alloc: &'mir Bump) -> Self {
|
|
||||||
Self::new(None, Vec::new_in(alloc))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn single(
|
|
||||||
alloc: &'mir Bump,
|
|
||||||
prev: MemoryState<'mir>,
|
|
||||||
delta: MemoryStateChange,
|
|
||||||
) -> MemoryState<'mir> {
|
|
||||||
let mut deltas = Vec::new_in(alloc);
|
|
||||||
deltas.push(delta);
|
|
||||||
Self::new(Some(prev), deltas)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn double(
|
|
||||||
alloc: &'mir Bump,
|
|
||||||
prev: MemoryState<'mir>,
|
|
||||||
delta1: MemoryStateChange,
|
|
||||||
delta2: MemoryStateChange,
|
|
||||||
) -> MemoryState<'mir> {
|
|
||||||
let mut deltas = Vec::new_in(alloc);
|
|
||||||
deltas.push(delta1);
|
|
||||||
deltas.push(delta2);
|
|
||||||
Self::new(Some(prev), deltas)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
prev: Option<MemoryState<'mir>>,
|
|
||||||
deltas: BumpVec<'mir, MemoryStateChange>,
|
|
||||||
) -> MemoryState<'mir> {
|
|
||||||
Self(Rc::new(RefCell::new(MemoryStateInner { prev, deltas })))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn state_for_offset(&self, offset: Offset) -> CellState {
|
|
||||||
self.0.borrow().state_for_offset(offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_forget_delta(&self) -> bool {
|
|
||||||
self.0
|
|
||||||
.borrow()
|
|
||||||
.deltas
|
|
||||||
.iter()
|
|
||||||
.any(|d| matches!(d, MemoryStateChange::Forget))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for MemoryState<'_> {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.0
|
|
||||||
.try_borrow()
|
|
||||||
.map(|s| MemoryStateInner::fmt(&*s, f))
|
|
||||||
.unwrap_or_else(|_| f.debug_struct("MemoryState").finish_non_exhaustive())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The known state of memory relative to the pointer
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
struct MemoryStateInner<'mir> {
|
|
||||||
prev: Option<MemoryState<'mir>>,
|
|
||||||
deltas: BumpVec<'mir, MemoryStateChange>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'mir> MemoryStateInner<'mir> {
|
|
||||||
fn state_for_offset(&self, offset: Offset) -> CellState {
|
|
||||||
let mut offset = offset;
|
|
||||||
for delta in &self.deltas {
|
|
||||||
match delta {
|
|
||||||
MemoryStateChange::Change {
|
|
||||||
offset: write_offset,
|
|
||||||
new_state,
|
|
||||||
} if *write_offset == offset => return new_state.clone(),
|
|
||||||
MemoryStateChange::Move(change) => offset -= change,
|
|
||||||
// we may not access the forbidden knowledge
|
|
||||||
MemoryStateChange::Forget => return CellState::Unknown,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.prev
|
|
||||||
.as_ref()
|
|
||||||
.map(|state| state.state_for_offset(offset))
|
|
||||||
.unwrap_or(CellState::Unknown)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The abstract representation of a store in memory. Corresponding loads can also hold
|
|
||||||
/// a reference to this to mark the store as alive
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Store(Rc<Cell<StoreInner>>);
|
|
||||||
|
|
||||||
impl Store {
|
|
||||||
pub fn dead() -> Self {
|
|
||||||
StoreKind::Dead.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn id(&self) -> u64 {
|
|
||||||
self.inner().id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_load(&self) {
|
|
||||||
let old = self.inner();
|
|
||||||
let kind = match old.kind {
|
|
||||||
StoreKind::Unknown => StoreKind::UsedAtLeast(NonZeroU32::new(1).unwrap()),
|
|
||||||
StoreKind::UsedExact(n) => StoreKind::UsedExact(n.checked_add(1).unwrap()),
|
|
||||||
StoreKind::UsedAtLeast(n) => StoreKind::UsedAtLeast(n.checked_add(1).unwrap()),
|
|
||||||
StoreKind::Dead => StoreKind::UsedExact(NonZeroU32::new(1).unwrap()),
|
|
||||||
};
|
|
||||||
self.0.set(StoreInner { id: old.id, kind })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_maybe_dead(&self) -> bool {
|
|
||||||
matches!(self.inner().kind, StoreKind::Dead | StoreKind::Unknown)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mark_dead(&self) {
|
|
||||||
let old = self.inner();
|
|
||||||
self.0.set(StoreInner {
|
|
||||||
id: old.id,
|
|
||||||
kind: StoreKind::Dead,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clobber(&self) {
|
|
||||||
let old = self.inner();
|
|
||||||
let kind = match old.kind {
|
|
||||||
StoreKind::Unknown => StoreKind::Unknown,
|
|
||||||
StoreKind::UsedExact(n) => StoreKind::UsedAtLeast(n),
|
|
||||||
StoreKind::UsedAtLeast(n) => StoreKind::UsedAtLeast(n),
|
|
||||||
StoreKind::Dead => StoreKind::Unknown,
|
|
||||||
};
|
|
||||||
self.0.set(StoreInner { id: old.id, kind })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inner(&self) -> StoreInner {
|
|
||||||
self.0.get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Store {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
self.inner().kind.fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct StoreInner {
|
|
||||||
id: u64,
|
|
||||||
kind: StoreKind,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
enum StoreKind {
|
|
||||||
/// No information is known about uses of the store, it has probably been clobbered
|
|
||||||
Unknown,
|
|
||||||
/// The exact amount of subsequent loads is known about the store, and it's this
|
|
||||||
UsedExact(NonZeroU32),
|
|
||||||
/// The exact amount of subsequent loads not known about this store, but it's at least this
|
|
||||||
UsedAtLeast(NonZeroU32),
|
|
||||||
/// The store is known to be dead
|
|
||||||
Dead,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<StoreKind> for Store {
|
|
||||||
fn from(kind: StoreKind) -> Self {
|
|
||||||
Self(Rc::new(Cell::new(StoreInner {
|
|
||||||
id: rand::random(),
|
|
||||||
kind,
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
use std::{
|
|
||||||
cmp,
|
|
||||||
fmt::{Debug, Formatter},
|
|
||||||
};
|
|
||||||
|
|
||||||
use bumpalo::Bump;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
|
||||||
pub struct Span {
|
|
||||||
start: u32,
|
|
||||||
len: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Span {
|
|
||||||
fn single(idx: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
start: idx.try_into().unwrap(),
|
|
||||||
len: 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// start..end
|
|
||||||
fn start_end(start: usize, end: usize) -> Span {
|
|
||||||
Self {
|
|
||||||
start: start.try_into().unwrap(),
|
|
||||||
len: (end - start).try_into().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// start..=end
|
|
||||||
fn start_end_incl(start: usize, end: usize) -> Span {
|
|
||||||
Self {
|
|
||||||
start: start.try_into().unwrap(),
|
|
||||||
len: (end - start + 1).try_into().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn until(&self, other: Self) -> Self {
|
|
||||||
Self {
|
|
||||||
start: self.start,
|
|
||||||
len: (other.start + other.len) - self.len,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn merge(&self, other: Self) -> Self {
|
|
||||||
Self::start_end(
|
|
||||||
cmp::min(self.start(), other.start()),
|
|
||||||
cmp::max(self.end(), other.end()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start(&self) -> usize {
|
|
||||||
self.start.try_into().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.len.try_into().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ..end
|
|
||||||
pub fn end(&self) -> usize {
|
|
||||||
self.start() + self.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for Span {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
Debug::fmt(&(self.start..(self.start + self.len)), f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Ast<'ast> = Vec<(Instr<'ast>, Span), &'ast Bump>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum Instr<'ast> {
|
|
||||||
Add,
|
|
||||||
Sub,
|
|
||||||
Right,
|
|
||||||
Left,
|
|
||||||
Out,
|
|
||||||
In,
|
|
||||||
Loop(Ast<'ast>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct ParseError;
|
|
||||||
|
|
||||||
pub fn parse<I>(alloc: &Bump, mut src: I) -> Result<Ast<'_>, ParseError>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = (usize, u8)>,
|
|
||||||
{
|
|
||||||
let mut instrs = Vec::new_in(alloc);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
match src.next() {
|
|
||||||
Some((idx, b'+')) => instrs.push((Instr::Add, Span::single(idx))),
|
|
||||||
Some((idx, b'-')) => instrs.push((Instr::Sub, Span::single(idx))),
|
|
||||||
Some((idx, b'>')) => instrs.push((Instr::Right, Span::single(idx))),
|
|
||||||
Some((idx, b'<')) => instrs.push((Instr::Left, Span::single(idx))),
|
|
||||||
Some((idx, b'.')) => instrs.push((Instr::Out, Span::single(idx))),
|
|
||||||
Some((idx, b',')) => instrs.push((Instr::In, Span::single(idx))),
|
|
||||||
Some((idx, b'[')) => {
|
|
||||||
let (loop_instrs, span) = parse_loop(alloc, &mut src, 0, idx)?;
|
|
||||||
instrs.push((Instr::Loop(loop_instrs), span));
|
|
||||||
}
|
|
||||||
Some((_, b']')) => return Err(ParseError),
|
|
||||||
Some(_) => {} // comment
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(instrs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_loop<'ast, I>(
|
|
||||||
alloc: &'ast Bump,
|
|
||||||
src: &mut I,
|
|
||||||
depth: u16,
|
|
||||||
start_idx: usize,
|
|
||||||
) -> Result<(Ast<'ast>, Span), ParseError>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = (usize, u8)>,
|
|
||||||
{
|
|
||||||
const MAX_DEPTH: u16 = 1000;
|
|
||||||
|
|
||||||
if depth > MAX_DEPTH {
|
|
||||||
return Err(ParseError);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut instrs = Vec::new_in(alloc);
|
|
||||||
|
|
||||||
let end_idx = loop {
|
|
||||||
match src.next() {
|
|
||||||
Some((idx, b'+')) => instrs.push((Instr::Add, Span::single(idx))),
|
|
||||||
Some((idx, b'-')) => instrs.push((Instr::Sub, Span::single(idx))),
|
|
||||||
Some((idx, b'>')) => instrs.push((Instr::Right, Span::single(idx))),
|
|
||||||
Some((idx, b'<')) => instrs.push((Instr::Left, Span::single(idx))),
|
|
||||||
Some((idx, b'.')) => instrs.push((Instr::Out, Span::single(idx))),
|
|
||||||
Some((idx, b',')) => instrs.push((Instr::In, Span::single(idx))),
|
|
||||||
Some((idx, b'[')) => {
|
|
||||||
let (loop_instrs, span) = parse_loop(alloc, src, depth + 1, idx)?;
|
|
||||||
instrs.push((Instr::Loop(loop_instrs), span));
|
|
||||||
}
|
|
||||||
Some((idx, b']')) => break idx,
|
|
||||||
Some(_) => {} // comment
|
|
||||||
None => return Err(ParseError),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((instrs, Span::start_end_incl(start_idx, end_idx)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use bumpalo::Bump;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn simple() {
|
|
||||||
let alloc = Bump::new();
|
|
||||||
|
|
||||||
let bf = ">+<++[-].";
|
|
||||||
let instrs = super::parse(&alloc, bf.bytes().enumerate());
|
|
||||||
insta::assert_debug_snapshot!(instrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn nested_loop() {
|
|
||||||
let alloc = Bump::new();
|
|
||||||
|
|
||||||
let bf = "+[-[-[-]]+>>>]";
|
|
||||||
let instrs = super::parse(&alloc, bf.bytes().enumerate());
|
|
||||||
insta::assert_debug_snapshot!(instrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
---
|
|
||||||
source: src/parse.rs
|
|
||||||
expression: instrs
|
|
||||||
---
|
|
||||||
Ok(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Add,
|
|
||||||
0..1,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Loop(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Sub,
|
|
||||||
2..3,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Loop(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Sub,
|
|
||||||
4..5,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Loop(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Sub,
|
|
||||||
6..7,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
5..8,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
3..9,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Add,
|
|
||||||
9..10,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Right,
|
|
||||||
10..11,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Right,
|
|
||||||
11..12,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Right,
|
|
||||||
12..13,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
1..14,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
source: src/parse.rs
|
|
||||||
expression: instrs
|
|
||||||
---
|
|
||||||
Ok(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Right,
|
|
||||||
0..1,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Add,
|
|
||||||
1..2,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Left,
|
|
||||||
2..3,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Add,
|
|
||||||
3..4,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Add,
|
|
||||||
4..5,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Loop(
|
|
||||||
[
|
|
||||||
(
|
|
||||||
Sub,
|
|
||||||
6..7,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
5..8,
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Out,
|
|
||||||
8..9,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
---
|
|
||||||
source: src/lib.rs
|
|
||||||
assertion_line: 43
|
|
||||||
expression: "String::from_utf8(stdout)"
|
|
||||||
---
|
|
||||||
Ok(
|
|
||||||
"1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz\n16\n17\nFizz\n19\nBuzz\nFizz\n22\n23\nFizz\nBuzz\n26\nFizz\n28\n29\nFizzBuzz\n31\n32\nFizz\n34\nBuzz\nFizz\n37\n38\nFizz\nBuzz\n41\nFizz\n43\n44\nFizzBuzz\n46\n47\nFizz\n49\nBuzz\nFizz\n52\n53\nFizz\nBuzz\n56\nFizz\n58\n59\nFizzBuzz\n61\n62\nFizz\n64\nBuzz\nFizz\n67\n68\nFizz\nBuzz\n71\nFizz\n73\n74\nFizzBuzz\n76\n77\nFizz\n79\nBuzz\nFizz\n82\n83\nFizz\nBuzz\n86\nFizz\n88\n89\nFizzBuzz\n91\n92\nFizz\n94\nBuzz\nFizz\n97\n98\nFizz\nBuzz\n",
|
|
||||||
)
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
source: src/lib.rs
|
|
||||||
expression: "String::from_utf8(stdout)"
|
|
||||||
---
|
|
||||||
Ok(
|
|
||||||
"AAAAAAAABBBBBBBBCCCCCCCCCCCCCCCCCCDDDDEFEEDDDCCCCCBBBBBBBBBBBBBBB\nAAAAAAABBBBBBCCCCCCCCCCCCCCCCCDDDDDDEEFIKGGGDDDDDCCCCBBBBBBBBBBBB\nAAAAAABBBBCCCCCCCCCCCCCCCCCDDDDDDDEEEFGHKPIGFEDDDDDCCCCCBBBBBBBBB\nAAAAABBBCCCCCCCCCCCCCCCCCDDDDDDDEEEFGPVT Q[HEEEEDDDCCCCCCBBBBBBB\nAAAABBCCCCCCCCCCCCCCCCDDDDDDDEEFFFGGHK HGFFEEEDDDCCCCCBBBBBB\nAAABBCCCCCCCCCCCCCCCDDDDDEEEFGK MJJ NR YS L HHGIJFDDCCCCCCBBBB\nAAABCCCCCCCCCCCCCDDDEEEEEEFFFHI MGEDDCCCCCCBBB\nAABCCCCCCCCCCCDDEEEEEEEEFFFGY Q MHGEEDCCCCCCCBB\nAACCCCCCDDDDDEEFLHGGHMHGGGHIR QLHEDDCCCCCCCB\nABCCDDDDDDEEEEFGIKU RLJJL IFEDDCCCCCCCB\nACDDDDDDEEEEEGGHOS QR JFEDDDCCCCCCC\nADDDDDEFFFGGHKOPS GEEDDDCCCCCCC\nA PJGFEEDDDCCCCCCC\nADDDDDEFFFGGHKOPS GEEDDDCCCCCCC\nACDDDDDDEEEEEGGHOS QR JFEDDDCCCCCCC\nABCCDDDDDDEEEEFGIKU RLJJL IFEDDCCCCCCCB\nAACCCCCCDDDDDEEFLHGGHMHGGGHIR QLHEDDCCCCCCCB\nAABCCCCCCCCCCCDDEEEEEEEEFFFGY Q MHGEEDCCCCCCCBB\nAAABCCCCCCCCCCCCCDDDEEEEEEFFFHI MGEDDCCCCCCBBB\nAAABBCCCCCCCCCCCCCCCDDDDDEEEFGK MJJ NR YS L HHGIJFDDCCCCCCBBBB\nAAAABBCCCCCCCCCCCCCCCCDDDDDDDEEFFFGGHK HGFFEEEDDDCCCCCBBBBBB\nAAAAABBBCCCCCCCCCCCCCCCCCDDDDDDDEEEFGPVT Q[HEEEEDDDCCCCCCBBBBBBB\nAAAAAABBBBCCCCCCCCCCCCCCCCCDDDDDDDEEEFGHKPIGFEDDDDDCCCCCBBBBBBBBB\nAAAAAAABBBBBBCCCCCCCCCCCCCCCCCDDDDDDEEFIKGGGDDDDDCCCCBBBBBBBBBBBB\n",
|
|
||||||
)
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
+++++>[-]+++[<.>]
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue