Skip to content

Commit

Permalink
add command-line defines
Browse files Browse the repository at this point in the history
  • Loading branch information
hlorenzi committed Jun 19, 2023
1 parent 5759ed6 commit f3247a0
Show file tree
Hide file tree
Showing 38 changed files with 360 additions and 12 deletions.
54 changes: 54 additions & 0 deletions src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ pub struct AssemblyOptions
pub debug_iterations: bool,
pub optimize_statically_known: bool,
pub optimize_instruction_matching: bool,

pub driver_symbol_defs: Vec<DriverSymbolDef>,
}


pub struct DriverSymbolDef
{
pub name: String,
pub value: expr::Value,
}


Expand Down Expand Up @@ -123,6 +132,8 @@ impl AssemblyOptions
debug_iterations: false,
optimize_statically_known: true,
optimize_instruction_matching: true,

driver_symbol_defs: Vec::new(),
}
}
}
Expand Down Expand Up @@ -230,6 +241,11 @@ pub fn assemble<S>(
assembly.decls.as_ref().unwrap(),
assembly.defs.as_ref().unwrap())?);

check_unused_defines(
report,
opts,
assembly.decls.as_ref().unwrap())?;

Ok(())
};

Expand All @@ -244,4 +260,42 @@ pub fn assemble<S>(
}

assembly
}


