aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2022-08-07 06:41:48 +0200
committerlemon <lsof@mailbox.org>2022-08-07 06:41:48 +0200
commit27e22daa10040999f6e5bfe47aa2b8b504b40071 (patch)
treed6c99539f5e30f1927c5c616ae14d21e5d325313
parent4a0b52a8259810ef7838eece5af030158616d5e5 (diff)
union init
-rw-r--r--bootstrap/parse.c11
-rw-r--r--bootstrap/test.cff17
2 files changed, 19 insertions, 9 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index f61e65b..b18c169 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -731,6 +731,7 @@ parsestructini(struct parser *P, const struct type *ty) {
vec_t(struct iniarg) args = {0};
int idx = 0;
struct aggfield *fld;
+ const char *kind = ty->t == TYstruct ? "struct" : "union";
ex.span = lexpeek(P).span;
@@ -742,7 +743,7 @@ parsestructini(struct parser *P, const struct type *ty) {
lexexpect(P, ':');
idx = structfldnam2idx(ty, fnam);
if (idx < 0)
- fatal(P, tok.span, "struct %t has no field `%s'", ty, fnam);
+ fatal(P, tok.span, "%s %t has no field `%s'", kind, ty, fnam);
}
fld = structidx2fld(ty, idx++);
@@ -753,8 +754,8 @@ parsestructini(struct parser *P, const struct type *ty) {
"excess elements in struct initializer");
if (!typeof2(e.ty, fld->ty))
fatal(P, e.span,
- "incompatible element `%s` type in struct initializer (%t, expected %t)",
- fld->name, e.ty, fld->ty);
+ "incompatible element `%s` type in %s initializer (%t, expected %t)",
+ fld->name, kind, e.ty, fld->ty);
vec_push(&args, ((struct iniarg) {
.fld = fld->name,
@@ -886,7 +887,7 @@ pexprimary(struct parser *P) {
lexexpect(P, ':');
P->targty = ty;
goto enumlit;
- } else if (ty->t == TYstruct || ty->t == TYenum) {
+ } else if (ty->t == TYstruct || ty->t == TYunion) {
lexexpect(P, '{');
P->targty = ty;
goto aggini;
@@ -954,7 +955,7 @@ pexprimary(struct parser *P) {
fatal(P, tok.span, "cannot infer type for compound initializer");
if (lexmatch(P, &tok, '}'))
ex.t = Ezeroini, ex.ty = P->targty;
- else if (P->targty->t == TYstruct)
+ else if (P->targty->t == TYstruct || P->targty->t == TYunion)
ex = parsestructini(P, P->targty);
else if (P->targty->t == TYarr)
ex = parsearrini(P, P->targty);
diff --git a/bootstrap/test.cff b/bootstrap/test.cff
index e466bba..a000224 100644
--- a/bootstrap/test.cff
+++ b/bootstrap/test.cff
@@ -1,11 +1,12 @@
import "libc.hff";
import "libc.hff";
+
union Val {
- x i64,
- lo i32,
- y f64,
+ u u32,
+ f f32,
}
+
enum Color {
Red, Green, Blue
}
@@ -50,9 +51,16 @@ struct Vec2f {
fn spanz(cstr *const u8) [#]const u8 {
extern fn strlen(s *const u8) usize;
- return cstr[0::strlen(cstr)];
+ return cstr[0::strlen(cstr) + 1];
}
+defmacro transmute(Type, x) [
+ (do
+ union T { from typeof(x), to Type };
+ T{x}.to;
+ )
+]
+
extern fn main (argc int, argv **u8) int {
let colors [3]Color = { :Red, :Green, :Blue } ;
@@ -77,6 +85,7 @@ extern fn main (argc int, argv **u8) int {
printf("sizeof(is) = %zu\n", sizeof(is));
printf("sizeof *void = %zu\n", sizeof *void);
+ printf("1.2 -> %#.8x\n", transmute(u32, 1.2f));
return 0;