mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-11-05 04:51:40 +03:00
Allow hyphen in variable names
This commit is contained in:
parent
958dec51cc
commit
4409cf0a60
@ -4,12 +4,9 @@ use std::{fmt, num::ParseIntError};
|
||||
#[derive(Logos, Debug, PartialEq, Clone)]
|
||||
#[logos(error=LexingError)]
|
||||
pub enum Token {
|
||||
#[regex("[_.a-zA-Z][_.a-zA-Z0-9]*", |lex| lex.slice().parse().ok())]
|
||||
#[regex("[_.a-zA-Z][_.a-zA-Z0-9-]*", |lex| lex.slice().parse().ok())]
|
||||
Name(String),
|
||||
|
||||
#[regex("[_.a-zA-Z][_.a-zA-Z0-9]*-1", |lex| lex.slice().parse().ok())]
|
||||
Pred(String),
|
||||
|
||||
#[regex("@|λ")]
|
||||
Lambda,
|
||||
|
||||
@ -243,7 +240,7 @@ fn normalized_char(lexer: &mut Lexer<Token>) -> Option<u64> {
|
||||
impl fmt::Display for Token {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Self::Name(s) | Self::Pred(s) => write!(f, "{}", s),
|
||||
Self::Name(s) => write!(f, "{}", s),
|
||||
Self::Lambda => write!(f, "λ"),
|
||||
Self::Dollar => write!(f, "$"),
|
||||
Self::Let => write!(f, "let"),
|
||||
|
@ -96,6 +96,19 @@ where
|
||||
select!(Token::Name(name) => Name(name))
|
||||
}
|
||||
|
||||
/// A top level name that not accepts `-`.
|
||||
fn tl_name<'a, I>() -> impl Parser<'a, I, Name, extra::Err<Rich<'a, Token>>>
|
||||
where
|
||||
I: ValueInput<'a, Token = Token, Span = SimpleSpan>,
|
||||
{
|
||||
select!(Token::Name(name) => Name(name)).validate(|out, span, emitter| {
|
||||
if out.contains('-') {
|
||||
emitter.emit(Rich::custom(span, "Names with '-' are not supported at top level."));
|
||||
}
|
||||
out
|
||||
})
|
||||
}
|
||||
|
||||
fn tag<'a, I>(default: Tag) -> impl Parser<'a, I, Tag, extra::Err<Rich<'a, Token>>>
|
||||
where
|
||||
I: ValueInput<'a, Token = Token, Span = SimpleSpan>,
|
||||
@ -145,9 +158,6 @@ where
|
||||
let term_sep = just(Token::Semicolon).or_not();
|
||||
|
||||
recursive(|term| {
|
||||
// <Name>-1
|
||||
let pred = select!(Token::Pred(s) => Term::Var { nam: Name(s) }).boxed();
|
||||
|
||||
// *
|
||||
let era = just(Token::Asterisk).to(Term::Era).boxed();
|
||||
|
||||
@ -314,7 +324,6 @@ where
|
||||
num_op,
|
||||
app,
|
||||
era,
|
||||
pred,
|
||||
))
|
||||
})
|
||||
}
|
||||
@ -338,7 +347,7 @@ where
|
||||
recursive(|pattern| {
|
||||
let var = name_or_era().map(Pattern::Var).boxed();
|
||||
|
||||
let ctr = name()
|
||||
let ctr = tl_name()
|
||||
.then(pattern.clone().repeated().collect())
|
||||
.map(|(nam, xs)| Pattern::Ctr(nam, xs))
|
||||
.delimited_by(just(Token::LParen), just(Token::RParen))
|
||||
@ -374,7 +383,7 @@ fn rule_pattern<'a, I>() -> impl Parser<'a, I, (Name, Vec<Pattern>), extra::Err<
|
||||
where
|
||||
I: ValueInput<'a, Token = Token, Span = SimpleSpan>,
|
||||
{
|
||||
let lhs = name().then(pattern().repeated().collect()).boxed();
|
||||
let lhs = tl_name().then(pattern().repeated().collect()).boxed();
|
||||
choice((lhs.clone(), lhs.clone().delimited_by(just(Token::LParen), just(Token::RParen))))
|
||||
.then_ignore(just(Token::Equals))
|
||||
}
|
||||
@ -418,8 +427,8 @@ fn datatype<'a, I>() -> impl Parser<'a, I, (Name, Adt), extra::Err<Rich<'a, Toke
|
||||
where
|
||||
I: ValueInput<'a, Token = Token, Span = SimpleSpan>,
|
||||
{
|
||||
let arity_0 = name().map(|nam| (nam, vec![]));
|
||||
let arity_n = name()
|
||||
let arity_0 = tl_name().map(|nam| (nam, vec![]));
|
||||
let arity_n = tl_name()
|
||||
.then(name().repeated().collect::<Vec<_>>())
|
||||
.delimited_by(just(Token::LParen), just(Token::RParen))
|
||||
.map(|(nam, args)| (nam, args));
|
||||
@ -428,7 +437,7 @@ where
|
||||
let data = soft_keyword("data");
|
||||
|
||||
data
|
||||
.ignore_then(name())
|
||||
.ignore_then(tl_name())
|
||||
.then_ignore(just(Token::Equals))
|
||||
.then(ctr.separated_by(just(Token::Or)).collect::<Vec<(Name, Vec<Name>)>>())
|
||||
.map(|(name, ctrs)| (name, Adt { ctrs: ctrs.into_iter().collect() }))
|
||||
|
@ -183,7 +183,7 @@ fn hangs() {
|
||||
let lck = Arc::new(RwLock::new(false));
|
||||
let got = lck.clone();
|
||||
std::thread::spawn(move || {
|
||||
let _ = run_book(book, 1 << 20, true, false, false, true, Opts::heavy());
|
||||
let _ = run_book(book, 1 << 20, true, false, false, WarningOpts::deny_all(), Opts::heavy());
|
||||
*got.write().unwrap() = true;
|
||||
});
|
||||
std::thread::sleep(std::time::Duration::from_secs(expected_normalization_time));
|
||||
|
14
tests/golden_tests/run_file/names_hyphen.hvm
Normal file
14
tests/golden_tests/run_file/names_hyphen.hvm
Normal file
@ -0,0 +1,14 @@
|
||||
id cool-var-name = cool-var-name
|
||||
|
||||
data Done_ = (Done done-var)
|
||||
|
||||
toZero n =
|
||||
match n {
|
||||
0: (Done 1)
|
||||
+: (toZero n-1)
|
||||
}
|
||||
|
||||
main =
|
||||
match is-done = (toZero 4) {
|
||||
Done: is-done.done-var
|
||||
}
|
5
tests/golden_tests/run_file/names_hyphen_toplevel.hvm
Normal file
5
tests/golden_tests/run_file/names_hyphen_toplevel.hvm
Normal file
@ -0,0 +1,5 @@
|
||||
this-is-not-allowed = 1
|
||||
|
||||
data Foo-Bar = Baz-Qux
|
||||
|
||||
main = (this-is-not-allowed Baz-Qux)
|
5
tests/snapshots/run_file__names_hyphen.hvm.snap
Normal file
5
tests/snapshots/run_file__names_hyphen.hvm.snap
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/names_hyphen.hvm
|
||||
---
|
||||
1
|
7
tests/snapshots/run_file__names_hyphen_toplevel.hvm.snap
Normal file
7
tests/snapshots/run_file__names_hyphen_toplevel.hvm.snap
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
source: tests/golden_tests.rs
|
||||
input_file: tests/golden_tests/run_file/names_hyphen_toplevel.hvm
|
||||
---
|
||||
At line 1: Names with '-' are not supported at top level.
|
||||
At line 3: Names with '-' are not supported at top level.
|
||||
At line 3: Names with '-' are not supported at top level.
|
Loading…
Reference in New Issue
Block a user