yapcad.dsl package

Subpackages

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: Statement

An 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: Statement

An assignment to an existing variable (e.g., x = 5).

target: Expression
value: Expression
class yapcad.dsl.ast.AstNode(span: SourceSpan)[source]

Bases: ABC

Base class for all AST nodes.

accept(visitor: AstVisitor) Any[source]

Accept a visitor for traversal.

span: SourceSpan
class yapcad.dsl.ast.AstVisitor[source]

Bases: ABC

Base class for AST visitors.

generic_visit(node: AstNode) Any[source]

Default visit method.

class yapcad.dsl.ast.BinaryOp(span: SourceSpan, left: Expression, operator: TokenType, right: Expression)[source]

Bases: Expression

A binary operation (e.g., a + b, x and y).

left: Expression
operator: TokenType
right: Expression
class yapcad.dsl.ast.Block(span: SourceSpan, statements: List[Statement], final_expression: Expression | None = None)[source]

Bases: AstNode

A block of statements (indented block).

In Pythonic syntax, blocks are delimited by indentation (INDENT/DEDENT) rather than braces.

final_expression: Expression | None = None
statements: List[Statement]
yapcad.dsl.ast.Command

alias of FunctionDef

class yapcad.dsl.ast.Decorator(span: ~yapcad.dsl.tokens.SourceSpan, name: str, arguments: ~typing.List[~yapcad.dsl.ast.Expression] = <factory>)[source]

Bases: AstNode

A decorator (e.g., @native).

arguments: List[Expression]
name: str
class yapcad.dsl.ast.DictLiteral(span: SourceSpan, entries: dict[str, Expression])[source]

Bases: Expression

A dictionary literal (e.g., {“key”: value, …}).

entries: dict[str, Expression]
class yapcad.dsl.ast.ElifBranch(span: SourceSpan, condition: Expression, body: Block)[source]

Bases: AstNode

An elif branch in an if expression/statement.

body: Block
condition: Expression
class yapcad.dsl.ast.EmitStatement(span: ~yapcad.dsl.tokens.SourceSpan, value: ~yapcad.dsl.ast.Expression, metadata: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]

Bases: Statement

An 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: AstNode

An export statement (e.g., export function_name).

name: str
class yapcad.dsl.ast.ExportUseStatement(span: SourceSpan, module_path: List[str])[source]

Bases: AstNode

An export use statement (e.g., export use other.module).

module_path: List[str]
class yapcad.dsl.ast.Expression(span: SourceSpan)[source]

Bases: AstNode

Base class for all expressions.

class yapcad.dsl.ast.ExpressionStatement(span: SourceSpan, expression: Expression)[source]

Bases: Statement

An expression used as a statement.

expression: Expression
class yapcad.dsl.ast.ForStatement(span: SourceSpan, variable: str, iterable: Expression, body: Block)[source]

Bases: Statement

A for loop (e.g., for i in range(n):).

body: Block
iterable: Expression
variable: str
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: Expression

A 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: AstNode

A function definition (uses ‘def’ keyword).

Syntax:
def function_name(param1: type1, param2: type2) -> return_type:

Replaces the old ‘command’ syntax.

body: Block
decorators: List[Decorator]
name: str
parameters: List[Parameter]
return_type: TypeNode | None
class yapcad.dsl.ast.GenericType(span: SourceSpan, name: str, type_args: List[TypeNode])[source]

Bases: TypeNode

A generic type like ‘list[point3d]’ or ‘dict[str, int]’.

name: str
type_args: List[TypeNode]
class yapcad.dsl.ast.Identifier(span: SourceSpan, name: str)[source]

Bases: Expression

A variable or function name reference.

name: str
class yapcad.dsl.ast.IdentifierPattern(span: SourceSpan, name: str)[source]

Bases: Pattern

A binding pattern (e.g., ‘match x { case n: … }’).

name: str
class yapcad.dsl.ast.IfExpr(span: ~yapcad.dsl.tokens.SourceSpan, condition: ~yapcad.dsl.ast.Expression, then_branch: ~yapcad.dsl.ast.Block, elif_branches: ~typing.List[~yapcad.dsl.ast.ElifBranch] = <factory>, else_branch: ~yapcad.dsl.ast.Block | None = None)[source]

Bases: Expression

An if-else expression (returns a value).

condition: Expression
elif_branches: List[ElifBranch]
else_branch: Block | None = None
then_branch: Block
class yapcad.dsl.ast.IfStatement(span: ~yapcad.dsl.tokens.SourceSpan, condition: ~yapcad.dsl.ast.Expression, then_branch: ~yapcad.dsl.ast.Block, elif_branches: ~typing.List[~yapcad.dsl.ast.ElifBranch] = <factory>, else_branch: ~yapcad.dsl.ast.Block | None = None)[source]

Bases: Statement

An if statement (doesn’t return a value).

Syntax:
if condition:

elif condition:

else:

condition: Expression
elif_branches: List[ElifBranch]
else_branch: Block | None = None
then_branch: Block
class yapcad.dsl.ast.IndexAccess(span: SourceSpan, object: Expression, index: Expression)[source]

Bases: Expression

Index access (e.g., list[0]).

index: Expression
object: Expression
class yapcad.dsl.ast.LambdaExpr(span: SourceSpan, parameters: List[str], body: Expression)[source]

