aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-06-24 04:18:59 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-06-24 04:20:14 +0200
commitfbaa65a2319745c8a236a5c9c66e3406f42447c3 (patch)
treed3200a0713af19432aa8aaa0fa7a3c52ae86e89c /src
parent02ce35872c86d4ff056b8121121253fec40bafc0 (diff)
Support ‘…’ and ‘...’ in initializers
Diffstat (limited to 'src')
-rw-r--r--src/codegen.c4
-rw-r--r--src/lexer.c13
-rw-r--r--src/lexer.h4
-rw-r--r--src/parser.c25
-rw-r--r--src/parser.h5
5 files changed, 44 insertions, 7 deletions
diff --git a/src/codegen.c b/src/codegen.c
index 6fc7848..665f071 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -240,6 +240,10 @@ codegendecl(struct cgctx ctx, idx_t i)
assert(ctx.ast.kinds[i] == ASTDECL);
+ /* Don’t assign a default value to ‘x: int = …’ */
+ if (ctx.aux.buf[p.lhs].decl.isundef)
+ return fwdnode(ctx.ast, i);
+
if (!ctx.types[i].isfloat && ctx.aux.buf[p.lhs].decl.isstatic) {
strview_t sv = ctx.toks.strs[ctx.ast.lexemes[i]];
/* TODO: Namespace the name */
diff --git a/src/lexer.c b/src/lexer.c
index 30686d8..a613585 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -70,6 +70,10 @@ lexstring(const uchar *code, size_t codesz)
data.kinds[data.len++] = ch;
break;
+ case RUNE_C(0x2026): /* U+2026 HORIZONTAL ELLIPSIS */
+ data.kinds[data.len++] = LEXELIP;
+ break;
+
/* Single- or double-byte literals */
case '/':
if (code < end && code[0] == '*') {
@@ -80,7 +84,6 @@ lexstring(const uchar *code, size_t codesz)
data.kinds[data.len++] = ch;
break;
-
case '<': case '>':
data.kinds[data.len++] = ch;
@@ -91,6 +94,13 @@ lexstring(const uchar *code, size_t codesz)
}
break;
+ case '.':
+ if (unlikely(end - code < 2) || code[0] != '.' || code[1] != '.')
+ goto fallback;
+ code += 2;
+ data.kinds[data.len++] = LEXELIP;
+ break;
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
data.kinds[data.len] = LEXNUM;
@@ -112,6 +122,7 @@ lexstring(const uchar *code, size_t codesz)
break;
default:
+fallback:
if (!rune_is_xids(ch))
continue;
diff --git a/src/lexer.h b/src/lexer.h
index 5436030..fb63fd8 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -13,6 +13,10 @@ enum {
LEXEOF, /* End of token stream */
LEXIDENT, /* Identifier */
LEXNUM, /* Numeric constant */
+ LEXELIP, /* Ellipsis */
+
+ /* NOTE: Make sure that the enumerations above this comment don’t
+ conflict with the following explicitly assigned enumerations! */
LEXAMP = '&',
LEXCOLON = ':',
diff --git a/src/parser.c b/src/parser.c
index 5b12e21..46a1fb6 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -128,6 +128,7 @@ parsedecl(ast_t *ast, aux_t *aux, lexemes_t toks, bool toplvl)
}
aux->buf[j].decl.isstatic = toplvl;
+ aux->buf[j].decl.isundef = false;
if (toplvl && toks.kinds[toksidx] == LEXIDENT
&& strview_eq(SV("pub"), toks.strs[toksidx]))
{
@@ -165,11 +166,27 @@ parsedecl(ast_t *ast, aux_t *aux, lexemes_t toks, bool toplvl)
err("parser: Expected colon, equals, or semicolon");
}
- bool func = toks.kinds[toksidx] == LEXLPAR;
- if (func && ast->kinds[i] == ASTDECL)
- err("Cannot assign function to mutable variable");
+ idx_t rhs;
+ bool func = false;
+
+ switch (toks.kinds[toksidx]) {
+ case LEXLPAR:
+ func = true;
+ if (ast->kinds[i] == ASTDECL)
+ err("Cannot assign function to mutable variable");
+ rhs = parsefunc(ast, aux, toks);
+ break;
+ case LEXELIP:
+ toksidx++;
+ if (ast->kinds[i] == ASTCDECL)
+ err("parser: Cannot assign to ‘…’ in constant declaration");
+ rhs = AST_EMPTY;
+ aux->buf[j].decl.isundef = true;
+ break;
+ default:
+ rhs = parseexpr(ast, aux, toks);
+ }
- idx_t rhs = (func ? parsefunc : parseexpr)(ast, aux, toks);
ast->kids[i].rhs = rhs;
if (!func && toks.kinds[toksidx++] != LEXSEMI)
err("parser: Expected semicolon");
diff --git a/src/parser.h b/src/parser.h
index 9f7bf5e..d8991c0 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -71,8 +71,9 @@ typedef struct {
union {
struct {
idx_t type;
- bool ispub;
- bool isstatic;
+ bool ispub : 1;
+ bool isstatic : 1;
+ bool isundef : 1;
} decl;
} *buf;
size_t len, cap;