-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a0ab3ea
commit a835afd
Showing
4 changed files
with
125 additions
and
2 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
use cider_idx::impl_index; | ||
|
||
/// An identifier representing a given file path | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
pub struct FileId(u32); | ||
impl_index!(FileId); | ||
|
||
/// An identifier representing a location in the Calyx source code | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
pub struct PositionId(u32); | ||
impl_index!(PositionId); | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct LineNum(u32); | ||
|
||
impl LineNum { | ||
pub fn as_usize(&self) -> usize { | ||
self.0 as usize | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,101 @@ | ||
pub struct MetadataTable {} | ||
use std::{ | ||
cell::RefCell, | ||
collections::HashMap, | ||
io::{BufReader, Read}, | ||
path::PathBuf, | ||
}; | ||
|
||
pub struct FileTable {} | ||
use cider_idx::maps::IndexedMap; | ||
|
||
use crate::ids::{FileId, LineNum, PositionId}; | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct MetadataTable { | ||
/// map file ids to the file path, note that this does not contain file content | ||
file_map: IndexedMap<FileId, PathBuf>, | ||
position_map: IndexedMap<PositionId, SourceLocation>, | ||
} | ||
|
||
impl MetadataTable { | ||
pub fn lookup_file_path(&self, file: FileId) -> &PathBuf { | ||
&self.file_map[file] | ||
} | ||
|
||
pub fn lookup_position(&self, pos: PositionId) -> &SourceLocation { | ||
&self.position_map[pos] | ||
} | ||
|
||
pub fn file_reader(&self) -> MetadataFileReader<'_> { | ||
MetadataFileReader::new(self) | ||
} | ||
|
||
pub fn add_file(&mut self, path: PathBuf) -> FileId { | ||
self.file_map.push(path) | ||
} | ||
|
||
pub fn add_position(&mut self, file: FileId, line: LineNum) -> PositionId { | ||
self.position_map.push(SourceLocation::new(line, file)) | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct SourceLocation { | ||
line: LineNum, | ||
file: FileId, | ||
} | ||
|
||
impl SourceLocation { | ||
pub fn new(line: LineNum, file: FileId) -> Self { | ||
Self { line, file } | ||
} | ||
|
||
pub fn line(&self) -> &LineNum { | ||
&self.line | ||
} | ||
|
||
pub fn file(&self) -> FileId { | ||
self.file | ||
} | ||
} | ||
|
||
pub struct MetadataFileReader<'a> { | ||
metadata: &'a MetadataTable, | ||
reader_map: RefCell<HashMap<FileId, Box<str>>>, | ||
} | ||
|
||
impl<'a> MetadataFileReader<'a> { | ||
pub fn new(metadata: &'a MetadataTable) -> Self { | ||
Self { | ||
metadata, | ||
reader_map: RefCell::new(HashMap::new()), | ||
} | ||
} | ||
|
||
/// Looks up the given source position. If the file used by this position | ||
/// has not been read yet this will cause the contents of the file to be | ||
/// read into memory. Will panic if the file does not exist or does not have | ||
/// the line number indicated by the position | ||
/// | ||
/// TODO griffin: make this able to return [str] instead of [String]. Maybe | ||
/// also don't buffer file contents into memory? | ||
pub fn lookup_source(&self, pos: &SourceLocation) -> String { | ||
let mut mut_read = self.reader_map.borrow_mut(); | ||
let content = mut_read.entry(pos.file).or_insert_with(|| { | ||
let file_path = self.metadata.lookup_file_path(pos.file); | ||
let mut buffer = String::new(); | ||
BufReader::new( | ||
std::fs::File::open(file_path).expect("unable to open file"), | ||
) | ||
.read_to_string(&mut buffer) | ||
.expect("couldn't read into str"); | ||
buffer.into_boxed_str() | ||
}); | ||
|
||
let line = content | ||
.lines() | ||
.nth(pos.line.as_usize()) | ||
.expect("file does not have the given line number"); | ||
|
||
line.to_string() | ||
} | ||
} |