2023-07-01 11:58:00 -04:00
|
|
|
|
T Symbol
|
|
|
|
|
|
String id
|
|
|
|
|
|
Int lbp
|
|
|
|
|
|
Int nud_bp
|
|
|
|
|
|
Int led_bp
|
|
|
|
|
|
(ASTNode -> ASTNode) nud
|
|
|
|
|
|
((ASTNode, ASTNode) -> ASTNode) led
|
|
|
|
|
|
|
|
|
|
|
|
F set_nud_bp(nud_bp, nud)
|
|
|
|
|
|
.nud_bp = nud_bp
|
|
|
|
|
|
.nud = nud
|
|
|
|
|
|
|
|
|
|
|
|
F set_led_bp(led_bp, led)
|
|
|
|
|
|
.led_bp = led_bp
|
|
|
|
|
|
.led = led
|
|
|
|
|
|
|
|
|
|
|
|
T Var
|
|
|
|
|
|
String name
|
|
|
|
|
|
Int value
|
|
|
|
|
|
F (name)
|
|
|
|
|
|
.name = name
|
|
|
|
|
|
[Var] vars
|
|
|
|
|
|
|
|
|
|
|
|
T ASTNode
|
|
|
|
|
|
Symbol& symbol
|
|
|
|
|
|
Int var_index
|
|
|
|
|
|
ASTNode? first_child
|
|
|
|
|
|
ASTNode? second_child
|
|
|
|
|
|
|
|
|
|
|
|
F eval()
|
|
|
|
|
|
S .symbol.id
|
|
|
|
|
|
‘(var)’
|
|
|
|
|
|
R :vars[.var_index].value
|
|
|
|
|
|
‘|’
|
|
|
|
|
|
R .first_child.eval() [|] .second_child.eval()
|
|
|
|
|
|
‘^’
|
|
|
|
|
|
R .first_child.eval() (+) .second_child.eval()
|
|
|
|
|
|
‘&’
|
|
|
|
|
|
R .first_child.eval() [&] .second_child.eval()
|
|
|
|
|
|
‘!’
|
2024-03-06 22:25:12 -08:00
|
|
|
|
R ~.first_child.eval() [&] 1
|
2023-07-01 11:58:00 -04:00
|
|
|
|
‘(’
|
|
|
|
|
|
R .first_child.eval()
|
|
|
|
|
|
E
|
|
|
|
|
|
assert(0B)
|
|
|
|
|
|
R 0
|
|
|
|
|
|
|
|
|
|
|
|
[String = Symbol] symbol_table
|
|
|
|
|
|
[String] tokens
|
|
|
|
|
|
V tokeni = -1
|
|
|
|
|
|
ASTNode token_node
|
|
|
|
|
|
|
|
|
|
|
|
F advance(sid = ‘’)
|
|
|
|
|
|
I sid != ‘’
|
|
|
|
|
|
assert(:token_node.symbol.id == sid)
|
|
|
|
|
|
:tokeni++
|
|
|
|
|
|
:token_node = ASTNode()
|
|
|
|
|
|
I :tokeni == :tokens.len
|
|
|
|
|
|
:token_node.symbol = :symbol_table[‘(end)’]
|
|
|
|
|
|
R
|
|
|
|
|
|
V token = :tokens[:tokeni]
|
|
|
|
|
|
I token[0].is_alpha()
|
|
|
|
|
|
:token_node.symbol = :symbol_table[‘(var)’]
|
|
|
|
|
|
L(v) :vars
|
|
|
|
|
|
I v.name == token
|
|
|
|
|
|
:token_node.var_index = L.index
|
|
|
|
|
|
L.break
|
|
|
|
|
|
L.was_no_break
|
|
|
|
|
|
:token_node.var_index = :vars.len
|
|
|
|
|
|
:vars.append(Var(token))
|
|
|
|
|
|
E
|
|
|
|
|
|
:token_node.symbol = :symbol_table[token]
|
|
|
|
|
|
|
|
|
|
|
|
F expression(rbp = 0)
|
|
|
|
|
|
ASTNode t = move(:token_node)
|
|
|
|
|
|
advance()
|
|
|
|
|
|
V left = t.symbol.nud(move(t))
|
|
|
|
|
|
L rbp < :token_node.symbol.lbp
|
|
|
|
|
|
t = move(:token_node)
|
|
|
|
|
|
advance()
|
|
|
|
|
|
left = t.symbol.led(t, move(left))
|
|
|
|
|
|
R left
|
|
|
|
|
|
|
|
|
|
|
|
F parse(expr_str) -> ASTNode
|
|
|
|
|
|
:tokens = re:‘\s*(\w+|.)’.find_strings(expr_str)
|
|
|
|
|
|
:tokeni = -1
|
|
|
|
|
|
:vars.clear()
|
|
|
|
|
|
advance()
|
|
|
|
|
|
R expression()
|
|
|
|
|
|
|
|
|
|
|
|
F symbol(id, bp = 0) -> &
|
|
|
|
|
|
I id !C :symbol_table
|
|
|
|
|
|
V s = Symbol()
|
|
|
|
|
|
s.id = id
|
|
|
|
|
|
s.lbp = bp
|
|
|
|
|
|
:symbol_table[id] = s
|
|
|
|
|
|
R :symbol_table[id]
|
|
|
|
|
|
|
|
|
|
|
|
F infix(id, bp)
|
|
|
|
|
|
F led(ASTNode self, ASTNode left)
|
|
|
|
|
|
self.first_child = left
|
|
|
|
|
|
self.second_child = expression(self.symbol.led_bp)
|
|
|
|
|
|
R self
|
|
|
|
|
|
symbol(id, bp).set_led_bp(bp, led)
|
|
|
|
|
|
|
|
|
|
|
|
F prefix(id, bp)
|
|
|
|
|
|
F nud(ASTNode self)
|
|
|
|
|
|
self.first_child = expression(self.symbol.nud_bp)
|
|
|
|
|
|
R self
|
|
|
|
|
|
symbol(id).set_nud_bp(bp, nud)
|
|
|
|
|
|
|
|
|
|
|
|
infix(‘|’, 1)
|
|
|
|
|
|
infix(‘^’, 2)
|
|
|
|
|
|
infix(‘&’, 3)
|
|
|
|
|
|
prefix(‘!’, 4)
|
|
|
|
|
|
|
|
|
|
|
|
F nud(ASTNode self)
|
|
|
|
|
|
R self
|
|
|
|
|
|
symbol(‘(var)’).nud = nud
|
|
|
|
|
|
symbol(‘(end)’)
|
|
|
|
|
|
|
|
|
|
|
|
F nud_parens(ASTNode self)
|
|
|
|
|
|
V expr = expression()
|
|
|
|
|
|
advance(‘)’)
|
|
|
|
|
|
R expr
|
|
|
|
|
|
symbol(‘(’).nud = nud_parens
|
|
|
|
|
|
symbol(‘)’)
|
|
|
|
|
|
|
|
|
|
|
|
L(expr_str) [‘!A | B’, ‘A ^ B’, ‘S | ( T ^ U )’, ‘A ^ (B ^ (C ^ D))’]
|
|
|
|
|
|
print(‘Boolean expression: ’expr_str)
|
|
|
|
|
|
print()
|
|
|
|
|
|
ASTNode p = parse(expr_str)
|
|
|
|
|
|
print(vars.map(v -> v.name).join(‘ ’)‘ : ’expr_str)
|
|
|
|
|
|
L(i) 0 .< (1 << vars.len)
|
|
|
|
|
|
L(v) vars
|
|
|
|
|
|
v.value = (i >> (vars.len - 1 - L.index)) [&] 1
|
|
|
|
|
|
print(v.value, end' ‘ ’)
|
|
|
|
|
|
print(‘: ’p.eval())
|
|
|
|
|
|
print()
|