|
@@ -665,6 +665,7 @@ type
|
|
pbifnSet_Union,
|
|
pbifnSet_Union,
|
|
pbifnSpaceLeft,
|
|
pbifnSpaceLeft,
|
|
pbifnStringSetLength,
|
|
pbifnStringSetLength,
|
|
|
|
+ pbifnTrunc, // rtl.trunc
|
|
pbifnUnitInit,
|
|
pbifnUnitInit,
|
|
pbivnExceptObject,
|
|
pbivnExceptObject,
|
|
pbivnIntfExprRefs,
|
|
pbivnIntfExprRefs,
|
|
@@ -830,6 +831,7 @@ const
|
|
'unionSet', // rtl.unionSet +
|
|
'unionSet', // rtl.unionSet +
|
|
'spaceLeft', // rtl.spaceLeft
|
|
'spaceLeft', // rtl.spaceLeft
|
|
'strSetLength', // rtl.strSetLength
|
|
'strSetLength', // rtl.strSetLength
|
|
|
|
+ 'trunc', // pbifnTrunc
|
|
'$init',
|
|
'$init',
|
|
'$e',
|
|
'$e',
|
|
'$ir',
|
|
'$ir',
|
|
@@ -1783,7 +1785,7 @@ type
|
|
// simple JS expressions
|
|
// simple JS expressions
|
|
Function CreateMulNumber(El: TPasElement; JS: TJSElement; n: TMaxPrecInt): TJSElement; virtual;
|
|
Function CreateMulNumber(El: TPasElement; JS: TJSElement; n: TMaxPrecInt): TJSElement; virtual;
|
|
Function CreateDivideNumber(El: TPasElement; JS: TJSElement; n: TMaxPrecInt): TJSElement; virtual;
|
|
Function CreateDivideNumber(El: TPasElement; JS: TJSElement; n: TMaxPrecInt): TJSElement; virtual;
|
|
- Function CreateMathFloor(El: TPasElement; JS: TJSElement): TJSElement; virtual;
|
|
|
|
|
|
+ Function CreateTruncFloor(El: TPasElement; JS: TJSElement; FloorAndCeil: boolean): TJSElement; virtual;
|
|
Function CreateDotNameExpr(PosEl: TPasElement; MExpr: TJSElement;
|
|
Function CreateDotNameExpr(PosEl: TPasElement; MExpr: TJSElement;
|
|
const aName: TJSString): TJSDotMemberExpression; virtual;
|
|
const aName: TJSString): TJSDotMemberExpression; virtual;
|
|
Function CreateDotExpression(aParent: TPasElement; Left, Right: TJSElement;
|
|
Function CreateDotExpression(aParent: TPasElement; Left, Right: TJSElement;
|
|
@@ -7115,8 +7117,8 @@ begin
|
|
case El.OpCode of
|
|
case El.OpCode of
|
|
eopDiv:
|
|
eopDiv:
|
|
begin
|
|
begin
|
|
- // convert "a div b" to "Math.floor(a/b)"
|
|
|
|
- Result:=CreateMathFloor(El,Result);
|
|
|
|
|
|
+ // convert "a div b" to "rtl.trunc(a/b)"
|
|
|
|
+ Result:=CreateTruncFloor(El,Result,true);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -7305,7 +7307,7 @@ begin
|
|
else if El.OpCode=eopShr then
|
|
else if El.OpCode=eopShr then
|
|
begin
|
|
begin
|
|
// BigInt shr const -> Math.floor(A/otherconst)
|
|
// BigInt shr const -> Math.floor(A/otherconst)
|
|
- Result:=CreateMathFloor(El,CreateDivideNumber(El,A,TMaxPrecInt(1) shl BInt));
|
|
|
|
|
|
+ Result:=CreateTruncFloor(El,CreateDivideNumber(El,A,TMaxPrecInt(1) shl BInt),false);
|
|
A:=nil;
|
|
A:=nil;
|
|
FreeAndNil(B);
|
|
FreeAndNil(B);
|
|
exit;
|
|
exit;
|
|
@@ -7379,22 +7381,22 @@ begin
|
|
end;
|
|
end;
|
|
eopDivide:
|
|
eopDivide:
|
|
begin
|
|
begin
|
|
- // currency / currency -> Math.floor((currency/currency)*10000)
|
|
|
|
- // currency / number -> Math.floor(currency/number)
|
|
|
|
- // number / currency -> Math.floor(number/currency)
|
|
|
|
|
|
+ // currency / currency -> rtl.trunc((currency/currency)*10000)
|
|
|
|
+ // currency / number -> rtl.trunc(currency/number)
|
|
|
|
+ // number / currency -> rtl.trunc(number/currency)
|
|
Result:=TJSMultiplicativeExpressionDiv(CreateElement(TJSMultiplicativeExpressionDiv,El));
|
|
Result:=TJSMultiplicativeExpressionDiv(CreateElement(TJSMultiplicativeExpressionDiv,El));
|
|
TJSBinaryExpression(Result).A:=A; A:=nil;
|
|
TJSBinaryExpression(Result).A:=A; A:=nil;
|
|
TJSBinaryExpression(Result).B:=B; B:=nil;
|
|
TJSBinaryExpression(Result).B:=B; B:=nil;
|
|
if (LeftResolved.BaseType=btCurrency) and (RightResolved.BaseType=btCurrency) then
|
|
if (LeftResolved.BaseType=btCurrency) and (RightResolved.BaseType=btCurrency) then
|
|
Result:=CreateMulNumber(El,Result,10000);
|
|
Result:=CreateMulNumber(El,Result,10000);
|
|
- Result:=CreateMathFloor(El,Result);
|
|
|
|
|
|
+ Result:=CreateTruncFloor(El,Result,true);
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
eopPower:
|
|
eopPower:
|
|
begin
|
|
begin
|
|
- // currency^^currency -> Math.floor(Math.pow(currency/10000,currency/10000)*10000)
|
|
|
|
- // currency^^number -> Math.floor(Math.pow(currency/10000,number)*10000)
|
|
|
|
- // number^^currency -> Math.floor(Math.pow(number,currency/10000)*10000)
|
|
|
|
|
|
+ // currency^^currency -> rtl.trunc(Math.pow(currency/10000,currency/10000)*10000)
|
|
|
|
+ // currency^^number -> rtl.trunc(Math.pow(currency/10000,number)*10000)
|
|
|
|
+ // number^^currency -> rtl.trunc(Math.pow(number,currency/10000)*10000)
|
|
if LeftResolved.BaseType=btCurrency then
|
|
if LeftResolved.BaseType=btCurrency then
|
|
A:=CreateDivideNumber(El,A,10000);
|
|
A:=CreateDivideNumber(El,A,10000);
|
|
if RightResolved.BaseType=btCurrency then
|
|
if RightResolved.BaseType=btCurrency then
|
|
@@ -7404,7 +7406,7 @@ begin
|
|
Call.AddArg(A); A:=nil;
|
|
Call.AddArg(A); A:=nil;
|
|
Call.AddArg(B); B:=nil;
|
|
Call.AddArg(B); B:=nil;
|
|
Result:=CreateMulNumber(El,Call,10000);
|
|
Result:=CreateMulNumber(El,Call,10000);
|
|
- Result:=CreateMathFloor(El,Result);
|
|
|
|
|
|
+ Result:=CreateTruncFloor(El,Result,true);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
RaiseNotSupported(El,AContext,20180422104215);
|
|
RaiseNotSupported(El,AContext,20180422104215);
|
|
@@ -8468,8 +8470,8 @@ begin
|
|
if FromBT=btCurrency then
|
|
if FromBT=btCurrency then
|
|
begin
|
|
begin
|
|
if ToBT<>btCurrency then
|
|
if ToBT<>btCurrency then
|
|
- // currency to integer -> Math.floor(value/10000)
|
|
|
|
- Result:=CreateMathFloor(PosEl,CreateDivideNumber(PosEl,Result,10000));
|
|
|
|
|
|
+ // currency to integer -> rtl.trunc(value/10000)
|
|
|
|
+ Result:=CreateTruncFloor(PosEl,CreateDivideNumber(PosEl,Result,10000),true);
|
|
end
|
|
end
|
|
else if ToBT=btCurrency then
|
|
else if ToBT=btCurrency then
|
|
// integer to currency -> value*10000
|
|
// integer to currency -> value*10000
|
|
@@ -10302,13 +10304,13 @@ begin
|
|
begin
|
|
begin
|
|
if JSBaseType=pbtJSValue then
|
|
if JSBaseType=pbtJSValue then
|
|
begin
|
|
begin
|
|
- // convert jsvalue to integer -> Math.floor(value)
|
|
|
|
|
|
+ // convert jsvalue to integer -> rtl.trunc(value)
|
|
Result:=ConvertExpression(Param,AContext);
|
|
Result:=ConvertExpression(Param,AContext);
|
|
// Note: convert Param first in case it raises an exception
|
|
// Note: convert Param first in case it raises an exception
|
|
if to_bt=btCurrency then
|
|
if to_bt=btCurrency then
|
|
- // jsvalue to currency -> Math.floor(value*10000)
|
|
|
|
|
|
+ // jsvalue to currency -> rtl.trunc(value*10000)
|
|
Result:=CreateMulNumber(Param,Result,10000);
|
|
Result:=CreateMulNumber(Param,Result,10000);
|
|
- Result:=CreateMathFloor(El,Result);
|
|
|
|
|
|
+ Result:=CreateTruncFloor(El,Result,true);
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
@@ -11873,7 +11875,7 @@ begin
|
|
if Shift=32 then
|
|
if Shift=32 then
|
|
begin
|
|
begin
|
|
// JS bitwise operations work only 32bit -> use division for bigger shifts
|
|
// JS bitwise operations work only 32bit -> use division for bigger shifts
|
|
- Result:=CreateMathFloor(El,CreateDivideNumber(El,Result,$100000000));
|
|
|
|
|
|
+ Result:=CreateTruncFloor(El,CreateDivideNumber(El,Result,$100000000),false);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
begin
|
|
begin
|
|
@@ -18762,9 +18764,9 @@ begin
|
|
// currency := currency
|
|
// currency := currency
|
|
else if AssignContext.RightResolved.BaseType in btAllJSFloats then
|
|
else if AssignContext.RightResolved.BaseType in btAllJSFloats then
|
|
begin
|
|
begin
|
|
- // currency := double -> currency := Math.floor(double*10000)
|
|
|
|
|
|
+ // currency := double -> currency := rtl.trunc(double*10000)
|
|
AssignContext.RightSide:=CreateMulNumber(El,AssignContext.RightSide,10000);
|
|
AssignContext.RightSide:=CreateMulNumber(El,AssignContext.RightSide,10000);
|
|
- AssignContext.RightSide:=CreateMathFloor(El,AssignContext.RightSide);
|
|
|
|
|
|
+ AssignContext.RightSide:=CreateTruncFloor(El,AssignContext.RightSide,true);
|
|
end
|
|
end
|
|
else if AssignContext.RightResolved.BaseType in btAllJSInteger then
|
|
else if AssignContext.RightResolved.BaseType in btAllJSInteger then
|
|
begin
|
|
begin
|
|
@@ -20845,11 +20847,12 @@ begin
|
|
Mul.B:=CreateLiteralNumber(El,n);
|
|
Mul.B:=CreateLiteralNumber(El,n);
|
|
end;
|
|
end;
|
|
|
|
|
|
-function TPasToJSConverter.CreateMathFloor(El: TPasElement; JS: TJSElement
|
|
|
|
- ): TJSElement;
|
|
|
|
|
|
+function TPasToJSConverter.CreateTruncFloor(El: TPasElement; JS: TJSElement;
|
|
|
|
+ FloorAndCeil: boolean): TJSElement;
|
|
// create Math.floor(JS)
|
|
// create Math.floor(JS)
|
|
var
|
|
var
|
|
Value: TJSValue;
|
|
Value: TJSValue;
|
|
|
|
+ Call: TJSCallExpression;
|
|
begin
|
|
begin
|
|
if JS is TJSLiteral then
|
|
if JS is TJSLiteral then
|
|
begin
|
|
begin
|
|
@@ -20877,18 +20880,24 @@ begin
|
|
exit(JS);
|
|
exit(JS);
|
|
end;
|
|
end;
|
|
jstNumber:
|
|
jstNumber:
|
|
|
|
+ begin
|
|
if IsNan(Value.AsNumber) or IsInfinite(Value.AsNumber) then
|
|
if IsNan(Value.AsNumber) or IsInfinite(Value.AsNumber) then
|
|
- exit(JS)
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- Value.AsNumber:=Trunc(Value.AsNumber);
|
|
|
|
exit(JS);
|
|
exit(JS);
|
|
- end;
|
|
|
|
|
|
+ if FloorAndCeil then
|
|
|
|
+ Value.AsNumber:=Trunc(Value.AsNumber)
|
|
|
|
+ else
|
|
|
|
+ Value.AsNumber:=Floor(Value.AsNumber);
|
|
|
|
+ exit(JS);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
- Result:=CreateCallExpression(El);
|
|
|
|
- TJSCallExpression(Result).Expr:=CreatePrimitiveDotExpr('Math.floor',El);
|
|
|
|
- TJSCallExpression(Result).AddArg(JS);
|
|
|
|
|
|
+ Call:=CreateCallExpression(El);
|
|
|
|
+ Result:=Call;
|
|
|
|
+ if FloorAndCeil then
|
|
|
|
+ Call.Expr:=CreatePrimitiveDotExpr(GetBIName(pbivnRTL)+'.'+GetBIName(pbifnTrunc),El)
|
|
|
|
+ else
|
|
|
|
+ Call.Expr:=CreatePrimitiveDotExpr('Math.floor',El);
|
|
|
|
+ Call.AddArg(JS);
|
|
end;
|
|
end;
|
|
|
|
|
|
function TPasToJSConverter.CreateDotNameExpr(PosEl: TPasElement;
|
|
function TPasToJSConverter.CreateDotNameExpr(PosEl: TPasElement;
|