Recent

Author Topic: C# to Pascal  (Read 1945 times)

Dzandaa

  • Sr. Member
  • ****
  • Posts: 393
  • From C# to Lazarus
C# to Pascal
« on: July 18, 2024, 04:47:03 pm »
Hi everybody,

Is it possible to write the equivalent of that C# code in Pascal using Dynamic Array?

with
Code: C  [Select][+][-]
  1. void MyFunc(double[] Data, double[] w)
  2.  

Code: C  [Select][+][-]
  1.  
  2. double [] Data;
  3. double [] w;
  4.  
  5. Data : new double[64];
  6. w: new double[64]
  7. nw := 32
  8. ...
  9. MyFunc(&Data[16], &w[nw - 16]);
  10.  
  11.  

I tried
Code: Pascal  [Select][+][-]
  1. Type
  2.  Darray = Array of Double;
  3. ...
  4. procedure MyFunc(Data: Darray; w: Darray);
  5.  

Code: Pascal  [Select][+][-]
  1.  
  2. Data: Darray;
  3. w: Darray;
  4. nw: Integer;
  5.  
  6. SetLength(Data, 64);
  7. SetLength(w,  63);
  8. nw := 32
  9. ...
  10.  
  11. MyFunc(@Data[16], @w[nw - 16]);
  12.  
  13.  

But it doesn't work.

B->
Regards,
Dzandaa

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11947
  • FPC developer.
Re: C# to Pascal
« Reply #1 on: July 18, 2024, 05:24:21 pm »
Myfunc must be of type pointer, with a separate length, as a pointer has no length, and you must make sure that 16 and nw-16 are valid elements

Code: Pascal  [Select][+][-]
  1. procedure myfunc(data:pdouble;lendata:integer;w:pdouble;lend:integer);
  2.  
  3. MyFunc(@Data[16],length(data)-16+1),@w[nw-16],length(w)-(nw-16)+1));
  4.  

A three parameter slice() could do better maybe, but afaik that doesn't exist.

Dzandaa

  • Sr. Member
  • ****
  • Posts: 393
  • From C# to Lazarus
Re: C# to Pascal
« Reply #2 on: July 18, 2024, 05:38:00 pm »
Hi,
That's what I thought, but I think I'll give it up,
 the translation to Pascal is more than 3000 lines of code
with a lot of functions and procedures, so hours of debugging.

Effectively, I was looking to a solution that doesn't change the number of parameters.

Anyway, thank you.

B->
Regards,
Dzandaa

440bx

  • Hero Member
  • *****
  • Posts: 4749
Re: C# to Pascal
« Reply #3 on: July 18, 2024, 05:41:01 pm »
It's been quite some time since I played with C# but, I don't remember C# supporting some kind of open array.

IOW, as Marcov stated, somehow that C# function must obtain the number of elements present in its array parameters.

