Skip to content

Interpreter: switch statement lowering#72

Open
Franklin-Qi wants to merge 1 commit into
uutils:mainfrom
Franklin-Qi:feature-task#70-Interpreter-switch-statement-lowering
Open

Interpreter: switch statement lowering#72
Franklin-Qi wants to merge 1 commit into
uutils:mainfrom
Franklin-Qi:feature-task#70-Interpreter-switch-statement-lowering

Conversation

@Franklin-Qi

Copy link
Copy Markdown
Contributor

Add AST lowering for switch: evaluate the scrutinee once into a register, emit a branch chain for each case, and jump to the default branch or past the statement when nothing matches.

Match literal cases with Eq; match regex and typed-regex cases with Matches. Support default placed anywhere in the case list, including before later cases.

Fixes #70

Add AST lowering for switch: evaluate the scrutinee once into a register, emit a branch chain for each case, and jump to the default branch or past the statement when nothing matches.

Match literal cases with Eq; match regex and typed-regex cases with Matches.
Support default placed anywhere in the case list, including before later cases.

Fixes uutils#70

@Alonely0 Alonely0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a first glance this looks great, but my head aches a bit too much for me to continue looking at a screen today, sorry. I'll push the review comments I have and try to do some more tomorrow.

Comment thread interpreter/src/types.rs
Comment on lines +80 to +93
pub fn matches_regex(&self, pattern: &[u8]) -> bool {
let mut subject = Vec::with_capacity(self.string_size_hint());
self.write_string(&mut subject);
let Ok(subject) = str::from_utf8(&subject) else {
return false;
};
let Ok(pattern) = str::from_utf8(pattern) else {
return false;
};
regex::Regex::new(pattern)
.ok()
.is_some_and(|re| re.is_match(subject))
}

@Alonely0 Alonely0 Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If only life were so simple. gawk has regex extensions, so we will probably have to build our own regex layer on top of regex-automata, or at the very least do a pre-processing pass. We can keep as-is this for now so it's testable, tho.

case: &Atom<'_>,
case_ix: usize,
) -> (Label, usize) {
let cmp = self.alloc_reg();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure we could reuse this destination register for all comparisons. Would it not be better to allocate it once in lower_switch and pass it as an argument?


for (br_label, case_ix) in pending_branches {
self.bc.nth(br_label).set_then_label(case_labels[case_ix]);
self.bc.nth(br_label).set_label(Label(br_label.0 + 1));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be able to set the else_label at the time of generation of each branch in emit_switch_case_match(). Notice this is just the position of the next instruction, which is known when it is emitted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interpreter: switch statement lowering.

2 participants