diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cfd336d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.idea/
+
+env/
+**/__pycache__/
+
+test.fbf
\ No newline at end of file
diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md
new file mode 100644
index 0000000..3315752
--- /dev/null
+++ b/DOCUMENTATION.md
@@ -0,0 +1,87 @@
+#Documentation
+
+Hi, if you are reading this, you want to learn how to use FuckBrainFuck.
+
+First you need to know the classic BrainFuck syntax.
+You should read this course:
+- [Brainfuck Language (English) (by roachhd)](https://gist.github.com/roachhd/dce54bec8ba55fb17d3a)
+- [Brainfuck Language (French) (by Astremy)](https://cdn.discordapp.com/attachments/815331771197030441/824402769397940234/brainfuck.pdf)
+
+
+Now I'm going to explain how to use the new implementations of FuckBrainFuck.
+
+###FuckBrainFuck already offers:
+
+- "Safe" comments
+- Functions
+
+
+## Comments
+Safe comments allow you to use any characters in the comments as opposed to the classic brainfuck comments
+where you can't use the characters used by the language
+
+You can write comments between two `#` characters.
+
+Example:
+```
+,# This is a safe comment. I can use <>+-[],. and
+others characters of FuckBrainFuck here like :;
+I can also skip lines. This program returns the character of the input #.
+```
+
+
+## Functions
+Functions are a way to use the same code multiple times.
+Functions are stored in a different array than the classic BrainFuck array.
+
+You can define functions between `:` and `;`. To call it, use `x`.
+
+You can use recursive functions.
+You can also define functions inside functions,
+but you have to move the pointer to right or left
+because you can't have multiple functions in the same cell.
+
+
+Example:
+```
+:,++.; # This functions asks the user and adds two to the cell and then prints the result. #
+x # Execute the function. #
+```
+
+Nested Functions:
+```
+:
+ ,
+ >:
+ <++
+ ; # This function go to left and adds 2 to the value of the cell.#
+ x. # Execute the function and display the result.
+ After executing the function, we are one square ahead.
+ Here, the function is obviously useless since we use it only once.#
+;
+x
+```
+_In the example above, I indented the code. It makes it more readable, doesn't it?_
+
+You can see that before declaring the second function, I moved my pointer to the right.
+This allows me to avoid unexpected behavior.
+
+
+Recursive Functions:
+```
+:
+ [[->+>[->+>+<<]>>[-<<+>>]<<<<]>>[-]>[-<+>]<<[-<+>]<-x[-]]
+; # This function calculates the factorial of a number. #
+>>+<<
++++++ # Here is the input for the recursive function. #
+x>>. # The output will be "x" because 120 is the ASCII value of "x".
+ The output is always the remainder of the factorial divided by 255. #
+```
+_Thanks Astremy for the code!_
+
+
+I think you now know all about the FuckBrainFuck's syntax.
+Thanks for reading the documentation.
+Maybe the people in [the BrainFuck channel on Graven's server](https://discord.gg/DTtXYNc3ct)
+will help you with FuckBrainFuck (in French).
+I hope everything goes well for you, goodbye
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0d6506d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,183 @@
+
+
+
+[![Contributors][contributors-shield]][contributors-url]
+[![Forks][forks-shield]][forks-url]
+[![Stargazers][stars-shield]][stars-url]
+[![Issues][issues-shield]][issues-url]
+[![MIT License][license-shield]][license-url]
+
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+ -
+ About The Project
+
+
+ -
+ Getting Started
+
+
+ - Usage
+ - Contributing
+ - License
+ - Contact
+ - Acknowledgments
+
+
+
+
+
+
+## About The Project
+
+It all started on the Discord server of Graven, on 26th June 2022.
+It was a joke that ended up on this shit...
+
+So FuckBrainFuck was born. It is an improvement of the classic BrainFuck.
+
+We have already implemented:
+
+- Functions
+- "Safe" comments
+
+(back to top)
+
+
+
+### Built With
+
+* [![Python][python-shield]][python-url]
+
+(back to top)
+
+
+
+
+## Getting Started
+
+### Prerequisites
+
+You may need to install Python 3.6 or higher.
+
+### Installation
+
+
+
+1. Clone the repo
+ ```sh
+ git clone https://github.com/Sellig6792/FuckBrainFuck.git
+ ```
+
+
+(back to top)
+
+
+
+
+## Usage
+
+Soon...
+
+[//]: # ((back to top)
)
+
+
+
+## Contributing
+
+Contributions are what make the open source community such an amazing place to learn, inspire, and create.
+Any contributions you make are **greatly appreciated**.
+
+If you have a suggestion that would make this better, please fork the repo and create a pull request.
+You can also simply open an issue with the tag "enhancement".
+Don't forget to give the project a star! Thanks again!
+
+1. Fork the Project
+2. Create your Feature Branch (`git flow feature start [feature name]`)
+3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
+4. Push to the Branch (`git flow feature publish [feature name]`)
+5. Open a Pull Request on the develop branch
+
+(back to top)
+
+
+
+
+## License
+
+Distributed under the MIT License. See `LICENSE.txt` for more information.
+
+(back to top)
+
+
+
+
+## Contact
+
+Your Name - [@Sellig6792](https://twitter.com/Sellig6792) - sellig6792@gmail.com
+
+Project Link: [https://github.com/Sellig6792/FuckBrainFuck](https://github.com/Sellig6792/FuckBrainFuck)
+
+(back to top)
+
+
+
+
+## Acknowledgments
+
+* [Wikipedia - Brainfuck][wikipedia-brainfuck-url]
+* [Astremy - Brainfuck Course (French)][astremy-brainfuck-pdf]
+(back to top)
+
+
+
+
+
+[contributors-shield]: https://img.shields.io/github/contributors/Sellig6792/FuckBrainFuck.svg?style=for-the-badge
+[contributors-url]: https://github.com/Sellig6792/FuckBrainFuck/graphs/contributors
+[forks-shield]: https://img.shields.io/github/forks/Sellig6792/FuckBrainFuck.svg?style=for-the-badge
+[forks-url]: https://github.com/Sellig6792/FuckBrainFuck/network/members
+[stars-shield]: https://img.shields.io/github/stars/Sellig6792/FuckBrainFuck.svg?style=for-the-badge
+[stars-url]: https://github.com/Sellig6792/FuckBrainFuck/stargazers
+[issues-shield]: https://img.shields.io/github/issues/Sellig6792/FuckBrainFuck.svg?style=for-the-badge
+[issues-url]: https://github.com/Sellig6792/FuckBrainFuck/issues
+[license-shield]: https://img.shields.io/github/license/Sellig6792/FuckBrainFuck.svg?style=for-the-badge
+[license-url]: https://github.com/Sellig6792/FuckBrainFuck/blob/master/LICENSE.txt
+[Python-url]: https://www.python.org/
+[Python-shield]: https://img.shields.io/badge/-Python-black.svg?style=for-the-badge&logo=python&colorB=555
+[BrainFuck-url]: https://en.wikipedia.org/wiki/Brainfuck
+[BrainFuck-shield]: https://img.shields.io/badge/-BrainFuck-black.svg?style=for-the-badge&logo=brainfuck&colorB=555
+
+[graven-discord-url]: https://discord.gg/graven
+[astremy-brainfuck-pdf]: https://cdn.discordapp.com/attachments/815331771197030441/824402769397940234/brainfuck.pdf
+[wikipedia-brainfuck-url]: https://en.wikipedia.org/wiki/Brainfuck
diff --git a/assets/logo.png b/assets/logo.png
new file mode 100644
index 0000000..b437e08
Binary files /dev/null and b/assets/logo.png differ
diff --git a/fbf.py b/fbf.py
new file mode 100644
index 0000000..872b10a
--- /dev/null
+++ b/fbf.py
@@ -0,0 +1,38 @@
+import os
+import sys
+import argparse
+
+from interpreter import Interpreter
+
+
+def get_usage() -> str:
+ return "fbf (path) [-h] [-c COMPILE] [-x EXECUTE]"
+
+
+def get_args() -> argparse.Namespace:
+ if not sys.argv[1].startswith('-'):
+ path = sys.argv[1]
+ del sys.argv[1]
+ else:
+ path = None
+
+ parser = argparse.ArgumentParser(prog="FuckBrainFuck", description="The improved version of BrainFuck",
+ usage=get_usage())
+
+ parser.add_argument("-c", "--compile", help="Compile the file")
+ parser.add_argument("-x", "--execute", help="Execute a string")
+
+ _args = parser.parse_args()
+ setattr(_args, 'path', path)
+ return _args
+
+
+if __name__ == '__main__':
+ args = get_args()
+
+ if args.path:
+ with open(args.path, mode='r+') as file:
+ code = ''.join(file.readlines())
+ Interpreter(code)()
+ if args.execute:
+ Interpreter(args.execute)()
diff --git a/interpreter/__init__.py b/interpreter/__init__.py
new file mode 100644
index 0000000..c893c2c
--- /dev/null
+++ b/interpreter/__init__.py
@@ -0,0 +1,206 @@
+class Interpreter:
+ def __init__(self,
+ code: str,
+ pointer: int = 0,
+
+ stdin: str = None,
+ stdout: str = '',
+
+ stack: list = None,
+ cells: list[int] = None,
+
+ function_cells: list[str] = None,
+
+ is_function: bool = False,
+ ):
+ self.is_function = is_function
+ self.i = 0
+ self.code = code.replace('\n', '').replace('\t', '').replace(' ', '')
+ if ',' in self.code and not stdin:
+ stdin = [*input()]
+
+ self.stack = stack or []
+ self.cells = cells or [0] * 30000
+
+ self.function_cells = function_cells or [''] * 30000
+ self.opened_functions = []
+
+ self.stdin = stdin
+ self.stdout = stdout
+
+ self.pointer = pointer
+
+ self.writing_function: bool = False
+ self.in_comment: bool = False
+
+ @property
+ def cell(self):
+ return self.cells[self.pointer]
+
+ @cell.setter
+ def cell(self, value):
+ self.cells[self.pointer] = value
+
+ @property
+ def function_cell(self):
+ return self.function_cells[self.pointer]
+
+ @function_cell.setter
+ def function_cell(self, value):
+ self.function_cells[self.pointer] = value
+
+ def __call__(self, *args, **kwargs) -> dict:
+ while self.i < len(self.code):
+ instruction = self.code[self.i]
+
+ if instruction == '#':
+ self.i += 1
+ self.in_comment = not self.in_comment
+ continue
+ if self.in_comment:
+ self.i += 1
+ continue
+
+ if self.writing_function:
+ if instruction == ';':
+ # Close the last function opened. If there is only one function opened left, end the function.
+ self.opened_functions.pop()
+ if len(self.opened_functions) == 0:
+ self.end_function()
+ self.i += 1
+ continue
+
+ self.function_cell += instruction
+ if instruction == ':':
+ self.opened_functions.append(self.i)
+ self.i += 1
+ continue
+
+ if instruction == '>':
+ self.right()
+ if instruction == '<':
+ self.left()
+
+ if instruction == '+':
+ self.add()
+ if instruction == '-':
+ self.sub()
+
+ if instruction == '.':
+ self.outp()
+ if instruction == ',':
+ self.inp()
+
+ if instruction == '[':
+ self.start_loop()
+ if instruction == ']':
+ self.end_loop()
+
+ if instruction == ':':
+ self.start_function()
+
+ if instruction == 'x':
+ self.execute()
+ self.i += 1
+
+ if self.is_function:
+ return {
+ 'stdin': self.stdin,
+ 'stdout': self.stdout,
+ 'cells': self.cells,
+ 'function_cells': self.function_cells,
+ 'stack': self.stack,
+ 'pointer': self.pointer
+ }
+ else:
+ print(self.stdout)
+
+ def right(self):
+ """
+ Decrement the data pointer (to point to the next cell to the left).
+ """
+ self.pointer = (self.pointer + 1) % 30000
+
+ def left(self):
+ """
+ Decrement the data pointer (to point to the next cell to the left).
+ """
+ self.pointer = (self.pointer - 1) % 30000
+
+ def add(self):
+ """
+ Increment (increase by one) the byte at the data pointer.
+ """
+ self.cell = (self.cell + 1) % 255
+
+ def sub(self):
+ """
+ Decrement (decrease by one) the byte at the data pointer.
+ """
+ self.cell = (self.cell - 1) % 255
+
+ def outp(self):
+ """
+ Output the byte at the data pointer.
+ """
+ self.stdout += chr(self.cell)
+
+ def inp(self):
+ """
+ Accept one byte of input, storing its value in the byte at the data pointer.
+ """
+ char, *self.stdin = self.stdin
+ self.cell = ord(char)
+
+ def start_loop(self):
+ """
+ If the byte at the data pointer is zero,
+ then instead of moving the instruction pointer forward to the next command,
+ jump it forward to the command after the matching ] command.
+ """
+ if self.cell:
+ self.stack.append(self.i)
+ else:
+ n = -1
+ while self.code[self.i] != ']' or n:
+ instruction = self.code[self.i]
+ if instruction == '[':
+ n += 1
+ elif instruction == ']':
+ n -= 1
+ self.i += 1
+
+ def end_loop(self):
+ """
+ If the byte at the data pointer is nonzero,
+ then instead of moving the instruction pointer forward to the next command,
+ jump it back to the command after the matching [ command.
+ """
+ self.i = self.stack.pop() - 1
+
+ def execute(self):
+ """
+ Execute the function at the data pointer.
+ """
+ function = Interpreter(
+ self.function_cell, self.pointer,
+ self.stdin, self.stdout,
+ self.stack, self.cells,
+ self.function_cells, True
+ )
+ args = function()
+ self.__dict__.update(args)
+
+ def start_function(self):
+ """
+ Start writing a function.
+ """
+ self.function_cell = ''
+ self.opened_functions.append(self.i)
+ self.writing_function = True
+
+ def end_function(self):
+ """
+ End writing a function
+ """
+ self.writing_function = False