Embarrassingly revealing the extent of my procrastination. Befunge is a toy
stack language. http://en.wikipedia.org/wiki/Befunge
Note 'BEHOLD BEFUNGE 2.0'
first > is optional
arbitrary sized matrix. Extensible to multidimensional matrixes.
allows list instead of matrix (corrected with leading axis) also scalar @ is
valid.
debug support (run x instructions then return. (with stack and ip) resume where
left off)
debug support includes tracing each instruction with boxed power parameter
start/resume at any point with any stack
user input functions are aribtrary J functions. Can be used to change
dimension or cause other side effects.
invalid unhandled instructions conveniently turned into 0
to make language even saner, p helpfully changed to use 3 stack parameters
domain errors helpfully teach you to write your code better through meditation
and no other information.
)
cocurrent 'z'
defaults1 =: ([`]@.(0=#@>@[))
defaults =: defaults1"0 0 f.
fixlenx =: 1 : (':';'((#y) {. x) u y')
eval =: 1 : ' a: 1 : m'
pD_z_ =: 1!:2&2
NB. implement with "global"/instance vars for inputcb, prog
cocurrent 'befunge'
new =: 3 : 0
o =. lastbefunge_base_ =: conew 'befunge'
create__o y
)
create =: 3 : 0
'P startp cbN cbT' =: y defaults fixlenx a:;_;'<@?@2:';'3 : '' ;/ ''''Hello
World!'''' '' '
while. 2>#$P do. P =: ,: P end.
cbN =: cbN eval
cbT =: cbT eval
'h w' =: $ P
ptr =: 0 0
stack =: a:
quotemode=: 0
startp start a:
)
NB. op list. functions always provided inst ptr and stack.
T =: cutLF 0 : 0
]
>3 : ('y';~'nextptr =: nextptrl')
<3 : ('y';~'nextptr =: nextptrr')
^3 : ('y';~'nextptr =: nextptru')
v3 : ('y';~'nextptr =: nextptrd')
@3 : ('y';~'nextptr =: nextptrend')
+(_2 }. ]) , <@:+/@:>@:(_2 {. ])
"3 : ('y';~'quotemode=: -. quotemode')
,(_1 }. ]) , {&a. each@:{:
#3 : ('y';~'domod=: (([: nextptr each {.) , }.)' )
&] , cbN
~] , cbT
)
execstep =: 4 : 0 NB. x is command, y is stack. returns new stack
if. quotemode do. if. '"' ~: x do. y , < pD x return. end. else. pD 'quotemode
0' end.
i =. x i.~ {. &> T
if. i = # T do. y , < 0 ". x return. end.
pD i{T
(}. > i{T) eval y
)
domod=: ]
mod =: 3 : 0
o =. domod y
domod =: ]
o
)
NB. y is ptr (h w) ;stack (list of boxed stack values)
start =: 4 : 0
y =. y defaults fixlenx ptr;stack
o =. mod@:(([: nextptr each {.) , }. execstep~ P {~ {.)^:x y
pD ptr =: > {. o
pD stack =: }. o
if. '@' = P{~ < ptr do. 2}. o else. o end.
)
getptr =: 3 : ' P{~ < ptr"_^:(0=#) y'
NB. y is just ptr. function gets modified by ><^v. initlmode
nextptr =: nextptrl =: 3 : '({. , [: 0:^:(w<]) >:@:{: ) y'
nextptrr =: 3 : '({. , [: w"_^:(0>]) <:@:{: ) y'
nextptru =: 3 : '({: ,~ [: h"_^:(0>]) <:@:{.) y'
nextptrd =: 3 : '({: ,~ [: 0:^:(h<]) >:@:{.) y'
nextptrend =: ]
cocurrent 'base'
p =: > cutLF 0 : 0
>"Hello World!" v
v @#<
>55+, "from J"^
)
NB. usage see
http://www.reddit.com/r/dailyprogrammer/comments/270mll/612014_challenge_164_hard_what_the_funge_is_this/chwg1vh
; new_befunge_ < p
Hello World!
from J
the number parameter tells it how many steps to make in order to guard from non
termination.
redditfmt new_befunge_ p;19
┌────┬┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│1 13││H│e│l│l│o│ │W│o│r│l│d│!│
└────┴┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
when it doesn't complete to end, it returns the stack pointer together with
stack.
can ask for the current code pointer value
quote getptr__lastbefunge ''
' ' NB. just a space
or character at any pointer:
getptr__lastbefunge 0 0
>
can resume where left off
33 start__lastbefunge a:
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│H│e│l│l│o│ │W│o│r│l│d│!│ │r│e│d│d│i│t│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
says to go forward another 33 steps. When it terminates (hits @) returns just
the stack.
can invoke a befunge program in one line specifying program as a string
new_befunge_ '@';3 NB. running too many steps is ok.
new_befunge_ '23+@';6 NB. first > is optional
5
new_befunge_ 12 ;~ 2 4 $ '23+v@ <'
same program as above. J allows to format a table in one line:
new_befunge_ < 2 4 $ '23+v@ <'
also same program... number of steps is optional.
parameters are implemented. Pass a user function that could return any number
of new stack items to add. all of these functions return 5
new_befunge_ '2&+@';_;'<@3:'
new_befunge_ '&+@';_;'2;3:'
new_befunge_ '2&+@';_;'1 + leaf {:'
last function takes the last value on stack to modify it(add 1+2 in J code + 2
on stack by befunge code)
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm