mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-15 05:45:02 +01:00
Compare commits
86 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8157f2ceb | |||
| 04dd019806 | |||
| deefc18959 | |||
| 54b5c9b1f8 | |||
| a52cbda492 | |||
| 64e5ac616f | |||
| b6982d5023 | |||
| 5e401a0d6d | |||
| 3b8b091406 | |||
| d5d80f79b7 | |||
| 039b5ea9c7 | |||
| f88c486088 | |||
| bd2bde58b8 | |||
| 9db60ac38d | |||
| 80b1b0e3f6 | |||
| d0718adf7f | |||
| 5fc5c49dff | |||
| ddf2686049 | |||
| 5d943ba51c | |||
| fb2986783e | |||
| 93f97e9a08 | |||
| 014770b6fe | |||
| 4490d49d35 | |||
| d7fea43acf | |||
| 290201ab98 | |||
| 31f2304a30 | |||
| 3eb9486a8c | |||
| 904356eb4e | |||
| 46229fd74f | |||
| 4d9648bf97 | |||
| d9f163ef3a | |||
| 7973d9f77b | |||
| c3c24c73fe | |||
| 6575e09957 | |||
| 9d140c45d7 | |||
| c130627b63 | |||
| 53ad68e3f2 | |||
| 9924aa2037 | |||
| b535178cb8 | |||
| 7dd2c82fa4 | |||
| 1e1a2a277b | |||
| 2df17352d1 | |||
| eda2476021 | |||
| 799b1591e0 | |||
| cec7204c6d | |||
| 5634330287 | |||
| e82b14b09a | |||
| 7b88c99039 | |||
| 539d0e0502 | |||
| 66bd69e674 | |||
| 2d854539aa | |||
| 2484fe1f44 | |||
| 2b1daa55fb | |||
| 3994acef78 | |||
| f9998535de | |||
| 7d352e0b5c | |||
| d5520e1f42 | |||
| db362072b7 | |||
| ab27352faa | |||
| 076156bd34 | |||
|
|
a4fa459805 | ||
| c2bdc73179 | |||
|
|
6cc64160e1 | ||
|
|
6df903675e | ||
| e7165c876e | |||
| 206e0293ec | |||
| 0a8ecd3a92 | |||
| e9d3a88bb6 | |||
| 2202c79521 | |||
| d1141cc6a6 | |||
| dc79c96f63 | |||
| 6d4c6f5b69 | |||
| 6f23444e4f | |||
| 669b004044 | |||
| e13d82ff46 | |||
| 296fd4a279 | |||
| 579d81021a | |||
| a96567038d | |||
| 273027e8af | |||
| 5f6d1d5b4b | |||
| e815fd8c66 | |||
| b30fa04dcc | |||
| 3ee494fed9 | |||
| 812e492640 | |||
| 68d07ae79e | |||
| 2a147ef178 |
81 changed files with 18720 additions and 930 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.bf linguist-vendored
|
||||||
|
*.b linguist-vendored
|
||||||
12
README.md
12
README.md
|
|
@ -1,15 +1,17 @@
|
||||||
# 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:
|
||||||
- Haskell
|
- Idris
|
||||||
- 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()
|
return program.chars().parallel()
|
||||||
.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,5 +1,3 @@
|
||||||
/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.0"
|
version = "0.1.1"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bfinterpreter"
|
name = "bfinterpreter"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|
@ -8,6 +8,8 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
412
bfi-rust/flamegraph.svg
Normal file
412
bfi-rust/flamegraph.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 437 KiB |
23
ibfi-ts/.gitignore
vendored
Normal file
23
ibfi-ts/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# 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*
|
||||||
27
ibfi-ts/README.md
Normal file
27
ibfi-ts/README.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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
|
||||||
50
ibfi-ts/package.json
Normal file
50
ibfi-ts/package.json
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
ibfi-ts/public/favicon.ico
Normal file
BIN
ibfi-ts/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
43
ibfi-ts/public/index.html
Normal file
43
ibfi-ts/public/index.html
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!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>
|
||||||
BIN
ibfi-ts/public/logo192.png
Normal file
BIN
ibfi-ts/public/logo192.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
BIN
ibfi-ts/public/logo512.png
Normal file
BIN
ibfi-ts/public/logo512.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
25
ibfi-ts/public/manifest.json
Normal file
25
ibfi-ts/public/manifest.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
3
ibfi-ts/public/robots.txt
Normal file
3
ibfi-ts/public/robots.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
128
ibfi-ts/src/App.scss
Normal file
128
ibfi-ts/src/App.scss
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
157
ibfi-ts/src/brainfuck/Interpreter.ts
Normal file
157
ibfi-ts/src/brainfuck/Interpreter.ts
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
41
ibfi-ts/src/components/App.tsx
Normal file
41
ibfi-ts/src/components/App.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
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;
|
||||||
22
ibfi-ts/src/components/CodeDisplay.tsx
Normal file
22
ibfi-ts/src/components/CodeDisplay.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
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;
|
||||||
83
ibfi-ts/src/components/CodeInput.tsx
Normal file
83
ibfi-ts/src/components/CodeInput.tsx
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
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;
|
||||||
15
ibfi-ts/src/components/ProgramOutput.tsx
Normal file
15
ibfi-ts/src/components/ProgramOutput.tsx
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
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;
|
||||||
118
ibfi-ts/src/components/RunDisplay.tsx
Normal file
118
ibfi-ts/src/components/RunDisplay.tsx
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
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;
|
||||||
189
ibfi-ts/src/components/Runner.tsx
Normal file
189
ibfi-ts/src/components/Runner.tsx
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
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;
|
||||||
13
ibfi-ts/src/index.css
Normal file
13
ibfi-ts/src/index.css
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
11
ibfi-ts/src/index.tsx
Normal file
11
ibfi-ts/src/index.tsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
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')
|
||||||
|
);
|
||||||
8
ibfi-ts/src/presets.json
Normal file
8
ibfi-ts/src/presets.json
Normal file
File diff suppressed because one or more lines are too long
1
ibfi-ts/src/react-app-env.d.ts
vendored
Normal file
1
ibfi-ts/src/react-app-env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="react-scripts" />
|
||||||
26
ibfi-ts/tsconfig.json
Normal file
26
ibfi-ts/tsconfig.json
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"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
Normal file
11965
ibfi-ts/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
2
js/.gitignore
vendored
Normal file
2
js/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules
|
||||||
|
.idea
|
||||||
4
js/.prettierrc.json
Normal file
4
js/.prettierrc.json
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100
|
||||||
|
}
|
||||||
1
js/fizzbuzz.bf
vendored
Normal file
1
js/fizzbuzz.bf
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
hello...[[].]]
|
||||||
11
js/package.json
Normal file
11
js/package.json
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"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
Normal file
113
js/src/index.js
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
8
js/yarn.lock
Normal file
8
js/yarn.lock
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 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
Normal file
2
rust2/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
target
|
||||||
|
.idea
|
||||||
3
rust2/.rustfmt.toml
Normal file
3
rust2/.rustfmt.toml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
imports_granularity = "Crate"
|
||||||
|
newline_style = "Unix"
|
||||||
|
group_imports = "StdExternalCrate"
|
||||||
1238
rust2/Cargo.lock
generated
Normal file
1238
rust2/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
29
rust2/Cargo.toml
Normal file
29
rust2/Cargo.toml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
[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
|
||||||
5
rust2/benches/bench.bf
vendored
Normal file
5
rust2/benches/bench.bf
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
Benchmark brainf*ck program
|
||||||
|
>++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++
|
||||||
|
[>++++++++<-]>.[-]<<>++++++++++[>++++++++++[>++
|
||||||
|
++++++++[>++++++++++[>++++++++++[>++++++++++[>+
|
||||||
|
+++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++.
|
||||||
44
rust2/benches/bottles.bf
vendored
Normal file
44
rust2/benches/bottles.bf
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>>
|
||||||
|
[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<
|
||||||
|
-]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<<
|
||||||
|
[>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++
|
||||||
|
+++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-
|
||||||
|
]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+
|
||||||
|
++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]>
|
||||||
|
>>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++
|
||||||
|
+>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------
|
||||||
|
---->-]<.>++++++[<+++++++++++>-]<.+++..+++++++++++++.>++++++
|
||||||
|
++[<---------->-]<--.>+++++++++[<+++++++++>-]<--.-.>++++++++
|
||||||
|
[<---------->-]<++.>++++++++[<++++++++++>-]<++++.-----------
|
||||||
|
-.---.>+++++++[<---------->-]<+.>++++++++[<+++++++++++>-]<-.
|
||||||
|
>++[<----------->-]<.+++++++++++..>+++++++++[<---------->-]<
|
||||||
|
-----.---.>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>>+++
|
||||||
|
+[<++++++>-]<--.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.
|
||||||
|
><+++++..--------.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++
|
||||||
|
++++++++++++.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<++
|
||||||
|
+++++++>-]<--.---------.>+++++++[<---------->-]<.>++++++[<++
|
||||||
|
+++++++++>-]<.+++..+++++++++++++.>++++++++++[<---------->-]<
|
||||||
|
-.---.>+++++++[<++++++++++>-]<++++.+++++++++++++.++++++++++.
|
||||||
|
------.>+++++++[<---------->-]<+.>++++++++[<++++++++++>-]<-.
|
||||||
|
-.---------.>+++++++[<---------->-]<+.>+++++++[<++++++++++>-
|
||||||
|
]<--.+++++++++++.++++++++.---------.>++++++++[<---------->-]
|
||||||
|
<++.>+++++[<+++++++++++++>-]<.+++++++++++++.----------.>++++
|
||||||
|
+++[<---------->-]<++.>++++++++[<++++++++++>-]<.>+++[<----->
|
||||||
|
-]<.>+++[<++++++>-]<..>+++++++++[<--------->-]<--.>+++++++[<
|
||||||
|
++++++++++>-]<+++.+++++++++++.>++++++++[<----------->-]<++++
|
||||||
|
.>+++++[<+++++++++++++>-]<.>+++[<++++++>-]<-.---.++++++.----
|
||||||
|
---.----------.>++++++++[<----------->-]<+.---.[-]<<<->[-]>[
|
||||||
|
-]<<[>+>+<<-]>>[<<+>>-]>>>[-]<<<+++++++++<[>>>+<<[>+>[-]<<-]
|
||||||
|
>[<+>-]>[<<++++++++++>>>+<-]<<-<-]+++++++++>[<->-]>>+>[<[-]<
|
||||||
|
<+>>>-]>[-]+<<[>+>-<<-]<<<[>>+>+<<<-]>>>[<<<+>>>-]<>>[<+>-]<
|
||||||
|
<-[>[-]<[-]]>>+<[>[-]<-]<++++++++[<++++++<++++++>>-]>>>[>+>+
|
||||||
|
<<-]>>[<<+>>-]<[<<<<<.>>>>>-]<<<<<<.>>[-]>[-]++++[<++++++++>
|
||||||
|
-]<.>++++[<++++++++>-]<++.>+++++[<+++++++++>-]<.><+++++..---
|
||||||
|
-----.-------.>>[>>+>+<<<-]>>>[<<<+>>>-]<[<<<<++++++++++++++
|
||||||
|
.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<-
|
||||||
|
-.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-]
|
||||||
|
<.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[
|
||||||
|
<+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++
|
||||||
|
++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+.
|
||||||
|
>++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++
|
||||||
|
..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]
|
||||||
7
rust2/benches/fizzbuzz.bf
vendored
Normal file
7
rust2/benches/fizzbuzz.bf
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
++++++++++[>++++++++++<-]>>++++++++++>->>>>>>>>>>>>>>>>-->+++++++[->++\n++++++++<]>[->+>+>+>+<<<<]+++>>+++>>>++++++++[-<
|
||||||
|
++++<++++<++++>>>]++++\n+[-<++++<++++>>]>>-->++++++[->+++++++++++<]>[->+>+>+>+<<<<]+++++>>+>++\n++++>++++++>++++++++[-<+
|
||||||
|
+++<++++<++++>>>]++++++[-<+++<+++<+++>>>]>>-->\n---+[-<+]-<[+[->+]-<<->>>+>[-]++[-->++]-->+++[---++[--<++]---->>-<+>[+\n
|
||||||
|
+++[----<++++]--[>]++[-->++]--<]>++[--+[-<+]->>[-]+++++[---->++++]-->[\n->+<]>>[.>]++[-->++]]-->+++]---+[-<+]->>-[+>>>+[
|
||||||
|
-<+]->>>++++++++++<<[-\n>+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>\n+>>]<<<<<]>[-]>>[>++++++
|
||||||
|
[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->+++\n+++++<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]+[-<+]->>]+[-]<<<.>>>+[\n
|
||||||
|
-<+]-<<]
|
||||||
709
rust2/benches/hanoi.bf
vendored
Normal file
709
rust2/benches/hanoi.bf
vendored
Normal file
|
|
@ -0,0 +1,709 @@
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>[-]>[-]+++++++++++++++++++++++++++.++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++.-------------------.-------
|
||||||
|
--------------------------------------.+++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++++.-----------------------------------------.++++++
|
||||||
|
++++++++++++++++++.[-]+++++++++++++++++++++++++++.++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++.-------------------------------------
|
||||||
|
----.+++++++++.---------.+++++.+++++++++++++++++.++++++++++++.++++++++++++++
|
||||||
|
+++++++++++++.++++++++.------------------.+++++++++++++.+.------------------
|
||||||
|
-----------------------------------------------------------------.++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------
|
||||||
|
---.----------------------------------------------------------------------.+
|
||||||
|
+++++++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++++.++++++++++
|
||||||
|
+++.+.------.---------------------------------------------------------------
|
||||||
|
----------.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++.+++++.-------------------------------------------------------------
|
||||||
|
-----------------.++++++++++++++++++++++++++++++++++.+++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++.-----------------.++++++++.+++++.--------.--------
|
||||||
|
----------------------------------------------------.+++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++.++++++++.[-]+++++++++++++++++++++++++++.+
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.------------
|
||||||
|
----------------------------.++++++++.----------.++++.+++++++++++++++++++.++
|
||||||
|
+++++++++++++.+++++++++++++++++++++++++++.---------.+++++++++++..-----------
|
||||||
|
----.+++++++++.-------------------------------------------------------------
|
||||||
|
-----------------.++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++.+++++++++++++++++++++++.-------------------------------------------
|
||||||
|
----------------------------------------------.+++++++++++++++++++++++++++++
|
||||||
|
++++++.+++++++++++++++++++++++++++++++++++++++++.---.---..+++++++++.+++.----
|
||||||
|
----------.-----------------------------------------------------------------
|
||||||
|
---.+++++++++++++++++++++++++++++++++++++++++++++++++++++++.++++++++++++++++
|
||||||
|
++++++++.---.------.--------------------------------------------------------
|
||||||
|
--------------.++++++++++++++++++++++++++++.++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++.++++++++++++..----.--------------------------------------------
|
||||||
|
----------.-----------..++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++...-----------------------------------------------------
|
||||||
|
--------------------.+++++++++++++++++++++++++++++++++++++++++++++++++++++.+
|
||||||
|
++++++++.---.---..+++++++++.+++.--------------.-----------------------------
|
||||||
|
-------------------------.++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+.+++++++++++++++++++.------------------------------------------------------
|
||||||
|
---------------.+++++++++++++++++++++++++++++++++++++++++++++++++++.++++.---
|
||||||
|
.+++++++++++++.+++++.-------------------------------------------------------
|
||||||
|
---------------.+++++++++++++++.[-]>[-]+++++++++>[-]+++>>[-]>[-]<<<<<[->>>>>
|
||||||
|
+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<
|
||||||
|
<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]
|
||||||
|
>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-
|
||||||
|
<<+>>]<<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<[>[-]++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++>[-]<<<<<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]<+++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++>]<<<[>>>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<<
|
||||||
|
->>>][-]++++++++++++++++>[-]++++++++++++++>>>>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<
|
||||||
|
<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[
|
||||||
|
[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+
|
||||||
|
<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>
|
||||||
|
>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<+++++>>>>]>[-]>[-
|
||||||
|
]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]+<<[-]+>>
|
||||||
|
>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
||||||
|
]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
||||||
|
[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<
|
||||||
|
[[-]<<<++++++++++>>>][-]>[-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<+<<<<<<<+
|
||||||
|
>>>>>>>>][-]+++++++++++++++++++++++++<<<[-]>>[>>[-]<[->+<]>[-<+<<<+>>>>]<<-]
|
||||||
|
[-]<<[->>+<<]>>[-<<+<<+>>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<<<<<<<
|
||||||
|
<+>>>>->>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>->>>>]>[-]
|
||||||
|
>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]++<<[-
|
||||||
|
]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+
|
||||||
|
>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>
|
||||||
|
>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>
|
||||||
|
]<<<[[-]<<<<----->>>>][-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<
|
||||||
|
+>>>>>>->>>][-]+++++++++++++++++++++++++++.+++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++.>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>
|
||||||
|
>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[
|
||||||
|
-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->
|
||||||
|
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<
|
||||||
|
+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]
|
||||||
|
>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<
|
||||||
|
<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>
|
||||||
|
+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>
|
||||||
|
>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[
|
||||||
|
-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>
|
||||||
|
]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+
|
||||||
|
+++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-
|
||||||
|
<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->
|
||||||
|
>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<
|
||||||
|
[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>
|
||||||
|
]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>
|
||||||
|
>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]
|
||||||
|
<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[
|
||||||
|
[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>
|
||||||
|
[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<
|
||||||
|
<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>
|
||||||
|
>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->
|
||||||
|
[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
||||||
|
+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[
|
||||||
|
-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<
|
||||||
|
<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>
|
||||||
|
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<
|
||||||
|
<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[-
|
||||||
|
>>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<+++
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<
|
||||||
|
]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<+++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.
|
||||||
|
>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]
|
||||||
|
<<]<<<<<<--------------------------------.>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>
|
||||||
|
>>[-<+<<<<<+>>>>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+++++
|
||||||
|
+++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<
|
||||||
|
+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+
|
||||||
|
<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]
|
||||||
|
>>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>
|
||||||
|
>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>
|
||||||
|
>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[
|
||||||
|
-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>
|
||||||
|
>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]
|
||||||
|
>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<
|
||||||
|
+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->
|
||||||
|
>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>
|
||||||
|
->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[
|
||||||
|
-]+>>]<]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>
|
||||||
|
>>]<<[-<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]+++++
|
||||||
|
+++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[
|
||||||
|
[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[
|
||||||
|
->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+
|
||||||
|
>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+
|
||||||
|
<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>]
|
||||||
|
[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
||||||
|
+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>
|
||||||
|
[[-<<<+>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-
|
||||||
|
<<<+<<+>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>]
|
||||||
|
[-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<
|
||||||
|
<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>
|
||||||
|
[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]
|
||||||
|
<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>
|
||||||
|
[-]+<[[-<+>]<++++++++++++++++++++++++++++++++++++++++++++++++.<+++++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<+++++++
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++.<+++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++.>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++.>>>>>>]<<]<<<<<<+++++++++++++.>[-]>[-]<<<<<<<[->>>>>>>+<<<<<<<]>>>>
|
||||||
|
>>>[-<+<<<<<<+>>>>>>>][-]+++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
||||||
|
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>
|
||||||
|
>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<
|
||||||
|
+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<[-]<<<<<<<<[->>>>>>>>+<<<
|
||||||
|
<<<<<]>>>>>>[-]>>[-<<<<<<<<+>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..
|
||||||
|
>>>-]<<<.>>>>>[-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>>>>[-]>>[-<<<<<<<<+>>>>>>+>>
|
||||||
|
][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]>>>[-]>[-]<<<<<<<[->>>>>>>+<<<<<
|
||||||
|
<<]>>>>>>>[-<+<<<<<<+>>>>>>>][-]++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>
|
||||||
|
[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>
|
||||||
|
+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]
|
||||||
|
>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]+++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<<<<<<<<]>>>[-]<<<<
|
||||||
|
<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]<<<<<<<[-]<[-]<[-]>>>>>>>>>>[-]<<<<<[->>>
|
||||||
|
>>+<<<<<]>>>>>[-<<<<<+<<<+>>>>>>>>][-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>]<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-
|
||||||
|
[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<[->>>>>+<<<<
|
||||||
|
<]>>>>>[[-<<<<<+>>>>>]<<<<<->>>>>]<]<<<<<+>>[-]+>>[-]>[-]<<<<<[->>>>>+<<<<<]
|
||||||
|
>>>>>[-<+<<<<+>>>>>][-]++++++++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>
|
||||||
|
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<
|
||||||
|
<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<
|
||||||
|
<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<]<<<[-]>[-]+>[-]++>[-]++++++++>[-]
|
||||||
|
+>[-]+[>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++<<[-]>>>[-]>[
|
||||||
|
-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<-
|
||||||
|
>->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>
|
||||||
|
]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]+>>>][-]<[->+<]>[[-<+>]<<<[-]+>>>]<<<[>[-
|
||||||
|
]<<<<<[->>>>>+<<<<<]>>>>>[[-<<<<<+>>>>>]>[-]>[-]>[-]>>[-]>[-]<<<<<<<<<<[->>>
|
||||||
|
>>>>>>>+<<<<<<<<<<]>>>>>>>>>>[-<+<<<<<<<<<+>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<
|
||||||
|
<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[
|
||||||
|
-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
||||||
|
][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<[-]
|
||||||
|
+>[-]+>>]>[-]>[-]<<<<<<<<<<[->>>>>>>>>>+<<<<<<<<<<]>>>>>>>>>>[-<+<<<<<<<<<+>
|
||||||
|
>>>>>>>>>][-]+++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]
|
||||||
|
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[-
|
||||||
|
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->
|
||||||
|
+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<[-]+>>[-]+>][-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-
|
||||||
|
]>>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>[-]>[-<
|
||||||
|
<<<<<<<<<<<<<<+>>>>>>>>>>>>>>+>]<[<+>-]>[-]<<<<<<<<<<<<<<[->>>>>>>>>>>>>>+<<
|
||||||
|
<<<<<<<<<<<<]>>>>>>>>>>>>>[-]>[-<<<<<<<<<<<<<<+>>>>>>>>>>>>>+>]<[<+++>-]>[-]
|
||||||
|
<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>[-]>[-<<<<<<<<<<<<<+>
|
||||||
|
>>>>>>>>>>>+>]<[<+++++++++>-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<[->>+<<]>>[-<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<
|
||||||
|
<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>
|
||||||
|
>-]<<[>>>>]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>[-]<<<<<<<<<<<<[->>>>>>>>>>>>+<<<<<<<<<<<<]>>>>>>>>>>>>[-<
|
||||||
|
<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<
|
||||||
|
<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<+<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]
|
||||||
|
<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<
|
||||||
|
<<]>>>>>>>>>>>[-<<<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<
|
||||||
|
<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>[-<<<<<<<<
|
||||||
|
<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<
|
||||||
|
<<<+>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>+>>>>>>>>>>>>>][-]<<[->>+<<]>>[[-<<+>>]>[-]<<<<<<<<<<<<[->>>>
|
||||||
|
>>>>>>>>+<<<<<<<<<<<<]>>>>>[-]>>>>>>>[-<<<<<<<<<<<<+>>>>>+>>>>>>>][-]<<<<<<<
|
||||||
|
<<<<[->>>>>>>>>>>+<<<<<<<<<<<]<[-]>>>>>>>>>>>>[-<<<<<<<<<<<+<+>>>>>>>>>>>>][
|
||||||
|
-]<<<<<<<[->>>>>>>+<<<<<<<]<<<<[-]>>>>>>>>>>>[-<<<<<<<+<<<<+>>>>>>>>>>>]<<<<
|
||||||
|
<<<<<<->[-]>+>>>>>>>][-]<[->+<]>[[-<+>]>[-]<<<<<<<<<<<<[->>>>>>>>>>>>+<<<<<<
|
||||||
|
<<<<<<]>>>>>[-]>>>>>>>[-<<<<<<<<<<<<+>>>>>+>>>>>>>][-]<<<<<<<<<<<<<[->>>>>>>
|
||||||
|
>>>>>>+<<<<<<<<<<<<<]>[-]>>>>>>>>>>>>[-<<<<<<<<<<<<<+>+>>>>>>>>>>>>][-]<<<<<
|
||||||
|
<<[->>>>>>>+<<<<<<<]<<<<<<[-]>>>>>>>>>>>>>[-<<<<<<<+<<<<<<+>>>>>>>>>>>>>]<<<
|
||||||
|
<<<<<<<->[-]>+>>>>>>>]<<<<]>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<+<<<<<+>>>
|
||||||
|
>>>][-]++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<
|
||||||
|
<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<
|
||||||
|
]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-
|
||||||
|
<+>]<<<[-]>>>]<<<[[-]>>>>[-]++>>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<
|
||||||
|
<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]<<[-]+>>>[-
|
||||||
|
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[
|
||||||
|
<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
||||||
|
+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-
|
||||||
|
]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]>[-]<<<<<<<<<<<<<<<[-
|
||||||
|
>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>
|
||||||
|
>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
||||||
|
<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<
|
||||||
|
<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[
|
||||||
|
-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<
|
||||||
|
<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]++<<[-]+>>
|
||||||
|
>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
||||||
|
]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
||||||
|
[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<
|
||||||
|
[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>[-]>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>]<]>[-]
|
||||||
|
>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<
|
||||||
|
<<<<<<<<<<+>>>>>>>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-
|
||||||
|
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<
|
||||||
|
+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<
|
||||||
|
[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>
|
||||||
|
>>>>>>>>>>[-]>>>>>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<
|
||||||
|
<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+
|
||||||
|
<<<<]<<>>>>]>>[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<
|
||||||
|
<<<[->>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>
|
||||||
|
>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>
|
||||||
|
>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->
|
||||||
|
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+
|
||||||
|
<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>[-]>>>>>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]
|
||||||
|
<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>
|
||||||
|
>+<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>[-<+<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>][-]++<<[
|
||||||
|
-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]
|
||||||
|
+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
||||||
|
>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>
|
||||||
|
>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-
|
||||||
|
]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>[-]<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>>>>-]<<<<]<<
|
||||||
|
[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<
|
||||||
|
<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>
|
||||||
|
>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
||||||
|
>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>
|
||||||
|
[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]
|
||||||
|
<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>[-]<<<<<[->>>>>
|
||||||
|
+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<+>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>
|
||||||
|
>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+
|
||||||
|
>>>>-]<<<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<
|
||||||
|
<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>
|
||||||
|
][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>
|
||||||
|
>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>
|
||||||
|
[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]
|
||||||
|
<<<[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]
|
||||||
|
<<<<<[->>>>>+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<<<
|
||||||
|
]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<[
|
||||||
|
->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]
|
||||||
|
++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
||||||
|
<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
||||||
|
<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<
|
||||||
|
[-]>>>]<<<[[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-
|
||||||
|
]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<<<<<[->>
|
||||||
|
>>>+<<<<<]>>>>>[-<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>][-]<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>>[<<<<+>>>>-]<-[<<<<+>>>>-]<<
|
||||||
|
<<]<<[-]>>>[<<<+>>>-]<<[>>>>]><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>]>[-]>[-]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>
|
||||||
|
>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
||||||
|
>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>
|
||||||
|
>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<
|
||||||
|
+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>+>>>]<]>[-]>[-]<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>
|
||||||
|
>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>>>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>
|
||||||
|
>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->
|
||||||
|
>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<
|
||||||
|
<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>>>]<]>[-]>[-]
|
||||||
|
<<<<<<<<<<<<<[->>>>>>>>>>>>>+<<<<<<<<<<<<<]>>>>>>>>>>>>>[-<+<<<<<<<<<<<<+>>>
|
||||||
|
>>>>>>>>>>][-]++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]
|
||||||
|
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[-
|
||||||
|
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->
|
||||||
|
+<]>[[-<+>]<<<[-]>>>]<<<[[-]>[-]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>+>>>]<]<[->>>>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]>>[-]<<
|
||||||
|
<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>[-]>>>>
|
||||||
|
>[-<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>+>>>>>][-]<<<<<<<<[->>>>>>>>+<<<<<<<<]>>>
|
||||||
|
>[-]>>>>[-<<<<<<<<+>>>>+>>>>]<<<[-]++++++++++++++++++++++++++++++++>>-<]>[[-
|
||||||
|
]>[-]<<<<<<<<<<<<<<<<[->>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<]>>>>>>>>>>>[-]>>>>>
|
||||||
|
[-<<<<<<<<<<<<<<<<+>>>>>>>>>>>+>>>>>][-]<<<<<<<[->>>>>>>+<<<<<<<]>>>[-]>>>>[
|
||||||
|
-<<<<<<<+>>>+>>>>]<<<[-]++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++>>]<[-]++++++++++++++++>[-]+++++++++++++
|
||||||
|
+>>>>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][
|
||||||
|
-]<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
||||||
|
<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-
|
||||||
|
<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<
|
||||||
|
[-]>>>]<<<[[-]<<<<+++++>>>>]>[-]>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>
|
||||||
|
[-<+<<<<<<<<+>>>>>>>>>][-]+<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<
|
||||||
|
<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>
|
||||||
|
>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]
|
||||||
|
>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[[-]<<<++++++++++>>>][-]>[-]<<<<<<<<[->>>
|
||||||
|
>>>>>+<<<<<<<<]>>>>>>>>[-<+<<<<<<<+>>>>>>>>][-]+++++++++++++++++++++++++<<<[
|
||||||
|
-]>>[>>[-]<[->+<]>[-<+<<<+>>>>]<<-][-]<<[->>+<<]>>[-<<+<<+>>>>][-]<<<<<<<<<<
|
||||||
|
<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>[-<<<<<<<<<<<+>>>>>>>->>>>][-]<<<<<<<<
|
||||||
|
<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>>>[-<<<<<<<<<<<+>>>>>>>->>>>]>[-]>[-]<
|
||||||
|
<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<+<<<<<<<<+>>>>>>>>>][-]++<<[-]+>>>
|
||||||
|
[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]
|
||||||
|
<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[
|
||||||
|
-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<<[
|
||||||
|
[-]<<<<----->>>>][-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<<<<<<+>>>->>>][-]++++++++
|
||||||
|
+++++++++++++++++++.++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++.>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>]>>>[-]>[-]<<<<<[->>>
|
||||||
|
>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>
|
||||||
|
+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<
|
||||||
|
[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]
|
||||||
|
>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<
|
||||||
|
<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>
|
||||||
|
[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[
|
||||||
|
-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
||||||
|
]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<
|
||||||
|
<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<
|
||||||
|
<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<
|
||||||
|
<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+
|
||||||
|
<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
||||||
|
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<
|
||||||
|
+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>
|
||||||
|
>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>
|
||||||
|
[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
||||||
|
>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>
|
||||||
|
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<
|
||||||
|
<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++
|
||||||
|
>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>
|
||||||
|
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]
|
||||||
|
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]
|
||||||
|
<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<
|
||||||
|
<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+
|
||||||
|
<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>
|
||||||
|
>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-
|
||||||
|
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]
|
||||||
|
<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.<++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<
|
||||||
|
<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>-<]>[[-]<<<<<<+++
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]<<]<<<<<<--------------
|
||||||
|
------------------.>[-]>[-]<<<<<<[->>>>>>+<<<<<<]>>>>>>[-<+<<<<<+>>>>>>]>>>[
|
||||||
|
-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->
|
||||||
|
>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]
|
||||||
|
>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>
|
||||||
|
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[->+<]>[[-<+>
|
||||||
|
]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]>[-]<<<<<[->
|
||||||
|
>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-
|
||||||
|
]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<
|
||||||
|
<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[-
|
||||||
|
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<
|
||||||
|
<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++
|
||||||
|
++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
||||||
|
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<
|
||||||
|
<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<[-]>>>>
|
||||||
|
>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<->>>>]>]<<<[
|
||||||
|
-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-
|
||||||
|
]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>
|
||||||
|
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+
|
||||||
|
>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>
|
||||||
|
>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>
|
||||||
|
>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]
|
||||||
|
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]
|
||||||
|
<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
||||||
|
]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>>]<<[-<<<->>
|
||||||
|
>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>
|
||||||
|
>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-
|
||||||
|
]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>
|
||||||
|
[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>
|
||||||
|
>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>]<++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>-<]>[[-]>
|
||||||
|
[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>-
|
||||||
|
<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>]<<]<<<<
|
||||||
|
<<+++++++++++++.>[-]>[-]<<<<<<<[->>>>>>>+<<<<<<<]>>>>>>>[-<+<<<<<<+>>>>>>>][
|
||||||
|
-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++<<[-]+>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>
|
||||||
|
>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>
|
||||||
|
>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<
|
||||||
|
]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[-]+++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++.<-<]>[[-]<<<<<<.>>>>>>]<[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>
|
||||||
|
>[-]>>[-<<<<<<<<<<<+>>>>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]
|
||||||
|
<<<.>>>>>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>>>>[-]>>[-<<<<<<<<<<<
|
||||||
|
+>>>>>>>>>+>>][-]<<[->>+<<]>>[[-<<+>>]<<->>]<<[<<<..>>>-]>>>[-]>[-]<<<<<<<[-
|
||||||
|
>>>>>>>+<<<<<<<]>>>>>>>[-<+<<<<<<+>>>>>>>][-]+++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<[-]+>>>[-]>[-]<<<
|
||||||
|
[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-
|
||||||
|
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]
|
||||||
|
[-]<<[->>+<<]>>[[-<<+>>]<<<[-]>>>][-]<[->+<]>[[-<+>]<<<[-]>>>]<<[-]+<[[-]>>[
|
||||||
|
-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++.<-<]>[[-]<<<<<<.>>>>>>]<<<<<<
|
||||||
|
<<<]>[-]++++++++++.[-]+>[-]+>[-]+++++++++++++++++++++++++++.++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++.>[-]>[-]<<<[->>>+<<<]>>>[-<
|
||||||
|
+<<+>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<
|
||||||
|
[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<
|
||||||
|
<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[
|
||||||
|
-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[-]<[
|
||||||
|
->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<<[-]
|
||||||
|
>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>[-]<
|
||||||
|
<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+
|
||||||
|
<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>
|
||||||
|
>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<+>>]
|
||||||
|
<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>
|
||||||
|
][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>
|
||||||
|
>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<
|
||||||
|
<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<
|
||||||
|
<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-<<<<
|
||||||
|
->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[
|
||||||
|
-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>
|
||||||
|
]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]
|
||||||
|
>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+
|
||||||
|
<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>
|
||||||
|
[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<
|
||||||
|
[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<
|
||||||
|
->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]
|
||||||
|
<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+>>>>
|
||||||
|
>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++
|
||||||
|
++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<
|
||||||
|
<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>
|
||||||
|
>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-
|
||||||
|
]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[-<+>
|
||||||
|
]<++++++++++++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++++.>
|
||||||
|
>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++.>>>>>>-<]>[[-]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>>
|
||||||
|
>>>>]<<]<<<<<<--------------------------------.>[-]>[-]<<<<[->>>>+<<<<]>>>>[
|
||||||
|
-<+<<<+>>>>]>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++>[
|
||||||
|
-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>
|
||||||
|
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>
|
||||||
|
>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<]<<<]<<<[-]>>>>>>[
|
||||||
|
-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<<+>>>>>>>]<<[-<<<<<->>>>>]>]<<
|
||||||
|
<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<<<<[-]>>>>[>>>
|
||||||
|
[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[-
|
||||||
|
>>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<
|
||||||
|
<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[->>+<<]>>[[-<<
|
||||||
|
+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>
|
||||||
|
>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<
|
||||||
|
<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[
|
||||||
|
-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<
|
||||||
|
]<]<<<]<<[-]>>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<<+>>>>>>]<<[-
|
||||||
|
<<<<->>>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++++++++<<
|
||||||
|
<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+
|
||||||
|
>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<[->>>>+<
|
||||||
|
<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]+>[-]<<[
|
||||||
|
->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]>[-]<<<<<[->>>>>+<<<<<]>
|
||||||
|
>>>>[-<+<<<<+>>>>>][-]++++++++++>[-]<<[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]
|
||||||
|
<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<
|
||||||
|
[<<<->>->[-]>[-]<<<<[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+
|
||||||
|
>>>]<<[-]+>>]<]<]<<<]<[-]>>>>[-]<[->+<]>[[-<+>]>[-]<<<[->>>+<<<]>>>[-<<<+<<+
|
||||||
|
>>>>>]<<[-<<<->>>]>]<<<[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<<<+>>>>>][-]++++
|
||||||
|
++++++<<<<<[-]>>>>[>>>[-]<<[->>+<<]>[-]>[-<<+>+>][-]>[-]<<<<[->>>>+<<<<]>>>>
|
||||||
|
[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<<->>->[-]>[-]<<<<
|
||||||
|
[->>>>+<<<<]>>>>[[-<<<<+>>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]
|
||||||
|
+>[-]<<[->>+<<]>>[[-<<+>>]<[-]>]<[[-]<<<<<<<+>>>>>>>]<<<][-]<[->+<]>>[-]+<[[
|
||||||
|
-<+>]<++++++++++++++++++++++++++++++++++++++++++++++++.<++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++.>>>>-<]>[[-]>[-]<<<<[->>>>+<<<<]>>>>>[-]+<[[-<<<<+>>>>]<<<<++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++.<++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++.>>>>>>-<]>[[-]<<<<<<+++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+.>>>>>>]<<]<<<<<<+++++++++++++.<<[-]+++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++[>[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[>[-]+++++++++
|
||||||
|
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+++++++++++++++[-]<-]<-]<<<<<]<<<<+>>>>[-]>[-]<<<<<[->>>>>+<<<<<]>>>>>[-<+<<
|
||||||
|
<<+>>>>>][-]++++<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>
|
||||||
|
>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->
|
||||||
|
>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<<[->>+<<]>>[[-<<+>>]<<<[-]+>>>][-]<[->
|
||||||
|
+<]>[[-<+>]<<<[-]+>>>]<<<]<<->>[-]<<[->>+<<]>>[[-<<+>>]<<<<<<<<-<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[-]<[-]<[-]>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>>>>>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>
|
||||||
|
>>>>>>>>[-<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>-[<<<<+>
|
||||||
|
>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-]>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>[-]>>>>>[-]<<<<<<<<<[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<+<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>>>
|
||||||
|
-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]<[-]<[-
|
||||||
|
]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>[-]>>>>[-]<<<<<<<<<[
|
||||||
|
->>>>>>>>>+<<<<<<<<<]>>>>>>>>>[-<<<<<<<<<+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<[<<<[-]<[-]<[-]+>>>
|
||||||
|
>>-[<<<<+>>>>-]<<<<]<<[->>+>+<<<]>>[-<<+>>]<[>>[->>>>+<<<<]<<>>>>]>>[->>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
[-]>[-]>>>>>>>[-]++++++++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<<<<]>>>>>>
|
||||||
|
>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]>
|
||||||
|
[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<<<]>>>[[-<
|
||||||
|
<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[->+<]>[[-<+>]<<<[-]+
|
||||||
|
>>>]<<<[<<<<<<<<--------->>+>>>>>>>[-]++++++++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>
|
||||||
|
>>+<<<<<<<<<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>
|
||||||
|
>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-
|
||||||
|
]<<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<
|
||||||
|
[->+<]>[[-<+>]<<<[-]+>>>]<<<]>[-]++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>+<<<<<<<<
|
||||||
|
<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+<<<]>>>[[
|
||||||
|
-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<<<[->>>+<
|
||||||
|
<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[->+<]>[[-<
|
||||||
|
+>]<<<[-]+>>>]<<<[<<<<<<<<--->+>>>>>>>>[-]++>[-]>[-]<<<<<<<<<<<[->>>>>>>>>>>
|
||||||
|
+<<<<<<<<<<<]>>>>>>>>>>>[-<+<<<<<<<<<<+>>>>>>>>>>>]<<<[-]>>>[-]>[-]<<<[->>>+
|
||||||
|
<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<[<<->->[-]>[-]<
|
||||||
|
<<[->>>+<<<]>>>[[-<<<+>>>]>[-]<<<[->>>+<<<]>>>[[-<<<+>>>]<<[-]+>>]<]<][-]<[-
|
||||||
|
>+<]>[[-<+>]<<<[-]+>>>]<<<]<<<<+>>>]<<]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
212
rust2/benches/mandelbrot.bf
vendored
Normal file
212
rust2/benches/mandelbrot.bf
vendored
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
|
||||||
|
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++
|
||||||
|
+++++++-[[>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[
|
||||||
|
-]<<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+<<<<<<<<>+++++<>[<>-
|
||||||
|
<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>>+<<<<<<<<>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>[<<<>>>
|
||||||
|
>>>>>>[>>>>>>>[-]<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[-]+<<<<<<<
|
||||||
|
>++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<>++
|
||||||
|
+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<<<<
|
||||||
|
<<<<<<[<<<<<<<<<]>>>[<<<>>>[-]<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<
|
||||||
|
<<<<<>[-<>>>>>>>+<<<<<<<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<
|
||||||
|
]>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>
|
||||||
|
>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[<<<<<<<>>>>>>
|
||||||
|
>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>+++++++++
|
||||||
|
+++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<
|
||||||
|
<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>
|
||||||
|
>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+<<
|
||||||
|
>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||||
|
<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>
|
||||||
|
>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->
|
||||||
|
>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[
|
||||||
|
<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||||
|
>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>>>
|
||||||
|
]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>
|
||||||
|
>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<
|
||||||
|
<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>>>
|
||||||
|
+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<
|
||||||
|
>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[-
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>
|
||||||
|
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-<<
|
||||||
|
<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>
|
||||||
|
>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<
|
||||||
|
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
||||||
|
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++
|
||||||
|
+++++++++++++++++++++<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>[-]<<]>>[<<<<<<<
|
||||||
|
+<[-<+>>>>+<<[-]]>[-><<<[->+>>>-<<<<]>>>]>>>>>>>>>>>>>[>>[-]<<>>>[-]<<<>
|
||||||
|
>>>[-]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>>>>>>[>>>>>[-<<<<<>
|
||||||
|
+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>
|
||||||
|
>>>[>>[-<<<<<<<<<+>>>>>>>>>]<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++
|
||||||
|
+++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||||
|
<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>[-<<+
|
||||||
|
>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>
|
||||||
|
>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<
|
||||||
|
<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<
|
||||||
|
<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<[->+<]>>>]<<<
|
||||||
|
>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>
|
||||||
|
>>>>>+<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>
|
||||||
|
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>
|
||||||
|
>>+<<<<<<[->>[-<<+>>]<<[->>+<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]
|
||||||
|
<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>
|
||||||
|
>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>
|
||||||
|
>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<
|
||||||
|
<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[
|
||||||
|
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<<<<
|
||||||
|
<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]
|
||||||
|
<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>
|
||||||
|
>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>
|
||||||
|
>>>-<<<<<>>>>-<<<<+>>>>>]<<<<<>>>>>>[<<<<<<>>>>>>-<<<<<<[->>>>>+<<<<<>>>
|
||||||
|
>+<<<<>>>>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>
|
||||||
|
>>>>]<<<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>+<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]>
|
||||||
|
>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>[-<<->>]+<<
|
||||||
|
[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[
|
||||||
|
>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+>>]<<[->>+<<<<<<<<<<<[<
|
||||||
|
<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<
|
||||||
|
<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>
|
||||||
|
>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>
|
||||||
|
+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>>+<<<<<<>>>]
|
||||||
|
<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>>
|
||||||
|
+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>
|
||||||
|
>>>+<<<<<<>>>]<<<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>
|
||||||
|
>[>+<>>[-<<>-<>>]<<>[-<>>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>+<<<<<<>
|
||||||
|
>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>[-<<>>>>>>+<<<<<<>>]<<>>>]<<<
|
||||||
|
>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>]<>>>[-<<<>>>>>>+<<<<<<>>[
|
||||||
|
-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>>>]<<<>>[-<<>>>>>>+<<<<<<>>]<
|
||||||
|
<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>>>>>
|
||||||
|
>>>>]<<<<<<<<<[>[-<>>>>>>+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><
|
||||||
|
>>>[-<<<>>>>>>+<<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>
|
||||||
|
>><>>>]<<<>]<>>[-<<>>>>>>+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>
|
||||||
|
><>>>]<<<>>]<<>>>[-<<<>>>>>>+<<<<<<>>>]<<<<<<<<<<<<]]>[-]<>>>[-]<<<>>>>[
|
||||||
|
-]<<<<>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[
|
||||||
|
>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<
|
||||||
|
<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[
|
||||||
|
-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>
|
||||||
|
>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<
|
||||||
|
<<<<[->>[-<<+>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>
|
||||||
|
>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<
|
||||||
|
<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>
|
||||||
|
>>>>>]<<<<<<<<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<
|
||||||
|
[->+<]>>>]<<<>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<
|
||||||
|
<<<<<<<[<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<
|
||||||
|
<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[-+>>>[-<<<->>>
|
||||||
|
]+<<<[->>>-<<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]
|
||||||
|
+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+
|
||||||
|
>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<
|
||||||
|
]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>
|
||||||
|
]<<<[->>>+<<<>>>>>>>>>[>+<>>>>[-<<<<>-<>>>>]<<<<>[-<>>>>+<<<<>]<>>>>>>>>
|
||||||
|
>]<<<<<<<<<>+<[>[-<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>[-<<<<>>+<
|
||||||
|
<>>>>]<<<<>>>]<<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>]<>>>[-<<
|
||||||
|
<>>+<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>>>]<<<>>>>[-<<<<>>+<
|
||||||
|
<>>>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<
|
||||||
|
<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>+<<>>>>[-<<<<>>-<<
|
||||||
|
><<<<<<<<<+>>>>>>>>><>>>[-<<<>>+<<>>>]<<<>>>>]<<<<>>>[-<<<>>-<<><<<<<<<<
|
||||||
|
<+>>>>>>>>><>>>]<<<>]<>>>>[-<<<<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>
|
||||||
|
>>]<<<>>>>]<<<<>>>[-<<<>>+<<>>>]<<<<<<<<<<<<]>>>>>+<<<<<]>>>>>>>>>[>>>[-
|
||||||
|
]<<<>>>>[-]<<<<>>>>>[-]<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>[
|
||||||
|
-]<<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<>>>
|
||||||
|
+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>
|
||||||
|
-<<<<+>>>>>]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<[->>>>>+<<<<<>>>>+<<<<>>>
|
||||||
|
>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>>>>>>]<<<
|
||||||
|
<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]+>>>>[
|
||||||
|
-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+
|
||||||
|
>>]<<[->>+<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>
|
||||||
|
[-<<->>]+<<[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<
|
||||||
|
<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<
|
||||||
|
<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>>[>+<>>[-<<>-<>>]<<>[-<>
|
||||||
|
>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<
|
||||||
|
<<+>>>>>>>>><>>[-<<>>>>>+<<<<<>>]<<>>>]<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>
|
||||||
|
>>>>>>><>>]<<>]<>>>[-<<<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>>
|
||||||
|
<>>]<<>>>]<<<>>[-<<>>>>>+<<<<<>>]<<<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>[<<<<<<
|
||||||
|
<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]]>>>>[-<<<<
|
||||||
|
+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>
|
||||||
|
>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>
|
||||||
|
>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>
|
||||||
|
]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>
|
||||||
|
>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>>>]<<<
|
||||||
|
<[->>>>+<<<<>>>>>[-]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[
|
||||||
|
->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-<>>>>>+<<<<
|
||||||
|
<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>
|
||||||
|
>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<
|
||||||
|
<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<
|
||||||
|
<<<<<<<<]]>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||||
|
<<<>>>>[-]<<<<>>>>>>>>>[>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]
|
||||||
|
<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>
|
||||||
|
[-<>>>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++
|
||||||
|
+++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<
|
||||||
|
<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>
|
||||||
|
>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+
|
||||||
|
<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<
|
||||||
|
<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>
|
||||||
|
>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<
|
||||||
|
->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<
|
||||||
|
>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]
|
||||||
|
>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>
|
||||||
|
>>]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[
|
||||||
|
>>>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<
|
||||||
|
<<<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>
|
||||||
|
>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<
|
||||||
|
<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>
|
||||||
|
[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>
|
||||||
|
>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-
|
||||||
|
<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>
|
||||||
|
>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<
|
||||||
|
<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<
|
||||||
|
<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>-<<>>>>[-<<<<+>>>>]<<<<[->>>>+
|
||||||
|
<<<<>>[-]<<]>>]<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[<<<<>>>>-<<
|
||||||
|
<<<<<.>>>>>>>]<<<<>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<>>>>>>>>>[>[-]>[-]>[-]>[
|
||||||
|
-]>[-]>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]<<<<<>>>
|
||||||
|
>>>>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<
|
||||||
|
>]<>>>>>>>>>>]<>>>>>+<<<<<>>>>>>>>>>>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>
|
||||||
|
>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>[-]<<<<<<<>>>>>>>>>[>>
|
||||||
|
>>>>>>>]<<<<<<<<<[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<[
|
||||||
|
<<<<<<<<<]>>>>>>>[-]+<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>[-<<<<<<<+>>>>
|
||||||
|
>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>>>[>+<>>>>>[-<<<<<>-<>>>>>]<<<<<>[-<>
|
||||||
|
>>>>+<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>+<<<<<<<[>>>>>[<<<<<>>>>>-<<<<<>>
|
||||||
|
>>>>>+<<<<<<<>>>>>]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<->>
|
||||||
|
>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>>]<
|
||||||
|
[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>>>>>>>-<<<<<<<>
|
||||||
|
>>[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>>>>>[>
|
||||||
|
>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<
|
||||||
|
->>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>
|
||||||
|
>]<[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<
|
||||||
|
>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>+<<<<<[<<<<<<<<<]>>>>>>>>
|
||||||
|
>[-+>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>-<<<<<>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<
|
||||||
|
<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>
|
||||||
|
+<]]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>[-<<<<<+>>>>
|
||||||
|
>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[
|
||||||
|
-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<
|
||||||
|
<<<>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>-<<<<<[<<
|
||||||
|
<<<<<<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<
|
||||||
|
<]>+++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<
|
||||||
|
<<>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]
|
||||||
|
<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>[-]<<<<<<<<>>>>>>>>>[>>>>>>>>>]<<<<<<
|
||||||
|
<<<[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<[<<<<<<<<
|
||||||
|
<]>>>>>>>>[-]+<<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<<<<+>>>>>>>>
|
||||||
|
]<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>>[>+<>>>>>>[-<<<<<<>-<>>>>>>]<<<<<<>
|
||||||
|
[-<>>>>>>+<<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>>+<<<<<<<<[>>>>>>[<<<<<<>>>
|
||||||
|
>>>-<<<<<<>>>>>>>>+<<<<<<<<>>>>>>]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<
|
||||||
|
<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>
|
||||||
|
>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<<<>[<>-<>>>>>>>>+<<<<<<<<>]<+
|
||||||
|
<<<<<<<<<]>>>>>>>>-<<<<<<<<>>>[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
||||||
|
<<<<[->>>>>>>>-<<<<<<<<>>>>>>>>>[>>>>>>[<<<<<<>>>>>>-<<<<<<>>>>>>>>+<<<<
|
||||||
|
<<<<>>>>>>]<<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<
|
||||||
|
<<<<<+>[<->-<<<<<<<<<<>>>>>>>>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<
|
||||||
|
<<>[<>-<>>>>>>>>+<<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<
|
||||||
|
<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
||||||
|
<<<[<<<<<<<<<]>>>>>>>>>[-+>>>>>>[-<<<<<<->>>>>>]+<<<<<<[->>>>>>-<<<<<<>>
|
||||||
|
>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<
|
||||||
|
]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
||||||
|
<<<<[->>>>>>>>-<<<<<<<<>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<
|
||||||
|
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
||||||
|
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<<>+++++<>[<>-<>[<>-<>>>>
|
||||||
|
>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>-<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>-<<<<<<[<<<<<<<<<]]>>>]<<<
|
||||||
55
rust2/benches/opts.rs
Normal file
55
rust2/benches/opts.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
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);
|
||||||
3
rust2/benches/twinkle.bf
vendored
Normal file
3
rust2/benches/twinkle.bf
vendored
Normal file
File diff suppressed because one or more lines are too long
212
rust2/mandelbrot.bf
vendored
Normal file
212
rust2/mandelbrot.bf
vendored
Normal file
|
|
@ -0,0 +1,212 @@
|
||||||
|
A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
|
||||||
|
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++
|
||||||
|
+++++++-[[>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[
|
||||||
|
-]<<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+<<<<<<<<>+++++<>[<>-
|
||||||
|
<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>>+<<<<<<<<>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>[<<<>>>
|
||||||
|
>>>>>>[>>>>>>>[-]<<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[-]+<<<<<<<
|
||||||
|
>++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<>++
|
||||||
|
+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>>+<<<<<<<<<<
|
||||||
|
<<<<<<[<<<<<<<<<]>>>[<<<>>>[-]<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<
|
||||||
|
<<<<<>[-<>>>>>>>+<<<<<<<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<
|
||||||
|
]>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>
|
||||||
|
>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>[<<<<<<<>>>>>>
|
||||||
|
>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>+++++++++
|
||||||
|
+++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<
|
||||||
|
<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>
|
||||||
|
>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+<<
|
||||||
|
>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||||
|
<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>
|
||||||
|
>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->
|
||||||
|
>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[
|
||||||
|
<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||||
|
>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>>>
|
||||||
|
]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>
|
||||||
|
>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<
|
||||||
|
<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>>>
|
||||||
|
+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<
|
||||||
|
>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[-
|
||||||
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>
|
||||||
|
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-<<
|
||||||
|
<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>
|
||||||
|
>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<
|
||||||
|
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
||||||
|
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++
|
||||||
|
+++++++++++++++++++++<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>[-]<<]>>[<<<<<<<
|
||||||
|
+<[-<+>>>>+<<[-]]>[-><<<[->+>>>-<<<<]>>>]>>>>>>>>>>>>>[>>[-]<<>>>[-]<<<>
|
||||||
|
>>>[-]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>>>>>>[>>>>>[-<<<<<>
|
||||||
|
+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>
|
||||||
|
>>>[>>[-<<<<<<<<<+>>>>>>>>>]<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++
|
||||||
|
+++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||||
|
<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>[-<<+
|
||||||
|
>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>
|
||||||
|
>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<
|
||||||
|
<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<
|
||||||
|
<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<[->+<]>>>]<<<
|
||||||
|
>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>
|
||||||
|
>>>>>+<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>
|
||||||
|
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>
|
||||||
|
>>+<<<<<<[->>[-<<+>>]<<[->>+<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]
|
||||||
|
<>]<>>>>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>
|
||||||
|
>]<<<<<<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>
|
||||||
|
>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<
|
||||||
|
<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>[
|
||||||
|
-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<<<<
|
||||||
|
<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]
|
||||||
|
<<<<<<<<>[-<>>>>>>>>+<<<<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>
|
||||||
|
>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>
|
||||||
|
>>>-<<<<<>>>>-<<<<+>>>>>]<<<<<>>>>>>[<<<<<<>>>>>>-<<<<<<[->>>>>+<<<<<>>>
|
||||||
|
>+<<<<>>>>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>
|
||||||
|
>>>>]<<<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>+<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]>
|
||||||
|
>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>[-<<->>]+<<
|
||||||
|
[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[
|
||||||
|
>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+>>]<<[->>+<<<<<<<<<<<[<
|
||||||
|
<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<
|
||||||
|
<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>
|
||||||
|
>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>
|
||||||
|
+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>>+<<<<<<>>>]
|
||||||
|
<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>>
|
||||||
|
+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>
|
||||||
|
>>>+<<<<<<>>>]<<<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>
|
||||||
|
>[>+<>>[-<<>-<>>]<<>[-<>>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>>+<<<<<<>
|
||||||
|
>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>[-<<>>>>>>+<<<<<<>>]<<>>>]<<<
|
||||||
|
>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>]<>>>[-<<<>>>>>>+<<<<<<>>[
|
||||||
|
-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><>>]<<>>>]<<<>>[-<<>>>>>>+<<<<<<>>]<
|
||||||
|
<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>>>>>
|
||||||
|
>>>>]<<<<<<<<<[>[-<>>>>>>+<<<<<<>>[-<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>><
|
||||||
|
>>>[-<<<>>>>>>+<<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>
|
||||||
|
>><>>>]<<<>]<>>[-<<>>>>>>+<<<<<<>>>[-<<<>>>>>>-<<<<<<><<<<<<<<<+>>>>>>>>
|
||||||
|
><>>>]<<<>>]<<>>>[-<<<>>>>>>+<<<<<<>>>]<<<<<<<<<<<<]]>[-]<>>>[-]<<<>>>>[
|
||||||
|
-]<<<<>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[
|
||||||
|
>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]<>>>>>>>>>]<<<<<<<<<[<<<
|
||||||
|
<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[
|
||||||
|
-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>
|
||||||
|
>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<
|
||||||
|
<<<<[->>[-<<+>>]<<[->>+<<>>>+<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>
|
||||||
|
>>>>>>>[>>>>>>>>>]<<<<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<
|
||||||
|
<<<<<<>]<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>
|
||||||
|
>>>>>]<<<<<<<<<[>[-]<->>>[<<<>>>-<<<+>[<->-<<<<<<<<<<>>>+<<<>>>>>>>>>>]<
|
||||||
|
[->+<]>>>]<<<>[<>-<>>>+<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<
|
||||||
|
<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]<<<>>>>>>>>>]<<
|
||||||
|
<<<<<<<[<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>>>++++++++++++++++-[[>>>>>>>>>]<<<
|
||||||
|
<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[-+>>>[-<<<->>>
|
||||||
|
]+<<<[->>>-<<<>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]
|
||||||
|
+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+
|
||||||
|
>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<
|
||||||
|
]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>
|
||||||
|
]<<<[->>>+<<<>>>>>>>>>[>+<>>>>[-<<<<>-<>>>>]<<<<>[-<>>>>+<<<<>]<>>>>>>>>
|
||||||
|
>]<<<<<<<<<>+<[>[-<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>[-<<<<>>+<
|
||||||
|
<>>>>]<<<<>>>]<<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>]<>>>[-<<
|
||||||
|
<>>+<<>>>>[-<<<<>>-<<><<<<<<<<<+>>>>>>>>><>>>>]<<<<>>>]<<<>>>>[-<<<<>>+<
|
||||||
|
<>>>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<
|
||||||
|
<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>+<<>>>>[-<<<<>>-<<
|
||||||
|
><<<<<<<<<+>>>>>>>>><>>>[-<<<>>+<<>>>]<<<>>>>]<<<<>>>[-<<<>>-<<><<<<<<<<
|
||||||
|
<+>>>>>>>>><>>>]<<<>]<>>>>[-<<<<>>+<<>>>[-<<<>>-<<><<<<<<<<<+>>>>>>>>><>
|
||||||
|
>>]<<<>>>>]<<<<>>>[-<<<>>+<<>>>]<<<<<<<<<<<<]>>>>>+<<<<<]>>>>>>>>>[>>>[-
|
||||||
|
]<<<>>>>[-]<<<<>>>>>[-]<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]<<<>>>>[
|
||||||
|
-]<<<<>>>>>>>>>[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<>>>
|
||||||
|
+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>
|
||||||
|
-<<<<+>>>>>]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<[->>>>>+<<<<<>>>>+<<<<>>>
|
||||||
|
>+<<<<]>>>>>[<<<<<>>>>>-<<<<<+>>>>>]<<<<<>>>>-<<<<>>>>>+<<<<<>>>>>>>]<<<
|
||||||
|
<<<<>>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<[->>>>>+<<<<<]+>>>>[
|
||||||
|
-<<<<->>>>]+<<<<[->>>>-<<<<>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>[-<<+
|
||||||
|
>>]<<[->>+<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>
|
||||||
|
[-<<->>]+<<[->>-<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<
|
||||||
|
<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<
|
||||||
|
<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+<<<>>>>>>>>>[>+<>>[-<<>-<>>]<<>[-<>
|
||||||
|
>+<<>]<>>>>>>>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<
|
||||||
|
<<+>>>>>>>>><>>[-<<>>>>>+<<<<<>>]<<>>>]<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>
|
||||||
|
>>>>>>><>>]<<>]<>>>[-<<<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>>
|
||||||
|
<>>]<<>>>]<<<>>[-<<>>>>>+<<<<<>>]<<<<<<<<<<<]>>>>>[-]<<<<<>>>>>>>[<<<<<<
|
||||||
|
<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>+<<<<<]]>>>>[-<<<<
|
||||||
|
+>>>>]<<<<[->>>>+<<<<>>>>>>>>>[>+<>>>[-<<<>-<>>>]<<<>[-<>>>+<<<>]<>>>>>>
|
||||||
|
>>>]<<<<<<<<<>+<[>[-<>>>>>+<<<<<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>
|
||||||
|
>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>
|
||||||
|
]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>
|
||||||
|
>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>>>]<<<
|
||||||
|
<[->>>>+<<<<>>>>>[-]<<<<<>>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>>>>>>>]<<<<<<<[
|
||||||
|
->>>>>>>+<<<<<<<>>>>>+<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-<>>>>>+<<<<
|
||||||
|
<>>[-<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>[-<<<>>>>>+<<<<<>>>]<<<>>]<<>>
|
||||||
|
>[-<<<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>]<>>[-<<>>>>>+<<<<<>>>[-<<
|
||||||
|
<>>>>>-<<<<<><<<<<<<<<+>>>>>>>>><>>>]<<<>>]<<>>>[-<<<>>>>>+<<<<<>>>]<<<<
|
||||||
|
<<<<<<<<]]>>>>>>>>>[>>[-]<<>>>[-]<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||||
|
<<<>>>>[-]<<<<>>>>>>>>>[>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<>>+<<>]
|
||||||
|
<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>
|
||||||
|
[-<>>>>>>+<<<<<<>>>+<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++
|
||||||
|
+++++++++-[[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<
|
||||||
|
<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>
|
||||||
|
>>>>>>>>[>-<>>>>>[-<<<<<>+<>>>>>]<<<<<>[-<>>>>>+<<<<<[->>[-<<+>>]<<[->>+
|
||||||
|
<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[>>>>>>>>>]<<<
|
||||||
|
<<<<<<<>[<>>[<<>>-<<>>>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>]<>>[<<>>-<<>>
|
||||||
|
>>>>>>>>>+<<<<<<<<<<<>>]<<<<<<<<<<<>>>>>>>>>>+<>>>>>>>>>]<<<<<<<<<[>[-]<
|
||||||
|
->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<<<>>>>>>>>>>]<[->+<]>>>>]<<<<
|
||||||
|
>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>+<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]
|
||||||
|
>>>>>>>>>[>-<>>>>>>[-<<<<<<>+<>>>>>>]<<<<<<>[-<>>>>>>+<<<<<<[->>>[-<<<+>
|
||||||
|
>>]<<<[->>>+<<<>>>>+<<<<]+>>>>>>>>>]><<<<<<<<<[<<<<<<<<<]<>]<>>>>>>>>>>[
|
||||||
|
>>>>>>>>>]<<<<<<<<<<>[<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<
|
||||||
|
<<<<<<>]<>>>[<<<>>>-<<<>>>>>>>>>>>>+<<<<<<<<<<<<>>>]<<<<<<<<<<<<>>>>>>>>
|
||||||
|
>>+<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>[<<<<>>>>-<<<<+>[<->-<<<<<<<<<<>>>>+<<
|
||||||
|
<<>>>>>>>>>>]<[->+<]>>>>]<<<<>[<>-<>>>>+<<<<>]<+<<<<<<<<<]>>>>>>>>>[>>>>
|
||||||
|
[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>]<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++++++++++-[[>>>>>>
|
||||||
|
>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+<<<<<<<<<>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>+<<<[<<<<<<<<<]>>>>>>>>>[-+>>>[-<<<->>>]+<<<[->>>-<<<>>>>[-
|
||||||
|
<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>
|
||||||
|
>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<>>>[-<<<+>>>]<<<[->>>+<<<<<<<
|
||||||
|
<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<
|
||||||
|
<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>-<<>>>>[-<<<<+>>>>]<<<<[->>>>+
|
||||||
|
<<<<>>[-]<<]>>]<<+>>>>[-<<<<->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[<<<<>>>>-<<
|
||||||
|
<<<<<.>>>>>>>]<<<<>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<>>>>>>>>>[>[-]>[-]>[-]>[
|
||||||
|
-]>[-]>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]<<<<<>>>
|
||||||
|
>>>>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<
|
||||||
|
>]<>>>>>>>>>>]<>>>>>+<<<<<>>>>>>>>>>>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>
|
||||||
|
>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>[-]<<<<<<<>>>>>>>>>[>>
|
||||||
|
>>>>>>>]<<<<<<<<<[>>>>>>>[-<<<<<<<>+<>>>>>>>]<<<<<<<>[-<>>>>>>>+<<<<<<<[
|
||||||
|
<<<<<<<<<]>>>>>>>[-]+<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>[-<<<<<<<+>>>>
|
||||||
|
>>>]<<<<<<<[->>>>>>>+<<<<<<<>>>>>>>>>[>+<>>>>>[-<<<<<>-<>>>>>]<<<<<>[-<>
|
||||||
|
>>>>+<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>+<<<<<<<[>>>>>[<<<<<>>>>>-<<<<<>>
|
||||||
|
>>>>>+<<<<<<<>>>>>]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<->>
|
||||||
|
>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>>]<
|
||||||
|
[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>>>>>>>-<<<<<<<>
|
||||||
|
>>[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>>>>>[>
|
||||||
|
>>>>[<<<<<>>>>>-<<<<<>>>>>>>+<<<<<<<>>>>>]<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<
|
||||||
|
->>>>>>>[<<<<<<<>>>>>>>-<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>+<<<<<<<>>>>>>>>>
|
||||||
|
>]<[->+<]>>>>>>>]<<<<<<<>[<>-<>>>>>>>+<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<
|
||||||
|
>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>+<<<<<[<<<<<<<<<]>>>>>>>>
|
||||||
|
>[-+>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>-<<<<<>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<
|
||||||
|
<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>
|
||||||
|
+<]]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<<<<<<>>>>>[-<<<<<+>>>>
|
||||||
|
>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[
|
||||||
|
-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<
|
||||||
|
<<<>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>-<<<<<[<<
|
||||||
|
<<<<<<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]<<<<<<>>>>>>>>>]<<<<<<<<<[<<<<<<<<
|
||||||
|
<]>+++++++++<>[<>-<>[<>-<>>>>>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<
|
||||||
|
<<>>>>>>>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>]
|
||||||
|
<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>[-]<<<<<<<<>>>>>>>>>[>>>>>>>>>]<<<<<<
|
||||||
|
<<<[>>>>>>>>[-<<<<<<<<>+<>>>>>>>>]<<<<<<<<>[-<>>>>>>>>+<<<<<<<<[<<<<<<<<
|
||||||
|
<]>>>>>>>>[-]+<<<<<<<<>>>>>>>>>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<<<<+>>>>>>>>
|
||||||
|
]<<<<<<<<[->>>>>>>>+<<<<<<<<>>>>>>>>>[>+<>>>>>>[-<<<<<<>-<>>>>>>]<<<<<<>
|
||||||
|
[-<>>>>>>+<<<<<<>]<>>>>>>>>>]<<<<<<<<<>>>>>>>>+<<<<<<<<[>>>>>>[<<<<<<>>>
|
||||||
|
>>>-<<<<<<>>>>>>>>+<<<<<<<<>>>>>>]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<
|
||||||
|
<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<<<<<<+>[<->-<<<<<<<<<<>>>>>>>
|
||||||
|
>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<<<>[<>-<>>>>>>>>+<<<<<<<<>]<+
|
||||||
|
<<<<<<<<<]>>>>>>>>-<<<<<<<<>>>[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
||||||
|
<<<<[->>>>>>>>-<<<<<<<<>>>>>>>>>[>>>>>>[<<<<<<>>>>>>-<<<<<<>>>>>>>>+<<<<
|
||||||
|
<<<<>>>>>>]<<<<<<>>>>>>>>>]<<<<<<<<<[>[-]<->>>>>>>>[<<<<<<<<>>>>>>>>-<<<
|
||||||
|
<<<<<+>[<->-<<<<<<<<<<>>>>>>>>+<<<<<<<<>>>>>>>>>>]<[->+<]>>>>>>>>]<<<<<<
|
||||||
|
<<>[<>-<>>>>>>>>+<<<<<<<<>]<+<<<<<<<<<]>+++++<>[<>-<>[<>-<>>>>>>>>>>+<<<
|
||||||
|
<<<<<<<>]<>>>>>>>>>>]<>>>>>>+<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<
|
||||||
|
<<<[<<<<<<<<<]>>>>>>>>>[-+>>>>>>[-<<<<<<->>>>>>]+<<<<<<[->>>>>>-<<<<<<>>
|
||||||
|
>>>>>>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<<<
|
||||||
|
]>>>>[-]+<<<<>>>>>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<
|
||||||
|
<<<<[->>>>>>>>-<<<<<<<<>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<
|
||||||
|
<<<[<<<<<<<<<]>>>[-]+<<<>>>>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<
|
||||||
|
<<<<<>]<>>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<<>+++++<>[<>-<>[<>-<>>>>
|
||||||
|
>>>>>>+<<<<<<<<<<>]<>>>>>>>>>>]<>>>>>>-<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>-<<<<<<[<<<<<<<<<]]>>>]<<<
|
||||||
2
rust2/rust-toolchain.toml
Normal file
2
rust2/rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly-2022-04-17"
|
||||||
102
rust2/src/hir/mod.rs
Normal file
102
rust2/src/hir/mod.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
||||||
|
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
|
||||||
|
}
|
||||||
321
rust2/src/hir/opts.rs
Normal file
321
rust2/src/hir/opts.rs
Normal file
|
|
@ -0,0 +1,321 @@
|
||||||
|
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
Normal file
185
rust2/src/lib.rs
Normal file
|
|
@ -0,0 +1,185 @@
|
||||||
|
#![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));
|
||||||
|
}
|
||||||
|
}
|
||||||
139
rust2/src/lir/interpreter.rs
Normal file
139
rust2/src/lir/interpreter.rs
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
137
rust2/src/lir/mod.rs
Normal file
137
rust2/src/lir/mod.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
//! 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);
|
||||||
|
}
|
||||||
31
rust2/src/main.rs
Normal file
31
rust2/src/main.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
#![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);
|
||||||
|
});
|
||||||
|
}
|
||||||
120
rust2/src/mir/mod.rs
Normal file
120
rust2/src/mir/mod.rs
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
//! 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 }
|
||||||
|
}
|
||||||
215
rust2/src/mir/opts.rs
Normal file
215
rust2/src/mir/opts.rs
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
220
rust2/src/mir/state.rs
Normal file
220
rust2/src/mir/state.rs
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
// 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,
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
}
|
||||||
176
rust2/src/parse.rs
Normal file
176
rust2/src/parse.rs
Normal file
|
|
@ -0,0 +1,176 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
---
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
43
rust2/src/snapshots/brainfuck__parse__tests__simple.snap
Normal file
43
rust2/src/snapshots/brainfuck__parse__tests__simple.snap
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
---
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
8
rust2/src/snapshots/brainfuck__tests__fizzbuzz.snap
Normal file
8
rust2/src/snapshots/brainfuck__tests__fizzbuzz.snap
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
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",
|
||||||
|
)
|
||||||
7
rust2/src/snapshots/brainfuck__tests__mandelbrot.snap
Normal file
7
rust2/src/snapshots/brainfuck__tests__mandelbrot.snap
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
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
rust2/test.bf
vendored
Normal file
1
rust2/test.bf
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
+++++>[-]+++[<.>]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue