Skip to content

Commit

Permalink
fix #16: implement symbol output
Browse files Browse the repository at this point in the history
  • Loading branch information
hlorenzi committed Oct 3, 2019
1 parent 1557a05 commit 918c186
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "customasm"
version = "0.10.1"
version = "0.10.2"
edition = "2018"
authors = ["Henrique Lorenzi <[email protected]>"]

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Options:
decc, hexc, logisim8, logisim16
-o, --output FILE The name of the output file.
-s, --symbol FILE The name of the output symbol file.
-p, --print Print output to stdout instead of writing to a file.
-q, --quiet Suppress progress reports.
-v, --version Display version information.
Expand Down
37 changes: 37 additions & 0 deletions src/asm/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,43 @@ impl AssemblerState

output
}


pub fn get_symbol_output(&self) -> String
{
let mut result = String::new();

for global_label in &self.labels.name_to_index_map
{
let global_value = &self.labels.global_labels[*global_label.1];

if global_label.0 != ""
{
match global_value.value
{
ExpressionValue::Integer(ref integer) =>
{
result.push_str(&format!("{} = {:#x}\n", global_label.0, integer));
}
_ => {}
}
}

for local_label in &global_value.local_labels
{
match local_label.1
{
ExpressionValue::Integer(ref integer) =>
{
result.push_str(&format!("{}{} = {:#x}\n", global_label.0, local_label.0, integer));
}
_ => {}
}
}
}

result
}
}


Expand Down
8 changes: 4 additions & 4 deletions src/asm/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::collections::HashMap;

pub struct LabelManager
{
global_labels: Vec<GlobalLabel>,
name_to_index_map: HashMap<String, usize>
pub global_labels: Vec<GlobalLabel>,
pub name_to_index_map: HashMap<String, usize>
}


Expand All @@ -16,8 +16,8 @@ pub type LabelContext = usize;

pub struct GlobalLabel
{
value: ExpressionValue,
local_labels: HashMap<String, ExpressionValue>
pub value: ExpressionValue,
pub local_labels: HashMap<String, ExpressionValue>
}


Expand Down
97 changes: 65 additions & 32 deletions src/driver.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::diagn::RcReport;
use crate::util::FileServer;
use crate::util::enable_windows_ansi_support;
use crate::asm::BinaryBlock;
use crate::asm::AssemblerState;
use std::io::stdout;
use getopts;
Expand Down Expand Up @@ -63,7 +62,7 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec<String>, fi

if matches.opt_present("v")
{
print_version();
print_info();
return Ok(());
}

Expand Down Expand Up @@ -108,44 +107,54 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec<String>, fi

let main_asm_file = matches.free[0].clone();

let output_symbol_requested = matches.opt_present("s");
let output_requested = matches.opt_present("o");

let output_symbol_file = matches.opt_str("s");
let output_file = match matches.opt_str("o")
{
Some(f) => f,
Some(f) => Some(f),
None =>
{
match get_default_output_filename(report.clone(), &main_asm_file)
if output_symbol_requested || output_symbol_file.is_some()
{ None }
else
{
Ok(f) => f,
Err(_) => return Err(true)
match get_default_output_filename(report.clone(), &main_asm_file)
{
Ok(f) => Some(f),
Err(_) => None,
}
}
}
};

let mut filenames = matches.opt_strs("i");
for filename in matches.free
{ filenames.push(filename); }

let assembled = assemble(report.clone(), fileserver, &filenames, quiet).map_err(|_| false)?;

