Source code for yapcad.dsl.symbols

"""
Symbol table management for the yapCAD DSL type checker.

Provides scoped symbol tables for tracking variable definitions,
function signatures, and type information during type checking.
"""

from dataclasses import dataclass, field
from typing import Optional, Dict, List, Callable, Any, Tuple
from enum import Enum, auto

from .types import (
    Type, FunctionType, ListType, ERROR, UNKNOWN,
    INT, FLOAT, BOOL, STRING,
    POINT, POINT2D, POINT3D, VECTOR, VECTOR2D, VECTOR3D, TRANSFORM,
    LINE_SEGMENT, ARC, CIRCLE, ELLIPSE, PARABOLA, HYPERBOLA,
    CATMULLROM, NURBS, BEZIER,
    PATH2D, PATH3D, PROFILE2D, REGION2D, LOOP3D,
    SURFACE, SHELL, SOLID, DICT,
    make_list_type, make_optional_type,
)
from .tokens import SourceSpan


[docs] class SymbolKind(Enum): """The kind of symbol being tracked.""" VARIABLE = auto() PARAMETER = auto() FUNCTION = auto() COMMAND = auto() MODULE = auto()
[docs] @dataclass class Symbol: """A symbol in the symbol table.""" name: str kind: SymbolKind type: Type span: Optional[SourceSpan] = None # Where it was defined is_mutable: bool = False has_python_block: bool = False # Commands with Python blocks
[docs] @dataclass class FunctionSignature: """Type signature for a function or built-in.""" name: str params: List[Tuple[str, Type, Optional[Any]]] # (name, type, default) return_type: Type is_method: bool = False # True for methods like curve.at() is_variadic: bool = False # True for functions that accept list<T> as well
[docs] @dataclass class Scope: """A single scope in the scope stack.""" symbols: Dict[str, Symbol] = field(default_factory=dict) parent: Optional["Scope"] = None name: str = "" # For debugging: "command MAKE_GEAR", "for loop", etc.
[docs] def define(self, symbol: Symbol) -> None: """Define a symbol in this scope.""" self.symbols[symbol.name] = symbol
[docs] def lookup_local(self, name: str) -> Optional[Symbol]: """Look up a symbol in this scope only.""" return self.symbols.get(name)
[docs] def lookup(self, name: str) -> Optional[Symbol]: """Look up a symbol in this scope or any parent scope.""" symbol = self.symbols.get(name) if symbol is not None: return symbol if self.parent is not None: return self.parent.lookup(name) return None
[docs] class SymbolTable: """ Manages scopes and symbol definitions for type checking. Provides: - Nested scope management (push/pop) - Symbol definition and lookup - Built-in function registry """ def __init__(self): # Global scope contains built-in functions and types self._global_scope = Scope(name="global") self._current_scope = self._global_scope # Built-in function signatures self._builtins: Dict[str, FunctionSignature] = {} # Initialize built-ins self._init_builtins() def _init_builtins(self) -> None: """Initialize built-in function signatures.""" # Tier 1: Point and Vector constructors self._register_builtin("point", [ ("x", FLOAT, None), ("y", FLOAT, None), ("z", FLOAT, "optional"), # Optional - presence determines 2D/3D, default 0.0 ], POINT) # Convenience constructor for 2D points (z=0) self._register_builtin("point2d", [ ("x", FLOAT, None), ("y", FLOAT, None), ], POINT2D) self._register_builtin("vector", [ ("dx", FLOAT, None), ("dy", FLOAT, None), ("dz", FLOAT, None), ], VECTOR) # Convenience constructor for 2D vectors (dz=0) self._register_builtin("vector2d", [ ("dx", FLOAT, None), ("dy", FLOAT, None), ], VECTOR2D) # Solid transformation functions (translate, rotate, scale solids directly) self._register_builtin("translate", [ ("s", SOLID, None), ("x", FLOAT, None), ("y", FLOAT, None), ("z", FLOAT, None), ], SOLID) self._register_builtin("rotate", [ ("s", SOLID, None), ("x", FLOAT, None), ("y", FLOAT, None), ("z", FLOAT, None), ], SOLID) self._register_builtin("scale", [ ("s", SOLID, None), ("x", FLOAT, None), ("y", FLOAT, None), ("z", FLOAT, None), ], SOLID) # Transform constructors (for advanced use - create transform matrices) self._register_builtin("translate_xform", [("v", VECTOR, None)], TRANSFORM) self._register_builtin("rotate_xform", [ ("axis", VECTOR3D, None), ("angle", FLOAT, None), ], TRANSFORM) self._register_builtin("rotate_2d", [("angle", FLOAT, None)], TRANSFORM) self._register_builtin("scale_xform", [("factors", VECTOR, None)], TRANSFORM) self._register_builtin("scale_uniform", [("factor", FLOAT, None)], TRANSFORM) self._register_builtin("mirror", [("s", SOLID, None), ("plane_normal", VECTOR3D, None)], SOLID) self._register_builtin("mirror_2d", [("axis", VECTOR2D, None)], TRANSFORM) self._register_builtin("mirror_y", [], TRANSFORM) # Convenience self._register_builtin("identity_transform", [], TRANSFORM) # Tier 2: Curve constructors self._register_builtin("line", [ ("start", POINT, None), ("end", POINT, None), ], LINE_SEGMENT) self._register_builtin("arc", [ ("center", POINT, None), ("radius", FLOAT, None), ("start_angle", FLOAT, None), ("end_angle", FLOAT, None), ], ARC) self._register_builtin("circle", [ ("center", POINT, None), ("radius", FLOAT, None), ], CIRCLE) self._register_builtin("ellipse", [ ("center", POINT, None), ("semi_major", FLOAT, None), ("semi_minor", FLOAT, None), ("rotation", FLOAT, "optional"), ("start", FLOAT, "optional"), ("end", FLOAT, "optional"), ], ELLIPSE) self._register_builtin("bezier", [ ("control_points", make_list_type(POINT), None), ], BEZIER) self._register_builtin("catmullrom", [ ("points", make_list_type(POINT), None), ("closed", BOOL, "optional"), # default false ("alpha", FLOAT, "optional"), # default 0.5 ], CATMULLROM) self._register_builtin("nurbs", [ ("points", make_list_type(POINT), None), ("weights", make_list_type(FLOAT), "optional"), # default all 1.0 ("degree", INT, "optional"), # default 3 ], NURBS) # Curve sampling functions self._register_builtin("sample_curve", [ ("curve", UNKNOWN, None), # Any curve type ("t", FLOAT, None), ], POINT) self._register_builtin("sample_curve_n", [ ("curve", UNKNOWN, None), ("n", INT, None), ], make_list_type(POINT)) self._register_builtin("curve_length", [ ("curve", UNKNOWN, None), ], FLOAT) # Tier 3: Path/Region operations self._register_builtin("path", [ ("segments", make_list_type(UNKNOWN), None), # list of curves ], PATH2D) # Returns path2d or path3d based on input self._register_builtin("join", [ ("p1", PATH2D, None), ("p2", PATH2D, None), ], PATH2D) # Path3D constructors for sweep operations (variadic) self._register_builtin("make_path3d", [ ("segment", PATH3D, None), ], PATH3D, is_variadic=True) self._register_builtin("path3d_line", [ ("start", POINT3D, None), ("end", POINT3D, None), ], PATH3D) self._register_builtin("path3d_arc", [ ("center", POINT3D, None), ("start", POINT3D, None), ("end", POINT3D, None), ("normal", VECTOR3D, None), ], PATH3D) # Arc with auto-computed normal from geometry # flip=false: normal = (center->start) x (center->end), takes shorter arc # flip=true: negated normal, takes longer arc (opposite direction) self._register_builtin("path3d_arc_auto", [ ("center", POINT3D, None), ("start", POINT3D, None), ("end", POINT3D, None), ("flip", BOOL, None), ], PATH3D) self._register_builtin("close", [("p", PROFILE2D, None)], REGION2D) self._register_builtin("closeC0", [("p", PROFILE2D, None)], REGION2D) self._register_builtin("closeC1", [("p", PROFILE2D, None)], REGION2D) self._register_builtin("rectangle", [ ("width", FLOAT, None), ("height", FLOAT, None), ("center", POINT2D, "optional"), ], REGION2D) self._register_builtin("regular_polygon", [ ("n", INT, None), ("radius", FLOAT, None), ("center", POINT2D, "optional"), ], REGION2D) # Polygon from points self._register_builtin("polygon", [ ("points", make_list_type(POINT), None), ], REGION2D) # Disk (filled circle as polygon) self._register_builtin("disk", [ ("center", POINT, None), ("radius", FLOAT, None), ("segments", INT, "optional"), # default 64 ], REGION2D) # 2D Boolean operations self._register_builtin("union2d", [ ("a", REGION2D, None), ("b", REGION2D, None), ], REGION2D) self._register_builtin("difference2d", [ ("a", REGION2D, None), ("b", REGION2D, None), ], REGION2D) self._register_builtin("intersection2d", [ ("a", REGION2D, None), ("b", REGION2D, None), ], REGION2D) # Phase 3: 2D boolean aggregation functions self._register_builtin("union2d_all", [ ("regions", make_list_type(REGION2D), None), ], REGION2D) self._register_builtin("difference2d_all", [ ("base", REGION2D, None), ("tools", make_list_type(REGION2D), None), ], REGION2D) self._register_builtin("intersection2d_all", [ ("regions", make_list_type(REGION2D), None), ], REGION2D) # Path2D construction self._register_builtin("make_path2d", [ ("curves", make_list_type(UNKNOWN), None), ], PATH2D) self._register_builtin("close_path", [ ("path", PATH2D, None), ], REGION2D) # Region from spline self._register_builtin("region_from_spline", [ ("spline", UNKNOWN, None), ("segments", INT, "optional"), ], REGION2D) # Tier 4: Surface operations self._register_builtin("planar_surface", [ ("boundary", LOOP3D, None), ], SURFACE) self._register_builtin("cylindrical_surface", [ ("axis", VECTOR3D, None), ("radius", FLOAT, None), ("height", FLOAT, None), ], SURFACE) self._register_builtin("loft_surface", [ ("profiles", make_list_type(PATH3D), None), ], SURFACE) self._register_builtin("shell", [ ("surfaces", make_list_type(SURFACE), None), ], SHELL) # Tier 5: Solid operations self._register_builtin("extrude", [ ("profile", REGION2D, None), ("height", FLOAT, None), ("direction", VECTOR3D, "optional"), ], SOLID) self._register_builtin("revolve", [ ("profile", REGION2D, None), ("axis", VECTOR3D, None), ("angle", FLOAT, None), ], SOLID) self._register_builtin("sweep", [ ("profile", REGION2D, None), ("spine", PATH3D, None), ], SOLID) self._register_builtin("sweep_hollow", [ ("outer_profile", REGION2D, None), ("inner_profile", REGION2D, None), ("spine", PATH3D, None), ], SOLID) self._register_builtin("sweep_adaptive", [ ("profile", REGION2D, None), ("spine", PATH3D, None), ("threshold", FLOAT, None), # Angle in degrees ], SOLID) self._register_builtin("sweep_adaptive_hollow", [ ("outer_profile", REGION2D, None), ("inner_profiles", REGION2D, None), # Single region2d or list ("spine", PATH3D, None), ("threshold", FLOAT, None), ], SOLID) # Frenet frame variants - profile follows natural curvature self._register_builtin("sweep_adaptive_frenet", [ ("profile", REGION2D, None), ("spine", PATH3D, None), ("threshold", FLOAT, None), ], SOLID) self._register_builtin("sweep_adaptive_hollow_frenet", [ ("outer_profile", REGION2D, None), ("inner_profiles", REGION2D, None), ("spine", PATH3D, None), ("threshold", FLOAT, None), ], SOLID) self._register_builtin("loft", [ ("profiles", make_list_type(REGION2D), None), ], SOLID) self._register_builtin("box", [ ("width", FLOAT, None), ("depth", FLOAT, None), ("height", FLOAT, None), ], SOLID) self._register_builtin("cylinder", [ ("radius", FLOAT, None), ("height", FLOAT, None), ], SOLID) self._register_builtin("sphere", [ ("radius", FLOAT, None), ], SOLID) self._register_builtin("oblate_spheroid", [ ("equatorial_diameter", FLOAT, None), ("oblateness", FLOAT, None), ], SOLID) self._register_builtin("cone", [ ("radius1", FLOAT, None), ("radius2", FLOAT, None), ("height", FLOAT, None), ], SOLID) # Involute gear - creates a proper gear profile self._register_builtin("involute_gear", [ ("teeth", INT, None), ("module_mm", FLOAT, None), ("pressure_angle", FLOAT, None), ("face_width", FLOAT, None), ], SOLID) # Herringbone gear - double-helix gear with smooth tooth surfaces self._register_builtin("herringbone_gear", [ ("teeth", INT, None), ("module_mm", FLOAT, None), ("face_width", FLOAT, None), ("helix_angle", FLOAT, None), ], SOLID) # Sun gear with integrated hub - optimized to avoid expensive boolean self._register_builtin("sun_gear_with_hub", [ ("teeth", INT, None), ("module_mm", FLOAT, None), ("face_width", FLOAT, None), ("helix_angle", FLOAT, None), ("hub_diameter", FLOAT, None), ("hub_height", FLOAT, None), ("bolt_circle", FLOAT, None), ("num_bolts", INT, None), ("bolt_hole_diameter", FLOAT, None), ], SOLID) # Phase 2 geometry primitives self._register_builtin("dodecahedron", [ ("diameter", FLOAT, None), ], SOLID) self._register_builtin("tube", [ ("outer_diameter", FLOAT, None), ("wall_thickness", FLOAT, None), ("length", FLOAT, None), ], SOLID) self._register_builtin("conic_tube", [ ("bottom_od", FLOAT, None), ("top_od", FLOAT, None), ("wall_thickness", FLOAT, None), ("length", FLOAT, None), ], SOLID) self._register_builtin("spherical_shell", [ ("outer_diameter", FLOAT, None), ("wall_thickness", FLOAT, None), ], SOLID) self._register_builtin("helical_extrude", [ ("profile", REGION2D, None), ("height", FLOAT, None), ("twist_angle", FLOAT, None), ], SOLID) # Phase 3 text support self._register_builtin("text_solid", [ ("text", STRING, None), ("height", FLOAT, None), ("depth", FLOAT, None), ("spacing", FLOAT, None), ], SOLID) self._register_builtin("engrave_text", [ ("target", SOLID, None), ("text", STRING, None), ("position", VECTOR3D, None), ("normal", VECTOR3D, None), ("height", FLOAT, None), ("depth", FLOAT, None), ("spacing", FLOAT, None), ], SOLID) self._register_builtin("text_width", [ ("text", STRING, None), ("height", FLOAT, None), ("spacing", FLOAT, None), ], FLOAT) # Phase 4 path utilities & manufacturing self._register_builtin("path3d_eval", [ ("path", PATH3D, None), ("t", FLOAT, None), ], POINT3D) # Returns point (tangent available via separate call if needed) self._register_builtin("path3d_length", [ ("path", PATH3D, None), ], FLOAT) self._register_builtin("split_solid", [ ("s", SOLID, None), ("plane_point", POINT3D, None), ("plane_normal", VECTOR3D, None), ], SOLID) # Returns list but typed as SOLID for now (first half) # Planet gear with integrated hub - eliminates tooth root holes # Hub fills from bore to dedendum radius, full face width self._register_builtin("planet_gear_with_hub", [ ("teeth", INT, None), ("module_mm", FLOAT, None), ("face_width", FLOAT, None), ("helix_angle", FLOAT, None), ("bore_diameter", FLOAT, None), ], SOLID) # Fasteners - hex bolts and nuts from catalog # Metric fasteners (ISO 4014/4017 bolts, ISO 4032 nuts) self._register_builtin("metric_hex_bolt", [ ("size", STRING, None), # e.g., "M8", "M10" ("length", FLOAT, None), # shank length in mm ], SOLID) self._register_builtin("metric_hex_nut", [ ("size", STRING, None), # e.g., "M8", "M10" ], SOLID) # Unified fasteners (ASME B18.2.1 bolts, ASME B18.2.2 nuts) self._register_builtin("unified_hex_bolt", [ ("size", STRING, None), # e.g., "1/4-20", "1/2-13" ("length", FLOAT, None), # shank length in inches ], SOLID) self._register_builtin("unified_hex_nut", [ ("size", STRING, None), # e.g., "1/4-20", "1/2-13" ], SOLID) # Text solid generation - 3D extruded text self._register_builtin("text_solid", [ ("text", STRING, None), # Text string to render ("height", FLOAT, None), # Character height in mm ("depth", FLOAT, None), # Extrusion depth in mm ], SOLID) self._register_builtin("text_solid_fitted", [ ("text", STRING, None), # Text string to render ("max_width", FLOAT, None), # Maximum width in mm (auto-scales height) ("depth", FLOAT, None), # Extrusion depth in mm ], SOLID) # text_on_surface - Simple way to place text on any surface # Handles all coordinate frame transformations automatically self._register_builtin("text_on_surface", [ ("text", STRING, None), # Text string to render ("surface_center", POINT3D, None), # Center point of target surface (x, y, z) ("surface_normal", POINT3D, None), # Outward-pointing normal vector ("up_direction", POINT3D, None), # "Up" direction on surface (text baseline to top) ("max_width", FLOAT, None), # Maximum text width in mm ("depth", FLOAT, None), # How far text protrudes from surface ], SOLID) # Boolean operations (variadic) self._register_builtin("union", [ ("a", SOLID, None), ("b", SOLID, None), ], SOLID, is_variadic=True) self._register_builtin("difference", [ ("a", SOLID, None), ("b", SOLID, None), ], SOLID, is_variadic=True) self._register_builtin("intersection", [ ("a", SOLID, None), ("b", SOLID, None), ], SOLID, is_variadic=True) self._register_builtin("compound", [ ("a", SOLID, None), ("b", SOLID, None), ], SOLID, is_variadic=True) # List-based boolean aggregation (Phase 3 functional combinators) self._register_builtin("union_all", [ ("solids", make_list_type(SOLID), None), ], SOLID) self._register_builtin("difference_all", [ ("base", SOLID, None), ("tools", make_list_type(SOLID), None), ], SOLID) self._register_builtin("intersection_all", [ ("solids", make_list_type(SOLID), None), ], SOLID) # Fillet and chamfer operations (OCC-based edge finishing) self._register_builtin("fillet", [ ("s", SOLID, None), ("radius", FLOAT, None), ], SOLID) self._register_builtin("chamfer", [ ("s", SOLID, None), ("distance", FLOAT, None), ], SOLID) # Pattern operations self._register_builtin("radial_pattern", [ ("shape", UNKNOWN, None), # Any geometry ("count", INT, None), ("axis", VECTOR3D, None), ("center", POINT, None), ], UNKNOWN) # Returns same type as input self._register_builtin("linear_pattern", [ ("shape", UNKNOWN, None), ("count", INT, None), ("spacing", VECTOR, None), ], UNKNOWN) # Query operations self._register_builtin("volume", [("s", SOLID, None)], FLOAT) self._register_builtin("surface_area", [("s", SOLID, None)], FLOAT) self._register_builtin("area", [("r", REGION2D, None)], FLOAT) self._register_builtin("perimeter", [("r", REGION2D, None)], FLOAT) self._register_builtin("centroid", [("s", SOLID, None)], POINT3D) self._register_builtin("distance", [ ("a", POINT, None), ("b", POINT, None), ("tolerance", FLOAT, None), ], FLOAT) # Transform application - type-specific versions self._register_builtin("apply", [ ("t", TRANSFORM, None), ("shape", SOLID, None), ], SOLID) self._register_builtin("apply_surface", [ ("t", TRANSFORM, None), ("shape", SURFACE, None), ], SURFACE) self._register_builtin("apply_point", [ ("t", TRANSFORM, None), ("p", POINT, None), ], POINT) self._register_builtin("apply_vector", [ ("t", TRANSFORM, None), ("v", VECTOR3D, None), ], VECTOR3D) # Math functions self._register_builtin("sin", [("x", FLOAT, None)], FLOAT) self._register_builtin("cos", [("x", FLOAT, None)], FLOAT) self._register_builtin("tan", [("x", FLOAT, None)], FLOAT) self._register_builtin("asin", [("x", FLOAT, None)], FLOAT) self._register_builtin("acos", [("x", FLOAT, None)], FLOAT) self._register_builtin("atan", [("x", FLOAT, None)], FLOAT) self._register_builtin("atan2", [("y", FLOAT, None), ("x", FLOAT, None)], FLOAT) self._register_builtin("sqrt", [("x", FLOAT, None)], FLOAT) self._register_builtin("abs", [("x", FLOAT, None)], FLOAT) self._register_builtin("min", [("a", FLOAT, None), ("b", FLOAT, None)], FLOAT) self._register_builtin("max", [("a", FLOAT, None), ("b", FLOAT, None)], FLOAT) self._register_builtin("radians", [("degrees", FLOAT, None)], FLOAT) self._register_builtin("degrees", [("radians", FLOAT, None)], FLOAT) self._register_builtin("floor", [("x", FLOAT, None)], INT) self._register_builtin("ceil", [("x", FLOAT, None)], INT) self._register_builtin("round", [("x", FLOAT, None)], INT) self._register_builtin("pow", [("base", FLOAT, None), ("exp", FLOAT, None)], FLOAT) self._register_builtin("exp", [("x", FLOAT, None)], FLOAT) self._register_builtin("log", [("x", FLOAT, None)], FLOAT) self._register_builtin("log10", [("x", FLOAT, None)], FLOAT) self._register_builtin("pi", [], FLOAT) # Constant: pi self._register_builtin("tau", [], FLOAT) # Constant: tau (2*pi) # List operations self._register_builtin("len", [("list", make_list_type(UNKNOWN), None)], INT) self._register_builtin("range", [("end", INT, None)], make_list_type(INT), is_variadic=True) self._register_builtin("concat", [ ("list1", make_list_type(UNKNOWN), None), ("list2", make_list_type(UNKNOWN), None), ], make_list_type(UNKNOWN)) # Concatenate two lists self._register_builtin("reverse", [ ("list", make_list_type(UNKNOWN), None), ], make_list_type(UNKNOWN)) # Reverse a list self._register_builtin("flatten", [ ("list", make_list_type(make_list_type(UNKNOWN)), None), ], make_list_type(UNKNOWN)) # Flatten nested list self._register_builtin("print", [("value", UNKNOWN, None)], BOOL, is_variadic=True) # Phase 3: Numeric aggregation functions self._register_builtin("sum", [ ("values", make_list_type(FLOAT), None), ], FLOAT) # Sum of numeric list self._register_builtin("product", [ ("values", make_list_type(FLOAT), None), ], FLOAT) # Product of numeric list self._register_builtin("any_true", [ ("values", make_list_type(BOOL), None), ], BOOL) # True if any element is true self._register_builtin("all_true", [ ("values", make_list_type(BOOL), None), ], BOOL) # True if all elements are true self._register_builtin("min_of", [ ("values", make_list_type(FLOAT), None), ], FLOAT) # Minimum value in list self._register_builtin("max_of", [ ("values", make_list_type(FLOAT), None), ], FLOAT) # Maximum value in list # Utility self._register_builtin("is_empty", [("s", SOLID, None)], BOOL) self._register_builtin("empty_solid", [], SOLID) self._register_builtin("empty_region", [], REGION2D) def _register_builtin( self, name: str, params: List[Tuple[str, Type, Optional[Any]]], return_type: Type, is_variadic: bool = False ) -> None: """Register a built-in function signature.""" self._builtins[name] = FunctionSignature( name=name, params=params, return_type=return_type, is_variadic=is_variadic )
[docs] def push_scope(self, name: str = "") -> None: """Push a new scope onto the stack.""" new_scope = Scope(parent=self._current_scope, name=name) self._current_scope = new_scope
[docs] def pop_scope(self) -> None: """Pop the current scope.""" if self._current_scope.parent is not None: self._current_scope = self._current_scope.parent
[docs] def define(self, symbol: Symbol) -> bool: """ Define a symbol in the current scope. Returns True if successful, False if already defined in current scope. """ if self._current_scope.lookup_local(symbol.name) is not None: return False self._current_scope.define(symbol) return True
[docs] def lookup(self, name: str) -> Optional[Symbol]: """Look up a symbol in the current scope chain.""" return self._current_scope.lookup(name)
[docs] def lookup_builtin(self, name: str) -> Optional[FunctionSignature]: """Look up a built-in function signature.""" return self._builtins.get(name)
[docs] def is_builtin(self, name: str) -> bool: """Check if a name is a built-in function.""" return name in self._builtins
[docs] def current_scope_name(self) -> str: """Get the name of the current scope (for debugging).""" return self._current_scope.name
[docs] def get_all_builtins(self) -> Dict[str, FunctionSignature]: """Get all registered built-in functions.""" return dict(self._builtins)
# ============================================================================= # Method Signatures for Object Types # ============================================================================= # Methods available on curve types (Tier 2) CURVE_METHODS: Dict[str, FunctionSignature] = { "at": FunctionSignature( name="at", params=[("t", FLOAT, None)], return_type=POINT, is_method=True ), "tangent_at": FunctionSignature( name="tangent_at", params=[("t", FLOAT, None)], return_type=VECTOR, is_method=True ), "normal_at": FunctionSignature( name="normal_at", params=[("t", FLOAT, None)], return_type=VECTOR, is_method=True ), "curvature_at": FunctionSignature( name="curvature_at", params=[("t", FLOAT, None)], return_type=FLOAT, is_method=True ), "length": FunctionSignature( name="length", params=[], return_type=FLOAT, is_method=True ), } # Methods available on solid types (Tier 5) SOLID_METHODS: Dict[str, FunctionSignature] = { "union": FunctionSignature( name="union", params=[("other", SOLID, None)], return_type=SOLID, is_method=True ), "difference": FunctionSignature( name="difference", params=[("other", SOLID, None)], return_type=SOLID, is_method=True ), "intersection": FunctionSignature( name="intersection", params=[("other", SOLID, None)], return_type=SOLID, is_method=True ), "translate": FunctionSignature( name="translate", params=[("v", VECTOR, None)], return_type=SOLID, is_method=True ), "rotate": FunctionSignature( name="rotate", params=[("axis", VECTOR3D, None), ("angle", FLOAT, None)], return_type=SOLID, is_method=True ), "scale": FunctionSignature( name="scale", params=[("factors", VECTOR, None)], return_type=SOLID, is_method=True ), "apply": FunctionSignature( name="apply", params=[("t", TRANSFORM, None)], return_type=SOLID, is_method=True ), } # Methods available on region2d types (Tier 3) REGION2D_METHODS: Dict[str, FunctionSignature] = { "union": FunctionSignature( name="union", params=[("other", REGION2D, None)], return_type=REGION2D, is_method=True ), "difference": FunctionSignature( name="difference", params=[("other", REGION2D, None)], return_type=REGION2D, is_method=True ), "intersection": FunctionSignature( name="intersection", params=[("other", REGION2D, None)], return_type=REGION2D, is_method=True ), } # Methods available on transform types TRANSFORM_METHODS: Dict[str, FunctionSignature] = { "compose": FunctionSignature( name="compose", params=[("other", TRANSFORM, None)], return_type=TRANSFORM, is_method=True ), "inverse": FunctionSignature( name="inverse", params=[], return_type=TRANSFORM, is_method=True ), "translation": FunctionSignature( name="translation", params=[], return_type=VECTOR3D, is_method=True ), "is_rigid": FunctionSignature( name="is_rigid", params=[], return_type=BOOL, is_method=True ), }
[docs] def get_method_signature(obj_type: Type, method_name: str) -> Optional[FunctionSignature]: """Get the method signature for a type, if it exists.""" from .types import is_curve, is_solid, is_compound_curve if is_curve(obj_type): return CURVE_METHODS.get(method_name) if is_solid(obj_type): return SOLID_METHODS.get(method_name) if is_compound_curve(obj_type) and obj_type.name == "region2d": return REGION2D_METHODS.get(method_name) if obj_type.name == "transform": return TRANSFORM_METHODS.get(method_name) return None