Skip to content

Instantly share code, notes, and snippets.

@Johann150
Created February 9, 2019 12:35
Show Gist options
  • Save Johann150/017852d4385e1811bae85bbe04cb6182 to your computer and use it in GitHub Desktop.
Save Johann150/017852d4385e1811bae85bbe04cb6182 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div style="float:left;">
<textarea id="in" cols="80" rows="30"></textarea><br>
<button onclick="go()">go!</button>
<a href="https://esolangs.org/wiki/Emmental" target="_blank">?</a>
</div>
<pre id="out"></pre>
<script>
let stack,queue;
function interpret(str,instr){
let diffs=[];
for(let i=0;i<str.length;i++){
let x=str[i];
if(!instr.hasOwnProperty(x))
continue;
x=instr[x](instr);
if(Array.isArray(x))
x.forEach((e)=>{
instr[e[0]]=e[1];
diffs=diffs.filter((elem)=>{
return elem[0]!=e[0];
});
diffs.push(e);
});
}
return diffs;
}
function number(){stack.push(stack.pop()*10+this);}
function program(){
let str=[];
while(stack.length>0&&stack[stack.length-1]!=';'.charCodeAt(0)){
str.unshift(stack.pop());
}
if(stack.length==0){
throw new Error("no semicolon found","Emmental program",0);
}
stack.pop();// pop semicolon
return String.fromCharCode.apply(null,str);
}
function go(){
// reset state
stack=[];
queue=[];
document.getElementById('out').innerText="";
let instr={
'#':()=>{stack.push(0);},
'0':number.bind(0),
'1':number.bind(1),
'2':number.bind(2),
'3':number.bind(3),
'4':number.bind(4),
'5':number.bind(5),
'6':number.bind(6),
'7':number.bind(7),
'8':number.bind(8),
'9':number.bind(9),
'+':()=>{
stack.push(stack.pop()+stack.pop());
},
'-':()=>{
let x=stack.pop();
stack.push(stack.pop()-x);
},
'~':()=>{
let x=stack.pop();
while(x<0)
x+=256;
x%=256;
if(x==0){stack.push(8);}
else if(x==1){stack.push(0);}
else if(x<4){stack.push(1);}
else if(x<8){stack.push(2);}
else if(x<16){stack.push(3);}
else if(x<32){stack.push(4);}
else if(x<64){stack.push(5);}
else if(x<128){stack.push(6);}
else{stack.push(7);}
},
'.':()=>{
document.getElementById('out').innerText+=String.fromCharCode(stack.pop());
},
',':()=>{
stack.push((prompt('input; one character only')||'\0').charCodeAt(0));
},
'^':()=>{
queue.push(stack.pop());
},
'v':()=>{
stack.push(queue.shift());
},
':':()=>{
stack.push(stack[stack.length-1]);
},
'!':()=>{
let i=String.fromCharCode(stack.pop()),
str=program();
// just return a diff list
return [[i,interpret.bind(0,str,instr)]];
},
'?':(instr)=>{
let x=String.fromCharCode(stack.pop());
return interpret.bind(0,x,instr)();
},
';':()=>{
stack.push(';'.charCodeAt(0));
}
};
try{
interpret(document.getElementById('in').value,instr);
}catch(err){
console.error(err);
alert("execution aborted with error: "+err.message);
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment