yapcad.dsl.transforms package

Submodules

yapcad.dsl.transforms.base module

AST transformation framework for DSL optimization.

Provides a base class for AST transformations that can be applied before interpretation. This allows for future optimizations like: - Constant folding - Dead code elimination - Pattern unrolling - Common subexpression caching

class yapcad.dsl.transforms.base.AstTransform[source]

Bases: ABC

Base class for AST transformations.

Transforms are applied to a Module and return a (potentially modified) Module. Transforms can be composed in a pipeline.

abstract property name: str

Name of this transform for debugging/logging.

abstractmethod transform(module: Module) Module[source]

Apply this transform to a module.

Parameters:

module – The input module AST

Returns:

The transformed module (may be the same object or a copy)

class yapcad.dsl.transforms.base.IdentityTransform[source]

Bases: AstTransform

Identity transform - returns module unchanged.

property name: str

Name of this transform for debugging/logging.

transform(module: Module) Module[source]

Apply this transform to a module.

Parameters:

module – The input module AST

Returns:

The transformed module (may be the same object or a copy)

class yapcad.dsl.transforms.base.TransformPipeline(transforms: List[AstTransform] = None)[source]

Bases: object

A pipeline of AST transforms to apply in sequence.

add(transform: AstTransform) TransformPipeline[source]

Add a transform to the pipeline.

apply(module: Module) Module[source]

Apply all transforms in sequence.

class yapcad.dsl.transforms.base.TreeTransform[source]

Bases: AstTransform

A transform that walks the tree and can modify nodes.

Subclasses override visit_* methods to transform specific node types. By default, nodes are copied unchanged.

transform(module: Module) Module[source]

Transform a module by visiting all nodes.

visit_assignment(node: AssignmentStatement) Statement[source]

Visit an assignment statement.

visit_binary_op(node: BinaryOp) Expression[source]
visit_block(node: Block) Statement[source]

Visit a block.

visit_command(node: FunctionDef) FunctionDef[source]

Visit a command node.

visit_dict_literal(node: DictLiteral) Expression[source]
visit_emit(node: EmitStatement) Statement[source]

Visit an emit statement.

visit_expr_statement(node: ExpressionStatement) Statement[source]

Visit an expression statement.

visit_expression(node: Expression) Expression[source]

Visit an expression node.

visit_for(node: ForStatement) Statement[source]

Visit a for statement.

visit_function_call(node: FunctionCall) Expression[source]
visit_identifier(node: Identifier) Expression[source]
visit_if_expr(node: IfExpr) Expression[source]
visit_index_access(node: IndexAccess) Expression[source]
visit_lambda(node: LambdaExpr) Expression[source]
visit_let(node: VarDecl) Statement[source]

Visit a let statement.

visit_list_comprehension(node: ListComprehension) Expression[source]
visit_list_literal(node: ListLiteral) Expression[source]
visit_literal(node: Literal) Expression[source]
visit_match_expr(node: MatchExpr) Expression[source]
visit_member_access(node: MemberAccess) Expression[source]
visit_method_call(node: MethodCall) Expression[source]
visit_module(node: Module) Module[source]

Visit a module node.

visit_python_block(node: PythonBlock) Statement[source]

Visit a Python block (no transformation by default).

visit_python_expr(node: PythonExpr) Expression[source]
visit_range(node: RangeExpr) Expression[source]
visit_require(node: AssertStatement) Statement[source]

Visit a require statement.

visit_return(node: ReturnStatement) Statement[source]

Visit a return statement.

visit_statement(node: Statement) Statement[source]

Visit a statement node.

visit_unary_op(node: UnaryOp) Expression[source]

yapcad.dsl.transforms.metadata module

AST-level metadata transform for the v1.1 assembly/operation namespaces.

This transform runs before interpretation, walking the Module AST and validating every FunctionDef.meta_hint dict. It catches structural errors early — at parse/check time rather than at solid-build time — and normalises the hint into a canonical form so the runtime apply_meta_hint call in the interpreter can be a simple, trust-the-input dispatch.

