mirror of
https://github.com/Noratrieb/m8db.git
synced 2026-01-16 00:05:03 +01:00
debug printing the program now shows the original source code
This commit is contained in:
parent
dba4a2e2ec
commit
92b026ccba
3 changed files with 69 additions and 36 deletions
33
src/db.rs
33
src/db.rs
|
|
@ -1,9 +1,11 @@
|
||||||
use crate::stmt::Stmt;
|
use crate::stmt::{Code, Stmt};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct Vm {
|
struct Vm<'a> {
|
||||||
stmts: Vec<Stmt>,
|
stmts: Vec<Stmt>,
|
||||||
|
span: Vec<usize>,
|
||||||
|
code_lines: Vec<&'a str>,
|
||||||
pc: usize,
|
pc: usize,
|
||||||
registers: Vec<usize>,
|
registers: Vec<usize>,
|
||||||
breakpoints: Vec<usize>,
|
breakpoints: Vec<usize>,
|
||||||
|
|
@ -17,7 +19,7 @@ enum VmState {
|
||||||
OutOfBounds,
|
OutOfBounds,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vm {
|
impl Vm<'_> {
|
||||||
fn step(&mut self) -> VmState {
|
fn step(&mut self) -> VmState {
|
||||||
let pc = self.pc;
|
let pc = self.pc;
|
||||||
self.pc += 1;
|
self.pc += 1;
|
||||||
|
|
@ -57,10 +59,12 @@ enum VmInstruction {
|
||||||
Set(usize, usize),
|
Set(usize, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(stmts: Vec<Stmt>) {
|
pub fn run(code: Code) {
|
||||||
let max_register_index = max_register(&stmts);
|
let max_register_index = max_register(&code.stmts);
|
||||||
let mut vm = Vm {
|
let mut vm = Vm {
|
||||||
stmts,
|
stmts: code.stmts,
|
||||||
|
span: code.span,
|
||||||
|
code_lines: code.code_lines,
|
||||||
pc: 0,
|
pc: 0,
|
||||||
registers: vec![0; max_register_index + 1],
|
registers: vec![0; max_register_index + 1],
|
||||||
breakpoints: vec![],
|
breakpoints: vec![],
|
||||||
|
|
@ -157,16 +161,19 @@ fn print_program(vm: &Vm) {
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
|
|
||||||
println!("Program:");
|
println!("Program:");
|
||||||
let lower = if vm.pc > 5 { vm.pc - 5 } else { 0 };
|
let lower_stmt = if vm.pc > 5 { vm.pc - 5 } else { 0 };
|
||||||
let len = vm.stmts.len();
|
let len = vm.stmts.len();
|
||||||
let higher = if len < 5 { len } else { min(vm.pc + 5, len) };
|
let higher_stmt = if len < 5 { len } else { min(vm.pc + 5, len) };
|
||||||
|
|
||||||
for i in lower..higher {
|
let lower_code = vm.span[lower_stmt];
|
||||||
let stmt = vm.stmts[i];
|
let higher_code = vm.span[higher_stmt - 1];
|
||||||
if i == vm.pc {
|
|
||||||
println!("> {} {}", i, stmt)
|
for line_number in lower_code..higher_code {
|
||||||
|
let code_line = vm.code_lines[line_number];
|
||||||
|
if line_number == vm.span[vm.pc] {
|
||||||
|
println!("> {} {}", line_number, code_line)
|
||||||
} else {
|
} else {
|
||||||
println!("{} {}", i, stmt);
|
println!("{} {}", line_number, code_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
src/stmt.rs
62
src/stmt.rs
|
|
@ -11,6 +11,13 @@ pub enum Stmt {
|
||||||
Stop,
|
Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Code<'a> {
|
||||||
|
pub stmts: Vec<Stmt>,
|
||||||
|
/// Has the same length as `stmts`, points to line numbers where the instructions come from
|
||||||
|
pub span: Vec<usize>,
|
||||||
|
pub code_lines: Vec<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
enum IrStmt<'a> {
|
enum IrStmt<'a> {
|
||||||
Inc(usize),
|
Inc(usize),
|
||||||
Dec(usize),
|
Dec(usize),
|
||||||
|
|
@ -20,13 +27,15 @@ enum IrStmt<'a> {
|
||||||
Stop,
|
Stop,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(text: &str) -> Result<Vec<Stmt>, String> {
|
pub fn parse(text: &str) -> Result<Code, String> {
|
||||||
let mut labels = HashMap::new();
|
let mut labels = HashMap::new();
|
||||||
|
|
||||||
let mut statements = Vec::new();
|
let mut statements = Vec::new();
|
||||||
let mut statement_number = 0;
|
let mut statement_number = 0;
|
||||||
|
|
||||||
for (line_number, line) in text.lines().enumerate() {
|
let code_lines = text.lines().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (line_number, line) in code_lines.iter().enumerate() {
|
||||||
if line.split_whitespace().next().is_none() {
|
if line.split_whitespace().next().is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -43,26 +52,43 @@ pub fn parse(text: &str) -> Result<Vec<Stmt>, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
statements
|
let result: Result<Vec<(Stmt, usize)>, String> = statements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|stmt| match stmt.0 {
|
.map(|(stmt, span)| match *stmt {
|
||||||
IrStmt::Inc(r) => Ok(Stmt::Inc(r)),
|
IrStmt::Inc(r) => Ok((Stmt::Inc(r), *span)),
|
||||||
IrStmt::Dec(r) => Ok(Stmt::Dec(r)),
|
IrStmt::Dec(r) => Ok((Stmt::Dec(r), *span)),
|
||||||
IrStmt::IsZero(r, label) => Ok(Stmt::IsZero(
|
IrStmt::IsZero(r, label) => Ok((
|
||||||
r,
|
Stmt::IsZero(
|
||||||
match labels.get(label) {
|
r,
|
||||||
Some(line) => *line,
|
match labels.get(label) {
|
||||||
None => return Err(format!("Label '{}' not found on line {}", label, stmt.1)),
|
Some(line) => *line,
|
||||||
},
|
None => {
|
||||||
|
return Err(format!("Label '{}' not found on line {}", label, span))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
*span,
|
||||||
)),
|
)),
|
||||||
IrStmt::Jump(label) => Ok(Stmt::Jump(match labels.get(label) {
|
IrStmt::Jump(label) => Ok((
|
||||||
Some(line) => *line,
|
Stmt::Jump(match labels.get(label) {
|
||||||
None => return Err(format!("Label '{}' not found on line {}", label, stmt.1)),
|
Some(line) => *line,
|
||||||
})),
|
None => return Err(format!("Label '{}' not found on line {}", label, span)),
|
||||||
IrStmt::Stop => Ok(Stmt::Stop),
|
}),
|
||||||
|
*span,
|
||||||
|
)),
|
||||||
|
IrStmt::Stop => Ok((Stmt::Stop, *span)),
|
||||||
IrStmt::Label(_) => unreachable!(),
|
IrStmt::Label(_) => unreachable!(),
|
||||||
})
|
})
|
||||||
.collect()
|
.collect();
|
||||||
|
|
||||||
|
result.map(|vec| {
|
||||||
|
let (stmts, span) = vec.iter().cloned().unzip();
|
||||||
|
Code {
|
||||||
|
stmts,
|
||||||
|
span,
|
||||||
|
code_lines,
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_line(line: &str) -> Result<IrStmt, String> {
|
fn parse_line(line: &str) -> Result<IrStmt, String> {
|
||||||
|
|
|
||||||
10
test.m8
10
test.m8
|
|
@ -1,8 +1,8 @@
|
||||||
INC 0
|
INC 1
|
||||||
INC 0
|
.test1
|
||||||
|
.test2
|
||||||
|
.test3
|
||||||
|
INC 1
|
||||||
JUMP end
|
JUMP end
|
||||||
DEC 0
|
|
||||||
DEC 0
|
|
||||||
DEC 0
|
|
||||||
.end
|
.end
|
||||||
STOP
|
STOP
|
||||||
Loading…
Add table
Add a link
Reference in a new issue