Devlog: Giving Flower an Internal cstr Foundation
Even after Flower got a real string type, the compiler itself was still leaning directly on C-style string helpers for its own internal work.
That meant a lot of Flower source was still semantically depending on libc behavior:
!strncmp(...)
strcmp(...)
strlen(...)
strcpy(...)
strncpy(...)
strdup(...)
strrchr(...)
That is not where I want the language to stay.
What changed
I added a new internal module:
import "src/stdlib/cstr.flo" as cstr
and gave it compiler-facing helpers like:
prop func len(s: @char): int
prop func eq(a: @char, b: @char): bool
prop func eq_n(a: @char, b: @char, n: int): bool
prop func copy(dst: @char, src: @char): @char
prop func copy_n(dst: @char, src: @char, n: int): @char
prop func dup(src: @char): @char
prop func find_last(src: @char, ch: char): @char
This helper module is essentially the precursor to a future strings.flo library that can be distributed. But for now, it uses a basic API layer purely meant for in-house usage.
Then I migrated compiler internals over to that module across:
src/parser.flosrc/module.flosrc/lexer.flosrc/typecheck.flosrc/codegen.flosrc/globals.flosrc/main.flo
So instead of using C-string behavior directly everywhere, the compiler now goes through Flower-owned helpers first.
The Compiler Strikes Back
This was one of those changes that sounds mechanical until it absolutely is not.
A big trap was that old code often relied on C comparison functions returning 0 on equality, so patterns looked like this:
not strncmp(...)
But cstr.eq_n(...) returns an actual bool, which means blindly rewriting those calls gives inverted logic.
So this:
if ps.alias_lengths[i] == tok.length and not cstr.eq_n(...):
was completely wrong. It had to become:
if ps.alias_lengths[i] == tok.length and cstr.eq_n(...):
That bug showed up in alias parsing first, which made it especially cursed, because it caused normal namespace-style calls like cstr.eq(...) to stop parsing correctly and crash the bootstrap path in confusing ways. I spent way longer than I wish to admit on trying to figure out why it wasn’t playing nice. But, once I figured it out, it was a really quick fix (I literally just cmd + f’d not cstr and replaced it with cstr lol).
Are we done yet..?
This does not mean Flower is free from the C backend yet.
It does mean something important, though: compiler logic is starting to depend on Flower-defined helper semantics instead of scattered raw libc calls. That is a much better stage for the future backend story, because when C eventually stops being the primary lowering target, the compiler will already have more of its own vocabulary.
In other words, this was less about “remove C” and more about “stop letting C define the language’s internal habits.” Nah just kidding, I really wanted that bloated “builtin_c_call” stuff gone. Unfortunately I only managed to skim it, but that’s closer than before!
Result
After fixing the migration mistakes and the alias/parser fallout, the compiler bootstrapped successfully again.
Flower now has an internal cstr layer, and compiler string handling is a little more its own.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.