mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 13:11:11 +00:00
Implement while instructions
This commit is contained in:
parent
4fb43e520e
commit
4eae5788ca
2 changed files with 28 additions and 4 deletions
|
@ -394,10 +394,10 @@ fn format_code_and_pointer<E: ErrorDisplay + ?Sized>(
|
||||||
let mut pointer = " ".repeat(lineno.to_string().len() + 2); // +2 means `| `
|
let mut pointer = " ".repeat(lineno.to_string().len() + 2); // +2 means `| `
|
||||||
if i == 0 && i == final_step {
|
if i == 0 && i == final_step {
|
||||||
pointer += &" ".repeat(col_begin);
|
pointer += &" ".repeat(col_begin);
|
||||||
pointer += &"^".repeat(cmp::max(1, col_end - col_begin));
|
pointer += &"^".repeat(cmp::max(1, col_end.saturating_sub(col_begin)));
|
||||||
} else if i == 0 {
|
} else if i == 0 {
|
||||||
pointer += &" ".repeat(col_begin);
|
pointer += &" ".repeat(col_begin);
|
||||||
pointer += &"^".repeat(cmp::max(1, codes[i].len() - col_begin));
|
pointer += &"^".repeat(cmp::max(1, codes[i].len().saturating_sub(col_begin)));
|
||||||
} else if i == final_step {
|
} else if i == final_step {
|
||||||
pointer += &"^".repeat(col_end);
|
pointer += &"^".repeat(col_end);
|
||||||
} else {
|
} else {
|
||||||
|
@ -406,7 +406,7 @@ fn format_code_and_pointer<E: ErrorDisplay + ?Sized>(
|
||||||
writeln!(
|
writeln!(
|
||||||
res,
|
res,
|
||||||
"{lineno}{VBAR_UNICODE} {code}\n{pointer}",
|
"{lineno}{VBAR_UNICODE} {code}\n{pointer}",
|
||||||
code = codes[i]
|
code = codes.get(i).unwrap_or(&String::new()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1138,11 +1138,34 @@ impl CodeGenerator {
|
||||||
self.write_arg((idx_for_iter / 2) as u8);
|
self.write_arg((idx_for_iter / 2) as u8);
|
||||||
let idx_end = self.cur_block().lasti;
|
let idx_end = self.cur_block().lasti;
|
||||||
self.edit_code(idx_for_iter + 1, (idx_end - idx_for_iter - 2) / 2);
|
self.edit_code(idx_for_iter + 1, (idx_end - idx_for_iter - 2) / 2);
|
||||||
// self.emit_pop_top();
|
|
||||||
self.stack_dec();
|
self.stack_dec();
|
||||||
self.emit_load_const(ValueObj::None);
|
self.emit_load_const(ValueObj::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_while_instr(&mut self, mut args: Args) {
|
||||||
|
log!(info "entered {} ({})", fn_name!(), args);
|
||||||
|
let cond = args.remove(0);
|
||||||
|
self.emit_expr(cond.clone());
|
||||||
|
let idx_while = self.cur_block().lasti;
|
||||||
|
self.write_instr(POP_JUMP_IF_FALSE);
|
||||||
|
self.write_arg(0);
|
||||||
|
self.stack_dec();
|
||||||
|
let lambda = enum_unwrap!(args.remove(0), Expr::Lambda);
|
||||||
|
let init_stack_len = self.cur_block().stack_len;
|
||||||
|
let params = self.gen_param_names(&lambda.params);
|
||||||
|
self.emit_frameless_block(lambda.body, params);
|
||||||
|
if self.cur_block().stack_len > init_stack_len {
|
||||||
|
self.emit_pop_top();
|
||||||
|
}
|
||||||
|
self.emit_expr(cond);
|
||||||
|
self.write_instr(POP_JUMP_IF_TRUE);
|
||||||
|
self.write_arg(((idx_while + 2) / 2) as u8);
|
||||||
|
self.stack_dec();
|
||||||
|
let idx_end = self.cur_block().lasti;
|
||||||
|
self.edit_code(idx_while + 1, idx_end / 2);
|
||||||
|
self.emit_load_const(ValueObj::None);
|
||||||
|
}
|
||||||
|
|
||||||
fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) {
|
fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let expr = args.remove(0);
|
let expr = args.remove(0);
|
||||||
|
@ -1316,6 +1339,7 @@ impl CodeGenerator {
|
||||||
"Del" => self.emit_del_instr(args),
|
"Del" => self.emit_del_instr(args),
|
||||||
"discard" => self.emit_discard_instr(args),
|
"discard" => self.emit_discard_instr(args),
|
||||||
"for" | "for!" => self.emit_for_instr(args),
|
"for" | "for!" => self.emit_for_instr(args),
|
||||||
|
"while!" => self.emit_while_instr(args),
|
||||||
"if" | "if!" => self.emit_if_instr(args),
|
"if" | "if!" => self.emit_if_instr(args),
|
||||||
"match" | "match!" => self.emit_match_instr(args, true),
|
"match" | "match!" => self.emit_match_instr(args, true),
|
||||||
"with!" => self.emit_with_instr(args),
|
"with!" => self.emit_with_instr(args),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue