src/ail_ref/ast.py

Read-only source from the unchanged 0.3.4 kit. Existing license terms apply.

from __future__ import annotations

from dataclasses import dataclass
from decimal import Decimal
from typing import Union


@dataclass(frozen=True)
class Atom:
    value: str


@dataclass(frozen=True)
class Variable:
    name: str


@dataclass(frozen=True)
class Unknown:
    pass


@dataclass(frozen=True)
class String:
    value: str


@dataclass(frozen=True)
class Number:
    value: Decimal


@dataclass(frozen=True)
class Boolean:
    value: bool


@dataclass(frozen=True)
class Alias:
    target: Atom
    label: str


@dataclass(frozen=True)
class ListValue:
    items: tuple["Value", ...]


@dataclass(frozen=True)
class Call:
    name: str
    args: tuple["Value", ...]


@dataclass(frozen=True)
class Record:
    name: str
    fields: tuple[tuple[str, "Value"], ...]

    def get(self, key: str) -> "Value | None":
        for field_name, value in self.fields:
            if field_name == key:
                return value
        return None


Value = Union[Atom, Variable, Unknown, String, Number, Boolean, Alias, ListValue, Call, Record]


@dataclass(frozen=True)
class ProtocolUnit:
    header: str
    value: Value


@dataclass(frozen=True)
class Document:
    units: tuple[ProtocolUnit, ...]