I wasn't sure that this was the right forum, but the Lua one seems to be just for Gmod Lua, and besides, I thought that you guys would appreciate it more ;)
I've always had a bit of a thing for brainfuck: the way that even the simplest program ccould become a festering monstrosity of code brought a warmth to your heart, and the sight of the tiniest snippet brings back warm memories of evenings spent squinting at my monitor trying to find the bug hidden in the bubbling soup of code spilled out across it. The one thing I seemed to lack was some way to take it with me, to keep my self entertained on long journeys; but, after a long time spent looking, I was still unable to find a way to satiate my portable brainfucking cravings. Unable to bear it any longer, I took the most drastic action imaginable: I set out to rectify the problem myself.
And so, without further ado, here is the script in all of its (dubious) glory:
[code]
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Initialising memory...")
stopDrawing()
data = {}
i = 1
while i <= 30000 do
data[i] = 0
i = i + 1
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Loading...")
stopDrawing()
file = io.open("rcat.bf", "r")
prog = file:read()
file:close()
file = io.open("in.cfg", "r")
inpt = file:read()
file:close()
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Beginning execution...")
stopDrawing()
i = 1
p = 1
ip = 1
out = ""
while i <= string.len(prog) do
v = string.byte(prog, i)
if v==43 then
data[p] = data[p] + 1
if data[p] > 255 then data[p] = 0 end
elseif v == 45 then
data[p] = data[p] - 1
if data[p] < 0 then data[p] = 255 end
elseif v == 60 then
p = p - 1
if p < 1 then p = 30000 end
elseif v == 62 then
p = p + 1
if p > 30000 then p = 1 end
elseif v == 46 then
out = out..string.char(data[p])
elseif v == 44 then
if ip <= string.len(inpt) then
data[p] = string.byte(inpt, ip)
ip = ip + 1
end
elseif v == 91 then
if data[p] == 0 then
vb = 0
while vb ~= 93 do
i = i + 1
vb = string.byte(prog, i)
end
end
elseif v == 93 then
if data[p] ~= 0 then
vb = 0
while vb ~= 91 do
i = i - 1
vb = string.byte(prog, i)
end
end
end
i = i + 1
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Execution complete!")
screen.print(SCREEN_UP, 2, 12,"output: "..out)
stopDrawing()
file = io.open("out.txt", "w")
file:write(out)
file:close()
[/code]
It's not without its faults: as of yet, it does not support nested loops, and filenames are hardcoded into the script; the focus was more on getting it up and running.
In spite of its faults, and the slightly wordy style, it does work with any scripts that don't contain nested loops. For instance:
[quote="helloworld.bf"]++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
[/quote]
[quote=OUT.TXT]Hello World![/quote]
and rcat:
[quote=rcat.bf],[>,]<[.<][/quote]
[quote=IN.CFG]Check out mah sample text lols :D[/quote]
[quote=OUT.TXT]D: slol txet elpmas ham kcehC[/quote]
In case you guys were wondering why the input file is a cfg instead of a txt, it's because DSOrganise won't allow you to edit txts - I type out all of my scripts on my DS :biggrin:
FYI it's [/code] for the end code tag.
I'd love to see a video of it working on a DS.
Whoops, slight typo there.
As for a video, there isn't really anything to see: you run it, it loads the file, loads the input from a file, and writes the output to another file when it's done. It would make for pretty boring watching.
[QUOTE=r0b0tsquid;20555235]Whoops, slight typo there.
As for a video, there isn't really anything to see: you run it, it loads the file, loads the input from a file, and writes the output to another file when it's done. It would make for pretty boring watching.[/QUOTE]
Oh right, I thought it might display or something.
Would it be possible to make it display the output?
Heh, reminds me of my Befunge interpreter I made in Lua.
[media]http://www.youtube.com/watch?v=nYgwqgktxvE[/media]
[QUOTE=Jallen;20555261]Oh right, I thought it might display or something.
Would it be possible to make it display the output?[/QUOTE]
On my to-do list - I think I might fix up the file dialogue and nested loops first.
[QUOTE=r0b0tsquid;20555476]On my to-do list - I think I might fix up the file dialogue and nested loops first.[/QUOTE]
I remember when I made my interpreter back in the day my nested loops didn't work. I might rewrite it some time.
Yeah. I had a go at nested loops, but the whole thing just hung, so I pulled them out and popped them further down the list.
New version should be up in a few minutes - wrestling with a few bugs :frown:
[editline]07:34PM[/editline]
[code]filelist={
"cat.bf",
"helloworld.bf",
"hi.bf",
"rcat.bf",
"numwarp.bf"
}
cursorpos = 1
while true do
while not Keys.held.Select do
Controls.read()
if Keys.newPress.Up then cursorpos = cursorpos - 1 end
if Keys.newPress.Down then cursorpos = cursorpos + 1 end
if cursorpos < 1 then cursorpos = #filelist end
if cursorpos > #filelist then cursorpos = 1 end
startDrawing()
for i, v in ipairs(filelist) do
screen.print(SCREEN_UP, 6, i*10+2, v)
end
screen.print(SCREEN_UP, 2, cursorpos*10+2, ">")
stopDrawing()
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Initialising memory...")
stopDrawing()
data = {}
i = 1
while i <= 30000 do
data[i] = 0
i = i + 1
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Loading...")
stopDrawing()
file = io.open(filelist[cursorpos], "r")
prog = file:read()
file:close()
file = io.open("in.cfg", "r")
inpt = file:read()
file:close()
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Beginning execution...")
stopDrawing()
i = 1
p = 1
ip = 1
out = ""
while i <= string.len(prog) do
v = string.byte(prog, i)
if v==43 then
data[p] = data[p] + 1
if data[p] > 255 then data[p] = 0 end
elseif v == 45 then
data[p] = data[p] - 1
if data[p] < 0 then data[p] = 255 end
elseif v == 60 then
p = p - 1
if p < 1 then p = 30000 end
elseif v == 62 then
p = p + 1
if p > 30000 then p = 1 end
elseif v == 46 then
out = out..string.char(data[p])
elseif v == 44 then
if ip <= string.len(inpt) then
data[p] = string.byte(inpt, ip)
ip = ip + 1
end
elseif v == 91 then
if data[p] == 0 then
vb = 0
while vb ~= 93 do
i = i + 1
vb = string.byte(prog, i)
end
end
elseif v == 93 then
if data[p] ~= 0 then
vb = 0
while vb ~= 91 do
i = i - 1
vb = string.byte(prog, i)
end
end
end
i = i + 1
end
file = io.open("out.txt", "w")
file:write(out)
file:close()
while not Keys.held.B do
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Execution complete!")
screen.print(SCREEN_UP, 2, 12, "input: "..inpt)
screen.print(SCREEN_UP, 2, 22,"output: "..out)
screen.print(SCREEN_UP, 2, 32,"Press B to return")
stopDrawing()
end
end
[/code]
Okay - that's the file selection dialogue up and running. It still doesn't run the way I would like - I've had to put the filenames in a table up top, and the user just selects one - but I was having problems getting it to work that way, so this is how it is :frown:
Also, it now displays the program's input and output after execution is complete. I'll add a new version when nested loops are working.
I have a DS with access to the DSLua homebrew, I think I'll test this out in a while.
[QUOTE=windwakr;20556304]My Brainfuck is a little rusty, but here's something you can test with it:
[code]
++++++++[>>+++++++++>+++++++++>++++<<<<-]>>--->+.+++++.++++++.<.>--.--.++.<.>++.>.<.<+++.+.>-.<---------------.>>..<<--.+++++...+++++++.
[/code]The code's a little bigger than it should be, but I'm lazy, and you don't have nested loop support.
[editline]...[/editline]
Here's some better, more optimized, shit I made some time ago:
[code]++++++++++[>+++>++++++>+>+>+++++++++<<<<<-]>++>+++++>--[<.+>-]+++++[>.>.-<<<<......>.+>-]>.--[>.-<-][/code]Outputs:
[code]
ABCDEFGH
Z I
Y J
X K
W L
V M
UTSRQPON
[/code]If you don't get the same output, there's something wrong with your interpreter.[/QUOTE]
[quote=OUT.TXT]INTERPRET THIS: 8===D[/quote]
Lol. Hold on, will try the other one.
[editline]08:17PM[/editline]
[quote=OUT.TXT]ABCDEFGH
Z I
Y J
X K
W L
V M
UTSRQPON[/quote]
lol. hold on, tea now.
[editline]09:00PM[/editline]
Oh and by the way, if anyone else here has a homebrew enabled DS them they can feel free to have a go with this - it runs on micro lua ds 2.0.
I'm going to have another crack at nested loops now - I'll try to respond to you guys, but I can't guarantee it, as my brother is on WoW so I'm having to use my phone for facepunching :frown:
[editline]09:53PM[/editline]
Whooo! Nested loops are now working! :D
Unfortunately, I can't post it just now, due to the aforementioned WoW problem. But I will post it tomorrow, I promise!
Is brainfuck even supposed to have nested loops?
[QUOTE=efeX;20560669]Is brainfuck even supposed to have nested loops?[/QUOTE]
Even if it doesn't, you can reduce every nested loop to one big loop :)
[QUOTE=efeX;20560669]Is brainfuck even supposed to have nested loops?[/QUOTE]
Yes.
[editline]11:28PM[/editline]
[QUOTE=aVoN;20560933]Even if it doesn't, you can reduce every nested loop to one big loop :)[/QUOTE]
That really is a brain fuck though.
Nested loops are easy peasy if you know what you're doing (but I'll admit - I was stuck on this for a bit a few years ago)
Just push the index when you get to a [ and pop when you get to a ]
[QUOTE=turb_;20567800]Nested loops are easy peasy if you know what you're doing (but I'll admit - I was stuck on this for a bit a few years ago)
Just push the index when you get to a [ and pop when you get to a ][/QUOTE]
And remember to skip the correct number of [], when skipping.
Hopefully brainfuck interpreters don't trend up again :v:
Still waiting on some LOLcode interpreters made by FP.
[code]filelist={
"cat.bf",
"helloworld.bf",
"hi.bf",
"rcat.bf",
"numwarp.bf",
"windwakr.bf",
"windwakr2.bf",
"add.bf",
"count.bf"
}
cursorpos = 1
while true do
while not Keys.held.Select do
Controls.read()
if Keys.newPress.Up then cursorpos = cursorpos - 1 end
if Keys.newPress.Down then cursorpos = cursorpos + 1 end
if cursorpos < 1 then cursorpos = #filelist end
if cursorpos > #filelist then cursorpos = 1 end
startDrawing()
for i, v in ipairs(filelist) do
screen.print(SCREEN_UP, 6, i*10+2, v)
end
screen.print(SCREEN_UP, 2, cursorpos*10+2, ">")
stopDrawing()
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Initialising memory...")
stopDrawing()
data = {}
i = 1
while i <= 30000 do
data[i] = 0
i = i + 1
end
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Loading...")
stopDrawing()
file = io.open(filelist[cursorpos], "r")
prog = file:read()
file:close()
file = io.open("in.cfg", "r")
inpt = file:read()
file:close()
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Success! Beginning execution...")
stopDrawing()
i = 1
p = 1
ip = 1
lc = 0
out = ""
while i <= string.len(prog) do
v = string.byte(prog, i)
if v==43 then
data[p] = data[p] + 1
if data[p] > 255 then data[p] = 0 end
elseif v == 45 then
data[p] = data[p] - 1
if data[p] < 0 then data[p] = 255 end
elseif v == 60 then
p = p - 1
if p < 1 then p = 30000 end
elseif v == 62 then
p = p + 1
if p > 30000 then p = 1 end
elseif v == 46 then
out = out..string.char(data[p])
elseif v == 44 then
if ip <= string.len(inpt) then
data[p] = string.byte(inpt, ip)
ip = ip + 1
end
elseif v == 91 then
if data[p] == 0 then
lco = lc
lc = lc + 1
vb = 0
while lc ~= lco do
i = i + 1
vb = string.byte(prog, i)
if vb == 91 then lc = lc + 1 end
if vb == 93 then lc = lc - 1 end
end
else
lc = lc + 1
end
elseif v == 93 then
if data[p] ~= 0 then
lco = lc
lc = lc + 1
vb = 0
while lc ~= lco do
i = i - 1
vb = string.byte(prog, i)
if vb == 91 then lc = lc - 1 end
if vb == 93 then lc = lc + 1 end
end
else
lc = lc - 1
end
end
i = i + 1
end
file = io.open("out.txt", "w")
file:write(out)
file:close()
while not Keys.held.B do
startDrawing()
screen.print(SCREEN_UP, 2, 2, "Execution complete!")
screen.print(SCREEN_UP, 2, 12, "input: "..inpt)
screen.print(SCREEN_UP, 2, 22,"output: "..out)
screen.print(SCREEN_UP, 2, 32,"Press B to return")
stopDrawing()
end
end
[/code]Here you go - nested loops! :dance:
Haven't had much chance to test this out, but it seems to be working.
I need to leave for school in ten minutes, but I'll try to keep replying when I can find the time :frown:
Heh this is fun :)
To give my nested loops a go, I tried numwarp on the first 20 places of Pi:
[quote=in.cfg]3.14159265358979323846[/quote]
OUT.TXT:
[code] /
\/\
\ \/
\/\
/\
\/\
/\ \/
/\
/\ /
/
/\ \/
/\
/\ /
\/\
/\
\
/\
\/\
/\
\/\
/ \/
\/\
/\ /
/\
/ /
\/\
/ /
\/\
/\ \/
/
/\ \/
\/\
/
\/\
\ /
\
\
\/\
\
\
/\ /
/\
/
[/code]:dance:
Oddly, it only seems to work properly if you strip all non-BF characters from the file; I think I might get the script to do this automatically when I load the file.
[editline]11:40AM[/editline]
Damn, mah automerge :(
[editline]11:56AM[/editline]
Oh, and I decided to make the interface a [I]little[/I] less ugly:
[IMG]http://i50.tinypic.com/wt7x9u.jpg[/IMG]
Here is the current code, if you guys want it:
[code]filelist={
"cat.bf",
"helloworld.bf",
"hi.bf",
"rcat.bf",
"numwarp.bf",
"windwakr.bf",
"windwakr2.bf",
"add.bf",
"count.bf"
}
bg = Image.load("top.png", VRAM)
cursorpos = 1
while true do
while not Keys.held.Select do
Controls.read()
if Keys.newPress.Up then cursorpos = cursorpos - 1 end
if Keys.newPress.Down then cursorpos = cursorpos + 1 end
if cursorpos < 1 then cursorpos = #filelist end
if cursorpos > #filelist then cursorpos = 1 end
startDrawing()
screen.blit(SCREEN_UP, 0, 0, bg)
for i, v in ipairs(filelist) do
screen.print(SCREEN_DOWN, 8, i*10+2, v)
end
screen.print(SCREEN_DOWN, 2, cursorpos*10+2, ">")
stopDrawing()
end
startDrawing()
screen.blit(SCREEN_UP, 0, 0, bg)
screen.print(SCREEN_DOWN, 2, 2, "Initialising memory...")
stopDrawing()
data = {}
i = 1
while i <= 30000 do
data[i] = 0
i = i + 1
end
startDrawing()
screen.blit(SCREEN_UP, 0, 0, bg)
screen.print(SCREEN_DOWN, 2, 2, "Success! Loading...")
stopDrawing()
file = io.open(filelist[cursorpos], "r")
prog = file:read()
file:close()
prog2 = ""
i = 1
while i <= string.len(prog) do
v = string.byte(prog, i)
if (v >= 43 and v <= 46) or v == 60 or v == 62 or v == 91 or v == 93 then
prog2 = prog2..string.char(v)
end
i = i + 1
end
prog = prog2
prog2 = nil
file = io.open("in.cfg", "r")
inpt = file:read()
file:close()
startDrawing()
screen.blit(SCREEN_UP, 0, 0, bg)
screen.print(SCREEN_DOWN, 2, 2, "Success! Beginning execution...")
stopDrawing()
i = 1
p = 1
ip = 1
lc = 0
out = ""
while i <= string.len(prog) do
v = string.byte(prog, i)
if v==43 then
data[p] = data[p] + 1
if data[p] > 255 then data[p] = 0 end
elseif v == 45 then
data[p] = data[p] - 1
if data[p] < 0 then data[p] = 255 end
elseif v == 60 then
p = p - 1
if p < 1 then p = 30000 end
elseif v == 62 then
p = p + 1
if p > 30000 then p = 1 end
elseif v == 46 then
out = out..string.char(data[p])
elseif v == 44 then
if ip <= string.len(inpt) then
data[p] = string.byte(inpt, ip)
ip = ip + 1
end
elseif v == 91 then
if data[p] == 0 then
lco = lc
lc = lc + 1
vb = 0
while lc ~= lco do
i = i + 1
vb = string.byte(prog, i)
if vb == 91 then lc = lc + 1 end
if vb == 93 then lc = lc - 1 end
end
else
lc = lc + 1
end
elseif v == 93 then
if data[p] ~= 0 then
lco = lc
lc = lc + 1
vb = 0
while lc ~= lco do
i = i - 1
vb = string.byte(prog, i)
if vb == 91 then lc = lc - 1 end
if vb == 93 then lc = lc + 1 end
end
else
lc = lc - 1
end
end
i = i + 1
end
file = io.open("out.txt", "w")
file:write(out)
file:close()
while not Keys.held.B do
startDrawing()
screen.blit(SCREEN_UP, 0, 0, bg)
screen.print(SCREEN_DOWN, 2, 2, "Execution complete!")
screen.print(SCREEN_DOWN, 2, 12, "input: "..inpt)
screen.print(SCREEN_DOWN, 2, 22,"output: "..out)
screen.print(SCREEN_DOWN, 2, 32,"Press B to return")
stopDrawing()
end
end
[/code]And numwarp.bf, if you want to try it out:
[code]>>>>+>+++>+++>>>>>+++[>,+>++++[>++++<-]>[<<[-[->]]>[<]>-]<<[>+>+>>+>+[<<<<]<+>>[+<]<[>]>+[[>>>]>>+[<<<<]>-]+<+>>>-[<<+[>]>>+<<<+<+<--------[<<-<<+[>]>+<<-<<-[<<<+<-[>>]<-<-<<<-<----[<<<->>>>+<-[<<<+[>]>+<<+<-<-[<<+<-<+[>>]<+<<<<+<-[<<-[>]>>-<<<-<-<-[<<<+<-[>>]<+<<<+<+<-[<<<<+[>]<-<<-[<<+[>]>>-<<<<-<-[>>>>>+<-<<<+<-[>>+<<-[<<-<-[>]>+<<-<-<-[<<+<+[>]<+<+<-[>>-<-<-[<<-[>]<+<++++[<-------->-]++<[<<+[>]>>-<-<<<<-[<<-<<->>>>-[<<<<+[>]>+<<<<-[<<+<<-[>>]<+<<<<<-[>>>>-<<<-<-]]]]]]]]]]]]]]]]]]]]]]>[>[[[<<<<]>+>>[>>>>>]<-]<]>>>+>>>>>>>+>]<]<[-]<<<<<<<++<+++<+++[[>]>>>>>>++++++++[<<++++>++++++>-]<-<<[-[<+>>.<-]]<<<<[-[-[>+<-]>]>>>>>[.[>]]<<[<+>-]>>>[<<++[<+>--]>>-]<<[->+<[<++>-]]<<<[<+>-]<<<<]>>+>>>--[<+>---]<.>>[[-]<<]<][/code]
If you wanna try it out on your computer, then you can download MLS 0.4 from [URL="http://code.google.com/p/microlua-sim/"]here[/URL]. You'll need to put a file called in.cfg in the same directory as the script, along with any bf files that you want to run.
Sorry, you need to Log In to post a reply to this thread.