Befunge JavaScript interpreter

:
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;
 }
 }
}
Category:Implementations