241 lines
6.4 KiB
Python
241 lines
6.4 KiB
Python
|
from enum import Enum, auto
|
||
|
from position import Node
|
||
|
from typing import Optional, List
|
||
|
|
||
|
class Pattern:
|
||
|
def __str__(self) -> str:
|
||
|
raise NotImplementedError()
|
||
|
|
||
|
class PatternError(Pattern):
|
||
|
def __init__(self, message: str) -> None:
|
||
|
super().__init__()
|
||
|
self.message = message
|
||
|
|
||
|
class Expr:
|
||
|
def __str__(self) -> str:
|
||
|
raise NotImplementedError()
|
||
|
|
||
|
|
||
|
class ExprError(Expr):
|
||
|
def __init__(self, message: str) -> None:
|
||
|
super().__init__()
|
||
|
self.message = message
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"ErrorExpr({self.message})"
|
||
|
|
||
|
class Id(Expr):
|
||
|
def __init__(self, value: str) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Id({self.value})"
|
||
|
|
||
|
class Int(Expr):
|
||
|
def __init__(self, value: int) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Int({self.value})"
|
||
|
|
||
|
|
||
|
class Char(Expr):
|
||
|
def __init__(self, value: str) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Char('{self.value}')"
|
||
|
|
||
|
|
||
|
class String(Expr):
|
||
|
def __init__(self, value: str) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"String(\"{self.value}\")"
|
||
|
|
||
|
|
||
|
class Bool(Expr):
|
||
|
def __init__(self, value: bool) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
value = "true" if self.value else "false"
|
||
|
return f"Bool({value})"
|
||
|
|
||
|
|
||
|
class Unit(Expr):
|
||
|
def __init__(self) -> None:
|
||
|
super().__init__()
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return "Unit"
|
||
|
|
||
|
|
||
|
class Block(Expr):
|
||
|
def __init__(self, statements: List[Node[Expr]], value: Optional[Node[Expr]]) -> None:
|
||
|
super().__init__()
|
||
|
self.statements = statements
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
statements = ", ".join(node.__str__() for node in self.statements)
|
||
|
return f"Block {{ statements: [{statements}], value: {self.value} }}"
|
||
|
|
||
|
|
||
|
class If(Expr):
|
||
|
def __init__(self, condition: Node[Expr], truthy: Node[Expr], falsy: Optional[Node[Expr]]) -> None:
|
||
|
super().__init__()
|
||
|
self.condition = condition
|
||
|
self.truthy = truthy
|
||
|
self.falsy = falsy
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"If {{ condition: {self.condition}, truthy: {self.truthy}, falsy: {self.falsy} }}"
|
||
|
|
||
|
class MatchArm:
|
||
|
def __init__(self, pattern: Node[Pattern], expr: Node[Expr]) -> None:
|
||
|
self.pattern = pattern
|
||
|
self.expr = expr
|
||
|
|
||
|
class Match(Expr):
|
||
|
def __init__(self, value: Node[Expr], arms: List[Node[MatchArm]]) -> None:
|
||
|
super().__init__()
|
||
|
self.value = value
|
||
|
self.arms = arms
|
||
|
|
||
|
class Loop(Expr):
|
||
|
def __init__(self, body: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.body = body
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Loop {{ body: {self.body} }}"
|
||
|
|
||
|
class While(Expr):
|
||
|
def __init__(self, condition: Node[Expr], body: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.condition = condition
|
||
|
self.body = body
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"While {{ condition: {self.condition}, body: {self.body} }}"
|
||
|
|
||
|
class For(Expr):
|
||
|
def __init__(self, subject: Node[Pattern], value: Node[Expr], body: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.subject = subject
|
||
|
self.value = value
|
||
|
self.body = body
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"For {{ subject: {self.subject}, value: {self.value}, body: {self.body} }}"
|
||
|
|
||
|
class StructMember(Expr):
|
||
|
def __init__(self, subject: Node[Expr], member_id: str) -> None:
|
||
|
super().__init__()
|
||
|
self.subject = subject
|
||
|
self.member_id = member_id
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"StructMember {{ subject: {self.subject}, member_id: {self.member_id} }}"
|
||
|
|
||
|
class TupleMember(Expr):
|
||
|
def __init__(self, subject: Node[Expr], member_index: int) -> None:
|
||
|
super().__init__()
|
||
|
self.subject = subject
|
||
|
self.member_index = member_index
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"StructMember {{ subject: {self.subject}, member_index: {self.member_index} }}"
|
||
|
|
||
|
class Index(Expr):
|
||
|
def __init__(self, subject: Node[Expr], value: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.subject = subject
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Index {{ subject: {self.subject}, value: {self.value} }}"
|
||
|
|
||
|
class Call(Expr):
|
||
|
def __init__(self, subject: Node[Expr], arguments: List[Node[Expr]]) -> None:
|
||
|
super().__init__()
|
||
|
self.subject = subject
|
||
|
self.arguments = arguments
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
arguments = ", ".join(node.__str__() for node in self.arguments)
|
||
|
return f"Index {{ subject: {self.subject}, arguments: {arguments} }}"
|
||
|
|
||
|
class UnaryType(Enum):
|
||
|
Not = auto()
|
||
|
Negate = auto()
|
||
|
Reference = auto()
|
||
|
ReferenceMut = auto()
|
||
|
Dereference = auto()
|
||
|
|
||
|
|
||
|
class Unary(Expr):
|
||
|
def __init__(self, unary_type: UnaryType, subject: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.unary_type = unary_type
|
||
|
self.subject = subject
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Unary {{ unary_type: {self.unary_type}, subject: {self.subject} }}"
|
||
|
|
||
|
|
||
|
class BinaryType(Enum):
|
||
|
And = auto()
|
||
|
Or = auto()
|
||
|
Add = auto()
|
||
|
Subtract = auto()
|
||
|
Multiply = auto()
|
||
|
Divide = auto()
|
||
|
Modulo = auto()
|
||
|
Exponent = auto()
|
||
|
Equal = auto()
|
||
|
Inequal = auto()
|
||
|
LT = auto()
|
||
|
GT = auto()
|
||
|
LTEqual = auto()
|
||
|
GTEqual = auto()
|
||
|
In = auto()
|
||
|
|
||
|
|
||
|
class Binary(Expr):
|
||
|
def __init__(self, binary_type: BinaryType, left: Node[Expr], right: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.binary_type = binary_type
|
||
|
self.left = left
|
||
|
self.right = right
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Binary {{ binary_type: {self.binary_type}, left: {self.left}, right: {self.right} }}"
|
||
|
|
||
|
|
||
|
class AssignType(Enum):
|
||
|
Assign = auto()
|
||
|
Add = auto()
|
||
|
Subtract = auto()
|
||
|
Multiply = auto()
|
||
|
Divide = auto()
|
||
|
Modulo = auto()
|
||
|
|
||
|
|
||
|
class Assign(Expr):
|
||
|
def __init__(self, assign_type: AssignType, subject: Node[Expr], value: Node[Expr]) -> None:
|
||
|
super().__init__()
|
||
|
self.assign_type = assign_type
|
||
|
self.subject = subject
|
||
|
self.value = value
|
||
|
|
||
|
def __str__(self) -> str:
|
||
|
return f"Assign {{ assign_type: {self.assign_type}, subject: {self.subject}, value: {self.value} }}"
|