From 9e6c0a92dbedb5b8801772802e2e5d2e56cb9bcf Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Tue, 14 Sep 2021 00:19:40 +0200 Subject: ch3: added LLVM IR code gen - Added safe wrapper around LLVM C API - Added codegen module to emit LLVM IR for the AST - Update the main repl loop to codegen LLVM IR --- src/main.rs | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index 2646873..7160e04 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,24 @@ -mod lexer; -mod parser; +use llvm_kaleidoscope_rs::{ + codegen::Codegen, + lexer::{Lexer, Token}, + llvm, + parser::Parser, + Either, +}; -use lexer::{Lexer, Token}; -use parser::Parser; use std::io::Read; -fn handle_definition(p: &mut Parser) +fn handle_definition(p: &mut Parser, module: &llvm::Module) where I: Iterator, { match p.parse_definition() { - Ok(expr) => println!("Parse 'def'\n{:?}", expr), + 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(); @@ -18,12 +26,17 @@ where } } -fn handle_extern(p: &mut Parser) +fn handle_extern(p: &mut Parser, module: &llvm::Module) where I: Iterator, { match p.parse_extern() { - Ok(expr) => println!("Parse 'extern'\n{:?}", expr), + 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(); @@ -31,12 +44,17 @@ where } } -fn handle_top_level_expression(p: &mut Parser) +fn handle_top_level_expression(p: &mut Parser, module: &llvm::Module) where I: Iterator, { match p.parse_top_level_expr() { - Ok(expr) => println!("Parse top-level expression\n{:?}", 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(); @@ -49,16 +67,22 @@ fn main() { 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, @@ -66,9 +90,12 @@ fn main() { // Ignore top-level semicolon. parser.get_next_token() } - Token::Def => handle_definition(&mut parser), - Token::Extern => handle_extern(&mut parser), - _ => handle_top_level_expression(&mut parser), + 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(); } -- cgit v1.2.3