Vasm cli wrapper will now export a symbol table

This commit is contained in:
2023-01-07 02:09:27 -06:00
parent 3e6a33899a
commit 11f0760b01
5 changed files with 58 additions and 15 deletions
Generated
+24
View File
@@ -592,6 +592,12 @@ dependencies = [
"web-sys",
]
[[package]]
name = "itoa"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jni-sys"
version = "0.3.0"
@@ -1203,6 +1209,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "ryu"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "safe_arch"
version = "0.5.2"
@@ -1230,6 +1242,17 @@ version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
[[package]]
name = "serde_json"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha-1"
version = "0.8.2"
@@ -1386,6 +1409,7 @@ version = "0.1.0"
dependencies = [
"clap",
"regex",
"serde_json",
"vasm_core",
]
+1
View File
@@ -9,3 +9,4 @@ edition = "2021"
vasm_core = { path = "../vasm_core" }
clap = { version = "3.1.18", features = ["derive"] }
regex = "1.7.0"
serde_json = "1.0.91"
+21 -3
View File
@@ -1,8 +1,10 @@
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Write;
use clap::lazy_static::lazy_static;
use clap::Parser;
use regex::Regex;
use serde_json::json;
/// Vulcan Assembler
#[derive(Parser, Debug)]
@@ -12,6 +14,10 @@ struct Args {
#[clap(short, long)]
output: Option<String>,
/// Whether to generate a JSON file containing the symbol table
#[clap(short, long)]
symbols: bool,
/// Input file
#[clap()]
file: String,
@@ -51,10 +57,22 @@ fn main() {
args.deduce();
match vasm_core::assemble_file(args.file.as_str()) {
Ok(bytes) => {
//println!("We got some bytes... {} of them", bytes.len());
let mut outfile = File::create(args.output.unwrap()).expect("Failed to open output file");
Ok((bytes, scope)) => {
let mut outfile = File::create(args.output.as_ref().unwrap()).expect("Failed to open output file");
outfile.write(bytes.as_slice()).expect("Failed to write to output file");
if args.symbols {
let mut important_symbols : BTreeMap<String, i32> = BTreeMap::new();
for (sym, addr) in scope {
if !sym.starts_with("__gensym") {
important_symbols.insert(sym, addr);
}
}
let mut symfile = File::create(format!("{}.sym", args.output.unwrap())).expect("Failed to open symbol file");
let json = json!(important_symbols).to_string();
symfile.write(json.as_bytes()).expect("Failed to write to symbol file");
}
}
Err(error) => {
println!("{}", error)
+10 -10
View File
@@ -179,11 +179,11 @@ pub fn assemble_snippet<T: IntoIterator<Item = String>>(
})
.collect();
assemble_line_results(line_results)
assemble_line_results(line_results).map(|(bytes, _)| { bytes })
}
/// Assemble a file from the filesystem, opening other files as it includes them.
pub fn assemble_file(filename: &str) -> Result<Vec<u8>, AssembleError> {
pub fn assemble_file(filename: &str) -> Result<(Vec<u8>, Scope), AssembleError> {
let lines = lines_from_file(filename)?;
let line_results: Vec<Result<Line, AssembleError>> = LineSource::new(filename, lines, |file| {
lines_from_file(file.as_str())
@@ -195,7 +195,7 @@ pub fn assemble_file(filename: &str) -> Result<Vec<u8>, AssembleError> {
fn assemble_line_results(
mut line_results: Vec<Result<Line, AssembleError>>,
) -> Result<Vec<u8>, AssembleError> {
) -> Result<(Vec<u8>, Scope), AssembleError> {
if let Some(Err(error)) = line_results.iter().find(|line| line.is_err()) {
Err(error.clone())
} else {
@@ -224,7 +224,7 @@ fn lines_from_file(filename: &str) -> Result<Vec<String>, AssembleError> {
///
/// Vulcan is a little-endian architecture: multi-byte arguments / .dbs will store the
/// least-significant byte at the lowest address, then the more significant bytes following.
fn generate_code<T: IntoIterator<Item = Line>>(lines: T) -> Result<Vec<u8>, AssembleError> {
fn generate_code<T: IntoIterator<Item = Line>>(lines: T) -> Result<(Vec<u8>, Scope), AssembleError> {
let lines: Vec<Line> = lines.into_iter().collect();
let scope = solve_equs(&lines)?;
let line_lengths = measure_instructions(&lines, &scope);
@@ -276,7 +276,7 @@ fn generate_code<T: IntoIterator<Item = Line>>(lines: T) -> Result<Vec<u8>, Asse
}
}
Ok(code)
Ok((code, scope))
}
#[cfg(test)]
@@ -485,13 +485,13 @@ mod test {
#[test]
fn test_generate_code() {
assert_eq!(generate_code(parse(["add"])), Ok(vec![4]));
assert_eq!(generate_code(parse(["add"])).unwrap().0, vec![4]);
assert_eq!(
generate_code(parse([".org 0x400", "add 7"])),
Ok(vec![5, 7])
generate_code(parse([".org 0x400", "add 7"])).unwrap().0,
vec![5, 7]
);
assert_eq!(generate_code(parse([".db 57"])), Ok(vec![57, 0, 0]));
assert_eq!(generate_code(parse([".db \"AZ\0\""])), Ok(vec![65, 90, 0]));
assert_eq!(generate_code(parse([".db 57"])).unwrap().0, vec![57, 0, 0]);
assert_eq!(generate_code(parse([".db \"AZ\0\""])).unwrap().0, vec![65, 90, 0]);
}
#[test]
+1 -1
View File
@@ -1 +1 @@
{"$BRNZ":28,"$BRZ":27,"$CALL":25,"$JMP":23,"$JMPR":24,"$PUSH":0,"$RET":26,"$SWAP":20,"$end":4617,"$start":1024,"advance_entry":1141,"backslash":3276,"close_paren":3267,"close_paren_stub":3275,"compare":1414,"compile_dict_start":3429,"compile_dictionary":4222,"compile_handleword":3150,"compile_instruction":1537,"compile_instruction_arg":1511,"compile_tick":1196,"cr":1067,"cursor":4210,"data_start":3340,"dict_start":3588,"dictionary":4219,"does_at_runtime":2225,"does_word":2196,"dupnz":1074,"dupnz_done":1080,"emit":1025,"emit_cursor":1042,"emit_hook":4228,"end0_pop1":1093,"end0_pop2":1092,"end1_pop2":1096,"eval":1773,"eval_word_buffer":4487,"expected_word_err":3388,"find_in_dict":1149,"find_in_dict_next":1179,"find_word":2584,"handleword_hook":4198,"heap":4195,"heap_start":4618,"hex_is_number":1280,"hex_itoa":1701,"immediate_handleword":3113,"input_number":1595,"invalid_mnemonic":3293,"invalid_mnemonic_str":3353,"is_digit":1084,"is_number":1205,"is_number_hook":4201,"itoa":1618,"itoa_hook":4204,"itoa_loop":1648,"itoa_pos":1637,"itoa_print_loop":1685,"lambda_nesting_level":4216,"lambda_start_ptr":4213,"line_len":4207,"linecomment":3209,"missing_word":3301,"missing_word_str":3340,"mnemonics":2258,"mnemonics_end":2469,"new_dict":1451,"new_dict_error":1497,"nova_asm_to":2563,"nova_bracket_tick":2634,"nova_char":2689,"nova_close_brace":3049,"nova_close_bracket":1998,"nova_colon":2146,"nova_comma":2133,"nova_compile_dotquote":2877,"nova_compile_opcode":2555,"nova_compile_open_brace":3024,"nova_compile_squote":2810,"nova_continue":2007,"nova_create":1946,"nova_dec":2660,"nova_dotquote":2856,"nova_emit":3007,"nova_exit":2099,"nova_here":2579,"nova_hex":2672,"nova_immediate":2105,"nova_immediate_open_brace":3012,"nova_literal":2654,"nova_number":1932,"nova_opcode":2550,"nova_opcode_for_word":2469,"nova_open_bracket":1990,"nova_peekr":2961,"nova_popr":2994,"nova_postpone":2017,"nova_print_stack":2907,"nova_pushr":2981,"nova_quote_string_to":2715,"nova_resolve":1568,"nova_rpick":2969,"nova_safe_opcode":2529,"nova_semicolon":2154,"nova_squote":2780,"nova_tick":2613,"nova_word":1852,"nova_word_to":1902,"nova_word_to_pad":2164,"open_paren":3250,"pad":4231,"parencomment":3211,"parse_hex_digit":1326,"pos_is_number":1234,"pos_is_number_bad":1271,"pos_is_number_done":1276,"pos_is_number_loop":1236,"print":1045,"print_number":1613,"print_stack_end":3426,"print_stack_start":3422,"push_jump":1552,"quit":3317,"quit_vector":4225,"r_stack":4522,"r_stack_ptr":4519,"skip_nonword":1388,"skip_word":1371,"stop":1024,"tick":1187,"unclosed_error":3372,"word_char":1081,"wordeq":1100}
{"$BRNZ":28,"$BRZ":27,"$CALL":25,"$JMP":23,"$JMPR":24,"$PUSH":0,"$RET":26,"$SWAP":20,"advance_entry":1141,"backslash":3276,"close_paren":3267,"close_paren_stub":3275,"compare":1414,"compile_dict_start":3429,"compile_dictionary":4222,"compile_handleword":3150,"compile_instruction":1537,"compile_instruction_arg":1511,"compile_tick":1196,"cr":1067,"cursor":4210,"data_start":3340,"dict_start":3588,"dictionary":4219,"does_at_runtime":2225,"does_word":2196,"dupnz":1074,"dupnz_done":1080,"emit":1025,"emit_cursor":1042,"emit_hook":4228,"end0_pop1":1093,"end0_pop2":1092,"end1_pop2":1096,"eval":1773,"eval_word_buffer":4487,"expected_word_err":3388,"find_in_dict":1149,"find_in_dict_next":1179,"find_word":2584,"handleword_hook":4198,"heap":4195,"heap_start":4618,"hex_is_number":1280,"hex_itoa":1701,"immediate_handleword":3113,"input_number":1595,"invalid_mnemonic":3293,"invalid_mnemonic_str":3353,"is_digit":1084,"is_number":1205,"is_number_hook":4201,"itoa":1618,"itoa_hook":4204,"itoa_loop":1648,"itoa_pos":1637,"itoa_print_loop":1685,"lambda_nesting_level":4216,"lambda_start_ptr":4213,"line_len":4207,"linecomment":3209,"missing_word":3301,"missing_word_str":3340,"mnemonics":2258,"mnemonics_end":2469,"new_dict":1451,"new_dict_error":1497,"nova_asm_to":2563,"nova_bracket_tick":2634,"nova_char":2689,"nova_close_brace":3049,"nova_close_bracket":1998,"nova_colon":2146,"nova_comma":2133,"nova_compile_dotquote":2877,"nova_compile_opcode":2555,"nova_compile_open_brace":3024,"nova_compile_squote":2810,"nova_continue":2007,"nova_create":1946,"nova_dec":2660,"nova_dotquote":2856,"nova_emit":3007,"nova_exit":2099,"nova_here":2579,"nova_hex":2672,"nova_immediate":2105,"nova_immediate_open_brace":3012,"nova_literal":2654,"nova_number":1932,"nova_opcode":2550,"nova_opcode_for_word":2469,"nova_open_bracket":1990,"nova_peekr":2961,"nova_popr":2994,"nova_postpone":2017,"nova_print_stack":2907,"nova_pushr":2981,"nova_quote_string_to":2715,"nova_resolve":1568,"nova_rpick":2969,"nova_safe_opcode":2529,"nova_semicolon":2154,"nova_squote":2780,"nova_tick":2613,"nova_word":1852,"nova_word_to":1902,"nova_word_to_pad":2164,"open_paren":3250,"pad":4231,"parencomment":3211,"parse_hex_digit":1326,"pos_is_number":1234,"pos_is_number_bad":1271,"pos_is_number_done":1276,"pos_is_number_loop":1236,"print":1045,"print_number":1613,"print_stack_end":3426,"print_stack_start":3422,"push_jump":1552,"quit":3317,"quit_vector":4225,"r_stack":4522,"r_stack_ptr":4519,"skip_nonword":1388,"skip_word":1371,"stop":1024,"tick":1187,"unclosed_error":3372,"word_char":1081,"wordeq":1100}