mirror of
https://github.com/uutils/awk.git
synced 2026-06-10 16:15:04 -07:00
chore(interpreter): better formatting
This commit is contained in:
@@ -3,10 +3,9 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// files that was distributed with this source code.
|
||||
|
||||
use std::{fmt::Display, hash::Hash, mem::forget};
|
||||
use std::{hash::Hash, mem::forget};
|
||||
|
||||
use bumpalo::{Bump, collections::Vec};
|
||||
use indexmap::IndexSet;
|
||||
use parser::{
|
||||
Atom, BinaryOperator, BinaryPlaceOperator, Body, Expr, ExprNode, Place, SimpleStatement,
|
||||
Statement, UnaryOperator, Variable,
|
||||
@@ -14,14 +13,14 @@ use parser::{
|
||||
|
||||
use crate::{
|
||||
ir::{Hint, HintedReg, Instruction, Label, NonLocal, OpCode, Reg},
|
||||
vm::{ExecMode, Interpreter, SymbolTable, Value},
|
||||
vm::{Consts, ExecMode, Interpreter, SymbolTable, Value},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Code<'arena> {
|
||||
pub arena: &'arena Bump,
|
||||
pub bc: Bytecode<'arena>,
|
||||
pub consts: IndexSet<Value>,
|
||||
pub consts: Consts,
|
||||
pub symbols: SymbolTable<'arena>,
|
||||
free_regs: Vec<'arena, Reg>,
|
||||
pub reg_pointer: u16,
|
||||
@@ -176,7 +175,7 @@ impl Code<'_> {
|
||||
}
|
||||
|
||||
fn register_const(&mut self, value: Value) -> NonLocal {
|
||||
NonLocal(self.consts.insert_full(value).0 as u16)
|
||||
NonLocal(self.consts.0.insert_full(value).0 as u16)
|
||||
}
|
||||
|
||||
fn following_instr(&self, nth: u16) -> Label {
|
||||
@@ -236,21 +235,20 @@ impl RegsState {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_interpreter(stmnt: &Body<'_>) -> impl Display {
|
||||
pub fn test_interpreter(stmnt: &Body<'_>) -> String {
|
||||
let bump = Bump::with_capacity(16384);
|
||||
let mut c = Code {
|
||||
arena: &bump,
|
||||
bc: Bytecode::new_in(&bump),
|
||||
consts: IndexSet::new(),
|
||||
consts: Consts::new(),
|
||||
symbols: SymbolTable::new_in(&bump),
|
||||
reg_pointer: 0,
|
||||
free_regs: Vec::new_in(&bump),
|
||||
};
|
||||
c.lower_body(stmnt);
|
||||
let code = c.to_string();
|
||||
let mut vm = Interpreter::new(ExecMode::Uu, c);
|
||||
vm.run();
|
||||
format!("{code}---\n{vm:#?}")
|
||||
vm.to_string()
|
||||
}
|
||||
|
||||
impl From<UnaryOperator> for OpCode {
|
||||
@@ -301,33 +299,6 @@ impl Eq for Value {}
|
||||
// fn fold(&self, args: Self::Args) -> T;
|
||||
// }
|
||||
|
||||
impl Display for Bytecode<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let n = self.code.len() / 10 + 1;
|
||||
for (i, e) in self.code.iter().enumerate() {
|
||||
write!(f, "{i:n$}: {e}")?;
|
||||
if i + 1 < self.code.len() as _ {
|
||||
writeln!(f)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Code<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "Bytecode:\n{}\n", self.bc)?;
|
||||
writeln!(f, "Consts:")?;
|
||||
for (i, e) in self.consts.iter().enumerate() {
|
||||
write!(f, "mem[{i}] = {}", e.0)?;
|
||||
if i + 1 < self.consts.len() as _ {
|
||||
writeln!(f)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl LinearReg {
|
||||
fn into_inner(self) -> Reg {
|
||||
let inner = self.0;
|
||||
|
||||
+74
-2
@@ -1,3 +1,5 @@
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use bumpalo::{Bump, collections::Vec};
|
||||
use hashbrown::{DefaultHashBuilder, HashMap};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
@@ -26,7 +28,7 @@ pub struct Interpreter<'a> {
|
||||
program_counter: usize,
|
||||
registers: Registers<'a>,
|
||||
symbols: SymbolTable<'a>,
|
||||
consts: IndexSet<Value>,
|
||||
consts: Consts,
|
||||
compat: ExecMode,
|
||||
}
|
||||
|
||||
@@ -41,6 +43,9 @@ pub struct SymbolTable<'a> {
|
||||
// etc
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Consts(pub IndexSet<Value>);
|
||||
|
||||
impl<'a> Interpreter<'a> {
|
||||
pub fn new(compat: ExecMode, code: Code<'a>) -> Self {
|
||||
Self {
|
||||
@@ -83,6 +88,12 @@ impl<'a> SymbolTable<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Consts {
|
||||
pub fn new() -> Self {
|
||||
Self(IndexSet::with_capacity(4))
|
||||
}
|
||||
}
|
||||
|
||||
impl Interpreter<'_> {
|
||||
pub fn run(&mut self) {
|
||||
while let Some(instr) = self.bc.code.get(self.program_counter) {
|
||||
@@ -103,7 +114,7 @@ impl Interpreter<'_> {
|
||||
ix if let Some(&(dest, src)) = ix.get_load_store() => match ix.opcode {
|
||||
OpCode::LoadConst => self
|
||||
.registers
|
||||
.write(dest, self.consts.get_index(src.0 as _).unwrap()),
|
||||
.write(dest, self.consts.0.get_index(src.0 as _).unwrap()),
|
||||
OpCode::LoadUser => {
|
||||
self.registers
|
||||
.write(dest, self.symbols.lookup_user_var(src));
|
||||
@@ -141,3 +152,64 @@ impl Registers<'_> {
|
||||
self.0[dest.0 as usize] = Value::clone(src);
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Interpreter<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{}\n", self.bc)?;
|
||||
writeln!(f, "{}\n", self.registers)?;
|
||||
writeln!(f, "{}\n", self.symbols)?;
|
||||
write!(f, "{}", self.consts)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Code<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "{}\n", self.bc)?;
|
||||
writeln!(f, "{}\n", self.symbols)?;
|
||||
write!(f, "{}", self.consts)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Bytecode<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Bytecode:")?;
|
||||
let n = self.code.len().checked_ilog10().unwrap_or(0) as usize + 1;
|
||||
fmt_list(f, self.code.iter(), |f, i, e| write!(f, "{i:0n$}: {e}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Registers<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Registers:")?;
|
||||
let n = self.0.len().checked_ilog10().unwrap_or(0) as usize + 1;
|
||||
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "r{i:0n$} = {e:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for SymbolTable<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Symbols:")?;
|
||||
fmt_list(f, self.user.iter(), |f, i, (k, v)| {
|
||||
write!(f, "user[{i}] @ {k} = {v:?}")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Consts {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Consts:")?;
|
||||
fmt_list(f, self.0.iter(), |f, i, e| write!(f, "mem[{i}] = {e:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_list<'a, T: Copy>(
|
||||
f: &mut fmt::Formatter<'a>,
|
||||
iter: impl Iterator<Item = T>,
|
||||
cb: impl Fn(&mut fmt::Formatter<'a>, usize, T) -> fmt::Result,
|
||||
) -> fmt::Result {
|
||||
for (i, e) in iter.enumerate() {
|
||||
write!(f, "\n ")?;
|
||||
cb(f, i, e)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user