calculator: add initial AST implementation

The AST's class hierarchy is defined inside the `calculator.ast` module.

An abstract visitor is defined inside the `calculator.ast.visit`
package.
This commit is contained in:
Bruno BELANYI 2019-11-30 15:18:26 +01:00
parent e7c70bd6a5
commit 5ea82de840
8 changed files with 132 additions and 0 deletions

View file

@ -0,0 +1 @@
import calculator.ast

View file

@ -0,0 +1,4 @@
from .node import Node # isort:skip
from .binop import BinOp
from .constant import Constant
from .unaryop import UnaryOp

View file

@ -0,0 +1,28 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Callable
from pydantic.dataclasses import dataclass
from .node import Node
if TYPE_CHECKING:
from calculator.ast.visit import Visitor
class Config:
arbitrary_types_allowed = True
@dataclass(config=Config)
class BinOp(Node):
"""
Node to represent a binary operation
"""
op: Callable[[int, int], int]
lhs: Node
rhs: Node
def accept(self, v: Visitor) -> None:
v.visit_binop(self)

View file

@ -0,0 +1,26 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from pydantic.dataclasses import dataclass
from .node import Node
if TYPE_CHECKING:
from calculator.ast.visit import Visitor
class Config:
arbitrary_types_allowed = True
@dataclass(config=Config)
class Constant(Node):
"""
Node to represent a constant value.
"""
value: int
def accept(self, v: Visitor) -> None:
v.visit_constant(self)

View file

@ -0,0 +1,17 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from calculator.ast.visit import Visitor
class Node(ABC):
"""
Abstract Node class for calculator AST.
"""
@abstractmethod
def accept(self, v: Visitor) -> None:
pass

View file

@ -0,0 +1,27 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Callable
from pydantic.dataclasses import dataclass
from .node import Node
if TYPE_CHECKING:
from calculator.ast.visit import Visitor
class Config:
arbitrary_types_allowed = True
@dataclass(config=Config)
class UnaryOp(Node):
"""
Node to represent a unary operation
"""
op: Callable[[int], int]
rhs: Node
def accept(self, v: Visitor) -> None:
v.visit_unaryop(self)

View file

@ -0,0 +1 @@
from .visitor import Visitor # isort:skip

View file

@ -0,0 +1,28 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from calculator.ast import BinOp, Constant, Node, UnaryOp
class Visitor(ABC):
"""
Abstract Visitor class for the AST class hierarchy.
"""
def visit(self, n: Node) -> None:
n.accept(self)
@abstractmethod
def visit_constant(self, c: Constant) -> None:
pass
@abstractmethod
def visit_binop(self, b: BinOp) -> None:
pass
@abstractmethod
def visit_unaryop(self, b: UnaryOp) -> None:
pass