diff --git a/rs/main/src/lib.rs b/rs/main/src/lib.rs index 8562a3c..ffbb115 100644 --- a/rs/main/src/lib.rs +++ b/rs/main/src/lib.rs @@ -177,8 +177,14 @@ impl Engine { // self.ast `Yoke`, and we can't `self.ast.take()` and then re-use the allocation there // 'cause then we'll be unable to do this diffing thing against what it used to be b/c // it'll have been overwritten. + + // Normalize line endings to \n + let normalized_code = code.replace("\r\n", "\n"); + let new_ast: YokedAst = - Yoke::try_attach_to_cart(code.to_owned().into_boxed_str(), |code| get_ast(code))?; + Yoke::try_attach_to_cart(normalized_code.to_owned().into_boxed_str(), |code| { + get_ast(code) + })?; self.temp_node_index.clear(); diff --git a/rs/parser/src/glicol.pest b/rs/parser/src/glicol.pest index 895543a..1c7ca1d 100644 --- a/rs/parser/src/glicol.pest +++ b/rs/parser/src/glicol.pest @@ -1,7 +1,7 @@ -block = ${ SOI ~ ("\n"|WHITESPACE)* ~ ( (line|comment) ~ WHITESPACE* ~ ";"? ~ WHITESPACE* ~ ("\n" ~ WHITESPACE*)* )* ~ EOI} +block = ${ SOI ~ (NEWLINE|WHITESPACE)* ~ ( (line|comment) ~ WHITESPACE* ~ ";"? ~ WHITESPACE* ~ (NEWLINE ~ WHITESPACE*)* )* ~ EOI} comment = _{ "//" ~ (!NEWLINE ~ ANY)* ~ NEWLINE* ~ !NEWLINE} line = ${ reference ~ WHITESPACE* ~ ":" ~ WHITESPACE* ~ chain} -chain = ${ node ~ (WHITESPACE* ~ "\n"? ~ WHITESPACE* ~ ((">>" ~ WHITESPACE* ~ node) | comment) )* } +chain = ${ node ~ (WHITESPACE* ~ NEWLINE? ~ WHITESPACE* ~ ((">>" ~ WHITESPACE* ~ node) | comment) )* } node = ${ (reverb|arrange|psampler|mix|seq|choose|mul|add|sin|saw|squ|tri|pan|speed|noise|onepole| sp|constsig|lpf|rhpf|onepole|imp|delayn|delayms|envperc|apfmsgain|plate|sendpass| @@ -38,7 +38,7 @@ eval_sentence = ${ assign_to ~ ws* ~ ":=" ~ ws* ~ assign_value ~ ws* ~ ";" } assign_to = ${ var } assign_value = @{ value_char* } value_char = { !(";"|"`") ~ valid_token } -valid_token = {var|" "|"\n"|"%"|"+"|"-"|"*"|"/"|"^"|"("|")"|"["|"]"|">="|"<="|"=="|"!="|">"|"<"|"true"|"false"|"&"|"."|ASCII_DIGIT } +valid_token = {var|" "|NEWLINE|"%"|"+"|"-"|"*"|"/"|"^"|"("|")"|"["|"]"|">="|"<="|"=="|"!="|">"|"<"|"true"|"false"|"&"|"."|ASCII_DIGIT } var = _{ ASCII_ALPHA_LOWER+ ~ ("_" | ASCII_ALPHA_LOWER | ASCII_DIGIT )* } meta = ${ ("meta"|"script") ~ WHITESPACE+ ~ code} @@ -107,7 +107,7 @@ loose_match = ${".."} rest = ${ "_" } integer = ${ ("+" | "-")? ~(ASCII_DIGIT)+ ~ !"." } WHITESPACE = _{" "|","|"|"|"\t"} -ws = _{" "|","|"|"|"\t"|"\n"} +ws = _{" "|","|"|"|"\t"|NEWLINE} node_name = ${"reverb"|"arrange"|"adsr"|"sig"|"psampler"|"synth"|"msgsynth"|"psynth"|"p_synth"|"pattern_synth"| "bd"|"sn"|"hh"|"squsynth"|"trisynth"|"seq"|"speed"|"choose"|"mul"|"add"| diff --git a/rs/parser/tests/pest.rs b/rs/parser/tests/pest.rs new file mode 100644 index 0000000..84811ac --- /dev/null +++ b/rs/parser/tests/pest.rs @@ -0,0 +1,22 @@ +#![cfg(test)] + +use glicol_parser::{GlicolParser, Rule}; +use pest::Parser; + +#[test] +fn test_line_endings() { + // Unix style (LF) + let unix_input = "a: sin 440\nb: saw 220"; + let unix_result = GlicolParser::parse(Rule::block, unix_input); + assert!(unix_result.is_ok()); + + // Windows style (CRLF) + let windows_input = "a: sin 440\r\nb: saw 220"; + let windows_result = GlicolParser::parse(Rule::block, windows_input); + assert!(windows_result.is_ok()); + + // Mixed line endings + let mixed_input = "a: sin 440\nb: saw 220\r\nc: squ 110"; + let mixed_result = GlicolParser::parse(Rule::block, mixed_input); + assert!(mixed_result.is_ok()); +}