Coder Social home page Coder Social logo

brain-labs / brain Goto Github PK

View Code? Open in Web Editor NEW
130.0 12.0 17.0 1.1 MB

An esoteric programming language compiler on top of LLVM based on Brainfuck

Home Page: https://brain-labs.github.io/brain/docs/html/index.html

License: GNU General Public License v3.0

Makefile 2.50% C++ 84.04% Brainfuck 0.59% C 12.00% Shell 0.71% HTML 0.16%
llvm brain brainfuck compiler interpreter repl language brainfuck-interpreter brainfuck-compiler brainfuck-parser

brain's Introduction

Logo

Brain

Build Status

A computer language based on Brainfuck.

Table of Contents

About

Brain wants to improve the performance of the Brainfuck programming language and extend it as well, as Brainfuck itself has a lack of flexibility and does not perform great control over complex computations. Brain is open to new model represetantion and allows programmers to extend its capability by attaching LLVM IR to its code.

One of the main ideas of Brain is saving some operations in machine language, creating an instruction optmizer due to the excess of instructions that Brainfuck would generate. Brain aims to implement it by using current technology (LLVM).

In spite of implementing new commands and features, Brain is completely compatible with Brainfuck (but the opposite is not true).

Install

Arch Linux via AUR

yaourt -S brain

Docker

docker pull luizperes/brain:1.0
docker run -it luizperes/brain:1.0

Documentation

You can check this repository documentation on https://brain-labs.github.io/brain/docs/html/index.html

Current Status

Brain is stable on its tag version 1.0

Obs.: To use Project Status (the "Kanban" below), please visit:https://github.com/luizperes/status-projects/blob/master/README.md and http://luizperes.github.io/status-projects/

Project Name Status Technology Priority Deadline
Brain 1.0 Progress C/C++/LLVM Low
Brain 1.1 Progress C/C++/LLVM Low
To Do In Progress Done
PostIt PostIt PostIt PostIt
PostItPostIt
PostItPostIt
PostItPostIt
PostIt

TODO List

If you want to check the micro TODO list, please see this issue.

How to build LLVM

Brain runs on the top of LLVM, thus, you are required to install the lastest versions of LLVM. You can do that by following this http://llvm.org/releases/download.html

How to install pre-commit

This project uses pre-commit to help us to check our commits in order to minimize bugs and other problems on the project, therefore is strongly recommended that you use it, if you are intending to contribute to the project. For that, you can install by:

if you have pip installed:

Mac

brew install pre-commit

Linux

sudo pip install pre-commit

After that, go to where Brain lives:

$ cd /path/to/brain
$ pre-commit install

More information about that here

How to build Brain and run files

To build it, after installing LLVM, execute:

$ cd /path/to/brain/src
$ make
$ make install

Brain will try to run on clang and clang++ automatically. However you can change your CC with the commands:

  • make build-3.8 or make build-3.9 for LLVM 3.8 and 3.9
  • make CC=clang++-3.7 LLVM_CONFIG=clang++-3.7 for older versions (3.7 in this case)

And you can do the same for installing it and running tests:

  • make install C=clang-3.7
  • make tests C=clang-3.7

After running make and make install on it, you can execute:./brain your_brain_file.b. Please check the current status of the project.

How it has been built

Brain is based on previous work https://github.com/luizperes/BrainfuckInterpreter and https://github.com/Lisapple/BF-Compiler-Tutorial-with-LLVM, now trying to make something more serious: Turing Complete, faster, more features/commands and different types.

Technical Information

Brain is now a Turing Complete language. You can now extend the tape size by using the flag --size=<tape size>.

Commands

