Skip to content

renamed FX_FLOAT, FX_FLOAT16 to FX_F16TOF32, FX_F32TOF16. Added fx_bf16, FX_BF16TOF32, FX_F32TOBF16#40

Merged
vpisarev merged 6 commits into
masterfrom
bf16runtime
Jul 11, 2026
Merged

renamed FX_FLOAT, FX_FLOAT16 to FX_F16TOF32, FX_F32TOF16. Added fx_bf16, FX_BF16TOF32, FX_F32TOBF16#40
vpisarev merged 6 commits into
masterfrom
bf16runtime

Conversation

@vpisarev

Copy link
Copy Markdown
Owner

towards adding bf16 type.

vpisarev and others added 6 commits July 11, 2026 22:55
…ine)

The C file writer (PP.pprint_to_string_list) rstripped a line only when the
whole str() chunk ended in '\n', so a multi-line chunk (e.g. an inline @ccode
block) kept trailing whitespace on its interior lines. Split each chunk on
every '\n' and rstrip each completed line instead. Also drop the redundant
final pp.newline() in C_pp.pprint_top_to_string: join_embrace already
terminates the file with a single '\n', so the extra break left a blank last
line.

Net effect: generated C is byte-clean (0/55 bootstrap modules carry trailing
whitespace; files end in exactly one '\n'), which also stops editor
trim-on-save from desyncing the committed bootstrap from the compiler output.
Behavior is unchanged: only PP.c and C_pp.c differ semantically, every other
regenerated module is whitespace/blank-line only. Ladder green, fixpoint holds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fp16 is now the canonical name for the 16-bit float type: the parser accepts
'fp16', and every printer (typ2str, K_form, Ast_pp, K_pp) emits "fp16". The
value-level conversions become fp16(x); Builtins traits/string/print are
retyped to fp16; NN's NN_Data_FP16 payload is fp16 [].

For source compatibility 'half' is kept as a stdlib type alias
(type half = fp16), and fp32/fp64 are added as consistent aliases for
float/double. Being non-builtin type names, all three can be shadowed by a
user's own binding (unlike a builtin) -- an acceptable tradeoff for now.

Done as a two-stage bootstrap (accept both spellings -> regen -> drop 'half'
from the parser -> regen); fixpoint holds, full ladder green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bf16 is a 16-bit float type with an 8-bit exponent (float32 range) and an
8-bit significand. It mirrors fp16 end to end: 16-bit storage, arithmetic
promoted to float32, printing, array element type, scalar coercion.

Representation: bf16 reuses the float-type constructor with the width code 17
(fp16 is the real 16); 17/8 == 2 so the byte size falls out for free, and every
generic `TypFloat _` site treats bf16 as a float automatically. Ast.BF16 = 17
names the code for construction; patterns match the literal 17. The
fp16-specific sites gain a bf16 sibling: parser ("bf16" type name),
typ2str/K_form/Ast_pp/K_pp printers ("bf16"), C_form C type (fx_bf16),
K_mangle ("g"), the float32 value-promotion in K_normalize, the KExpCast
lowering (FX_BF16TOF32 / FX_F32TOBF16, including the fp16<->bf16 cross casts),
klit2str / C_pp literal emission, and the literal-range bounds in typecheck.

Literals: a real float followed by the two-char 'bf' suffix (1.5bf) lexes to
bf16, matching fp16's 'h' suffix; both are handled in LexerUtils.getnumber.

stdlib (Builtins): __is_scalar__, scalar_type (Type_BF16), string, print,
and the bf16(x) scalar/tuple/array conversions.

Rounding is the runtime's fast round-half-up (FX_F32TOBF16, unchanged) --
exact round-to-nearest-even is too slow in software. Constant folding does not
model 16-bit rounding, exactly as for fp16.

test/test_fp16bf16.fx covers literals, arithmetic promotion, per-type rounding
(257 -> 258 for bf16 vs exact for fp16, read through a runtime array to defeat
folding), arrays, inf/nan round-trip, and string(). Ladder green, fixpoint holds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…E.md gotcha

types1_report.md documents the half->fp16 rename, the bf16 twin (TypFloat(17)
representation, sites, 'bf' literal, stdlib, round-half-up decision), and the
trim-clean codegen fix. language_changes §3.4 flipped to IMPLEMENTED with a
snapshot. CLAUDE.md gains a 16-bit-float gotcha (fp16/bf16, h/bf literals,
match 17 not BF16, folding does not round). rrb census (WP-2) lands separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sizes the container reform (§3.5): capability x location map of what RRB
vector has vs Dynvec, LoC per layer (runtime 1255, ~120 compiler wiring, ~85
stdlib), and the reusable runtime primitives. Recommendation skeleton (facts;
decision is Vadim's) flags the load-bearing order and the key asymmetry --
rrb is immutable/persistent, Dynvec is mutable, so a "symmetric" promotion
introduces an in-place write surface rrb never had, which gates the rest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vpisarev vpisarev merged commit 32f1acd into master Jul 11, 2026
3 checks passed
@vpisarev vpisarev deleted the bf16runtime branch July 11, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant