Recent

Author Topic: FPC Unleashed (inline vars, statement expr, tuples, match, indexed/lazy labels)  (Read 35431 times)

Okoba

  • Hero Member
  • *****
  • Posts: 659
@Fibonacci what a fantastic work! A lot of interesting work, thank you!
This mode is working based on objfpc, and to me it is better than Delphi mode in almost all cases except generic. Generics with generic and specialized keywords make the code too long and hard to read, especially if you are writing a lot of generic code. Can we have a modeswitch that removes their need while staying in objfpc mode?

ccrause

  • Hero Member
  • *****
  • Posts: 1117
Extending the existing number syntax pattern to a string literal without creating yet another syntax or type cast overload can simply be achieved by defining a suitable (as in uniquely identifiable and descriptive) prefix that is recognized by the parser/tokenizer. Once it is tokenized the fun is over, it is just a number.

Potential example using the arbitrary prefix ! (only because it is not an existing special character):
Code: [Select]
const x = !'abcd';

In the spirit of this discussion, here is a branch that implements the above syntax for specifying a string literal as a number. This branch accepts a new special character as delimiter for a new numerical prefix (!). To fully implement the feature required updating Val() to decode the new format, since the compiler itself uses Val to decode patterns from the parser.

This allows specifying a number as a delimited string anywhere in code (where a literal number would make sense).
Code: Pascal  [Select][+][-]
  1. const
  2.   x = !'MZ';
  3.  
  4. var
  5.   y: word = !'A';
  6.  
  7. begin
  8.   if x > !'QQ' then
  9.  

Not saying ! is an intuitive delimiter. Also note that endian issues are at play when storing the number (this is different to the requested functionality of "string as byte array").

The feature is already implemented in Unleashed and works everywhere - const, var, typed const, inline vars, and even without any variable at all:
- writeln(DWORD('abcd'))
- writeln(DWORD(#0#0'a'#0))
- if WORD('xy')>0 then
- if WORD('x'#0)>0 then
etc.

The disassembly confirms it's a plain immediate value, not a pointer or a function call. No RTL/Val() changes were needed either. What's wrong with the current implementation? Or do you just really want that ! prefix?

I consider this one done.
I was merely scratching my own itch. No-one needs to pay any attention to this experiment, it was more about alternative syntax than solving a specific problem.  At least I corrected some of my assumptions of how the compiler works internally.

Fibonacci

  • Hero Member
  • *****
  • Posts: 949
  • Behold, I bring salvation - FPC Unleashed
@Fibonacci what a fantastic work! A lot of interesting work, thank you!
This mode is working based on objfpc, and to me it is better than Delphi mode in almost all cases except generic. Generics with generic and specialized keywords make the code too long and hard to read, especially if you are writing a lot of generic code. Can we have a modeswitch that removes their need while staying in objfpc mode?

Thanks, glad you like it :)

Doable, sure. As far as I can see, the shorter generic syntax is currently gated on mode delphi (no modeswitch for it). Adding a modeswitch so it works in mode objfpc / unleashed is definitely possible.

The question is whether to enable it by default in mode unleashed. I'd like to hear other opinions before deciding.
FPC Unleashed - inline vars, tuples, statement expressions, array equality, compound assignments, indexed/lazy labels, no-RTTI & more. ⭐ Star it on GitHub!

Okoba

  • Hero Member
  • *****
  • Posts: 659
@Fibonacci nice to hear. That is a yes from me, you already added a lot of things that are more Delphi mode alike. Altough I suggest adding a modeswitch and activing it by default, so people can deactive it. That is my suggestion for many of your changes. For example a team that dont like inline vars can disable it by that switch. In my personal opinion modeswitches are very good tool to give developers option, and mode must be built as a official template based on modeswitches.

Just to use your kindness, what do you think about removing useless warns about not initialized records even when they have Initialize operator? Here is a link to the case: https://forum.lazarus.freepascal.org/index.php/topic,73286.msg574549.html#msg574549

BTW your update on warn for WITH block for shadow is a really useful.

Thaddy

  • Hero Member
  • *****
  • Posts: 19156
  • Glad to be alive.
I currently (today) have some build problems. Is that due to new commits?
Which revision should I build? I tend to build everything I see, so it might be solved already.
objects are fine constructs. You can even initialize them with constructors.

Fibonacci

  • Hero Member
  • *****
  • Posts: 949
  • Behold, I bring salvation - FPC Unleashed
I currently (today) have some build problems. Is that due to new commits?
Which revision should I build? I tend to build everything I see, so it might be solved already.

Unleashed? Details please. There is only one version - main.
FPC Unleashed - inline vars, tuples, statement expressions, array equality, compound assignments, indexed/lazy labels, no-RTTI & more. ⭐ Star it on GitHub!

Thaddy

  • Hero Member
  • *****
  • Posts: 19156
  • Glad to be alive.
No I mean of course the git entry, maybe a few commits back. Anyway I'll try again today.
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6488
@Fibonacci,

You mentioned you are using A.I to assist you with FPC Unleashed.  If I may ask, what A.I model are you using ?  Claude Code by any chance ?

Any and all information you can provide is appreciated.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Fibonacci

  • Hero Member
  • *****
  • Posts: 949
  • Behold, I bring salvation - FPC Unleashed
@Fibonacci,

You mentioned you are using A.I to assist you with FPC Unleashed.  If I may ask, what A.I model are you using ?  Claude Code by any chance ?

Any and all information you can provide is appreciated.

I use an AI tool my employer provides. The agreement is clear: I can use it for personal projects (including this fork), but I'm not allowed to share access or disclose any details about the AI.

They obviously don't have their own model - they wrap something in the backend. I actually know what's behind it, but the NDA prevents me from sharing and I intend to honor it O:-) Especially since every conversation with the AI is logged - they almost certainly know I'm working on FPC, know about this forum, know who I am on it, and can easily verify whether I've leaked details. So I'm closing this topic here and not going back to it.



Outside of that I also pay for Claude Pro and ChatGPT Plus (Codex). I pay for them precisely because I don't want my employer knowing "everything" I do, so I split my work across different AIs. Claude is the better coder, but hits limits fast - I tried using it for FPC and burned the 5-hour limit in about 10 minutes, then burned the entire weekly limit in a single day. FPC is apparently too big a project and eats too many tokens, while Claude's limits are fairly low. From what I've read, even at Pro pricing they're still subsidizing heavy users - you pay for Pro, and they're not making money, they're topping it up. I suspect prices will go up significantly and limits will tighten soon enough. Step 1 - get developers hooked on AI. Step 2 - raise prices / cut limits :D Codex keeps going longer and handles more, but quality is a step below. ChatGPT also handles image generation, which Claude can't do.
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: 6488
Thank you @Fibonacci for all that information.

My experience with Claude parallels yours.  It really is a nice tool but, it consumes tokens like kids eat candy resulting in inevitable unwanted cavities ;)

