feat: Add comments to AST nodes

This commit introduces support for comments within the AST nodes.
Comments are now parsed by the lexer and stored within the `Token`
struct.
These comments are then propagated through various compiler phases,
including
the `Node` struct, ensuring they are preserved in the Abstract Syntax
Tree.
This change enhances the AST's ability to retain source code
information,
which can be valuable for debugging and analysis.
This commit is contained in:
2026-03-25 18:36:53 +01:00
parent b436e09840
commit ee89d2330d
16 changed files with 180 additions and 24 deletions
+1
View File
@@ -298,6 +298,7 @@ impl<'a> Analyzer<'a> {
Node {
identity: node.identity.clone(),
kind: new_kind,
comments: node.comments.clone(),
ty: NodeMetrics {
original: node_rc,
purity,
+2
View File
@@ -539,6 +539,7 @@ impl Binder {
self.make_node(node.identity.clone(), NodeKind::Error)
}
SyntaxKind::Error => Node {
comments: node.comments.clone(),
identity: node.identity.clone(),
kind: NodeKind::Error,
ty: (),
@@ -701,6 +702,7 @@ impl Binder {
fn make_node(&self, identity: Identity, kind: NodeKind<BoundPhase>) -> Node<BoundPhase> {
Node {
comments: std::rc::Rc::from([]),
identity,
kind,
ty: (),
+4 -2
View File
@@ -79,9 +79,10 @@ impl Lowering {
ty: RuntimeMetadata {
ty: node.ty.original.ty.clone(),
is_tail: is_tail_position,
original: node_rc,
original: node_rc.clone(),
stack_size: 0,
},
comments: node.comments.clone(),
};
}
@@ -261,9 +262,10 @@ impl Lowering {
ty: RuntimeMetadata {
ty: node.ty.original.ty.clone(),
is_tail: is_tail_position,
original: node_rc,
original: node_rc.clone(),
stack_size,
},
comments: node.comments.clone(),
}
}
}
+26
View File
@@ -95,6 +95,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let p_names = self.extract_param_names(&params)?;
self.registry.define(name.name, p_names, (*body).clone());
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Nop,
ty: (),
@@ -128,6 +129,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_args = self.expand_recursive((*args).clone())?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Call {
callee: Rc::new(expanded_callee),
@@ -146,6 +148,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
self.registry.pop();
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Block {
exprs: expanded_exprs,
@@ -161,6 +164,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
self.registry.pop();
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Lambda {
params: Rc::new(expanded_params),
@@ -184,6 +188,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
None
};
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::If {
cond: Rc::new(cond),
@@ -198,6 +203,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let pattern = self.expand_recursive((*pattern).clone())?;
let value = self.expand_recursive((*value).clone())?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Def {
pattern: Rc::new(pattern),
@@ -212,6 +218,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let target = self.expand_recursive((*target).clone())?;
let value = self.expand_recursive((*value).clone())?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Assign {
target: Rc::new(target),
@@ -228,6 +235,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
expanded_elements.push(Rc::new(self.expand_recursive((*e).clone())?));
}
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Tuple {
elements: expanded_elements,
@@ -245,6 +253,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
));
}
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Record {
fields: expanded_fields,
@@ -257,6 +266,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Expansion { original_call, expanded } => {
let expanded = self.expand_recursive((*expanded).clone())?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Expansion {
original_call,
@@ -269,6 +279,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Again { args } => {
let expanded_args = self.expand_recursive((*args).clone())?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Again {
args: Rc::new(expanded_args),
@@ -316,9 +327,11 @@ impl<E: MacroEvaluator> MacroExpander<E> {
};
let original_call = SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(),
kind: SyntaxKind::Call {
callee: Rc::new(SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(),
kind: SyntaxKind::Identifier {
symbol: Symbol::from(name),
@@ -327,6 +340,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
ty: (),
}),
args: Rc::new(SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(),
kind: SyntaxKind::Tuple {
elements: bindings.into_values().map(Rc::new).collect(),
@@ -338,6 +352,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
};
Ok(SyntaxNode {
comments: std::rc::Rc::from([]),
identity,
kind: SyntaxKind::Expansion {
original_call: Rc::new(original_call),
@@ -371,6 +386,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
// Inside a template, all internal identifiers are colored.
symbol.context = Some(state.expansion_id.clone());
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Identifier {
symbol,
@@ -406,6 +422,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let pattern = self.expand_template((*pattern).clone(), state)?;
let val = self.expand_template((*value).clone(), state)?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Def {
pattern: Rc::new(pattern),
@@ -420,6 +437,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let target = self.expand_template((*target).clone(), state)?;
let value = self.expand_template((*value).clone(), state)?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Assign {
target: Rc::new(target),
@@ -441,6 +459,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
}
}
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Tuple {
elements: new_elements,
@@ -460,6 +479,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
}
}
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Block { exprs: new_exprs },
ty: (),
@@ -475,6 +495,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
));
}
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Record {
fields: new_fields,
@@ -488,6 +509,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_callee = self.expand_template((*callee).clone(), state)?;
let expanded_args = self.expand_template((*args).clone(), state)?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Call {
callee: Rc::new(expanded_callee),
@@ -510,6 +532,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
None
};
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::If {
cond: Rc::new(cond),
@@ -524,6 +547,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_params = self.expand_template((*params).clone(), state)?;
let body = self.expand_template((*body).clone(), state)?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Lambda {
params: Rc::new(expanded_params),
@@ -537,6 +561,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Again { args } => {
let expanded_args = self.expand_template((*args).clone(), state)?;
Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity,
kind: SyntaxKind::Again {
args: Rc::new(expanded_args),
@@ -582,6 +607,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
match val {
Value::Quote(rc) => rc.as_ref().clone(),
_ => SyntaxNode {
comments: std::rc::Rc::from([]),
identity,
kind: SyntaxKind::Constant(val),
ty: (),
+2
View File
@@ -724,6 +724,7 @@ impl Optimizer {
Rc::new(Node {
identity: node.identity.clone(),
kind: new_kind,
comments: node.comments.clone(),
ty: metrics,
})
}
@@ -780,6 +781,7 @@ impl Optimizer {
_ => return node_rc.clone(),
};
Rc::new(Node {
comments: node.comments.clone(),
identity: node.identity.clone(),
kind: new_kind,
ty: node.ty.clone(),
+4
View File
@@ -19,11 +19,13 @@ impl<'a> Folder<'a> {
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: NodeKind::Constant(val.clone()),
comments: template.comments.clone(),
ty: ty.clone(),
});
Node {
identity: template.identity.clone(),
kind: NodeKind::Constant(val),
comments: template.comments.clone(),
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
@@ -36,11 +38,13 @@ impl<'a> Folder<'a> {
let typed_original = Rc::new(Node {
identity: template.identity.clone(),
kind: NodeKind::Nop,
comments: template.comments.clone(),
ty: StaticType::Void,
});
Node {
identity: template.identity.clone(),
kind: NodeKind::Nop,
comments: template.comments.clone(),
ty: NodeMetrics {
original: typed_original,
purity: Purity::Pure,
@@ -231,6 +231,7 @@ impl SubstitutionMap {
Rc::new(Node {
identity: node.identity.clone(),
kind: new_kind,
comments: node.comments.clone(),
ty: metrics,
})
}
+3
View File
@@ -150,6 +150,7 @@ impl Specializer {
identity: node.identity,
kind: new_kind,
ty: metrics,
comments: node.comments.clone(),
}
}
@@ -262,6 +263,7 @@ impl Specializer {
identity: template.identity.clone(),
kind: NodeKind::Constant(val.clone()),
ty: ty.clone(),
comments: template.comments.clone(),
});
Node {
identity: template.identity.clone(),
@@ -271,6 +273,7 @@ impl Specializer {
purity: Purity::Pure,
is_recursive: false,
},
comments: template.comments.clone(),
}
}
}
+15
View File
@@ -206,6 +206,7 @@ impl TypeChecker {
},
},
ty: fn_ty,
comments: node.comments.clone(),
}
}
_ => {
@@ -269,6 +270,7 @@ impl TypeChecker {
},
},
ty: fn_ty,
comments: node.comments.clone(),
}
}
@@ -303,11 +305,13 @@ impl TypeChecker {
},
},
ty: specialized_ty.clone(),
comments: pattern.comments.clone(),
}),
value: Rc::new(Node {
identity: node.identity.clone(),
kind: NodeKind::Nop,
ty: specialized_ty.clone(),
comments: Rc::from([]),
}),
info: DefBinding {
captured_by: info.captured_by.clone(),
@@ -338,11 +342,13 @@ impl TypeChecker {
identity: node.identity.clone(),
kind: NodeKind::Nop,
ty: specialized_ty.clone(),
comments: Rc::from([]),
}),
value: Rc::new(Node {
identity: node.identity.clone(),
kind: NodeKind::Nop,
ty: specialized_ty.clone(),
comments: Rc::from([]),
}),
info: AssignBinding {
addr: info.addr,
@@ -385,6 +391,7 @@ impl TypeChecker {
identity: node.identity.clone(),
kind,
ty,
comments: node.comments.clone(),
}
}
@@ -416,6 +423,7 @@ impl TypeChecker {
identity: node.identity.clone(),
kind: NodeKind::Error,
ty: StaticType::Error,
comments: node.comments.clone(),
};
}
}
@@ -447,6 +455,7 @@ impl TypeChecker {
elements: typed_elements,
},
ty: StaticType::Tuple(elem_types),
comments: node.comments.clone(),
}
}
@@ -495,6 +504,7 @@ impl TypeChecker {
},
},
ty,
comments: node.comments.clone(),
};
}
@@ -519,6 +529,7 @@ impl TypeChecker {
_ => NodeKind::Error,
},
ty: ty.clone(),
comments: pattern.comments.clone(),
};
(
@@ -617,6 +628,7 @@ impl TypeChecker {
identity: node.identity.clone(),
kind: NodeKind::Nop,
ty: ty.clone(),
comments: Rc::from([]),
})
};
@@ -776,6 +788,7 @@ impl TypeChecker {
elements: final_elements,
},
ty: StaticType::Tuple(elem_types),
comments: args.comments.clone(),
}
} else {
self.check_node(args, ctx, diag)
@@ -819,6 +832,7 @@ impl TypeChecker {
elements: typed_elements,
},
ty: StaticType::Tuple(elem_types),
comments: args.comments.clone(),
}
} else {
self.check_node(args, ctx, diag)
@@ -948,6 +962,7 @@ impl TypeChecker {
identity: node.identity.clone(),
kind,
ty,
comments: node.comments.clone(),
}
}
}