sphinx/debug/symbol/
table.rs

1use core::cmp::Ordering;
2use std::collections::HashMap;
3use crate::codegen::Chunk;
4use crate::debug::symbol::DebugSymbol;
5
6pub type ChunkSymbols = HashMap<Chunk, DebugSymbolTable>;
7
8/// Maps bytecode offsets to DebugSymbols
9#[derive(Debug)]
10pub struct DebugSymbolTable {
11    entries: Vec<SymbolTableEntry>,
12}
13
14impl Default for DebugSymbolTable {
15    fn default() -> Self { Self::new() }
16}
17
18impl DebugSymbolTable {
19    pub fn new() -> Self {
20        Self { entries: Vec::new() }
21    }
22    
23    pub fn insert(&mut self, offset: usize, symbol: DebugSymbol) {
24        let entry = SymbolTableEntry(offset, symbol);
25        
26        if matches!(self.entries.last(), Some(last_entry) if entry <= *last_entry) {
27            panic!("symbol inserted out of order");
28        }
29        
30        self.entries.push(entry)
31    }
32    
33    pub fn lookup(&self, offset: usize) -> Option<&DebugSymbol> {
34        if let Ok(index) = self.entries.binary_search_by_key(&offset, SymbolTableEntry::offset) {
35            Some(&self.entries[index].1)
36        } else {
37            None
38        }
39    }
40    
41    pub fn iter(&self) -> impl Iterator<Item=(usize, &DebugSymbol)> + '_ {
42        self.entries.iter().map(|entry| {
43            let SymbolTableEntry(offset, symbol) = entry;
44            (*offset, symbol)
45        })
46    }
47    
48    pub fn symbols(&self) -> impl Iterator<Item=&DebugSymbol> {
49        self.entries.iter().map(|entry| &entry.1)
50    }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54struct SymbolTableEntry(usize, DebugSymbol);
55
56impl PartialOrd for SymbolTableEntry {
57    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
58        usize::partial_cmp(&self.0, &other.0)
59    }
60}
61
62impl Ord for SymbolTableEntry {
63    fn cmp(&self, other: &Self) -> Ordering {
64        usize::cmp(&self.0, &other.0)
65    }
66}
67
68impl SymbolTableEntry {
69    fn offset(&self) -> usize { self.0 }
70}