The very few other models I've tried have shown performance that is noticeably inferior to Claude's to the point that I'm not sure they would actually be an improvement over not having their assistance (at least as far as design and coding goes but, maybe I should give other models another try.)

Again, thank you.  That is useful information and, it's nice to know that I'm not the only one experiencing Claude "withdrawals".
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

JCLRQ

  • Newbie
  • Posts: 3
On using AI for FPC project including Lazarus, I have been using the following:

- sketch a skeleton from discussion with Copilot while on the go (incl. abonnement family)
- Set up a local AI tool: Ollama + Hermes agent + Qwen 3.6 + discussion through Telegram : to refine the framework while I was having a lunch break at home.
- Back at home:
    - use AntiGravity credits (Gemini Pro abonnement): Prepare agent, skills and documentation with Claude Opus > Sonnet > Gemini Pro
    - use Gemini flash for simple thinking task. Debugging
    - use GPT 5.3 codex for heavy lifting coding. It passes where Gemini flash and Pro fails.
- Now I am at a stage where I mostly do the manual adjustement in Antigravity with either of the AI agents

NB: I tried VS code but could not figure out using my GPT API without Github copilot. I stop using any local AI at this point as it is too complex to them.

440bx

  • Hero Member
  • *****
  • Posts: 6488
feature request:

Add the compound operator "not in" and allow "in" and "not in" to test for a value being in or not in a range ("borrowed" from SQL.)  Note that this is for range testing, not set membership testing.

This addition would allow the following examples to be valid:
Code: Pascal  [Select][+][-]
  1. type
  2.    TRange     = 10_000..10_100;
  3.    Percentage = 0..100;
  4.    CharSet    = set of char;
  5.  
  6. const
  7.    Letters : CharSet = ['a'..'z', 'A'..'Z'];
  8.  
  9. var
  10.    i   : integer = 10_050;
  11.    pct : integer = 75;
  12.    ch  : char    = 'a';
  13.  
  14. begin
  15.    // Range membership — inline
  16.    if i in 10_000..10_100 then
  17.       write('in range');
  18.  
  19.    if i not in 10_000..10_100 then
  20.       write('out of range');
  21.  
  22.    // Range membership — named type
  23.    if i in TRange then
  24.       write('in range');
  25.  
  26.    if i not in TRange then
  27.       write('out of range');
  28.  
  29.    // Percentage check
  30.    if pct in Percentage then
  31.       write('valid percentage');
  32.  
  33.    if pct not in Percentage then
  34.       halt(1);
  35.  
  36.    // Set membership — existing behaviour unchanged
  37.    if ch in Letters then
  38.       write('letter');
  39.  
  40.   // it would also be nice to allow "not in" for sets.  This should not cause any _new_ problems.
  41.    if ch not in Letters then
  42.       write('not a letter');
  43.  
  44.    // Negated forms are symmetric
  45.    if i in 1..100 then
  46.       write('small');
  47.  
  48.    if i not in 1..100 then
  49.       write('not small');
  50. end
  51.  
Caution:set membership is a different thing than range inclusion testing.  The following compiles but does not operate as expected:
Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.   int         : integer = 10000;
  4.  
  5. begin
  6.   if int in [10000..10100] then ;
  7.  
whereas:
Code: Pascal  [Select][+][-]
  1.  
  2. var
  3.   int         : integer = 10000;
  4.  
  5. begin
  6.   if int in 10000..10100 then ;  // note the use of a range not set membership
  7.  
this should work as expected (once and if the grammar has been extended to accept this form)
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

creaothceann

  • Sr. Member
  • ****
  • Posts: 361
Instead of

Code: Pascal  [Select][+][-]
  1. if x not in ...

why not just this:

Code: Pascal  [Select][+][-]
  1. if not (x in ...)

Thaddy

  • Hero Member
  • *****
  • Posts: 19156
  • Glad to be alive.
Why not expand it to if x > y < z and family. If you test for ranges, this is probably the same code.
objects are fine constructs. You can even initialize them with constructors.

440bx

  • Hero Member
  • *****
  • Posts: 6488
Instead of

Code: Pascal  [Select][+][-]
  1. if x not in ...

why not just this:

Code: Pascal  [Select][+][-]
  1. if not (x in ...)
Only because one reads more naturally than the other.  That's all.  Just nicer.

For the same reason I wouldn't be in favor of @Thaddy's suggestion.
FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018