Bases: Expression

A lambda/anonymous function (e.g., (x) => x * 2).

body: Expression
parameters: List[str]
yapcad.dsl.ast.LetStatement

alias of VarDecl

class yapcad.dsl.ast.ListComprehension(span: SourceSpan, element_expr: Expression, variable: str, iterable: Expression, condition: Expression | None = None)[source]

Bases: Expression

A list comprehension (e.g., [f(x) for x in items if cond]).

condition: Expression | None = None
element_expr: Expression
iterable: Expression
variable: str
class yapcad.dsl.ast.ListLiteral(span: SourceSpan, elements: List[Expression])[source]

Bases: Expression

A 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: Expression

A literal value (int, float, string, bool).

literal_type: TokenType
value: int | float | str | bool
class yapcad.dsl.ast.LiteralPattern(span: SourceSpan, value: Literal)[source]

Bases: Pattern

A literal pattern (e.g., ‘match x { case 42: … }’).

value: Literal
class yapcad.dsl.ast.MatchArm(span: SourceSpan, pattern: Pattern, body: Expression)[source]

Bases: AstNode

A single arm of a match expression.

body: Expression
pattern: Pattern
class yapcad.dsl.ast.MatchExpr(span: SourceSpan, subject: Expression, arms: List[MatchArm])[source]

Bases: Expression

A match expression.

arms: List[MatchArm]
subject: Expression
class yapcad.dsl.ast.MemberAccess(span: SourceSpan, object: Expression, member: str)[source]

Bases: Expression

Member access (e.g., point.x).

member: str
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: Expression

A method call (e.g., curve.at(0.5)).

arguments: List[Expression]
method: str
named_arguments: dict[str, Expression]
object: Expression
class yapcad.dsl.ast.Module(span: ~yapcad.dsl.tokens.SourceSpan, name: str | None, uses: ~typing.List[~yapcad.dsl.ast.UseStatement | ~yapcad.dsl.ast.ExportUseStatement] = <factory>, native_blocks: ~typing.List[~yapcad.dsl.ast.NativeBlock] = <factory>, native_functions: ~typing.List[~yapcad.dsl.ast.NativeFunction] = <factory>, functions: ~typing.List[~yapcad.dsl.ast.FunctionDef] = <factory>, exports: ~typing.List[~yapcad.dsl.ast.ExportStatement] = <factory>)[source]

Bases: AstNode

A 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]
name: str | None
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: AstNode

A 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.

code: str
exports: List[NativeFunctionDecl]
class yapcad.dsl.ast.NativeFunction(span: SourceSpan, name: str, parameters: List[Parameter], return_type: TypeNode, python_code: str)[source]

Bases: AstNode

A 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.

name: str
parameters: List[Parameter]
python_code: str
return_type: TypeNode
class yapcad.dsl.ast.NativeFunctionDecl(span: SourceSpan, name: str, parameters: List[Parameter], return_type: TypeNode)[source]

Bases: AstNode

A function declaration in a native block’s exports section (legacy).

Represents: fn name(param1: type1, param2: type2) -> return_type;

name: str
parameters: List[Parameter]
return_type: TypeNode
class yapcad.dsl.ast.OptionalType(span: SourceSpan, inner: TypeNode)[source]

Bases: TypeNode

An optional type, e.g., ‘point3d?’.

inner: TypeNode
class yapcad.dsl.ast.Parameter(span: SourceSpan, name: str, type_annotation: TypeNode | None = None, default_value: Expression | None = None)[source]

Bases: AstNode

A function parameter.

default_value: Expression | None = None
name: str
type_annotation: TypeNode | None = None
class yapcad.dsl.ast.PassStatement(span: SourceSpan)[source]

Bases: Statement

A pass statement (placeholder for empty blocks).

class yapcad.dsl.ast.Pattern(span: SourceSpan)[source]

Bases: AstNode

Base class for match patterns.

class yapcad.dsl.ast.PrintVisitor(indent: int = 0)[source]

Bases: AstVisitor

Debug visitor that prints the AST structure.

generic_visit(node: AstNode) None[source]

Default visit method.

class yapcad.dsl.ast.PythonBlock(span: SourceSpan, code: str)[source]

Bases: Statement

An inline Python block (legacy support).

code: str
class yapcad.dsl.ast.PythonExpr(span: SourceSpan, code: str, return_type: TypeNode)[source]

Bases: Expression

A python block that returns a value (legacy support).

code: str
return_type: TypeNode
class yapcad.dsl.ast.RangeExpr(span: SourceSpan, start: Expression, end: Expression, step: Expression | None = None)[source]

Bases: Expression

A 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: Statement

A return statement.

value: Expression | None = None
class yapcad.dsl.ast.SimpleType(span: SourceSpan, name: str)[source]

Bases: TypeNode

A simple type like ‘int’, ‘float’, ‘solid’, etc.

name: str
class yapcad.dsl.ast.Statement(span: SourceSpan)[source]

Bases: AstNode

Base class for all statements.

class yapcad.dsl.ast.TypeNode(span: SourceSpan)[source]

Bases: AstNode

Base class for type annotations.

class yapcad.dsl.ast.UnaryOp(span: SourceSpan, operator: TokenType, operand: Expression)[source]

