PAS2JS: operations with array of record

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

PAS2JS: operations with array of record

Free Pascal - General mailing list

Since it's missing the Pas2JS specific forum, I don't know if here is correct place to post things about "Pas2JS". 

I'm using it a lot and it's very promising. I came across with issue when dealing with array of records.

I would like to convert this little piece of DWScript code to Pas2JS, unfortunately, I couldn't find a way how to push an array of record. For instance:

type 
  JC = record 
     id : integer; external 'id'; 
     name : string; external 'name'; 
     age : integer; external 'age'; 
  end; 

type 
  JB = record 
    field1 : string; external 'field1'; 
    params : Array of JC; external 'params'; 
  end; 

type 
  JA= record 
    fields : array of JB; external 'JA'; 
  end; 

var recA : JA; 
var recB : JB; 
var recC : JC; 


for var k:=0 to 2 do begin 
  recC.id := k; 
  recC.name := 'abc'+IntToStr(k); 
  recC.age := 10+k; 

  recB.field1 := 'rec'+ IntToStr(k); 
  recB.params.Add(recC); 

  recA.fields.Add(recB); 
end; 

Just to referente, the above DWScript code will emit the following JS:

function Copy$JC(s,d) { 
   d.id=s.id; 
   d.name=s.name; 
   d.age=s.age; 
   return d; 
} 
function Clone$JC($) { 
   return { 
      id:$.id, 
      name:$.name, 
      age:$.age 
   } 
} 
/// JB = record 
/// [line: 23, column: 3] 
function Copy$JB(s,d) { 
   d.field1=s.field1; 
   d.params=s.params; 
   return d; 
} 
function Clone$JB($) { 
   return { 
      field1:$.field1, 
      params:$.params 
   } 
} 
/// JA = record 
/// [line: 29, column: 3] 
function Copy$JA(s,d) { 
   d.JA=s.JA; 
   return d; 
} 
function Clone$JA($) { 
   return { 
      JA:$.JA 
   } 
} 
var recA = {JA:[]}; 
var recB = {field1:"",params:[]}; 
var recC = {id:0,name:"",age:0}; 
var k = 0; 

for(k=0;k<=2;k++) { 
  recC.id = k; 
  recC.name = "abc"+k.toString(); 
  recC.age = 10+k; 
  recB.field1 = "rec"+k.toString(); 
  recB.params.push(Clone$JC(recC)); 
  recA.JA.push(Clone$JB(recB)); 
} 

/*
  RecA object
*/

{"JA" : [{ 
        "field1" : "rec0", 
        "params" : [{ 
                "id" : 0, 
                "name" : "abc0", 
                "age" : 10 
            }, { 
                "id" : 1, 
                "name" : "abc1", 
                "age" : 11 
            }, { 
                "id" : 2, 
                "name" : "abc2", 
                "age" : 12 
            } 
        ] 
    }, { 
        "field1" : "rec1", 
        "params" : [{ 
                "id" : 0, 
                "name" : "abc0", 
                "age" : 10 
            }, { 
                "id" : 1, 
                "name" : "abc1", 
                "age" : 11 
            }, { 
                "id" : 2, 
                "name" : "abc2", 
                "age" : 12 
            } 
        ] 
    }, { 
        "field1" : "rec2", 
        "params" : [{ 
                "id" : 0, 
                "name" : "abc0", 
                "age" : 10 
            }, { 
                "id" : 1, 
                "name" : "abc1", 
                "age" : 11 
            }, { 
                "id" : 2, 
                "name" : "abc2", 
                "age" : 12 
            } 
        ] 
    } 
]} 

 I believe it will be nice if PAS2JS could generate similar code, each record type, the DWScript compiler emits corresponding intermediate Clone and Copy functions.

The PAS2JS transpiler uses another approach (the record variable creates a JavaScript object) whereas DWScript with identical functionality using ordinary arrays.

I don't know, I believe it will achieves better performance using ordinary arrays, at least.

