70 lines
2.0 KiB
Python
70 lines
2.0 KiB
Python
"""
|
|
Tiny DSL -> contract translator.
|
|
|
|
This module provides a minimal, production-friendly, deterministic translator
|
|
from a compact DSL representation to a GridVerse LocalProblem payload.
|
|
It is intended for the MVP's low-code development flow as a seed for codegen.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Dict
|
|
|
|
|
|
def parse_simple_dsl(text: str) -> Dict[str, Any]:
|
|
"""
|
|
Parse a very small DSL into a payload dict.
|
|
|
|
DSL format (line-based, simple key=value):
|
|
site_id=site-01
|
|
description=Example local problem
|
|
variables.temperature=22.5
|
|
variables.flow=3.2
|
|
|
|
Nested keys are expressed with dot notation. Arrays are comma-separated
|
|
values after a key ending in [] (not currently used, but reserved).
|
|
"""
|
|
result: Dict[str, Any] = {"site_id": "", "description": "", "variables": {}}
|
|
if not text:
|
|
return result
|
|
for raw in text.strip().splitlines():
|
|
line = raw.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if "=" not in line:
|
|
continue
|
|
key, val = line.split("=", 1)
|
|
key = key.strip()
|
|
val = val.strip()
|
|
if key == "site_id":
|
|
result["site_id"] = val
|
|
elif key == "description":
|
|
result["description"] = val
|
|
elif key.startswith("variables."):
|
|
var_name = key.split(".", 1)[1]
|
|
# naive type inference
|
|
parsed = _infer_type(val)
|
|
result["variables"][var_name] = parsed
|
|
else:
|
|
# generic top-level
|
|
result[key] = _infer_type(val)
|
|
# ensure variables exists
|
|
if "variables" not in result:
|
|
result["variables"] = {}
|
|
return result
|
|
|
|
|
|
def _infer_type(value: str) -> Any:
|
|
# Try int, float, bool, otherwise string
|
|
if value.lower() in {"true", "false"}:
|
|
return value.lower() == "true"
|
|
try:
|
|
return int(value)
|
|
except ValueError:
|
|
pass
|
|
try:
|
|
return float(value)
|
|
except ValueError:
|
|
pass
|
|
return value
|