Bases: Expression

A unary operation (e.g., not x, -n).

operand: Expression
operator: TokenType
class yapcad.dsl.ast.UseStatement(span: SourceSpan, module_path: List[str], alias: str | None = None)[source]

Bases: AstNode

A 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)

alias: str | None = None
module_path: List[str]
class yapcad.dsl.ast.VarDecl(span: SourceSpan, name: str, type_annotation: TypeNode | None, initializer: Expression | None)[source]

Bases: Statement

A 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
name: str
type_annotation: TypeNode | None
class yapcad.dsl.ast.WhileStatement(span: SourceSpan, condition: Expression, body: Block)[source]

Bases: Statement

A while loop (e.g., while condition:).

body: Block
condition: Expression
class yapcad.dsl.ast.WildcardPattern(span: SourceSpan)[source]

Bases: Pattern

The wildcard pattern ‘_’.

yapcad.dsl.ast.print_ast(node: AstNode) None[source]

Print an AST node for debugging.

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: object

Result of type checking a module.

diagnostics: List[Diagnostic]
has_errors: bool
has_python_blocks: bool
has_warnings: bool
class yapcad.dsl.checker.TypeChecker(max_errors: int = 20)[source]

Bases: object

Type 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: ~yapcad.dsl.errors.ErrorSeverity, span: ~yapcad.dsl.tokens.SourceSpan, source_line: str | None = None, hints: ~typing.List[str] = <factory>, related: ~typing.List[~yapcad.dsl.errors.Diagnostic] = <factory>)[source]

Bases: object

A single diagnostic message (error, warning, etc.).

code: str
format(show_source: bool = True) str[source]

Format the diagnostic for display.

hints: List[str]
message: str
related: List[Diagnostic]
severity: ErrorSeverity
source_line: str | None = None
span: SourceSpan
to_json() dict[source]

Convert to JSON-serializable dict for tooling integration.

class yapcad.dsl.errors.DiagnosticCollector(max_errors: int = 20)[source]

Bases: object

Collects diagnostics during compilation.

add(diagnostic: Diagnostic) None[source]

Add a diagnostic.

add_error(error: DslError) None[source]

Add an error exception as a diagnostic.

property error_count: int
format_all(show_source: bool = True) str[source]

Format all diagnostics for display.

property has_errors: bool
property has_warnings: bool
property should_stop: bool

Check if we’ve hit the max error limit.

to_json() dict[source]

Convert all diagnostics to JSON format.

property warning_count: int
exception yapcad.dsl.errors.DslError(diagnostic: Diagnostic)[source]

Bases: Exception

Base exception for DSL errors.

class yapcad.dsl.errors.ErrorSeverity(*values)[source]

Bases: Enum

Severity levels for diagnostics.

ERROR = 'error'
HINT = 'hint'
INFO = 'info'
WARNING = 'warning'
exception yapcad.dsl.errors.LexerError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during lexical analysis (E0xx).

exception yapcad.dsl.errors.ParserError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during parsing (E1xx).

exception yapcad.dsl.errors.SemanticError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during semantic analysis (E3xx).

exception yapcad.dsl.errors.TypeError(diagnostic: Diagnostic)[source]

Bases: DslError

Error 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.introspection.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.introspection.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.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: object

Tokenizer 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)

get_source_line(line_num: int) str | None[source]

Get a specific line of source (1-indexed).

property lines: List[str]

Lazy-load line list for error reporting.

tokenize() List[Token][source]

Tokenize the entire source, returning a list of tokens.

yapcad.dsl.lexer.tokenize(source: str, filename: str | None = None) List[Token][source]

Convenience function to tokenize source code.

Parameters:
  • source – The source code to tokenize

  • filename – Optional filename for error messages

Returns:

List of tokens

Raises:

LexerError – If tokenization fails

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: object

Result 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: object

Recursive 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}
parse_module() Module[source]

Parse a complete module.

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: object

Type signature for a function or built-in.

is_method: bool = False
is_variadic: bool = False
name: str
params: List[Tuple[str, Type, Any | None]]
return_type: Type
class yapcad.dsl.symbols.Scope(symbols: ~typing.Dict[str, ~yapcad.dsl.symbols.Symbol] = <factory>, parent: ~yapcad.dsl.symbols.Scope | None = None, name: str = '')[source]

Bases: object

A single scope in the scope stack.

define(symbol: Symbol) None[source]

Define a symbol in this scope.

lookup(name: str) Symbol | None[source]

Look up a symbol in this scope or any parent scope.

lookup_local(name: str) Symbol | None[source]

Look up a symbol in this scope only.

name: str = ''
parent: Scope | None = None
symbols: Dict[str, Symbol]
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: object

A symbol in the symbol table.

has_python_block: bool = False
is_mutable: bool = False
kind: SymbolKind
name: str
span: SourceSpan | None = None
type: Type
class yapcad.dsl.symbols.SymbolKind(*values)[source]

Bases: Enum

The kind of symbol being tracked.

COMMAND = 4
FUNCTION = 3
MODULE = 5
PARAMETER = 2
VARIABLE = 1
class yapcad.dsl.symbols.SymbolTable[source]

Bases: object

Manages scopes and symbol definitions for type checking.

