Recent

Author Topic: Constructing a constant string  (Read 502 times)

MarkMLl

  • Full Member
  • ***
  • Posts: 132
Constructing a constant string
« on: October 06, 2019, 10:30:26 am »
Apologies if this is an FAQ, but "Free Pascal allows the use of strings as case labels, and in that case the case variable must also be a string.".

While working on something to diagnose rubbish coming from hardware I wrote

     case command of
          'A',
          'a': begin
...
          #$ff + #$00 + #$00 + #$ff + #$00 + #$00 + #$ff + #$00 + #$00: begin

which failed with a type error, while

    const a110=  #$ff + #$00 + #$00 + #$ff + #$00 + #$00 + #$ff + #$00 + #$00:;
...
     case command of
          'A',
          'a': begin
...
          a110:

 worked. How can one construct a string inline with the code which contains non-printing characters but is guaranteed to be evaluated at compilation time?

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

Handoko

  • Hero Member
  • *****
  • Posts: 3152
  • My goal: build my own game engine using Lazarus
Re: Constructing a constant string
« Reply #1 on: October 06, 2019, 10:41:03 am »
Yes, you're right. Your first example does not work, I just tested it on my Lazarus 2.0.4. But at least this below works:

Code: Pascal  [Select]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   a: string;
  4. begin
  5.   a := #$ff + #$00 + #$00 + #$ff + #$00 + #$00 + #$ff + #$00 + #$00;
  6.   case a of
  7.     'a': ;
  8.     'b': ;
  9.     #$ff#$00#$00#$ff#$00#$00#$ff#$00#$00: ShowMessage('This works!');
  10.   end;
  11. end;

Maybe an incomplete feature or bug?

MarkMLl

  • Full Member
  • ***
  • Posts: 132
Re: Constructing a constant string
« Reply #2 on: October 06, 2019, 10:54:48 am »
Thanks, I'd forgotten (or never knew about) that form. Should probably be documented in the "Constant strings" section of the manual.

In practical terms I'm probably going to change my code to not use that, but this was a case where separating the sequence of characters/bytes and the code that was reacting to them detracted a lot from clarity.
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

winni

  • Sr. Member
  • ****
  • Posts: 307
Re: Constructing a constant string
« Reply #3 on: October 06, 2019, 04:55:55 pm »
Hi!

There is another feature (or bug?) about strings as case labels should be mentioned.

If you use a range of strings the labels are only treated as leading substrings.

Example:

// working on function keys

Code: Pascal  [Select]
  1. case idx of
  2. 'F1'..'F9'    : .....
  3. 'F10'..'F12' : ..... // <-- compiler error
  4. end;
  5.  

The compiler moans in the second line of case labels: "Error: duplicate case label"

This means that in the label 'F1' the labels 'F10'..'F12' are contained.

If you know that, it is useful for some reasons like working with dictionaries.

But in the above example you have to do

Code: Pascal  [Select]
  1. case idx of
  2. 'F1', 'F2'..'F9'    : .....
  3. 'F10'..'F12' : ..... // <-- no compiler error
  4. end;
  5.  

Here the F1 is not in a range but a single value and will not be expanded.

Btw: Good to  know is the strange policy from M$ about function keys F13..F24:

In Windows 7 (and Apple) pressing Shift F1..F12 leds to the result F13..F24

In Windows 8 F20..F24 are disabled

In Windows 10 F13..F24 are disabled

Happy coding
Winni

winni

  • Sr. Member
  • ****
  • Posts: 307
Re: Constructing a constant string
« Reply #4 on: October 06, 2019, 05:42:47 pm »
@Thaddy

Despite the documentation: It works fine!

Never confuse theory with practice
Key lesson: never eat the menu card

And about strings as case labels: It is cool and I waited over 20 years for them!

Winni
     

Thaddy

  • Hero Member
  • *****
  • Posts: 8869
Re: Constructing a constant string
« Reply #5 on: October 06, 2019, 05:43:23 pm »
You should report that ( in my hope string case labels go away ) because indeed a "duplicate case label" error is thrown and that is not according to the documentation.
It should not work "sometimes". Both your examples should work.
« Last Edit: October 06, 2019, 05:44:57 pm by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

