-
Notifications
You must be signed in to change notification settings - Fork 0
Mapping
CDTk provides a powerful yet intuitive system for transforming Abstract Syntax Trees (ASTs) into target code. With its strongly-typed, field-based mapping rules and integration with the Model System, CDTk supports generating flexible and efficient outputs for any target language.
Mapping is the process of converting an AST into a structured output, such as source code or data, using predefined patterns.
-
Map: Defines how a specific AST node type is rendered. -
MapSet: Groups multiple mappings into one cohesive framework.
class Maps : MapSet
{
public Map AssignmentNode = "let {variable} = {value};";
}For this AST:
{
"type": "AssignmentNode",
"fields": {
"variable": "x",
"value": 42
}
}The resulting output will be:
let x = 42;-
Field-Based Mapping: Directly reference AST fields using a clean template syntax (
{fieldName}). - Integration with Models: Extend mapping functionality with semantic data from models.
- Validation: Ensure all mappings are defined and consistent with your AST structure.
- Multi-Target Support: Generate output for multiple languages or formats simultaneously.
A MapSet holds all mappings for your project and ensures modular, clean mapping definitions.
Create a class inheriting from MapSet and populate it with Map fields:
class Maps : MapSet
{
public Map AssignmentNode = "let {variable} = {value};";
public Map BinaryOpNode = "({left} {operator} {right})";
public Map IfNode = "if ({condition}) {body}";
}Placeholders ({fieldName}) substitute AST fields into the output:
public Map BinaryOpNode = "({left} {operator} {right})";Given this AST:
{
"type": "BinaryOpNode",
"fields": {
"left": "x",
"operator": "+",
"right": "y"
}
}The resulting output is:
(x + y)Models integrate seamlessly with MapSet to extend functionality for semantic transformations.
class Maps : MapSet
{
public MyModel Model => new MyModel(__AllRules, __Ast);
public Map AssignmentNode = "let {variable} = {value};";
}class MyModel : Model
{
private readonly __AllRules _rules;
private readonly __Ast _ast;
public MyModel(__AllRules rules, __Ast ast)
{
_rules = rules;
_ast = ast;
}
public override object Build(object input)
{
if (input is AstNode node)
{
return new { ProcessedValue = Transform(node) };
}
return input;
}
private object Transform(AstNode node)
{
return node.GetFields(); // Perform semantic transformations
}
}Benefits:
- Decouple intermediate AST processing from template rendering.
- Simplify mapping logic for complex transformations.
Guarantee all nodes are handled by defining a fallback rule:
public Map Fallback = "// TODO: Handle {type}";This flags unmapped nodes for further debugging.
Generate outputs for multiple languages or use cases:
var compiler = new Compiler()
.WithTokens(new Tokens())
.WithRules(new Rules())
.WithTargets(
("C", new CMapping()),
("Python", new PythonMapping()),
("JavaScript", new JavaScriptMapping())
)
.Build();Compile once and access different outputs:
var result = compiler.Compile(inputSource);
Console.WriteLine(result.Outputs["C"]);
Console.WriteLine(result.Outputs["Python"]);
Console.WriteLine(result.Outputs["JavaScript"]);Ensure your MapSet adheres to your defined grammar and AST structure:
var diagnostics = mapSet.Validate();
if (diagnostics.HasErrors)
{
foreach (var diagnostic in diagnostics.Items)
{
Console.WriteLine($"{diagnostic.Level}: {diagnostic.Message}");
}
}Validation detects:
- Undefined placeholders in templates.
- Missing mappings for certain AST nodes.
CDTk’s diagnostics aid in debugging mapping issues:
diagnostics.Add(
Stage.Mapping,
DiagnosticLevel.Error,
"Mapping failed at node {type}",
SourceSpan.Unknown
);Enable deduplication to reduce redundant diagnostics:
diagnostics.Deduplicate = true;-
Always Include a Fallback: Ensure unmapped nodes don’t crash the pipeline:
public Map UnknownNode = "// TODO: Handle {type}";
-
Leverage Models: Use models for complex semantic transformations that simplify your mapping templates.
-
Modularize Maps: Break down large mapping logic into smaller, intuitive templates.
-
Test Incrementally: Validate mapping outputs with diverse sample ASTs to catch potential issues early.
-
Use Descriptive Names: Make templates clear and maintainable:
public Map VariableDeclaration = "let {name} = {value};";
Now that you’re familiar with mapping:
- Explore Rules: Learn how ASTs are built from rules.
- Learn Validation: Prevent errors before compilation.
- Study Models: Add semantic transformations to your pipeline.