Provides: - Nested scope management (push/pop) - Symbol definition and lookup - Built-in function registry

current_scope_name() str[source]

Get the name of the current scope (for debugging).

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.

is_builtin(name: str) bool[source]

Check if a name is a built-in function.

lookup(name: str) Symbol | None[source]

Look up a symbol in the current scope chain.

lookup_builtin(name: str) FunctionSignature | None[source]

Look up a built-in function signature.

pop_scope() None[source]

Pop the current scope.

push_scope(name: str = '') None[source]

Push a new scope onto the stack.

yapcad.dsl.symbols.get_method_signature(obj_type: Type, method_name: str) FunctionSignature | None[source]

Get the method signature for a type, if it exists.

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: object

Represents a position in source code.

column: int
filename: str | None = None
line: int
offset: int
class yapcad.dsl.tokens.SourceSpan(start: SourceLocation, end: SourceLocation)[source]

Bases: object

Represents a range in source code.

end: SourceLocation
start: SourceLocation
class yapcad.dsl.tokens.Token(type: TokenType, value: Any, lexeme: str, span: SourceSpan)[source]

Bases: object

A single token from the lexer.

lexeme: str
span: SourceSpan
type: TokenType
value: Any
class yapcad.dsl.tokens.TokenType(*values)[source]

Bases: Enum

All 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.tokens.is_deprecated_keyword(keyword: str) bool[source]

Check if a keyword is deprecated.

yapcad.dsl.tokens.is_type_token(token_type: TokenType) bool[source]

Check if a token type represents a type keyword.

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: Type

A Tier 3 compound curve type (paths, profiles, regions).

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.CurveType(_name: str)[source]

Bases: Type

A Tier 2 curve primitive type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.DictType[source]

Bases: Type

A dictionary type (string keys).

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.ErrorType[source]

Bases: Type

A type representing a type error (prevents cascading errors).

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.FunctionType(param_types: Tuple[Type, ...], return_type: Type)[source]

Bases: Type

A function type for lambdas and built-in functions.

property name: str

The type name for display/errors.

param_types: Tuple[Type, ...]
return_type: Type
property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.GeometricPrimitiveType(_name: str, dimension: int | None = None)[source]

Bases: Type

A 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.

dimension: int | None = None
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.ListType(element_type: Type)[source]

Bases: Type

A generic list type: list<T>.

element_type: Type
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.NoneType[source]

Bases: Type

The none/null type (only valid for optional types).

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.OptionalTypeWrapper(inner_type: Type)[source]

Bases: Type

An optional type: T?

inner_type: Type
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.PrimitiveType(_name: str)[source]

Bases: Type

A primitive type (int, float, bool, string).

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.SolidType(_name: str = 'solid')[source]

Bases: Type

A Tier 5 solid type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.SurfaceType(_name: str)[source]

Bases: Type

A Tier 4 surface type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.Type[source]

Bases: ABC

Base class for all DSL types.

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

abstract property name: str

The type name for display/errors.

abstract property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.types.TypeTier(*values)[source]

Bases: Enum

Tier 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: Type

A placeholder for type inference or error recovery.

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

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_curve(t: Type) bool[source]

Check if type is a curve (Tier 2).

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.is_numeric(t: Type) bool[source]

Check if type is numeric (int or float).

yapcad.dsl.types.is_solid(t: Type) bool[source]

Check if type is a solid (Tier 5).

yapcad.dsl.types.is_surface(t: Type) bool[source]

Check if type is a surface (Tier 4).

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.

yapcad.dsl.types.resolve_type_name(name: str) Type | None[source]

Look up a type by name.

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: Statement

An assignment to an existing variable (e.g., x = 5).

span: SourceSpan
target: Expression
value: Expression
class yapcad.dsl.AstNode(span: SourceSpan)[source]

Bases: ABC

Base class for all AST nodes.

accept(visitor: AstVisitor) Any[source]

Accept a visitor for traversal.

span: SourceSpan
class yapcad.dsl.AstTransform[source]

Bases: ABC

Base class for AST transformations.

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

abstract property name: str

Name of this transform for debugging/logging.

abstractmethod transform(module: Module) Module[source]

Apply this transform to a module.

Parameters:

module – The input module AST

Returns:

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

class yapcad.dsl.AstVisitor[source]

Bases: ABC

Base class for AST visitors.

generic_visit(node: AstNode) Any[source]

Default visit method.

class yapcad.dsl.BinaryOp(span: SourceSpan, left: Expression, operator: TokenType, right: Expression)[source]

Bases: Expression

A binary operation (e.g., a + b, x and y).

left: Expression
operator: TokenType
right: Expression
span: SourceSpan
class yapcad.dsl.Block(span: SourceSpan, statements: List[Statement], final_expression: Expression | None = None)[source]

Bases: AstNode

A block of statements (indented block).

In Pythonic syntax, blocks are delimited by indentation (INDENT/DEDENT) rather than braces.

final_expression: Expression | None = None
span: SourceSpan
statements: List[Statement]
class yapcad.dsl.CheckResult(diagnostics: List[Diagnostic], has_errors: bool, has_warnings: bool, has_python_blocks: bool)[source]

Bases: object

Result of type checking a module.

