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
use std::sync::Arc;

use calypso_ast::{pretty::PrettyPrinter, traverse::Visitor};
use calypso_common::gcx::GlobalCtxt;
use calypso_diagnostic::prelude::*;
use calypso_parsing::{
    lexer::{self, Token},
    parser::grammar::ExprsParser,
};

pub fn run_parser(gcx: &Arc<GlobalCtxt>, file_name: String, contents: String) -> CalResult<()> {
    let file_id = gcx.sourcemgr.write().add(file_name, contents);

    let sourcemgr = gcx.sourcemgr.read();
    let source = sourcemgr.source(file_id).unwrap();
    let mut tokens = lexer::tokens(source, file_id, Arc::clone(gcx))
        .filter_map(|x| {
            if matches!(x.value().0, Token::Comment(_)) {
                None
            } else {
                Some((x.span().lo(), x.value_owned().0, x.span().hi()))
            }
        })
        .peekable();

    // let grcx_read = gcx.grcx.read();
    // if let Some(fatal) = grcx_read.fatal() {
    //     let mut emit = gcx.emit.write();
    //     let mut buf = emit.err.buffer();
    //     fatal.render(&mut buf, &sourcemgr, None)?;
    //     emit.err.emit(&buf)?.flush()?;
    // } else {
    //     grcx_read
    //         .errors()
    //         .iter()
    //         .try_for_each(|e| -> CalResult<()> {
    //             let mut emit = gcx.emit.write();
    //             let mut buf = emit.err.buffer();
    //             e.render(&mut buf, &sourcemgr, None)?;
    //             emit.err.emit(&buf)?;
    //             Ok(())
    //         })?;
    //     gcx.emit.write().err.flush()?;
    // }
    // drop(grcx_read);

    let parser = ExprsParser::new();

    loop {
        if tokens.peek().is_none() {
            break;
        }
        match parser.parse(file_id, &mut tokens) {
            Ok(exprs) => {
                for expr in exprs {
                    let mut printer = PrettyPrinter::default();
                    printer.visit_expr(source, expr.as_ref())?;
                    println!("{}", printer);
                }
            }
            Err(err) => {
                let mut emit = gcx.emit.write();
                emit.err
                    .error(None, "Parse error", Some(&format!("{:#?}", err)))?
                    .flush()?;
                break;
            }
        };
    }

    Ok(())
}