Giter Club home page Giter Club logo

brainduck's Introduction

Brainduck

Code Review

Inspired by the Rubberduck project for VBA, this project is called Brainduck (it was either that or Rubberf... erhm...)

Brainduck is a tool for Brainfuck written in Java and Groovy

Features

  • Can run Brainfuck programs
  • Editor with line numbers
  • Step through the code to see what happens
  • Code Analysis
  • Memory Analysis

Planned features

  • Groovy DSL (Domain-Specific-Language) for writing Brainfuck programs
  • Fully-fledged debugger, with breakpoints
  • Brainfuck code to Groovy code conversion
  • Support for test-cases
  • Syntax highlighting
  • Showing Errors and Warnings in Editor
  • Showing Tips for how to improve the Brainfuck code

Try it

git clone [email protected]:Zomis/Brainduck.git
cd Brainduck
./gradlew dist

A *-all.jar file can be found in Brainduck/build/libs/, run it with java -jar *-all.jar

Or download the latest *-all.jar version from my Jenkins

See also

My contributions to the Brainfuck tag on Code Review

brainduck's People

Contributors

zomis 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

karthickeyang

brainduck's Issues

Program Validation according to standards

See http://www.muppetlabs.com/~breadbox/bf/standards.html

Determine if a program lives up to "standards", and if so, which.

