Skip to content

Commit 4bfce36

Browse files
committed
chore(interpreter): code clean-up
1 parent 94dc851 commit 4bfce36

2 files changed

Lines changed: 76 additions & 96 deletions

File tree

‎interpreter/src/ir.rs‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,17 @@ impl Instruction {
117117
}
118118
}
119119

120-
fn push_start_label(&mut self) {
121-
if let Self::Branch((_, label, _)) = self {
120+
fn push_end_label(&mut self) {
121+
if let Self::Branch((_, _, label)) = self {
122122
label.0 += 1;
123123
} else {
124124
debug_assert!(false, "Incorrect label set!");
125125
}
126126
}
127+
128+
fn br(cond: MaybeImm, then: Label) -> Self {
129+
Self::Branch((cond, then, Label(0)))
130+
}
127131
}
128132

129133
impl Display for Instruction {

‎interpreter/src/ir/lower.rs‎

Lines changed: 70 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -49,47 +49,26 @@ impl<'a> Code<'a> {
4949
fn lower_statement(&mut self, stmnt: &Statement) {
5050
match stmnt {
5151
Statement::If { condition, then_body, else_body } => {
52-
let mut state = RegsState::new(self);
53-
let condition = self.lower_expr(condition);
54-
let label_then = self.following_instr(1);
55-
let if_label = self.bc.emit(Instruction::Branch((
56-
condition.to_mi(),
57-
label_then,
58-
Label(0),
59-
)));
60-
condition.free(self);
61-
self.lower_body(then_body);
62-
let next = self.following_instr(0);
63-
self.bc.nth(if_label).set_label(next);
52+
let state = RegsState::new(self);
53+
let (if_label, _) = self.emit_branch(condition, |this| this.lower_body(then_body));
6454

6555
if let Some(else_body) = else_body {
66-
state.reg_pointer =
67-
state.reg_pointer.checked_add(1).expect("register overflow");
68-
self.bc.nth(if_label).push_start_label();
69-
let end_label = self.bc.emit(Instruction::Jump(Label(0)));
70-
state.scope_hwm(self, |c| c.lower_body(else_body));
71-
let next = self.following_instr(0);
72-
self.bc.nth(end_label).set_label(next);
56+
self.bc.nth(if_label).push_end_label();
57+
self.emit_jump(|this| state.scope_hwm(this, |this| this.lower_body(else_body)));
7358
}
7459
}
7560
Statement::While { condition, then_body } => {
7661
let cond_label = self.following_instr(0);
77-
let condition = self.lower_expr(condition);
78-
let while_label = self.bc.emit(Instruction::Branch((
79-
condition.to_mi(),
80-
self.following_instr(1),
81-
Label(0),
82-
)));
83-
condition.free(self);
84-
self.lower_body(then_body);
85-
self.bc.emit(Instruction::Jump(cond_label));
86-
let next = self.following_instr(0);
87-
self.bc.nth(while_label).set_label(next);
62+
self.emit_branch(condition, |this| {
63+
this.lower_body(then_body);
64+
this.bc.emit(Instruction::Jump(cond_label));
65+
});
8866
}
8967
Statement::DoWhile { then_body, condition } => {
9068
let do_label = self.following_instr(0);
9169
self.lower_body(then_body);
9270
let condition = self.lower_expr(condition);
71+
9372
self.bc.emit(Instruction::Branch((
9473
condition.to_mi(),
9574
do_label,
@@ -99,39 +78,28 @@ impl<'a> Code<'a> {
9978
}
10079
Statement::For { init, condition, update, body } => {
10180
if let Some(SimpleStatement::Expression(expr)) = init {
102-
let value = self.lower_expr(expr);
103-
value.free(self);
81+
self.lower_expr(expr).free(self);
10482
}
83+
10584
let cond_label = self.following_instr(0);
10685
if let Some(condition) = condition {
107-
let condition = self.lower_expr(condition);
108-
let body_label = self.following_instr(1);
109-
let while_label = self.bc.emit(Instruction::Branch((
110-
condition.to_mi(),
111-
body_label,
112-
Label(0),
113-
)));
114-
condition.free(self);
115-
self.lower_body(body);
116-
if let Some(SimpleStatement::Expression(expr)) = update {
117-
let value = self.lower_expr(expr);
118-
value.free(self);
119-
}
120-
self.bc.emit(Instruction::Jump(cond_label));
121-
let next = self.following_instr(0);
122-
self.bc.nth(while_label).set_label(next);
86+
self.emit_branch(condition, |this| {
87+
this.lower_body(body);
88+
if let Some(SimpleStatement::Expression(expr)) = update {
89+
this.lower_expr(expr).free(this);
90+
}
91+
this.bc.emit(Instruction::Jump(cond_label));
92+
});
12393
} else {
12494
self.lower_body(body);
12595
if let Some(SimpleStatement::Expression(expr)) = update {
126-
let value = self.lower_expr(expr);
127-
value.free(self);
96+
self.lower_expr(expr).free(self);
12897
}
12998
self.bc.emit(Instruction::Jump(cond_label));
13099
}
131100
}
132101
Statement::Simple(SimpleStatement::Expression(expr)) => {
133-
let value = self.lower_expr(expr);
134-
value.free(self);
102+
self.lower_expr(expr).free(self);
135103
}
136104
Statement::Simple(SimpleStatement::Command { name, args, redirection }) => {
137105
let (call_start, call_end, redir) = self.gen_call_convention(args, |this| {
@@ -231,32 +199,21 @@ impl<'a> Code<'a> {
231199
lhs.free(self);
232200
rhs.free(self);
233201
}
234-
ExprNode::Ternary(cond, true_then, false_then) => {
235-
let cond = self.lower_expr(cond);
236-
let branch = self.bc.emit(Instruction::Branch((
237-
cond.to_mi(),
238-
self.following_instr(1),
239-
Label(0),
240-
)));
241-
cond.free(self);
242-
243-
let mut state = RegsState::new(self);
244-
state = state
245-
.scope(self, |c| {
246-
c.lower_expr_into(true_then, dest);
247-
})
248-
.0;
249-
250-
let jump = self.bc.emit(Instruction::Jump(Label(0)));
251-
let label = self.following_instr(0);
252-
253-
state.scope_hwm(self, |c| {
254-
c.lower_expr_into(false_then, dest);
202+
ExprNode::Ternary(condition, true_then, false_then) => {
203+
let (if_label, state) = self.emit_branch(condition, |this| {
204+
RegsState::new(this)
205+
.scope(this, |this| {
206+
this.lower_expr_into(true_then, dest);
207+
})
208+
.0
255209
});
256210

257-
self.bc.nth(branch).set_label(label);
258-
let next = self.following_instr(0);
259-
self.bc.nth(jump).set_label(next);
211+
self.bc.nth(if_label).push_end_label();
212+
self.emit_jump(|this| {
213+
state.scope_hwm(this, |this| {
214+
this.lower_expr_into(false_then, dest);
215+
});
216+
});
260217
}
261218
ExprNode::BinaryPlaceOperation(op, place, expr) => {
262219
let val = self.lower_expr(expr);
@@ -334,12 +291,9 @@ impl<'a> Code<'a> {
334291
}
335292
Place::Index(var, index) => {
336293
let (start, end, _) = self.gen_call_convention(index, |_| ());
337-
self.bc.emit(Instruction::LoadBuiltinArray((
338-
dest,
339-
start,
340-
end,
341-
var_index(var),
342-
)));
294+
let index = var_index(var);
295+
self.bc
296+
.emit(Instruction::LoadBuiltinArray((dest, start, end, index)));
343297
MaybeImm::Reg(dest)
344298
}
345299
Place::ChainedIndex(_, _) => todo!(),
@@ -355,15 +309,13 @@ impl<'a> Code<'a> {
355309
rec.free(self);
356310
}
357311
Place::Variable(Variable::User(ident)) => {
358-
self.bc.emit(Instruction::StoreUserScalar((
359-
dest,
360-
src,
361-
self.symbols.register_user_var(ident, self.arena),
362-
)));
312+
let var = self.symbols.register_user_var(ident, self.arena);
313+
self.bc.emit(Instruction::StoreUserScalar((dest, src, var)));
363314
}
364315
Place::Variable(var) => {
316+
let index = var_index(var);
365317
self.bc
366-
.emit(Instruction::StoreBuiltinScalar((dest, src, var_index(var))));
318+
.emit(Instruction::StoreBuiltinScalar((dest, src, index)));
367319
}
368320
Place::Index(Variable::User(ident), index) => {
369321
let place = self.symbols.register_user_var(ident, self.arena);
@@ -373,17 +325,39 @@ impl<'a> Code<'a> {
373325
}
374326
Place::Index(var, index) => {
375327
let (start, end, _) = self.gen_call_convention(index, |_| ());
376-
self.bc.emit(Instruction::StoreBuiltinArray((
377-
dest,
378-
start,
379-
end,
380-
var_index(var),
381-
)));
328+
let index = var_index(var);
329+
self.bc
330+
.emit(Instruction::StoreBuiltinArray((dest, start, end, index)));
382331
}
383332
Place::ChainedIndex(_, _) => todo!(),
384333
}
385334
}
386335

336+
fn emit_branch<T>(
337+
&mut self,
338+
condition: &Expr<'_>,
339+
cb: impl FnOnce(&mut Self) -> T,
340+
) -> (Label, T) {
341+
let condition = self.lower_expr(condition);
342+
let then_label = self.following_instr(1);
343+
let if_label = self.bc.emit(Instruction::br(condition.to_mi(), then_label));
344+
condition.free(self);
345+
346+
let res = cb(self);
347+
let next = self.following_instr(0);
348+
self.bc.nth(if_label).set_label(next);
349+
350+
(if_label, res)
351+
}
352+
353+
fn emit_jump<T>(&mut self, cb: impl FnOnce(&mut Self) -> T) -> T {
354+
let label = self.bc.emit(Instruction::Jump(Label(0)));
355+
let res = cb(self);
356+
let next = self.following_instr(0);
357+
self.bc.nth(label).set_label(next);
358+
res
359+
}
360+
387361
fn alloc_reg(&mut self) -> LinearReg {
388362
self.free_regs.pop().map(LinearReg).unwrap_or_else(|| {
389363
let current = self.reg_pointer;
@@ -466,13 +440,15 @@ impl RegsState {
466440
n_free_regs: code.free_regs.len(),
467441
}
468442
}
443+
469444
fn scope<T>(self, code: &mut Code, f: impl FnOnce(&mut Code) -> T) -> (Self, T) {
470445
let ret = f(code);
471446
let old = code.reg_pointer;
472447
code.reg_pointer = self.reg_pointer;
473448
code.free_regs.truncate(self.n_free_regs);
474449
(Self { reg_pointer: old, ..self }, ret)
475450
}
451+
476452
fn scope_hwm<T>(self, code: &mut Code, f: impl FnOnce(&mut Code) -> T) {
477453
f(code);
478454
code.reg_pointer = code.reg_pointer.max(self.reg_pointer);

0 commit comments

Comments
 (0)