算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
macro-systems【设计与创意】Expert skill for designing and implementing macro systems including hygienic macros, procedural macros, and macro expansion. Supports pattern-based macros, quasi-quotation, and hygiene management.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Design and implement macro systems for programming languages, from simple text-based macros to sophisticated hygienic macro systems.
Invoke this skill when you need to:
| Parameter | Type | Required | Description |
|---|---|---|---|
| macroType | string | Yes | Type of macro system (pattern, procedural, hygienic) |
| targetLanguage | string | Yes | Language for macro implementation (Rust, Scheme, etc.) |
| syntax | object | No | Custom syntax specifications |
| hygieneModel | string | No | Hygiene model (sets-of-scopes, marks, none) |
| features | array | No | Features to implement |
{
"features": [
"pattern-matching",
"quasi-quotation",
"hygiene",
"procedural-macros",
"expansion-tracing",
"error-recovery",
"recursive-macros",
"macro-modularization"
]
}
macro-system/
├── syntax/
│ ├── macro-definition.grammar # Macro definition syntax
│ ├── macro-invocation.grammar # Invocation syntax
│ └── quasi-quote.grammar # Quasi-quotation syntax
├── expansion/
│ ├── pattern-matcher.ts # Pattern matching engine
│ ├── template-substitution.ts # Template instantiation
│ ├── hygiene-manager.ts # Hygiene/scope management
│ └── expander.ts # Main expansion driver
├── procedural/
│ ├── proc-macro-api.ts # Procedural macro API
│ ├── token-stream.ts # Token manipulation
│ └── quote.ts # Quasi-quotation impl
├── debugging/
│ ├── expansion-trace.ts # Expansion tracing
│ └── error-reporter.ts # Macro error messages
└── tests/
├── hygiene.test.ts
├── patterns.test.ts
└── expansion.test.ts
;; Definition
(define-syntax my-or
(syntax-rules ()
[(my-or) #f]
[(my-or e) e]
[(my-or e1 e2 ...)
(let ([t e1])
(if t t (my-or e2 ...)))]))
;; Implementation pattern
interface MacroRule {
pattern: Pattern;
template: Template;
literals: string[];
}
function matchPattern(pattern: Pattern, syntax: Syntax): Bindings | null {
// Pattern matching with ellipsis handling
}
function substituteTemplate(template: Template, bindings: Bindings): Syntax {
// Template instantiation with hygiene
}
// Derive macro example
#[proc_macro_derive(Debug)]
pub fn derive_debug(input: TokenStream) -> TokenStream {
let ast = syn::parse(input).unwrap();
impl_debug(&ast)
}
// Implementation pattern
interface ProcMacroContext {
inputTokens: TokenStream;
span: Span;
hygiene: HygieneContext;
}
interface ProcMacro {
expand(ctx: ProcMacroContext): TokenStream;
}
// Sets of Scopes hygiene model (Racket-style)
interface Syntax {
datum: any;
scopes: Set<Scope>;
srcLoc: SourceLocation;
}
interface Scope {
id: number;
bindings: Map<Symbol, Binding>;
}
function introduceScope(syntax: Syntax, scope: Scope): Syntax {
return { ...syntax, scopes: new Set([...syntax.scopes, scope]) };
}
function flipScope(syntax: Syntax, scope: Scope): Syntax {
const newScopes = new Set(syntax.scopes);
if (newScopes.has(scope)) {
newScopes.delete(scope);
} else {
newScopes.add(scope);
}
return { ...syntax, scopes: newScopes };
}
function resolve(syntax: Syntax): Binding | undefined {
// Find binding with maximal matching scope set
}
// Quasi-quote syntax
// `(list ,x ,@xs) => (list (unquote x) (unquote-splicing xs))
interface QuasiQuote {
template: QQTemplate;
}
type QQTemplate =
| { type: 'literal'; value: any }
| { type: 'unquote'; expr: Syntax }
| { type: 'unquote-splicing'; expr: Syntax }
| { type: 'list'; elements: QQTemplate[] };
function expandQuasiQuote(qq: QuasiQuote, env: Environment): Syntax {
function expand(template: QQTemplate): Syntax {
switch (template.type) {
case 'literal':
return quoteLiteral(template.value);
case 'unquote':
return evaluate(template.expr, env);
case 'unquote-splicing':
// Splice into enclosing list
return evaluateAndSplice(template.expr, env);
case 'list':
return makeList(template.elements.flatMap(expand));
}
}
return expand(qq.template);
}
interface ExpansionStep {
macroName: string;
inputSyntax: Syntax;
outputSyntax: Syntax;
bindings: Map<string, Syntax>;
location: SourceLocation;
}
class ExpansionTracer {
private steps: ExpansionStep[] = [];
recordStep(step: ExpansionStep): void {
this.steps.push(step);
}
formatTrace(): string {
return this.steps.map((step, i) =>
`Step ${i + 1}: ${step.macroName}\n` +
` Input: ${formatSyntax(step.inputSyntax)}\n` +
` Output: ${formatSyntax(step.outputSyntax)}\n` +
` Bindings: ${formatBindings(step.bindings)}`
).join('\n\n');
}
}
interface MacroError {
type: 'pattern-mismatch' | 'hygiene-violation' | 'expansion-limit' | 'syntax-error';
message: string;
macroName: string;
inputSyntax: Syntax;
suggestions: string[];
}
function reportMacroError(error: MacroError): string {
const base = `Macro expansion error in '${error.macroName}':\n${error.message}`;
const context = `\nInput syntax:\n ${formatSyntax(error.inputSyntax)}`;
const hints = error.suggestions.length > 0
? `\n\nSuggestions:\n${error.suggestions.map(s => ` - ${s}`).join('\n')}`
: '';
return base + context + hints;
}