Befunge JavaScript interpreter
Jump to navigation
Jump to search
The follwing is a JavaScript interpreter for Befunge-93 by User:None1. It uses unrestricted playfield size, and division or modulo by 0 results in 0.
// Befunge 93 with unrestricted playfield function pop(s){ if(s.length==0){ return 0; }else{ return s.pop(); } } function befunge(program,input){ var playfield=[],maxw=0; for(let i of program.split('\n')){ playfield.push(i.split("")); if(i.length>maxw){ maxw=i.length; } } for(let i of playfield){ while(i.length<maxw){ i.push(" "); } } var ipx=0,ipy=0,ipdx=0,ipdy=1,output='',stack=[]; while(1){ var cmd=playfield[ipx][ipy]; if('1234567890'.includes(cmd)){ stack.push(cmd.charCodeAt(0)-48); } switch(cmd){ case '@':{ return output; break; } case '+':{ var a=pop(stack); var b=pop(stack); stack.push(b+a); break; } case '-':{ var a=pop(stack); var b=pop(stack); stack.push(b-a); break; } case '*':{ var a=pop(stack); var b=pop(stack); stack.push(b*a); break; } case '/':{ var a=pop(stack); var b=pop(stack); if(a==0){ stack.push(0); break; } stack.push(a<0?Math.ceil(b/a):Math.floor(b/a)); break; } case '%':{ var a=pop(stack); var b=pop(stack); if(a==0){ stack.push(0); break; } stack.push(b%a); break; } case '!':{ var a=pop(stack); if(a){ stack.push(0); break; } stack.push(1); break; } case '`':{ var a=pop(stack); var b=pop(stack); if(b>a){ stack.push(1); break; } stack.push(0); break; } case '>':{ ipdx=0; ipdy=1; break; } case '<':{ ipdx=0; ipdy=-1; break; } case 'v':{ ipdx=1; ipdy=0; break; } case '^':{ ipdx=-1; ipdy=0; break; } case '?':{ var x=Math.floor(Math.random()*4); ipdx=[0,0,1,-1][x]; ipdy=[1,-1,0,0][x]; break; } case '_':{ ipdx=0; if(pop(stack)){ ipdy=-1; }else{ ipdy=1; } break; } case '|':{ ipdy=0; if(pop(stack)){ ipdx=-1; }else{ ipdx=1; } break; } case '\"':{ do{ ipx+=ipdx; ipy+=ipdy; while(ipx>=playfield.length){ ipx-=playfield.length; } while(ipx<0){ ipx+=playfield.length; } while(ipy>=maxw||ipy==-1){ ipy-=maxw; } while(ipy<0){ ipy+=maxw; } stack.push(playfield[ipx][ipy].charCodeAt(0)); }while(playfield[ipx][ipy]!='\"'); pop(stack); break; } case ':':{ stack.push(stack.length==0?0:stack[stack.length-1]); break; } case '\\':{ var a=pop(stack); var b=pop(stack); stack.push(a); stack.push(b); break; } case '$':{ pop(stack); break; } case '.':{ output+=pop(stack)+' '; break; } case ',':{ output+=String.fromCharCode(pop(stack)); break; } case '#':{ ipx+=ipdx; ipy+=ipdy; break; } case 'g':{ var b=pop(stack); var a=pop(stack); if(b>=playfield.length||a>=maxw){ stack.push(0); }else{ stack.push(playfield[b][a].charCodeAt(0)); } break; } case 'p':{ var b=pop(stack); var a=pop(stack); var v=pop(stack); playfield[b][a]=String.fromCharCode(v); break; } case '&':{ var result=0,flag=1; if(input[0]=='-'){ flag=-1; input=input.slice(1); } while(input.length>0&&'1234567890'.includes(input[0])){ result*=10; result+=input.charCodeAt(0)-48; input=input.slice(1); } while(input.length>0&&!'1234567890'.includes(input[0])){ input=input.slice(1); } stack.push(result*flag) break; } case '~':{ stack.push(input[0]); input=input.slice(1); break; } } ipx+=ipdx; ipy+=ipdy; while(ipx>=playfield.length){ ipx-=playfield.length; } while(ipx<0){ ipx+=playfield.length; } while(ipy>=maxw||ipy==-1){ ipy-=maxw; } while(ipy<0){ ipy+=maxw; } } }