Skip to content

Commit

Permalink
else-if
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Feb 10, 2025
1 parent 01378f1 commit 8d4a376
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 30 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added

- Added a version checker that prints a warn message if not using latest esp-generate version (#87)
- After generating the project the tool now checks the rust version, espflash version and probe-rs version (#88)

- Be more helpful in case of common linker errors (#94)
- Support for `ELIF` conditions (#96)

### Changed
- Update `probe-rs run` arguments (#90)
Expand Down
117 changes: 109 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,42 @@ fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}

#[derive(Clone, Copy)]
enum BlockKind {
// All lines are included
Root,

// (current branch to be included, any previous branches included)
IfElse(bool, bool),
}

impl BlockKind {
fn include_line(self) -> bool {
match self {
BlockKind::Root => true,
BlockKind::IfElse(current, any) => current && !any,
}
}

fn new_if(current: bool) -> BlockKind {
BlockKind::IfElse(current, false)
}

fn into_else_if(self, condition: bool) -> BlockKind {
let BlockKind::IfElse(previous, any) = self else {
panic!("ELIF without IF");
};
BlockKind::IfElse(condition, any || previous)
}

fn into_else(self) -> BlockKind {
let BlockKind::IfElse(previous, any) = self else {
panic!("ELSE without IF");
};
BlockKind::IfElse(!any, any || previous)
}
}

fn process_file(
contents: &str, // Raw content of the file
options: &[String], // Selected options
Expand All @@ -391,7 +427,7 @@ fn process_file(
let mut res = String::new();

let mut replace: Option<Vec<(String, String)>> = None;
let mut include = vec![true];
let mut include = vec![BlockKind::Root];
let mut first_line = true;

// Create a new Rhai engine and scope
Expand Down Expand Up @@ -489,16 +525,43 @@ fn process_file(
} else {
trimmed.strip_prefix("//IF ").unwrap()
};
let res = engine.eval::<bool>(cond).unwrap();
include.push(res && *include.last().unwrap());
let last = *include.last().unwrap();

// Only evaluate condition if this IF is in a branch that should be included
let current = if last.include_line() {
engine.eval::<bool>(cond).unwrap()
} else {
false
};

include.push(BlockKind::new_if(current));
} else if trimmed.starts_with("#ELIF ") || trimmed.starts_with("//ELIF ") {
let cond = if trimmed.starts_with("#ELIF ") {
trimmed.strip_prefix("#ELIF ").unwrap()
} else {
trimmed.strip_prefix("//ELIF ").unwrap()
};
let last = include.pop().unwrap();

// Only evaluate condition if no other branches evaluated to true
let current = if matches!(last, BlockKind::IfElse(false, false)) {
engine.eval::<bool>(cond).unwrap()
} else {
false
};

include.push(last.into_else_if(current));
} else if trimmed.starts_with("#ELSE") || trimmed.starts_with("//ELSE") {
let res = !*include.last().unwrap();
include.pop();
include.push(res);
let last = include.pop().unwrap();
include.push(last.into_else());
} else if trimmed.starts_with("#ENDIF") || trimmed.starts_with("//ENDIF") {
include.pop();
let prev = include.pop();
assert!(
matches!(prev, Some(BlockKind::IfElse(_, _))),
"ENDIF without IF"
);
// Trim #+ and //+
} else if include.iter().all(|v| *v) {
} else if include.iter().all(|v| v.include_line()) {
let mut line = line.to_string();

if trimmed.starts_with("#+") {
Expand Down Expand Up @@ -725,4 +788,42 @@ mod test {
res.trim()
);
}

#[test]
fn test_basic_elseif() {
let template = r#"
#IF option("opt1")
opt1
#ELIF option("opt2")
opt2
#ELIF option("opt3")
opt3
#ELSE
opt4
#ENDIF
"#;

const PAIRS: &[(&[&str], &str)] = &[
(&["opt1"], "opt1"),
(&["opt1", "opt2"], "opt1"),
(&["opt1", "opt3"], "opt1"),
(&["opt1", "opt2", "opt3"], "opt1"),
(&["opt2"], "opt2"),
(&["opt2", "opt3"], "opt2"),
(&["opt3"], "opt3"),
(&["opt4"], "opt4"),
(&[], "opt4"),
];

for (options, expected) in PAIRS.iter().cloned() {
let res = process_file(
template,
&options.iter().map(|o| o.to_string()).collect::<Vec<_>>(),
&[],
&mut String::from("main.rs"),
)
.unwrap();
assert_eq!(expected, res.trim(), "options: {:?}", options);
}
}
}
3 changes: 1 addition & 2 deletions template/.cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ ESP_LOG="INFO"
rustflags = [
#IF option("xtensa")
"-C", "link-arg=-nostartfiles",
#ENDIF
#IF option("riscv")
#ELIF option("riscv")
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
# NOTE: May negatively impact performance of produced code
"-C", "force-frame-pointers",
Expand Down
12 changes: 5 additions & 7 deletions template/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ esp-hal = { version = "0.23.1", features = [
#REPLACE esp32c6 mcu
esp-println = { version = "0.13.0", features = ["esp32c6", "log"] }
log = { version = "0.4.21" }
#ELSE
#+defmt = "0.3.10"
#+defmt-rtt = "0.4.1"
#ENDIF
#IF option("alloc")
esp-alloc = { version = "0.6.0" }
Expand Down Expand Up @@ -61,8 +64,7 @@ esp-wifi = { version = "0.12.0", default-features=false, features = [
"esp-alloc",
#IF option("probe-rs")
#+"defmt",
#ENDIF
#IF !option("probe-rs")
#ELSE
"log",
#ENDIF
] }
Expand All @@ -86,15 +88,11 @@ smoltcp = { version = "0.12.0", default-features = false, features = [
#IF option("ble")
#+bleps = { git = "https://github.com/bjoernQ/bleps", package = "bleps", rev = "a5148d8ae679e021b78f53fd33afb8bb35d0b62e", features = [ "macros", "async"] }
#ENDIF
#IF option("probe-rs")
#+defmt = "0.3.10"
#+defmt-rtt = "0.4.1"
#ENDIF
#IF option("embassy")
embassy-executor = { version = "0.7.0", features = [
"task-arena-size-20480",
#IF option("probe-rs")
"defmt"
#+"defmt"
#ENDIF
] }
embassy-time = { version = "0.4.0", features = ["generic-queue-8"] }
Expand Down
3 changes: 1 addition & 2 deletions template/rust-toolchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ channel = "stable"
components = ["rust-src"]
#REPLACE riscv32imac-unknown-none-elf rust_target
targets = ["riscv32imac-unknown-none-elf"]
#ENDIF
#IF option("xtensa")
#ELIF option("xtensa")
#+channel = "esp"
#ENDIF
11 changes: 5 additions & 6 deletions template/src/bin/async_main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ use esp_hal::clock::CpuClock;
//IF option("probe-rs")
//+ use defmt_rtt as _;
//+ use defmt::info;
//ENDIF
//IF !option("probe-rs")
//ELSE
use log::info;
//ENDIF

Expand All @@ -24,17 +23,17 @@ async fn main(spawner: Spawner) {
//REPLACE generate-version generate-version
// generator version: generate-version

//IF !option("probe-rs")
esp_println::logger::init_logger_from_env();
//ENDIF

let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);

//IF option("alloc")
esp_alloc::heap_allocator!(72 * 1024);
//ENDIF

//IF !option("probe-rs")
esp_println::logger::init_logger_from_env();
//ENDIF

//IF !option("esp32")
let timer0 = esp_hal::timer::systimer::SystemTimer::new(peripherals.SYSTIMER);
esp_hal_embassy::init(timer0.alarm0);
Expand Down
8 changes: 4 additions & 4 deletions template/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ fn main() -> ! {
//REPLACE generate-version generate-version
// generator version: generate-version

//IF !option("probe-rs")
esp_println::logger::init_logger_from_env();
//ENDIF

let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
//IF option("wifi") || option("ble")
let peripherals = esp_hal::init(config);
//ELSE
//+let _peripherals = esp_hal::init(config);
//ENDIF

//IF !option("probe-rs")
esp_println::logger::init_logger_from_env();
//ENDIF

//IF option("alloc")
esp_alloc::heap_allocator!(72 * 1024);
//ENDIF
Expand Down

0 comments on commit 8d4a376

Please sign in to comment.