Anyway, what I couldn't find is the built-in kind of pseudo-methods for the record data type, set of operations, for inserting, removing, sorting and otherwise manipulate the content, for instance:

In addition to Low, High, Length and Count,  

· Add(item [,...]) / Push(item [,...]) : increases Length by one and adds one or more item at the end of the array, can also add arrays (concatenation).  

· Clear() : empties the array (equivalent to SetLength(0))  

· Copy(startIndex[, count]) : creates a new dynamic array containing count items from startIndex, if count isn't specified, copies to the end of the array.  

· Delete(index[, count]) : deletes the item at the specified index and reduces Length by count (default one).  

· IndexOf([startIndex, ]item) : returns the index of an item, returns a negative value if not found.  

· Insert(index, item) : insert an item at the specified index.  

· Join(delimiter : String) : joins the elements of an array into a string, and returns the string.

· Map([map function]) : creates a new array by mapping elements of the array according to a map function. The map function takes a single parameter of the type of the array items and returns the mapped value.  

· Peek() : returns the last item.  

· Pop() : returns the last item and removes it from the array.  

· Remove([startIndex, ]item) : removes the item if it can be found and returns its previous index, returns a negative value if not found.  

· Reverse() : reverses the order of the items.  

· SetLength(newLength) : defines the length of a dynamic array  

· Sort([compare function]) : sort an array according to the compare function, the comparison function can be omitted for arrays of String, Integer and Float.  

· Swap(index1, index2) : swaps to items of specified indexes.  

just an idea.



Sent from the Free Pascal - General mailing list archive at Nabble.com.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Free Pascal - General mailing list
Am 11.01.2018 08:16 schrieb "warleyalex via fpc-pascal" <[hidden email]>:

Anyway, what I couldn't find is the built-in kind of pseudo-methods for the record data type, set of operations, for inserting, removing, sorting and otherwise manipulate the content, for instance:

Don't you mean "pseudo-methods for the array data type"? 

In addition to Low, High, Length and Count,  

I suppose that the standard Pascal way of using SetLength() is used to add elements. Maybe also the "+" operator (not know if that already got implemented for arrays; in FPC it is still missing for now). Also it could be that Insert(), Delete(), Concat() and Concat()  already support arrays as well in addition to strings (like FPC itself does).

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Michael Van Canneyt


On Thu, 11 Jan 2018, Sven Barth via fpc-pascal wrote:

> Am 11.01.2018 08:16 schrieb "warleyalex via fpc-pascal" <
> [hidden email]>:
>
> Anyway, what I couldn't find is the built-in kind of *pseudo-methods for
> the record data type*, set of operations, for inserting, removing, sorting
> and otherwise manipulate the content, for instance:
>
> Don't you mean "pseudo-methods for the array data type"?
>
> In addition to *Low*, *High*, *Length* and *Count*,
>
> I suppose that the standard Pascal way of using SetLength() is used to add
> elements. Maybe also the "+" operator (not know if that already got
> implemented for arrays; in FPC it is still missing for now). Also it could
> be that Insert(), Delete(), Concat() and Concat()  already support arrays
> as well in addition to strings (like FPC itself does).

Except the SetLength() one, none of these methods is supported yet.

The easiest currently is to do a TJSArray(myarray).push(myelement)

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Free Pascal - General mailing list

Thanks a lot for the feedback.

it worked as expected! The solution was:

/* in DWScript world */
var recA : JA;
    recB : JB;
    recC : JC;

for var k:=0 to 2 do begin
  recC.id := k;
  recC.name := 'abc'+IntToStr(k);
  recC.age := 10+k;
  recB.field1 := 'rec'+ IntToStr(k);
  recB.params.Add(recC);
  recA.fields.Add(recB);
end;


/* in Pas2JS world */
var recA : JA;
    recB : JB;
    recC : JC;
    k:    Integer;