fn check_unused_defines(
report: &mut diagn::Report,
opts: &asm::AssemblyOptions,
decls: &asm::ItemDecls)
-> Result<(), ()>
{
let mut had_error = false;

for symbol_def in &opts.driver_symbol_defs
{
let hierarchy = symbol_def.name
.split(".")
.collect::<Vec<_>>();

let maybe_decl = decls.symbols.try_get_by_name(
&util::SymbolContext::new_global(),
0,
&hierarchy);

if let None = maybe_decl
{
report.error(
format!(
"unused define `{}`",
symbol_def.name));

had_error = true;
}
}

match had_error
{
false => Ok(()),
true => Err(()),
}
}
14 changes: 14 additions & 0 deletions src/asm/resolver/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ fn resolve_constant_simple(
let asm::AstSymbolKind::Constant(ref ast_const) = ast_symbol.kind
else { unreachable!() };


// Overwrite with a value from the command-line, if present
let symbol_decl = decls.symbols.get(item_ref);
if let Some(driver_def) = opts.driver_symbol_defs
.iter()
.find(|s| s.name == symbol_decl.name)
{
let symbol = defs.symbols.get_mut(item_ref);
symbol.value = driver_def.value.clone();
symbol.resolved = true;
return Ok(asm::ResolutionState::Resolved);
}


let value = asm::resolver::eval_simple(
report,
decls,
Expand Down
94 changes: 94 additions & 0 deletions src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@ fn make_opts() -> getopts::Options
"q", "quiet",
"Suppress progress reports.");

opts.opt(
"d", "define",
"Defines a constant.",
"VALUE",
getopts::HasArg::Yes,
getopts::Occur::Multi);

opts.opt(
"", "color",
"Style the output with colors. [on/off]",
Expand Down Expand Up @@ -337,6 +344,14 @@ fn parse_command(
command.show_version |= parsed.opt_present("v");
command.show_help |= parsed.opt_present("h");

for define_arg in parsed.opt_strs("d")
{
command.opts.driver_symbol_defs.push(
parse_define_arg(
report,
&define_arg)?);
}

command.opts.debug_iterations |=
parsed.opt_present("debug-iters");

Expand Down Expand Up @@ -619,6 +634,85 @@ pub fn parse_output_format(
}


fn parse_define_arg(
report: &mut diagn::Report,
raw_str: &str)
-> Result<asm::DriverSymbolDef, ()>
{
let split = raw_str
.split('=')
.collect::<Vec<_>>();

let name = split[0].to_string();

if split.len() == 1
{
return Ok(asm::DriverSymbolDef {
name,
value: expr::Value::make_bool(true),
});
}

if split.len() != 2
{
report.error(
format!(
"invalid define argument `{}`",
raw_str));

return Err(());
}

let value_str = split[1];

let value = {
if value_str == "true"
{
expr::Value::make_bool(true)
}
else if value_str == "false"
{
expr::Value::make_bool(false)
}
else
{
let has_negative_sign = split[1].chars().next() == Some('-');

let maybe_value = syntax::excerpt_as_bigint(
None,
diagn::Span::new_dummy(),
if has_negative_sign { split[1].get(1..).unwrap() } else { split[1] });


use std::ops::Neg;

match maybe_value
{
Ok(value) =>
expr::Value::make_integer(
if has_negative_sign { value.neg() } else { value }),

Err(()) =>
{
report.error(
format!(
"invalid value for define `{}`",
name));

return Err(());
}
}
}
};


Ok(asm::DriverSymbolDef {
name,
value,
})
}


pub fn format_output(
fileserver: &dyn util::FileServer,
decls: &asm::ItemDecls,
Expand Down
6 changes: 6 additions & 0 deletions src/expr/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ impl Value
}


pub fn make_bool(value: bool) -> Value
{
Value::Bool(value)
}


pub fn make_string<T: Into<String>, S: Into<String>>(value: T, encoding: S) -> Value
{
Value::String(ExprString
Expand Down
2 changes: 1 addition & 1 deletion src/expr/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ impl<'a, 'tokens> ExpressionParser<'a, 'tokens>
let number = tk_number.excerpt.clone().unwrap();

let bigint = syntax::excerpt_as_bigint(
self.report,
Some(self.report),
tk_number.span,
&number)?;

Expand Down
20 changes: 13 additions & 7 deletions src/syntax/excerpt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ pub fn excerpt_as_usize(


pub fn excerpt_as_bigint(
report: &mut diagn::Report,
report: Option<&mut diagn::Report>,
span: diagn::Span,
excerpt: &str)
-> Result<util::BigInt, ()>
Expand All @@ -195,9 +195,12 @@ pub fn excerpt_as_bigint(
Some(d) => d,
None =>
{
report.error_span(
"invalid digits",
span);
if let Some(report) = report
{
report.error_span(
"invalid digits",
span);
}

return Err(());
}
Expand All @@ -211,9 +214,12 @@ pub fn excerpt_as_bigint(

if digit_num == 0
{
report.error_span(
"invalid value",
span);
if let Some(report) = report
{
report.error_span(
"invalid value",
span);
}

return Err(());
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub fn extract_expectations(
{
let value =
syntax::excerpt_as_bigint(
&mut diagn::Report::new(),
None,
diagn::Span::new_dummy(),
value_str)
.unwrap();
Expand Down
12 changes: 9 additions & 3 deletions src/usage_help.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,15 @@ Examples:
* `-h, --help`
Display this information.
* `-t, --iters=NUM`
The max number of resolution iterations to attempt. (Default: 10)
The maximum number of resolution iterations to attempt.
(Default: 10)
* `-dNAME, --define=NAME`
* `-dNAME=VALUE, --define=NAME=VALUE`
Overwrites a constant definition with the given value,
or `true` if none is given.
* `--color=on/off`
Whether to style the output with colors. (Default: on)
Whether to style the output with colors.
(Default: on)
* `--debug-iters`
Print debug info during resolution iterations.
* `--debug-no-optimize-static`
Expand Down Expand Up @@ -54,7 +60,7 @@ Examples:
* `binary`

* `annotated,base:16,group:2`
Annotate the output data with snippets
Annotates the output data with snippets
of the source code.

* `annotatedbin`
Expand Down
10 changes: 10 additions & 0 deletions tests/driver/err_define_invalid/main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ruledef test
{
ld {x: u8} => 0x55 @ x
}

val = 0
ld val

; command: main.asm -o out.bin -dval=abc=123
; error: invalid define argument `val=abc=123`
10 changes: 10 additions & 0 deletions tests/driver/err_define_invalid_name/main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ruledef test
{
ld {x: u8} => 0x55 @ x
}

val = 0
ld val

; command: main.asm -o out.bin -d123=123
; error: unused define `123`
10 changes: 10 additions & 0 deletions tests/driver/err_define_invalid_value/main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ruledef test
{
ld {x: u8} => 0x55 @ x
}

val = 0
ld val

; command: main.asm -o out.bin -dval=abc
; error: invalid value for define `val`
8 changes: 8 additions & 0 deletions tests/driver/err_define_no_declaration/main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ruledef test
{
ld {x: u8} => 0x55 @ x
}

ld val ; error: failed / note:_:3: within / error: unknown symbol `val`

; command: main.asm -o out.bin -dval
10 changes: 10 additions & 0 deletions tests/driver/err_define_unused/main.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ruledef test
{
ld {x: u8} => 0x55 @ x
}

val = 0
ld val

; command: main.asm -o out.bin -dvalue=0x55
; error: unused define `value`
3 changes: 3 additions & 0 deletions tests/driver/ok_define_if1/err_no_define.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "include.asm" ; error:include.asm:5: invalid argument types

; command: err_no_define.asm -o out.bin
18 changes: 18 additions & 0 deletions tests/driver/ok_define_if1/include.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#d 0xaa

variant = {}

#if variant == 0
{
#d 0x00
}
#elif variant == 1
{
#d 0x11
}
#elif variant == 2
{
#d 0x22
}

#d 0xff
Loading

0 comments on commit f3247a0

Please sign in to comment.