summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/br.rs85
1 files changed, 62 insertions, 23 deletions
diff --git a/src/bin/br.rs b/src/bin/br.rs
index bf3befe..e96df54 100644
--- a/src/bin/br.rs
+++ b/src/bin/br.rs
@@ -43,13 +43,18 @@ fn main_run(args: Run) {
unsafe { VERBOSE = true; }
}
- let bytecode = load_bytecode(args.program.as_ref().map(|p| p.as_path()));
+ let program_path = args.program.as_ref().map(|p| p.as_path());
+ let Bytecode { bytes: bytecode, path } = load_bytecode(program_path);
+ let symbols_path = path.as_ref().map(|p| {
+ let mut path = p.to_path_buf();
+ path.set_extension("br.sym");
+ path
+ });
+
let metadata = parse_metadata(&bytecode);
if metadata.is_none() {
verbose!("Could not read program metadata");
}
- // TODO: Load and parse symbols file into debug state, use nearest symbol
- // path when debugging.
let mut config = EmulatorConfig {
dimensions: ScreenDimensions::ZERO,
@@ -60,6 +65,7 @@ fn main_run(args: Run) {
initial_transmission: None,
decode_stdin: args.decode_stdin,
encode_stdout: args.encode_stdout,
+ symbols_path,
};
let phosphor = Phosphor::new();
@@ -106,14 +112,18 @@ fn main_run(args: Run) {
std::process::exit(0);
}
-fn load_bytecode(path: Option<&Path>) -> Vec<u8> {
+fn load_bytecode(path: Option<&Path>) -> Bytecode {
// TODO: Etch file location into bytecode.
if let Some(path) = path {
if let Ok(bytecode) = load_bytecode_from_file(path) {
- verbose!("Loaded program from {path:?} ({} bytes)", bytecode.len());
+ let length = bytecode.bytes.len();
+ let path = bytecode.path();
+ verbose!("Loaded program from {path:?} ({length} bytes)");
return bytecode;
- } else if let Some((bytecode, path)) = load_bytecode_from_bedrock_path(path) {
- verbose!("Loaded program from {path:?} ({} bytes)", bytecode.len());
+ } else if let Some(bytecode) = load_bytecode_from_bedrock_path(path) {
+ let length = bytecode.bytes.len();
+ let path = bytecode.path();
+ verbose!("Loaded program from {path:?} ({length} bytes)");
return bytecode;
} else {
eprintln!("Could not read program from {path:?}, exiting");
@@ -122,7 +132,8 @@ fn load_bytecode(path: Option<&Path>) -> Vec<u8> {
} else {
verbose!("Reading program from standard input...");
if let Ok(bytecode) = load_bytecode_from_stdin() {
- verbose!("Loaded program from standard input ({} bytes)", bytecode.len());
+ let length = bytecode.bytes.len();
+ verbose!("Loaded program from standard input ({length} bytes)");
return bytecode;
} else {
eprintln!("Could not read program from standard input, exiting");
@@ -131,13 +142,8 @@ fn load_bytecode(path: Option<&Path>) -> Vec<u8> {
}
}
-/// Attempt to load bytecode from a file path.
-fn load_bytecode_from_file(path: &Path) -> Result<Vec<u8>, std::io::Error> {
- load_bytecode_from_readable_source(std::fs::File::open(path)?)
-}
-
/// Attempt to load bytecode from a directory in the BEDROCK_PATH environment variable.
-fn load_bytecode_from_bedrock_path(path: &Path) -> Option<(Vec<u8>, PathBuf)> {
+fn load_bytecode_from_bedrock_path(path: &Path) -> Option<Bytecode> {
if path.is_relative() && path.components().count() == 1 {
for base_path in std::env::var("BEDROCK_PATH").ok()?.split(':') {
let mut base_path = PathBuf::from(base_path);
@@ -145,29 +151,48 @@ fn load_bytecode_from_bedrock_path(path: &Path) -> Option<(Vec<u8>, PathBuf)> {
base_path.push(path);
verbose!("Attempting to load program from {base_path:?}");
if let Ok(bytecode) = load_bytecode_from_file(&base_path) {
- return Some((bytecode, base_path));
+ return Some(bytecode);
}
if path.extension().is_some() { continue; }
base_path.set_extension("br");
verbose!("Attempting to load program from {base_path:?}");
if let Ok(bytecode) = load_bytecode_from_file(&base_path) {
- return Some((bytecode, base_path));
+ return Some(bytecode);
}
}
}
return None;
}
+/// Attempt to load bytecode from a file path.
+fn load_bytecode_from_file(path: &Path) -> Result<Bytecode, std::io::Error> {
+ load_bytecode_from_readable_source(std::fs::File::open(path)?, Some(path))
+}
+
/// Attempt to load bytecode from standard input.
-fn load_bytecode_from_stdin() -> Result<Vec<u8>, std::io::Error> {
- load_bytecode_from_readable_source(std::io::stdin())
+fn load_bytecode_from_stdin() -> Result<Bytecode, std::io::Error> {
+ load_bytecode_from_readable_source(std::io::stdin(), None)
}
/// Attempt to load bytecode from a source that implements std::io::Read.
-fn load_bytecode_from_readable_source(source: impl Read) -> Result<Vec<u8>, std::io::Error> {
- let mut bytecode = Vec::<u8>::new();
- source.take(65536).read_to_end(&mut bytecode)?;
- return Ok(bytecode);
+fn load_bytecode_from_readable_source(source: impl Read, path: Option<&Path>) -> Result<Bytecode, std::io::Error> {
+ let mut bytes = Vec::<u8>::new();
+ source.take(65536).read_to_end(&mut bytes)?;
+ return Ok(Bytecode { bytes, path: path.map(|p| p.to_path_buf()) });
+}
+
+struct Bytecode {
+ bytes: Vec<u8>,
+ path: Option<PathBuf>,
+}
+
+impl Bytecode {
+ fn path(&self) -> String {
+ match &self.path {
+ Some(path) => path.as_os_str().to_string_lossy().to_string(),
+ None => String::from("<unknown>"),
+ }
+ }
}
@@ -248,7 +273,19 @@ fn main_asm(args: Asm) {
// -----------------------------------------------------------------------
// GENERATE symbols file and bytecode
let bytecode = generate_bytecode(&mut semantic_tokens);
- // let symbols = generate_symbols_file(&semantic_tokens);
+
+ if args.symbols && !args.check {
+ if let Some(path) = &args.output {
+ let mut symbols_path = path.to_path_buf();
+ symbols_path.set_extension("br.sym");
+ let symbols = generate_symbols_file(&semantic_tokens);
+ if let Err(err) = std::fs::write(&symbols_path, symbols) {
+ verbose!("Could not write to symbols path {symbols_path:?}: ({err:?}).");
+ } else {
+ verbose!("Saved debug symbols to {symbols_path:?}");
+ }
+ }
+ }
let length = bytecode.len();
let percentage = (length as f32 / 65536.0 * 100.0).round() as u16;
@@ -361,6 +398,8 @@ xflags::xflags! {
optional --check
/// Only return resolved source code.
optional --resolve
+ /// Generate debug symbols with file extension '.br.sym'
+ optional --symbols
}
}
}