RosettaCodeData/Task/Arithmetic-evaluation/11l/arithmetic-evaluation.11l

117 lines
2.6 KiB
Text
Raw Permalink Normal View History

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 ASTNode
Symbol& symbol
Int value
ASTNode? first_child
ASTNode? second_child
F eval()
S .symbol.id
(number)
R .value
+
R .first_child.eval() + .second_child.eval()
-
R I .second_child == N {-.first_child.eval()} E .first_child.eval() - .second_child.eval()
*
R .first_child.eval() * .second_child.eval()
/
R .first_child.eval() / .second_child.eval()
(
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]
:token_node.symbol = :symbol_table[I token.is_digit() {(number)} E token]
I token.is_digit()
:token_node.value = Int(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*(\d+|.).find_strings(expr_str)
:tokeni = -1
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(-, 1)
infix(*, 2)
infix(/, 2)
prefix(-, 3)
F nud(ASTNode self)
R self
symbol((number)).nud = nud
symbol((end))
F nud_parens(ASTNode self)
V expr = expression()
advance())
R expr
symbol(().nud = nud_parens
symbol())
L(expr_str) [-2 / 2 + 4 + 3 * 2,
2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10]
print(expr_str = parse(expr_str).eval())