Allow hyphen in variable names

This commit is contained in:
imaqtkatt 2024-01-30 15:06:21 -03:00
parent 958dec51cc
commit 4409cf0a60
7 changed files with 52 additions and 15 deletions

View File

@ -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"),

View File

@ -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() }))

View File

@ -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));

View 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
}

View File

@ -0,0 +1,5 @@
this-is-not-allowed = 1
data Foo-Bar = Baz-Qux
main = (this-is-not-allowed Baz-Qux)

View File

@ -0,0 +1,5 @@
---
source: tests/golden_tests.rs
input_file: tests/golden_tests/run_file/names_hyphen.hvm
---
1

View 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.