150 lines
3.2 KiB
Python
150 lines
3.2 KiB
Python
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
from typing import Any, TypeVar, Generic
|
|
|
|
from src.token import Token
|
|
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Expr(ABC):
|
|
@abstractmethod
|
|
def accept(self, visitor: Visitor[T]) -> T:
|
|
...
|
|
|
|
class Visitor(ABC, Generic[T]):
|
|
@abstractmethod
|
|
def visit_assign_expr(self, expr: AssignExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_binary_expr(self, expr: BinaryExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_unary_expr(self, expr: UnaryExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_call_expr(self, expr: CallExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_get_expr(self, expr: GetExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_grouping_expr(self, expr: GroupingExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_literal_expr(self, expr: LiteralExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_variable_expr(self, expr: VariableExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_logical_expr(self, expr: LogicalExpr) -> T:
|
|
...
|
|
|
|
@abstractmethod
|
|
def visit_set_expr(self, expr: SetExpr) -> T:
|
|
...
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AssignExpr(Expr):
|
|
name: Token
|
|
value: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_assign_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BinaryExpr(Expr):
|
|
left: Expr
|
|
operator: Token
|
|
right: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_binary_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class UnaryExpr(Expr):
|
|
operator: Token
|
|
right: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_unary_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CallExpr(Expr):
|
|
callee: Expr
|
|
paren: Token
|
|
arguments: list[Expr]
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_call_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class GetExpr(Expr):
|
|
object: Expr
|
|
name: Token
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_get_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class GroupingExpr(Expr):
|
|
expression: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_grouping_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class LiteralExpr(Expr):
|
|
value: Any
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_literal_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class VariableExpr(Expr):
|
|
name: Token
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_variable_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class LogicalExpr(Expr):
|
|
left: Expr
|
|
operator: Token
|
|
right: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_logical_expr(self)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SetExpr(Expr):
|
|
object: Expr
|
|
name: Token
|
|
value: Expr
|
|
|
|
def accept(self, visitor: Expr.Visitor[T]) -> T:
|
|
return visitor.visit_set_expr(self)
|