diagnostics: List[Diagnostic]
has_errors: bool
has_python_blocks: bool
has_warnings: bool
yapcad.dsl.Command

alias of FunctionDef

class yapcad.dsl.CompoundCurveType(_name: str)[source]

Bases: Type

A Tier 3 compound curve type (paths, profiles, regions).

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.CurveType(_name: str)[source]

Bases: Type

A Tier 2 curve primitive type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.Diagnostic(code: str, message: str, severity: ~yapcad.dsl.errors.ErrorSeverity, span: ~yapcad.dsl.tokens.SourceSpan, source_line: str | None = None, hints: ~typing.List[str] = <factory>, related: ~typing.List[~yapcad.dsl.errors.Diagnostic] = <factory>)[source]

Bases: object

A single diagnostic message (error, warning, etc.).

code: str
format(show_source: bool = True) str[source]

Format the diagnostic for display.

hints: List[str]
message: str
related: List[Diagnostic]
severity: ErrorSeverity
source_line: str | None = None
span: SourceSpan
to_json() dict[source]

Convert to JSON-serializable dict for tooling integration.

class yapcad.dsl.DiagnosticCollector(max_errors: int = 20)[source]

Bases: object

Collects diagnostics during compilation.

add(diagnostic: Diagnostic) None[source]

Add a diagnostic.

add_error(error: DslError) None[source]

Add an error exception as a diagnostic.

property error_count: int
format_all(show_source: bool = True) str[source]

Format all diagnostics for display.

property has_errors: bool
property has_warnings: bool
property should_stop: bool

Check if we’ve hit the max error limit.

to_json() dict[source]

Convert all diagnostics to JSON format.

property warning_count: int
class yapcad.dsl.DictLiteral(span: SourceSpan, entries: dict[str, Expression])[source]

Bases: Expression

A dictionary literal (e.g., {“key”: value, …}).

entries: dict[str, Expression]
span: SourceSpan
class yapcad.dsl.DictType[source]

Bases: Type

A dictionary type (string keys).

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

exception yapcad.dsl.DslError(diagnostic: Diagnostic)[source]

Bases: Exception

Base exception for DSL errors.

class yapcad.dsl.EmitResult(value: ~yapcad.dsl.runtime.values.Value, metadata: ~typing.Dict[str, ~typing.Any] = <factory>)[source]

Bases: object

Result of an emit statement - the final output of a command.

Contains the emitted geometry plus any metadata attached via with {…}.

property data: Any

Get the raw geometry data.

metadata: Dict[str, Any]
property type: Type

Get the DSL type.

value: Value
class yapcad.dsl.EmitStatement(span: ~yapcad.dsl.tokens.SourceSpan, value: ~yapcad.dsl.ast.Expression, metadata: dict[str, ~yapcad.dsl.ast.Expression] = <factory>)[source]

Bases: Statement

An emit statement with optional metadata kwargs.

Syntax:

emit gear # Simple emit emit gear, name=”spur”, material=”steel” # With metadata

metadata: dict[str, Expression]
span: SourceSpan
value: Expression
class yapcad.dsl.ErrorSeverity(*values)[source]

Bases: Enum

Severity levels for diagnostics.

ERROR = 'error'
HINT = 'hint'
INFO = 'info'
WARNING = 'warning'
class yapcad.dsl.ExecutionContext(current_scope: ~yapcad.dsl.runtime.context.Scope = <factory>, module_name: str = '', command_name: str = '', parameters: ~typing.Dict[str, ~typing.Any] = <factory>, emit_result: ~yapcad.dsl.runtime.values.EmitResult | None = None, require_failures: ~typing.List[~yapcad.dsl.runtime.values.RequireFailure] = <factory>, diagnostics: ~yapcad.dsl.errors.DiagnosticCollector = <factory>, source_lines: ~typing.List[str] = <factory>, _should_return: bool = False, _return_value: ~yapcad.dsl.runtime.values.Value | None = None)[source]

Bases: object

The 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.

clear_return() None[source]

Clear the return signal (used after handling return).

command_name: str = ''
current_scope: Scope
diagnostics: DiagnosticCollector
emit_result: EmitResult | None = None
get_variable(name: str) Value | None[source]

Look up a variable in the current scope chain.

property has_errors: bool

Check if any errors occurred.

property has_warnings: bool

Check if any warnings occurred.

module_name: str = ''
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))

parameters: Dict[str, Any]
require_failures: List[RequireFailure]
property return_value: Value | None

Get the return value if early return was signaled.

set_emit(value: Value, metadata: Dict[str, Any] = None) None[source]

Set the emit result for this command.

set_variable(name: str, value: Value) None[source]

Define a new variable in the current scope.

property should_return: bool

Check if early return was signaled.

signal_return(value: Value) None[source]

Signal an early return from a command.

source_lines: List[str]
update_variable(name: str, value: Value) bool[source]

Update an existing variable (for assignment statements).

class yapcad.dsl.ExecutionResult(success: bool, emit_result: ~yapcad.dsl.runtime.values.EmitResult | None = None, require_failures: ~typing.List[~yapcad.dsl.runtime.values.RequireFailure] = <factory>, provenance: ~yapcad.dsl.runtime.provenance.Provenance | None = None, error_message: str | None = None)[source]

Bases: object

Result of executing a command.

