2023-04-06 03:17:57 +01:00
|
|
|
from enum import Enum, auto
|
|
|
|
from position import Node
|
|
|
|
from typing import Optional, List
|
2023-04-10 03:20:05 +01:00
|
|
|
from utils import escape_string
|
2023-04-06 03:17:57 +01:00
|
|
|
|
2023-04-08 18:21:37 +01:00
|
|
|
class Type:
|
|
|
|
def __str__(self) -> str:
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
class TypeError(Type):
|
|
|
|
def __init__(self, message: str) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.message = message
|
|
|
|
|
2023-04-06 03:17:57 +01:00
|
|
|
class Pattern:
|
|
|
|
def __str__(self) -> str:
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
class PatternError(Pattern):
|
|
|
|
def __init__(self, message: str) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.message = message
|
|
|
|
|
2023-04-08 18:21:37 +01:00
|
|
|
class Parameter:
|
|
|
|
def __init__(self, subject: Pattern, value_type: Type) -> None:
|
|
|
|
self.subject = subject
|
|
|
|
self.value_type = value_type
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return f"Parameter {{ subject: {self.subject}, value_type: {self.value_type} }}"
|
|
|
|
|
2023-04-06 03:17:57 +01:00
|
|
|
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:
|
2023-04-10 03:20:05 +01:00
|
|
|
return f"Char('{escape_string(self.value)}')"
|
2023-04-06 03:17:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
class String(Expr):
|
|
|
|
def __init__(self, value: str) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
2023-04-10 03:20:05 +01:00
|
|
|
return f"String(\"{escape_string(self.value)}\")"
|
2023-04-06 03:17:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
2023-04-08 18:21:37 +01:00
|
|
|
class Tuple(Expr):
|
|
|
|
def __init__(self, values: List[Node[Expr]]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.values = values
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
2023-04-10 03:20:05 +01:00
|
|
|
values = ", ".join(str(node) for node in self.values)
|
2023-04-08 18:21:37 +01:00
|
|
|
return f"Tuple {{ values: [{values}] }}"
|
2023-04-06 03:17:57 +01:00
|
|
|
|
|
|
|
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:
|
2023-04-10 03:20:05 +01:00
|
|
|
statements = ", ".join(str(node) for node in self.statements)
|
2023-04-06 03:17:57 +01:00
|
|
|
return f"Block {{ statements: [{statements}], value: {self.value} }}"
|
|
|
|
|
2023-04-08 18:21:37 +01:00
|
|
|
class Lambda(Expr):
|
|
|
|
def __init__(self, params: List[Node[Parameter]], body: Node[Expr]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.params = params
|
|
|
|
self.body = body
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
2023-04-10 03:20:05 +01:00
|
|
|
params = ", ".join(str(node) for node in self.params)
|
2023-04-08 18:21:37 +01:00
|
|
|
return f"Lambda {{ params: [{params}], body: {self.body} }}"
|
|
|
|
|
2023-04-06 03:17:57 +01:00
|
|
|
|
|
|
|
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:
|
2023-04-10 03:20:05 +01:00
|
|
|
arguments = ", ".join(str(node) for node in self.arguments)
|
2023-04-06 03:17:57 +01:00
|
|
|
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} }}"
|
2023-04-08 18:21:37 +01:00
|
|
|
|
|
|
|
class Let(Expr):
|
|
|
|
def __init__(self, subject: Node[Pattern], value_type: Optional[Node[Type]], value: Node[Expr]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.subject = subject
|
|
|
|
self.value_type = value_type
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return f"Let {{ subject: {self.subject}, value_type: {self.value_type}, value: {self.value} }}"
|
|
|
|
|
|
|
|
class Function(Expr):
|
|
|
|
def __init__(self, subject_id: str, params: List[Node[Parameter]], body: Node[Expr]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.subject_id = subject_id
|
|
|
|
self.params = params
|
|
|
|
self.body = body
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
2023-04-10 03:20:05 +01:00
|
|
|
params = ", ".join(str(node) for node in self.params)
|
2023-04-08 18:21:37 +01:00
|
|
|
return f"Function {{ subject_id: {self.subject_id}, params: [{params}], body: {self.body} }}"
|
|
|
|
|
|
|
|
class Return(Expr):
|
|
|
|
def __init__(self, value: Optional[Node[Expr]]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return f"Return {{ value: {self.value} }}"
|
|
|
|
|
|
|
|
class Break(Expr):
|
|
|
|
def __init__(self, value: Optional[Node[Expr]]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return f"Break {{ value: {self.value} }}"
|
|
|
|
|
|
|
|
class Continue(Expr):
|
|
|
|
def __init__(self, value: Optional[Node[Expr]]) -> None:
|
|
|
|
super().__init__()
|
|
|
|
self.value = value
|
|
|
|
|
|
|
|
def __str__(self) -> str:
|
|
|
|
return f"Continue {{ value: {self.value} }}"
|
|
|
|
|