Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/a5c-ai-macro-systems/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 44% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 99% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 75% | 0% |
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 |
json{ "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.tsscheme;; 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 }
rust// 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; }
typescript// 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 }
typescript// 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); }
typescriptinterface 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'); } }
typescriptinterface 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; }
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 40,128 | 65,012 | +62% | 1 | 1 | 0% | 8,274 | 10,307 | +25% | 0 | 0 | — |
case-02 | fail→fail | 40,806 | 48,624 | +19% | 1 | 1 | 0% | 8,262 | 10,295 | +25% | 0 | 0 | — |
case-03 | fail→fail | 40,651 | 37,512 | -8% | 1 | 1 | 0% | 8,261 | 10,294 | +25% | 0 | 0 | — |
case-04 | fail→fail | 19,897 | 20,998 | +6% | 1 | 1 | 0% | 3,903 | 5,992 | +54% | 0 | 0 | — |
case-05 | pass→pass | 13,358 | 16,315 | +22% | 1 | 1 | 0% | 2,305 | 4,594 | +99% | 0 | 0 | — |
case-06 | pass→pass | 22,212 | 19,768 | -11% | 1 | 1 | 0% | 3,950 | 5,796 | +47% | 0 | 0 | — |
case-07 | fail→fail | 19,148 | 25,041 | +31% | 1 | 1 | 0% | 3,363 | 6,466 | +92% | 0 | 0 | — |
case-08 | pass→fail | 21,240 | 26,164 | +23% | 1 | 1 | 0% | 3,389 | 6,656 | +96% | 0 | 0 | — |
case-09 | pass→pass | 13,936 | 9,123 | -35% | 1 | 1 | 0% | 1,898 | 3,566 | +88% | 0 | 0 | — |
case-10 | fail→fail | 18,736 | 28,297 | +51% | 1 | 1 | 0% | 3,479 | 6,470 | +86% | 0 | 0 | — |
case-11 | fail→pass | 19,014 | 16,348 | -14% | 1 | 1 | 0% | 2,954 | 4,262 | +44% | 0 | 0 | — |
case-12 | pass→pass | 19,411 | 20,246 | +4% | 1 | 1 | 0% | 2,905 | 4,798 | +65% | 0 | 0 | — |
case-13 | pass→pass | 17,070 | 22,788 | +33% | 1 | 1 | 0% | 2,681 | 5,807 | +117% | 0 | 0 | — |
case-14 | pass→pass | 13,256 | 8,288 | -37% | 1 | 1 | 0% | 2,390 | 3,730 | +56% | 0 | 0 | — |
case-15 | pass→pass | 18,646 | 21,699 | +16% | 1 | 1 | 0% | 2,804 | 4,750 | +69% | 0 | 0 | — |
case-16 | fail→pass | 20,733 | 26,957 | +30% | 1 | 1 | 0% | 3,178 | 6,331 | +99% | 0 | 0 | — |
case-17 | fail→pass | 18,882 | 16,232 | -14% | 1 | 1 | 0% | 2,676 | 4,754 | +78% | 0 | 0 | — |
case-18 | pass→pass | 24,126 | 3,446 | -86% | 1 | 1 | 0% | 2,348 | 2,703 | +15% | 0 | 0 | — |
case-19 | pass→pass | 18,213 | 17,650 | -3% | 1 | 1 | 0% | 2,865 | 4,823 | +68% | 0 | 0 | — |
case-20 | pass→pass | 17,986 | 14,133 | -21% | 1 | 1 | 0% | 2,619 | 4,625 | +77% | 0 | 0 | — |
case-21 | fail→pass | 29,899 | 118,473 | +296% | 1 | 1 | 0% | 4,618 | 8,086 | +75% | 0 | 0 | — |
case-22 | fail→fail | 28,000 | 30,851 | +10% | 1 | 1 | 0% | 3,630 | 7,730 | +113% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +18 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.