emit_result: EmitResult | None = None
error_message: str | None = None
property geometry: Any

Get the emitted geometry data.

property metadata: Dict[str, Any]

Get the emit metadata.

provenance: Provenance | None = None
require_failures: List[RequireFailure]
success: bool
class yapcad.dsl.ExportUseStatement(span: SourceSpan, module_path: List[str])[source]

Bases: AstNode

An export use statement (e.g., export use other.module).

module_path: List[str]
span: SourceSpan
class yapcad.dsl.Expression(span: SourceSpan)[source]

Bases: AstNode

Base class for all expressions.

class yapcad.dsl.ExpressionStatement(span: SourceSpan, expression: Expression)[source]

Bases: Statement

An expression used as a statement.

expression: Expression
span: SourceSpan
class yapcad.dsl.ForStatement(span: SourceSpan, variable: str, iterable: Expression, body: Block)[source]

Bases: Statement

A for loop (e.g., for i in range(n):).

body: Block
iterable: Expression
span: SourceSpan
variable: str
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: Expression

A function or constructor call (e.g., point(1, 2, 3)).

arguments: List[Expression]
callee: Expression
named_arguments: dict[str, Expression]
span: SourceSpan
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: object

Type signature for a function or built-in.

is_method: bool = False
is_variadic: bool = False
name: str
params: List[Tuple[str, Type, Any | None]]
return_type: Type
class yapcad.dsl.FunctionType(param_types: Tuple[Type, ...], return_type: Type)[source]

Bases: Type

A function type for lambdas and built-in functions.

property name: str

The type name for display/errors.

param_types: Tuple[Type, ...]
return_type: Type
property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.GenericType(span: SourceSpan, name: str, type_args: List[TypeNode])[source]

Bases: TypeNode

A generic type like ‘list[point3d]’ or ‘dict[str, int]’.

name: str
span: SourceSpan
type_args: List[TypeNode]
class yapcad.dsl.GeometricPrimitiveType(_name: str, dimension: int | None = None)[source]

Bases: Type

A 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.

dimension: int | None = None
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.Identifier(span: SourceSpan, name: str)[source]

Bases: Expression

A variable or function name reference.

name: str
span: SourceSpan
class yapcad.dsl.IdentifierPattern(span: SourceSpan, name: str)[source]

Bases: Pattern

A binding pattern (e.g., ‘match x { case n: … }’).

name: str
span: SourceSpan
class yapcad.dsl.IfExpr(span: ~yapcad.dsl.tokens.SourceSpan, condition: ~yapcad.dsl.ast.Expression, then_branch: ~yapcad.dsl.ast.Block, elif_branches: ~typing.List[~yapcad.dsl.ast.ElifBranch] = <factory>, else_branch: ~yapcad.dsl.ast.Block | None = None)[source]

Bases: Expression

An if-else expression (returns a value).

condition: Expression
elif_branches: List[ElifBranch]
else_branch: Block | None = None
span: SourceSpan
then_branch: Block
class yapcad.dsl.IndexAccess(span: SourceSpan, object: Expression, index: Expression)[source]

Bases: Expression

Index access (e.g., list[0]).

index: Expression
object: Expression
span: SourceSpan
class yapcad.dsl.Interpreter(transforms: List[Callable[[Module], Module]] = None)[source]

Bases: object

Tree-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: Expression

A lambda/anonymous function (e.g., (x) => x * 2).

body: Expression
parameters: List[str]
span: SourceSpan
yapcad.dsl.LetStatement

alias of VarDecl

class yapcad.dsl.Lexer(source: str, filename: str | None = None)[source]

Bases: object

Tokenizer 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)

get_source_line(line_num: int) str | None[source]

Get a specific line of source (1-indexed).

property lines: List[str]

Lazy-load line list for error reporting.

tokenize() List[Token][source]

Tokenize the entire source, returning a list of tokens.

exception yapcad.dsl.LexerError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during lexical analysis (E0xx).

class yapcad.dsl.ListComprehension(span: SourceSpan, element_expr: Expression, variable: str, iterable: Expression, condition: Expression | None = None)[source]

Bases: Expression

A list comprehension (e.g., [f(x) for x in items if cond]).

condition: Expression | None = None
element_expr: Expression
iterable: Expression
span: SourceSpan
variable: str
class yapcad.dsl.ListLiteral(span: SourceSpan, elements: List[Expression])[source]

Bases: Expression

A list literal (e.g., [1, 2, 3]).

elements: List[Expression]
span: SourceSpan
class yapcad.dsl.ListType(element_type: Type)[source]

Bases: Type

A generic list type: list<T>.

element_type: Type
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.Literal(span: SourceSpan, value: int | float | str | bool, literal_type: TokenType)[source]

Bases: Expression

A literal value (int, float, string, bool).

literal_type: TokenType
span: SourceSpan
value: int | float | str | bool
class yapcad.dsl.LiteralPattern(span: SourceSpan, value: Literal)[source]

Bases: Pattern

A literal pattern (e.g., ‘match x { case 42: … }’).

span: SourceSpan
value: Literal
class yapcad.dsl.MatchArm(span: SourceSpan, pattern: Pattern, body: Expression)[source]

Bases: AstNode

A single arm of a match expression.

