[Pas2js] My 1st type helper
warleyalex
warleyalex at yahoo.com.br
Mon Mar 4 00:51:53 CET 2019
Ref: Pas2JS Compiler version 1.4.0RC4 [2019/03/03] for Win32 i386
==================================================
Test I:
==================================================
type
float = double;
type
TFloatHelper = type helper for Float
const NPI = 3.141592;
function ToStr: String;
end;
function TFloatHelper.ToStr: String;
begin
Result:= FloatToStr(Self);
end;
(...)
var
ReturnValue : Float;
begin
ReturnValue := 2.71;
ReturnValue:= (ReturnValue * Float.NPI);
console.log(ReturnValue.ToStr); //8.51371432 it works for me.
a) but we can't use it straightforward like
// console.log((ReturnValue * ReturnValue.NPI).ToStr); //8.51371432
==================================================
Test II:
==================================================
type
TMyClass = class
procedure MyProc;
function MyFunc: Integer;
end;
type
TMyClassHelper = class helper for TMyClass
procedure HelloWorld;
function MyFunc: Integer;
end;
implementation
procedure TMyClass.MyProc;
var
X: Integer;
begin
X := MyFunc;
end;
function TMyClass.MyFunc: Integer;
begin
WriteLn('TMyClass.MyFunc called');
end;
procedure TMyClassHelper.HelloWorld;
begin
Writeln(Self.ClassName); // Self refers to TMyClass type, not
TMyClassHelper
end;
function TMyClassHelper.MyFunc: Integer;
begin
// inherited;
WriteLn('TMyClassHelper.MyFunc called');
end;
(...)
var
X: TMyClass;
begin
X := TMyClass.Create;
X.MyProc; // Calls TMyClass.MyProc
X.HelloWorld; // Calls TMyClassHelper.HelloWorld
X.MyFunc; // Calls TMyClassHelper.MyFunc
----------------------------------
the console output is:
(*
TMyClassHelper.MyFunc called
TMyClass
TMyClassHelper.MyFunc called
*)
a) if I declare the method "MyFunc" with the keyword "inherited"
function TMyClassHelper.MyFunc: Integer;
begin
inherited;
WriteLn('TMyClassHelper.MyFunc called');
end;
the console is:
(*
TMyClass.MyFunc called
TMyClassHelper.MyFunc called
TMyClass
TMyClass.MyFunc called
TMyClassHelper.MyFunc called
*)
b) I would like to call TMyClass.MyProc method, but there's an active helper
with the method MyProc.
X := TMyClass.Create;
X.MyProc; // Calls TMyClass.MyProc
Hum, this is correct! it will show the console "TMyClassHelper.MyFunc
called" instead of "TMyClass.MyProc called" just because the class helper
takes precedence over the actual class type.
==================================================
Test III: class helper how old are you?
==================================================
{ TPessoa class }
type
TPessoa = class
private
FDataNasc: TDateTime;
public
property DataNasc: TDateTime read FDataNasc write FDataNasc;
end;
TPessoaHelper = class helper for TPessoa
private
function GetIdade: integer;
public
property Idade: integer read GetIdade;
end;
TIntHelper = type helper for Integer
public
function ToStr: String;
end;
implementation
{YearsBetween function}
function SpanOfNowAndThen(const ANow, AThen: Float): Float;
begin
if ANow < AThen then
Result := AThen - ANow
else
Result := ANow - AThen;
end;
function DaySpan(const ANow, AThen: Float): Float;
begin
Result := SpanOfNowAndThen(ANow, AThen);
end;
function YearSpan(const ANow, AThen: Float): Float;
begin
Result := DaySpan(ANow, AThen) / 365.25;
end;
function YearsBetween(const ANow, AThen: Float): Integer;
begin
Result := Trunc(YearSpan(ANow, AThen));
end;
{ TPessoaHelper }
function TPessoaHelper.GetIdade: integer;
begin
Result := YearsBetween(Self.DataNasc, Now);
end;
{ TIntHelper }
function TIntHelper.ToStr: String;
begin
Result := IntToStr(Self);
end;
(...)
oPessoa := TPessoa.Create;
try
oPessoa.DataNasc := EncodeDate(1986, 11, 26);
console.log(
(oPessoa.Idade).ToStr + ' years'
);
finally
oPessoa.Free;
end;
a) that we are using ToStr function instead of IntToStr. I see the console
"32 years", which is the expected! Today - BirthDate = 32
==================================================
Test IV: Multiple class helper (multihelpers) are supported
==================================================
We add 2 more helpers in the Test III:
TPessoaFisicaHelper = class helper (TPessoaHelper) for TPessoa
public
function isValidCPF():Boolean;
end;
TPessoaJuridicaHelper = class helper (TPessoaFisicaHelper) for TPessoa
public
function isValidCNPJ():Boolean;
end;
implementation
{ TPessoaFisicaHelper }
function TPessoaFisicaHelper.isValidCPF(): Boolean;
begin
WriteLn('CPF is valid');
end;
{ TPessoaJuridicaHelper }
function TPessoaJuridicaHelper.isValidCNPJ(): Boolean;
begin
WriteLn('CNPJ is valid');
end;
(...)
oPessoa := TPessoa.Create;
try
oPessoa.DataNasc := EncodeDate(1986, 11, 26);
console.log(
(oPessoa.Idade).ToStr + ' years'
);
txt := (oPessoa.Idade).ToStr;
console.log(txt);
oPessoa.isValidCPF;
oPessoa.isValidCNPJ;
finally
oPessoa.Free;
end;
we have the expected console:
(*
32 years
32
CPF is valid
CNPJ is valid
*)
We can not use the following syntax, when defining TPessoaFisicaHelper
helper, for instance:
TPessoaFisicaHelper = class helper for TPessoa
I'm getting this msg:
Error: identifier not found "Idade"
to disappear this error, we have to define this way:
TPessoaFisicaHelper = class helper (TPessoaHelper) for TPessoa
and
TPessoaJuridicaHelper = class helper (TPessoaFisicaHelper) for TPessoa
That is, MORE THAN ONE class helper for a given class may be in scope at any
time. For instance, if you have two helpers in scope, ALL OF THEM will be
recognised by the compiler.
==================================================
Test V: Helpers on functions pointers are not supported.
==================================================
type
TFunc = function: Integer;
{ TIntegerHelper }
TIntegerHelper = type helper (TIntHelper) for Integer
function ToString : String;
end;
implementation
{ TIntegerHelper }
function TIntegerHelper.ToString: String;
begin
Result := IntToStr(Self);
end;
(*
{ TFuncHelper }
function TFuncHelper.ToString: String;
begin
Result := IntToStr(Self);
end;
*)
We can not define a helper like this:
{ TFuncHelper }
(*
TFuncHelper = type helper for TFunc // this is not allowed
function ToString : String;
end;
*)
You've got this msg:
Error: Type "TFunc" cannot be extended by a type helper.
so Helper on function pointer are not supported.
(...)
function twenty: Integer;
begin
Result := 20;
end;
var
f: TFunc;
begin
f:= @twenty;
console.log(
f.ToString
);
the console is "20". Correct!
if we comment this line f:= @twenty;
Uncaught TypeError: $mod.f is not a function // this is correct.
==================================================
Test VI
==================================================
type
Vec2 = array [0..1] of Float;
type
TVec2Helper = type helper for Vec2
function Add(const v: Vec2): Vec2; overload;
function Add(const f: Float): Vec2; overload;
end;
implementation
{ TVec2Helper }
function TVec2Helper.Add(const v : Vec2): Vec2;
begin
Result:=[Self[0]+v[0], Self[1]+v[1]];
end;
function TVec2Helper.Add(const f : Float): Vec2;
begin
Result:=[Self[0]+f, Self[1]+f];
end;
(...)
var
v1: Vec2 = (1, 2);
v2: Vec2 = (10, 20);
v: array of Float;
begin
v1 := [1, 2];
v2 := [10, 20];
//v := v1 + v2; // Error: Operator is not overloaded: "Unit3.Vec2"
+ "Unit3.Vec2"
v:=[v1[0]+v2[0], v1[1]+v2[1]];
WriteLn(v[0]); // 11
WriteLn(v[1]); // 22
In this test, I'd like to test helper methods with operator overloading, but
it's not supported yet.
==================================================
==================================================
Test VII - helper class to TJSObject
==================================================
{ TJSValueHelper }
TJSValueHelper = type helper for TJSObject
public
function valid(ref: JSValue): boolean; assembler;
end;
var
this: TJSObject; external name 'this';
implementation
{ TJSValueHelper }
function TJSValueHelper.valid(ref: JSValue): boolean; assembler;
asm
return !( (ref == undefined) || (ref == null) );
end;
(...)
var
dt : TDateTime;
begin
dt := TDateTime(now);
if this.valid(dt) then
console.log(DateTimetoStr(dt)) else // 2019-03-03 18:16:49
dt := 0;
console.log(dt);
I think this very useful function! and it works for me.
**Note: I think we have a bug here at "dt: TDateTime" initialization!
for instance: If I comment
//dt := TDateTime(now);
if this.valid(dt) then
console.log(DateTimetoStr(dt)) else
//dt := 0;
console.log(dt);
the console outputs "1899-12-30" - I think the correct is "0"
==================================================
Test VIII - helper for array of record
==================================================
type
TFunction = function: TJSPromise;
type
TModelClassRegistration = record
TableName: string;
CreateFunc: TFunction;
end;
type
TModelClassRegistrations = array of TModelClassRegistration;
{ TTestHelper }
TTestHelper = type helper for TModelClassRegistrations
procedure Add(rec: TModelClassRegistration);
end;
implementation
{ TTestHelper }
procedure TTestHelper.Add(rec: TModelClassRegistration);
begin
TJSArray(Self).push(rec);
end;
(...)
function CreateServer: TJSPromise;
begin
result:=
TJSPromise.New(
procedure (resolve, reject: TJSPromiseResolver)
begin
console.log('test');
end);
end;
var
rec: TModelClassRegistration;
RegisteredModelClasses: TModelClassRegistrations;
i: integer;
begin
rec.TableName := 'devil_report';
rec.CreateFunc := @CreateServer;
RegisteredModelClasses.Add(rec);
rec.TableName:= 'flowers_report';
rec.CreateFunc := @CreateServer;
RegisteredModelClasses.Add(rec);
rec.TableName := 'cards_report';
rec.CreateFunc := @CreateServer;
RegisteredModelClasses.Add(rec);
for i:= Low(RegisteredModelClasses) to High(RegisteredModelClasses) do
console.log(RegisteredModelClasses[i])
We have the expected object output.
--------------------------------------------------------------------------------
regards,
warleyalex
--
Sent from: http://pas2js.38893.n8.nabble.com/
More information about the Pas2js
mailing list