Recent

Author Topic: [ANN] Fibo Code Format (FCF) - Pascal formatter with Unleashed support  (Read 327 times)

Fibonacci

  • Hero Member
  • *****
  • Posts: 1000
  • Behold, I bring salvation - FPC Unleashed
Fibo Code Format (FCF) - Pascal formatter with Unleashed support

A code formatter for Free Pascal that handles both stock FPC and the FPC Unleashed dialect (a fork adding inline vars, tuples, match, expression-if/case/try, defer / autofree, compound assignments, composable records, ...). Runs in your browser via WASM - your code never leaves your machine.

Try it here: https://fibo.gg/codeformat/

It is plain FPC under the hood

What runs in the browser is the same program compiled to WebAssembly - the source is 100% {$mode objfpc}, no Unleashed features in its own code, no dependencies beyond the FPC RTL. The exact same source compiles to a native EXE / ELF binary, or can be wrapped as a Lazarus .lpk package and dropped into the IDE as a built-in formatting tool.

It carries its own parser and CST (concrete syntax tree) builder, with no FPC compiler internals reused. The output is reconstructed by walking that tree, which is what keeps the result consistent regardless of how the input was laid out, and what makes adding a new dialect (like Unleashed) a matter of extending the grammar rather than patching tokens.

Web-only for now

I am not publishing the source yet. What is available is the compiled WASM and a hosted web version that runs it. The plan is to stay web-only until the bug list is cleaned out and the output is in good shape on real-world code; after that, sources go up.

The web channel also lets me iterate fast without anyone having to rebuild anything locally. If you find an input that the formatter mangles, please drop the smallest reproducer in this thread (with the option values you used if you changed any defaults) - those reports are the most useful thing right now.

Coming next
  • Wider fixture coverage - real projects pushed through and curated into the regression suite.
  • Theme toggle (light / dark). The site is dark-only today; a proper switch is on the way.
  • Customizable syntax colors. Tweak the highlight palette live in the browser.
  • Export to Lazarus XML. Save the customised palette as an XML file you can drop straight into Lazarus's settings folder. Editing syntax colours directly inside the IDE today is painful - this should make it bearable.
  • Import existing Lazarus XML. Pull your existing colour scheme in, tweak it in the web UI, export it back. Full round-trip.

Feedback, bug reports, and edge cases that break formatting are all welcome.
FPC Unleashed - inline vars, tuples, statement expressions, array equality, compound assignments, indexed/lazy labels, no-RTTI & more. ⭐ Star it on GitHub!

440bx

  • Hero Member
  • *****
  • Posts: 6532
It carries its own parser and CST (concrete syntax tree) builder, with no FPC compiler internals reused.
I just want to make sure I understand what that means correctly, does that mean you reversed engineered FPC's grammar wrote your own scanner and parser for it ?
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1000
  • Behold, I bring salvation - FPC Unleashed
It carries its own parser and CST (concrete syntax tree) builder, with no FPC compiler internals reused.
I just want to make sure I understand what that means correctly, does that mean you reversed engineered FPC's grammar wrote your own scanner and parser for it ?

Yes, custom scanner and parser, written from scratch. The pipeline is: input -> tokenizer -> CST -> emitter -> output. The emitter rebuilds the code from the tree using the config, preserving a few source-layout signals through trivia (blank lines between decls, tuple-row array literals, multi-line enums). For a given (input, config) pair the output is deterministic, and the formatter is idempotent - re-running it on its own output produces the same bytes.

"Reverse engineering" is a bit too strong though - the grammar is taken from the FPC language reference, with packages/fcl-passrc and the compiler sources used as a sanity check whenever the docs left ambiguities (generics < vs comparison, tuple vs paren, as / is, error recovery shape, etc.). The parser is scoped to what the formatter needs - some structural bodies are tracked at depth-level rather than fully decomposed per field/method, but the CST stays lossless on round-trip. The CST node hierarchy was designed independently of either - it has to carry trivia and comments losslessly, which fcl-passrc's AST doesn't.

For Unleashed I am tracking fpc-unleashed/freepascal directly and extending the parser as features land there.
FPC Unleashed - inline vars, tuples, statement expressions, array equality, compound assignments, indexed/lazy labels, no-RTTI & more. ⭐ Star it on GitHub!

440bx

  • Hero Member
  • *****
  • Posts: 6532
"Reverse engineering" is a bit too strong though
Yes but, it still is a fair amount of work because there are a good number of areas in the FPC grammar that are not as unambiguously specified as they should be.

Now, the question that comes to mind is, do you have a full EBNF grammar annotated with semantic rules to enable the accurate generation of a scanner and parser ?  if your answer is yes, that would be a rather desirable spec and code to have ;)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Fibonacci

  • Hero Member
  • *****
  • Posts: 1000
  • Behold, I bring salvation - FPC Unleashed
Now, the question that comes to mind is, do you have a full EBNF grammar annotated with semantic rules to enable the accurate generation of a scanner and parser ?  if your answer is yes, that would be a rather desirable spec and code to have ;)

Not in the form you're describing. There is no standalone EBNF spec - the parser is hand-written recursive descent, and the grammar lives in the parsing code and the CST node hierarchy.

The CST is built only as far as the formatter actually needs: token kinds, structural boundaries, expression precedence, and enough context to disambiguate the awkward bits (generics < vs comparison, tuple vs parenthesised expression, as / is in expression context, etc.). Anything beyond that - type checking, symbol resolution, overload disambiguation, generic specialisation - is deliberately out of scope. A formatter doesn't need to know that the LHS of := is assignable, only that := is at this position in this kind of statement. So the "semantic rules annotation" you're asking about is mostly absent by design - what's there is the minimum the formatter needs, not a full language semantics.
FPC Unleashed - inline vars, tuples, statement expressions, array equality, compound assignments, indexed/lazy labels, no-RTTI & more. ⭐ Star it on GitHub!

440bx

  • Hero Member
  • *****
  • Posts: 6532
Thank you @Fibonacci.  I agree that a code formatter doesn't need all the information a full fledged parser generates but, I figured I'd ask to which extent you took the parser.

Thanks again... still very useful. :)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018