Skip to content

Commit 3d2207a

Browse files
authored
Merge pull request #511 from shiika-lang/remove-hir-expressions
Remove HirExpressions
2 parents c64d86c + 836e144 commit 3d2207a

File tree

10 files changed

+137
-178
lines changed

10 files changed

+137
-178
lines changed

lib/skc_ast2hir/src/convert_exprs.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ use shiika_core::{names::*, ty, ty::*};
1616
use skc_hir::*;
1717

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

25-
Ok(HirExpressions::new(hir_exprs))
25+
Ok(Hir::expressions(hir_exprs))
2626
}
2727

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

201201
let mut else_hirs = match else_exprs {
202202
Some(exprs) => self.convert_exprs(exprs)?,
203-
None => HirExpressions::void(),
203+
None => Hir::expressions(vec![]),
204204
};
205205
let else_ctx = self.ctx_stack.pop_if_ctx();
206206
if_ctxs.push(else_ctx);
@@ -210,21 +210,21 @@ impl<'hir_maker> HirMaker<'hir_maker> {
210210
} else if else_hirs.ty.is_never_type() {
211211
then_hirs.ty.clone()
212212
} else if then_hirs.ty.is_void_type() {
213-
else_hirs.voidify();
213+
else_hirs = else_hirs.voidify();
214214
ty::raw("Void")
215215
} else if else_hirs.ty.is_void_type() {
216-
then_hirs.voidify();
216+
then_hirs = then_hirs.voidify();
217217
ty::raw("Void")
218218
} else {
219219
let opt_ty = self
220220
.class_dict
221221
.nearest_common_ancestor(&then_hirs.ty, &else_hirs.ty);
222222
let ty = type_checking::check_if_body_ty(opt_ty)?;
223223
if !then_hirs.ty.equals_to(&ty) {
224-
then_hirs = then_hirs.bitcast_to(ty.clone());
224+
then_hirs = Hir::bit_cast(ty.clone(), then_hirs);
225225
}
226226
if !else_hirs.ty.equals_to(&ty) {
227-
else_hirs = else_hirs.bitcast_to(ty.clone());
227+
else_hirs = Hir::bit_cast(ty.clone(), else_hirs);
228228
}
229229
ty
230230
};
@@ -1063,8 +1063,8 @@ impl<'hir_maker> HirMaker<'hir_maker> {
10631063
));
10641064
}
10651065

1066-
exprs.push(Hir::lvar_ref(ary_ty, tmp_name, locs.clone()));
1067-
Hir::parenthesized_expression(Hir::expressions(exprs), locs)
1066+
exprs.push(Hir::lvar_ref(ary_ty.clone(), tmp_name, locs.clone()));
1067+
Hir::parenthesized_expression(ary_ty, exprs, locs)
10681068
}
10691069

10701070
fn convert_self_expr(&self, locs: &LocationSpan) -> HirExpression {

lib/skc_ast2hir/src/hir_maker.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
5252
}
5353

