diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..63d8a8d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +*/bin/* \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f860955 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 2bbb + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dcde136 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# ofxBrainfuck + +## How to use + +TODO + +## API + +TODO + +## Update history + +### ver 0.01 release + +## License + +MIT License. + +## Author + +* ISHII 2bit [bufferRenaiss co., ltd.] +* ishii[at]buffer-renaiss.com + +## At the last + +Please create new issue, if there is a problem. +And please throw pull request, if you have a cool idea!! \ No newline at end of file diff --git a/example/main.cpp b/example/main.cpp new file mode 100644 index 0000000..5a870b4 --- /dev/null +++ b/example/main.cpp @@ -0,0 +1,13 @@ +#include "ofMain.h" +#include "ofApp.h" + +//======================================================================== +int main( ){ + ofSetupOpenGL(400, 400, OF_WINDOW); // <-------- setup the GL context + + // this kicks off the running of my app + // can be OF_WINDOW or OF_FULLSCREEN + // pass in width and height too: + ofRunApp(new ofApp()); + +} diff --git a/example/ofApp.cpp b/example/ofApp.cpp new file mode 100644 index 0000000..19ce165 --- /dev/null +++ b/example/ofApp.cpp @@ -0,0 +1,83 @@ +#include "ofApp.h" + +//-------------------------------------------------------------- +void ofApp::setup(){ + string source = ofxGetBrainfuckSource("Hello Brainfuck, on openFrameworks!!"); + ofLogNotice() << source; + fuck.setup(source); + bPause = true; +} + +//-------------------------------------------------------------- +void ofApp::update(){ + for(int i = 0; i < 27; i++) if(!bPause) fuck.update(); +} + +//-------------------------------------------------------------- +void ofApp::draw(){ + ofBackground(0, 0, 0); + + ofSetColor(255, 255, 255); + ofDrawBitmapString("space: start/pause | r: reset", ofPoint(10, 20)); + + const vector memoryState = fuck.getCurrentMemoryState(); + for(int i = 0; i < memoryState.size(); i++) { + ofSetColor((fuck.getCurrentProcessiState() == OFX_BRAINFUCK_ERROR) ? 255 : 0, (fuck.getCurrentProcessiState() == OFX_BRAINFUCK_PROCESS_NOW) && (i == fuck.getCurrentPointer()) ? 255 : 0, memoryState[i]); + ofRect(i % 10 * 40, i / 10 * 40 + 40, 40, 40); + + ofSetColor(255, 255, 255); + ofDrawBitmapString(ofToString(memoryState[i]), ofPoint(i % 10 * 40 + 10, i / 10 * 40 + 60)); + } + + ofSetColor(255, 255, 255); + ofDrawBitmapString(fuck.getResult(), ofPoint(10, 380)); +} + +//-------------------------------------------------------------- +void ofApp::keyPressed(int key){ + if(key == ' ') { + bPause = !bPause; + } else if(key == 'r') { + fuck.reset(); + } +} + +//-------------------------------------------------------------- +void ofApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseMoved(int x, int y ){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mousePressed(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void ofApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void ofApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void ofApp::dragEvent(ofDragInfo dragInfo){ + +} diff --git a/example/ofApp.h b/example/ofApp.h new file mode 100644 index 0000000..603596a --- /dev/null +++ b/example/ofApp.h @@ -0,0 +1,25 @@ +#pragma once + +#include "ofMain.h" +#include "ofxBrainfuck.h" + +class ofApp : public ofBaseApp{ +public: + void setup(); + void update(); + void draw(); + + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y ); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + +private: + ofxBrainfuck fuck; + bool bPause; +}; diff --git a/src/ofxBrainfuck.cpp b/src/ofxBrainfuck.cpp new file mode 100644 index 0000000..c6af3e0 --- /dev/null +++ b/src/ofxBrainfuck.cpp @@ -0,0 +1,164 @@ +// +// ofxBrainfuck.cpp +// +// Created by ISHII 2bit +// + +#include "ofxBrainfuck.h" + +char charAtPosition(string str, int position) { + if(position < 0 || str.length() <= position) { + ofLogError() << "Index out of bounds"; + return '\0'; + } else { + return str[position]; + } +} + +void repeat(stringstream &stream, string str, int n) { + string res = ""; + for(int i = 0; i < n; i++) { + stream << str; + } +} + +string createSourcePieces(stringstream &stream, int num, string op) { + float sqrtNum = sqrtf(num); + int m = num, n = num, r = num; + for(int i = 0; i < sqrtNum; i++) { + for(int j = 0; j < sqrtNum; j++) { + if((i + j + num - i * j) < m + n + r) { + m = i; + n = j; + r = num - i * j; + } + } + } + + repeat(stream, "+", m); + stream << "[>"; + repeat(stream, op, n); + stream << "<-]>"; + repeat(stream, op, r); + stream << "."; + return stream.str(); +} + +string ofxGetBrainfuckSource(string str) { + stringstream stream; + repeat(stream, "+", 8); + stream << "[>"; + repeat(stream, "+", 8); + stream << "<-]>+[>"; + repeat(stream, ">+>", str.length()); + repeat(stream, "<<", str.length()); + stream << "<-]"; + for(int i = 0; i < str.length(); i++) { + int c = charAtPosition(str, i) - 65; + char sign = c < 0 ? -1 : 1; + c *= sign; + stream << ">"; + string sourcePiece = createSourcePieces(stream, c, sign < 0 ? "-" : "+"); + } + + return stream.str(); +} + +void ofxBrainfuck::setup(string source) { + this->source = source; + this->reset(); +} + +void ofxBrainfuck::reset() { + memory.clear(); + memory.push_back(0); + pointer = 0; + cursor = 0; + resultStream.str(""); + resultStream.clear(stringstream::goodbit); + state = OFX_BRAINFUCK_PROCESS_NOW; +} + +ofxBrainfuckState ofxBrainfuck::update() { + if(state != OFX_BRAINFUCK_PROCESS_NOW) return state; + + char x = charAtPosition(source, cursor); + switch(x) { + case '>': + pointer++; + if(memory.size() <= pointer) { + memory.push_back(0); + } + break; + case '<': + pointer--; + if(pointer < 0) { + ofLogError("Negative Memory Index"); + return (state = OFX_BRAINFUCK_ERROR); + } + break; + case '+': + memory[pointer]++; + break; + case '-': + memory[pointer]--; + break; + case '.': + putchar(memory[pointer]); + resultStream << (char)memory[pointer]; + break; + case ',': + memory[pointer] = getchar(); + break; + case '[': + if(0 == memory[pointer]) { + while (charAtPosition(source, cursor) != ']') { + cursor++; + } + } else { + loopPosition.push_back(cursor); + } + break; + case ']': + if(loopPosition.size() == 0) { + ofLogError("Loop Bracket is Unbalance"); + return (state = OFX_BRAINFUCK_ERROR); + } + cursor = loopPosition[loopPosition.size() - 1] - 1; + loopPosition.pop_back(); + break; + } + cursor++; + + return (state = cursor < source.length() ? OFX_BRAINFUCK_PROCESS_NOW : OFX_BRAINFUCK_SUCCESS); +} + +ofxBrainfuckState ofxBrainfuck::interpret() { + while(true) { + ofxBrainfuckState state = update(); + if(state != OFX_BRAINFUCK_PROCESS_NOW) { + return state; + } + } + return OFX_BRAINFUCK_UNKNOWN; +} + +const vector &ofxBrainfuck::getCurrentMemoryState() const { + return memory; +} + +ofxBrainfuckState ofxBrainfuck::getCurrentProcessiState() const { + return state; +} + +int ofxBrainfuck::getCurrentPointer() const { + return pointer; +} + +int ofxBrainfuck::getCurrentCursor() const { + return cursor; +} + +const string ofxBrainfuck::getResult() const { + return resultStream.str(); +} \ No newline at end of file diff --git a/src/ofxBrainfuck.h b/src/ofxBrainfuck.h new file mode 100644 index 0000000..c96a799 --- /dev/null +++ b/src/ofxBrainfuck.h @@ -0,0 +1,47 @@ +// +// ofxBrainfuck.h +// +// Created by ISHII 2bit +// + +#ifndef __ofxBrainfuck__ +#define __ofxBrainfuck__ + +#include "ofMain.h" + +string ofxGetBrainfuckSource(string str); + +typedef enum { + OFX_BRAINFUCK_ERROR, + OFX_BRAINFUCK_PROCESS_NOW, + OFX_BRAINFUCK_SUCCESS, + OFX_BRAINFUCK_UNKNOWN +} ofxBrainfuckState; + +class ofxBrainfuck { +public: + void setup(string source); + void reset(); + ofxBrainfuckState update(); + ofxBrainfuckState interpret(); + + const vector &getCurrentMemoryState() const; + ofxBrainfuckState getCurrentProcessiState() const; + int getCurrentPointer() const; + int getCurrentCursor() const; + + const string getResult() const; + +private: + string source; + + ofxBrainfuckState state; + vector memory; + int pointer; + int cursor; + vector loopPosition; + + stringstream resultStream; +}; + +#endif /* defined(__ofxBrainfuck__) */