diff options
| author | 2022-08-07 06:41:48 +0200 | |
|---|---|---|
| committer | 2022-08-07 06:41:48 +0200 | |
| commit | 27e22daa10040999f6e5bfe47aa2b8b504b40071 (patch) | |
| tree | d6c99539f5e30f1927c5c616ae14d21e5d325313 /bootstrap | |
| parent | 4a0b52a8259810ef7838eece5af030158616d5e5 (diff) | |
union init
Diffstat (limited to 'bootstrap')
| -rw-r--r-- | bootstrap/parse.c | 11 | ||||
| -rw-r--r-- | bootstrap/test.cff | 17 |
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; |