5454
/// Destructively convert self to Hir
55-
pub fn extract_hir(&mut self, main_exprs: HirExpressions, main_lvars: HirLVars) -> Hir {
55+
pub fn extract_hir(&mut self, main_exprs: HirExpression, main_lvars: HirLVars) -> Hir {
5656
// Extract data from self
5757
let sk_types = std::mem::take(&mut self.class_dict.sk_types);
5858
let sk_methods = std::mem::take(&mut self.method_dict.0);
@@ -141,7 +141,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
141141
pub fn convert_toplevel_items(
142142
&mut self,
143143
items: Vec<shiika_ast::TopLevelItem>,
144-
) -> Result<(HirExpressions, HirLVars)> {
144+
) -> Result<(HirExpression, HirLVars)> {
145145
let mut defs = vec![];
146146
let mut top_exprs = vec![];
147147
for item in items {
@@ -164,7 +164,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
164164
debug_assert!(self.ctx_stack.len() == 1);
165165
let mut toplevel_ctx = self.ctx_stack.pop_toplevel_ctx();
166166
Ok((
167-
HirExpressions::new(main_exprs),
167+
Hir::expressions(main_exprs),
168168
extract_lvars(&mut toplevel_ctx.lvars),
169169
))
170170
}
@@ -471,11 +471,13 @@ impl<'hir_maker> HirMaker<'hir_maker> {
471471
}
472472
let mut hir_exprs = self.convert_exprs(body_exprs)?;
473473
if signature.has_default_expr() {
474-
hir_exprs.prepend(_set_defaults(self, ast_sig)?);
474+
let mut exprs = _set_defaults(self, ast_sig)?;
475+
exprs.push(hir_exprs);
476+
hir_exprs = Hir::expressions(exprs);
475477
}
476478
// Insert ::Void so that last expr always matches to ret_ty
477479
if signature.ret_ty.is_void_type() {
478-
hir_exprs.voidify();
480+
hir_exprs = hir_exprs.voidify();
479481
}
480482
let mut method_ctx = self.ctx_stack.pop_method_ctx();
481483
let lvars = extract_lvars(&mut method_ctx.lvars);
@@ -548,7 +550,7 @@ impl<'hir_maker> HirMaker<'hir_maker> {
548550
let initialize = SkMethod::simple(
549551
signature,
550552
SkMethodBody::Normal {
551-
exprs: HirExpressions::new(exprs),
553+
exprs: Hir::expressions(exprs),
552554
},
553555
);
554556
self.method_dict
@@ -648,14 +650,8 @@ fn _set_default(
648650
let arg = Hir::arg_ref(value_expr.ty.clone(), idx, locs.clone());
649651
let cond_expr = Hir::is_omitted_value(arg.clone());
650652

651-
let mut then_exprs = HirExpressions::void();
652-
then_exprs.prepend(vec![Hir::lvar_assign(
653-
name.to_string(),
654-
value_expr,
655-
locs.clone(),
656-
)]);
657-
let mut else_exprs = HirExpressions::void();
658-
else_exprs.prepend(vec![Hir::lvar_assign(name.to_string(), arg, locs)]);
653+
let then_exprs = Hir::lvar_assign(name.to_string(), value_expr, locs.clone());
654+
let else_exprs = Hir::lvar_assign(name.to_string(), arg, locs);
659655

660656
let if_expr = Hir::if_expression(
661657
ty::raw("Void"),

lib/skc_ast2hir/src/pattern_match.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ fn compile_body(
7070
mk: &mut HirMaker,
7171
components: &[Component],
7272
body: &[AstExpression],
73-
) -> Result<(HirExpressions, HirLVars)> {
73+
) -> Result<(HirExpression, HirLVars)> {
7474
mk.ctx_stack.push(HirMakerContext::match_clause());
7575
// Declare lvars introduced by matching
7676
for component in components {
@@ -97,7 +97,9 @@ fn calc_result_ty(mk: &HirMaker, clauses_: &mut [MatchClause]) -> Result<TermTy>
9797
} else if clauses.iter().any(|c| c.body_hir.ty.is_void_type()) {
9898
for c in clauses.iter_mut() {
9999
if !c.body_hir.ty.is_void_type() {
100-
c.body_hir.voidify();
100+
let mut tmp = Hir::expressions(vec![]);
101+
std::mem::swap(&mut tmp, &mut c.body_hir);
102+
c.body_hir = tmp.voidify();
101103
}
102104
}
103105
Ok(ty::raw("Void"))
@@ -124,7 +126,7 @@ fn calc_result_ty(mk: &HirMaker, clauses_: &mut [MatchClause]) -> Result<TermTy>
124126
fn bitcast_match_clause_body(c: &mut MatchClause, ty: TermTy) {
125127
let mut tmp = Hir::expressions(Default::default());
126128
std::mem::swap(&mut tmp, &mut c.body_hir);
127-
tmp = tmp.bitcast_to(ty);
129+
tmp = Hir::bit_cast(ty, tmp);
128130
std::mem::swap(&mut tmp, &mut c.body_hir);
129131
}
130132

lib/skc_ast2hir/src/type_system/type_checking.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ macro_rules! type_error {
1717
pub fn check_return_value(
1818
class_dict: &ClassDict,
1919
sig: &MethodSignature,
20-
body_exprs: &HirExpressions,
20+
body_exprs: &HirExpression,
2121
) -> Result<()> {
2222
let ty = &body_exprs.ty;
2323
if sig.ret_ty.is_void_type() {

lib/skc_codegen/src/gen_exprs.rs

+30-30
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,6 @@ use std::rc::Rc;
1919
const EXIT_BREAK: u64 = 1;
2020

2121
impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
22-
/// Generate LLVM IR from HirExpressions.
23-
/// May return `None` when, for example, it ends with a `return`
24-
/// expression.
25-
pub fn gen_exprs(
26-
&'run self,
27-
ctx: &mut CodeGenContext<'hir, 'run>,
28-
exprs: &'hir HirExpressions,
29-
) -> Result<Option<SkObj<'run>>> {
30-
debug_assert!(!exprs.exprs.is_empty());
31-
let mut last_value = None;
32-
for expr in &exprs.exprs {
33-
let value = self.gen_expr(ctx, expr)?;
34-
if value.is_none() {
35-
//log::warn!("detected unreachable code");
36-
return Ok(None);
37-
} else {
38-
last_value = Some(value);
39-
}
40-
}
41-
Ok(last_value.unwrap())
42-
}
43-
4422
pub fn gen_expr(
4523
&'run self,
4624
ctx: &mut CodeGenContext<'hir, 'run>,
@@ -171,7 +149,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
171149
initialize_name,
172150
init_cls_name,
173151
))),
174-
HirParenthesizedExpr { exprs } => self.gen_exprs(ctx, exprs),
152+
HirParenthesizedExpr { exprs } => self.gen_parenthesized_expr(ctx, exprs),
175153
HirDefaultExpr => Ok(Some(self.gen_default_expr(&expr.ty))),
176154
HirIsOmittedValue { expr } => self.gen_is_omitted_value(ctx, expr),
177155
}
@@ -262,8 +240,8 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
262240
ctx: &mut CodeGenContext<'hir, 'run>,
263241
ty: &TermTy,
264242
cond_expr: &'hir HirExpression,
265-
then_exprs: &'hir HirExpressions,
266-
else_exprs: &'hir HirExpressions,
243+
then_exprs: &'hir HirExpression,
244+
else_exprs: &'hir HirExpression,
267245
) -> Result<Option<SkObj<'run>>> {
268246
let begin_block = self.context.append_basic_block(ctx.function, "IfBegin");
269247
let then_block = self.context.append_basic_block(ctx.function, "IfThen");
@@ -277,14 +255,14 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
277255
self.gen_conditional_branch(cond_value, then_block, else_block);
278256
// IfThen:
279257
self.builder.position_at_end(then_block);
280-
let then_value = self.gen_exprs(ctx, then_exprs)?;
258+
let then_value = self.gen_expr(ctx, then_exprs)?;
281259
if then_value.is_some() {
282260
self.builder.build_unconditional_branch(merge_block);
283261
}
284262
let then_block_end = self.builder.get_insert_block().unwrap();
285263
// IfElse:
286264
self.builder.position_at_end(else_block);
287-
let else_value = self.gen_exprs(ctx, else_exprs)?;
265+
let else_value = self.gen_expr(ctx, else_exprs)?;
288266
if else_value.is_some() {
289267
self.builder.build_unconditional_branch(merge_block);
290268
}
@@ -400,7 +378,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
400378
}
401379
}
402380
let result = self
403-
.gen_exprs(ctx, &clause.body_hir)?
381+
.gen_expr(ctx, &clause.body_hir)?
404382
.map(|v| self.bitcast(v, result_ty, "as"));
405383
ctx.lvars = orig_lvars;
406384
Ok(result)
@@ -410,7 +388,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
410388
&'run self,
411389
ctx: &mut CodeGenContext<'hir, 'run>,
412390
cond_expr: &'hir HirExpression,
413-
body_exprs: &'hir HirExpressions,
391+
body_exprs: &'hir HirExpression,
414392
) -> Result<Option<SkObj<'run>>> {
415393
let begin_block = self.context.append_basic_block(ctx.function, "WhileBegin");
416394
self.builder.build_unconditional_branch(begin_block);
@@ -426,7 +404,7 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
426404
let rc2 = Rc::clone(&rc1);
427405
let orig_loop_end = ctx.current_loop_end.as_ref().map(Rc::clone);
428406
ctx.current_loop_end = Some(rc1);
429-
self.gen_exprs(ctx, body_exprs)?;
407+
self.gen_expr(ctx, body_exprs)?;
430408
ctx.current_loop_end = orig_loop_end;
431409
self.builder.build_unconditional_branch(begin_block);
432410

@@ -1266,6 +1244,28 @@ impl<'hir, 'run, 'ictx> CodeGen<'hir, 'run, 'ictx> {
12661244
cls_obj
12671245
}
12681246

1247+
/// Compile successive expressions. The last evaluated value is returned.
1248+
/// Returns `None` if terminated with a `Never` type (`return`, `panic`, etc.)
1249+
fn gen_parenthesized_expr(
1250+
&'run self,
1251+
ctx: &mut CodeGenContext<'hir, 'run>,
1252+
exprs: &'hir [HirExpression],
1253+
) -> Result<Option<SkObj<'run>>> {
1254+
debug_assert!(!exprs.is_empty());
1255+
let mut last_value = None;
1256+
for expr in exprs {
1257+
let value = self.gen_expr(ctx, expr)?;
1258+
if value.is_none() {
1259+
// Found `return`, `panic` or something. The rest of `exprs`
1260+
// will never be executed
1261+
return Ok(None);
1262+
} else {
1263+
last_value = Some(value);
1264+
}
1265+
}
1266+
Ok(last_value.unwrap())
1267+
}
1268+
12691269
/// Returns a special value (currently a nullptr) that denotes using the default argument value.
12701270
fn gen_default_expr(&'run self, ty: &TermTy) -> SkObj<'run> {
12711271
self.null_ptr(ty)

0 commit comments

Comments
 (0)