calculator: add printer visitor

This commit is contained in:
Bruno BELANYI 2019-11-30 19:21:36 +01:00
parent 2ac7ce0520
commit f77f7b9ed7
3 changed files with 86 additions and 0 deletions

View file

@ -0,0 +1 @@
from .printer import Printer

View 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

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