Files
pebble/src/ast/expr.py

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)