From 20a20027d32545f95ed12b4fcecf0a94232eff8f Mon Sep 17 00:00:00 2001 From: imaqtkatt Date: Fri, 24 May 2024 10:50:04 -0300 Subject: [PATCH] Dont allow variable names contain '__' --- docs/syntax.md | 10 ++++++++-- src/fun/parser.rs | 11 ++++++++++- .../compile_file/variable_name_double_underscore.bend | 2 ++ ...le_file__variable_name_double_underscore.bend.snap | 9 +++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 tests/golden_tests/compile_file/variable_name_double_underscore.bend create mode 100644 tests/snapshots/compile_file__variable_name_double_underscore.bend.snap diff --git a/docs/syntax.md b/docs/syntax.md index 69430329..9a29684a 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -372,7 +372,10 @@ some_var foo/bar ``` -A variable can be anything matching the regex `[A-Za-z0-9_.-/]+`. +A variable can be anything matching the regex `[A-Za-z0-9_.-/]+` but with some restrictions: + +- It can not start with `//` +- It can not contain `__` A variable is a name for some immutable expression. It is possible to rebind variables with the same name. @@ -681,7 +684,10 @@ The constructors inherit the name of their types and become functions (`Tree/Nod ### Variables -A variable can be anything matching the regex `[A-Za-z0-9_.-/]+`. +A variable can be anything matching the regex `[A-Za-z0-9_.-/]+` but with some restrictions: + +- It can not start with `//` +- It can not contain `__` A variable is a name for some immutable expression. It is possible to rebind variables with the same name. diff --git a/src/fun/parser.rs b/src/fun/parser.rs index 80722051..b8c0fefc 100644 --- a/src/fun/parser.rs +++ b/src/fun/parser.rs @@ -821,8 +821,17 @@ pub trait ParserCommons<'a>: Parser<'a> { } fn parse_bend_name(&mut self) -> ParseResult { + let ini_idx = *self.index(); let name = self.take_while(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/'); - if name.is_empty() { self.expected("name") } else { Ok(Name::new(name.to_owned())) } + let end_idx = *self.index(); + if name.contains("__") { + let msg = "Variable names are not allowed to contain \"__\".".to_string(); + self.with_ctx(Err(msg), ini_idx, end_idx) + } else if name.is_empty() { + self.expected("name") + } else { + Ok(Name::new(name.to_owned())) + } } /// Consumes exactly the text without skipping. diff --git a/tests/golden_tests/compile_file/variable_name_double_underscore.bend b/tests/golden_tests/compile_file/variable_name_double_underscore.bend new file mode 100644 index 00000000..db204ccb --- /dev/null +++ b/tests/golden_tests/compile_file/variable_name_double_underscore.bend @@ -0,0 +1,2 @@ +def main: + return __this_should_fail__(*) diff --git a/tests/snapshots/compile_file__variable_name_double_underscore.bend.snap b/tests/snapshots/compile_file__variable_name_double_underscore.bend.snap new file mode 100644 index 00000000..667887ed --- /dev/null +++ b/tests/snapshots/compile_file__variable_name_double_underscore.bend.snap @@ -0,0 +1,9 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/compile_file/variable_name_double_underscore.bend +--- +Errors: +In tests/golden_tests/compile_file/variable_name_double_underscore.bend : +- expected: expression +- detected: + 2 | return __this_should_fail__(*)