Some basic conditionals
- No terminator analysis yet
This commit is contained in:
parent
090589fc3e
commit
dbb51fd1d0
4 changed files with 57 additions and 16 deletions
|
@ -5,13 +5,7 @@ fn main() -> int {
|
||||||
return 10;
|
return 10;
|
||||||
} else if x > 50 {
|
} else if x > 50 {
|
||||||
return 50;
|
return 50;
|
||||||
} else {
|
|
||||||
if x < 20 {
|
|
||||||
return 20;
|
|
||||||
} else if x > 40 {
|
|
||||||
return 40;
|
|
||||||
} else {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 65;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,27 @@ impl<W: Write> LlvmIrCodegen<W> {
|
||||||
None => bail!("Invalid types on operation."),
|
None => bail!("Invalid types on operation."),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let common_ty = type_to_llvm(&left.ty);
|
||||||
let left = self.convert_expr(left)?;
|
let left = self.convert_expr(left)?;
|
||||||
|
|
||||||
let right = self.convert_expr(right)?;
|
let right = self.convert_expr(right)?;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
Op::LessThan => todo!(),
|
Op::LessThan => writeln!(
|
||||||
Op::GreaterThan => todo!(),
|
self.writer,
|
||||||
|
"{} = icmp slt {} {}, {}",
|
||||||
|
expr_ref,
|
||||||
|
common_ty,
|
||||||
|
left.as_str(),
|
||||||
|
right.as_str(),
|
||||||
|
)?,
|
||||||
|
Op::GreaterThan => writeln!(
|
||||||
|
self.writer,
|
||||||
|
"{} = icmp sgt {} {}, {}",
|
||||||
|
expr_ref,
|
||||||
|
common_ty,
|
||||||
|
left.as_str(),
|
||||||
|
right.as_str(),
|
||||||
|
)?,
|
||||||
Op::Plus => writeln!(
|
Op::Plus => writeln!(
|
||||||
self.writer,
|
self.writer,
|
||||||
"{} = add {} {}, {}",
|
"{} = add {} {}, {}",
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::io::Write;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::ast::{IfElse, Stmt, Type};
|
use crate::ast::{ElseClause, IfElse, Stmt, Type};
|
||||||
|
|
||||||
use super::LlvmIrCodegen;
|
use super::LlvmIrCodegen;
|
||||||
|
|
||||||
|
@ -11,9 +11,42 @@ impl<W: Write> LlvmIrCodegen<W> {
|
||||||
&mut self,
|
&mut self,
|
||||||
if_else: &IfElse<Type>,
|
if_else: &IfElse<Type>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// Build condition
|
// Use a common identifier so they have the same number
|
||||||
let cond = self.convert_expr(&if_else.cond);
|
let cond = self.gensym(None, "cond");
|
||||||
|
let success_label = format!("{cond}.success");
|
||||||
|
let fail_label = format!("{cond}.fail");
|
||||||
|
let exit_label = format!("{cond}.exit");
|
||||||
|
|
||||||
todo!()
|
// Build condition
|
||||||
|
let cond = self.convert_expr(&if_else.cond)?;
|
||||||
|
writeln!(
|
||||||
|
self.writer,
|
||||||
|
"br i1 {}, label %{}, label %{}",
|
||||||
|
cond.as_str(),
|
||||||
|
success_label,
|
||||||
|
fail_label
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// If true
|
||||||
|
writeln!(self.writer, "{}:", success_label)?;
|
||||||
|
self.convert_stmts(&if_else.body)?;
|
||||||
|
writeln!(self.writer, "br label %{}", exit_label)?;
|
||||||
|
|
||||||
|
// If false
|
||||||
|
writeln!(self.writer, "{}:", fail_label)?;
|
||||||
|
match &if_else.else_clause {
|
||||||
|
Some(ElseClause::If(if_else2)) => self.convert_if_else(if_else2)?,
|
||||||
|
Some(ElseClause::Body(body)) => self.convert_stmts(body)?,
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
writeln!(self.writer, "br label %{}", exit_label)?;
|
||||||
|
|
||||||
|
// Exit branch
|
||||||
|
writeln!(self.writer, "{}:", exit_label)?;
|
||||||
|
// No-op in case this is the last statement
|
||||||
|
let nop = self.gensym(Some("%"), "nop");
|
||||||
|
writeln!(self.writer, "{nop} = add i1 0, 0")?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ Expr: Expr<()> = {
|
||||||
"(" <expr:Expr> ")" => expr,
|
"(" <expr:Expr> ")" => expr,
|
||||||
|
|
||||||
#[precedence(level = "0")]
|
#[precedence(level = "0")]
|
||||||
r"[0-9]+" => Expr { kind: ExprKind::Int(<>.parse::<i64>().unwrap()), ty: () },
|
r"-?[0-9]+" => Expr { kind: ExprKind::Int(<>.parse::<i64>().unwrap()), ty: () },
|
||||||
|
|
||||||
#[precedence(level = "0")]
|
#[precedence(level = "0")]
|
||||||
Ident => Expr { kind: ExprKind::Var(<>), ty: () },
|
Ident => Expr { kind: ExprKind::Var(<>), ty: () },
|
||||||
|
|
Loading…
Reference in a new issue