1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
pub mod assignable;
pub mod attribute;
pub mod brackets;
pub mod dependency;
mod error;
pub mod expr;
pub mod generics;
pub mod intrinsics;
mod item;
pub mod keywords;
mod literal;
pub mod parse;
pub mod parser;
pub mod path;
pub mod pattern;
mod priv_prelude;
pub mod program;
pub mod punctuated;
pub mod statement;
mod token;
pub mod ty;
pub mod where_clause;

pub use crate::{
    assignable::Assignable,
    attribute::AttributeDecl,
    brackets::{AngleBrackets, Braces},
    dependency::Dependency,
    error::{ParseError, ParseErrorKind},
    expr::{
        asm::{AsmBlock, AsmRegisterDeclaration},
        op_code::Instruction,
        AbiCastArgs, CodeBlockContents, Expr, ExprArrayDescriptor, ExprStructField,
        ExprTupleDescriptor, IfCondition, IfExpr, MatchBranch, MatchBranchKind,
    },
    generics::{GenericArgs, GenericParams},
    intrinsics::*,
    item::{
        item_abi::ItemAbi,
        item_const::ItemConst,
        item_enum::ItemEnum,
        item_fn::ItemFn,
        item_impl::ItemImpl,
        item_storage::{ItemStorage, StorageField},
        item_struct::ItemStruct,
        item_trait::{ItemTrait, Traits},
        item_use::{ItemUse, UseTree},
        FnArg, FnArgs, FnSignature, Item, ItemKind, TypeField,
    },
    keywords::{DoubleColonToken, PubToken},
    literal::{LitInt, LitIntType, Literal},
    parse::Parse,
    parser::Parser,
    path::{PathExpr, PathExprSegment, PathType, PathTypeSegment, QualifiedPathRoot},
    pattern::{Pattern, PatternStructField},
    program::{Program, ProgramKind},
    statement::{Statement, StatementLet},
    token::lex,
    token::LexError,
    ty::Ty,
    where_clause::{WhereBound, WhereClause},
};

use crate::priv_prelude::*;
use std::{path::PathBuf, sync::Arc};

#[derive(Debug, Clone, PartialEq, Hash, Error)]
pub enum ParseFileError {
    #[error(transparent)]
    Lex(LexError),
    #[error("Unable to parse: {}", .0.iter().map(|x| x.kind.to_string()).collect::<Vec<String>>().join("\n"))]
    Parse(Vec<ParseError>),
}

pub fn parse_file(src: Arc<str>, path: Option<Arc<PathBuf>>) -> Result<Program, ParseFileError> {
    let token_stream = match lex(&src, 0, src.len(), path) {
        Ok(token_stream) => token_stream,
        Err(error) => return Err(ParseFileError::Lex(error)),
    };
    let mut errors = Vec::new();
    let parser = Parser::new(&token_stream, &mut errors);
    let program = match parser.parse_to_end() {
        Ok((program, _parser_consumed)) => program,
        Err(_error_emitted) => return Err(ParseFileError::Parse(errors)),
    };
    Ok(program)
}