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
|
use llvm_kaleidoscope_rs::{
codegen::Codegen,
lexer::{Lexer, Token},
llvm,
parser::Parser,
Either,
};
use std::io::Read;
fn main_loop<I>(mut parser: Parser<I>)
where
I: Iterator<Item = char>,
{
// 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 => match parser.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);
parser.get_next_token();
}
},
Token::Extern => match parser.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);
parser.get_next_token();
}
},
_ => match parser.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);
parser.get_next_token();
}
},
};
}
// Dump all the emitted LLVM IR to stdout.
module.dump();
}
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();
main_loop(parser);
// De-allocate managed static LLVM data.
llvm::shutdown();
}
|