Restructure a bit
This commit is contained in:
parent
6a4c30e49e
commit
8defa39b31
@ -5,6 +5,10 @@ fn main() {
|
|||||||
let simpleAdd = 2 + 2;
|
let simpleAdd = 2 + 2;
|
||||||
let simpleMult = 7 * 2; // 14
|
let simpleMult = 7 * 2; // 14
|
||||||
let arithmetic = 3 + 2 * 5 + 1 * 2; // 15
|
let arithmetic = 3 + 2 * 5 + 1 * 2; // 15
|
||||||
|
|
||||||
|
if simpleAdd < test {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
return arithmetic + simpleMult * arithmetic;
|
return arithmetic + simpleMult * arithmetic;
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ pub enum IRType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl IRType {
|
impl IRType {
|
||||||
fn in_context(&self, context: &mut IRContext) -> *mut LLVMType {
|
fn in_context(&self, context: &IRContext) -> *mut LLVMType {
|
||||||
use IRType::*;
|
use IRType::*;
|
||||||
unsafe {
|
unsafe {
|
||||||
return match self {
|
return match self {
|
||||||
@ -38,14 +38,14 @@ impl IRType {
|
|||||||
pub struct IRValue(pub IRType, *mut LLVMValue);
|
pub struct IRValue(pub IRType, *mut LLVMValue);
|
||||||
|
|
||||||
impl IRValue {
|
impl IRValue {
|
||||||
pub fn from_literal(literal: &ast::Literal, block: &mut IRBlock) -> Self {
|
pub fn from_literal(literal: &ast::Literal, module: &IRModule) -> Self {
|
||||||
use ast::Literal;
|
use ast::Literal;
|
||||||
match literal {
|
match literal {
|
||||||
Literal::I32(v) => {
|
Literal::I32(v) => {
|
||||||
let ir_type = IRType::I32;
|
let ir_type = IRType::I32;
|
||||||
unsafe {
|
unsafe {
|
||||||
let ir_value = LLVMConstInt(
|
let ir_value = LLVMConstInt(
|
||||||
ir_type.in_context(block.function.module.context),
|
ir_type.in_context(module.context),
|
||||||
mem::transmute(*v as i64),
|
mem::transmute(*v as i64),
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
@ -116,13 +116,13 @@ impl<'a> Drop for IRModule<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct IRFunction<'a, 'b> {
|
pub struct IRFunction<'a, 'b> {
|
||||||
module: &'b mut IRModule<'a>,
|
pub module: &'b IRModule<'a>,
|
||||||
/// The actual function
|
/// The actual function
|
||||||
value: *mut LLVMValue,
|
value: *mut LLVMValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> IRFunction<'a, 'b> {
|
impl<'a, 'b> IRFunction<'a, 'b> {
|
||||||
pub fn new(name: &String, module: &'b mut IRModule<'a>) -> IRFunction<'a, 'b> {
|
pub fn new(name: &String, module: &'b IRModule<'a>) -> IRFunction<'a, 'b> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// TODO, fix later!
|
// TODO, fix later!
|
||||||
|
|
||||||
@ -140,23 +140,26 @@ impl<'a, 'b> IRFunction<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn attach(&mut self, block: IRBlock) {
|
||||||
|
unsafe { LLVMAppendExistingBasicBlock(self.value, block.blockref) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IRBlock<'a, 'b, 'c> {
|
pub struct IRBlock<'a, 'b> {
|
||||||
function: &'a mut IRFunction<'b, 'c>,
|
pub module: &'b IRModule<'a>,
|
||||||
blockref: *mut LLVMBasicBlock,
|
blockref: *mut LLVMBasicBlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
|
impl<'a, 'b, 'c> IRBlock<'a, 'b> {
|
||||||
pub fn new(function: &'a mut IRFunction<'b, 'c>) -> IRBlock<'a, 'b, 'c> {
|
pub fn new(module: &'b IRModule<'a>) -> IRBlock<'a, 'b> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let blockref = LLVMCreateBasicBlockInContext(
|
let blockref = LLVMCreateBasicBlockInContext(
|
||||||
function.module.context.context,
|
module.context.context,
|
||||||
into_cstring("entryblock").as_ptr(),
|
into_cstring("entryblock").as_ptr(),
|
||||||
);
|
);
|
||||||
LLVMPositionBuilderAtEnd(function.module.context.builder, blockref);
|
|
||||||
|
|
||||||
IRBlock { function, blockref }
|
IRBlock { module, blockref }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +169,12 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
|
|||||||
IRValue(rhs_t, rhs_v): IRValue,
|
IRValue(rhs_t, rhs_v): IRValue,
|
||||||
) -> Result<IRValue, Error> {
|
) -> Result<IRValue, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
|
||||||
if lhs_t == rhs_t {
|
if lhs_t == rhs_t {
|
||||||
Ok(IRValue(
|
Ok(IRValue(
|
||||||
lhs_t,
|
lhs_t,
|
||||||
LLVMBuildAdd(
|
LLVMBuildAdd(
|
||||||
self.function.module.context.builder,
|
self.module.context.builder,
|
||||||
lhs_v,
|
lhs_v,
|
||||||
rhs_v,
|
rhs_v,
|
||||||
c"tmpadd".as_ptr(),
|
c"tmpadd".as_ptr(),
|
||||||
@ -188,11 +192,12 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
|
|||||||
IRValue(rhs_t, rhs_v): IRValue,
|
IRValue(rhs_t, rhs_v): IRValue,
|
||||||
) -> Result<IRValue, Error> {
|
) -> Result<IRValue, Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
|
||||||
if lhs_t == rhs_t {
|
if lhs_t == rhs_t {
|
||||||
Ok(IRValue(
|
Ok(IRValue(
|
||||||
lhs_t,
|
lhs_t,
|
||||||
LLVMBuildMul(
|
LLVMBuildMul(
|
||||||
self.function.module.context.builder,
|
self.module.context.builder,
|
||||||
lhs_v,
|
lhs_v,
|
||||||
rhs_v,
|
rhs_v,
|
||||||
c"tmpadd".as_ptr(),
|
c"tmpadd".as_ptr(),
|
||||||
@ -204,21 +209,14 @@ impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_return(self, value: Option<IRValue>) {
|
pub fn add_return(&mut self, value: Option<IRValue>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
LLVMPositionBuilderAtEnd(self.module.context.builder, self.blockref);
|
||||||
if let Some(IRValue(_, value)) = value {
|
if let Some(IRValue(_, value)) = value {
|
||||||
LLVMBuildRet(self.function.module.context.builder, value);
|
LLVMBuildRet(self.module.context.builder, value);
|
||||||
} else {
|
} else {
|
||||||
LLVMBuildRetVoid(self.function.module.context.builder);
|
LLVMBuildRetVoid(self.module.context.builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
LLVMAppendExistingBasicBlock(self.function.value, self.blockref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -6,8 +6,8 @@ use llvm::{Error, IRBlock, IRContext, IRFunction, IRModule, IRValue};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
BinaryOperator, Block, BlockLevelStatement, Expression, ExpressionKind, FunctionDefinition,
|
Block, BlockLevelStatement, Expression, ExpressionKind, FunctionDefinition, LetStatement,
|
||||||
LetStatement, ReturnType,
|
ReturnType,
|
||||||
},
|
},
|
||||||
TopLevelStatement,
|
TopLevelStatement,
|
||||||
};
|
};
|
||||||
@ -42,19 +42,23 @@ impl FunctionDefinition {
|
|||||||
fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
|
fn codegen(&self, scope: &mut ScopeData, module: &mut IRModule) {
|
||||||
let FunctionDefinition(signature, block, _) = self;
|
let FunctionDefinition(signature, block, _) = self;
|
||||||
let mut ir_function = IRFunction::new(&signature.name, module);
|
let mut ir_function = IRFunction::new(&signature.name, module);
|
||||||
let ir_block = IRBlock::new(&mut ir_function);
|
|
||||||
block.codegen(scope.inner(ir_block));
|
let ir_block = IRBlock::new(&module);
|
||||||
|
let mut scope = scope.inner(ir_block);
|
||||||
|
block.codegen(&mut scope);
|
||||||
|
|
||||||
|
ir_function.attach(scope.block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
fn codegen(&self, mut scope: Scope) {
|
fn codegen(&self, scope: &mut Scope) {
|
||||||
for statement in &self.0 {
|
for statement in &self.0 {
|
||||||
statement.codegen(&mut scope);
|
statement.codegen(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((_, return_exp)) = &self.1 {
|
if let Some((_, return_exp)) = &self.1 {
|
||||||
let value = return_exp.codegen(&mut scope);
|
let value = return_exp.codegen(scope);
|
||||||
scope.block.add_return(Some(value));
|
scope.block.add_return(Some(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,7 +87,7 @@ impl Expression {
|
|||||||
|
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
match kind {
|
match kind {
|
||||||
Literal(lit) => IRValue::from_literal(lit, &mut scope.block),
|
Literal(lit) => IRValue::from_literal(lit, &mut scope.block.module),
|
||||||
VariableName(v) => scope.data.fetch(v),
|
VariableName(v) => scope.data.fetch(v),
|
||||||
Binop(op, lhs, rhs) => {
|
Binop(op, lhs, rhs) => {
|
||||||
let lhs = lhs.codegen(scope);
|
let lhs = lhs.codegen(scope);
|
||||||
@ -112,11 +116,11 @@ impl ScopeData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_block<'a, 'b, 'c>(self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> {
|
fn with_block<'a, 'b>(self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
|
||||||
Scope { data: self, block }
|
Scope { data: self, block }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inner<'a, 'b, 'c>(&self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> {
|
fn inner<'a, 'b>(&self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
|
||||||
self.clone().with_block(block)
|
self.clone().with_block(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,13 +139,13 @@ impl ScopeData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Scope<'a, 'b, 'c> {
|
struct Scope<'a, 'b> {
|
||||||
data: ScopeData,
|
data: ScopeData,
|
||||||
block: IRBlock<'a, 'b, 'c>,
|
block: IRBlock<'a, 'b>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c> Scope<'a, 'b, 'c> {
|
impl<'a, 'b> Scope<'a, 'b> {
|
||||||
fn inner(&self, block: IRBlock<'a, 'b, 'c>) -> Scope<'a, 'b, 'c> {
|
fn inner(&self, block: IRBlock<'a, 'b>) -> Scope<'a, 'b> {
|
||||||
self.data.clone().with_block(block)
|
self.data.clone().with_block(block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user