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
+6 -4
View File
@@ -1,5 +1,5 @@
;; Benchmark: 1.2us ;; Benchmark: 1.2us
;; Benchmark-Repeat: 1731 ;; Benchmark-Repeat: 1731
;; Output: [150 130 "Insufficient funds" 130] ;; Output: [150 130 "Insufficient funds" 130]
; --------------------------------------------------------- ; ---------------------------------------------------------
@@ -36,10 +36,12 @@
; 2. Call 'deposit' method ; 2. Call 'deposit' method
; Note the double parens: (.deposit my-acc) gets the function, then we call it ; Note the double parens: (.deposit my-acc) gets the function, then we call it
(def b1 ((.deposit my-acc) 50)) ; balance is now 150 ; balance is now 150
(def b1 ((.deposit my-acc) 50))
; 3. Call 'withdraw' method ; 3. Call 'withdraw' method
(def b2 ((.withdraw my-acc) 20)) ; balance is now 130 ; balance is now 130
(def b2 ((.withdraw my-acc) 20))
; 4. Call 'withdraw' with invalid amount ; 4. Call 'withdraw' with invalid amount
(def error-msg ((.withdraw my-acc) 1000)) (def error-msg ((.withdraw my-acc) 1000))
+7 -5
View File
@@ -1,13 +1,15 @@
;; Benchmark: 102ns ;; Benchmark: 102ns
;; Benchmark-Repeat: 20685 ;; Benchmark-Repeat: 20685
;; Output: [42 150] ;; Output: [42 150]
(do (do
;; 1. Provokation Stack-Gap (bei Optimization Level 2) ;; 1. Provokation Stack-Gap (bei Optimization Level 2)
(def result (def result
(fn [] (fn []
(do (do
(def unused 10) ;; Wird entfernt, Slot 0 ist dann "leer" ;; Wird entfernt, Slot 0 ist dann "leer"
(def used 42) ;; Bleibt auf Slot 1 -> Lücke! (def unused 10)
;; Bleibt auf Slot 1 -> Lücke!
(def used 42)
used))) used)))
;; 2. Provokation Inlining-Blockade ;; 2. Provokation Inlining-Blockade
+2 -1
View File
@@ -17,7 +17,8 @@
(pipe [ticker] (pipe [ticker]
(fn [_] (fn [_]
(do (do
(def change (* (- (random) 0.5) 2.0)) ; Matches Rust: (rng.f64() - 0.5) * 2.0 ; Matches Rust: (rng.f64() - 0.5) * 2.0
(def change (* (- (random) 0.5) 2.0))
(def open last-close) (def open last-close)
(def high (+ open (abs (* (random) 2.0)))) (def high (+ open (abs (* (random) 2.0))))
(def low (- open (abs (* (random) 2.0)))) (def low (- open (abs (* (random) 2.0))))
+1
View File
@@ -298,6 +298,7 @@ impl<'a> Analyzer<'a> {
Node { Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: new_kind, kind: new_kind,
comments: node.comments.clone(),
ty: NodeMetrics { ty: NodeMetrics {
original: node_rc, original: node_rc,
purity, purity,
+2
View File
@@ -539,6 +539,7 @@ impl Binder {
self.make_node(node.identity.clone(), NodeKind::Error) self.make_node(node.identity.clone(), NodeKind::Error)
} }
SyntaxKind::Error => Node { SyntaxKind::Error => Node {
comments: node.comments.clone(),
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Error, kind: NodeKind::Error,
ty: (), ty: (),
@@ -701,6 +702,7 @@ impl Binder {
fn make_node(&self, identity: Identity, kind: NodeKind<BoundPhase>) -> Node<BoundPhase> { fn make_node(&self, identity: Identity, kind: NodeKind<BoundPhase>) -> Node<BoundPhase> {
Node { Node {
comments: std::rc::Rc::from([]),
identity, identity,
kind, kind,
ty: (), ty: (),
+4 -2
View File
@@ -79,9 +79,10 @@ impl Lowering {
ty: RuntimeMetadata { ty: RuntimeMetadata {
ty: node.ty.original.ty.clone(), ty: node.ty.original.ty.clone(),
is_tail: is_tail_position, is_tail: is_tail_position,
original: node_rc, original: node_rc.clone(),
stack_size: 0, stack_size: 0,
}, },
comments: node.comments.clone(),
}; };
} }
@@ -261,9 +262,10 @@ impl Lowering {
ty: RuntimeMetadata { ty: RuntimeMetadata {
ty: node.ty.original.ty.clone(), ty: node.ty.original.ty.clone(),
is_tail: is_tail_position, is_tail: is_tail_position,
original: node_rc, original: node_rc.clone(),
stack_size, 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)?; let p_names = self.extract_param_names(&params)?;
self.registry.define(name.name, p_names, (*body).clone()); self.registry.define(name.name, p_names, (*body).clone());
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Nop, kind: SyntaxKind::Nop,
ty: (), ty: (),
@@ -128,6 +129,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_args = self.expand_recursive((*args).clone())?; let expanded_args = self.expand_recursive((*args).clone())?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Call { kind: SyntaxKind::Call {
callee: Rc::new(expanded_callee), callee: Rc::new(expanded_callee),
@@ -146,6 +148,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
self.registry.pop(); self.registry.pop();
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Block { kind: SyntaxKind::Block {
exprs: expanded_exprs, exprs: expanded_exprs,
@@ -161,6 +164,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
self.registry.pop(); self.registry.pop();
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Lambda { kind: SyntaxKind::Lambda {
params: Rc::new(expanded_params), params: Rc::new(expanded_params),
@@ -184,6 +188,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
None None
}; };
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::If { kind: SyntaxKind::If {
cond: Rc::new(cond), cond: Rc::new(cond),
@@ -198,6 +203,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let pattern = self.expand_recursive((*pattern).clone())?; let pattern = self.expand_recursive((*pattern).clone())?;
let value = self.expand_recursive((*value).clone())?; let value = self.expand_recursive((*value).clone())?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Def { kind: SyntaxKind::Def {
pattern: Rc::new(pattern), pattern: Rc::new(pattern),
@@ -212,6 +218,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let target = self.expand_recursive((*target).clone())?; let target = self.expand_recursive((*target).clone())?;
let value = self.expand_recursive((*value).clone())?; let value = self.expand_recursive((*value).clone())?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Assign { kind: SyntaxKind::Assign {
target: Rc::new(target), target: Rc::new(target),
@@ -228,6 +235,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
expanded_elements.push(Rc::new(self.expand_recursive((*e).clone())?)); expanded_elements.push(Rc::new(self.expand_recursive((*e).clone())?));
} }
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Tuple { kind: SyntaxKind::Tuple {
elements: expanded_elements, elements: expanded_elements,
@@ -245,6 +253,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
)); ));
} }
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Record { kind: SyntaxKind::Record {
fields: expanded_fields, fields: expanded_fields,
@@ -257,6 +266,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Expansion { original_call, expanded } => { SyntaxKind::Expansion { original_call, expanded } => {
let expanded = self.expand_recursive((*expanded).clone())?; let expanded = self.expand_recursive((*expanded).clone())?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Expansion { kind: SyntaxKind::Expansion {
original_call, original_call,
@@ -269,6 +279,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Again { args } => { SyntaxKind::Again { args } => {
let expanded_args = self.expand_recursive((*args).clone())?; let expanded_args = self.expand_recursive((*args).clone())?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Again { kind: SyntaxKind::Again {
args: Rc::new(expanded_args), args: Rc::new(expanded_args),
@@ -316,9 +327,11 @@ impl<E: MacroEvaluator> MacroExpander<E> {
}; };
let original_call = SyntaxNode { let original_call = SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(), identity: identity.clone(),
kind: SyntaxKind::Call { kind: SyntaxKind::Call {
callee: Rc::new(SyntaxNode { callee: Rc::new(SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(), identity: identity.clone(),
kind: SyntaxKind::Identifier { kind: SyntaxKind::Identifier {
symbol: Symbol::from(name), symbol: Symbol::from(name),
@@ -327,6 +340,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
ty: (), ty: (),
}), }),
args: Rc::new(SyntaxNode { args: Rc::new(SyntaxNode {
comments: std::rc::Rc::from([]),
identity: identity.clone(), identity: identity.clone(),
kind: SyntaxKind::Tuple { kind: SyntaxKind::Tuple {
elements: bindings.into_values().map(Rc::new).collect(), elements: bindings.into_values().map(Rc::new).collect(),
@@ -338,6 +352,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
}; };
Ok(SyntaxNode { Ok(SyntaxNode {
comments: std::rc::Rc::from([]),
identity, identity,
kind: SyntaxKind::Expansion { kind: SyntaxKind::Expansion {
original_call: Rc::new(original_call), original_call: Rc::new(original_call),
@@ -371,6 +386,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
// Inside a template, all internal identifiers are colored. // Inside a template, all internal identifiers are colored.
symbol.context = Some(state.expansion_id.clone()); symbol.context = Some(state.expansion_id.clone());
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Identifier { kind: SyntaxKind::Identifier {
symbol, symbol,
@@ -406,6 +422,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let pattern = self.expand_template((*pattern).clone(), state)?; let pattern = self.expand_template((*pattern).clone(), state)?;
let val = self.expand_template((*value).clone(), state)?; let val = self.expand_template((*value).clone(), state)?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Def { kind: SyntaxKind::Def {
pattern: Rc::new(pattern), pattern: Rc::new(pattern),
@@ -420,6 +437,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let target = self.expand_template((*target).clone(), state)?; let target = self.expand_template((*target).clone(), state)?;
let value = self.expand_template((*value).clone(), state)?; let value = self.expand_template((*value).clone(), state)?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Assign { kind: SyntaxKind::Assign {
target: Rc::new(target), target: Rc::new(target),
@@ -441,6 +459,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
} }
} }
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Tuple { kind: SyntaxKind::Tuple {
elements: new_elements, elements: new_elements,
@@ -460,6 +479,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
} }
} }
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Block { exprs: new_exprs }, kind: SyntaxKind::Block { exprs: new_exprs },
ty: (), ty: (),
@@ -475,6 +495,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
)); ));
} }
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Record { kind: SyntaxKind::Record {
fields: new_fields, fields: new_fields,
@@ -488,6 +509,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_callee = self.expand_template((*callee).clone(), state)?; let expanded_callee = self.expand_template((*callee).clone(), state)?;
let expanded_args = self.expand_template((*args).clone(), state)?; let expanded_args = self.expand_template((*args).clone(), state)?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Call { kind: SyntaxKind::Call {
callee: Rc::new(expanded_callee), callee: Rc::new(expanded_callee),
@@ -510,6 +532,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
None None
}; };
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::If { kind: SyntaxKind::If {
cond: Rc::new(cond), cond: Rc::new(cond),
@@ -524,6 +547,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
let expanded_params = self.expand_template((*params).clone(), state)?; let expanded_params = self.expand_template((*params).clone(), state)?;
let body = self.expand_template((*body).clone(), state)?; let body = self.expand_template((*body).clone(), state)?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Lambda { kind: SyntaxKind::Lambda {
params: Rc::new(expanded_params), params: Rc::new(expanded_params),
@@ -537,6 +561,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
SyntaxKind::Again { args } => { SyntaxKind::Again { args } => {
let expanded_args = self.expand_template((*args).clone(), state)?; let expanded_args = self.expand_template((*args).clone(), state)?;
Ok(SyntaxNode { Ok(SyntaxNode {
comments: node.comments.clone(),
identity: node.identity, identity: node.identity,
kind: SyntaxKind::Again { kind: SyntaxKind::Again {
args: Rc::new(expanded_args), args: Rc::new(expanded_args),
@@ -582,6 +607,7 @@ impl<E: MacroEvaluator> MacroExpander<E> {
match val { match val {
Value::Quote(rc) => rc.as_ref().clone(), Value::Quote(rc) => rc.as_ref().clone(),
_ => SyntaxNode { _ => SyntaxNode {
comments: std::rc::Rc::from([]),
identity, identity,
kind: SyntaxKind::Constant(val), kind: SyntaxKind::Constant(val),
ty: (), ty: (),
+2
View File
@@ -724,6 +724,7 @@ impl Optimizer {
Rc::new(Node { Rc::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: new_kind, kind: new_kind,
comments: node.comments.clone(),
ty: metrics, ty: metrics,
}) })
} }
@@ -780,6 +781,7 @@ impl Optimizer {
_ => return node_rc.clone(), _ => return node_rc.clone(),
}; };
Rc::new(Node { Rc::new(Node {
comments: node.comments.clone(),
identity: node.identity.clone(), identity: node.identity.clone(),
kind: new_kind, kind: new_kind,
ty: node.ty.clone(), ty: node.ty.clone(),
+4
View File
@@ -19,11 +19,13 @@ impl<'a> Folder<'a> {
let typed_original = Rc::new(Node { let typed_original = Rc::new(Node {
identity: template.identity.clone(), identity: template.identity.clone(),
kind: NodeKind::Constant(val.clone()), kind: NodeKind::Constant(val.clone()),
comments: template.comments.clone(),
ty: ty.clone(), ty: ty.clone(),
}); });
Node { Node {
identity: template.identity.clone(), identity: template.identity.clone(),
kind: NodeKind::Constant(val), kind: NodeKind::Constant(val),
comments: template.comments.clone(),
ty: NodeMetrics { ty: NodeMetrics {
original: typed_original, original: typed_original,
purity: Purity::Pure, purity: Purity::Pure,
@@ -36,11 +38,13 @@ impl<'a> Folder<'a> {
let typed_original = Rc::new(Node { let typed_original = Rc::new(Node {
identity: template.identity.clone(), identity: template.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
comments: template.comments.clone(),
ty: StaticType::Void, ty: StaticType::Void,
}); });
Node { Node {
identity: template.identity.clone(), identity: template.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
comments: template.comments.clone(),
ty: NodeMetrics { ty: NodeMetrics {
original: typed_original, original: typed_original,
purity: Purity::Pure, purity: Purity::Pure,
@@ -231,6 +231,7 @@ impl SubstitutionMap {
Rc::new(Node { Rc::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: new_kind, kind: new_kind,
comments: node.comments.clone(),
ty: metrics, ty: metrics,
}) })
} }
+3
View File
@@ -150,6 +150,7 @@ impl Specializer {
identity: node.identity, identity: node.identity,
kind: new_kind, kind: new_kind,
ty: metrics, ty: metrics,
comments: node.comments.clone(),
} }
} }
@@ -262,6 +263,7 @@ impl Specializer {
identity: template.identity.clone(), identity: template.identity.clone(),
kind: NodeKind::Constant(val.clone()), kind: NodeKind::Constant(val.clone()),
ty: ty.clone(), ty: ty.clone(),
comments: template.comments.clone(),
}); });
Node { Node {
identity: template.identity.clone(), identity: template.identity.clone(),
@@ -271,6 +273,7 @@ impl Specializer {
purity: Purity::Pure, purity: Purity::Pure,
is_recursive: false, is_recursive: false,
}, },
comments: template.comments.clone(),
} }
} }
} }
+15
View File
@@ -206,6 +206,7 @@ impl TypeChecker {
}, },
}, },
ty: fn_ty, ty: fn_ty,
comments: node.comments.clone(),
} }
} }
_ => { _ => {
@@ -269,6 +270,7 @@ impl TypeChecker {
}, },
}, },
ty: fn_ty, ty: fn_ty,
comments: node.comments.clone(),
} }
} }
@@ -303,11 +305,13 @@ impl TypeChecker {
}, },
}, },
ty: specialized_ty.clone(), ty: specialized_ty.clone(),
comments: pattern.comments.clone(),
}), }),
value: Rc::new(Node { value: Rc::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
ty: specialized_ty.clone(), ty: specialized_ty.clone(),
comments: Rc::from([]),
}), }),
info: DefBinding { info: DefBinding {
captured_by: info.captured_by.clone(), captured_by: info.captured_by.clone(),
@@ -338,11 +342,13 @@ impl TypeChecker {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
ty: specialized_ty.clone(), ty: specialized_ty.clone(),
comments: Rc::from([]),
}), }),
value: Rc::new(Node { value: Rc::new(Node {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
ty: specialized_ty.clone(), ty: specialized_ty.clone(),
comments: Rc::from([]),
}), }),
info: AssignBinding { info: AssignBinding {
addr: info.addr, addr: info.addr,
@@ -385,6 +391,7 @@ impl TypeChecker {
identity: node.identity.clone(), identity: node.identity.clone(),
kind, kind,
ty, ty,
comments: node.comments.clone(),
} }
} }
@@ -416,6 +423,7 @@ impl TypeChecker {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Error, kind: NodeKind::Error,
ty: StaticType::Error, ty: StaticType::Error,
comments: node.comments.clone(),
}; };
} }
} }
@@ -447,6 +455,7 @@ impl TypeChecker {
elements: typed_elements, elements: typed_elements,
}, },
ty: StaticType::Tuple(elem_types), ty: StaticType::Tuple(elem_types),
comments: node.comments.clone(),
} }
} }
@@ -495,6 +504,7 @@ impl TypeChecker {
}, },
}, },
ty, ty,
comments: node.comments.clone(),
}; };
} }
@@ -519,6 +529,7 @@ impl TypeChecker {
_ => NodeKind::Error, _ => NodeKind::Error,
}, },
ty: ty.clone(), ty: ty.clone(),
comments: pattern.comments.clone(),
}; };
( (
@@ -617,6 +628,7 @@ impl TypeChecker {
identity: node.identity.clone(), identity: node.identity.clone(),
kind: NodeKind::Nop, kind: NodeKind::Nop,
ty: ty.clone(), ty: ty.clone(),
comments: Rc::from([]),
}) })
}; };
@@ -776,6 +788,7 @@ impl TypeChecker {
elements: final_elements, elements: final_elements,
}, },
ty: StaticType::Tuple(elem_types), ty: StaticType::Tuple(elem_types),
comments: args.comments.clone(),
} }
} else { } else {
self.check_node(args, ctx, diag) self.check_node(args, ctx, diag)
@@ -819,6 +832,7 @@ impl TypeChecker {
elements: typed_elements, elements: typed_elements,
}, },
ty: StaticType::Tuple(elem_types), ty: StaticType::Tuple(elem_types),
comments: args.comments.clone(),
} }
} else { } else {
self.check_node(args, ctx, diag) self.check_node(args, ctx, diag)
@@ -948,6 +962,7 @@ impl TypeChecker {
identity: node.identity.clone(), identity: node.identity.clone(),
kind, kind,
ty, ty,
comments: node.comments.clone(),
} }
} }
} }
+2
View File
@@ -549,6 +549,7 @@ impl Environment {
identity: bound_ast.identity.clone(), identity: bound_ast.identity.clone(),
kind: NodeKind::Tuple { elements: vec![] }, kind: NodeKind::Tuple { elements: vec![] },
ty: (), ty: (),
comments: Rc::from([]),
}), }),
body: std::rc::Rc::new(bound_ast), body: std::rc::Rc::new(bound_ast),
info: LambdaBinding { info: LambdaBinding {
@@ -557,6 +558,7 @@ impl Environment {
}, },
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
}; };
Some(checker.check(&wrapped_ast, &[], diagnostics)) Some(checker.check(&wrapped_ast, &[], diagnostics))
+66 -5
View File
@@ -27,12 +27,15 @@ pub enum TokenKind {
pub struct Token { pub struct Token {
pub kind: TokenKind, pub kind: TokenKind,
pub location: SourceLocation, pub location: SourceLocation,
pub comments: Rc<[Rc<str>]>,
} }
pub struct Lexer<'a> { pub struct Lexer<'a> {
input: Peekable<Chars<'a>>, input: Peekable<Chars<'a>>,
line: u32, line: u32,
col: u32, col: u32,
at_line_start: bool,
comments_buffer: Vec<Rc<str>>,
} }
impl<'a> Lexer<'a> { impl<'a> Lexer<'a> {
@@ -41,11 +44,29 @@ impl<'a> Lexer<'a> {
input: input.chars().peekable(), input: input.chars().peekable(),
line: 1, line: 1,
col: 1, col: 1,
at_line_start: true,
comments_buffer: Vec::new(),
} }
} }
pub fn next_token(&mut self) -> Result<Token, String> { pub fn next_token(&mut self) -> Result<Token, String> {
self.skip_whitespace(); self.skip_whitespace_and_comments()?;
let comments: Rc<[Rc<str>]> = if self.comments_buffer.is_empty() {
Rc::from([])
} else {
let mut start = 0;
while start < self.comments_buffer.len() && self.comments_buffer[start].is_empty() {
start += 1;
}
let mut end = self.comments_buffer.len();
while end > start && self.comments_buffer[end - 1].is_empty() {
end -= 1;
}
let res: Rc<[Rc<str>]> = self.comments_buffer[start..end].iter().cloned().collect();
self.comments_buffer.clear();
res
};
let start_location = SourceLocation { let start_location = SourceLocation {
line: self.line, line: self.line,
@@ -62,6 +83,7 @@ impl<'a> Lexer<'a> {
return Ok(Token { return Ok(Token {
kind: TokenKind::EOF, kind: TokenKind::EOF,
location: start_location, location: start_location,
comments,
}); });
} }
}; };
@@ -119,6 +141,7 @@ impl<'a> Lexer<'a> {
Ok(Token { Ok(Token {
kind, kind,
location: start_location, location: start_location,
comments,
}) })
} }
@@ -126,28 +149,66 @@ impl<'a> Lexer<'a> {
self.input.peek() self.input.peek()
} }
fn skip_whitespace(&mut self) { fn skip_whitespace_and_comments(&mut self) -> Result<(), String> {
let mut consecutive_newlines = 0;
while let Some(&c) = self.peek() { while let Some(&c) = self.peek() {
if c.is_whitespace() || is_invisible(c) || c == ',' { if c.is_whitespace() || is_invisible(c) || c == ',' {
if c == '\n' { if c == '\n' {
self.line += 1; self.line += 1;
self.col = 1; self.col = 1;
self.at_line_start = true;
consecutive_newlines += 1;
} else { } else {
self.col += 1; self.col += 1;
} }
self.input.next(); self.input.next();
} else if c == ';' || c == '#' { } else if c == ';' {
for c in self.input.by_ref() { if !self.at_line_start {
if c == '\n' { return Err(format!("Inline comments are not allowed at {}:{}", self.line, self.col));
}
if !self.comments_buffer.is_empty() && consecutive_newlines > 1 {
for _ in 0..(consecutive_newlines - 1) {
self.comments_buffer.push(Rc::from(""));
}
}
consecutive_newlines = 0;
self.input.next(); // consume ';'
self.col += 1;
if let Some(&' ') = self.peek() {
self.input.next();
self.col += 1;
}
let mut comment_text = String::new();
while let Some(&cc) = self.peek() {
if cc == '\n' {
break;
}
comment_text.push(self.input.next().unwrap());
self.col += 1;
}
self.comments_buffer.push(Rc::from(comment_text));
} else if c == '#' {
if !self.at_line_start {
return Err(format!("Inline directives are not allowed at {}:{}", self.line, self.col));
}
for cc in self.input.by_ref() {
if cc == '\n' {
self.line += 1; self.line += 1;
self.col = 1; self.col = 1;
self.at_line_start = true;
consecutive_newlines += 1;
break; break;
} }
} }
} else { } else {
self.at_line_start = false;
break; break;
} }
} }
Ok(())
} }
fn read_while<F>(&mut self, mut predicate: F) -> String fn read_while<F>(&mut self, mut predicate: F) -> String
+2
View File
@@ -250,6 +250,7 @@ pub struct Node<P: CompilerPhase = BoundPhase> {
pub identity: Identity, pub identity: Identity,
pub kind: NodeKind<P>, pub kind: NodeKind<P>,
pub ty: P::Metadata, pub ty: P::Metadata,
pub comments: Rc<[Rc<str>]>,
} }
impl<P: CompilerPhase> Clone for Node<P> { impl<P: CompilerPhase> Clone for Node<P> {
@@ -258,6 +259,7 @@ impl<P: CompilerPhase> Clone for Node<P> {
identity: self.identity.clone(), identity: self.identity.clone(),
kind: self.kind.clone(), kind: self.kind.clone(),
ty: self.ty.clone(), ty: self.ty.clone(),
comments: self.comments.clone(),
} }
} }
} }
+37 -7
View File
@@ -21,6 +21,7 @@ impl<'a> Parser<'a> {
Token { Token {
kind: TokenKind::EOF, kind: TokenKind::EOF,
location: SourceLocation { line: 1, col: 1 }, location: SourceLocation { line: 1, col: 1 },
comments: Rc::from([]),
} }
} }
}; };
@@ -40,6 +41,7 @@ impl<'a> Parser<'a> {
Token { Token {
kind: TokenKind::EOF, kind: TokenKind::EOF,
location: self.current_token.location, location: self.current_token.location,
comments: Rc::from([]),
} }
} }
}; };
@@ -59,7 +61,7 @@ impl<'a> Parser<'a> {
TokenKind::LeftBracket => self.parse_vector_literal(), TokenKind::LeftBracket => self.parse_vector_literal(),
TokenKind::LeftBrace => self.parse_record_literal(), TokenKind::LeftBrace => self.parse_record_literal(),
TokenKind::Quote => { TokenKind::Quote => {
self.advance(); // consume ' let token = self.advance(); // consume '
let expr = self.parse_expression(); let expr = self.parse_expression();
SyntaxNode { SyntaxNode {
identity: identity.clone(), identity: identity.clone(),
@@ -71,22 +73,25 @@ impl<'a> Parser<'a> {
elements: vec![Rc::new(expr)], elements: vec![Rc::new(expr)],
}, },
ty: (), ty: (),
comments: Rc::from([]),
}), }),
}, },
ty: (), ty: (),
comments: token.comments,
} }
} }
TokenKind::Backtick => { TokenKind::Backtick => {
self.advance(); // consume ` let token = self.advance(); // consume `
let expr = self.parse_expression(); let expr = self.parse_expression();
SyntaxNode { SyntaxNode {
identity, identity,
kind: SyntaxKind::Template(Rc::new(expr)), kind: SyntaxKind::Template(Rc::new(expr)),
ty: (), ty: (),
comments: token.comments,
} }
} }
TokenKind::Tilde => { TokenKind::Tilde => {
self.advance(); // consume ~ let token = self.advance(); // consume ~
if *self.peek() == TokenKind::At { if *self.peek() == TokenKind::At {
self.advance(); // consume @ self.advance(); // consume @
let expr = self.parse_expression(); let expr = self.parse_expression();
@@ -94,6 +99,7 @@ impl<'a> Parser<'a> {
identity, identity,
kind: SyntaxKind::Splice(Rc::new(expr)), kind: SyntaxKind::Splice(Rc::new(expr)),
ty: (), ty: (),
comments: token.comments,
} }
} else { } else {
let expr = self.parse_expression(); let expr = self.parse_expression();
@@ -101,6 +107,7 @@ impl<'a> Parser<'a> {
identity, identity,
kind: SyntaxKind::Placeholder(Rc::new(expr)), kind: SyntaxKind::Placeholder(Rc::new(expr)),
ty: (), ty: (),
comments: token.comments,
} }
} }
} }
@@ -159,12 +166,13 @@ impl<'a> Parser<'a> {
identity, identity,
kind, kind,
ty: (), ty: (),
comments: token.comments,
} }
} }
fn parse_list(&mut self) -> SyntaxNode { fn parse_list(&mut self) -> SyntaxNode {
let start_loc = self.advance().location; // consume '(' let token = self.advance(); // consume '('
let identity = NodeIdentity::new(start_loc); let identity = NodeIdentity::new(token.location);
if *self.peek() == TokenKind::RightParen { if *self.peek() == TokenKind::RightParen {
self.diagnostics.push_error( self.diagnostics.push_error(
@@ -176,12 +184,13 @@ impl<'a> Parser<'a> {
identity, identity,
kind: SyntaxKind::Error, kind: SyntaxKind::Error,
ty: (), ty: (),
comments: token.comments,
}; };
} }
let head = self.parse_expression(); let head = self.parse_expression();
let node = if let SyntaxKind::Identifier { ref symbol, .. } = head.kind { let mut node = if let SyntaxKind::Identifier { ref symbol, .. } = head.kind {
match symbol.name.as_ref() { match symbol.name.as_ref() {
"if" => self.parse_if(identity), "if" => self.parse_if(identity),
"fn" => self.parse_fn(identity), "fn" => self.parse_fn(identity),
@@ -197,6 +206,7 @@ impl<'a> Parser<'a> {
}; };
self.expect(TokenKind::RightParen); self.expect(TokenKind::RightParen);
node.comments = token.comments;
node node
} }
@@ -211,6 +221,7 @@ impl<'a> Parser<'a> {
identity: identity.clone(), identity: identity.clone(),
kind: SyntaxKind::Tuple { elements }, kind: SyntaxKind::Tuple { elements },
ty: (), ty: (),
comments: Rc::from([]),
}; };
SyntaxNode { SyntaxNode {
@@ -219,6 +230,7 @@ impl<'a> Parser<'a> {
args: Rc::new(args_node), args: Rc::new(args_node),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -239,6 +251,7 @@ impl<'a> Parser<'a> {
else_br, else_br,
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -254,6 +267,7 @@ impl<'a> Parser<'a> {
info: (), info: (),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -270,6 +284,7 @@ impl<'a> Parser<'a> {
info: (), info: (),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -282,6 +297,7 @@ impl<'a> Parser<'a> {
identity, identity,
kind: SyntaxKind::Block { exprs }, kind: SyntaxKind::Block { exprs },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -297,6 +313,7 @@ impl<'a> Parser<'a> {
info: (), info: (),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -322,6 +339,7 @@ impl<'a> Parser<'a> {
body: Rc::new(body), body: Rc::new(body),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -338,6 +356,7 @@ impl<'a> Parser<'a> {
identity: NodeIdentity::new(self.current_token.location), identity: NodeIdentity::new(self.current_token.location),
kind: SyntaxKind::Error, kind: SyntaxKind::Error,
ty: (), ty: (),
comments: Rc::from([]),
}; };
} }
self.parse_pattern() self.parse_pattern()
@@ -359,6 +378,7 @@ impl<'a> Parser<'a> {
binding: (), binding: (),
}, },
ty: (), ty: (),
comments: token.comments,
} }
} }
TokenKind::LeftBracket => { TokenKind::LeftBracket => {
@@ -375,6 +395,7 @@ impl<'a> Parser<'a> {
identity, identity,
kind: SyntaxKind::Tuple { elements }, kind: SyntaxKind::Tuple { elements },
ty: (), ty: (),
comments: token.comments,
} }
} }
TokenKind::Tilde => { TokenKind::Tilde => {
@@ -386,6 +407,7 @@ impl<'a> Parser<'a> {
identity: NodeIdentity::new(token.location), identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Splice(Rc::new(expr)), kind: SyntaxKind::Splice(Rc::new(expr)),
ty: (), ty: (),
comments: token.comments,
} }
} else { } else {
let expr = self.parse_expression(); let expr = self.parse_expression();
@@ -393,6 +415,7 @@ impl<'a> Parser<'a> {
identity: NodeIdentity::new(token.location), identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Placeholder(Rc::new(expr)), kind: SyntaxKind::Placeholder(Rc::new(expr)),
ty: (), ty: (),
comments: token.comments,
} }
} }
} }
@@ -404,11 +427,12 @@ impl<'a> Parser<'a> {
), ),
Some(NodeIdentity::new(self.current_token.location)), Some(NodeIdentity::new(self.current_token.location)),
); );
self.advance(); let token = self.advance();
SyntaxNode { SyntaxNode {
identity: NodeIdentity::new(self.current_token.location), identity: NodeIdentity::new(self.current_token.location),
kind: SyntaxKind::Error, kind: SyntaxKind::Error,
ty: (), ty: (),
comments: token.comments,
} }
} }
} }
@@ -426,6 +450,7 @@ impl<'a> Parser<'a> {
identity: identity.clone(), identity: identity.clone(),
kind: SyntaxKind::Tuple { elements }, kind: SyntaxKind::Tuple { elements },
ty: (), ty: (),
comments: Rc::from([]),
}; };
SyntaxNode { SyntaxNode {
@@ -435,6 +460,7 @@ impl<'a> Parser<'a> {
args: Rc::new(args_node), args: Rc::new(args_node),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
@@ -453,6 +479,7 @@ impl<'a> Parser<'a> {
identity: NodeIdentity::new(token.location), identity: NodeIdentity::new(token.location),
kind: SyntaxKind::Tuple { elements }, kind: SyntaxKind::Tuple { elements },
ty: (), ty: (),
comments: token.comments,
} }
} }
@@ -495,6 +522,7 @@ impl<'a> Parser<'a> {
layout: (), layout: (),
}, },
ty: (), ty: (),
comments: token.comments,
} }
} }
@@ -511,6 +539,7 @@ impl<'a> Parser<'a> {
Token { Token {
kind, kind,
location: self.current_token.location, location: self.current_token.location,
comments: Rc::from([]),
} }
} }
} }
@@ -523,6 +552,7 @@ impl<'a> Parser<'a> {
binding: (), binding: (),
}, },
ty: (), ty: (),
comments: Rc::from([]),
} }
} }
} }