calculator: add printer visitor
This commit is contained in:
parent
2ac7ce0520
commit
f77f7b9ed7
1
calculator/calculator/print/__init__.py
Normal file
1
calculator/calculator/print/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .printer import Printer
|
57
calculator/calculator/print/printer.py
Normal file
57
calculator/calculator/print/printer.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from calculator.ast.visit import Visitor
|
||||
from calculator.core.operations import (
|
||||
identity,
|
||||
int_div,
|
||||
minus,
|
||||
negate,
|
||||
plus,
|
||||
pow,
|
||||
times,
|
||||
)
|
||||
from pydantic.dataclasses import dataclass
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from calculator.ast import BinOp, Constant, Node, UnaryOp
|
||||
|
||||
OP_TO_STR = {
|
||||
plus: "+",
|
||||
minus: "-",
|
||||
times: "*",
|
||||
int_div: "/",
|
||||
pow: "^",
|
||||
identity: "+",
|
||||
negate: "-",
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class Printer(Visitor):
|
||||
"""
|
||||
Print a Tree
|
||||
"""
|
||||
|
||||
indent: int = dataclasses.field(default=0, init=False)
|
||||
|
||||
def print(self, n: Node) -> None:
|
||||
n.accept(self)
|
||||
|
||||
def visit_constant(self, c: Constant) -> None:
|
||||
print(" " * self.indent + str(c.value))
|
||||
|
||||
def visit_binop(self, b: BinOp) -> None:
|
||||
print(" " * self.indent + OP_TO_STR[b.op])
|
||||
self.indent += 2
|
||||
self.print(b.lhs)
|
||||
self.print(b.rhs)
|
||||
self.indent -= 2
|
||||
|
||||
def visit_unaryop(self, b: UnaryOp) -> None:
|
||||
print(" " * self.indent + OP_TO_STR[b.op])
|
||||
self.indent += 2
|
||||
self.print(b.rhs)
|
||||
self.indent -= 2
|
28
calculator/calculator/print/test_printer.py
Normal file
28
calculator/calculator/print/test_printer.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
import pytest
|
||||
from calculator.parse import parse_infix
|
||||
|
||||
from .printer import Printer
|
||||
|
||||
|
||||
def print_test_helper(input: str, expected: str, capsys):
|
||||
Printer().print(parse_infix(input))
|
||||
out, __ = capsys.readouterr()
|
||||
assert out == expected
|
||||
|
||||
|
||||
def test_printer_constant(capsys):
|
||||
print_test_helper("42", "42\n", capsys)
|
||||
|
||||
|
||||
def test_printer_negated_constant(capsys):
|
||||
print_test_helper("-42", "-\n 42\n", capsys)
|
||||
|
||||
|
||||
def test_printer_binaryop(capsys):
|
||||
print_test_helper("12 + 27", "+\n 12\n 27\n", capsys)
|
||||
|
||||
|
||||
def test_print_complex_expression(capsys):
|
||||
print_test_helper(
|
||||
"12 + 27 * 42 ^51", "+\n 12\n *\n 27\n ^\n 42\n 51\n", capsys
|
||||
)
|
Loading…
Reference in a new issue