Download 1
Download 2
Download 3 (most recent)
(sort of still under development, so I'd rather not submit it to the archives just yet.)

Brainf*^!
A brainf*** interpreter in pure TI-BASIC! The interpreter's named after the three commands I added in (they don't affect normal program flow, but could be used to do fun stuff):


^ - shifts everything right of the pointer one cell to the left, removing the tape cell at the pointer
* - makes pointer jump to cell # of the value in the current cell
! - prints both the tape and the pointer's current value.


Some notes:
- The idea of * making the pointer jump comes from this post on the XKCD forums. However, unlike him, I'm not entirely convinced that * can replace < and >, so I left those in.
- As this is in TI-Basic, where there's no concept of ASCII, it only allows you to enter numbers for input (and anything that returns a number works, even decimals, negatives and expressions). As such, any usage 48 +'s or 48 -'s to convert numbers to/from ASCII should be removed from programs.
- Does not allow programs longer than 999 bytes. I'll upload a (slower, unfortunately) version of the program tomorrow that'll be able to handle longer inputs.
- Doesn't use Celtic/hybrid libs; you have to input the string manually.
- Could still be optimized. A lot.
[wrong advice deleted (sorry)]
Also, think about doing some short-circuiting. If you find out that Str0 is >, you don't need to check if it's "[", "]", ".", or ",".

Try starting your main loop with an
Code:
inString("<>-+.,[]",sub(Str9,θ,1→T
so you don't need to check for string equality so many times. Or, even better, if you expect an input of size less than 1000, just do seq(inString("<>-+.,[]",sub(Str9,θ,1)),θ,1,length(Str1→L₂ at the start and you won't need to worry about strings for the rest of the program.
Good point, that would definitely make it faster. Both examples you gave worked great, so thanks!
How should I handle popping from the stack (to save memory)? I was thinking of including a ^ command that would require the user to manually pop from the stack, but I'm starting to think it would be a better idea to automatically pop an element if its value is 0, it's not being pointed to and it's at the end of the stack.
Of course, doing it automatically would disallow the user from popping from the middle or beginning of the stack... but regular Brainf*** does just fine without a that feature, doesn't it? Then again, it would be useful for the user to be able to pop unnecessary elements so that they don't clog up memory.

So what should I do? Manual pop, automatic pop or both?
(and if I go with manual popping, should it just delete the element from the list or change its value to zero? Both are possible.)

Edit- Thinking of going with both. If somebody can optimize my popping routine, though, please do:

Code:

For(N,P+1,dim(L1 //P is the pointer variable
L1(N->L1(N-1
End
dim(L1)-1->dim(L1
Good work, @M.I.Wright. I spent some time considering ways to increase the speed of Brainf code on the Z80 calcs. Thats why I used Str7 as the input for my compiler, so it can act as a jit compiler for self running Brainf programs, using something like this: (displays a +).

Code:

"+++++++++++.,->Str7
Asm(prgmBFC84CSE
Asm(prgmAOUT

This method does have the disadvantage of causing Assembly style crashes if there are errors in the Brainf.
I tried doing the 'short-circuiting' thing by prematurely ending the For( loop, but it doesn't seem to be much faster... am I doing something wrong?


Code:
1->P:DelVar L11->dim(L1
Input "",Str9
seq(inString("><+-.,[]^/*",sub(Str9,S,1)),S,1,length(Str9->L2
For(S,1,dim(Ans))
L2(S->T
P+(T=1)-(T=2->P
If not(P:dim(L1->P
If T<=2:End
dim(L1
Ans+(P-Ans)(P>Ans->dim(L1
L1(P)+(T=3)-(T=4->L1(P
If T and T<=4:End
If T=5
Disp L1(P
If T=6:Then
Input V
V->L1(P
End
If T and T<=6:End
If T=9
seq(L1(X+(X>=P)),X,1,dim(L1)-1->L1
If T=9:End
If T=7 and not(L1(P:Then
DelVar A
For(C,S,length(Str9
sub(Str9,C,1
A+(Ans="[")-(Ans="]->A
If not(A:Then
C->S
1+length(Str9->C
End
End
End
If T=7:End
If T=8 and L1(P:Then
DelVar A
For(C,S,1,~1
sub(Str9,C,1
A+(Ans="]")-(Ans="[->A
If not(A:Then
C->S:0->C
End
End
End
If T=8:End
S+(T=10)length(Str9->S
If T=11
Disp L1,P
If T=11:End


Edit: It seems like brackets are taking the most time to compute, understandably. I'm thinking of finding a way to maybe store bracket locations in L₃ before the program starts running, so that whenever it encounters a bracket it'll be able to jump almost instantaneously to the corresponding bracket location. Thoughts?

Code:
cumsum((L₂=7)-(L₂=8

will give you the depths of all brackets. For example,
"+++[>+<-]" will become {0,0,0,1,1,1,1,1,0}. From there, you can find pairs of matching brackets.

Note that Brainfuck is not required to have the pointer wrap around to the last element of the list when < is called at position 0. Also, all non-instruction characters should be ignored, so I think If T and T≤4 can just be If T≤4.
Oh, that's smart. Thank you!
I'm on mobile atm so I can't update the file, but I've now shortened those lines down to this (I changed the loop variable/program counter from theta to S):

Code:

If T=7 and not(L1(P
2+sum(not(cumSum(L3(S)-1=seq(L3(X),X,S+1,dim(L3->S
If T=7:End
If T=8 and L1(P
1+sum(not(cumSum(L3=1+L3(S->S
If T=8:End


One major caveat: it will fail on separate brackets of thethe same depth. Consider this program:

Code:
+[>][+]

This should produce a two-element stack in L1, and infinitely increase the second element, so {1,∞}. Instead, when it reaches the last closing bracket, it'll loop back to the first opening bracket instead of the one it's supposed to loop back to, so by the fourth iteration L1 will look like {1,0,0,0,0}. I'll see if I can fix this, maybe by reversing L3 and using the code for T=7?

I'm aware that wrapping isn't required, but it makes things a lot easier and it's a feature in a lot of Brainf compilers/interpreters I've seen.
I wish I could get rd of that, but it starts throwing a syntax error (extra End) if T=0 :/

Edit: opening brackets also fail to jump when the current stack value is 0. Not sure why yet.
Edit 2: never mind, it wasn't searching for the right value. Fixed the code above.
Ugh. I'd just about fixed the ] bracket to work with the seq( command, then my RAM reset :/ I'll figure it out sometime in the next few days again.
As you might have seen yesterday, I have a new version up! Not a single For loop in there except for the main one Smile Thanks, lirtosiast!

Should I add an option to presupply input as a list before running the program?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement