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

117 lines
2.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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())