diff options
| author | 2026-10-14 16:47:08 +0330 | |
|---|---|---|
| committer | 2026-10-14 16:47:08 +0330 | |
| commit | 4a96db860c95ed6ea8a03cb24c54ebfb9325ada8 (patch) | |
| tree | 9fa3a1fe8a667661cbc7efffa278702e44842604 | |
| parent | zc0umd: no recast uses a visible u/m/d as its tag (spec 1.6.3); spec: the fix... (diff) | |
globals: an integer constant initializing a float or f32 global converts to float (float g = 2; is 2.0)
| -rw-r--r-- | docs/SPEC.md | 2 | ||||
| -rw-r--r-- | src/compiler/decl.zc | 3 | ||||
| -rw-r--r-- | tests/conformance/5-declarations/global_float_int_init.zc | 9 |
3 files changed, 12 insertions, 2 deletions
diff --git a/docs/SPEC.md b/docs/SPEC.md index 3eda4f3..f53c469 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -703,7 +703,7 @@ a bare `name(params) { ... }` with no `fn` and no type is not a function declara 5.3.1 `T a = e, b, c[10];`, `let g = 1, buf[10];`, `int[10] buf;`, `point origin;`. storage is emitted in place, zero initialised. -5.3.2 an initializer is: a constant expression (3.14), a word string, a byte string, or a brace list or compound literal for an array. anything else is an error: for `int a = f();` error: expected ';', found '('. a `float`, `f64` or `f32` global takes a float literal initializer (`float g = 1.5;`). a name of another global in the initializer evaluates to its address, not its value: `int a = 5; int b = a + 1;` gives `b` the value `&a + 1`. +5.3.2 an initializer is: a constant expression (3.14), a word string, a byte string, or a brace list or compound literal for an array. anything else is an error: for `int a = f();` error: expected ';', found '('. a `float`, `f64` or `f32` global takes a float literal initializer (`float g = 1.5;`); an integer constant initializer converts to float (`float g = 2;` stores 2.0), as it does for a local. a name of another global in the initializer evaluates to its address, not its value: `int a = 5; int b = a + 1;` gives `b` the value `&a + 1`. 5.3.3 a global cannot be tagged (error: tags go on locals and parameters, not globals), cannot be `void`, and an array global needs a length or an initializer. diff --git a/src/compiler/decl.zc b/src/compiler/decl.zc index 371e8e8..e9500c4 100644 --- a/src/compiler/decl.zc +++ b/src/compiler/decl.zc @@ -484,7 +484,8 @@ int gdecl2(int t, int tg, int n) { vv = tv; next(); if (t == tf32) vv = rt.zs2f(rt.zf2s(vv)); *(a + hdelta) = vv; // an f32 scalar is a rounded double } else { - vv = cnorm(t, cexpr()); *(a + hdelta) = vv; + vv = cnorm(t, cexpr()); if (t && isfl(t)) { vv = vf_i2f(vv); if (t == tf32) vv = rt.zs2f(rt.zf2s(vv)); } // float g = 2; is 2.0 + *(a + hdelta) = vv; if (gok) { if (!gty) gty = tint; else if (gty != tint) gok = 0; } } } else if (gok) gok = 0; // no initializer: nothing says what it is diff --git a/tests/conformance/5-declarations/global_float_int_init.zc b/tests/conformance/5-declarations/global_float_int_init.zc new file mode 100644 index 0000000..ac0e187 --- /dev/null +++ b/tests/conformance/5-declarations/global_float_int_init.zc @@ -0,0 +1,9 @@ +// expect: 1/1/1/1/1/ +// spec 5.3.2: an integer constant initializing a float or f32 converts to float, for globals and locals +include rt; +void pn(int x) { rt.put_n(x); rt.put_c(10); } +float g = 2; +f32 h = 1 + 2; +float n = -4; +fn main() { float l = 2; f32 m = 3; pn(g == 2.0); pn(h == 3.0); pn(n == -4.0); pn(l == 2.0); pn(m == 3.0); return 0; } +// zc0: skip |
