Jump to page: 1 2
Thread overview
Just for fun brainfuck'a'like textprocessor
May 22, 2007
Gregor Kopp
May 23, 2007
janderson
May 23, 2007
Gregor Kopp
May 23, 2007
Gregor Kopp
RFC (was: Re: Just for fun brainfuck'a'like textprocessor)
May 23, 2007
davidb
May 24, 2007
Gregor Kopp
Re: RFC
May 24, 2007
davidb
May 24, 2007
Gregor Kopp
Re: RFC
May 24, 2007
janderson
May 24, 2007
Henning Hasemann
May 24, 2007
janderson
May 25, 2007
janderson
May 24, 2007
janderson
Jun 02, 2007
Daniel Cristofani
Jun 11, 2007
Gregor Kopp
May 22, 2007
Hi, I've just written this small peace of thing.
Have fun with it.

I think everyone should read code from others, so I for myself want to provide you my code. If you have improvements: post it ;)




May 23, 2007
Gregor Kopp wrote:
> Hi, I've just written this small peace of thing.
> Have fun with it.
> 
> I think everyone should read code from others, so I for myself want to provide you my code. If you have improvements: post it ;)
> 
> 

Nice work!

BTW: did you see Gregor Richards compile time version?

Gregor Richards
------------------------------------------------------------
ctbf.d:
------------------------------------------------------------
module ctbf;

import std.cstream;
import std.stdio;

static char[] ctbf(char[] bf)
{
    char[] code = `
    byte[] mem;
    uint memptr = 0;
    mem.length = 1;
    void expand() {
        if (mem.length <= memptr) {
            mem.length = memptr + 1;
        }
    }
    `;

    foreach (c; bf) {
        switch (c) {
            case '>':
                code ~= "memptr++; expand();\n";
                break;

            case '<':
                code ~= "memptr--;\n";
                break;

            case '+':
                code ~= "mem[memptr]++;\n";
                break;

            case '-':
                code ~= "mem[memptr]--;\n";
                break;

            case '[':
                code ~= "while (mem[memptr]) {\n";
                break;

            case ']':
                code ~= "}\n";
                break;

            case '.':
                code ~= "dout.write(cast(char) mem[memptr]);\n";
                break;

            case ',':
                code ~= "din.read(mem[memptr]);\n";
                break;

            default:
        }
    }

    return code;
}

int main()
{
    mixin(ctbf(import("helloworld.bf")));
    return 0;
}
May 23, 2007
janderson wrote:
> Nice work!

thank you!


just for safety: change the part handling the case '[': to:

        case '[':
            klammernstack.push(kommandoindex);
            break;

got braindamage yesterday...

I tried to compile Gregor Richtards version with dmd 1.014 on windows xp, but it didn't work:

D:\>dmd ctbf.d
ctbf.d(62): Error: need -Jpath switch to import text file helloworld.bf
ctbf.d(62): Error: cannot evaluate ctbf("") at compile time
ctbf.d(62): Error: argument to mixin must be a string, not (ctbf(""))

helloworld.bf did exist in the same directory with the following content:

,[.,]

This brainfuck program should print what you type in, till you kill the brainfuck interpreter.

I fiddled around with din, cget(stdin), getchar, fflush(stdin) and so on... but I didn't get managed, that a console program just read a keystroke and continues. It always wants a linebreak.
I readed in several c-book, they say:
fflush(stdin) isn't covered completely in ansi standard, so it's behaviour may change from system to system.

Hm. difficulty to implement the , then...
May 23, 2007
Gregor Kopp wrote:
> helloworld.bf did exist in the same directory with the following content:
> 
> ,[.,]

Sorry, change the testprogram to the following:

,[..,]

it should print the entered key twice, till you kill the interpreter.
May 23, 2007
> Gregor Kopp wrote:
...

So, what about a kind of "official" RFC - please comment my code so I can improve my style? (just put "RFC ..." in the topic)

This way, you could not only learn through your own code being commented upon, but also through watching other people's style & improvements!

That said, I'll make a first try @Gregor Kopp's code:
1) You'd definitely want a default case in your switch statement
    which btw. fits nicely with "other characters (which are ignored)"
    (http://en.wikipedia.org/wiki/Brainfuck)
    (currently it exits with an "Error: Switch Default ..."
     if it encounters any other symbol than the ones checked for)
2) Just personal preference, but I'd try not to put too much
    functionality in main(), makes code more clear and above all:
    easier reusable
    (okay, its a bf interpreter, no big reuse here ;-).
3) []-handling: not quite the specs implemented, but nicely done with
    a stack :-)
4) line 61:
    I don't quite see why you use char[] initialized with 1 for cells,
    but that's probably just me.
5) line 62:
    if "for (;;) ... " has only one statement(?), you don't need
    enclosing {} (just cosmetics, but hey - 2 chars less typing *g*)
    (or did you use it here as a means to show your intention
     more clearly?)
6) descriptive names in addition to clear indentation
    => very easily readable code, nice!

Nice work Gregor Kopp!

Considering the Stack class:
I'm not quite sure about the use of "this.length" in the various
contexts, could someone please explain it to me?


