idea115-taxalpha-studio-dec.../idea115_taxalpha_studio_dec.../dsl.py

64 lines
2.0 KiB
Python

"""Tiny DSL parser for Phase-0.
Supports simple line-oriented declarations like:
TaxLot id=lot1 acquisition_date=2020-01-01 basis=100 quantity=10 market_value=80
Account id=acct1 jurisdiction=US tax_profile=taxable
This is intentionally minimal and deterministic for testing and the early
prototype. It returns IR dataclasses.
"""
from .ir import TaxLot, Account
from datetime import datetime
from typing import List
def _parse_kv_tokens(tokens):
data = {}
for t in tokens:
if "=" not in t:
continue
k, v = t.split("=", 1)
data[k.strip()] = v.strip()
return data
def parse_declarations(text: str):
"""Parse multiple lines of simple declarations into IR objects.
Returns dict with lists: {"taxlots": [...], "accounts": [...]}.
"""
taxlots = []
accounts = []
for raw in text.splitlines():
line = raw.strip()
if not line or line.startswith("#"):
continue
parts = line.split()
kind = parts[0]
kv = _parse_kv_tokens(parts[1:])
if kind == "TaxLot":
acq = kv.get("acquisition_date")
acq_date = datetime.strptime(acq, "%Y-%m-%d").date() if acq else None
lot = TaxLot(
id=kv.get("id"),
acquisition_date=acq_date,
basis=float(kv.get("basis", 0)),
quantity=float(kv.get("quantity", 0)),
market_value=float(kv.get("market_value")) if kv.get("market_value") else None,
lot_status=kv.get("lot_status", "open"),
)
taxlots.append(lot)
elif kind == "Account":
acct = Account(
id=kv.get("id"),
jurisdiction=kv.get("jurisdiction", "unknown"),
tax_profile=kv.get("tax_profile", "unknown"),
)
accounts.append(acct)
else:
# unknown declarations ignored for now
continue
return {"taxlots": taxlots, "accounts": accounts}