PascalDragon

  • Hero Member
  • *****
  • Posts: 616
  • Compiler Developer
Re: Constructing a constant string
« Reply #6 on: October 07, 2019, 09:37:02 am »
Thanks, I'd forgotten (or never knew about) that form. Should probably be documented in the "Constant strings" section of the manual.
It is documented as part of the ordinary string syntax.

You should report that ( in my hope string case labels go away ) because indeed a "duplicate case label" error is thrown and that is not according to the documentation.
It should not work "sometimes". Both your examples should work.
I don't know if ranges for strings are even intended to work or if it was forgotten to correctly disable them for case-of-string...

Thaddy

  • Hero Member
  • *****
  • Posts: 8869
Re: Constructing a constant string
« Reply #7 on: October 07, 2019, 09:45:06 am »
I don't know if ranges for strings are even intended to work or if it was forgotten to correctly disable them for case-of-string...
Well, it is documented that ranges work, in some quirky way...
https://freepascal.org/docs-html/ref/refsu56.html

At the bottom.... O:-) ? Maybe that should be removed...
(btw: you made my day last week by fixing the class const thingy!)
« Last Edit: October 07, 2019, 09:47:23 am by Thaddy »
Most people that want to use threading should learn to patch their jeans first: use a needle.

egsuh

  • Full Member
  • ***
  • Posts: 239
Re: Constructing a constant string
« Reply #8 on: October 07, 2019, 10:00:50 am »
Followings are only my guess.

Case statement with strings are different from case statements with ordinal type ... they are just like nested  else if statements.  So the range does not act like with ordinal types. It seems to act just like  (if >= and <=). 

So, in the following case,  'F10' is larger then 'F1' and smaller than 'F9', which caused duplication. 

     case s of
        'F1'..'F9' : // do something;
        'F10'..'F12': // do something
     end;

But,  in the following case, there are no duplication.

     case s of
        'F1', 'F2'..'F9' : // do something;
        'F10'..'F12': // do something
     end;

'F1'..'F9' is not 'F1', 'F2', 'F2', ....

lucamar

  • Hero Member
  • *****
  • Posts: 2012
Re: Constructing a constant string
« Reply #9 on: October 07, 2019, 11:55:40 am »
Case statement with strings are different from case statements with ordinal type ... they are just like nested  else if statements.  So the range does not act like with ordinal types. It seems to act just like  (if >= and <=).

Yes, it's documented in the Reference Guide:

Quote from: Free Pascal Reference Guide
The case with strings is equivalent to a series of if then else statements, no optimizations are performed.

However, ranges are allowed, and are the equivalent of:

Code: Pascal  [Select]
  1. if (value>=beginrange) and (value<=endrange) then  
  2.   begin  
  3.   end;
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

Thaddy

  • Hero Member
  • *****
  • Posts: 8869
Re: Constructing a constant string
« Reply #10 on: October 07, 2019, 11:59:15 am »
That's why I wrote "Quirky".... Anyway that string case syntax still bothers me...
Most people that want to use threading should learn to patch their jeans first: use a needle.

PascalDragon

  • Hero Member
  • *****
  • Posts: 616
  • Compiler Developer
Re: Constructing a constant string
« Reply #11 on: October 08, 2019, 09:08:22 am »
Case statement with strings are different from case statements with ordinal type ... they are just like nested  else if statements.  So the range does not act like with ordinal types. It seems to act just like  (if >= and <=).

Yes, it's documented in the Reference Guide:

Quote from: Free Pascal Reference Guide
The case with strings is equivalent to a series of if then else statements, no optimizations are performed.

However, ranges are allowed, and are the equivalent of:

Code: Pascal  [Select]
  1. if (value>=beginrange) and (value<=endrange) then  
  2.   begin  
  3.   end;
Then the error indeed makes sense. Well, less work more me  :P

MarkMLl

  • Full Member
  • ***
  • Posts: 132
Re: Constructing a constant string
« Reply #12 on: October 08, 2019, 09:25:09 am »
If it makes sense, is it really an error? :-)
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.