Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/workshop-rs/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1976,7 +1976,7 @@ impl Parser<'_> {
)?;
let player = self.value()?;
self.expect(TokenKind::Comma, "expected ',' after loop player")?;
let (name, _, _) = self.phrase()?;
let (name, target_start, target_end) = self.phrase()?;
let variable = self.player_by_name(&name)?;
self.expect(TokenKind::Comma, "expected ',' after loop variable")?;
let start_value = self.value()?;
Expand Down Expand Up @@ -2004,6 +2004,7 @@ impl Parser<'_> {
step,
body,
span: Some(Span::new(self.file(), start, end_span.1)),
target_span: Some(Span::new(self.file(), target_start, target_end)),
};
Ok(self.target.actions.push(action))
}
Expand Down
1 change: 1 addition & 0 deletions crates/workshop-rs/src/wir/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ fn render_action(program: &Program, id: super::ActionId, out: &mut String, level
step,
body,
span,
..
} => {
out.push_str(&format!("{}forPlayerVariable ", indent(level)));
render_value(program, *player, out);
Expand Down
2 changes: 2 additions & 0 deletions crates/workshop-rs/src/wir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ pub enum Action {
step: ValueId,
body: Vec<ActionId>,
span: Option<Span>,
/// The exact span of the loop variable identifier.
target_span: Option<Span>,
},
/// Any other action call with side effects.
Call {
Expand Down
1 change: 1 addition & 0 deletions crates/workshop-rs/tests/action_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ fn program_with_structured_actions() -> (wir::Program, Vec<wir::ActionId>) {
step: number,
body: vec![nested_if_body],
span: None,
target_span: None,
});
let trailing_leaf = leaf(&mut program, number);
let actions = vec![
Expand Down
30 changes: 30 additions & 0 deletions crates/workshop-rs/tests/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,36 @@ fn spans_are_preserved() {
assert!(action.span().is_some());
}

#[test]
fn player_variable_loop_preserves_target_span() {
let text = r#"variables {
player:
0: I
}

rule ("r") {
event {
Ongoing - Global;
}
actions {
For Player Variable(Host Player, I, 0, 3, 1);
End;
}
}
"#;
let program = parser::parse(text, &catalog(), &Locale::new("en-US")).unwrap();
let rule = program.rules.iter().next().unwrap();
let action = program.actions.get(rule.actions[0]).unwrap();
let wir::Action::ForPlayerVariable { target_span, .. } = action else {
panic!("expected For Player Variable");
};
let target_span = target_span.expect("player loop target span");
assert_eq!(target_span.start.line, 11);
assert_eq!(target_span.start.col, 42);
assert_eq!(target_span.end.line, 11);
assert_eq!(target_span.end.col, 43);
}

#[test]
fn malformed_input_is_reported_as_malformed() {
// A rule-final If without `End;` is the oracle's valid spelling; an If
Expand Down
Loading