NB: (because I saw it in Gergor Kopps' code)
     Just a little gem from the specs:
    "Integers can have embedded '_' characters, which are ignored.
     The embedded '_' are useful for formatting long literals,
     such as using them as a thousands separator"
     (http://www.digitalmars.com/d/lex.html#integerliteral)
     (e.g. 300_000, 1_925_200, ...)


david

and attached, also a little bf interpreter


May 24, 2007
Gregor Kopp wrote:
> janderson wrote:
>> Nice work!
> 
> thank you!
> 
> 
> just for safety: change the part handling the case '[': to:
> 
>         case '[':
>             klammernstack.push(kommandoindex);
>             break;
> 
> got braindamage yesterday...
> 
> I tried to compile Gregor Richtards version with dmd 1.014 on windows xp, but it didn't work:
> 
> D:\>dmd ctbf.d
> ctbf.d(62): Error: need -Jpath switch to import text file helloworld.bf

From spec http://www.digitalmars.com/d/dcompiler.html
"
-Jpath
    where to look for files for ImportExpressions. This switch is required in order to use ImportExpressions. path is a ; separated list of paths. Multiple -J's can be used, and the paths are searched in the same order.
"

You need to say where the helloworld.bf lives since it writes the brainfucked program at compile time. (ie the outputted binary is the compiled helloworld.bf).

> ctbf.d(62): Error: cannot evaluate ctbf("") at compile time
> ctbf.d(62): Error: argument to mixin must be a string, not (ctbf(""))

Probably related to the first error.

> 
> helloworld.bf did exist in the same directory with the following content:
> 
> ,[.,]
> 

I hope that helped.
May 24, 2007
Hi davidb, thank you for your improvements, and hitting me to the ',' issue ;)

> So, what about a kind of "official" RFC - please comment my code so I can improve my style? (just put "RFC ..." in the topic)

Okay.

> This way, you could not only learn through your own code being commented upon, but also through watching other people's style & improvements!

That was my intention for posting it here ;)

> That said, I'll make a first try @Gregor Kopp's code:
> 1) You'd definitely want a default case in your switch statement
>     which btw. fits nicely with "other characters (which are ignored)"
>     (http://en.wikipedia.org/wiki/Brainfuck)
>     (currently it exits with an "Error: Switch Default ..."
>      if it encounters any other symbol than the ones checked for)

Your right, I started this small program to learn about the d, so I've learned several things, but as I see, not enough ;)

> 2) Just personal preference, but I'd try not to put too much
>     functionality in main(), makes code more clear and above all:
>     easier reusable
>     (okay, its a bf interpreter, no big reuse here ;-).

Normally I split up my code more modular, but here, its only about 100 loc.

> 3) []-handling: not quite the specs implemented, but nicely done with
>     a stack :-)

I just wanted to demonstrate the stack, I know it could also be done with pointers and other technics.

> 4) line 61:
>     I don't quite see why you use char[] initialized with 1 for cells,
>     but that's probably just me.

Here i have to think about it again how to improve this.

> 5) line 62:
>     if "for (;;) ... " has only one statement(?), you don't need
>     enclosing {} (just cosmetics, but hey - 2 chars less typing *g*)
>     (or did you use it here as a means to show your intention
>      more clearly?)

Normally I do it like you described it. I also put private, public and so on in front of every type and variable, just to say: I mean it that way. I'm curious.

> 6) descriptive names in addition to clear indentation
>     => very easily readable code, nice!

I want to be capable reading my code years after. My Ruby programs are
looking also that way and are "written", not obfuscated. My intetion
behind is also, that others can read my code without hurting there eyes.

> Considering the Stack class:
> I'm not quite sure about the use of "this.length" in the various
> contexts, could someone please explain it to me?

I used the length of my stack outside other programs. I wanted to know
the elements nested inside my stack in other programs. My future plan is
to write a small ide for the bf interpreter. So I have to rewrite the whole
thing.

> and attached, also a little bf interpreter

Thank you for that, I will study it.
May 24, 2007
davidb wrote:
[snip]
> 5) line 62:
>    if "for (;;) ... " has only one statement(?), you don't need
>    enclosing {} (just cosmetics, but hey - 2 chars less typing *g*)
>    (or did you use it here as a means to show your intention
>     more clearly?)
[snip]

I know this is mainly a style thing however I've seen many bugs caused by people who leave the scope brakes of the loop.
May 24, 2007
On Thu, 24 May 2007 02:45:05 -0700
janderson <askme@me.com> wrote:

> davidb wrote:
> [snip]
> > 5) line 62:
> >    if "for (;;) ... " has only one statement(?), you don't need
> >    enclosing {} (just cosmetics, but hey - 2 chars less typing *g*)
> >    (or did you use it here as a means to show your intention
> >     more clearly?)
> [snip]
> 
> I know this is mainly a style thing however I've seen many bugs caused by people who leave the scope brakes of the loop.

Ack, I also have only *very* few cases where I do not put brackets (also because I come from python so if I'm not concentrated I fear it might happen to me to rely on indentation)

Henning

-- 
GPG Public Key: http://keyserver.veridis.com:11371/search?q=0x41911851 Fingerprint: 344F 4072 F038 BB9E B35D  E6AB DDD6 D36D 4191 1851
May 24, 2007
Gregor Kopp wrote:
>> Considering the Stack class:
>> I'm not quite sure about the use of "this.length" in the various
>> contexts, could someone please explain it to me?
> 
> I used the length of my stack outside other programs. I wanted to know
> the elements nested inside my stack in other programs. My future plan is
> to write a small ide for the bf interpreter. So I have to rewrite the whole
> thing.

I meant this.size of course.
Note to self: first read, then post.
I mistook this.size for a kind of special (template) class property,
where it was just a function without the ()...

I don't know if the compiler optimizes it automatically,
but if you use e.g.
    data[this.size - 1] = element;
it will call this.size() to determine data.length,
whereas
    data[$-1] = element;
would just look it up from the array (no function call overhead).

david
« First   ‹ Prev
1 2