body: Expression
pattern: Pattern
span: SourceSpan
class yapcad.dsl.MatchExpr(span: SourceSpan, subject: Expression, arms: List[MatchArm])[source]

Bases: Expression

A match expression.

arms: List[MatchArm]
span: SourceSpan
subject: Expression
class yapcad.dsl.MemberAccess(span: SourceSpan, object: Expression, member: str)[source]

Bases: Expression

Member access (e.g., point.x).

member: str
object: Expression
span: SourceSpan
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: Expression

A method call (e.g., curve.at(0.5)).

arguments: List[Expression]
method: str
named_arguments: dict[str, Expression]
object: Expression
span: SourceSpan
class yapcad.dsl.Module(span: ~yapcad.dsl.tokens.SourceSpan, name: str | None, uses: ~typing.List[~yapcad.dsl.ast.UseStatement | ~yapcad.dsl.ast.ExportUseStatement] = <factory>, native_blocks: ~typing.List[~yapcad.dsl.ast.NativeBlock] = <factory>, native_functions: ~typing.List[~yapcad.dsl.ast.NativeFunction] = <factory>, functions: ~typing.List[~yapcad.dsl.ast.FunctionDef] = <factory>, exports: ~typing.List[~yapcad.dsl.ast.ExportStatement] = <factory>)[source]

Bases: AstNode

A 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]
name: str | None
native_blocks: List[NativeBlock]
native_functions: List[NativeFunction]
span: SourceSpan
uses: List[UseStatement | ExportUseStatement]
class yapcad.dsl.OptionalType(span: SourceSpan, inner: TypeNode)[source]

Bases: TypeNode

An optional type, e.g., ‘point3d?’.

inner: TypeNode
span: SourceSpan
class yapcad.dsl.OptionalTypeWrapper(inner_type: Type)[source]

Bases: Type

An optional type: T?

inner_type: Type
is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.PackageResult(*, success: bool, manifest: 'PackageManifest' | None = None, execution_result: ExecutionResult | None = None, error_message: str | None = None)[source]

Bases: object

Result 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: AstNode

A function parameter.

default_value: Expression | None = None
name: str
span: SourceSpan
type_annotation: TypeNode | None = None
class yapcad.dsl.Parser(tokens: List[Token], filename: str | None = None, source: str | None = None)[source]

Bases: object

Recursive 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}
parse_module() Module[source]

Parse a complete module.

exception yapcad.dsl.ParserError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during parsing (E1xx).

class yapcad.dsl.Pattern(span: SourceSpan)[source]

Bases: AstNode

Base class for match patterns.

class yapcad.dsl.PrimitiveType(_name: str)[source]

Bases: Type

A primitive type (int, float, bool, string).

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.Provenance(module_name: str, command_name: str, version: str = '0.0.0', parameters: ~typing.Dict[str, ~typing.Any] = <factory>, source_signature: str = '', timestamp: str = <factory>, extra: ~typing.Dict[str, ~typing.Any] = <factory>)[source]

Bases: object

Provenance 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

command_name: str
extra: Dict[str, Any]
classmethod from_dict(data: Dict[str, Any]) Provenance[source]

Create from dictionary.

module_name: str
parameters: Dict[str, Any]
source_signature: str = ''
timestamp: str
to_dict() Dict[str, Any][source]

Convert to dictionary for serialization.

to_json() str[source]

Convert to JSON string.

version: str = '0.0.0'
class yapcad.dsl.PythonBlock(span: SourceSpan, code: str)[source]

Bases: Statement

An inline Python block (legacy support).

code: str
span: SourceSpan
class yapcad.dsl.PythonExpr(span: SourceSpan, code: str, return_type: TypeNode)[source]

Bases: Expression

A python block that returns a value (legacy support).

code: str
return_type: TypeNode
span: SourceSpan
class yapcad.dsl.RangeExpr(span: SourceSpan, start: Expression, end: Expression, step: Expression | None = None)[source]

Bases: Expression

A range expression (e.g., 0..10 or range(10)).

end: Expression
span: SourceSpan
start: Expression
step: Expression | None = None
yapcad.dsl.RequireStatement

alias of AssertStatement

class yapcad.dsl.ReturnStatement(span: SourceSpan, value: Expression | None = None)[source]

Bases: Statement

A return statement.

span: SourceSpan
value: Expression | None = None
class yapcad.dsl.Scope(symbols: ~typing.Dict[str, ~yapcad.dsl.symbols.Symbol] = <factory>, parent: ~yapcad.dsl.symbols.Scope | None = None, name: str = '')[source]

Bases: object

A single scope in the scope stack.

define(symbol: Symbol) None[source]

Define a symbol in this scope.

lookup(name: str) Symbol | None[source]

Look up a symbol in this scope or any parent scope.

lookup_local(name: str) Symbol | None[source]

Look up a symbol in this scope only.

name: str = ''
parent: Scope | None = None
symbols: Dict[str, Symbol]
exception yapcad.dsl.SemanticError(diagnostic: Diagnostic)[source]

Bases: DslError

Error during semantic analysis (E3xx).

class yapcad.dsl.SimpleType(span: SourceSpan, name: str)[source]

Bases: TypeNode

A simple type like ‘int’, ‘float’, ‘solid’, etc.