begin
for k:=0 to 2 do begin
  recC.id := k;
  recC.name := 'abc'+IntToStr(k);
  recC.age := 10+k;
  recB.field1 := 'rec'+ IntToStr(k);
  TJSArray(recB.params).push(recC);
  TJSArray(recA.fields).push(recB);
end;

Take a look at this array of record example, in Smart Pascal world, as long as the datatypes match (e.g. field params is a array of record), we have the pseudo methods functionality "built-in" for all arrays, for instance. Pas2JS could have this high level functionality as well. Using the Pas2JS approach with external classes interfaces it looks so powerful :)



Sent from the Free Pascal - General mailing list archive at Nabble.com.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Mattias Gaertner
In reply to this post by Free Pascal - General mailing list
On Thu, 11 Jan 2018 11:44:30 +0100
Sven Barth via fpc-pascal <[hidden email]> wrote:

> Am 11.01.2018 08:16 schrieb "warleyalex via fpc-pascal" <
> [hidden email]>:
>
> Anyway, what I couldn't find is the built-in kind of *pseudo-methods for
> the record data type*, set of operations, for inserting, removing, sorting
> and otherwise manipulate the content, for instance:
>
> Don't you mean "pseudo-methods for the array data type"?
>
> In addition to *Low*, *High*, *Length* and *Count*,
>
> I suppose that the standard Pascal way of using SetLength() is used to add
> elements. Maybe also the "+" operator (not know if that already got
> implemented for arrays; in FPC it is still missing for now). Also it could
> be that Insert(), Delete(), Concat() and Concat()  already support arrays
> as well in addition to strings (like FPC itself does).

From the pas2js docs:
"Supported features of dynamic arrays: SetLength(), Length(),
equal/notequal nil, low(), high(), assigned(), concat(), copy(),
insert(), delete(), multi dimensional, array of record."

https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co#array

The "+' operator is not yet supported.

Mattias

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Michael Van Canneyt
In reply to this post by Free Pascal - General mailing list


On Thu, 11 Jan 2018, warleyalex via fpc-pascal wrote:

> Thanks a lot for the feedback.
> it worked as expected! The solution was:
> /* in DWScript world */var recA : JA;    recB : JB;    recC : JC;for var
> k:=0 to 2 do begin  recC.id := k;  recC.name := 'abc'+IntToStr(k);  recC.age
> := 10+k;  recB.field1 := 'rec'+ IntToStr(k);  recB.params.Add(recC);
> recA.fields.Add(recB);end;/* in Pas2JS world */var recA : JA;    recB : JB;
> recC : JC;    k:    Integer;beginfor k:=0 to 2 do begin  recC.id := k;
> recC.name := 'abc'+IntToStr(k);  recC.age := 10+k;  recB.field1 := 'rec'+
> IntToStr(k);  TJSArray(recB.params).push(recC);
> TJSArray(recA.fields).push(recB);end;
> Take a look at this array of record example, in Smart Pascal world, as long
> as the datatypes match (e.g. field params is a array of record), we have the
> pseudo methods functionality "built-in" for all arrays, for instance. Pas2JS
> could have this high level functionality as well. Using the Pas2JS approach
> with external classes interfaces it looks so powerful :)
> <http://free-pascal-general.1045716.n5.nabble.com/file/t339674/codeinsight.png>

In due course, array methods will be added, to get on par with FPC/Delphi.

But we have no plans to copy smart pascal extensions.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Michael Van Canneyt
In reply to this post by Mattias Gaertner


On Thu, 11 Jan 2018, Mattias Gaertner wrote:

