JavaScript (Node.js), 608 597 586 551 bytes
Takes input as (source)(input)
, where input is an array containing single characters and/or integers.
s=>I=>eval([..."@CDEJKLMNQTUWYZ^_bkmqw"].reduce((s,c)=>(a=s.split(c)).join(a.pop()),"(R=X=>(H={},o=P=[],S=[],z=x=p=i=0,gUs[p]?~(j=` \n`.indexOf(s[p++]N?j:gK:3,hUgK<2?Mn*2+j):V=n,GUx=z--&&S.pop(y=x),FUg(x=`mbQQ$mS[z+~(b])TSCce((z-=V=b-1,V)$mkJLmyJkTTLH[x]=y$mHD)qR[M1)]=_?R[P@p),V]:_Y_&!kY_&k<0Yp$E?P.popK:pT$^QQQQQqW+yw-yw*yw/y|0w%yN:^QTTo+=Buffer(D)$o+=k$Z.codePointAtKZ`Ct`$`[n-9],x&&eval(x,n=1N<3&&F(n*3+jN(1N(0)||R(1)||owN:^$WqTT$mz=S@kGKbgK?-M0):M0N_p$M1),E^E?g:pZ$HD=I[i++]Y?R[V]:Wz>1?(LmxU=n=>T$$QqqN))Mh(Lk,k,K()J),mx)$Ep=XD[k][email protected]"))
Try it online! (all test cases without comments)
Try it online! (an example with a commented source code as input)
###How?
Because the code is packed with RegPack, it is more efficient to repeat the same pieces of code over and over rather than defining too many helper functions.
The sequences of spaces, tabs and linefeeds are converted to an integer in base 3 with a leading \$1\$ until they match a known value:
seq. | base 3 | decimal
------+--------+---------
SS | 100 | 9
STS | 1010 | 30
STN | 1012 | 32
SNS | 1020 | 33
SNT | 1021 | 34
SNN | 1022 | 35
TTS | 1110 | 39
TTT | 1111 | 40
NSS | 1200 | 45
NST | 1201 | 46
NSN | 1202 | 47
NTS | 1210 | 48
NTT | 1211 | 49
NTN | 1212 | 50
NNN | 1222 | 53
TSSS | 11000 | 108
TSST | 11001 | 109
TSSN | 11002 | 110
TSTS | 11010 | 111
TSTT | 11011 | 112
TNSS | 11200 | 126
TNST | 11201 | 127
TNTS | 11210 | 129
TNTT | 11211 | 130
The commands are simply stored in a lookup table and executed with eval()
.
Everything is wrapped within the function \$R\$ which is called twice:
- First pass (\$X=0\$): we store all labels and ignore the jumps and the stack errors
- Second pass (\$X=1\$): the code is executed normally
###Unpacked and formatted
s => I => (
R = X => (
H = {},
o = P = [],
S = [],
z = x = p = i = 0,
g = n => s[p] ? ~(j = ` \t\n`.indexOf(s[p++])) ? j : g() : 3,
h = n => g() < 2 ? h(n * 2 + j) : V = n,
G = n => x = z-- && S.pop(y = x),
F = n => g(
x = [
"z=S.push(g()?-h(0):h(0))",,,,,,,,,,,,,,,,,,,,,
"z=S.push(S[z+~(g()?-h(0):h(0))])",,
"S.splice((z-=V=g()?-h(0):h(0))-1,V)",
"z=S.push(G()),z=S.push(x)",
"G(),G(),z=S.push(y),z=S.push(x)",
"G()",,,,
"G(),G(),H[x]=y",
"z=S.push(H[G()])",,,,,
"R[h(1)]=p",
"h(1),p=X?R[P.push(p),V]:p",
"h(1),p=X?R[V]:p",
"h(1),p=X&!G()?R[V]:p",
"h(1),p=X&G()<0?R[V]:p",
"p=X?P.pop():p",,,
"p=X?g:p",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
"z>1?(G(),G(),z=S.push(x+y)):p=X?g:p",
"z>1?(G(),G(),z=S.push(x-y)):p=X?g:p",
"z>1?(G(),G(),z=S.push(x*y)):p=X?g:p",
"z>1?(G(),G(),z=S.push(x/y|0)):p=X?g:p",
"z>1?(G(),G(),z=S.push(x%y)):p=X?g:p",,,,,,,,,,,,,,
"o+=Buffer([G()])",
"o+=G()",,
"H[G()]=I[i++].codePointAt()",
"H[G()]=I[i++]"
][n - 9],
x && eval(x, n = 1)
) < 3 && F(n * 3 + j)
)(1)
)(0) || R(1) || o