aboutsummaryrefslogtreecommitdiffstats
path: root/compiler/compile.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-30 13:02:39 +0100
committereunhhu <[email protected]>2026-09-30 13:02:39 +0100
commitbe1122a2e8bc720bd9473c130255eba46389c883 (patch)
tree3d55ac2444c602516a0c160c02e541b1f20af788 /compiler/compile.c
parentc69682e1f1bc73e2b1f4a22b8eb3ec463be588e3 (diff)
downloadaup-be1122a2e8bc720bd9473c130255eba46389c883.tar.gz
aup-be1122a2e8bc720bd9473c130255eba46389c883.zip
Let declared fields be apart by commas, as a value's are
A message's, a group's and a record's fields took a newline or a semicolon after each, while a value's (Kept { id: 1, t: "a" }, send) take commas, and the language's own examples declared message { title: text, points: number } and to: { city: text, zip: u32 }, which did not compile. Now a comma, a newline or a semicolon ends a declared field too (one after the last as well); without one it says so.
Diffstat (limited to 'compiler/compile.c')
-rw-r--r--compiler/compile.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/compiler/compile.c b/compiler/compile.c
index 86259dd..aa073f1 100644
--- a/compiler/compile.c
+++ b/compiler/compile.c
@@ -372,6 +372,19 @@ static void end(Compiler *c) {
separators(c);
}
+/* After a declared field (a message's, a group's, a record's): a comma, as
+ * between a value's fields, or the end of a line or a semicolon. */
+static void end_field(Compiler *c) {
+ if (!is(c, ",")) {
+ if (c->token.kind != T_NL && !is(c, ";") && !is(c, "}"))
+ fail_at(c, c->token.line, c->token.column, "expected a comma, newline or semicolon");
+ separators(c);
+ return;
+ }
+ take(c);
+ separators(c);
+}
+
static bool reserved_name(const char *name) {
for (size_t i = 0; i < sizeof(reserved) / sizeof(*reserved); ++i)
if (!strcmp(name, reserved[i])) return true;
@@ -1165,7 +1178,7 @@ static void message_fields(Compiler *c, Input *in, const char *group) {
expect(c, ":", "':'");
if (is(c, "{")) {
message_fields(c, in, path);
- end(c);
+ end_field(c);
continue;
}
if (c->field_count == FIELDS) fail_at(c, name.line, name.column, "at most %d message fields are allowed", FIELDS);
@@ -1189,7 +1202,7 @@ static void message_fields(Compiler *c, Input *in, const char *group) {
memcpy(in->field_names[in->fields], path, NAME);
in->field_types[in->fields++] = field_type;
++c->field_count;
- end(c);
+ end_field(c);
}
if (*group && in->fields == first) fail_at(c, c->token.line, c->token.column, "the group '%s' has no fields", group);
take(c);
@@ -1214,7 +1227,7 @@ static Expr *plain_string(Compiler *c, const char *what) {
return value->args[0];
}
-/* record Name { field = number; field: text = "..." } */
+/* record Name { field = number, field: text = "..." } */
static void record_declaration(Compiler *c) {
Token name = expect_name(c, "record name");
declare(c, &name);
@@ -1252,7 +1265,7 @@ static void record_declaration(Compiler *c) {
expect(c, "=", "'=' and a number, or ': text'");
r->field_number[index] = signed_number(c, "field default");
}
- end(c);
+ end_field(c);
}
take(c);
if (!r->fields) fail_at(c, name.line, name.column, "a record needs at least one field");