> On Thu, 11 Jan 2018 11:44:30 +0100
> Sven Barth via fpc-pascal <[hidden email]> wrote:
>
>> Am 11.01.2018 08:16 schrieb "warleyalex via fpc-pascal" <
>> [hidden email]>:
>>
>> Anyway, what I couldn't find is the built-in kind of *pseudo-methods for
>> the record data type*, set of operations, for inserting, removing, sorting
>> and otherwise manipulate the content, for instance:
>>
>> Don't you mean "pseudo-methods for the array data type"?
>>
>> In addition to *Low*, *High*, *Length* and *Count*,
>>
>> I suppose that the standard Pascal way of using SetLength() is used to add
>> elements. Maybe also the "+" operator (not know if that already got
>> implemented for arrays; in FPC it is still missing for now). Also it could
>> be that Insert(), Delete(), Concat() and Concat()  already support arrays
>> as well in addition to strings (like FPC itself does).
>
> From the pas2js docs:
> "Supported features of dynamic arrays: SetLength(), Length(),
> equal/notequal nil, low(), high(), assigned(), concat(), copy(),
> insert(), delete(), multi dimensional, array of record."
>
> https://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/utils/pas2js/docs/translation.html?view=co#array

Hm. I should read this document more often :)

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Mattias Gaertner
In reply to this post by Free Pascal - General mailing list
On Wed, 10 Jan 2018 11:40:48 -0700 (MST)
warleyalex via fpc-pascal <[hidden email]> wrote:

> Since it's missing the Pas2JS specific forum, I don't know if here is correct
> place to post things about "Pas2JS".&nbsp;

Hopefully there will be one soon.

 

> I'm using it a lot and it's very promising. I came across with issue when
> dealing with array of records.
>
> I would like to convert this little piece of DWScript code to Pas2JS,
> unfortunately, I couldn't find a way how to push an array of record. For
> instance:
> type
>   JC = record
>      id : integer; external 'id';
>      name : string; external 'name';
>      age : integer; external 'age';
>   end;

Why the 'external' modifiers?

> ...using JS object instead of function for record...
> I believe it will be nice if PAS2JS could generate similar code,

It's on the todo list.


> I don't know,&nbsp;I believe it will achieves better performance using
> ordinary arrays, at least.

And it is useful for many JS functions expecting an enumerable
object.


Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Mattias Gaertner
In reply to this post by Free Pascal - General mailing list
On Wed, 10 Jan 2018 11:40:48 -0700 (MST)
warleyalex via fpc-pascal <[hidden email]> wrote:

>[...]
> · Add(item [,...]) / Push(item [,...]) : increases Length by one and adds one or more item at the end of the array, can also add arrays (concatenation).  
>
> · Clear() : empties the array (equivalent to SetLength(0))  
>
> · Copy(startIndex[, count]) : creates a new dynamic array containing count items from startIndex, if count isn't specified, copies to the end of the array.  
> [...]

There are the usual Pascal array functions, like setlength, copy, insert, delete and concat.

You can also type cast the array to JSArray from unit js, which gives you all the JS functions.

And when eventually type helpers are implemented, functions can be added to Pascal arrays.

Mattias
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: PAS2JS: operations with array of record

Free Pascal - General mailing list
Am 11.01.2018 13:33 schrieb "Mattias Gaertner" <[hidden email]>:
On Wed, 10 Jan 2018 11:40:48 -0700 (MST)
warleyalex via fpc-pascal <[hidden email]> wrote:

>[...]
> · Add(item [,...]) / Push(item [,...]) : increases Length by one and adds one or more item at the end of the array, can also add arrays (concatenation).
>
> · Clear() : empties the array (equivalent to SetLength(0))
>
> · Copy(startIndex[, count]) : creates a new dynamic array containing count items from startIndex, if count isn't specified, copies to the end of the array.
> [...]

There are the usual Pascal array functions, like setlength, copy, insert, delete and concat.

You can also type cast the array to JSArray from unit js, which gives you all the JS functions.

And when eventually type helpers are implemented, functions can be added to Pascal arrays.

The problem with helper types is that you can't add them for all array types at once, but only for a specific one (and even then  - at least in Delphi and FPC - you can't use "array of X", but need to use an explicit array type). 

Especially with the concept of type helpers already existing it makes sense to think about "built in methods" for arrays...

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal