Add parse_program to parser
The `Parser` can now parse a sequence of top-level expressions, representing a complete program. This change modifies the `roundtrip` function to iterate over these expressions and emit them, allowing for multi-line program parsing.
This commit is contained in:
@@ -119,6 +119,15 @@ impl<'a> Parser<'a> {
|
|||||||
matches!(self.current_token.kind, TokenKind::EOF)
|
matches!(self.current_token.kind, TokenKind::EOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses a complete program as a sequence of top-level expressions.
|
||||||
|
pub fn parse_program(&mut self) -> Vec<SyntaxNode> {
|
||||||
|
let mut expressions = Vec::new();
|
||||||
|
while !self.at_eof() {
|
||||||
|
expressions.push(self.parse_expression());
|
||||||
|
}
|
||||||
|
expressions
|
||||||
|
}
|
||||||
|
|
||||||
fn synchronize(&mut self) {
|
fn synchronize(&mut self) {
|
||||||
while !self.at_eof() {
|
while !self.at_eof() {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
|
|||||||
+2
-2
@@ -186,7 +186,7 @@ impl CompilerApp {
|
|||||||
|
|
||||||
fn roundtrip(&mut self) {
|
fn roundtrip(&mut self) {
|
||||||
let mut parser = Parser::new(&self.source_code);
|
let mut parser = Parser::new(&self.source_code);
|
||||||
let ast = parser.parse_expression();
|
let expressions = parser.parse_program();
|
||||||
if parser.diagnostics.has_errors() {
|
if parser.diagnostics.has_errors() {
|
||||||
let errors: Vec<_> = parser
|
let errors: Vec<_> = parser
|
||||||
.diagnostics
|
.diagnostics
|
||||||
@@ -198,7 +198,7 @@ impl CompilerApp {
|
|||||||
self.active_tab = AppTab::Output;
|
self.active_tab = AppTab::Output;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.source_code = emitter::emit(&ast);
|
self.source_code = expressions.iter().map(emitter::emit).collect::<Vec<_>>().join("\n");
|
||||||
self.output_log = "Roundtrip complete — source reformatted.".to_string();
|
self.output_log = "Roundtrip complete — source reformatted.".to_string();
|
||||||
self.active_tab = AppTab::Output;
|
self.active_tab = AppTab::Output;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ fn test_real_m1_full_iteration() {
|
|||||||
assert!(total_records > 0, "Should have read some records");
|
assert!(total_records > 0, "Should have read some records");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: This test is flaky — thread scheduling can cause uneven read counts.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_real_concurrent_access() {
|
fn test_real_concurrent_access() {
|
||||||
if skip_if_no_data() {
|
if skip_if_no_data() {
|
||||||
|
|||||||
Reference in New Issue
Block a user