aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2026-10-06 17:33:16 +0200
committerMiquel Sabaté Solà <mssola@mssola.com>2026-10-06 17:33:16 +0200
commite71a73d0875c416507a3207bdec6fee145a79f68 (patch)
tree23bb734234b1e78d59333ef39f6a24937fae8c25
parent4bf12db91feb5db98d65b518dbad0c1a8c6748df (diff)
downloadtools.nes-e71a73d0875c416507a3207bdec6fee145a79f68.tar.gz
tools.nes-e71a73d0875c416507a3207bdec6fee145a79f68.zip
Don't error out on conditional .include
The hard requirement that an .include statement cannot be inside of another block was, in the end, a bit short-sighted. Imagine the following block: .ifdef DEBUG .include "debug.s" .endif This is perfectly sound-looking code, and it should not be punished as the developer is doing something that is not bending the assembler in weird ways. Hence, just nuke this check. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
-rw-r--r--lib/xixanta/src/parser.rs27
-rwxr-xr-xscripts/test-e2e.sh15
-rw-r--r--tests/code_to_include.s5
-rw-r--r--tests/conditionally_include.s16
-rw-r--r--tests/expected/conditionally_include.nesbin0 -> 17 bytes
-rw-r--r--tests/expected/conditionally_include.txt0
-rw-r--r--tests/expected/conditionally_include_debug.nesbin0 -> 20 bytes
-rw-r--r--tests/expected/conditionally_include_debug.txt0
8 files changed, 36 insertions, 27 deletions
diff --git a/lib/xixanta/src/parser.rs b/lib/xixanta/src/parser.rs
index a71c6f6..07d028c 100644
--- a/lib/xixanta/src/parser.rs
+++ b/lib/xixanta/src/parser.rs
@@ -1040,33 +1040,6 @@ impl Parser {
&node.node_type,
NodeType::Control(ControlType::IncludeSource)
) {
- // Validate that it's a top layer statement.
- if self.nodes.len() > 1 {
- // This is not a top layer statement! Usually it would be a
- // cause for trouble, but we actually allow this in case this is
- // all just a bunch of `.scope` statements surrounding
- // things. NOTE: the iteration has to go over all top nodes
- // except the last one which is the current one.
- let nodes = &self.nodes[..self.nodes.len() - 1];
- if nodes.iter().any(|n| {
- !matches!(
- n.last().unwrap().node_type,
- NodeType::Control(ControlType::StartScope)
- )
- }) {
- // There is something else besides a '.scope' statement,
- // this is just asking for trouble...
- return Err(Error {
- line: node.value.line,
- global: false,
- message: ".include statement cannot be inside of a code block".to_string(),
- expanded_from: vec![],
- source: self.sources[self.current_source].clone(),
- }
- .into());
- }
- }
-
// Before including all the nodes from the referenced file, add the
// .include statement. This should be ignored by the assembler, but
// maybe other tools want to make use of it.
diff --git a/scripts/test-e2e.sh b/scripts/test-e2e.sh
index 21c4c7f..0cf37f0 100755
--- a/scripts/test-e2e.sh
+++ b/scripts/test-e2e.sh
@@ -154,6 +154,21 @@ exit_code=$((exit_code + $?))
diff tests/out/out.nes tests/expected/out.nes
exit_code=$((exit_code + $?))
+echo "test: custom => conditionally_include.nes"
+# No DEBUG
+./target/debug/nasm -c empty -Werror --asan -o tests/out/conditionally_include.nes tests/conditionally_include.s 2> tests/out/conditionally_include.txt
+diff tests/out/conditionally_include.txt tests/expected/conditionally_include.txt
+exit_code=$((exit_code + $?))
+diff tests/out/conditionally_include.nes tests/expected/conditionally_include.nes
+exit_code=$((exit_code + $?))
+
+# With DEBUG
+./target/debug/nasm -c empty -Werror --asan -o tests/out/conditionally_include_debug.nes -D DEBUG=1 tests/conditionally_include.s 2> tests/out/conditionally_include_debug.txt
+diff tests/out/conditionally_include_debug.txt tests/expected/conditionally_include_debug.txt
+exit_code=$((exit_code + $?))
+diff tests/out/conditionally_include_debug.nes tests/expected/conditionally_include_debug.nes
+exit_code=$((exit_code + $?))
+
##
# code.nes
diff --git a/tests/code_to_include.s b/tests/code_to_include.s
new file mode 100644
index 0000000..4f315dc
--- /dev/null
+++ b/tests/code_to_include.s
@@ -0,0 +1,5 @@
+.segment "CODE"
+
+.proc foo
+ rts
+.endproc
diff --git a/tests/conditionally_include.s b/tests/conditionally_include.s
new file mode 100644
index 0000000..67ef7d2
--- /dev/null
+++ b/tests/conditionally_include.s
@@ -0,0 +1,16 @@
+.segment "HEADER"
+ .byte 'N', 'E', 'S', $1A
+ .byte $02, $01
+ .byte $00
+ .byte $00
+
+.segment "CODE"
+
+;;; asan:stack full
+
+.ifdef DEBUG
+ .include "code_to_include.s"
+ jsr foo
+.else
+ nop
+.endif
diff --git a/tests/expected/conditionally_include.nes b/tests/expected/conditionally_include.nes
new file mode 100644
index 0000000..a76a79b
--- /dev/null
+++ b/tests/expected/conditionally_include.nes
Binary files differ
diff --git a/tests/expected/conditionally_include.txt b/tests/expected/conditionally_include.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/expected/conditionally_include.txt
diff --git a/tests/expected/conditionally_include_debug.nes b/tests/expected/conditionally_include_debug.nes
new file mode 100644
index 0000000..d7b8ac5
--- /dev/null
+++ b/tests/expected/conditionally_include_debug.nes
Binary files differ
diff --git a/tests/expected/conditionally_include_debug.txt b/tests/expected/conditionally_include_debug.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/expected/conditionally_include_debug.txt