Things to detect include:

  • Does tape pointer ever go below zero?
  • Rightmost memory position used (9999, 30k, or higher)
  • Does tape pointer ever go to the right of memory size? (relying on wrap-around)
  • What range of values is used for a single cell? 0-127, 0-255, negative values? Wrap-around?
  • Input value when there's no more data, store a 0, store a -1, or value unchanged? (mostly applicable if , is used as the condition for a loop)
  • What value is expected when pressing ENTER, is it ASCII 10, ASCII 13, ASCII 0, or something else?
  • Balanced brackets
  • Check if any Brainfuck characters are used within Groovy code, which would make the BF code not behave the same in other interpreters (related to #10)

Using Run -> Step Continue can lead to infinite loop

When using this code: http://codereview.stackexchange.com/q/26648/31562 and pressing F8 (Step Continue) the program can hang, or it can also stop the loop at the wrong place.

The intended behavior, I believe, is:

  • If you are not inside any loop, then go to next loop if one exists. If no such loop exists, do the same as a single normal step would.
  • Otherwise, go to the END_WHILE of the loop that you are currently in. And then go one step beyond it (so that it is either the start of the next iteration, or at the loop end)

Repeated commands

Sometimes, in BF, a single command, or a pattern of commands may be repeated quite a number of times. It would be nice to have some sort of easier way to write repeated commands.

Perhaps it could look something like this:

(++>)*100

Which would execute ++> 100 times.

I got the idea from this PPCG post.

Embedded special instructions

To embed assertions, debugging and other stuff, there needs to be a way to do that.

How about something like ${instructions here} ?

A problem about Brainfuck is that all non-BF characters are treated as comments, which means that it's much harder to add special meanings to certain characters.

Related to #2

Headless issues

  • Make program work from command line (#46) out of the box in Headless environments without the user doing export DISPLAY=:0 or -Djava.awt.headless=true
  • Make program terminate correctly when run from command line, JavaFX Application Thread is still running.

Dynamic tooltips

Originally part of #6, but serves better as its own issue as it is quite a big one.

Use dynamic tooltips for inspecting the code, and use them to show the Hint, Warning and Error results from #28

Improve running + analyze performance

As more and more features are added to the analysis, it takes longer and longer time to run.
The FizzBuzz analysis alone takes about 17 seconds on my reasonably-fast computer.
Running without analysing takes 15.6 seconds
Running without groovy code enabled takes 0.7 seconds

Possible ways to improve performance:

  • Keep track of which [ and ] are grouped together to be able to jump to the other one immediately without requiring a code-search each time
  • Improve performance of Groovy code

Prevent hanging on infinite loops

Easiest way to hang the program: +[>+<]

Make the Brainfuck runner run in a separate thread, to avoid blocking the UI thread, also include a stop button.

Release plugin

Add a Gradle release plugin and use Travis to put releases on Github.

Run code until next loop starts

Add menu item for running until you encounter a [ (either from after a ] repeat or until the next such. If there are no more loop starts, run until end.

Run from command line

If one or more file names are specified on the command line, run those files directly instead of showing the GUI.

Remove that "Save code" button

Currently there is a "Save code" button which needs to be clicked in order to transform the String to BrainfuckCommands. This is bad user experience as it is easy to forget to click that button.

Instead, automatically transform code to BrainfuckCommands when you start to run the code or when the running stops.

String index out of range + Value arrived out of order

Start the program and the FizzBuzz BF code appears. Press Ctrl + End and then try to write something and you get this:

Exception in thread "JavaFX Application Thread" java.lang.StringIndexOutOfBoundsException: String index out of range: -151
    at java.lang.String.substring(String.java:1967)
    at org.fxmisc.richtext.Paragraph.substring(Paragraph.java:73)
    at org.fxmisc.richtext.StyledDocumentBase.sub(StyledDocumentBase.java:245)
    at org.fxmisc.richtext.StyledDocumentBase.getText(StyledDocumentBase.java:51)
    at org.fxmisc.richtext.EditableStyledDocument.lambda$null$24(EditableStyledDocument.java:129)
    at org.reactfx.util.Tuple2.map(Tuple2.java:31)
    at org.fxmisc.richtext.EditableStyledDocument.lambda$new$25(EditableStyledDocument.java:129)
    at org.reactfx.MappedStream.lambda$observeInputs$201(MappedStream.java:22)
    at org.reactfx.util.NonAccumulativeStreamNotifications.lambda$head$272(NotificationAccumulator.java:134)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.ProperEventStream.emit(ProperEventStream.java:18)
    at org.reactfx.EventStreams$20.tryEmit(EventStreams.java:441)
    at org.reactfx.EventStreams$20.lambda$observeInputs$36(EventStreams.java:436)
    at org.reactfx.util.NonAccumulativeStreamNotifications.lambda$head$272(NotificationAccumulator.java:134)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.ProperEventStream.emit(ProperEventStream.java:18)
    at org.reactfx.EventSource.push(EventSource.java:18)
    at org.fxmisc.richtext.EditableStyledDocument.replace(EditableStyledDocument.java:454)
    at org.fxmisc.richtext.EditableStyledDocument.replaceText(EditableStyledDocument.java:192)
    at org.fxmisc.richtext.StyledTextArea.replaceText(StyledTextArea.java:720)
    at org.fxmisc.richtext.TextEditingArea.replaceText(TextEditingArea.java:204)
    at org.fxmisc.richtext.EditActions.replaceSelection(EditActions.java:119)
    at org.fxmisc.richtext.skin.StyledTextAreaBehavior.keyTyped(StyledTextAreaBehavior.java:276)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$null$23(EventHandlerTemplate.java:156)
    at java.util.Optional.ifPresent(Optional.java:159)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$act$24(EventHandlerTemplate.java:155)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$Builder.lambda$create$21(EventHandlerTemplate.java:117)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$17(EventHandlerTemplate.java:39)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$bind$14(EventHandlerTemplate.java:18)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
    at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
    at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$354(GlassViewEventHandler.java:228)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
    at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
    at com.sun.glass.ui.View.notifyKey(View.java:966)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Value arrived out of order: 4487
    at org.reactfx.EventStreams$ExclusivePocket.set(EventStreams.java:671)
    at org.reactfx.EventStreams$21.lambda$observeInputs$37(EventStreams.java:459)
    at org.reactfx.util.NonAccumulativeStreamNotifications.lambda$head$272(NotificationAccumulator.java:134)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:68)
    at org.reactfx.ObservableBase.notifyObservers(ObservableBase.java:57)
    at org.reactfx.ProperEventStream.emit(ProperEventStream.java:18)
    at org.reactfx.EventSource.push(EventSource.java:18)
    at org.fxmisc.richtext.EditableStyledDocument.replace(EditableStyledDocument.java:453)
    at org.fxmisc.richtext.EditableStyledDocument.replaceText(EditableStyledDocument.java:192)
    at org.fxmisc.richtext.StyledTextArea.replaceText(StyledTextArea.java:720)
    at org.fxmisc.richtext.TextEditingArea.replaceText(TextEditingArea.java:204)
    at org.fxmisc.richtext.EditActions.replaceSelection(EditActions.java:119)
    at org.fxmisc.richtext.skin.StyledTextAreaBehavior.keyTyped(StyledTextAreaBehavior.java:276)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$null$23(EventHandlerTemplate.java:156)
    at java.util.Optional.ifPresent(Optional.java:159)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$On.lambda$act$24(EventHandlerTemplate.java:155)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate$Builder.lambda$create$21(EventHandlerTemplate.java:117)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$null$17(EventHandlerTemplate.java:39)
    at org.fxmisc.wellbehaved.event.EventHandlerTemplate.lambda$bind$14(EventHandlerTemplate.java:18)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
    at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
    at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
    at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$354(GlassViewEventHandler.java:228)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
    at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
    at com.sun.glass.ui.View.notifyKey(View.java:966)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

Support other kinds of commands in analyze

Currently Brainalyze only supports pure BrainFCommand, because of excessive use of command.ordinal()

Make it support other kinds of commands as well, either by using a Map with toString() keys or by using the actual command itself as key.

Code Analysis and optimization

First of all, remember that the only thing that can change a Brainfuck program behavior is user-input, with the , Brainfuck command.

  • Scan for how many times loops are executed. Find out if some loops are only executed specific number of times, possibly expand them.

  • Avoid taking unnecessary turns, for example:

    right 2 minus 1 left 1 inc 1 right 1
    

    which equals to >>-<+> can become simply >+>-

  • Track which memory positions are used or not

Optimize some things for speed (number of instructions being performed when running), optimize some things for code compactness.

Compare BF code to make sure it produces the same

For refactoring purposes, test one BF code by making sure it produces the same output as another BF code

For example: $ testWith 'otherfile' which will look for otherfile.bf, run it, and will compare the output of the current code with that file

More DSL support

  • changeAt(-2, 1) ---> <<->>
  • searchLeft(255) and corresponding searchRight ---> +[-<+]-
  • show 'text': Print a string without storing any text
  • text 'text': Save text to the tape
  • showNumber: Prints the number at the current position as decimal
  • random: Generates a pseudo-random number, based on some random seed
  • readLine: Save text from input to the tape

Some of these should perhaps be implemented as algorithm.algo files, with the format in https://esolangs.org/wiki/Brainfuck_algorithms

IDE Match code to memory

Use highlighting in the IDE, related to #14, so that code is matched to which memory cells it is doing work on, so that you when coding can move around in your code, at "compile time", and see where the memory marker is when that piece of code is running.

Step backwards

If at all possible in BF, it would be useful to "step backwards" while debugging so that you can easier find where things go wrong when they go wrong

Procedural Brainfuck

From http://4mhz.de/bfdev.html#pbrain

pbrain means "procedural brainfuck" and enables you to define and call procedures in your BF programs. For this purpose, pbrain adds three new commands to the BF language: "(", ")", and ":".

"(" starts definition of a procedure. This newly created procedure will be referenced with the value that's in the current memory cell.
")" ends the definition.
":" calls that procedure that is referenced by the current memory cell.
BFdev does not tolerate calling of undefined procedures. In this case, it will report an error. BFdev offers a stack of 65536 entries, that means you can nest procedures until a depth of 65536. There is no stack overflow checking. This doesn't mean BFdev crashes if the stack grows too big, but instead, your program crashes and you probably wouldn't know why. The IDE itself doesn't crash when the stack overflows (I cared for this).

See also http://www.parkscomputing.com/2014/04/pbrain/

Example programs, as found on the link above:

Unknown effect

+([-])
+(-:< <[>>+< <-]>[>+< -]>)
+([-]>++++++++++[< ++++>-]< ++++++++>[-]++:.)
>+++>+++++>++:
>+++:

This pbrain program initializes a memory location to 65, the ASCII value of the letter โ€˜Aโ€™. It then calls a function for subsequent memory locations to copy the previous location and add one to it. Once a few cells are initialized, it prints all the cells to standard output.

+([-]< [-]<[>+>+< <-]>>[< <+>>-])
+([-]>[-]+:< +)
>>+++++++++++++[< +++++>-]
 ++:
>++:
>++:
>++:
< <<<.>.>.>.>.

Note that this issue conflicts with #11 because of the use of ( and )

New, Open and Save

  • Menu items for New, Open, Save
  • Drag and drop into application to Open a file

Detecting patterns in while-loop analysis

There can be a lot of patterns in the while loop analysis. Try to detect these patterns and write in a more compact way

Compact ways can be:

1013 [(49..58) x 4, 49, 50, 51, 52, 53, 54]
1191 [(1 * 9, 0) x 26, 1 * 6]

Some examples: (from the two existing Brainfuck questions on Code Review)

1013 [49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 49, 50, 51, 52, 53, 54]
1191 [1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 6]
1694 [48 * 9, 49 * 10, 50 * 10, 51 * 10, 52 * 10, 53 * 10, 54 * 10, 55 * 10, 56 * 10, 57 * 10, 58, 48 * 9, 49 * 10, 50 * 10, 51 * 10, 52 * 10, 53 * 10, 54 * 10, 55 * 10, 56 * 10, 57 * 10, 58, 48 * 9, 49 * 10, 50 * 10, 51 * 10, 52 * 10, 53 * 7]
1872 [1 * 99, 0, 1 * 99, 0, 1 * 56]
2378 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]



2475 [1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0, 1 * 2, 0, 1 * 5, 0 * 2, 1 * 4, 0, 1 * 4, 0 * 2, 1 * 5, 0, 1 * 2, 0]
2930 [0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1, 0 * 2, 1, 0 * 5, 1 * 2, 0 * 4, 1, 0 * 4, 1 * 2, 0 * 5, 1, 0 * 2, 1]

3045 [14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22, 14 * 2, 22, 14, 22, 14 * 2, 22]
3145 [0 * 7, 1, 0 * 7, 1, 0 * 7, 1, 0 * 7, 1, 0 * 7, 1, 0 * 7, 1, 0 * 5]
3257 [9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17, 9 * 2, 17, 9, 17, 9 * 2, 17]
3354 [3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5, 3 * 2, 5, 3, 5, 3 * 2, 5]
3863 [1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2, 1, 0, 1 * 2, 0, 1 * 2, 0, 1, 0 * 2, 1 * 2, 0 * 2]
4036 [1, 2, 4, 7, 8, 11, 13, 14, 16, 17, 19, 22, 23, 26, 28, 29, 31, 32, 34, 37, 38, 41, 43, 44, 46, 47, 49, 52, 53, 56, 58, 59, 61, 62, 64, 67, 68, 71, 73, 74, 76, 77, 79, 82, 83, 86, 88, 89, 91, 92, 94, 97, 98]
4042 [1 * 31, 0, 1 * 10, 0, 1 * 12, 0, 1 * 13, 0, 1 * 15, 0, 1 * 16, 0, 1 * 18, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 12, 0, 1 * 9, 0, 1 * 15, 0, 1 * 9, 0, 1 * 17, 0, 1 * 9, 0, 1 * 18, 0, 1 * 9, 0, 1 * 9, 0, 1 * 10, 0, 1 * 9, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 9, 0, 1 * 13, 0, 1 * 9, 0, 1 * 9, 0, 1 * 16, 0, 1 * 9, 0, 1 * 9, 0, 1 * 17, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 10, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 12, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 13, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 15, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 16, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 18, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 12, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 15, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 17, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 18, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 10, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 13, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 16, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 17, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 10, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 12, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 13, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 15, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 16, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 18, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 12, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 15, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 17, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 18, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 10, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 11, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 13, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 16, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 9, 0, 1 * 8]
4071 [9, 8, 6, 3, 2, 9, 7, 6, 4, 3, 1, 8, 7, 4, 2, 1, 9, 8, 6, 3, 2, 9, 7, 6, 4, 3, 1, 8, 7, 4, 2, 1, 9, 8, 6, 3, 2, 9, 7, 6, 4, 3, 1, 8, 7, 4, 2, 1, 9, 8, 6, 3, 2]
4088 [0 * 5, 1 * 6, 2 * 5, 3 * 5, 4 * 6, 5 * 5, 6 * 5, 7 * 6, 8 * 5, 9 * 5]
4121 [10 * 5, 9 * 6, 8 * 5, 7 * 5, 6 * 6, 5 * 5, 4 * 5, 3 * 6, 2 * 5, 1 * 5]
4191 [49 * 6, 50 * 5, 51 * 5, 52 * 6, 53 * 5, 54 * 5, 55 * 6, 56 * 5, 57 * 5]
4218 [49, 50, 52, 55, 56, 49, 51, 52, 54, 55, 57, 50, 51, 54, 56, 57, 49, 50, 52, 55, 56, 49, 51, 52, 54, 55, 57, 50, 51, 54, 56, 57, 49, 50, 52, 55, 56, 49, 51, 52, 54, 55, 57, 50, 51, 54, 56, 57, 49, 50, 52, 55, 56]
4223 [1, 2, 4, 7, 8, 11, 13, 14, 16, 17, 19, 22, 23, 26, 28, 29, 31, 32, 34, 37, 38, 41, 43, 44, 46, 47, 49, 52, 53, 56, 58, 59, 61, 62, 64, 67, 68, 71, 73, 74, 76, 77, 79, 82, 83, 86, 88, 89, 91, 92, 94, 97, 98]

Show analysis in GUI

Instead of just printing analysis result to System.out, make it available in a grid-like table component.

Brainfuck to DSL conversion

By reading the Brainfuck code and detecting patterns, it might be possible to convert Brainfuck code back to DSL, or to something else (Java / Groovy).

Make it easier to test code for different inputs

Possibly something like this:

$ input 'ABCDEF' produces 'FEDCBA'
$ input 'qwerty' produces 'QWERTY'
$ input 'abc' validator 'groovyScript'

When running this code in some mode, the code is then tested with all those different inputs to make sure it produces the expected results.

SpecialCommand.toString returns empty string if appending code

Current code:

    @Override
    public String toString() {
        'GroovyCommand'
    }

Desired code:

    @Override
    public String toString() {
        'GroovyCommand: ' + this.code
    }

However, when changing this it somehow returns an empty string.

But doing this prints the code correctly:

    @Override
    public String toString() {
        println this.code
        'GroovyCommand'
    }

Run next x commands

Have a possibility to run an arbitrary amount of commands, for example next 143 commands.

Refactor Analysis to make it a composition

To improve code cleanness, and follow Single Responsibility Principle better, refactor Brainalyze so that it becomes a composition of analysis.

  • GroovyCommandAnalysis
  • WhileLoopAnalysis
  • CommandCountAnalysis
  • ReadWriteAnalysis (+ Memory Used)
  • MemoryValuesAnalysis
  • IOAnalysis
  • MemoryIndexAnalysis

and more...

Assertions

In the DSL, include support for the following:

  • assertPosition: asserts that the memory pointer is at a specific place. For example assertPosition 5
  • assertValue: asserts the value at the current memory index. For example assertValue 42
  • assertValues: asserts a range of values, around the current memory index. For example assertValues(-2, 5, [0, 1, 2, 3, 4]) (start index, memory length, values)

Full support for tabs

There is already some support for tabs, continue this to add full support.

  • Each tab should have its own code editor
  • Each tab should have its own memory tape view
  • Each tab should have its own output control
  • Each tab should have its own input controls
  • Each tab should be able to run independently of other tabs

Named/Tagged memory cells

Name and tag memory cells, as part of IDE and/or analysis.

Allow names to be specified in the DSL (#10), this can be done like this:

  • name 'fizz' from 0 to 7 (will name the current cell and offsets 1, 2, 3... 6, 7 as 'fizz')
  • name 'fizz' each 2 until 8 (will name the current cell and offsets 2, 4, 6, 8 as fizz)

These tags can then later cause other memory cells to notice that they have been affected in some way by cells with these tags.

Use both custom-tagged names, specified by the user, and automatic tagged fields. Tagging strategies can include:

  • Custom-tagged memory cells
  • Used as condition (in x different loops - i.e. count the different indexes in the source code where a [ or ] character considered this field)
  • User input (in x different places)
  • Printed field (in x different places)
  • ? Countdown (increased only once, then used as a countdown)
  • ? Temporary (used as a temporary multiplication helper for loops or other temporary stuff)
  • Add the functionality to the IDE to select one-or-more code-index-tags and one-or-more "type" tags (loop-continue, loop-begin, loop-end...) to highlight memory cells with those tags. Possibly use different colors depending on the type-tag.
  • Use line numbers + column numbers for auto-tags

Logging with log4j

Consider using logging with log4j, instead of System.out.println everywhere. Only use System.out.print for actual output produced from Brainfuck program.

The amount of logging needs to be overlooked as well.

Autosave

Autosave files being edited so that, if (or rather, when) program crashes, your work is not lost.

Coverage test

Add some plugin to the gradle build that requires a certain amount of code coverage in tests for the project to build.

Hints, warnings, and errors

Add a way for analysis to show hints, warnings and errors to the user

Errors include:

  • Infinite loops (halting problem is unsolvable, but try to detect some basic things)
  • Unbalanced brackets
  • Code does not produce expected output

Warnings include:

  • Each of the possible issues in Program Validation according to standards #12
  • Detect if any Brainfuck characters are used within comments, such as writing This program is awesome. which includes the BF command .
  • Input unused. When you feed more input to the BF program than the program reads.

Hints include:

  • +>+++<++>--<->+> performs change [2 2] and can be written as ++>++>
  • While loop always performed X times, consider expanding it (only show this if it would save characters + performance)
  • Memory cell(s) unused
  • Dead code

Many of these things are already available through some analysis, they just need to be converted to some kind of hint/warning/error object.

Related:

  • Code Analysis and optimization #4
  • Prevent hanging on infinite loops #8
  • Make it easier to test code for different inputs #26
  • Program Validation according to standards #12
  • Refactor Analysis to make it a composition #22 (also contains links to how Rubberduck handles code inspections)

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.