What this transform does

  1. Validates every @meta hint key against the v1.1 schema: - Recognises assembly.*, operation.*, layer, tags. - Rejects unknown dotted namespaces (not assembly or operation). - Validates enum values for operation.kind, operation.policy,

    operation.feature_kind, and assembly.joint_kind at AST time.

  2. Normalises the hint in place: - Booleans-as-strings ("true" / "false") are converted to real

    bools for assembly.no_cut, operation.through, operation.consume.

    • operation.target_filter given as a bare string is promoted to a one-element list.

    • operation.priority is coerced to float.

  3. Cross-field consistency checks: - An operation namespace present without operation.kind is an

    error (kind is the only required field per §6).

    • assembly.no_cut = true combined with operation.kind = "subtract" on the same command is contradictory and is flagged as a warning (not fatal — the author may be intentionally marking it a ghost cutter that also subtracts in some contexts, but it’s almost certainly a mistake).

    • operation present without any target_filter produces an info diagnostic (allowed, but resolver will subtract from every parent).

  4. Produces ``MetadataTransformResult`` entries (errors, warnings, infos) keyed to the FunctionDef’s span so the checker or IDE integration can surface them with source locations.

What this transform does NOT do

  • It does not evaluate expressions inside @meta hints. By the time this transform runs the parser has already reduced literal @meta args to a flat Python dict (meta_hint); any expression that wasn’t a literal is left as-is and will surface as a TypeError at runtime.

  • It does not write sidecar YAML (that’s Step 5).

  • It does not call apply_meta_hint or touch geometry (that’s the runtime).

  • It is idempotent: running it twice produces identical AST state.

Usage

from yapcad.dsl.transforms import TransformPipeline from yapcad.dsl.transforms.metadata import MetadataTransform

pipeline = TransformPipeline() pipeline.add(MetadataTransform()) module = pipeline.apply(module)

# Retrieve diagnostics after the transform: from yapcad.dsl.transforms.metadata import get_transform_diagnostics diags = get_transform_diagnostics(module) errors = [d for d in diags if d.level == “error”]

class yapcad.dsl.transforms.metadata.MetaDiagnostic(level: str, command: str, field: str, message: str, span: SourceSpan | None = None)[source]

Bases: object

A single diagnostic produced by MetadataTransform.

command: str
field: str
level: str
message: str
span: SourceSpan | None = None
class yapcad.dsl.transforms.metadata.MetadataTransform[source]

Bases: AstTransform

Pre-interpretation AST transform that validates and normalises FunctionDef.meta_hint dicts against the v1.1 metadata namespace schema.

Diagnostics are stored on the module object under the _metadata_transform_diagnostics attribute. They are also logged via the yapcad.dsl.transforms.metadata logger at the appropriate level.

The transform is non-destructive: it only modifies the values inside meta_hint dicts (coercions), never removes keys or changes structure.

property name: str

Name of this transform for debugging/logging.

transform(module: Module) Module[source]

Apply the metadata transform to module.

Returns the same module object with: - FunctionDef.meta_hint dicts normalised in place. - module._metadata_transform_diagnostics populated with any

errors, warnings, and infos found.

yapcad.dsl.transforms.metadata.get_transform_diagnostics(module: Module) List[MetaDiagnostic][source]

Return all MetaDiagnostic entries attached to module by MetadataTransform.

Returns an empty list if the transform has not been run or produced no diagnostics.

Module contents

DSL AST Transformation Framework.

Provides a framework for AST transformations that can be applied before interpretation. This allows for optimizations like: - Constant folding - Dead code elimination - Pattern unrolling - Common subexpression caching

Usage:

from yapcad.dsl.transforms import TransformPipeline, ConstantFoldTransform

pipeline = TransformPipeline() pipeline.add(ConstantFoldTransform())

optimized_module = pipeline.apply(module)