yapcad.dsl package
Subpackages
- yapcad.dsl.runtime package
- Submodules
- yapcad.dsl.runtime.builtins module
- yapcad.dsl.runtime.context module
ExecutionContextExecutionContext.add_error()ExecutionContext.add_require_failure()ExecutionContext.add_warning()ExecutionContext.clear_return()ExecutionContext.command_nameExecutionContext.current_scopeExecutionContext.diagnosticsExecutionContext.emit_resultExecutionContext.get_variable()ExecutionContext.has_errorsExecutionContext.has_warningsExecutionContext.module_nameExecutionContext.new_scope()ExecutionContext.parametersExecutionContext.require_failuresExecutionContext.return_valueExecutionContext.set_emit()ExecutionContext.set_variable()ExecutionContext.should_returnExecutionContext.signal_return()ExecutionContext.source_linesExecutionContext.update_variable()
Scopecreate_context()
- yapcad.dsl.runtime.interpreter module
- yapcad.dsl.runtime.provenance module
- yapcad.dsl.runtime.values module
EmitResultRequireFailureValuebool_val()check_type()coerce_numeric()dict_val()edge_list_val()float_val()int_val()list_val()none_val()path3d_val()point_val()region2d_val()shell_val()solid_val()string_val()surface_val()transform_val()unwrap_value()unwrap_values()vector_val()wrap_value()
- Module contents
BuiltinFunctionBuiltinRegistryEmitResultExecutionContextExecutionContext.add_error()ExecutionContext.add_require_failure()ExecutionContext.add_warning()ExecutionContext.clear_return()ExecutionContext.command_nameExecutionContext.current_scopeExecutionContext.diagnosticsExecutionContext.emit_resultExecutionContext.get_variable()ExecutionContext.has_errorsExecutionContext.has_warningsExecutionContext.module_nameExecutionContext.new_scope()ExecutionContext.parametersExecutionContext.require_failuresExecutionContext.return_valueExecutionContext.set_emit()ExecutionContext.set_variable()ExecutionContext.should_returnExecutionContext.signal_return()ExecutionContext.source_linesExecutionContext.update_variable()
ExecutionResultInterpreterProvenanceRequireFailureScopeValuebool_val()call_builtin()call_method()check_type()coerce_numeric()compile_and_run()compute_source_signature()create_context()create_provenance()dict_val()execute()float_val()get_builtin_registry()int_val()list_val()none_val()point_val()region2d_val()shell_val()solid_val()string_val()surface_val()transform_val()unwrap_value()unwrap_values()vector_val()verify_source_signature()wrap_value()
- yapcad.dsl.transforms package
- Submodules
- yapcad.dsl.transforms.base module
AstTransformIdentityTransformTransformPipelineTreeTransformTreeTransform.transform()TreeTransform.visit_assignment()TreeTransform.visit_binary_op()TreeTransform.visit_block()TreeTransform.visit_command()TreeTransform.visit_dict_literal()TreeTransform.visit_emit()TreeTransform.visit_expr_statement()TreeTransform.visit_expression()TreeTransform.visit_for()TreeTransform.visit_function_call()TreeTransform.visit_identifier()TreeTransform.visit_if_expr()TreeTransform.visit_index_access()TreeTransform.visit_lambda()TreeTransform.visit_let()TreeTransform.visit_list_comprehension()TreeTransform.visit_list_literal()TreeTransform.visit_literal()TreeTransform.visit_match_expr()TreeTransform.visit_member_access()TreeTransform.visit_method_call()TreeTransform.visit_module()TreeTransform.visit_python_block()TreeTransform.visit_python_expr()TreeTransform.visit_range()TreeTransform.visit_require()TreeTransform.visit_return()TreeTransform.visit_statement()TreeTransform.visit_unary_op()
- Module contents
AstTransformIdentityTransformTransformPipelineTreeTransformTreeTransform.transform()TreeTransform.visit_assignment()TreeTransform.visit_binary_op()TreeTransform.visit_block()TreeTransform.visit_command()TreeTransform.visit_dict_literal()TreeTransform.visit_emit()TreeTransform.visit_expr_statement()TreeTransform.visit_expression()TreeTransform.visit_for()TreeTransform.visit_function_call()TreeTransform.visit_identifier()TreeTransform.visit_if_expr()TreeTransform.visit_index_access()TreeTransform.visit_lambda()TreeTransform.visit_let()TreeTransform.visit_list_comprehension()TreeTransform.visit_list_literal()TreeTransform.visit_literal()TreeTransform.visit_match_expr()TreeTransform.visit_member_access()TreeTransform.visit_method_call()TreeTransform.visit_module()TreeTransform.visit_python_block()TreeTransform.visit_python_expr()TreeTransform.visit_range()TreeTransform.visit_require()TreeTransform.visit_return()TreeTransform.visit_statement()TreeTransform.visit_unary_op()
Submodules
yapcad.dsl.ast module
Abstract Syntax Tree (AST) node definitions for the yapCAD DSL v2 (Pythonic Syntax).
The AST represents the structure of a parsed DSL program, which can then be type-checked and compiled/interpreted.
Changes from v1: - FunctionDef replaces Command (uses ‘def’ keyword) - VarDecl replaces LetStatement (no ‘let’ keyword, optional type annotation) - AssertStatement replaces RequireStatement - NativeFunction for @native decorated functions - Added PassStatement, WhileStatement, ElifBranch
- class yapcad.dsl.ast.AssertStatement(span: SourceSpan, condition: Expression, message: Expression | None = None)[source]
Bases:
StatementAn assert statement (e.g., assert x > 0, “x must be positive”).
- condition: Expression
- message: Expression | None = None
- class yapcad.dsl.ast.AssignmentStatement(span: SourceSpan, target: Expression, value: Expression)[source]
Bases:
StatementAn assignment to an existing variable (e.g., x = 5).
- target: Expression
- value: Expression
- class yapcad.dsl.ast.AstNode(span: SourceSpan)[source]
Bases:
ABCBase class for all AST nodes.
- accept(visitor: AstVisitor) Any[source]
Accept a visitor for traversal.
- span: SourceSpan
- class yapcad.dsl.ast.BinaryOp(span: SourceSpan, left: Expression, operator: TokenType, right: Expression)[source]
Bases:
ExpressionA binary operation (e.g., a + b, x and y).
- left: Expression
- right: Expression
- class yapcad.dsl.ast.Block(span: SourceSpan, statements: List[Statement], final_expression: Expression | None = None)[source]
Bases:
AstNodeA block of statements (indented block).
In Pythonic syntax, blocks are delimited by indentation (INDENT/DEDENT) rather than braces.
- final_expression: Expression | None = None
- yapcad.dsl.ast.Command
alias of
FunctionDef
- class yapcad.dsl.ast.ComprehensionClause(span: SourceSpan, variable: str, iterable: Expression, conditions: List[Expression] = <factory>)[source]
Bases:
AstNodeA single for clause in a list comprehension.
Represents: for variable in iterable [if condition1] [if condition2] …
Multiple if conditions are allowed per clause, all must be true.
- conditions: List[Expression]
- iterable: Expression
- class yapcad.dsl.ast.ConditionalExpr(span: SourceSpan, condition: Expression, true_branch: Expression, false_branch: Expression)[source]
Bases:
ExpressionA ternary conditional expression (e.g., x if condition else y).
- Unlike IfExpr (which uses blocks), this is for inline expressions:
value: float = a if condition else b
Both branches must be expressions and the else is required.
- condition: Expression
- false_branch: Expression
- true_branch: Expression
- class yapcad.dsl.ast.Decorator(span: SourceSpan, name: str, arguments: List[Expression] = <factory>)[source]
Bases:
AstNodeA decorator (e.g., @native).
- arguments: List[Expression]
- class yapcad.dsl.ast.DictLiteral(span: SourceSpan, entries: dict[str, Expression])[source]
Bases:
ExpressionA dictionary literal (e.g., {“key”: value, …}).
- entries: dict[str, Expression]
- class yapcad.dsl.ast.ElifBranch(span: SourceSpan, condition: Expression, body: Block)[source]
Bases:
AstNodeAn elif branch in an if expression/statement.
- condition: Expression
- class yapcad.dsl.ast.EmitStatement(span: SourceSpan, value: Expression, metadata: dict[str, ~yapcad.dsl.ast.Expression]=<factory>)[source]
Bases:
StatementAn emit statement with optional metadata kwargs.
- Syntax:
emit gear # Simple emit emit gear, name=”spur”, material=”steel” # With metadata
- metadata: dict[str, Expression]
- value: Expression
- class yapcad.dsl.ast.ExportStatement(span: SourceSpan, name: str)[source]
Bases:
AstNodeAn export statement (e.g., export function_name).
- class yapcad.dsl.ast.ExportUseStatement(span: SourceSpan, module_path: List[str])[source]
Bases:
AstNodeAn export use statement (e.g., export use other.module).
- class yapcad.dsl.ast.Expression(span: SourceSpan)[source]
Bases:
AstNodeBase class for all expressions.
- class yapcad.dsl.ast.ExpressionStatement(span: SourceSpan, expression: Expression)[source]
Bases:
StatementAn expression used as a statement.
- expression: Expression
- class yapcad.dsl.ast.ForStatement(span: SourceSpan, variable: str, iterable: Expression, body: Block)[source]
Bases:
StatementA for loop (e.g., for i in range(n):).
- iterable: Expression
- class yapcad.dsl.ast.FunctionCall(span: ~yapcad.dsl.tokens.SourceSpan, callee: ~yapcad.dsl.ast.Expression, arguments: ~typing.List[~yapcad.dsl.ast.Expression], named_arguments: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]
Bases:
ExpressionA function or constructor call (e.g., point(1, 2, 3)).
- arguments: List[Expression]
- callee: Expression
- named_arguments: dict[str, Expression]
- class yapcad.dsl.ast.FunctionDef(span: ~yapcad.dsl.tokens.SourceSpan, name: str, parameters: ~typing.List[~yapcad.dsl.ast.Parameter], return_type: ~yapcad.dsl.ast.TypeNode | None, body: ~yapcad.dsl.ast.Block, decorators: ~typing.List[~yapcad.dsl.ast.Decorator] = <factory>)[source]
Bases:
AstNodeA function definition (uses ‘def’ keyword).
- Syntax:
- def function_name(param1: type1, param2: type2) -> return_type:
…
Replaces the old ‘command’ syntax.
- class yapcad.dsl.ast.GenericType(span: SourceSpan, name: str, type_args: List[TypeNode])[source]
Bases:
TypeNodeA generic type like ‘list[point3d]’ or ‘dict[str, int]’.
- class yapcad.dsl.ast.Identifier(span: SourceSpan, name: str)[source]
Bases:
ExpressionA variable or function name reference.
- class yapcad.dsl.ast.IdentifierPattern(span: SourceSpan, name: str)[source]
Bases:
PatternA binding pattern (e.g., ‘match x { case n: … }’).
- class yapcad.dsl.ast.IfExpr(span: SourceSpan, condition: Expression, then_branch: Block, elif_branches: List[ElifBranch] = <factory>, else_branch: Block | None = None)[source]
Bases:
ExpressionAn if-else expression (returns a value).
- condition: Expression
- elif_branches: List[ElifBranch]
- class yapcad.dsl.ast.IfStatement(span: SourceSpan, condition: Expression, then_branch: Block, elif_branches: List[ElifBranch] = <factory>, else_branch: Block | None = None)[source]
Bases:
StatementAn if statement (doesn’t return a value).
- Syntax:
- if condition:
…
- elif condition:
…
- else:
…
- condition: Expression
- elif_branches: List[ElifBranch]
- class yapcad.dsl.ast.IndexAccess(span: SourceSpan, object: Expression, index: Expression)[source]
Bases:
ExpressionIndex access (e.g., list[0]).
- index: Expression
- object: Expression
- class yapcad.dsl.ast.LambdaExpr(span: SourceSpan, parameters: List[str], body: Expression)[source]
Bases:
ExpressionA lambda/anonymous function (e.g., (x) => x * 2).
- body: Expression
- class yapcad.dsl.ast.ListComprehension(span: SourceSpan, element_expr: Expression, clauses: List[ComprehensionClause] = <factory>)[source]
Bases:
ExpressionA list comprehension with one or more for clauses.
- Single clause (original):
[f(x) for x in items if cond]
- Multiple clauses (nested):
[f(x, y) for x in xs for y in ys] [f(x, y) for x in xs for y in ys if x < y] [f(x, y) for x in xs if x > 0 for y in ys if y < 10]
The clauses are evaluated left-to-right as nested loops.
- clauses: List[ComprehensionClause]
- property condition: Expression | None
Get first condition (for single-clause compatibility).
- element_expr: Expression
- classmethod from_single(span: SourceSpan, element_expr: Expression, variable: str, iterable: Expression, condition: Expression | None = None) ListComprehension[source]
Create a single-clause comprehension (backward compatibility).
- property iterable: Expression
Get iterable (for single-clause compatibility).
- class yapcad.dsl.ast.ListLiteral(span: SourceSpan, elements: List[Expression])[source]
Bases:
ExpressionA list literal (e.g., [1, 2, 3]).
- elements: List[Expression]
- class yapcad.dsl.ast.Literal(span: SourceSpan, value: int | float | str | bool, literal_type: TokenType)[source]
Bases:
ExpressionA literal value (int, float, string, bool).
- class yapcad.dsl.ast.LiteralPattern(span: SourceSpan, value: Literal)[source]
Bases:
PatternA literal pattern (e.g., ‘match x { case 42: … }’).
- class yapcad.dsl.ast.MatchArm(span: SourceSpan, pattern: Pattern, body: Expression)[source]
Bases:
AstNodeA single arm of a match expression.
- body: Expression
- class yapcad.dsl.ast.MatchExpr(span: SourceSpan, subject: Expression, arms: List[MatchArm])[source]
Bases:
ExpressionA match expression.
- subject: Expression
- class yapcad.dsl.ast.MemberAccess(span: SourceSpan, object: Expression, member: str)[source]
Bases:
ExpressionMember access (e.g., point.x).
- object: Expression
- class yapcad.dsl.ast.MethodCall(span: ~yapcad.dsl.tokens.SourceSpan, object: ~yapcad.dsl.ast.Expression, method: str, arguments: ~typing.List[~yapcad.dsl.ast.Expression], named_arguments: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]
Bases:
ExpressionA method call (e.g., curve.at(0.5)).
- arguments: List[Expression]
- named_arguments: dict[str, Expression]
- object: Expression
- class yapcad.dsl.ast.Module(span: SourceSpan, name: str | None, uses: List[UseStatement | ExportUseStatement] = <factory>, native_blocks: List[NativeBlock] = <factory>, native_functions: List[NativeFunction] = <factory>, functions: List[FunctionDef] = <factory>, exports: List[ExportStatement] = <factory>)[source]
Bases:
AstNodeA complete DSL module.
- Syntax:
module module_name
use other.module
@native def native_func(…):
…
- def my_function(…):
…
- property commands: List[FunctionDef]
Backward compatibility alias for functions.
- exports: List[ExportStatement]
- functions: List[FunctionDef]
- native_blocks: List[NativeBlock]
- native_functions: List[NativeFunction]
- uses: List[UseStatement | ExportUseStatement]
- class yapcad.dsl.ast.NativeBlock(span: SourceSpan, code: str, exports: List[NativeFunctionDecl])[source]
Bases:
AstNodeA native Python block with exported function declarations (legacy).
- Syntax:
- native python {
# Python code here
- } exports {
fn func_name(param: type) -> return_type;
}
The Python code is executed to define functions, which are then made available to the DSL with the declared type signatures.
Note: This is the legacy syntax. New code should use @native decorator.
- exports: List[NativeFunctionDecl]
- class yapcad.dsl.ast.NativeFunction(span: SourceSpan, name: str, parameters: List[Parameter], return_type: TypeNode, python_code: str)[source]
Bases:
AstNodeA native function (Python code with DSL type signature).
- Syntax:
@native def function_name(param1: type1, param2: type2) -> return_type:
‘’’Python code here’’’ …
The function body contains Python code that is executed directly.
- class yapcad.dsl.ast.NativeFunctionDecl(span: SourceSpan, name: str, parameters: List[Parameter], return_type: TypeNode)[source]
Bases:
AstNodeA function declaration in a native block’s exports section (legacy).
Represents: fn name(param1: type1, param2: type2) -> return_type;
- class yapcad.dsl.ast.OptionalType(span: SourceSpan, inner: TypeNode)[source]
Bases:
TypeNodeAn optional type, e.g., ‘point3d?’.
- class yapcad.dsl.ast.Parameter(span: SourceSpan, name: str, type_annotation: TypeNode | None = None, default_value: Expression | None = None)[source]
Bases:
AstNodeA function parameter.
- default_value: Expression | None = None
- class yapcad.dsl.ast.PassStatement(span: SourceSpan)[source]
Bases:
StatementA pass statement (placeholder for empty blocks).
- class yapcad.dsl.ast.Pattern(span: SourceSpan)[source]
Bases:
AstNodeBase class for match patterns.
- class yapcad.dsl.ast.PrintVisitor(indent: int = 0)[source]
Bases:
AstVisitorDebug visitor that prints the AST structure.
- class yapcad.dsl.ast.PythonBlock(span: SourceSpan, code: str)[source]
Bases:
StatementAn inline Python block (legacy support).
- class yapcad.dsl.ast.PythonExpr(span: SourceSpan, code: str, return_type: TypeNode)[source]
Bases:
ExpressionA python block that returns a value (legacy support).
- class yapcad.dsl.ast.RangeExpr(span: SourceSpan, start: Expression, end: Expression, step: Expression | None = None)[source]
Bases:
ExpressionA range expression (e.g., 0..10 or range(10)).
- end: Expression
- start: Expression
- step: Expression | None = None
- yapcad.dsl.ast.RequireStatement
alias of
AssertStatement
- class yapcad.dsl.ast.ReturnStatement(span: SourceSpan, value: Expression | None = None)[source]
Bases:
StatementA return statement.
- value: Expression | None = None
- class yapcad.dsl.ast.SimpleType(span: SourceSpan, name: str)[source]
Bases:
TypeNodeA simple type like ‘int’, ‘float’, ‘solid’, etc.
- class yapcad.dsl.ast.Statement(span: SourceSpan)[source]
Bases:
AstNodeBase class for all statements.
- class yapcad.dsl.ast.TypeNode(span: SourceSpan)[source]
Bases:
AstNodeBase class for type annotations.
- class yapcad.dsl.ast.UnaryOp(span: SourceSpan, operator: TokenType, operand: Expression)[source]
Bases:
ExpressionA unary operation (e.g., not x, -n).
- operand: Expression
- class yapcad.dsl.ast.UseStatement(span: SourceSpan, module_path: List[str], alias: str | None = None)[source]
Bases:
AstNodeA use/import statement (e.g., use yapcad.stdlib.transforms).
- Syntax:
use module.path use module.path as alias use module.path.{item1, item2} # (future: selective imports)
- class yapcad.dsl.ast.VarDecl(span: SourceSpan, name: str, type_annotation: TypeNode | None, initializer: Expression | None)[source]
Bases:
StatementA variable declaration (Pythonic style, no ‘let’ keyword).
- Syntax options:
x = 42 # Type inferred x: int = 42 # Explicit type x: int # Declaration without initialization (rare)
- initializer: Expression | None
- class yapcad.dsl.ast.WhileStatement(span: SourceSpan, condition: Expression, body: Block)[source]
Bases:
StatementA while loop (e.g., while condition:).
- condition: Expression
- class yapcad.dsl.ast.WildcardPattern(span: SourceSpan)[source]
Bases:
PatternThe wildcard pattern ‘_’.
yapcad.dsl.checker module
Type checker for the yapCAD DSL.
Traverses the AST and validates types, collecting diagnostics for type errors, undefined identifiers, and other semantic issues.
- class yapcad.dsl.checker.CheckResult(diagnostics: List[Diagnostic], has_errors: bool, has_warnings: bool, has_python_blocks: bool)[source]
Bases:
objectResult of type checking a module.
- diagnostics: List[Diagnostic]
- class yapcad.dsl.checker.TypeChecker(max_errors: int = 20)[source]
Bases:
objectType checker for the yapCAD DSL.
Traverses the AST and validates: - Type compatibility in assignments and function calls - Return type matching - Require expression boolean constraint - Emit target type matching command return type - Undefined identifier detection - Python block flagging
- check(module: Module) CheckResult[source]
Type check a complete module.
- yapcad.dsl.checker.check(module: Module, max_errors: int = 20) CheckResult[source]
Convenience function to type check a module.
- Parameters:
module – The parsed module AST
max_errors – Maximum errors before stopping (default 20)
- Returns:
CheckResult with diagnostics
yapcad.dsl.errors module
DSL-specific exceptions and error handling.
Error code ranges (from Phase 3 roadmap): - E0xx: Lexer errors - E1xx: Parser errors - E2xx: Type errors - E3xx: Semantic errors
- class yapcad.dsl.errors.Diagnostic(code: str, message: str, severity: ErrorSeverity, span: SourceSpan, source_line: str | None = None, hints: List[str] = <factory>, related: List[Diagnostic] = <factory>)[source]
Bases:
objectA single diagnostic message (error, warning, etc.).
- severity: ErrorSeverity
- span: SourceSpan
- class yapcad.dsl.errors.DiagnosticCollector(max_errors: int = 20)[source]
Bases:
objectCollects diagnostics during compilation.
- add(diagnostic: Diagnostic) None[source]
Add a diagnostic.
- diagnostics: List[Diagnostic]
- exception yapcad.dsl.errors.DslError(diagnostic: Diagnostic)[source]
Bases:
ExceptionBase exception for DSL errors.
- class yapcad.dsl.errors.ErrorSeverity(*values)[source]
Bases:
EnumSeverity levels for diagnostics.
- ERROR = 'error'
- HINT = 'hint'
- INFO = 'info'
- WARNING = 'warning'
- exception yapcad.dsl.errors.LexerError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during lexical analysis (E0xx).
- exception yapcad.dsl.errors.ParserError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during parsing (E1xx).
- exception yapcad.dsl.errors.SemanticError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during semantic analysis (E3xx).
- exception yapcad.dsl.errors.TypeError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during type checking (E2xx).
- yapcad.dsl.errors.error_invalid_binary_literal(text: str, span: SourceSpan, source_line: str = None) LexerError[source]
E008: Invalid binary literal.
- yapcad.dsl.errors.error_invalid_escape_sequence(seq: str, span: SourceSpan, source_line: str = None) LexerError[source]
E005: Invalid escape sequence in string.
- yapcad.dsl.errors.error_invalid_expression(span: SourceSpan, source_line: str = None) ParserError[source]
E103: Invalid expression.
- yapcad.dsl.errors.error_invalid_hex_literal(text: str, span: SourceSpan, source_line: str = None) LexerError[source]
E007: Invalid hexadecimal literal.
- yapcad.dsl.errors.error_invalid_number_literal(text: str, span: SourceSpan, source_line: str = None) LexerError[source]
E006: Invalid number literal.
- yapcad.dsl.errors.error_require_failed(message: str, span: SourceSpan, source_line: str = None) SemanticError[source]
E301: Require constraint failed.
- yapcad.dsl.errors.error_type_mismatch(expected: str, found: str, span: SourceSpan, source_line: str = None) TypeError[source]
E201: Type mismatch.
- yapcad.dsl.errors.error_undefined_identifier(name: str, span: SourceSpan, source_line: str = None) TypeError[source]
E202: Undefined identifier.
- yapcad.dsl.errors.error_unexpected_character(char: str, span: SourceSpan, source_line: str = None) LexerError[source]
E001: Unexpected character.
- yapcad.dsl.errors.error_unexpected_eof(expected: str, span: SourceSpan) ParserError[source]
E102: Unexpected end of file.
- yapcad.dsl.errors.error_unexpected_token(expected: str, found: str, span: SourceSpan, source_line: str = None) ParserError[source]
E101: Unexpected token.
- yapcad.dsl.errors.error_unterminated_comment(span: SourceSpan, source_line: str = None) LexerError[source]
E004: Unterminated multi-line comment.
- yapcad.dsl.errors.error_unterminated_multiline_string(span: SourceSpan, source_line: str = None) LexerError[source]
E003: Unterminated multi-line string.
- yapcad.dsl.errors.error_unterminated_string(span: SourceSpan, source_line: str = None) LexerError[source]
E002: Unterminated string literal.
- yapcad.dsl.errors.warning_python_block(span: SourceSpan, source_line: str = None) Diagnostic[source]
W001: Python block requires manual approval.
yapcad.dsl.introspection module
DSL Introspection API for agentic engineering tools.
This module provides programmatic access to the yapCAD DSL’s type system, built-in functions, and methods. It’s designed to be queried by AI agents and other tools that need to understand the DSL’s capabilities.
- Usage:
- from yapcad.dsl.introspection import (
get_api_reference, get_function_info, get_type_info, list_functions, list_types, describe_function,
)
# Get complete API reference as a dictionary api = get_api_reference()
# Get info about a specific function info = get_function_info(“box”) print(info[“signature”]) # “box(width: float, depth: float, height: float) -> solid”
# List all available functions for name in list_functions():
print(name)
- yapcad.dsl.introspection.describe_function(name: str) str[source]
Get a human-readable description of a function.
- Parameters:
name – The function name
- Returns:
Formatted description string
- yapcad.dsl.introspection.get_api_as_json() str[source]
Get the complete API reference as a JSON string.
Useful for tools that prefer to parse JSON directly.
- yapcad.dsl.introspection.get_api_reference() Dict[str, Any][source]
Get the complete API reference as a dictionary.
Returns a dictionary with: - types: All available types with descriptions - functions: All built-in functions with signatures and descriptions - methods: Type-specific methods organized by receiver type
This is the primary entry point for agentic tools to understand the DSL’s capabilities.
- yapcad.dsl.introspection.get_common_pattern(name: str) str | None[source]
Get a common DSL pattern/example.
- Parameters:
name – Pattern name (e.g., “boolean_subtraction”, “gear_creation”)
- Returns:
DSL code example or None if pattern not found
- yapcad.dsl.introspection.get_function_info(name: str) Dict[str, Any] | None[source]
Get detailed information about a specific function.
- Parameters:
name – The function name
- Returns:
Dictionary with signature, description, example, etc. Returns None if function not found.
- yapcad.dsl.introspection.get_methods_for_type(type_name: str) Dict[str, Dict[str, Any]][source]
Get all methods available on a given type.
- Parameters:
type_name – The type name (e.g., “solid”, “curve”, “region2d”)
- Returns:
Dictionary mapping method names to their signatures
- yapcad.dsl.introspection.get_type_info(name: str) Dict[str, Any] | None[source]
Get information about a type.
- Parameters:
name – The type name
- Returns:
Dictionary with tier, description, constructor info. Returns None if type not found.
- yapcad.dsl.introspection.list_common_patterns() List[str][source]
List all available common pattern names.
yapcad.dsl.lexer module
Lexer for the yapCAD DSL v2 (Pythonic Syntax).
Converts source text into a stream of tokens for the parser. Supports: - Python-style indentation (INDENT/DEDENT tokens) - Significant newlines (NEWLINE tokens) - Implicit line continuation inside brackets - Single-line comments (#) - Multi-line comments (/* */) - String literals with escape sequences - Multi-line strings (triple quotes) - Integer literals (decimal, hex, binary) - Float literals (including scientific notation) - All DSL keywords and operators
- class yapcad.dsl.lexer.Lexer(source: str, filename: str | None = None)[source]
Bases:
objectTokenizer for the yapCAD DSL v2 with Python-style indentation.
This lexer generates INDENT and DEDENT tokens based on changes in leading whitespace, similar to Python’s tokenizer.
- Usage:
lexer = Lexer(source_code) tokens = lexer.tokenize()
- Or for streaming:
lexer = Lexer(source_code) for token in lexer:
process(token)
yapcad.dsl.packaging module
DSL-to-Package integration.
Provides functions to compile DSL source, execute commands, and package the resulting geometry with full provenance tracking.
- class yapcad.dsl.packaging.PackageResult(*, success: bool, manifest: 'PackageManifest' | None = None, execution_result: ExecutionResult | None = None, error_message: str | None = None)[source]
Bases:
objectResult of DSL-to-package operation.
- yapcad.dsl.packaging.package_from_dsl(source: str, command_name: str, parameters: Dict[str, Any], target_dir: Path | str, *, name: str, version: str, description: str | None = None, author: str | None = None, units: str | None = None, materials: Dict[str, Dict[str, Any]] | None = None, overwrite: bool = False) PackageResult[source]
Compile DSL source, execute a command, and package the result.
This is a high-level function that combines DSL compilation, execution, and packaging into a single workflow. The resulting package includes full provenance metadata linking it to the original DSL source.
- Parameters:
source – DSL source code containing the module and command definitions.
command_name – Name of the command to execute (e.g., “MAKE_GEAR”).
parameters – Dictionary of parameter values for the command.
target_dir – Directory where the package will be created.
name – Name for the package (used in manifest).
version – Version string for the package.
description – Optional description for the package.
author – Optional author name.
units – Unit system (default “mm”).
materials – Optional materials dictionary for the package.
overwrite – If True, overwrite existing package directory.
- Returns:
PackageResult with success status, manifest, and any error info.
Example
>>> source = ''' ... module gear_design; ... ... command MAKE_GEAR(teeth: int, module_mm: float) -> solid { ... let pitch_diameter: float = teeth * module_mm; ... let gear: solid = cylinder(pitch_diameter / 2.0, 10.0); ... emit gear; ... } ... ''' >>> result = package_from_dsl( ... source, ... "MAKE_GEAR", ... {"teeth": 24, "module_mm": 2.0}, ... "output/gear_pkg", ... name="gear_24t", ... version="1.0.0", ... ) >>> if result.success: ... print(f"Package created at {result.manifest.root}")
yapcad.dsl.parser module
Recursive descent parser for the yapCAD DSL v2 (Pythonic Syntax).
Converts a token stream into an Abstract Syntax Tree (AST). Supports Python-style indentation-based blocks.
- class yapcad.dsl.parser.Parser(tokens: List[Token], filename: str | None = None, source: str | None = None)[source]
Bases:
objectRecursive descent parser for the yapCAD DSL v2 with Python-style indentation.
- Usage:
parser = Parser(tokens) module = parser.parse_module()
- The parser implements standard precedence climbing for expressions:
- Lowest: or
and == != < > <= >= + - * / // %
- Highest: ** (power, right-associative)
unary (not -)
- PRECEDENCE = {TokenType.AND: 2, TokenType.DOUBLE_SLASH: 6, TokenType.DOUBLE_STAR: 7, TokenType.EQ: 3, TokenType.GE: 4, TokenType.GT: 4, TokenType.LE: 4, TokenType.LT: 4, TokenType.MINUS: 5, TokenType.NE: 3, TokenType.OR: 1, TokenType.PERCENT: 6, TokenType.PLUS: 5, TokenType.SLASH: 6, TokenType.STAR: 6}
- RIGHT_ASSOCIATIVE = {TokenType.DOUBLE_STAR}
- yapcad.dsl.parser.parse(tokens: List[Token], filename: str | None = None, source: str | None = None) Module[source]
Convenience function to parse tokens into a module.
- Parameters:
tokens – List of tokens from the lexer
filename – Optional filename for error messages
source – Optional original source code for extracting raw text
- Returns:
Parsed Module AST
- Raises:
ParserError – If parsing fails
yapcad.dsl.symbols module
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.
- class yapcad.dsl.symbols.FunctionSignature(name: str, params: List[Tuple[str, Type, Any | None]], return_type: Type, is_method: bool = False, is_variadic: bool = False)[source]
Bases:
objectType signature for a function or built-in.
- class yapcad.dsl.symbols.Scope(symbols: Dict[str, ~yapcad.dsl.symbols.Symbol]=<factory>, parent: Scope | None = None, name: str = '')[source]
Bases:
objectA single scope in the scope stack.
- class yapcad.dsl.symbols.Symbol(name: str, kind: SymbolKind, type: Type, span: SourceSpan | None = None, is_mutable: bool = False, has_python_block: bool = False)[source]
Bases:
objectA symbol in the symbol table.
- kind: SymbolKind
- span: SourceSpan | None = None
- class yapcad.dsl.symbols.SymbolKind(*values)[source]
Bases:
EnumThe kind of symbol being tracked.
- COMMAND = 4
- FUNCTION = 3
- MODULE = 5
- PARAMETER = 2
- VARIABLE = 1
- class yapcad.dsl.symbols.SymbolTable[source]
Bases:
objectManages scopes and symbol definitions for type checking.
Provides: - Nested scope management (push/pop) - Symbol definition and lookup - Built-in function registry
- define(symbol: Symbol) bool[source]
Define a symbol in the current scope.
Returns True if successful, False if already defined in current scope.
- get_all_builtins() Dict[str, FunctionSignature][source]
Get all registered built-in functions.
- lookup_builtin(name: str) FunctionSignature | None[source]
Look up a built-in function signature.
yapcad.dsl.tokens module
Token types for the yapCAD DSL lexer.
yapCAD DSL v2 - Pythonic Syntax
Token type categories follow error code ranges from the roadmap: - E0xx: Lexer errors - E1xx: Parser errors - E2xx: Type errors - E3xx: Semantic errors
- class yapcad.dsl.tokens.SourceLocation(line: int, column: int, offset: int, filename: str | None = None)[source]
Bases:
objectRepresents a position in source code.
- class yapcad.dsl.tokens.SourceSpan(start: SourceLocation, end: SourceLocation)[source]
Bases:
objectRepresents a range in source code.
- end: SourceLocation
- start: SourceLocation
- class yapcad.dsl.tokens.Token(type: TokenType, value: Any, lexeme: str, span: SourceSpan)[source]
Bases:
objectA single token from the lexer.
- span: SourceSpan
- class yapcad.dsl.tokens.TokenType(*values)[source]
Bases:
EnumAll token types recognized by the DSL lexer.
- AND = 76
- ARROW = 92
- AS = 19
- ASSERT = 17
- ASSIGN = 79
- AT = 97
- BOOL_LITERAL = 4
- CLOSE = 30
- CLOSE_C0 = 31
- CLOSE_C1 = 32
- COLON = 88
- COMMA = 90
- COMMAND = 23
- DEDENT = 100
- DEF = 8
- DOT = 91
- DOUBLE_ARROW = 93
- DOUBLE_SLASH = 67
- DOUBLE_STAR = 69
- ELIF = 12
- ELSE = 13
- EMIT = 10
- EOF = 102
- EQ = 74
- EXPORT = 21
- EXPORTS = 29
- FLOAT_LITERAL = 2
- FN = 28
- FOR = 14
- GE = 73
- GT = 71
- HASH = 98
- IDENTIFIER = 5
- IF = 11
- IN = 15
- INDENT = 99
- INT_LITERAL = 1
- LBRACE = 82
- LBRACKET = 86
- LE = 72
- LET = 24
- LPAREN = 84
- LT = 70
- MATCH = 20
- MINUS = 64
- MINUS_ASSIGN = 81
- MODULE = 6
- NATIVE = 22
- NATIVE_BLOCK = 103
- NE = 75
- NEWLINE = 101
- NOT = 78
- OR = 77
- PASS = 18
- PERCENT = 68
- PLUS = 63
- PLUS_ASSIGN = 80
- PYTHON = 27
- QUESTION = 95
- RANGE = 94
- RBRACE = 83
- RBRACKET = 87
- REQUIRE = 25
- RETURN = 9
- RPAREN = 85
- SEMICOLON = 89
- SLASH = 66
- STAR = 65
- STRING_LITERAL = 3
- TYPE_ARC = 45
- TYPE_BEZIER = 52
- TYPE_BOOL = 36
- TYPE_CATMULLROM = 50
- TYPE_CIRCLE = 46
- TYPE_DICT = 62
- TYPE_ELLIPSE = 47
- TYPE_FLOAT = 34
- TYPE_HYPERBOLA = 49
- TYPE_INT = 33
- TYPE_LINE_SEGMENT = 44
- TYPE_LIST = 61
- TYPE_LOOP3D = 57
- TYPE_NURBS = 51
- TYPE_PARABOLA = 48
- TYPE_PATH2D = 53
- TYPE_PATH3D = 54
- TYPE_POINT = 37
- TYPE_POINT2D = 38
- TYPE_POINT3D = 39
- TYPE_PROFILE2D = 55
- TYPE_REGION2D = 56
- TYPE_SHELL = 59
- TYPE_SOLID = 60
- TYPE_STRING = 35
- TYPE_SURFACE = 58
- TYPE_TRANSFORM = 43
- TYPE_VECTOR = 40
- TYPE_VECTOR2D = 41
- TYPE_VECTOR3D = 42
- UNDERSCORE = 96
- USE = 7
- WHILE = 16
- WITH = 26
- yapcad.dsl.tokens.get_deprecation_message(keyword: str) str | None[source]
Get the deprecation message for a keyword, if any.
yapcad.dsl.types module
Type system definitions for the yapCAD DSL.
- The type system is organized into five tiers:
Tier 1: Primitives (int, float, bool, string, point, vector, transform) Tier 2: Curve Primitives (line_segment, arc, circle, bezier, nurbs, etc.) Tier 3: Compound Curves (path2d, path3d, profile2d, region2d, loop3d) Tier 4: Surfaces (surface, shell) Tier 5: Solids (solid)
Plus generic types: list<T>, dict
- class yapcad.dsl.types.CompoundCurveType(_name: str)[source]
Bases:
TypeA Tier 3 compound curve type (paths, profiles, regions).
- class yapcad.dsl.types.ErrorType[source]
Bases:
TypeA type representing a type error (prevents cascading errors).
- class yapcad.dsl.types.FunctionType(param_types: Tuple[Type, ...], return_type: Type)[source]
Bases:
TypeA function type for lambdas and built-in functions.
- class yapcad.dsl.types.GeometricPrimitiveType(_name: str, dimension: int | None = None)[source]
Bases:
TypeA geometric primitive type (point, vector, transform).
Points and vectors are dimensionally polymorphic - they can be 2D or 3D. point2d/point3d and vector2d/vector3d are specific variants.
- class yapcad.dsl.types.ListType(element_type: Type)[source]
Bases:
TypeA generic list type: list<T>.
- class yapcad.dsl.types.NoneType[source]
Bases:
TypeThe none/null type (only valid for optional types).
- class yapcad.dsl.types.OptionalTypeWrapper(inner_type: Type)[source]
Bases:
TypeAn optional type: T?
- class yapcad.dsl.types.PrimitiveType(_name: str)[source]
Bases:
TypeA primitive type (int, float, bool, string).
- class yapcad.dsl.types.Type[source]
Bases:
ABCBase class for all DSL types.
- class yapcad.dsl.types.TypeTier(*values)[source]
Bases:
EnumTier classification for types in the hierarchy.
- COMPOUND_CURVE = 3
- CURVE = 2
- GENERIC = 0
- PRIMITIVE = 1
- SOLID = 5
- SURFACE = 4
- class yapcad.dsl.types.UnknownType[source]
Bases:
TypeA placeholder for type inference or error recovery.
- yapcad.dsl.types.common_type(t1: Type, t2: Type) Type | None[source]
Find the common type that both t1 and t2 can be assigned to.
Returns None if no common type exists.
- yapcad.dsl.types.is_compound_curve(t: Type) bool[source]
Check if type is a compound curve (Tier 3).
- yapcad.dsl.types.is_geometric_primitive(t: Type) bool[source]
Check if type is a geometric primitive (point, vector, transform).
- yapcad.dsl.types.is_geometry(t: Type) bool[source]
Check if type is any geometric type (Tier 1 geometric through Tier 5).
- yapcad.dsl.types.make_list_type(element_type: Type) ListType[source]
Create a list type with the given element type.
- yapcad.dsl.types.make_optional_type(inner_type: Type) OptionalTypeWrapper[source]
Create an optional type wrapping the given type.
Module contents
yapCAD Domain-Specific Language (DSL) compiler.
This module provides: - Lexer: Tokenizes DSL source code - Parser: Builds AST from tokens - Type checker: Validates types and constraints - Interpreter: Executes DSL commands to generate geometry - Transforms: AST transformations for optimization
- Usage:
from yapcad.dsl import tokenize, parse, check, Lexer, Parser, TypeChecker
# Simple parsing tokens = tokenize(‘let x: int = 42;’)
# Or parse and type check a complete module source = ‘’’ module my_design;
- command MAKE_BOX(width: float, height: float) -> solid {
let box: solid = box(width, height, 10.0); emit box;
tokens = tokenize(source) module = parse(tokens) result = check(module) if result.has_errors:
- for diag in result.diagnostics:
print(diag)
- class yapcad.dsl.AssignmentStatement(span: SourceSpan, target: Expression, value: Expression)[source]
Bases:
StatementAn assignment to an existing variable (e.g., x = 5).
- target: Expression
- value: Expression
- class yapcad.dsl.AstNode(span: SourceSpan)[source]
Bases:
ABCBase class for all AST nodes.
- accept(visitor: AstVisitor) Any[source]
Accept a visitor for traversal.
- span: SourceSpan
- class yapcad.dsl.AstTransform[source]
Bases:
ABCBase class for AST transformations.
Transforms are applied to a Module and return a (potentially modified) Module. Transforms can be composed in a pipeline.
- class yapcad.dsl.BinaryOp(span: SourceSpan, left: Expression, operator: TokenType, right: Expression)[source]
Bases:
ExpressionA binary operation (e.g., a + b, x and y).
- left: Expression
- right: Expression
- class yapcad.dsl.Block(span: SourceSpan, statements: List[Statement], final_expression: Expression | None = None)[source]
Bases:
AstNodeA block of statements (indented block).
In Pythonic syntax, blocks are delimited by indentation (INDENT/DEDENT) rather than braces.
- final_expression: Expression | None = None
- class yapcad.dsl.CheckResult(diagnostics: List[Diagnostic], has_errors: bool, has_warnings: bool, has_python_blocks: bool)[source]
Bases:
objectResult of type checking a module.
- diagnostics: List[Diagnostic]
- yapcad.dsl.Command
alias of
FunctionDef
- class yapcad.dsl.CompoundCurveType(_name: str)[source]
Bases:
TypeA Tier 3 compound curve type (paths, profiles, regions).
- class yapcad.dsl.Diagnostic(code: str, message: str, severity: ErrorSeverity, span: SourceSpan, source_line: str | None = None, hints: List[str] = <factory>, related: List[Diagnostic] = <factory>)[source]
Bases:
objectA single diagnostic message (error, warning, etc.).
- severity: ErrorSeverity
- span: SourceSpan
- class yapcad.dsl.DiagnosticCollector(max_errors: int = 20)[source]
Bases:
objectCollects diagnostics during compilation.
- add(diagnostic: Diagnostic) None[source]
Add a diagnostic.
- diagnostics: List[Diagnostic]
- class yapcad.dsl.DictLiteral(span: SourceSpan, entries: dict[str, Expression])[source]
Bases:
ExpressionA dictionary literal (e.g., {“key”: value, …}).
- entries: dict[str, Expression]
- exception yapcad.dsl.DslError(diagnostic: Diagnostic)[source]
Bases:
ExceptionBase exception for DSL errors.
- class yapcad.dsl.EmitResult(value: Value, metadata: Dict[str, ~typing.Any]=<factory>)[source]
Bases:
objectResult of an emit statement - the final output of a command.
Contains the emitted geometry plus any metadata attached via with {…}.
- class yapcad.dsl.EmitStatement(span: SourceSpan, value: Expression, metadata: dict[str, ~yapcad.dsl.ast.Expression]=<factory>)[source]
Bases:
StatementAn emit statement with optional metadata kwargs.
- Syntax:
emit gear # Simple emit emit gear, name=”spur”, material=”steel” # With metadata
- metadata: dict[str, Expression]
- value: Expression
- class yapcad.dsl.ErrorSeverity(*values)[source]
Bases:
EnumSeverity levels for diagnostics.
- ERROR = 'error'
- HINT = 'hint'
- INFO = 'info'
- WARNING = 'warning'
- class yapcad.dsl.ExecutionContext(current_scope: Scope = <factory>, module_name: str = '', command_name: str = '', parameters: Dict[str, ~typing.Any]=<factory>, emit_result: EmitResult | None = None, require_failures: List[RequireFailure] = <factory>, diagnostics: DiagnosticCollector = <factory>, source_lines: List[str] = <factory>, _should_return: bool = False, _return_value: Value | None = None)[source]
Bases:
objectThe full execution context for interpreting DSL code.
Tracks: - Variable scopes - Require failures - Emit result - Diagnostics (errors/warnings) - Module/command being executed
- add_error(message: str, span: SourceSpan) None[source]
Add an error diagnostic.
- add_require_failure(message: str, expression_text: str = None) None[source]
Record a require constraint failure.
- add_warning(message: str, span: SourceSpan) None[source]
Add a warning diagnostic.
- diagnostics: DiagnosticCollector
- emit_result: EmitResult | None = None
- new_scope(name: str = 'block')[source]
Context manager to create a new nested scope.
- Usage:
- with ctx.new_scope(“for-loop”):
# variables defined here are local to this scope ctx.set_variable(“i”, int_val(0))
- require_failures: List[RequireFailure]
- class yapcad.dsl.ExecutionResult(success: bool, emit_result: EmitResult | None = None, require_failures: List[RequireFailure] = <factory>, provenance: Provenance | None = None, error_message: str | None = None)[source]
Bases:
objectResult of executing a command.
- emit_result: EmitResult | None = None
- provenance: Provenance | None = None
- require_failures: List[RequireFailure]
- class yapcad.dsl.ExportUseStatement(span: SourceSpan, module_path: List[str])[source]
Bases:
AstNodeAn export use statement (e.g., export use other.module).
- class yapcad.dsl.Expression(span: SourceSpan)[source]
Bases:
AstNodeBase class for all expressions.
- class yapcad.dsl.ExpressionStatement(span: SourceSpan, expression: Expression)[source]
Bases:
StatementAn expression used as a statement.
- expression: Expression
- class yapcad.dsl.ForStatement(span: SourceSpan, variable: str, iterable: Expression, body: Block)[source]
Bases:
StatementA for loop (e.g., for i in range(n):).
- iterable: Expression
- class yapcad.dsl.FunctionCall(span: ~yapcad.dsl.tokens.SourceSpan, callee: ~yapcad.dsl.ast.Expression, arguments: ~typing.List[~yapcad.dsl.ast.Expression], named_arguments: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]
Bases:
ExpressionA function or constructor call (e.g., point(1, 2, 3)).
- arguments: List[Expression]
- callee: Expression
- named_arguments: dict[str, Expression]
- class yapcad.dsl.FunctionSignature(name: str, params: List[Tuple[str, Type, Any | None]], return_type: Type, is_method: bool = False, is_variadic: bool = False)[source]
Bases:
objectType signature for a function or built-in.
- class yapcad.dsl.FunctionType(param_types: Tuple[Type, ...], return_type: Type)[source]
Bases:
TypeA function type for lambdas and built-in functions.
- class yapcad.dsl.GenericType(span: SourceSpan, name: str, type_args: List[TypeNode])[source]
Bases:
TypeNodeA generic type like ‘list[point3d]’ or ‘dict[str, int]’.
- class yapcad.dsl.GeometricPrimitiveType(_name: str, dimension: int | None = None)[source]
Bases:
TypeA geometric primitive type (point, vector, transform).
Points and vectors are dimensionally polymorphic - they can be 2D or 3D. point2d/point3d and vector2d/vector3d are specific variants.
- class yapcad.dsl.Identifier(span: SourceSpan, name: str)[source]
Bases:
ExpressionA variable or function name reference.
- class yapcad.dsl.IdentifierPattern(span: SourceSpan, name: str)[source]
Bases:
PatternA binding pattern (e.g., ‘match x { case n: … }’).
- class yapcad.dsl.IfExpr(span: SourceSpan, condition: Expression, then_branch: Block, elif_branches: List[ElifBranch] = <factory>, else_branch: Block | None = None)[source]
Bases:
ExpressionAn if-else expression (returns a value).
- condition: Expression
- elif_branches: List[ElifBranch]
- class yapcad.dsl.IndexAccess(span: SourceSpan, object: Expression, index: Expression)[source]
Bases:
ExpressionIndex access (e.g., list[0]).
- index: Expression
- object: Expression
- class yapcad.dsl.Interpreter(transforms: List[Callable[[Module], Module]] = None, recursion_limit: int | None = None)[source]
Bases:
objectTree-walking interpreter for DSL execution.
Evaluates AST nodes by dispatching to type-specific methods.
- execute(module: Module, command_name: str, parameters: Dict[str, Any], source: str = '') ExecutionResult[source]
Execute a command from a module.
- Parameters:
module – The parsed and type-checked module
command_name – Name of the command to execute
parameters – Parameter values (raw Python values, not wrapped)
source – Original source code for error messages
- Returns:
ExecutionResult with geometry and provenance
- class yapcad.dsl.LambdaExpr(span: SourceSpan, parameters: List[str], body: Expression)[source]
Bases:
ExpressionA lambda/anonymous function (e.g., (x) => x * 2).
- body: Expression
- class yapcad.dsl.Lexer(source: str, filename: str | None = None)[source]
Bases:
objectTokenizer for the yapCAD DSL v2 with Python-style indentation.
This lexer generates INDENT and DEDENT tokens based on changes in leading whitespace, similar to Python’s tokenizer.
- Usage:
lexer = Lexer(source_code) tokens = lexer.tokenize()
- Or for streaming:
lexer = Lexer(source_code) for token in lexer:
process(token)
- exception yapcad.dsl.LexerError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during lexical analysis (E0xx).
- class yapcad.dsl.ListComprehension(span: SourceSpan, element_expr: Expression, clauses: List[ComprehensionClause] = <factory>)[source]
Bases:
ExpressionA list comprehension with one or more for clauses.
- Single clause (original):
[f(x) for x in items if cond]
- Multiple clauses (nested):
[f(x, y) for x in xs for y in ys] [f(x, y) for x in xs for y in ys if x < y] [f(x, y) for x in xs if x > 0 for y in ys if y < 10]
The clauses are evaluated left-to-right as nested loops.
- clauses: List[ComprehensionClause]
- property condition: Expression | None
Get first condition (for single-clause compatibility).
- element_expr: Expression
- classmethod from_single(span: SourceSpan, element_expr: Expression, variable: str, iterable: Expression, condition: Expression | None = None) ListComprehension[source]
Create a single-clause comprehension (backward compatibility).
- property iterable: Expression
Get iterable (for single-clause compatibility).
- class yapcad.dsl.ListLiteral(span: SourceSpan, elements: List[Expression])[source]
Bases:
ExpressionA list literal (e.g., [1, 2, 3]).
- elements: List[Expression]
- class yapcad.dsl.ListType(element_type: Type)[source]
Bases:
TypeA generic list type: list<T>.
- class yapcad.dsl.Literal(span: SourceSpan, value: int | float | str | bool, literal_type: TokenType)[source]
Bases:
ExpressionA literal value (int, float, string, bool).
- class yapcad.dsl.LiteralPattern(span: SourceSpan, value: Literal)[source]
Bases:
PatternA literal pattern (e.g., ‘match x { case 42: … }’).
- class yapcad.dsl.MatchArm(span: SourceSpan, pattern: Pattern, body: Expression)[source]
Bases:
AstNodeA single arm of a match expression.
- body: Expression
- class yapcad.dsl.MatchExpr(span: SourceSpan, subject: Expression, arms: List[MatchArm])[source]
Bases:
ExpressionA match expression.
- subject: Expression
- class yapcad.dsl.MemberAccess(span: SourceSpan, object: Expression, member: str)[source]
Bases:
ExpressionMember access (e.g., point.x).
- object: Expression
- class yapcad.dsl.MethodCall(span: ~yapcad.dsl.tokens.SourceSpan, object: ~yapcad.dsl.ast.Expression, method: str, arguments: ~typing.List[~yapcad.dsl.ast.Expression], named_arguments: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]
Bases:
ExpressionA method call (e.g., curve.at(0.5)).
- arguments: List[Expression]
- named_arguments: dict[str, Expression]
- object: Expression
- class yapcad.dsl.Module(span: SourceSpan, name: str | None, uses: List[UseStatement | ExportUseStatement] = <factory>, native_blocks: List[NativeBlock] = <factory>, native_functions: List[NativeFunction] = <factory>, functions: List[FunctionDef] = <factory>, exports: List[ExportStatement] = <factory>)[source]
Bases:
AstNodeA complete DSL module.
- Syntax:
module module_name
use other.module
@native def native_func(…):
…
- def my_function(…):
…
- property commands: List[FunctionDef]
Backward compatibility alias for functions.
- exports: List[ExportStatement]
- functions: List[FunctionDef]
- native_blocks: List[NativeBlock]
- native_functions: List[NativeFunction]
- uses: List[UseStatement | ExportUseStatement]
- class yapcad.dsl.OptionalType(span: SourceSpan, inner: TypeNode)[source]
Bases:
TypeNodeAn optional type, e.g., ‘point3d?’.
- class yapcad.dsl.OptionalTypeWrapper(inner_type: Type)[source]
Bases:
TypeAn optional type: T?
- class yapcad.dsl.PackageResult(*, success: bool, manifest: 'PackageManifest' | None = None, execution_result: ExecutionResult | None = None, error_message: str | None = None)[source]
Bases:
objectResult of DSL-to-package operation.
- class yapcad.dsl.Parameter(span: SourceSpan, name: str, type_annotation: TypeNode | None = None, default_value: Expression | None = None)[source]
Bases:
AstNodeA function parameter.
- default_value: Expression | None = None
- class yapcad.dsl.Parser(tokens: List[Token], filename: str | None = None, source: str | None = None)[source]
Bases:
objectRecursive descent parser for the yapCAD DSL v2 with Python-style indentation.
- Usage:
parser = Parser(tokens) module = parser.parse_module()
- The parser implements standard precedence climbing for expressions:
- Lowest: or
and == != < > <= >= + - * / // %
- Highest: ** (power, right-associative)
unary (not -)
- PRECEDENCE = {TokenType.AND: 2, TokenType.DOUBLE_SLASH: 6, TokenType.DOUBLE_STAR: 7, TokenType.EQ: 3, TokenType.GE: 4, TokenType.GT: 4, TokenType.LE: 4, TokenType.LT: 4, TokenType.MINUS: 5, TokenType.NE: 3, TokenType.OR: 1, TokenType.PERCENT: 6, TokenType.PLUS: 5, TokenType.SLASH: 6, TokenType.STAR: 6}
- RIGHT_ASSOCIATIVE = {TokenType.DOUBLE_STAR}
- exception yapcad.dsl.ParserError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during parsing (E1xx).
- class yapcad.dsl.Pattern(span: SourceSpan)[source]
Bases:
AstNodeBase class for match patterns.
- class yapcad.dsl.PrimitiveType(_name: str)[source]
Bases:
TypeA primitive type (int, float, bool, string).
- class yapcad.dsl.Provenance(module_name: str, command_name: str, version: str = '0.0.0', parameters: Dict[str, ~typing.Any]=<factory>, source_signature: str = '', timestamp: str = <factory>, extra: Dict[str, ~typing.Any]=<factory>)[source]
Bases:
objectProvenance information for a DSL command execution.
This metadata is attached to emitted geometry to enable: - Reproducibility: Re-run with same parameters - Audit trail: Track what generated each piece of geometry - Version control: Detect if source changed
- class yapcad.dsl.PythonBlock(span: SourceSpan, code: str)[source]
Bases:
StatementAn inline Python block (legacy support).
- class yapcad.dsl.PythonExpr(span: SourceSpan, code: str, return_type: TypeNode)[source]
Bases:
ExpressionA python block that returns a value (legacy support).
- class yapcad.dsl.RangeExpr(span: SourceSpan, start: Expression, end: Expression, step: Expression | None = None)[source]
Bases:
ExpressionA range expression (e.g., 0..10 or range(10)).
- end: Expression
- start: Expression
- step: Expression | None = None
- yapcad.dsl.RequireStatement
alias of
AssertStatement
- class yapcad.dsl.ReturnStatement(span: SourceSpan, value: Expression | None = None)[source]
Bases:
StatementA return statement.
- value: Expression | None = None
- class yapcad.dsl.Scope(symbols: Dict[str, ~yapcad.dsl.symbols.Symbol]=<factory>, parent: Scope | None = None, name: str = '')[source]
Bases:
objectA single scope in the scope stack.
- exception yapcad.dsl.SemanticError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during semantic analysis (E3xx).
- class yapcad.dsl.SimpleType(span: SourceSpan, name: str)[source]
Bases:
TypeNodeA simple type like ‘int’, ‘float’, ‘solid’, etc.
- class yapcad.dsl.SourceLocation(line: int, column: int, offset: int, filename: str | None = None)[source]
Bases:
objectRepresents a position in source code.
- class yapcad.dsl.SourceSpan(start: SourceLocation, end: SourceLocation)[source]
Bases:
objectRepresents a range in source code.
- end: SourceLocation
- start: SourceLocation
- class yapcad.dsl.Statement(span: SourceSpan)[source]
Bases:
AstNodeBase class for all statements.
- class yapcad.dsl.Symbol(name: str, kind: SymbolKind, type: Type, span: SourceSpan | None = None, is_mutable: bool = False, has_python_block: bool = False)[source]
Bases:
objectA symbol in the symbol table.
- kind: SymbolKind
- span: SourceSpan | None = None
- class yapcad.dsl.SymbolKind(*values)[source]
Bases:
EnumThe kind of symbol being tracked.
- COMMAND = 4
- FUNCTION = 3
- MODULE = 5
- PARAMETER = 2
- VARIABLE = 1
- class yapcad.dsl.SymbolTable[source]
Bases:
objectManages scopes and symbol definitions for type checking.
Provides: - Nested scope management (push/pop) - Symbol definition and lookup - Built-in function registry
- define(symbol: Symbol) bool[source]
Define a symbol in the current scope.
Returns True if successful, False if already defined in current scope.
- get_all_builtins() Dict[str, FunctionSignature][source]
Get all registered built-in functions.
- lookup_builtin(name: str) FunctionSignature | None[source]
Look up a built-in function signature.
- class yapcad.dsl.Token(type: TokenType, value: Any, lexeme: str, span: SourceSpan)[source]
Bases:
objectA single token from the lexer.
- span: SourceSpan
- class yapcad.dsl.TokenType(*values)[source]
Bases:
EnumAll token types recognized by the DSL lexer.
- AND = 76
- ARROW = 92
- AS = 19
- ASSERT = 17
- ASSIGN = 79
- AT = 97
- BOOL_LITERAL = 4
- CLOSE = 30
- CLOSE_C0 = 31
- CLOSE_C1 = 32
- COLON = 88
- COMMA = 90
- COMMAND = 23
- DEDENT = 100
- DEF = 8
- DOT = 91
- DOUBLE_ARROW = 93
- DOUBLE_SLASH = 67
- DOUBLE_STAR = 69
- ELIF = 12
- ELSE = 13
- EMIT = 10
- EOF = 102
- EQ = 74
- EXPORT = 21
- EXPORTS = 29
- FLOAT_LITERAL = 2
- FN = 28
- FOR = 14
- GE = 73
- GT = 71
- HASH = 98
- IDENTIFIER = 5
- IF = 11
- IN = 15
- INDENT = 99
- INT_LITERAL = 1
- LBRACE = 82
- LBRACKET = 86
- LE = 72
- LET = 24
- LPAREN = 84
- LT = 70
- MATCH = 20
- MINUS = 64
- MINUS_ASSIGN = 81
- MODULE = 6
- NATIVE = 22
- NATIVE_BLOCK = 103
- NE = 75
- NEWLINE = 101
- NOT = 78
- OR = 77
- PASS = 18
- PERCENT = 68
- PLUS = 63
- PLUS_ASSIGN = 80
- PYTHON = 27
- QUESTION = 95
- RANGE = 94
- RBRACE = 83
- RBRACKET = 87
- REQUIRE = 25
- RETURN = 9
- RPAREN = 85
- SEMICOLON = 89
- SLASH = 66
- STAR = 65
- STRING_LITERAL = 3
- TYPE_ARC = 45
- TYPE_BEZIER = 52
- TYPE_BOOL = 36
- TYPE_CATMULLROM = 50
- TYPE_CIRCLE = 46
- TYPE_DICT = 62
- TYPE_ELLIPSE = 47
- TYPE_FLOAT = 34
- TYPE_HYPERBOLA = 49
- TYPE_INT = 33
- TYPE_LINE_SEGMENT = 44
- TYPE_LIST = 61
- TYPE_LOOP3D = 57
- TYPE_NURBS = 51
- TYPE_PARABOLA = 48
- TYPE_PATH2D = 53
- TYPE_PATH3D = 54
- TYPE_POINT = 37
- TYPE_POINT2D = 38
- TYPE_POINT3D = 39
- TYPE_PROFILE2D = 55
- TYPE_REGION2D = 56
- TYPE_SHELL = 59
- TYPE_SOLID = 60
- TYPE_STRING = 35
- TYPE_SURFACE = 58
- TYPE_TRANSFORM = 43
- TYPE_VECTOR = 40
- TYPE_VECTOR2D = 41
- TYPE_VECTOR3D = 42
- UNDERSCORE = 96
- USE = 7
- WHILE = 16
- WITH = 26
- class yapcad.dsl.TransformPipeline(transforms: List[AstTransform] = None)[source]
Bases:
objectA pipeline of AST transforms to apply in sequence.
- add(transform: AstTransform) TransformPipeline[source]
Add a transform to the pipeline.
- class yapcad.dsl.TreeTransform[source]
Bases:
AstTransformA transform that walks the tree and can modify nodes.
Subclasses override visit_* methods to transform specific node types. By default, nodes are copied unchanged.
- visit_assignment(node: AssignmentStatement) Statement[source]
Visit an assignment statement.
- visit_binary_op(node: BinaryOp) Expression[source]
- 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_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_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_unary_op(node: UnaryOp) Expression[source]
- class yapcad.dsl.Type[source]
Bases:
ABCBase class for all DSL types.
- class yapcad.dsl.TypeChecker(max_errors: int = 20)[source]
Bases:
objectType checker for the yapCAD DSL.
Traverses the AST and validates: - Type compatibility in assignments and function calls - Return type matching - Require expression boolean constraint - Emit target type matching command return type - Undefined identifier detection - Python block flagging
- check(module: Module) CheckResult[source]
Type check a complete module.
- exception yapcad.dsl.TypeError(diagnostic: Diagnostic)[source]
Bases:
DslErrorError during type checking (E2xx).
- class yapcad.dsl.TypeNode(span: SourceSpan)[source]
Bases:
AstNodeBase class for type annotations.
- class yapcad.dsl.TypeTier(*values)[source]
Bases:
EnumTier classification for types in the hierarchy.
- COMPOUND_CURVE = 3
- CURVE = 2
- GENERIC = 0
- PRIMITIVE = 1
- SOLID = 5
- SURFACE = 4
- class yapcad.dsl.UnaryOp(span: SourceSpan, operator: TokenType, operand: Expression)[source]
Bases:
ExpressionA unary operation (e.g., not x, -n).
- operand: Expression
- class yapcad.dsl.UseStatement(span: SourceSpan, module_path: List[str], alias: str | None = None)[source]
Bases:
AstNodeA use/import statement (e.g., use yapcad.stdlib.transforms).
- Syntax:
use module.path use module.path as alias use module.path.{item1, item2} # (future: selective imports)
- class yapcad.dsl.Value(data: Any, type: Type)[source]
Bases:
objectA runtime value with DSL type information.
The data field holds the actual Python/yapCAD object. The type field holds the DSL type for runtime validation.
- class yapcad.dsl.WildcardPattern(span: SourceSpan)[source]
Bases:
PatternThe wildcard pattern ‘_’.
- yapcad.dsl.check(module: Module, max_errors: int = 20) CheckResult[source]
Convenience function to type check a module.
- Parameters:
module – The parsed module AST
max_errors – Maximum errors before stopping (default 20)
- Returns:
CheckResult with diagnostics
- yapcad.dsl.compile_and_run(source: str, command_name: str, parameters: Dict[str, Any], recursion_limit: int | None = None) ExecutionResult[source]
High-level API to compile and run DSL source code in one call.
This is the simplest way to execute DSL code:
from yapcad.dsl import compile_and_run
- result = compile_and_run(‘’’
module my_design; command MAKE_BOX(w: float, h: float, d: float) -> solid {
emit box(w, h, d);
}
‘’’, “MAKE_BOX”, {“w”: 10.0, “h”: 20.0, “d”: 5.0})
- if result.success:
geometry = result.geometry
- else:
print(f”Error: {result.error_message}”)
- Parameters:
source – DSL source code as a string
command_name – Name of the command to execute
parameters – Parameter values (raw Python values)
recursion_limit – Maximum depth for command-to-command calls (default 100, can also be set via YAPCAD_DSL_RECURSION_LIMIT env var)
- Returns:
ExecutionResult with geometry, provenance, and any errors
- yapcad.dsl.create_provenance(module_name: str, command_name: str, parameters: Dict[str, Any], source: str = '', version: str = '0.0.0', **extra: Any) Provenance[source]
Create a Provenance record for a command execution.
- Parameters:
module_name – Name of the DSL module
command_name – Name of the command being executed
parameters – Parameter values passed to the command
source – Original source code (for signature)
version – Version of the module
**extra – Additional metadata to include
- Returns:
A Provenance record
- yapcad.dsl.describe_function(name: str) str[source]
Get a human-readable description of a function.
- Parameters:
name – The function name
- Returns:
Formatted description string
- yapcad.dsl.execute(module: Module, command_name: str, parameters: Dict[str, Any], source: str = '') ExecutionResult[source]
Execute a command from a module.
This is a convenience wrapper around Interpreter.execute().
- yapcad.dsl.get_api_as_json() str[source]
Get the complete API reference as a JSON string.
Useful for tools that prefer to parse JSON directly.
- yapcad.dsl.get_api_reference() Dict[str, Any][source]
Get the complete API reference as a dictionary.
Returns a dictionary with: - types: All available types with descriptions - functions: All built-in functions with signatures and descriptions - methods: Type-specific methods organized by receiver type
This is the primary entry point for agentic tools to understand the DSL’s capabilities.
- yapcad.dsl.get_common_pattern(name: str) str | None[source]
Get a common DSL pattern/example.
- Parameters:
name – Pattern name (e.g., “boolean_subtraction”, “gear_creation”)
- Returns:
DSL code example or None if pattern not found
- yapcad.dsl.get_function_info(name: str) Dict[str, Any] | None[source]
Get detailed information about a specific function.
- Parameters:
name – The function name
- Returns:
Dictionary with signature, description, example, etc. Returns None if function not found.
- yapcad.dsl.get_method_signature(obj_type: Type, method_name: str) FunctionSignature | None[source]
Get the method signature for a type, if it exists.
- yapcad.dsl.get_methods_for_type(type_name: str) Dict[str, Dict[str, Any]][source]
Get all methods available on a given type.
- Parameters:
type_name – The type name (e.g., “solid”, “curve”, “region2d”)
- Returns:
Dictionary mapping method names to their signatures
- yapcad.dsl.get_type_info(name: str) Dict[str, Any] | None[source]
Get information about a type.
- Parameters:
name – The type name
- Returns:
Dictionary with tier, description, constructor info. Returns None if type not found.
- yapcad.dsl.is_type_token(token_type: TokenType) bool[source]
Check if a token type represents a type keyword.
- yapcad.dsl.list_functions(category: str | None = None) List[str][source]
List all available built-in function names.
- Parameters:
category – Optional filter by category (e.g., “solid”, “math”, “curve”)
- Returns:
Sorted list of function names
- yapcad.dsl.list_types(tier: int | None = None) List[str][source]
List all available types.
- Parameters:
tier – Optional filter by tier (0-5)
- Returns:
List of type names
- yapcad.dsl.make_list_type(element_type: Type) ListType[source]
Create a list type with the given element type.
- yapcad.dsl.make_optional_type(inner_type: Type) OptionalTypeWrapper[source]
Create an optional type wrapping the given type.
- yapcad.dsl.package_from_dsl(source: str, command_name: str, parameters: Dict[str, Any], target_dir: Path | str, *, name: str, version: str, description: str | None = None, author: str | None = None, units: str | None = None, materials: Dict[str, Dict[str, Any]] | None = None, overwrite: bool = False) PackageResult[source]
Compile DSL source, execute a command, and package the result.
This is a high-level function that combines DSL compilation, execution, and packaging into a single workflow. The resulting package includes full provenance metadata linking it to the original DSL source.
- Parameters:
source – DSL source code containing the module and command definitions.
command_name – Name of the command to execute (e.g., “MAKE_GEAR”).
parameters – Dictionary of parameter values for the command.
target_dir – Directory where the package will be created.
name – Name for the package (used in manifest).
version – Version string for the package.
description – Optional description for the package.
author – Optional author name.
units – Unit system (default “mm”).
materials – Optional materials dictionary for the package.
overwrite – If True, overwrite existing package directory.
- Returns:
PackageResult with success status, manifest, and any error info.
Example
>>> source = ''' ... module gear_design; ... ... command MAKE_GEAR(teeth: int, module_mm: float) -> solid { ... let pitch_diameter: float = teeth * module_mm; ... let gear: solid = cylinder(pitch_diameter / 2.0, 10.0); ... emit gear; ... } ... ''' >>> result = package_from_dsl( ... source, ... "MAKE_GEAR", ... {"teeth": 24, "module_mm": 2.0}, ... "output/gear_pkg", ... name="gear_24t", ... version="1.0.0", ... ) >>> if result.success: ... print(f"Package created at {result.manifest.root}")
- yapcad.dsl.parse(tokens: List[Token], filename: str | None = None, source: str | None = None) Module[source]
Convenience function to parse tokens into a module.
- Parameters:
tokens – List of tokens from the lexer
filename – Optional filename for error messages
source – Optional original source code for extracting raw text
- Returns:
Parsed Module AST
- Raises:
ParserError – If parsing fails