brainfuck interpreter
brainfuck cli rust
5

Configure Feed

Select the types of activity you want to include in your feed.

parser: switched to NamedSource for better errors, implemented Arc

digi.rip (Jun 9, 2026, 4:56 PM EDT) ba7993f7 4b5bc84d

+17 -21
+17 -21
src/parser.rs
··· 1 1 use crate::lexer::Token; 2 - use miette::{Diagnostic, SourceSpan}; 2 + use miette::{Diagnostic, NamedSource, SourceSpan}; 3 3 use std::fmt; 4 + use std::sync::Arc; 4 5 5 - #[derive(Debug, Diagnostic, Clone)] 6 + #[derive(Debug, Diagnostic)] 6 7 pub enum SyntaxError { 7 8 #[diagnostic(code(tachyon::syntax::missing_close))] 8 9 #[diagnostic(help("add a ']' to match this opening bracket"))] 9 10 MissingClosingBracket { 10 11 #[source_code] 11 - src: String, 12 + src: NamedSource<Arc<str>>, 12 13 #[label("this bracket is never closed")] 13 14 span: SourceSpan, 14 15 }, ··· 17 18 #[diagnostic(help("add a '[' to match this closing bracket"))] 18 19 MissingOpenBracket { 19 20 #[source_code] 20 - src: String, 21 + src: NamedSource<Arc<str>>, 21 22 #[label("this bracket is never opened")] 22 23 span: SourceSpan, 23 24 }, ··· 34 35 35 36 impl std::error::Error for SyntaxError {} 36 37 37 - pub fn parse_brackets(tokens: &[Token], source: &str) -> Result<Vec<usize>, SyntaxError> { 38 + pub fn parse_brackets( 39 + tokens: &[Token], 40 + filename: &str, 41 + source: &str, 42 + ) -> Result<Vec<usize>, SyntaxError> { 38 43 let mut jump_map = vec![0; tokens.len()]; 39 44 let mut balance = Vec::new(); 40 45 ··· 49 54 } 50 55 None => { 51 56 return Err(SyntaxError::MissingOpenBracket { 52 - src: source.to_string(), 57 + src: NamedSource::new(Arc::from(filename), Arc::from(source)), 53 58 span: (e.offset, 1).into(), 54 59 }); 55 60 } ··· 60 65 match balance.last() { 61 66 Some(pos) => { 62 67 let tok = &tokens[*pos]; 63 - // Err(SyntaxError::MissingClosingBracket(tok.line, tok.col)) 64 68 Err(SyntaxError::MissingClosingBracket { 65 - src: source.to_string(), 69 + src: NamedSource::new(Arc::from(filename), Arc::from(source)), 66 70 span: (tok.offset, 1).into(), 67 71 }) 68 72 } ··· 78 82 #[test] 79 83 fn are_balanced() { 80 84 let source = "[]"; 81 - let result = parse_brackets(&tokenizer(source), source).unwrap(); 85 + let result = parse_brackets(&tokenizer(source), "test", source).unwrap(); 82 86 assert!(!result.is_empty()); 83 87 } 84 88 85 89 #[test] 86 90 fn extra_closing_bracket() { 87 91 let source = "[]]"; 88 - let result = parse_brackets(&tokenizer(source), source); 89 - eprintln!( 90 - "{:?}", 91 - miette::Report::new(result.as_ref().unwrap_err().clone()) 92 - ); 93 - assert!(result.is_err()); 92 + let result = parse_brackets(&tokenizer(source), "test", source); 93 + eprintln!("{:?}", miette::Report::new(result.unwrap_err())); 94 94 } 95 95 96 96 #[test] 97 97 fn extra_opening_bracket() { 98 98 let source = "[[]"; 99 - let result = parse_brackets(&tokenizer(source), source); 100 - eprintln!( 101 - "{:?}", 102 - miette::Report::new(result.as_ref().unwrap_err().clone()) 103 - ); 104 - assert!(result.is_err()); 99 + let result = parse_brackets(&tokenizer(source), "test", source); 100 + eprintln!("{:?}", miette::Report::new(result.unwrap_err())); 105 101 } 106 102 }