Update fpexprpars lazarus / 64-FPC development ---------------------------------------------------------------------- ASerge · 2025-04-05 08:44 I decided to post here the changes I made in the standard fpexprpars.pp unit. Why here, and not in gitlab? Because admins really don't like units, that have changed so much that it haven't .diff file. Include: fpexprpars2.pp - modified version of fpexprpars.pp. testexprpars2.pp - modified version of testexprpars.pp (unit test). fpexprpars.pp - last version from gitlab. For compare. testexprpars.pp - last version from gitlab. For compare. changes.txt - description of what has changed. GuiTest.lpr - simple project for unit testing. The number two is added to the name to avoid conflict with the existing name, and to be able to try different versions of the module in the same project. In order not to annoy the admins, I left the testexprpars2.pp as similar as possible to the original version. That it 's easy for it to do .the diff file. I rolled back some changes, for example, I returned the comparison of double values as it was - through the implicit conversion of double to currency. And left "uninitialized variables", etc., which do not affect the result. The unit testexprpars2.pp is compatible with the previous fpexprpars.pp version, except that new bugs are fixed in it. New features added via conditional compilation. Some obvious bugs with memory leaks, etc. eliminated. I decided to roll back some features from the fpexprpars2.pp unit as well: Generating an error on numbers like ".E-1", which are considered valid zero by the System.Str function. Advanced type conversion that allows you to perform such operations: sum(1, 2,  '3', True). But added the ability to easily implement it. I ask those who have used this unit in real projects to test it. And also the admins should take a closer look, maybe it's include it in the source code. ---------------------------------------------------------------------- wp · 2025-04-05 08:50 I am afraid that when you don't describe what you changed and why nobody will look at it. And you attachment does not contain all the other files that you mention. ---------------------------------------------------------------------- d2010 · 2025-04-05 09:27 Quote from: ASerge on April 05, 2025, 10:44:46 amAnd left "uninitialized variables", etc., which do not affect the result. And also the admins should take a closer look, maybe it's include it in the source code. Okai You repair Lazarus or fpc, but you forget exists others compilators, (some are weak, the VirtualPascaL or GnuPascal is less FPC.exe)  :(That reason, you cannot RE-fix the LazarusParser. Always I initialize the variabiles at top of function/s, even inside "Lazarus". Some others (Virtual Pascal.exe, DelphiXe Or Gnu Pascal) , report the "nth" is not initialized , so they cannot complier before "FOR nth:=" , I put  "    nth:=000;" at ??? Code: [Select]Function dfn_get_fopencasthosts:integer; Var nth,clen,cid:integer; Begin scho.a:='';       clen:=00;       nth:=000;  ???       result:=01;       cid:=00;       for nth:=010 to casthost do        Begin cid:=stholist[nth];              if (length(AcuiPathName.sth[nth])>4) then                Begin inc(result);                      scho.a:=concat(scho.a,AcuiPathName.sth[nth],#13#10);                End;       End; End; ---------------------------------------------------------------------- cdbc · 2025-04-05 09:29 Hi Hmmm, @wp: I've got all the files he described...  Regards Benny ---------------------------------------------------------------------- wp · 2025-04-05 10:00 Yes, the attachment has been replaced now. I ran a diff between fpexprpars and fpexprpars2, and it is full of differences. So, I stick to my opinion that this submission is useless without any description of the changes. ---------------------------------------------------------------------- ASerge · 2025-04-05 10:05 Quote from: wp on April 05, 2025, 12:00:18 pmYes, the attachment has been replaced now. I ran a diff between fpexprpars and fpexprpars2, and it is full of differences. So, I stick to my opinion that this submission is useless without any description of the changes. See changes.txt. ---------------------------------------------------------------------- ASerge · 2025-04-05 10:07 Quote from: d2010 on April 05, 2025, 11:27:04 amOkai You repair Lazarus or fpc, but you forget exists others compilators, (some are weak, the VirtualPascaL or GnuPascal is less FPC.exe)  :(That reason, you cannot RE-fix the LazarusParser. These are not my mistakes, I left them in the code to make it more similar to the previous version. Did you see how outraged @wp was that there were a lot of changes? ---------------------------------------------------------------------- wp · 2025-04-05 10:31 Sorry, if I gave the impression that I am "outraged" - I am not. I just did not notice "changes.txt". It lists a lot of important changes which should be added from my point of view. But I am sure that unless you split that entire topic into small pieces you will have a hard time in the bug tracker to convince MvC... (BTW: I already had proposed including the formatsettings some time ago, and he rejected it). ---------------------------------------------------------------------- CM630 · 2025-04-07 07:13 From the changes.txt file, I get the impression that it partially solves https://gitlab.com/freepascal.org/fpc/source/-/issues/39351. But still in fpexprpars2.pp there is: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  CNull = #0;  CSingleQuote = '''';  CDoubleQuote = '"';It would be better if CSingleQuote was not a constant, so strings from Excel and other languages could be handled ditrectly. And maybe, some handling of thousands separators (#20; #194#160 etc.) might be useful. EDIT: I tried an app using fpexprpars. The following code compiles and works with fpexprpars, but does not compile with fpexprpars2. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i //Converts a number to binary. Example bin(45) returns %0010 1101; bin($45) returns %0010 1101;...  BuiltinIdentifiers.AddFunction(bcMath, 'bin',   'S', 'I',  @ExprBin);... procedure ExprBin(var Result: TFPExpressionResult; Const Args: TExprParameterArray);var  Argument: Longint;  i: integer;begin  Argument:= Args[0].ResInteger;  Result.ResString := Dec2Numb (Argument,0,2);  if length(Result.ResString) mod 8 <> 0    then Result.ResString := addcha r('0',Result.ResString,8*(trunc(length(Result.ResString)/8)+1));   for i:= 1 to trunc(Length(Result.ResString) / 4)-1 do    Insert (' ',Result.ResString,i*4+i);   Result.ResString := '%' + Result.ResString;end; (...Error: Can't take the address of constant expressions on line 17) ---------------------------------------------------------------------- ASerge · 2025-04-08 01:28 Quote from: CM630 on April 07, 2025, 09:13:09 am(...Error: Can't take the address of constant expressions on line 17) For safety ResString now a property, not a field. As for the thousands separator, RTL does not process it yet either: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DefaultFormatSettings.ThousandSeparator := '#';if TryStrToFloat('1#000', D) then  Writeln(D:0:0)else  Writeln('Bad number'); print "Bad number". You're right about the quotation marks. It's not difficult to make global variables instead of constants. The same applies to other separators. Just have to add code that checks when parsing expressions that they don't match each other. ---------------------------------------------------------------------- CM630 · 2025-04-08 06:30 Quote from: ASerge on April 08, 2025, 03:28:52 amFor safety ResString now a property, not a field. Definitely a good intention, but how many projects might be broken (I have updated the quoted code, now it works both with fpexprpars and fpexprpars2)? A couple of weeks ago, I was surprised to find out that it was me who reported a bug that fpexprpars does not handle division on zero, which maybe means that the component is not widely used, so no big harm could happen with that change. Quote from: ASerge on April 08, 2025, 03:28:52 amAs for the thousands separator, RTL does not process it yet either: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DefaultFormatSettings.ThousandSeparator := '#';if TryStrToFloat('1#000', D) then  Writeln(D:0:0)else  Writeln('Bad number'); print "Bad number". Maybe this is not handleable. SI strictly prohibits separators different than a space (which I believe does not exclude #194#160 and other spaces), but it occurs that even outside USA unbelievable characters are used for thousand separators. Quote from: ASerge on April 08, 2025, 03:28:52 amYou're right about the quotation marks. It's not difficult to make global variables instead of constants. The same applies to other separators. Just have to add code that checks when parsing expressions that they don't match each other. Recently, I tried to fix the fixed separator issue. I got stuck when I came to Single and Double quoutation marks. Double quotes are not documented; maybe their handling could be disabled if they are set to an empty string? Otherwise the user shall set it to character, that will never occur, maybe something < 0x20. EDIT: I do not understand how GExprParserFormatSettings is to be used. It is not a property but a variable ---------------------------------------------------------------------- ASerge · 2025-04-08 19:18 Quote from: CM630 on April 08, 2025, 08:30:44 amI do not understand how GExprParserFormatSettings is to be used. It is not a property but a variable Did you read changes.txt? ---------------------------------------------------------------------- CM630 · 2025-04-09 08:16 Quote from: ASerge on April 08, 2025, 09:18:43 pmDid you read changes.txt? That is the first thing I  did. Still I do not get the idea: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, fpexprpars2; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);  private   public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);  var  FParser1: TFPExpressionParser;  FParser2: TFPExpressionParser;  resultValue: Double;begin  FParser1 := TFPExpressionParser.Create(nil);  try    FParser1.BuiltIns := [bcMath];    GExprParserFormatSettings.ListSeparator := ';';    GExprParserFormatSettings.DecimalSeparator := ',';    FParser1.Expression := '1,5*2';    resultValue := FParser1.Evaluate.ResFloat;    ShowMessage(FParser1.Expression + ' = ' + FloatToStr(resultValue));  finally    FParser1.Free;  end;   FParser2 := TFPExpressionParser.Create(nil);  try    FParser2.BuiltIns := [bcMath];    FParser2.Expression := '1.5*2'; //This is not accepted, the parser still expects 1,5    resultValue := FParser2.Evaluate.ResFloat;    ShowMessage(FParser2.Expression + ' = ' + FloatToStr(resultValue));  finally    FParser2.Free;  end;end;  end.    GExprParserFormatSettings is global, if I have 5 instances of TFPExpressionParser, I have to set GExprParserFormatSettings before each FParser.Expression := xxx and still I am not sure that things will not get messed up. Am I missing something? ---------------------------------------------------------------------- ASerge · 2025-04-09 16:07 Quote from: CM630 on April 09, 2025, 10:16:34 amAm I missing something? Yes, that's right. This is done to simplify things. All intermediate classes, built-in functions, etc. use a single variable. If link between instances of classes to get to the parent one containing such a variable, many functions will be overgrown with parameters or additional functions. Even now, in a simplified form, admins do not want to use innovations, because there are a lot of them. And if all classes are overgrown with additional parameters, then compatibility will disappear. Then it will definitely be buried. New changes can be made after the accepting of the simplified version. ---------------------------------------------------------------------- PascalDragon · 2025-04-10 19:05 Quote from: ASerge on April 09, 2025, 06:07:12 pmNew changes can be made after the accepting of the simplified version. Unless you can split this up into smaller, incremental changes that can be reviewed there will be no “accepting”. ---------------------------------------------------------------------- valdir.marcos · 2026-03-09 03:52 Quote from: ASerge on April 05, 2025, 10:44:46 amI decided to post here the changes I made in the standard fpexprpars.pp unit. Why here, and not in gitlab? Because admins really don't like units, that have changed so much that it haven't .diff file. Quote from: PascalDragon on April 10, 2025, 09:05:31 pmQuote from: ASerge on April 09, 2025, 06:07:12 pmNew changes can be made after the accepting of the simplified version.Unless you can split this up into smaller, incremental changes that can be reviewed there will be no “accepting”. @ASerge I understand your needs and respect your effort in building a solution. Thinking individually, your effort may be useful to you and some of us. Unfortunately, thinking collectively, as @PascalDragon has already pointed out, your effort will not be accepted into the FPC project. That said, you can make even more effort to adapt yourself to the strange way the FPC project works, or simply move on like the absolute majority does.