name: str
span: SourceSpan
class yapcad.dsl.SolidType(_name: str = 'solid')[source]

Bases: Type

A Tier 5 solid type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.SourceLocation(line: int, column: int, offset: int, filename: str | None = None)[source]

Bases: object

Represents a position in source code.

column: int
filename: str | None = None
line: int
offset: int
class yapcad.dsl.SourceSpan(start: SourceLocation, end: SourceLocation)[source]

Bases: object

Represents a range in source code.

end: SourceLocation
start: SourceLocation
class yapcad.dsl.Statement(span: SourceSpan)[source]

Bases: AstNode

Base class for all statements.

class yapcad.dsl.SurfaceType(_name: str)[source]

Bases: Type

A Tier 4 surface type.

property name: str

The type name for display/errors.

property tier: TypeTier

The tier this type belongs to.

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: object

A symbol in the symbol table.

has_python_block: bool = False
is_mutable: bool = False
kind: SymbolKind
name: str
span: SourceSpan | None = None
type: Type
class yapcad.dsl.SymbolKind(*values)[source]

Bases: Enum

The kind of symbol being tracked.

COMMAND = 4
FUNCTION = 3
MODULE = 5
PARAMETER = 2
VARIABLE = 1
class yapcad.dsl.SymbolTable[source]

Bases: object

Manages scopes and symbol definitions for type checking.

Provides: - Nested scope management (push/pop) - Symbol definition and lookup - Built-in function registry

current_scope_name() str[source]

Get the name of the current scope (for debugging).

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.

is_builtin(name: str) bool[source]

Check if a name is a built-in function.

lookup(name: str) Symbol | None[source]

Look up a symbol in the current scope chain.

lookup_builtin(name: str) FunctionSignature | None[source]

Look up a built-in function signature.

pop_scope() None[source]

Pop the current scope.

push_scope(name: str = '') None[source]

Push a new scope onto the stack.

class yapcad.dsl.Token(type: TokenType, value: Any, lexeme: str, span: SourceSpan)[source]

Bases: object

A single token from the lexer.

lexeme: str
span: SourceSpan
type: TokenType
value: Any
class yapcad.dsl.TokenType(*values)[source]

Bases: Enum

All 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: object

A pipeline of AST transforms to apply in sequence.

add(transform: AstTransform) TransformPipeline[source]

Add a transform to the pipeline.

apply(module: Module) Module[source]

Apply all transforms in sequence.

class yapcad.dsl.TreeTransform[source]

Bases: AstTransform

A transform that walks the tree and can modify nodes.

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

transform(module: Module) Module[source]

Transform a module by visiting all nodes.

visit_assignment(node: AssignmentStatement) Statement[source]

Visit an assignment statement.

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

Visit a block.

visit_command(node: FunctionDef) FunctionDef[source]

Visit a command node.

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

Visit an emit statement.

visit_expr_statement(node: ExpressionStatement) Statement[source]

Visit an expression statement.

visit_expression(node: Expression) Expression[source]

Visit an expression node.

visit_for(node: ForStatement) Statement[source]

Visit a for statement.

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

Visit a let statement.

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

Visit a module node.

visit_python_block(node: PythonBlock) Statement[source]

Visit a Python block (no transformation by default).

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

Visit a require statement.

visit_return(node: ReturnStatement) Statement[source]

Visit a return statement.

visit_statement(node: Statement) Statement[source]

Visit a statement node.

visit_unary_op(node: UnaryOp) Expression[source]
class yapcad.dsl.Type[source]

Bases: ABC

Base class for all DSL types.

is_assignable_from(other: Type) bool[source]

Check if this type can accept a value of the other type.

abstract property name: str

The type name for display/errors.

abstract property tier: TypeTier

The tier this type belongs to.

class yapcad.dsl.TypeChecker(max_errors: int = 20)[source]

Bases: object

Type 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: DslError

Error during type checking (E2xx).

class yapcad.dsl.TypeNode(span: SourceSpan)[source]

Bases: AstNode

Base class for type annotations.

class yapcad.dsl.TypeTier(*values)[source]

Bases: Enum

Tier 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: Expression

A unary operation (e.g., not x, -n).

operand: Expression
operator: TokenType
span: SourceSpan
class yapcad.dsl.UseStatement(span: SourceSpan, module_path: List[str], alias: str | None = None)[source]

Bases: AstNode

A 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)

alias: str | None = None
module_path: List[str]
span: SourceSpan
class yapcad.dsl.Value(data: Any, type: Type)[source]

Bases: object

A 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.

data: Any
is_truthy() bool[source]

Check if this value is truthy in boolean context.

type: Type
class yapcad.dsl.WildcardPattern(span: SourceSpan)[source]

Bases: Pattern

The 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]) 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)

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_common_patterns() List[str][source]

List all available common pattern names.

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

yapcad.dsl.print_ast(node: AstNode) None[source]

Print an AST node for debugging.

yapcad.dsl.resolve_type_name(name: str) Type | None[source]

Look up a type by name.

yapcad.dsl.tokenize(source: str, filename: str | None = None) List[Token][source]

Convenience function to tokenize source code.

Parameters:
  • source – The source code to tokenize

  • filename – Optional filename for error messages

Returns:

List of tokens

Raises:

LexerError – If tokenization fails