Skip to content

Commit

Permalink
create bft package and dir, use char instead of dchar where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
Herringway committed Dec 16, 2017
1 parent e68ef7d commit 27b4ea1
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
2 changes: 1 addition & 1 deletion source/app.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import bf;
import bft;
void main() {
auto program = BFProgram!(import("mandel.b"))();
program.execute();
Expand Down
43 changes: 26 additions & 17 deletions source/bf.d → source/bft/bf.d
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
import std.range : isInputRange, isOutputRange;
///A brainfuck implementation that uses transpiling to produce native machine code.
module bft.bf;

import std.range : ElementType, isInputRange, isOutputRange;
import std.traits : isSomeString;
struct StdInput {
import std.stdio : stdin;
char lastRead;
bool empty() { return stdin.isOpen; }
char front() { return lastRead; }
void popFront() { if (stdin.rawRead([lastRead]).length == 0) stdin.close(); }
}
///A brainfuck program
struct BFProgram(string program, size_t memSize = 8192) {
///Just a big ol' block of memory
dchar[memSize] memory = void;
char[memSize] memory = void;
///Program data pointer
size_t ptr = 0;

///Compile and execute program
void execute() {
import std.stdio : stdin, stdout;
struct StdInput {
char lastRead;
bool empty() { return stdin.isOpen; }
char front() { return lastRead; }
void popFront() { if (stdin.rawRead([lastRead]).length == 0) stdin.close(); }
}
import std.stdio : stdout;
auto inp = StdInput();
auto outp = stdout.lockingTextWriter;
execute(inp, outp);
}
void execute(Input, Output)(Input stdin, Output stdout) if (isInputRange!Input && isOutputRange!(Output, char)) {
import std.range : put, front, popFront, empty;
///ditto
void execute(Input, Output)(Input stdin, Output stdout) if (isInputRange!Input && !isSomeString!Input && is(ElementType!Input : char) && isOutputRange!(Output, char)) {
import std.range : put;
import std.algorithm : copy;
memory[] = '\0';
mixin(transpile(program));
}
///ditto
void execute(Input, Output)(Input stdin, Output stdout) if (isSomeString!Input && isOutputRange!(Output, char)) {
import std.utf : byCodeUnit;
execute(stdin.byCodeUnit, stdout);
}
}
///Transpile bf -> D
string transpile(string program) pure @safe {
Expand Down Expand Up @@ -64,20 +75,19 @@ string transpile(string program) pure @safe {
}
return prog.join("\n");
}
///
unittest {
import std.array : appender;
{
auto program = BFProgram!(import("helloworld.b"), 7)();
auto outbuf = appender!(char[])();
char[] inbuf;
program.execute(inbuf, outbuf);
program.execute("", outbuf);
assert(outbuf.data == "Hello World!\n");
}
{
auto program = BFProgram!(import("bench.b"), 8)();
auto outbuf = appender!(char[])();
char[] inbuf;
program.execute(inbuf, outbuf);
program.execute("", outbuf);
assert(outbuf.data == "ZYXWVUTSRQPONMLKJIHGFEDCBA\n");
}
{
Expand All @@ -94,8 +104,7 @@ unittest {
import std.utf : toUTF8;
auto program = BFProgram!(import("392quine.b"), 1024)();
auto outbuf = appender!(char[])();
char[] inbuf;
program.execute(inbuf, outbuf);
program.execute("", outbuf);
assert(outbuf.data == import("392quine.b").splitter("\x1A").front.filter!(x => !x.isWhite).array.toUTF8~"\x1A");
}
}
3 changes: 3 additions & 0 deletions source/bft/package.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module bft;

public import bft.bf;

0 comments on commit 27b4ea1

Please sign in to comment.