As far as implementing something like that in Pascal, here is some code that implements the idea (uses int32 instead of double but, that doesn't make any difference):
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3.  
  4. program _ArraySlices;
  5.  
  6. procedure DoArrays(A, B : array of int32);
  7. var
  8.   i : int32;
  9.  
  10. begin
  11.   for i := low(A) to high(A) do
  12.   begin
  13.     writeln(i);
  14.   end;
  15.  
  16.   writeln('high(B): ', high(B));
  17. end;
  18.  
  19. var
  20.   A1 : array of int32 = (0, 1, 2, 3);
  21.  
  22.   B1 : array of int32 = (5, 6, 7);
  23.  
  24.  
  25. begin
  26.   DoArrays(A1, B1);
  27.  
  28.   readln;
  29. end.

That works fine in Pascal because an open array parameter includes with it the largest index (high(array))

HTH.

ETA:

Forgot to mention, it doesn't work with array slices, that is passing A1[1] is accepted but the compiler doesn't adjust the value of high. 
I don't know if that's a bug or if it's supposed to work that way.

Given that it accepts A1[1] as an array of int32, it probably should be passing an adjusted count.

Maybe one of the FPC developers can shed some light on the situation.


ETA:

Correction: it works fine.
« Last Edit: July 18, 2024, 06:31:18 pm by 440bx »
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5764
  • Compiler Developer
Re: C# to Pascal
« Reply #4 on: July 18, 2024, 09:58:34 pm »
Is it possible to write the equivalent of that C# code in Pascal using Dynamic Array?

with
Code: C  [Select][+][-]
  1. void MyFunc(double[] Data, double[] w)
  2.  

Code: C  [Select][+][-]
  1.  
  2. double [] Data;
  3. double [] w;
  4.  
  5. Data : new double[64];
  6. w: new double[64]
  7. nw := 32
  8. ...
  9. MyFunc(&Data[16], &w[nw - 16]);
  10.  
  11.  

If you use open array parameters instead of dynamic arrays you can use slices:

Code: Pascal  [Select][+][-]
  1. program tslice;
  2.  
  3. procedure MyFunc(Data, w: array of Double);
  4. begin
  5.   Writeln(Length(Data), ' ', Length(w));
  6. end;
  7.  
  8. type
  9.   TDoubleArray = array of Double;
  10.  
  11. var
  12.   Data, w: TDoubleArray;
  13.   nw: LongInt;
  14.  
  15. begin
  16.   SetLength(Data, 64);
  17.   SetLength(w, 63);
  18.   nw := 32;
  19.  
  20.   MyFunc(Data[16..High(Data)], w[nw-16..High(w)]);
  21. end.

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: C# to Pascal
« Reply #5 on: July 19, 2024, 12:46:31 am »
I interpret that a little differently, as for the function call.
Code: Pascal  [Select][+][-]
  1. Procedure MyFunc(Var Data,W:Double);
  2. Begin
  3.  W:= 20;
  4.   //Do something here
  5.   //C# indicated a Reference to an indices  "&"
  6. end;
  7.  
  8. procedure TForm1.Button1Click(Sender: TObject);
  9. var
  10.  Data:Array of Double;
  11. begin
  12. SetLength(Data,10);
  13. Data[0]:= 10;
  14. MyFunc(Data[2],Data[0]);
  15. Caption := Data[0].Tostring;
  16. end;                        
  17.  
  18.  
The only true wisdom is knowing you know nothing

MarkMLl

  • Hero Member
  • *****
  • Posts: 8039
Re: C# to Pascal
« Reply #6 on: July 19, 2024, 10:29:26 pm »
If you use open array parameters instead of dynamic arrays you can use slices:

Very cautiously- since I am potentially diverting the thread- can a slice be used as an lvalue?

xref to https://forum.lazarus.freepascal.org/index.php/topic,67950.msg524250

MarkMLl
« Last Edit: July 19, 2024, 10:47:39 pm by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Dzandaa

  • Sr. Member
  • ****
  • Posts: 393
  • From C# to Lazarus
Re: C# to Pascal
« Reply #7 on: July 20, 2024, 12:16:13 pm »
Hi,

With @PascalDragon idea, here is a modified working code.

Code: Pascal  [Select][+][-]
  1. // ******************************
  2. // ***** Test sub Procedure *****
  3. // ******************************
  4. procedure TFFTDisplayForm.TestProc(var Din: array of Double);
  5. var
  6.  Cnt: Integer;
  7. begin
  8.  for Cnt := 0 to 5 do
  9.   Din[Cnt]:= Din[Cnt]+Cnt;
  10. end;
  11.  
  12. // **************************
  13. // ***** Test Procedure *****
  14. // **************************
  15. procedure BTestSubClick(Sender: TObject);
  16. var
  17.  Din: Darray;
  18.  Cnt, Len: Integer;
  19. begin
  20.  Din := nil;
  21.  Len := 128;
  22.  SetLength(Din, Len);
  23.  for Cnt := 0 to Length(Din) -1 do
  24.   Din[Cnt] := Cnt;
  25.  
  26.  TestProc(Din[5..High(Din)]);
  27.  
  28. end;                                
  29.  
  30.  

Thank you.
Regards,
Dzandaa

PascalDragon

  • Hero Member
  • *****
  • Posts: 5764
  • Compiler Developer
Re: C# to Pascal
« Reply #8 on: July 22, 2024, 11:25:34 pm »
Very cautiously- since I am potentially diverting the thread- can a slice be used as an lvalue?

Yes, but you need to declare the parameter as var or out:

Code: Pascal  [Select][+][-]
  1. program tslice;
  2.  
  3. procedure Test1(aArr: array of LongInt);
  4. var
  5.   i: SizeInt;
  6. begin
  7.   for i := 0 to High(aArr) do
  8.     aArr[i] := 42;
  9. end;
  10.  
  11. procedure Test2(var aArr: array of LongInt);
  12. var
  13.   i: SizeInt;
  14. begin
  15.   for i := 0 to High(aArr) do
  16.     aArr[i] := 21;
  17. end;
  18.  
  19. procedure Print(aArr: array of LongInt);
  20. var
  21.   i: SizeInt;
  22. begin
  23.   for i := 0 to High(aArr) do begin
  24.     Write(aArr[i], ' ');
  25.   end;
  26.   Writeln;
  27. end;
  28.  
  29. var
  30.   arr: array of LongInt;
  31. begin
  32.   SetLength(arr, 10);
  33.   Print(arr);
  34.   Test1(arr[2..4]);
  35.   Print(arr);
  36.   Test2(arr[6..8]);
  37.   Print(arr);
  38. end.

Code: [Select]
PS C:\fpc\git> .\testoutput\tslice.exe
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 21 21 21 0

MarkMLl

  • Hero Member
  • *****
  • Posts: 8039
Re: C# to Pascal
« Reply #9 on: July 23, 2024, 08:32:22 am »
Very cautiously- since I am potentially diverting the thread- can a slice be used as an lvalue?

Yes, but you need to declare the parameter as var or out:

Thanks, got it.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018