commit 7674d856c5378b45a7f981e937e7d0099663fd91
parent 797d6544083434744cc572c955c4d671eae273ae
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 25 Feb 2021 14:53:51 -0500
hare::{ast, parse}: add IDENT_MAX
Diffstat:
2 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/hare/ast/types.ha b/hare/ast/types.ha
@@ -2,6 +2,12 @@
// significant part (foo::bar::baz becomes ["baz", "bar", "foo"].
export type ident = []str;
+// Maximum length of an identifier, as the sum of the lengths of its parts plus
+// one for each namespace deliniation.
+//
+// In other words, the length of "a::b::c" is 5.
+export def IDENT_MAX: size = 255;
+
// Frees resources associated with an identifier.
export fn ident_free(ident: ident) void = {
for (let i = 0z; i < len(ident); i += 1) {
diff --git a/hare/parse/parse.ha b/hare/parse/parse.ha
@@ -5,6 +5,7 @@ use slice;
fn ident_trailing(lexer: *lex::lexer) ((ast::ident, bool) | error) = {
let ident: []str = [];
+ let z = 0z;
for (true) {
let name = match (try_name(lexer)?) {
n: lex::name => n,
@@ -14,10 +15,17 @@ fn ident_trailing(lexer: *lex::lexer) ((ast::ident, bool) | error) = {
},
};
append(ident, name: str);
+ z += len(name);
match (try_btoken(lexer, btoken::DOUBLE_COLON)?) {
void => break,
* => void, // Grab the next ident
};
+ z += 1;
+ };
+ if (z > ast::IDENT_MAX) {
+ ast::ident_free(ident: ast::ident);
+ return syntaxerr(mkloc(lexer),
+ "Identifier exceeds maximum length");
};
slice::reverse(ident, size(ast::ident));
return (ident: ast::ident, false);