Skip to content

Commit

Permalink
Merge pull request #511 from shiika-lang/remove-hir-expressions
Browse files Browse the repository at this point in the history
Remove HirExpressions
  • Loading branch information
yhara authored Aug 15, 2023
2 parents c64d86c + 836e144 commit 3d2207a
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 178 deletions.
18 changes: 9 additions & 9 deletions lib/skc_ast2hir/src/convert_exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ use shiika_core::{names::*, ty, ty::*};
use skc_hir::*;

impl<'hir_maker> HirMaker<'hir_maker> {
pub(super) fn convert_exprs(&mut self, exprs: &[AstExpression]) -> Result<HirExpressions> {
pub(super) fn convert_exprs(&mut self, exprs: &[AstExpression]) -> Result<HirExpression> {
let hir_exprs = exprs
.iter()
.map(|expr| self.convert_expr(expr))
.collect::<Result<Vec<_>, _>>()?;

Ok(HirExpressions::new(hir_exprs))
Ok(Hir::expressions(hir_exprs))
}

pub(super) fn convert_expr(&mut self, expr: &AstExpression) -> Result<HirExpression> {
Expand Down Expand Up @@ -200,7 +200,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {

let mut else_hirs = match else_exprs {
Some(exprs) => self.convert_exprs(exprs)?,
None => HirExpressions::void(),
None => Hir::expressions(vec![]),
};
let else_ctx = self.ctx_stack.pop_if_ctx();
if_ctxs.push(else_ctx);
Expand All @@ -210,21 +210,21 @@ impl<'hir_maker> HirMaker<'hir_maker> {
} else if else_hirs.ty.is_never_type() {
then_hirs.ty.clone()
} else if then_hirs.ty.is_void_type() {
else_hirs.voidify();
else_hirs = else_hirs.voidify();
ty::raw("Void")
} else if else_hirs.ty.is_void_type() {
then_hirs.voidify();
then_hirs = then_hirs.voidify();
ty::raw("Void")
} else {
let opt_ty = self
.class_dict
.nearest_common_ancestor(&then_hirs.ty, &else_hirs.ty);
let ty = type_checking::check_if_body_ty(opt_ty)?;
if !then_hirs.ty.equals_to(&ty) {
then_hirs = then_hirs.bitcast_to(ty.clone());
then_hirs = Hir::bit_cast(ty.clone(), then_hirs);
}
if !else_hirs.ty.equals_to(&ty) {
else_hirs = else_hirs.bitcast_to(ty.clone());
else_hirs = Hir::bit_cast(ty.clone(), else_hirs);
}
ty
};
Expand Down Expand Up @@ -1063,8 +1063,8 @@ impl<'hir_maker> HirMaker<'hir_maker> {
));
}

exprs.push(Hir::lvar_ref(ary_ty, tmp_name, locs.clone()));
Hir::parenthesized_expression(Hir::expressions(exprs), locs)
exprs.push(Hir::lvar_ref(ary_ty.clone(), tmp_name, locs.clone()));
Hir::parenthesized_expression(ary_ty, exprs, locs)
}

fn convert_self_expr(&self, locs: &LocationSpan) -> HirExpression {
Expand Down
24 changes: 10 additions & 14 deletions lib/skc_ast2hir/src/hir_maker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
}

/// Destructively convert self to Hir
pub fn extract_hir(&mut self, main_exprs: HirExpressions, main_lvars: HirLVars) -> Hir {
pub fn extract_hir(&mut self, main_exprs: HirExpression, main_lvars: HirLVars) -> Hir {
// Extract data from self
let sk_types = std::mem::take(&mut self.class_dict.sk_types);
let sk_methods = std::mem::take(&mut self.method_dict.0);
Expand Down Expand Up @@ -141,7 +141,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
pub fn convert_toplevel_items(
&mut self,
items: Vec<shiika_ast::TopLevelItem>,
) -> Result<(HirExpressions, HirLVars)> {
) -> Result<(HirExpression, HirLVars)> {
let mut defs = vec![];
let mut top_exprs = vec![];
for item in items {
Expand All @@ -164,7 +164,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
debug_assert!(self.ctx_stack.len() == 1);
let mut toplevel_ctx = self.ctx_stack.pop_toplevel_ctx();
Ok((
HirExpressions::new(main_exprs),
Hir::expressions(main_exprs),
extract_lvars(&mut toplevel_ctx.lvars),
))
}
Expand Down Expand Up @@ -471,11 +471,13 @@ impl<'hir_maker> HirMaker<'hir_maker> {
}
let mut hir_exprs = self.convert_exprs(body_exprs)?;
if signature.has_default_expr() {
hir_exprs.prepend(_set_defaults(self, ast_sig)?);
let mut exprs = _set_defaults(self, ast_sig)?;
exprs.push(hir_exprs);
hir_exprs = Hir::expressions(exprs);
}
// Insert ::Void so that last expr always matches to ret_ty
if signature.ret_ty.is_void_type() {
hir_exprs.voidify();
hir_exprs = hir_exprs.voidify();
}
let mut method_ctx = self.ctx_stack.pop_method_ctx();
let lvars = extract_lvars(&mut method_ctx.lvars);
Expand Down Expand Up @@ -548,7 +550,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
let initialize = SkMethod::simple(
signature,
SkMethodBody::Normal {
exprs: HirExpressions::new(exprs),
exprs: Hir::expressions(exprs),
},
);
self.method_dict
Expand Down Expand Up @@ -648,14 +650,8 @@ fn _set_default(
let arg = Hir::arg_ref(value_expr.ty.clone(), idx, locs.clone());
let cond_expr = Hir::is_omitted_value(arg.clone());

let mut then_exprs = HirExpressions::void();
then_exprs.prepend(vec![Hir::lvar_assign(
name.to_string(),
value_expr,
locs.clone(),
)]);
let mut else_exprs = HirExpressions::void();
else_exprs.prepend(vec![Hir::lvar_assign(name.to_string(), arg, locs)]);
let then_exprs = Hir::lvar_assign(name.to_string(), value_expr, locs.clone());
let else_exprs = Hir::lvar_assign(name.to_string(), arg, locs);

let if_expr = Hir::if_expression(
ty::raw("Void"),
Expand Down
8 changes: 5 additions & 3 deletions lib/skc_ast2hir/src/pattern_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ fn compile_body(
mk: &mut HirMaker,
components: &[Component],
body: &[AstExpression],
) -> Result<(HirExpressions, HirLVars)> {
) -> Result<(HirExpression, HirLVars)> {
mk.ctx_stack.push(HirMakerContext::match_clause());
// Declare lvars introduced by matching
for component in components {
Expand All @@ -97,7 +97,9 @@ fn calc_result_ty(mk: &HirMaker, clauses_: &mut [MatchClause]) -> Result<TermTy>
} else if clauses.iter().any(|c| c.body_hir.ty.is_void_type()) {
for c in clauses.iter_mut() {
if !c.body_hir.ty.is_void_type() {
c.body_hir.voidify();
let mut tmp = Hir::expressions(vec![]);
std::mem::swap(&mut tmp, &mut c.body_hir);
c.body_hir = tmp.voidify();
}
}
Ok(ty::raw("Void"))
Expand All @@ -124,7 +126,7 @@ fn calc_result_ty(mk: &HirMaker, clauses_: &mut [MatchClause]) -> Result<TermTy>
fn bitcast_match_clause_body(c: &mut MatchClause, ty: TermTy) {
let mut tmp = Hir::expressions(Default::default());
std::mem::swap(&mut tmp, &mut c.body_hir);
tmp = tmp.bitcast_to(ty);
tmp = Hir::bit_cast(ty, tmp);
std::mem::swap(&mut tmp, &mut c.body_hir);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/skc_ast2hir/src/type_system/type_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ macro_rules! type_error {
pub fn check_return_value(
class_dict: &ClassDict,
sig: &MethodSignature,
body_exprs: &HirExpressions,
body_exprs: &HirExpression,
) -> Result<()> {
let ty = &body_exprs.ty;
if sig.ret_ty.is_void_type() {
Expand Down
60 changes: 30 additions & 30 deletions lib/skc_codegen/src/gen_exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,6 @@ use std::rc::Rc;
const EXIT_BREAK: u64 = 1;

impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
/// Generate LLVM IR from HirExpressions.
/// May return `None` when, for example, it ends with a `return`
/// expression.
pub fn gen_exprs(
&'run self,
ctx: &mut CodeGenContext<'hir, 'run>,
exprs: &'hir HirExpressions,
) -> Result<Option<SkObj<'run>>> {
debug_assert!(!exprs.exprs.is_empty());
let mut last_value = None;
for expr in &exprs.exprs {
let value = self.gen_expr(ctx, expr)?;
if value.is_none() {
//log::warn!("detected unreachable code");
return Ok(None);
} else {
last_value = Some(value);
}
}
Ok(last_value.unwrap())
}

pub fn gen_expr(
&'run self,
ctx: &mut CodeGenContext<'hir, 'run>,
Expand Down Expand Up @@ -171,7 +149,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
initialize_name,
init_cls_name,
))),
HirParenthesizedExpr { exprs } => self.gen_exprs(ctx, exprs),
HirParenthesizedExpr { exprs } => self.gen_parenthesized_expr(ctx, exprs),
HirDefaultExpr => Ok(Some(self.gen_default_expr(&expr.ty))),
HirIsOmittedValue { expr } => self.gen_is_omitted_value(ctx, expr),
}
Expand Down Expand Up @@ -262,8 +240,8 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
ctx: &mut CodeGenContext<'hir, 'run>,
ty: &TermTy,
cond_expr: &'hir HirExpression,
then_exprs: &'hir HirExpressions,
else_exprs: &'hir HirExpressions,
then_exprs: &'hir HirExpression,
else_exprs: &'hir HirExpression,
) -> Result<Option<SkObj<'run>>> {
let begin_block = self.context.append_basic_block(ctx.function, "IfBegin");
let then_block = self.context.append_basic_block(ctx.function, "IfThen");
Expand All @@ -277,14 +255,14 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
self.gen_conditional_branch(cond_value, then_block, else_block);
// IfThen:
self.builder.position_at_end(then_block);
let then_value = self.gen_exprs(ctx, then_exprs)?;
let then_value = self.gen_expr(ctx, then_exprs)?;
if then_value.is_some() {
self.builder.build_unconditional_branch(merge_block);
}
let then_block_end = self.builder.get_insert_block().unwrap();
// IfElse:
self.builder.position_at_end(else_block);
let else_value = self.gen_exprs(ctx, else_exprs)?;
let else_value = self.gen_expr(ctx, else_exprs)?;
if else_value.is_some() {
self.builder.build_unconditional_branch(merge_block);
}
Expand Down Expand Up @@ -400,7 +378,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
}
}
let result = self
.gen_exprs(ctx, &clause.body_hir)?
.gen_expr(ctx, &clause.body_hir)?
.map(|v| self.bitcast(v, result_ty, "as"));
ctx.lvars = orig_lvars;
Ok(result)
Expand All @@ -410,7 +388,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
&'run self,
ctx: &mut CodeGenContext<'hir, 'run>,
cond_expr: &'hir HirExpression,
body_exprs: &'hir HirExpressions,
body_exprs: &'hir HirExpression,
) -> Result<Option<SkObj<'run>>> {
let begin_block = self.context.append_basic_block(ctx.function, "WhileBegin");
self.builder.build_unconditional_branch(begin_block);
Expand All @@ -426,7 +404,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
let rc2 = Rc::clone(&rc1);
let orig_loop_end = ctx.current_loop_end.as_ref().map(Rc::clone);
ctx.current_loop_end = Some(rc1);
self.gen_exprs(ctx, body_exprs)?;
self.gen_expr(ctx, body_exprs)?;
ctx.current_loop_end = orig_loop_end;
self.builder.build_unconditional_branch(begin_block);

Expand Down Expand Up @@ -1266,6 +1244,28 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
cls_obj
}

/// Compile successive expressions. The last evaluated value is returned.
/// Returns `None` if terminated with a `Never` type (`return`, `panic`, etc.)
fn gen_parenthesized_expr(
&'run self,
ctx: &mut CodeGenContext<'hir, 'run>,
exprs: &'hir [HirExpression],
) -> Result<Option<SkObj<'run>>> {
debug_assert!(!exprs.is_empty());
let mut last_value = None;
for expr in exprs {
let value = self.gen_expr(ctx, expr)?;
if value.is_none() {
// Found `return`, `panic` or something. The rest of `exprs`
// will never be executed
return Ok(None);
} else {
last_value = Some(value);
}
}
Ok(last_value.unwrap())
}

/// Returns a special value (currently a nullptr) that denotes using the default argument value.
fn gen_default_expr(&'run self, ty: &TermTy) -> SkObj<'run> {
self.null_ptr(ty)
Expand Down
Loading

0 comments on commit 3d2207a

Please sign in to comment.