mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-09-11 11:56:54 +03:00
Merge pull request #487 from HigherOrderCO/478-dont-allow-variable-names-to-contain-__
478 dont allow variable names to contain "__"
This commit is contained in:
commit
cfd9b03efd
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -68,7 +68,7 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "bend-lang"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
dependencies = [
|
||||
"TSPL",
|
||||
"arrayvec",
|
||||
|
@ -2,7 +2,7 @@
|
||||
name = "bend-lang"
|
||||
description = "A high-level, massively parallel programming language"
|
||||
license = "Apache-2.0"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
edition = "2021"
|
||||
exclude = ["tests/snapshots/"]
|
||||
|
||||
|
@ -46,7 +46,7 @@ def main:
|
||||
|
||||
A function definition is composed by a name, a sequence of parameters and a body.
|
||||
|
||||
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names).
|
||||
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.
|
||||
|
||||
The last statement of each function must either be a `return` or a selection statement (`if`, `switch`, `match`, `fold`)
|
||||
where all branches `return`.
|
||||
@ -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.
|
||||
|
||||
@ -618,7 +621,7 @@ Name (Ctr1 sub_arg1 sub_arg2) arg3 = rule0_body
|
||||
Name Ctr2 arg3 = rule1_body
|
||||
```
|
||||
|
||||
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names).
|
||||
A top-level name can be anything matching the regex `[A-Za-z0-9_.-/]+`, except it can't have `__` (used for generated names) or start with `//`.
|
||||
|
||||
### Function Definitions
|
||||
|
||||
@ -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.
|
||||
|
||||
|
@ -805,24 +805,31 @@ pub trait ParserCommons<'a>: Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_top_level_name(&mut self) -> ParseResult<Name> {
|
||||
fn parse_restricted_name(&mut self, kind: &str) -> ParseResult<Name> {
|
||||
let ini_idx = *self.index();
|
||||
let nam = self.parse_bend_name()?;
|
||||
let name = self.take_while(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.' || c == '-' || c == '/');
|
||||
if name.is_empty() {
|
||||
self.expected("name")?
|
||||
}
|
||||
let name = Name::new(name.to_owned());
|
||||
let end_idx = *self.index();
|
||||
if nam.contains("__") {
|
||||
let msg = "Top-level names are not allowed to contain \"__\".".to_string();
|
||||
if name.contains("__") {
|
||||
let msg = format!("{kind} names are not allowed to contain \"__\".");
|
||||
self.with_ctx(Err(msg), ini_idx, end_idx)
|
||||
} else if nam.starts_with("//") {
|
||||
let msg = "Top-level names are not allowed to start with \"//\".".to_string();
|
||||
} else if name.starts_with("//") {
|
||||
let msg = format!("{kind} names are not allowed to start with \"//\".");
|
||||
self.with_ctx(Err(msg), ini_idx, end_idx)
|
||||
} else {
|
||||
Ok(nam)
|
||||
Ok(name)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_top_level_name(&mut self) -> ParseResult<Name> {
|
||||
self.parse_restricted_name("Top-level")
|
||||
}
|
||||
|
||||
fn parse_bend_name(&mut self) -> ParseResult<Name> {
|
||||
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())) }
|
||||
self.parse_restricted_name("Variable")
|
||||
}
|
||||
|
||||
/// Consumes exactly the text without skipping.
|
||||
|
@ -0,0 +1,2 @@
|
||||
def main:
|
||||
return __this_should_fail__(*)
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/compile_file/variable_name_double_underscore.bend
|
||||
---
|
||||
[4m[1m[31mErrors:[0m
|
||||
In tests/golden_tests/compile_file/variable_name_double_underscore.bend :
|
||||
[1m- expected:[0m expression
|
||||
[1m- detected:[0m
|
||||
[0m 2 | return __this_should_fail__[4m[31m([0m*)[0m
|
Loading…
Reference in New Issue
Block a user