diff --git a/examples/object_records.myc b/examples/object_records.myc index 4e38246..04afe5b 100644 --- a/examples/object_records.myc +++ b/examples/object_records.myc @@ -1,5 +1,5 @@ -;; Benchmark: 1.2us -;; Benchmark-Repeat: 1731 +;; Benchmark: 1.2us +;; Benchmark-Repeat: 1731 ;; Output: [150 130 "Insufficient funds" 130] ; --------------------------------------------------------- @@ -36,10 +36,12 @@ ; 2. Call 'deposit' method ; 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 - (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 (def error-msg ((.withdraw my-acc) 1000)) diff --git a/examples/optimizer_repro.myc b/examples/optimizer_repro.myc index 674c62f..38c338f 100644 --- a/examples/optimizer_repro.myc +++ b/examples/optimizer_repro.myc @@ -1,13 +1,15 @@ -;; Benchmark: 102ns -;; Benchmark-Repeat: 20685 -;; Output: [42 150] +;; Benchmark: 102ns +;; Benchmark-Repeat: 20685 +;; Output: [42 150] (do ;; 1. Provokation Stack-Gap (bei Optimization Level 2) (def result (fn [] (do - (def unused 10) ;; Wird entfernt, Slot 0 ist dann "leer" - (def used 42) ;; Bleibt auf Slot 1 -> Lücke! + ;; Wird entfernt, Slot 0 ist dann "leer" + (def unused 10) + ;; Bleibt auf Slot 1 -> Lücke! + (def used 42) used))) ;; 2. Provokation Inlining-Blockade diff --git a/examples/pipeline_script_ticker.myc b/examples/pipeline_script_ticker.myc index ded939a..f2d2f77 100644 --- a/examples/pipeline_script_ticker.myc +++ b/examples/pipeline_script_ticker.myc @@ -17,7 +17,8 @@ (pipe [ticker] (fn [_] (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 high (+ open (abs (* (random) 2.0)))) (def low (- open (abs (* (random) 2.0)))) diff --git a/src/ast/compiler/analyzer.rs b/src/ast/compiler/analyzer.rs index fdc0a1a..6b850c5 100644 --- a/src/ast/compiler/analyzer.rs +++ b/src/ast/compiler/analyzer.rs @@ -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, diff --git a/src/ast/compiler/binder.rs b/src/ast/compiler/binder.rs index e09d7a9..ac0f06f 100644 --- a/src/ast/compiler/binder.rs +++ b/src/ast/compiler/binder.rs @@ -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) -> Node { Node { + comments: std::rc::Rc::from([]), identity, kind, ty: (), diff --git a/src/ast/compiler/lowering.rs b/src/ast/compiler/lowering.rs index 13b6e58..cf8ecc4 100644 --- a/src/ast/compiler/lowering.rs +++ b/src/ast/compiler/lowering.rs @@ -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(), } } } diff --git a/src/ast/compiler/macros.rs b/src/ast/compiler/macros.rs index 3138f29..77f376f 100644 --- a/src/ast/compiler/macros.rs +++ b/src/ast/compiler/macros.rs @@ -95,6 +95,7 @@ impl MacroExpander { let p_names = self.extract_param_names(¶ms)?; 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 MacroExpander { 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 MacroExpander { self.registry.pop(); Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::Block { exprs: expanded_exprs, @@ -161,6 +164,7 @@ impl MacroExpander { 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 MacroExpander { None }; Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::If { cond: Rc::new(cond), @@ -198,6 +203,7 @@ impl MacroExpander { 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 MacroExpander { 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 MacroExpander { 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 MacroExpander { )); } Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::Record { fields: expanded_fields, @@ -257,6 +266,7 @@ impl MacroExpander { 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 MacroExpander { 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 MacroExpander { }; 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 MacroExpander { 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 MacroExpander { }; Ok(SyntaxNode { + comments: std::rc::Rc::from([]), identity, kind: SyntaxKind::Expansion { original_call: Rc::new(original_call), @@ -371,6 +386,7 @@ impl MacroExpander { // 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 MacroExpander { 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 MacroExpander { 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 MacroExpander { } } Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::Tuple { elements: new_elements, @@ -460,6 +479,7 @@ impl MacroExpander { } } Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::Block { exprs: new_exprs }, ty: (), @@ -475,6 +495,7 @@ impl MacroExpander { )); } Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::Record { fields: new_fields, @@ -488,6 +509,7 @@ impl MacroExpander { 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 MacroExpander { None }; Ok(SyntaxNode { + comments: node.comments.clone(), identity: node.identity, kind: SyntaxKind::If { cond: Rc::new(cond), @@ -524,6 +547,7 @@ impl MacroExpander { 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 MacroExpander { 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 MacroExpander { match val { Value::Quote(rc) => rc.as_ref().clone(), _ => SyntaxNode { + comments: std::rc::Rc::from([]), identity, kind: SyntaxKind::Constant(val), ty: (), diff --git a/src/ast/compiler/optimizer/engine.rs b/src/ast/compiler/optimizer/engine.rs index 53fda84..239a72d 100644 --- a/src/ast/compiler/optimizer/engine.rs +++ b/src/ast/compiler/optimizer/engine.rs @@ -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(), diff --git a/src/ast/compiler/optimizer/folder.rs b/src/ast/compiler/optimizer/folder.rs index 7356c2e..6672dc7 100644 --- a/src/ast/compiler/optimizer/folder.rs +++ b/src/ast/compiler/optimizer/folder.rs @@ -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, diff --git a/src/ast/compiler/optimizer/substitution_map.rs b/src/ast/compiler/optimizer/substitution_map.rs index 53d3ec7..8be9700 100644 --- a/src/ast/compiler/optimizer/substitution_map.rs +++ b/src/ast/compiler/optimizer/substitution_map.rs @@ -231,6 +231,7 @@ impl SubstitutionMap { Rc::new(Node { identity: node.identity.clone(), kind: new_kind, + comments: node.comments.clone(), ty: metrics, }) } diff --git a/src/ast/compiler/specializer.rs b/src/ast/compiler/specializer.rs index 7893ee1..9d54469 100644 --- a/src/ast/compiler/specializer.rs +++ b/src/ast/compiler/specializer.rs @@ -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(), } } } diff --git a/src/ast/compiler/type_checker.rs b/src/ast/compiler/type_checker.rs index c747d44..b9ca6e7 100644 --- a/src/ast/compiler/type_checker.rs +++ b/src/ast/compiler/type_checker.rs @@ -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(), } } } diff --git a/src/ast/environment.rs b/src/ast/environment.rs index 90e6627..3f00730 100644 --- a/src/ast/environment.rs +++ b/src/ast/environment.rs @@ -549,6 +549,7 @@ impl Environment { identity: bound_ast.identity.clone(), kind: NodeKind::Tuple { elements: vec![] }, ty: (), + comments: Rc::from([]), }), body: std::rc::Rc::new(bound_ast), info: LambdaBinding { @@ -557,6 +558,7 @@ impl Environment { }, }, ty: (), + comments: Rc::from([]), } }; Some(checker.check(&wrapped_ast, &[], diagnostics)) diff --git a/src/ast/lexer.rs b/src/ast/lexer.rs index 3d7d176..a90019a 100644 --- a/src/ast/lexer.rs +++ b/src/ast/lexer.rs @@ -27,12 +27,15 @@ pub enum TokenKind { pub struct Token { pub kind: TokenKind, pub location: SourceLocation, + pub comments: Rc<[Rc]>, } pub struct Lexer<'a> { input: Peekable>, line: u32, col: u32, + at_line_start: bool, + comments_buffer: Vec>, } impl<'a> Lexer<'a> { @@ -41,11 +44,29 @@ impl<'a> Lexer<'a> { input: input.chars().peekable(), line: 1, col: 1, + at_line_start: true, + comments_buffer: Vec::new(), } } pub fn next_token(&mut self) -> Result { - self.skip_whitespace(); + self.skip_whitespace_and_comments()?; + + let comments: Rc<[Rc]> = 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]> = self.comments_buffer[start..end].iter().cloned().collect(); + self.comments_buffer.clear(); + res + }; let start_location = SourceLocation { line: self.line, @@ -62,6 +83,7 @@ impl<'a> Lexer<'a> { return Ok(Token { kind: TokenKind::EOF, location: start_location, + comments, }); } }; @@ -119,6 +141,7 @@ impl<'a> Lexer<'a> { Ok(Token { kind, location: start_location, + comments, }) } @@ -126,28 +149,66 @@ impl<'a> Lexer<'a> { 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() { if c.is_whitespace() || is_invisible(c) || c == ',' { if c == '\n' { self.line += 1; self.col = 1; + self.at_line_start = true; + consecutive_newlines += 1; } else { self.col += 1; } self.input.next(); - } else if c == ';' || c == '#' { - for c in self.input.by_ref() { - if c == '\n' { + } else if c == ';' { + if !self.at_line_start { + 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.col = 1; + self.at_line_start = true; + consecutive_newlines += 1; break; } } } else { + self.at_line_start = false; break; } } + Ok(()) } fn read_while(&mut self, mut predicate: F) -> String diff --git a/src/ast/nodes.rs b/src/ast/nodes.rs index b00b8cd..12967df 100644 --- a/src/ast/nodes.rs +++ b/src/ast/nodes.rs @@ -250,6 +250,7 @@ pub struct Node { pub identity: Identity, pub kind: NodeKind

, pub ty: P::Metadata, + pub comments: Rc<[Rc]>, } impl Clone for Node

{ @@ -258,6 +259,7 @@ impl Clone for Node

{ identity: self.identity.clone(), kind: self.kind.clone(), ty: self.ty.clone(), + comments: self.comments.clone(), } } } diff --git a/src/ast/parser.rs b/src/ast/parser.rs index f99373b..284ca10 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -21,6 +21,7 @@ impl<'a> Parser<'a> { Token { kind: TokenKind::EOF, location: SourceLocation { line: 1, col: 1 }, + comments: Rc::from([]), } } }; @@ -40,6 +41,7 @@ impl<'a> Parser<'a> { Token { kind: TokenKind::EOF, location: self.current_token.location, + comments: Rc::from([]), } } }; @@ -59,7 +61,7 @@ impl<'a> Parser<'a> { TokenKind::LeftBracket => self.parse_vector_literal(), TokenKind::LeftBrace => self.parse_record_literal(), TokenKind::Quote => { - self.advance(); // consume ' + let token = self.advance(); // consume ' let expr = self.parse_expression(); SyntaxNode { identity: identity.clone(), @@ -71,22 +73,25 @@ impl<'a> Parser<'a> { elements: vec![Rc::new(expr)], }, ty: (), + comments: Rc::from([]), }), }, ty: (), + comments: token.comments, } } TokenKind::Backtick => { - self.advance(); // consume ` + let token = self.advance(); // consume ` let expr = self.parse_expression(); SyntaxNode { identity, kind: SyntaxKind::Template(Rc::new(expr)), ty: (), + comments: token.comments, } } TokenKind::Tilde => { - self.advance(); // consume ~ + let token = self.advance(); // consume ~ if *self.peek() == TokenKind::At { self.advance(); // consume @ let expr = self.parse_expression(); @@ -94,6 +99,7 @@ impl<'a> Parser<'a> { identity, kind: SyntaxKind::Splice(Rc::new(expr)), ty: (), + comments: token.comments, } } else { let expr = self.parse_expression(); @@ -101,6 +107,7 @@ impl<'a> Parser<'a> { identity, kind: SyntaxKind::Placeholder(Rc::new(expr)), ty: (), + comments: token.comments, } } } @@ -159,12 +166,13 @@ impl<'a> Parser<'a> { identity, kind, ty: (), + comments: token.comments, } } fn parse_list(&mut self) -> SyntaxNode { - let start_loc = self.advance().location; // consume '(' - let identity = NodeIdentity::new(start_loc); + let token = self.advance(); // consume '(' + let identity = NodeIdentity::new(token.location); if *self.peek() == TokenKind::RightParen { self.diagnostics.push_error( @@ -176,12 +184,13 @@ impl<'a> Parser<'a> { identity, kind: SyntaxKind::Error, ty: (), + comments: token.comments, }; } 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() { "if" => self.parse_if(identity), "fn" => self.parse_fn(identity), @@ -197,6 +206,7 @@ impl<'a> Parser<'a> { }; self.expect(TokenKind::RightParen); + node.comments = token.comments; node } @@ -211,6 +221,7 @@ impl<'a> Parser<'a> { identity: identity.clone(), kind: SyntaxKind::Tuple { elements }, ty: (), + comments: Rc::from([]), }; SyntaxNode { @@ -219,6 +230,7 @@ impl<'a> Parser<'a> { args: Rc::new(args_node), }, ty: (), + comments: Rc::from([]), } } @@ -239,6 +251,7 @@ impl<'a> Parser<'a> { else_br, }, ty: (), + comments: Rc::from([]), } } @@ -254,6 +267,7 @@ impl<'a> Parser<'a> { info: (), }, ty: (), + comments: Rc::from([]), } } @@ -270,6 +284,7 @@ impl<'a> Parser<'a> { info: (), }, ty: (), + comments: Rc::from([]), } } @@ -282,6 +297,7 @@ impl<'a> Parser<'a> { identity, kind: SyntaxKind::Block { exprs }, ty: (), + comments: Rc::from([]), } } @@ -297,6 +313,7 @@ impl<'a> Parser<'a> { info: (), }, ty: (), + comments: Rc::from([]), } } @@ -322,6 +339,7 @@ impl<'a> Parser<'a> { body: Rc::new(body), }, ty: (), + comments: Rc::from([]), } } @@ -338,6 +356,7 @@ impl<'a> Parser<'a> { identity: NodeIdentity::new(self.current_token.location), kind: SyntaxKind::Error, ty: (), + comments: Rc::from([]), }; } self.parse_pattern() @@ -359,6 +378,7 @@ impl<'a> Parser<'a> { binding: (), }, ty: (), + comments: token.comments, } } TokenKind::LeftBracket => { @@ -375,6 +395,7 @@ impl<'a> Parser<'a> { identity, kind: SyntaxKind::Tuple { elements }, ty: (), + comments: token.comments, } } TokenKind::Tilde => { @@ -386,6 +407,7 @@ impl<'a> Parser<'a> { identity: NodeIdentity::new(token.location), kind: SyntaxKind::Splice(Rc::new(expr)), ty: (), + comments: token.comments, } } else { let expr = self.parse_expression(); @@ -393,6 +415,7 @@ impl<'a> Parser<'a> { identity: NodeIdentity::new(token.location), kind: SyntaxKind::Placeholder(Rc::new(expr)), ty: (), + comments: token.comments, } } } @@ -404,11 +427,12 @@ impl<'a> Parser<'a> { ), Some(NodeIdentity::new(self.current_token.location)), ); - self.advance(); + let token = self.advance(); SyntaxNode { identity: NodeIdentity::new(self.current_token.location), kind: SyntaxKind::Error, ty: (), + comments: token.comments, } } } @@ -426,6 +450,7 @@ impl<'a> Parser<'a> { identity: identity.clone(), kind: SyntaxKind::Tuple { elements }, ty: (), + comments: Rc::from([]), }; SyntaxNode { @@ -435,6 +460,7 @@ impl<'a> Parser<'a> { args: Rc::new(args_node), }, ty: (), + comments: Rc::from([]), } } @@ -453,6 +479,7 @@ impl<'a> Parser<'a> { identity: NodeIdentity::new(token.location), kind: SyntaxKind::Tuple { elements }, ty: (), + comments: token.comments, } } @@ -495,6 +522,7 @@ impl<'a> Parser<'a> { layout: (), }, ty: (), + comments: token.comments, } } @@ -511,6 +539,7 @@ impl<'a> Parser<'a> { Token { kind, location: self.current_token.location, + comments: Rc::from([]), } } } @@ -523,6 +552,7 @@ impl<'a> Parser<'a> { binding: (), }, ty: (), + comments: Rc::from([]), } } }