let output = assembled.get_binary_output();
let output_symbol_data = assembled.get_symbol_output();
let output_data = match out_format
{
OutputFormat::Binary => assembled.generate_binary(0, assembled.len()),
OutputFormat::Binary => output.generate_binary(0, output.len()),

OutputFormat::BinStr => assembled.generate_binstr (0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::BinDump => assembled.generate_bindump (0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::HexStr => assembled.generate_hexstr (0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::HexDump => assembled.generate_hexdump (0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::Mif => assembled.generate_mif (0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::IntelHex => assembled.generate_intelhex(0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::DecComma => assembled.generate_comma (0, assembled.len(), 10).bytes().collect::<Vec<u8>>(),
OutputFormat::HexComma => assembled.generate_comma (0, assembled.len(), 16).bytes().collect::<Vec<u8>>(),
OutputFormat::DecC => assembled.generate_c_array (0, assembled.len(), 10).bytes().collect::<Vec<u8>>(),
OutputFormat::HexC => assembled.generate_c_array (0, assembled.len(), 16).bytes().collect::<Vec<u8>>(),
OutputFormat::LogiSim8 => assembled.generate_logisim (0, assembled.len(), 8).bytes().collect::<Vec<u8>>(),
OutputFormat::LogiSim16 => assembled.generate_logisim (0, assembled.len(), 16).bytes().collect::<Vec<u8>>(),
OutputFormat::BinStr => output.generate_binstr (0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::BinDump => output.generate_bindump (0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::HexStr => output.generate_hexstr (0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::HexDump => output.generate_hexdump (0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::Mif => output.generate_mif (0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::IntelHex => output.generate_intelhex(0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::DecComma => output.generate_comma (0, output.len(), 10).bytes().collect::<Vec<u8>>(),
OutputFormat::HexComma => output.generate_comma (0, output.len(), 16).bytes().collect::<Vec<u8>>(),
OutputFormat::DecC => output.generate_c_array (0, output.len(), 10).bytes().collect::<Vec<u8>>(),
OutputFormat::HexC => output.generate_c_array (0, output.len(), 16).bytes().collect::<Vec<u8>>(),
OutputFormat::LogiSim8 => output.generate_logisim (0, output.len(), 8).bytes().collect::<Vec<u8>>(),
OutputFormat::LogiSim16 => output.generate_logisim (0, output.len(), 16).bytes().collect::<Vec<u8>>(),

OutputFormat::AnnotatedHex => assembled.generate_annotated_hex(fileserver, 0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::AnnotatedBin => assembled.generate_annotated_bin(fileserver, 0, assembled.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::AnnotatedHex => output.generate_annotated_hex(fileserver, 0, output.len()).bytes().collect::<Vec<u8>>(),
OutputFormat::AnnotatedBin => output.generate_annotated_bin(fileserver, 0, output.len()).bytes().collect::<Vec<u8>>(),
};

if out_stdout
Expand All @@ -155,14 +164,34 @@ fn drive_inner(report: RcReport, opts: &getopts::Options, args: &Vec<String>, fi
println!("success");
println!("");
}

if output_requested || output_file.is_some()
{ println!("{}", String::from_utf8_lossy(&output_data)); }

println!("{}", String::from_utf8_lossy(&output_data));
if output_symbol_requested || output_symbol_file.is_some()
{ println!("{}", &output_symbol_data); }
}
else
{
println!("writing `{}`...", &output_file);
fileserver.write_bytes(report.clone(), &output_file, &output_data, None).map_err(|_| false)?;

let mut any_files_written = false;

if let Some(ref output_file) = output_file
{
println!("writing `{}`...", &output_file);
fileserver.write_bytes(report.clone(), &output_file, &output_data, None).map_err(|_| false)?;
any_files_written = true;
}

if let Some(ref output_symbol_file) = output_symbol_file
{
println!("writing `{}`...", &output_symbol_file);
fileserver.write_bytes(report.clone(), &output_symbol_file, &output_symbol_data.bytes().collect::<Vec<u8>>(), None).map_err(|_| false)?;
any_files_written = true;
}

if !any_files_written
{ println!("no files written"); }

if !quiet
{ println!("success"); }
}
Expand All @@ -176,7 +205,8 @@ fn make_opts() -> getopts::Options
let mut opts = getopts::Options::new();
opts.optopt("f", "format", "The format of the output file. Possible formats: binary, annotated, annotatedbin, binstr, hexstr, bindump, hexdump, mif, intelhex, deccomma, hexcomma, decc, hexc, logisim8, logisim16", "FORMAT");
opts.optmulti("i", "include", "Specifies an additional file for processing before the given <asm-files>. [deprecated]", "FILE");
opts.optopt("o", "output", "The name of the output file.", "FILE");
opts.opt("o", "output", "The name of the output file.", "FILE", getopts::HasArg::Maybe, getopts::Occur::Optional);
opts.opt("s", "symbol", "The name of the output symbol file.", "FILE", getopts::HasArg::Maybe, getopts::Occur::Optional);
opts.optflag("p", "print", "Print output to stdout instead of writing to a file.");
opts.optflag("q", "quiet", "Suppress progress reports.");
opts.optflag("v", "version", "Display version information.");
Expand All @@ -198,6 +228,8 @@ fn parse_opts(report: RcReport, opts: &getopts::Options, args: &Vec<String>) ->

fn print_usage(opts: &getopts::Options)
{
print_info();
println!("");
println!("{}", opts.usage(&format!("Usage: {} [options] <asm-file-1> ... <asm-file-N>", env!("CARGO_PKG_NAME"))));
}

Expand All @@ -208,9 +240,10 @@ fn print_version()
}


fn print_header()
fn print_info()
{
print_version();
println!("https://github.com/hlorenzi/customasm");
}


Expand All @@ -230,10 +263,10 @@ fn get_default_output_filename(report: RcReport, input_filename: &str) -> Result
}


pub fn assemble(report: RcReport, fileserver: &dyn FileServer, filenames: &[String], quiet: bool) -> Result<BinaryBlock, ()>
pub fn assemble(report: RcReport, fileserver: &dyn FileServer, filenames: &[String], quiet: bool) -> Result<AssemblerState, ()>
{
if !quiet
{ print_header(); }
{ print_version(); }

let mut asm = AssemblerState::new();

Expand All @@ -248,5 +281,5 @@ pub fn assemble(report: RcReport, fileserver: &dyn FileServer, filenames: &[Stri
}

asm.wrapup(report)?;
Ok(asm.get_binary_output())
Ok(asm)
}
Binary file modified web/customasm.gc.wasm
Binary file not shown.

0 comments on commit 918c186

Please sign in to comment.