Create a Boolean parser (continued) Continuation of this challenge because the author is gone and the question is closed.

What you need to do is create a Boolean parser.

Boolean expressions, in case you haven't heard of them yet, have two inputs and one output.
There are four &quot;gates&quot; in boolean arithmetic, namely:

OR (represented by |) (binary operator, between arguments)
AND (represented by &amp;) (binary operator, between arguments)
XOR (represented by ^) (binary operator, between arguments)
NOT (represented by !) (unary operator, argument on right)

These gates operate on their inputs which are either true (represented by 1) or false (represented by 0). We can list the possible inputs (A and B in this case) and the outputs (O) using a truth table as follows:
XOR
A|B|O
-----
0|0|0
0|1|1
1|0|1
1|1|0

OR
A|B|O
-----
0|0|0
0|1|1
1|0|1
1|1|1

AND
A|B|O
-----
0|0|0
0|1|0
1|0|0
1|1|1

NOT
A|O
---
0|1
1|0

An example input would be 1^((1|0&amp;0)^!(1&amp;!0&amp;1)), which would evaluate to:
 1^((1|0&amp;0)^!(1&amp;!0&amp;1))
=1^(( 1 &amp;0)^!(1&amp;!0&amp;1))
=1^(   0   ^!(1&amp;!0&amp;1))
=1^(   0   ^!(1&amp; 1&amp;1))
=1^(   0   ^!(  1 &amp;1))
=1^(   0   ^!    1   )
=1^(   0   ^    0    )
=1^0
=1

The output would be 1.
Details

As seen in the example, there is no order of prevalence. All are evaluated from left to right, except when inside parentheses, which should be evaluated first.
The input will only contain ()!^&amp;|01.
You can choose any 8-byte character to replace the 8 characters above, but they must have a 1-to-1 mapping and must be stated.
Specifically, the function eval is not allowed to be used on any string derived from the input. Specifically, the function input (or the equivalent in the language) and any function that calls it cannot be used by eval. You also cannot concatenate the input into your string inside the eval.

Scoring
This is code-golf. Shortest solution in bytes wins.
JavaScript (ES6) 116 bytes

edit thx @user81655 for 3 bytes saved and a bug found



s=&gt;[...s].map(x=&gt;x&lt;2?v=m[x]:x&lt;6?m=[,,m[1]+m[0],0+v,v+1,v+(1^v)][x]:x&gt;6?v=o.pop()[v]:m=o.push(m)&amp;&amp;a,o=[v=a=m='01'])|v


Probably not the best approach, but no eval and no boolean operators, just truth tables.

Character used:


! -> 2
&amp; -> 3
| -> 4
^ -> 5
( -> 6
) -> 7


Test



f=s=&gt;[...s].map(x=&gt;x&lt;2?v=m[x]:x&lt;6?m=[,,m[1]+m[0],0+v,v+1,v+(1^v)][x]:x&gt;6?v=o.pop()[v]:m=o.push(m)&amp;&amp;a,o=[v=a=m='01'])|v

console.log=(...x)=&gt;O.textContent+=x+'\n'

test=[ ["1^((1|0&amp;0)^!(1&amp;!0&amp;1))",1] 
// be more careful, step by step
,["0&amp;0",0],["0&amp;1",0],["1&amp;0",0],["1&amp;1",1]
,["0|0",0],["0|1",1],["1|0",1],["1|1",1]
,["0^0",0],["0^1",1],["1^0",1],["1^1",0]
,["0&amp;!0",0],["0&amp;!1",0],["1&amp;!0",1],["1&amp;!1",0]
,["0|!0",1],["0|!1",0],["1|!0",1],["1|!1",1]
,["0^!0",1],["0^!1",0],["1^!0",0],["1^!1",1]
,["!0&amp;0",0],["!0&amp;1",1],["!1&amp;0",0],["!1&amp;1",0]
,["!0|0",1],["!0|1",1],["!1|0",0],["!1|1",1]
,["!0^0",1],["!0^1",0],["!1^0",0],["!1^1",1]
// nand, nor
,["!(0&amp;0)",1],["!(0&amp;1)",1],["!(1&amp;0)",1],["!(1&amp;1)",0]
,["!(0|0)",1],["!(0|1)",0],["!(1|0)",0],["!(1|1)",0]
     ]

test.forEach(([x,check]) =&gt; {
  // remap operators (each one on its line, just to be clear)
  var t = x.replace(/!/g,"2")
  t = t.replace(/&amp;/g,"3")
  t = t.replace(/\|/g,"4")
  t = t.replace(/\^/g,"5")
  t = t.replace(/\(/g,"6")
  t = t.replace(/\)/g,"7")
  r = f(t)
  console.log((r==check?'OK':'KO')+' '+x +' '+r)
})
&lt;pre id=O&gt;&lt;/pre&gt;