Skip to content
Merged
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
4 changes: 2 additions & 2 deletions compatibility/compiler-expectations.json
Original file line number Diff line number Diff line change
Expand Up @@ -593,9 +593,9 @@
"provenance:real-world/ow1-emulator/fixture.json"
],
"owner": "opy-rs#88",
"note": "The full real-world project now resolves included-file #!mainFile and #!defineMember directives; it remains outside the compiler baseline at the next lexer line-continuation boundary.",
"note": "The full real-world project now resolves included-file #!mainFile, #!defineMember directives, and continued directive lines; it remains outside the compiler baseline at the duplicate-include macro-redeclaration boundary.",
"failureClass": "frontend",
"diagnosticCode": "lex-error"
"diagnosticCode": "macro-redeclaration"
},
{
"fixture": "synthetic/chase-condition-agentlab",
Expand Down
2 changes: 1 addition & 1 deletion compatibility/differential-expectations.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
{"fixture": "real-world/overpy-parabola", "nativeStatus": "failure", "classification": "known-gap", "ruleNames": false, "evidence": ["oracle:real-world/overpy-parabola/oracle.json", "regression:real-world/overpy-parabola/fixture.json"], "note": "The numeric enum member regression now resolves; the full project reaches the next multiline parenthesized expression gap at parabola.opy:50."},
{"fixture": "real-world/overpy-meipocalypse", "nativeStatus": "failure", "classification": "match", "ruleNames": false, "evidence": ["oracle:real-world/overpy-meipocalypse/oracle.json", "provenance:real-world/overpy-meipocalypse/fixture.json"], "note": "The reference rejects the missing script hook; native rejection is retained with a different earlier diagnostic."},
{"fixture": "real-world/overpy-zencopter", "nativeStatus": "failure", "classification": "match", "ruleNames": false, "evidence": ["oracle:real-world/overpy-zencopter/oracle.json", "provenance:real-world/overpy-zencopter/fixture.json"], "note": "Both sides reject the pinned upstream example; native diagnostic wording is not used as semantic evidence."},
{"fixture": "real-world/ow1-emulator", "nativeStatus": "failure", "classification": "match", "ruleNames": false, "evidence": ["oracle:real-world/ow1-emulator/oracle.json", "provenance:real-world/ow1-emulator/fixture.json"], "note": "The full project now resolves included-file #!mainFile and #!defineMember directives; the failure case remains at the next lexer line-continuation boundary."},
{"fixture": "real-world/ow1-emulator", "nativeStatus": "failure", "classification": "match", "ruleNames": false, "evidence": ["oracle:real-world/ow1-emulator/oracle.json", "provenance:real-world/ow1-emulator/fixture.json"], "note": "The full project now resolves included-file #!mainFile, #!defineMember directives, and continued directive lines; the failure case remains at the duplicate-include macro-redeclaration boundary."},
{"fixture": "real-world/6v6-adjustments", "nativeStatus": "failure", "classification": "match", "ruleNames": false, "evidence": ["oracle:real-world/6v6-adjustments/oracle.json", "provenance:real-world/6v6-adjustments/fixture.json"], "note": "The full project now resolves included-file #!mainFile and #!defineMember directives; the failure case remains at the existing included settings-placement boundary."},
{"fixture": "synthetic/issue-35-integration", "nativeStatus": "success", "classification": "match", "ruleNames": true, "evidence": ["oracle:synthetic/issue-35-integration/oracle.json", "implementation-invariant:opy-rs::compiler-vertical-slice"], "note": "The OPY source implementation resolves the source fixture; the compiler test independently lowers it through canonical WIR validation and deterministic workshop-rs emission."},
{"fixture": "synthetic/issue-40-structural", "nativeStatus": "success", "classification": "match", "ruleNames": false, "evidence": ["oracle:synthetic/issue-40-structural/oracle.json", "implementation-invariant:opy-rs::compiler-structural-lowering"], "note": "The pinned oracle records subroutine source identity, deterministic explicit/implicit variable allocation, and player event filters; the compiler test independently asserts those structures in canonical WIR."},
Expand Down
20 changes: 19 additions & 1 deletion crates/opy-rs/src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,13 @@ impl Lexer {
self.advance();
self.advance();
let mut text = String::new();
while self.pos < self.chars.len() && self.chars[self.pos] != '\n' {
while self.pos < self.chars.len() {
if self.chars[self.pos] == '\\' && self.skip_line_continuation() {
continue;
}
if self.chars[self.pos] == '\n' {
break;
}
text.push(self.chars[self.pos]);
self.advance();
}
Expand Down Expand Up @@ -574,6 +580,18 @@ mod tests {
assert!(!tokens.iter().any(|t| t.text == "comment"));
}

#[test]
fn directive_line_continuation_is_part_of_one_directive() {
let tokens = lex_ok("#!define X first + \\\n second\n");
let directive = tokens
.iter()
.find(|token| token.kind == TokenKind::Directive)
.unwrap();
assert_eq!(directive.text, "define X first + second");
assert_eq!(directive.span.start, Position::new(1, 1));
assert_eq!(directive.span.end, Position::new(2, 9));
}

#[test]
fn operators() {
let tokens = lex_ok("a += b == c <= d != e / f");
Expand Down
Loading