1mod ast;
8mod error;
9mod lexer;
10mod parser;
11mod source;
12mod span;
13mod token;
14
15pub use ast::{
16 BinaryOp, Block, EnumDecl, EnumVariant, Expr, ExprKind, FieldDecl, ForHead, Function, Ident,
17 ImplBlock, Item, Literal, MatchArm, ModDecl, Param, Path, PathStart, Pattern, Program,
18 SelfMode, Stmt, StructDecl, TypeExpr, UnaryOp, UseDecl, VariantField, VariantFields,
19};
20pub use error::{FixIt, SyntaxError, V0001, V0002, V0003, V0010, V0011, V0012};
21pub use lexer::{KEYWORDS, RESERVED_KEYWORDS, lex};
22pub use parser::parse;
23pub use source::SourceFile;
24pub use span::{FileId, Span};
25pub use token::{Token, TokenKind};
26
27pub fn parse_source(file: &SourceFile) -> (Program, Vec<SyntaxError>) {
33 let (tokens, lex_errors) = lex(file);
34 if !lex_errors.is_empty() {
35 return (Program { items: Vec::new() }, lex_errors);
36 }
37 parse(&tokens, file.id)
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use std::path::{Path, PathBuf};
44
45 fn example_files() -> Vec<PathBuf> {
49 let examples_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../examples");
50 let mut files = Vec::new();
51 collect_vr_files(&examples_dir, &mut files);
52 files
53 }
54
55 fn collect_vr_files(dir: &Path, files: &mut Vec<PathBuf>) {
56 let entries = std::fs::read_dir(dir)
57 .unwrap_or_else(|e| panic!("failed to read directory {dir:?}: {e}"));
58 for entry in entries {
59 let path = entry
60 .unwrap_or_else(|e| panic!("bad directory entry: {e}"))
61 .path();
62 if path.is_dir() {
63 collect_vr_files(&path, files);
64 } else if path.extension().and_then(|ext| ext.to_str()) == Some("vr") {
65 files.push(path);
66 }
67 }
68 }
69
70 #[test]
73 fn every_example_file_parses_with_zero_errors() {
74 let files = example_files();
75 assert!(
76 !files.is_empty(),
77 "found no .vr files under examples/; check the path"
78 );
79 for path in files {
80 let text = std::fs::read_to_string(&path)
81 .unwrap_or_else(|e| panic!("failed to read {path:?}: {e}"));
82 let file = SourceFile::new(FileId(0), path.clone(), text);
83 let (_program, errors) = parse_source(&file);
84 assert!(
85 errors.is_empty(),
86 "unexpected errors parsing {path:?}: {errors:?}"
87 );
88 }
89 }
90}