Skip to content

Commit

Permalink
add the #const directive and the noemit attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
hlorenzi committed Jun 4, 2023
1 parent 9ed6549 commit e48fe8d
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/asm/defs/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub fn define(

let symbol = asm::Symbol {
item_ref,
no_emit: true,
value_statically_known: true,
value: expr::Value::Function(fn_ref.0),
resolved: true,
Expand Down
2 changes: 2 additions & 0 deletions src/asm/defs/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::*;
pub struct Symbol
{
pub item_ref: util::ItemRef<Self>,
pub no_emit: bool,
pub value_statically_known: bool,
pub value: expr::Value,
pub resolved: bool,
Expand Down Expand Up @@ -42,6 +43,7 @@ pub fn define(

let symbol = Symbol {
item_ref,
no_emit: node.no_emit,
value_statically_known,
value: expr::Value::Unknown,
resolved: false,
Expand Down
3 changes: 3 additions & 0 deletions src/asm/parser/directive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub fn parse(
"bits" => Ok(asm::AstAny::DirectiveBits(
asm::parser::directive_bits::parse(report, walker, header_span)?)),

"const" => Ok(asm::AstAny::Symbol(
asm::parser::directive_const::parse(report, walker, header_span)?)),

"fn" => Ok(asm::AstAny::DirectiveFn(
asm::parser::directive_fn::parse(report, walker, header_span)?)),

Expand Down
64 changes: 64 additions & 0 deletions src/asm/parser/directive_const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use super::*;


pub fn parse(
report: &mut diagn::Report,
walker: &mut syntax::TokenWalker,
_header_span: diagn::Span)
-> Result<AstSymbol, ()>
{
let mut no_emit = false;

if let Some(_) = walker.maybe_expect(syntax::TokenKind::ParenOpen)
{
let tk_attrb = walker.expect(report, syntax::TokenKind::Identifier)?;
let attrb = tk_attrb.excerpt.as_ref().unwrap();

match attrb.as_ref()
{
"noemit" => no_emit = true,
_ =>
{
report.error_span(
format!("invalid attribute `{}`", attrb),
tk_attrb.span);

return Err(());
}
}

walker.expect(report, syntax::TokenKind::ParenClose)?;
}


let mut decl_span = diagn::Span::new_dummy();
let mut hierarchy_level = 0;

while let Some(tk_dot) = walker.maybe_expect(syntax::TokenKind::Dot)
{
hierarchy_level += 1;
decl_span = decl_span.join(tk_dot.span);
}

let tk_name = walker.expect(report, syntax::TokenKind::Identifier)?;
let name = tk_name.excerpt.clone().unwrap();
decl_span = decl_span.join(tk_name.span);


walker.expect(report, syntax::TokenKind::Equal)?;

let expr = expr::parse(report, walker)?;
walker.expect_linebreak(report)?;

Ok(AstSymbol {
decl_span,
hierarchy_level,
name,
kind: AstSymbolKind::Constant(AstSymbolConstant {
expr,
}),
no_emit,

item_ref: None,
})
}
31 changes: 6 additions & 25 deletions src/asm/parser/directive_noemit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,13 @@ pub struct AstDirectiveNoEmit

pub fn parse(
report: &mut diagn::Report,
walker: &mut syntax::TokenWalker,
_walker: &mut syntax::TokenWalker,
header_span: diagn::Span)
-> Result<AstDirectiveNoEmit, ()>
{
let tk_status = walker.expect(report, syntax::TokenKind::Identifier)?;
let status = tk_status.excerpt.as_ref().unwrap().to_ascii_lowercase();

walker.expect_linebreak(report)?;

let status = match status.as_ref()
{
"on" => true,
"off" => false,
_ =>
{
report.error_span(
"unknown noemit state",
tk_status.span,
);

return Err(());
}
};

Ok(AstDirectiveNoEmit {
header_span,
status,
})
report.error_span(
"`#noemit` is deprecated; use `#const(noemit)` at each constant declaration",
header_span);

Err(())
}
2 changes: 2 additions & 0 deletions src/asm/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub use directive_bits::{
AstDirectiveBits,
};

mod directive_const;

mod directive_data;
pub use directive_data::{
AstDirectiveData,
Expand Down
3 changes: 3 additions & 0 deletions src/asm/parser/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct AstSymbol
pub hierarchy_level: usize,
pub name: String,
pub kind: AstSymbolKind,
pub no_emit: bool,

pub item_ref: Option<util::ItemRef::<asm::Symbol>>,
}
Expand Down Expand Up @@ -59,6 +60,7 @@ pub fn parse(
kind: AstSymbolKind::Constant(AstSymbolConstant {
expr,
}),
no_emit: false,

item_ref: None,
}))
Expand All @@ -73,6 +75,7 @@ pub fn parse(
hierarchy_level,
name,
kind: AstSymbolKind::Label,
no_emit: false,

item_ref: None,
}))
Expand Down
26 changes: 14 additions & 12 deletions src/util/symbol_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,29 +126,31 @@ impl util::SymbolManager<asm::Symbol>
hierarchy.push(child_name.clone());


// TODO: Respect the #noemit directive
let symbol_decl = self.get(*child_ref);
let symbol = defs.symbols.get(symbol_decl.item_ref);

match symbol.value
if !symbol.no_emit
{
expr::Value::Integer(ref bigint) =>
match symbol.value
{
let mut name = String::new();

for i in 0..hierarchy.len()
expr::Value::Integer(ref bigint) =>
{
if i > 0
let mut name = String::new();

for i in 0..hierarchy.len()
{
name.push_str(".");
if i > 0
{
name.push_str(".");
}

name.push_str(&format!("{}", hierarchy[i]));
}

name.push_str(&format!("{}", hierarchy[i]));
formatter(result, symbol_decl, &name, &bigint);
}

formatter(result, symbol_decl, &name, &bigint);
_ => {}
}
_ => {}
}


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

#fn add1(x) => x + 1

start:
x1 = add1(0x10)
ld x1

#const x2 = 0x11
ld x2

#const(noemit) x3 = 0x11
ld x3

loop:
#const y1 = 0x22
ld y1

#const y2 = 0x22
ld y2

#const(noemit) y3 = 0x22
ld y3

.inner:
.z1 = 0x33
ld .z1

#const .z2 = 0x33
ld .z2

#const(noemit) .z3 = 0x33
ld .z3

; command: main.asm -f symbols -o out.txt
; output: out.txt
9 changes: 9 additions & 0 deletions tests/driver/ok_format_symbol_noemit/out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
start = 0x0
x1 = 0x11
x2 = 0x11
loop = 0x6
y1 = 0x22
y2 = 0x22
y3.inner = 0xc
y3.z1 = 0x33
y3.z2 = 0x33
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ruledef test
{
ld {x} => 0x55 @ x`8
}


#const(invalid) val = 0xaa ; error: invalid attribute
ld val
8 changes: 8 additions & 0 deletions tests/symbol_constant_simple/ok_literal_const.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ruledef test
{
ld {x} => 0x55 @ x`8
}


#const val = 0xaa
ld val ; = 0x55aa
8 changes: 8 additions & 0 deletions tests/symbol_constant_simple/ok_literal_const_noemit.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ruledef test
{
ld {x} => 0x55 @ x`8
}


#const(noemit) val = 0xaa
ld val ; = 0x55aa
11 changes: 11 additions & 0 deletions tests/symbol_constant_simple/ok_nested.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ruledef test
{
ld {x}, {y}, {z} => 0x55 @ x`8 @ y`8 @ z`8
}


x = 0x11
.y = 0x22
..z = 0x33
ld x, .y, ..z ; = 0x55112233
ld x, x.y, x.y.z ; = 0x55112233
11 changes: 11 additions & 0 deletions tests/symbol_constant_simple/ok_nested_const.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ruledef test
{
ld {x}, {y}, {z} => 0x55 @ x`8 @ y`8 @ z`8
}


#const x = 0x11
#const .y = 0x22
#const ..z = 0x33
ld x, .y, ..z ; = 0x55112233
ld x, x.y, x.y.z ; = 0x55112233

0 comments on commit e48fe8d

Please sign in to comment.