Implemented

  • > increment the data pointer (to point to the next cell to the righ.
  • < decrement the data pointer (to point to the next cell to the left).
  • + increment (increase by one) the value at the data pointer.
  • - decrement (decrease by one) the value at the data pointer.
  • . output the value at the data pointer.
  • , accept one value of input, storing its value in the value at the data pointer.
  • [ if the value 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.
  • ] jump to its correspondent [ .
  • * multiply *ptr with *(ptr-1). Store result in *ptr // format: 2 3 *
  • / divide *ptr with *(ptr-1). Store the result in *ptr // format: 2 3 /
  • % divide *ptr with *(ptr-1). Store the remainder in *ptr // format: 2 3 %
  • # prints out the current debug information.
  • { (for loop) iterates 'value-at-the-data-pointer' times and needs to be closed with a matching } command. It does not decrease the value at the data pointer. It will only work for positive values.
  • } jump to its correspondent { .
  • ! (break) jumps to the end of a loop ([ ] or { })
  • ? if the value at the data pointer is zero , jumps to the block with : or ; and executes the commands one by one up to its correlative ;, otherwise, it executes the code until it finds a : or ;.
  • : it works as an otherwise (or else) for ?.
  • ; ends a statement.
  • $ prints out the value at the data pointer divided by 100.
  • ^ move the data pointer (jump) on the tape. Ex.: ++++++++++^ // the data pointer will jump to cell 10.
  • & stores the value of *(ptr-1) in the *ptr-th cell // format: 10 500 & (stores 10 at cell number 500.)

Not Implemented

  • @ calls a function according to the value at the data pointer.

Example of the instructions above:

  • if-then: ? +++ ; // if (*ptr) { *ptr += 3; }
  • if-else: ? +++ : --- ; // if (*ptr) { *ptr += 3; } else { *ptr -= 3; }
  • for: ++++ { commands } // makes four iterations 4 through 0 (excluded)
  • float numbers: ++>+********$ cell 0[2] cell 1[256] // '$' prints out 256 / 100
  • break loop: +[+++++!] // *ptr = 1; while(*ptr) { *ptr += 5; break; }

Compiler Options

  • --code=<"inline code"> Sets inline brain code
  • --io=repl Sets the IO module to REPLs style
  • --out=<filename> Sets the output filename
  • --size=<number> Sets the number of cells used by the interpreter
  • --size-cell=<number> Sets the cell width (8, 16, 32, 64 bits) of each cell
  • --version Shows the current version of Brain
  • -emit-llvm Emits LLVM IR code for the given input
  • -emit-ast Emits the AST for the given input
  • -emit-code Emits an optimized code for the given input
  • -c Generates object file
  • -S Generates assembly file
  • -v Uses verbose mode for the output
  • -O0 Generates output code with no optmizations
  • -O1 Optimizes Brain generated output code (Default)

Applications on real life

  • Artificial Intelligence/ Machine Learning
  • Send commands to Arduino
  • Easy support to primitive processors

Help

Feel free to send your pull requests. :)

LICENSE

This project extends GNU GPL v. 3, so be aware of that, regarding copying, modifying and (re)destributing.

brain's People

Contributors

haskellcamargo avatar luizperes avatar rafaelcn avatar rdebath avatar ryukinix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brain's Issues

BreakExpr for nested stmts

BreakExpr does not seem to be working properly for nested statements, such as an IfExpr in a LoopExpr

Transfering the repository to `brain-labs`

I setup right now all the basic necessary structure and invoked you, @luizperes , as the Team Maintainer. As you wish, you can add more people and create new teams, as new repository too.

The structure is:

(setf brain-labs ('brain
                  'brain-repl
                  'brain-docs
                  'brain-experiments
                  'brain-examples
                  'brain-training
                  'brain-labs.github.io))

You are welcome.

Makefile and bash scripts problems

Our current problems are:

  • aliases on Linux seem to not be working with clang on Brain.
  • Brain can be compiled with the versions of LLVM 3.5, 3.8 and 3.9 (we have not tested versions 3.6 and 3.7)
  • We have way too many bash scripts. Should we reduce it?

Travis file bug

Travis is not working properly. PR #44 was supposed to have broken, but it is not, once Travis is downloading my dev branch instead.

Implement mov instruction '&'

Implement mov instruction as described on #17:

====== From #17

To keep the pattern in Brain, we decided that instead of allowing functions, we will implement the operator @ (or the &) as:

Imagine the tape with: [2][4][100][5000][0]....

The code >>>@ would then copy the number 100 to cell number 5000

Make tape cell size custom

Currently, each cell has the size of 32 bits. It should be custom, once Brainfuck interpreters rely on many cell sizes (you will find all kinds of them: 8, 16, 32 or 64 bits). This way we can keep the suporte do Brainfuck

Verbose mode for -emit-expr

Maybe can be useful get a more descriptive and friendly the expressions of -emit-expr. The idea is put things like IncrementExpr (3) as IncrementExpression 3 times in cell x.

Brain - LLVM IR inline

I was thinking of having a possibility to add LLVM IR.
That would be very useful for the creation of libraries for Brain. // using functions in the future
Any considerations?

Fix compiler warnings

Check and fix:

warning: unknown warning option '-Wno-maybe-uninitialized'; did you mean '-Wno-uninitialized'? [-Wunknown-warning-option]

Create a config file for brain

A tool that accepts its configuration with a file is highly customizable and fairly easy to work, we save two things when implementing a configuration file:

  • Time
  • Time

The process of compilation can last longer as the project increases, so it's to keep those things in mind. Therefore a configuration file to Brain would be nice to be implemented. All the properties of Brain would be customizable from that file.

Representing numbers in Brain

I'm opening this new thread because Brain needs to represent literal numbers in a better way than Brainfuck. How can we do that?

I have seen some languages doing (and @leonardohn has also suggested to use)

5+4---->3*

Although that would make us implement at least 10 more commands 0-9 and they would not be one byte commands anymore. Because of that, I'm thinking of a new way of representing numbers in a cheap way.

For example, image the number 123. How would one represent that in Brain?

+++++++++++ make number 11 on cell 0
> + make number 1 on cell 1 
* make number 11 on the next cell
* multiply cells 0 and 1 = 121
++ add 2 on cell 1

For that, I think that we should think on a new and faster way (that wouldn't create more commands). For example:

+    step 1 \ make number 1 on cell 0
>++ step 2 \ make number 2 on cell 1
>+++ step 3 \ make number 3 on cell 2
<<< step 4 \ return to cell 0
$ step 5 \ eval the number and write it on cell 4

In that way, $ would work as an eval for a number (making the literal number), in this way:

  • Step 1: [1][0][0][0][0]...
  • Step 2: [1][2][0][0][0]...
  • Step 3: [1][2][3][0][0]...
  • Step 4: [1][2][3][0][0]...
  • Step 5: [1][2][3][123][0]... // evaluates until it find a '0' and replace it with the number found

What do you guys think?

Nested if statements

? if the value at the data pointer is zero , jumps to the block with : or ; and executes the commands one by one up to its correlative ;, otherwise, it executes the code until it finds a : or ;.

Do you support code like this?

+?>+?>>:<<;:<;

Expanded:

+?
    >+?
        >>
        :
        <<
    ;
    :
    <
;

Are you able to figure out which : to jump to?

Implementation of the symbol `^`

Implement new command ^

Benefits:
Right now, If you want to move from the 1st cell to 100th cell you will need to write something like:

1st way

++++++++++>**-{>}

2nd way

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

While the 1st way runs in O(n), the 2nd way runs in O(1), where n is the desired cell. In this way, the 2nd way of writing is way faster, however, when the desired cell increases/decreases (let's think in a big number like 1000000), we would need need to write the command > one million times!

That is why I think that we should have a command ^.
In this way, if one wanted to move the pointer from the 1st cell to the 1-million-th cell that would be as easy as:

++++++++++>+******^

That would be also O(1) for all cases :D

Makefile rules build and install are mixed and confused

This is very annoying. The build triggers are getting sudo permissions to modify the OS filesystem on building the brain compiler.

I think it is better move all the statements for linking/creating libraries, move binaries and other stuffs to install trigger and keep build rule to just... build.

This is really more simple and clear.

So the INSTALL process will be:

make
sudo make install

I'm really angry about that, because I'm pain with the idiomatic way to build packages on ArchLinux don't allow to modify the OS before build the package. All the files need be put a sandbox, so after compressed, the system get all the files whose will be inserted on operating system and that way we can know exactly the files installed after it. That way is very simple remove the package.

Yes, it's very bad.

photo_2016-10-01_22-44-59

Create a wiki to make the README.md small and cleaner

The purpose of this issue is to lay down what needs to be done in order to clean the README.md file which is huge!

  • Page introducing Brain, the language and its features
  • Page introducing Brain alphabet which teaches in small pieces of code what each operator does
  • Compiler information, how does it work? What are the available options?

I think it would be healthier for the project to make README.md small, any information more than an simple introduction is too much.

Benchmark

Is any benchmark for this language?
Is possible to create benchmark in integer?

Segmentation fault!

Happens with v1.0 and master.

debian-jessie64(robert)brain-labs$ git describe --tags
v1.0
debian-jessie64(robert)brain-labs$ clang++ --version
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
debian-jessie64(robert)brain-labs$
debian-jessie64(robert)brain-labs$ ~/bfi/bf.bin/bfi -c tests/helloworld.b > c.cpp
debian-jessie64(robert)brain-labs$ clang++ -O3 -o c c.cpp
debian-jessie64(robert)brain-labs$ ./c
Hello World!
debian-jessie64(robert)brain-labs$
debian-jessie64(robert)brain-labs$ gdb -args bin/brain tests/helloworld.b                                                                           GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/brain...done.
(gdb) run
Starting program: /home/robert/brain-labs/bin/brain tests/helloworld.b
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000e9c55b in llvm::Value::setNameImpl(llvm::Twine const&) ()
(gdb) bt
#0  0x0000000000e9c55b in llvm::Value::setNameImpl(llvm::Twine const&) ()
#1  0x0000000000e9c9b9 in llvm::Value::setName(llvm::Twine const&) ()
#2  0x0000000000e3cfd5 in llvm::Function::BuildLazyArguments() const ()
#3  0x000000000073c2b4 in llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) ()
#4  0x000000000073b5a3 in llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) ()
#5  0x00000000004c2071 in (anonymous namespace)::X86DAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) ()
#6  0x00000000008ae0b6 in llvm::MachineFunctionPass::runOnFunction(llvm::Function&) ()
#7  0x0000000000e6afd3 in llvm::FPPassManager::runOnFunction(llvm::Function&) ()
#8  0x0000000000e6b1c3 in llvm::FPPassManager::runOnModule(llvm::Module&) ()
#9  0x0000000000e6b5c8 in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
#10 0x0000000000b49b8c in llvm::MCJIT::emitObject(llvm::Module*) ()
#11 0x0000000000b49da4 in llvm::MCJIT::generateCodeForModule(llvm::Module*) ()
#12 0x0000000000b4a7c1 in llvm::MCJIT::finalizeObject() ()
#13 0x000000000042de8c in Bootstrap::init (this=0x1698170, argc=<optimized out>, argv=<optimized out>) at src/utils/Bootstrap.cpp:119
#14 0x00007ffff69ddb45 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6
#15 0x000000000042c6e7 in _start ()
(gdb)

Implementation of the symbol `$`

Initially I was thinking about using the char $ for converting the current cell back and forth with float and int, that would have some implications with the LLVM IRBuilder, since we would need to implement suppport to floating numbers for each arithmetic operation, debug and so on... Although, my real concerns are related on how we would do it... I was thinking of using union for that

The 1.0 Brain

This issue holds all tasks that we need to do to reach 1.0! If you have done a task, please, mark it, and then add the commit hash aside of the task which you completed it.

Features and whatnot

  • Fix file testscripts.c.
    • Linux.
    • Mac.
  • Implement ?, :, ;.
  • Ignore else's without if's.
  • Improve the methods IsBranch, IsTerminator and so on.
  • Code refactoring for the return methods inside the recursivity.
  • Code refactoring for the whole project. Improve readability (CodeGen params too).
  • Create verbose mode describe on https://github.com/luizperes/brain/issues/2
  • Fix InputExpression
  • Implement optimization for empty whiles [ ]. Ignore them (For Else too).
  • Implement optimization for empty moves ShiftExpr(0) and IncrementExpression(0).
  • Change the if and while.if (*ptr != 0), not if (*ptr > 0). Although for is going to work only for positive numbers.
  • Implement -version flag.
  • Allow the compiler to have cells larger than 100 x 4
  • Implement a generate optimized code option for the compiler.
  • Implement a delete comments option for the compiler.
  • Improve the return at the method Parser::isSkippable. Check switch at the parser.
  • Change module's name.
  • Code's refactoring:
    • Move the content of brain.cpp to a boostrap file.
    • Refactor parser.cpp.
  • Make sure you are deleting objects from the heap.
  • Implement $ as a print for number / 100.
    • Create tests for $ as well.
  • Check if required functions (LLVM IR) are implemented.
  • Breaks are not working inside if (they are going back to the beginning of the loop)
  • Fix verbose mode and levels for the debug mode
  • Create install script. (remember to install the libs)

Documentation

Binary generation

The compiler should also, besides being a JIT compiler, read a brain file and generate an executable, the discussion is concerned on to whether the compiler should generate it only when requested, throught a flag, or it would generate the binary when called, like gcc and other compilers do.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.