aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main.rs
blob: be3dede0874e22951fb72b135c7d2d1043b1cd68 (plain) (blame)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use llvm_kaleidoscope_rs::{
    codegen::Codegen,
    lexer::{Lexer, Token},
    llvm,
    parser::Parser,
    Either,
};

use std::io::Read;

fn handle_definition<I>(p: &mut Parser<I>, module: &llvm::Module)
where
    I: Iterator<Item = char>,
{
    match p.parse_definition() {
        Ok(func) => {
            println!("Parse 'def'\n{:?}", func);
            if let Ok(func) = Codegen::compile(module, Either::B(&func)) {
                func.dump();
            }
        }
        Err(err) => {
            eprintln!("Error: {:?}", err);
            p.get_next_token();
        }
    }
}

fn handle_extern<I>(p: &mut Parser<I>, module: &llvm::Module)
where
    I: Iterator<Item = char>,
{
    match p.parse_extern() {
        Ok(proto) => {
            println!("Parse 'extern'\n{:?}", proto);
            if let Ok(proto) = Codegen::compile(module, Either::A(&proto)) {
                proto.dump();
            }
        }
        Err(err) => {
            eprintln!("Error: {:?}", err);
            p.get_next_token();
        }
    }
}

fn handle_top_level_expression<I>(p: &mut Parser<I>, module: &llvm::Module)
where
    I: Iterator<Item = char>,
{
    match p.parse_top_level_expr() {
        Ok(func) => {
            println!("Parse top-level expression\n{:?}", func);
            if let Ok(func) = Codegen::compile(module, Either::B(&func)) {
                func.dump();
            }
        }
        Err(err) => {
            eprintln!("Error: {:?}", err);
            p.get_next_token();
        }
    }
}

fn main() {
    println!("Parse stdin.");
    println!("ENTER to parse current input.");
    println!("C-d   to exit.");

    // Create lexer over stdin.
    let lexer = Lexer::new(std::io::stdin().bytes().filter_map(|v| {
        let v = v.ok()?;
        Some(v.into())
    }));

    // Create parser for kaleidoscope.
    let mut parser = Parser::new(lexer);

    // Throw first coin and initialize cur_tok.
    parser.get_next_token();

    // Initialize LLVM module with its own context.
    // We will emit LLVM IR into this module.
    let module = llvm::Module::new();

    loop {
        match *parser.cur_tok() {
            Token::Eof => break,
            Token::Char(';') => {
                // Ignore top-level semicolon.
                parser.get_next_token()
            }
            Token::Def => handle_definition(&mut parser, &module),
            Token::Extern => handle_extern(&mut parser, &module),
            _ => handle_top_level_expression(&mut parser, &module),
        }
    }

    // Dump all the emitted LLVM IR to stdout.
    module.dump();

    llvm::shutdown();
}