You are browsing as a guest. Sign up (or log in) to start making projects!

Open comments for this post

3h 38m 25s logged

Devlog: Replacing Flower’s Old Function Syntax with func name(...): type

This feature started out as what I thought would be a straightforward syntax cleanup.

Flower’s old function syntax looked like this:

int add(a: int, b: int):
    return a + b
end

and exported functions looked like this:

prop int test():
    return 1
end

It worked, technically, but it had started to annoy me more. The biggest issue was that function declarations did not visually match the direction Flower was already heading in, and instead felt much more C-like than I wanted.

prop func create(...): Person
func main(): int

This style says “this is a function” up front, gives a clean place for modifiers like prop, and keeps the return type attached to the signature rather than awkwardly leading it.

The goal was simple:

func name(...): type

instead of:

type name(...):

Simple in theory. not so much when the compiler is written in the language being refactored.

The Problem

Flower’s parser assumes top-level function definitions start with a type. Old parser logic was built around that:

int main():

means:

  1. parse a type,
  2. an identifier,
  3. params,
  4. and a body

That assumption was scattered through a few different places:

  • normal function definitions
  • prop function declarations
  • forward declarations
  • examples and docs
  • the compiler’s own source

Now, in retrospect, this was actually one of the easier changes. It didn’t take a whole lot of planning nor brain power, and I was able to change it pretty quickly. Luckily for me, I’ve built codegen to rely purely on ast values rather than shaping.

The New Shape

The new syntax is:

func add(a: int, b: int): int
    return a + b
end

and exported functions now look like:

prop func test(): int
    return 1
end

This is nicer because:

  • func makes declarations immediately recognizable
  • prop composes more cleanly with func
  • return types now live where people expect them to
  • future syntax has more room to grow without feeling backwards

It also feels more in line with Flower’s broader goals: explicit, readable, and not complex.

The Refactor

Previously, parse_func_def looked for a return type first:

type name(...):

Now it expects:

func name(...): type

So the order changed to:

  1. expect func
  2. parse function name
  3. parse parameter list
  4. expect :
  5. parse return type
  6. parse body until end

That part was conceptually easy.

The more annoying part was updating all the places that assumed if it isn’t a var decl and it looks like a func, it’s a func.

That fallback had to go (Good riddance!).

Instead, top-level parsing needed to become more explicit:

  • prop func → exported function
  • func → normal function
  • forward func → forward declaration

The old one worked, but it relied on vague “anything else is probably a function” rules.

The Bootstrap Mistake

At one point, I made a bootstrap build so I could use a Flower_new binary to compile the refactored compiler. Unfortunately, I had made a mistake in parse_forward: advancing before peek checks.

Feel free to check out the bootstrapper to see why this was an issue ;)

This meant my “new compiler to compile the new compiler” was built from a broken parser.

The workaround was cursed, but it worked:

  1. check out the commit before the refactor
  2. fix the bug
  3. compile a new binary
  4. switch to the refactor branch
  5. use the binary to compile the new version

Since the compiled binary was ignored by Git, this was actually fairly simple.

Not the most elegant bootstrap story, but it got the compiler to, well, compile.

2
407

Comments 8

@Rivaan

I be wating For your launch hope that would be success !

@mihaidraghici023

That is really cool. I am building myself a programming language, mine is very slow btw (cus it is natural speaking integrated with AI translation in code based on rules). But building a very fast programming language is really cool. Appreciate your work!!!

@pksmkwe26

It’s an really cool project, an low-level programming language is sure amazing, looking forward to it.

@rishe

the bootstrap mistake is the most cursed thing I’ve read today - using a broken compiler to compile the fix for the broken compiler. somehow it worked though

@IvyMycelia

I know right 😭
I was like there’s no way this works.. but just in case—

@SeradedStripes

Gosh thats a long devlog

@himanshu-singh7

wow

@IvyMycelia

Sorry! Is it too long?