Some basic conditionals

- No terminator analysis yet
This commit is contained in:
Michael Zhang 2022-07-17 22:26:11 -05:00
parent 090589fc3e
commit dbb51fd1d0
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 57 additions and 16 deletions

View file

@ -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;
} }

View file

@ -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 {} {}, {}",

View file

@ -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(())
} }
} }

View file

@ -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: () },