feat(cadfs): expand selector provenance coverage
This commit is contained in:
@@ -49,6 +49,12 @@ class Parser:
|
||||
|
||||
def primary(self) -> Any:
|
||||
token = self.pop()
|
||||
if token.value in {"+", "-"}:
|
||||
# FeatureScript permits a signed parenthesized scalar such as
|
||||
# ``-(138.6) / 2 * mm``. Keep it in the existing arithmetic AST
|
||||
# so every downstream constant/units validator sees the same
|
||||
# expression shape as a binary subtraction.
|
||||
return Call("__binary__", [0.0, token.value, self.primary()], token.line)
|
||||
if token.value == "(":
|
||||
value = self.expression(); self.accept(")"); return value
|
||||
if token.kind == "string": return _string(token.value)
|
||||
@@ -151,6 +157,20 @@ def _arg_map(call: Call) -> dict[str, Any]:
|
||||
return next((arg for arg in reversed(call.args) if isinstance(arg, dict)), {})
|
||||
|
||||
|
||||
def _feature_id(call: Call) -> str | None:
|
||||
"""Return the declared ID for one direct FeatureScript feature call.
|
||||
|
||||
FeatureScript operations share the ``operation(context, id + "F...",
|
||||
definition)`` shape. Retaining this generic boundary makes an unknown
|
||||
source operation visible to the capability registry and lowering instead
|
||||
of silently omitting it because its name is absent from a parser list.
|
||||
"""
|
||||
if len(call.args) < 2 or call.args[0] != "context":
|
||||
return None
|
||||
feature_id = symbolic_string(call.args[1])
|
||||
return feature_id if feature_id.startswith("F") else None
|
||||
|
||||
|
||||
def parse_featurescript(source: str, sample_id: str = "unknown") -> ModelIR:
|
||||
parser = Parser(source); calls = parser.statements()
|
||||
version = re.search(r"\bFeatureScript\s+(\d+(?:\.\d+)*)\s*;", source)
|
||||
@@ -175,8 +195,7 @@ def parse_featurescript(source: str, sample_id: str = "unknown") -> ModelIR:
|
||||
if model.sketches:
|
||||
args = _arg_map(call); eid = str(call.args[1]) if len(call.args) > 1 else f"E{len(model.sketches[-1].entities)}"
|
||||
model.sketches[-1].entities.append(FeatureIR(eid, call.name, args, line_start=call.line, raw_source=call.name))
|
||||
elif call.name in {"extrude", "revolve", "fillet", "chamfer", "hole", "linearPattern", "mirror", "cPlane", "referenceAxis", "shell", "loft", "sweep", "circularPattern", "booleanBodies", "deleteBodies", "transform", "draft", "thicken", "split", "moveFace", "replaceFace", "deleteFace", "derive"}:
|
||||
fid = symbolic_string(call.args[1]) if len(call.args) > 1 else f"feature_{len(model.features)}"
|
||||
elif (fid := _feature_id(call)) is not None:
|
||||
feature_ir = FeatureIR(fid, call.name, _arg_map(call), line_start=call.line, raw_source=call.name)
|
||||
model.features.append(feature_ir); model.steps.append(feature_ir)
|
||||
return model
|
||||
|
||||
Reference in New Issue
Block a user