mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-18 02:59:28 +02:00
pastojs: typecast char to word
git-svn-id: trunk@41062 -
This commit is contained in:
parent
c7bb028d35
commit
1a59a4a4a3
@ -272,6 +272,7 @@ begin
|
||||
// conversion magic
|
||||
SetCodePage(RawByteString(Result), CP_ACP, False);
|
||||
end;
|
||||
{$endif}
|
||||
|
||||
function QuoteJSString(const S: TJSString; Quote: TJSChar): TJSString;
|
||||
var
|
||||
@ -302,8 +303,6 @@ begin
|
||||
Result := Result + Quote;
|
||||
end;
|
||||
|
||||
{$endif}
|
||||
|
||||
{ TBufferWriter }
|
||||
|
||||
function TBufferWriter.GetBufferLength: Integer;
|
||||
|
@ -1803,6 +1803,9 @@ type
|
||||
Function ConvertArrayValues(El: TArrayValues; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertInheritedExpr(El: TInheritedExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertNilExpr(El: TNilExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertCharToInt(Arg: TJSElement; PosEl: TPasElement; ArgContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertIntToInt(Arg: TJSElement; FromBT, ToBT: TResolverBaseType; PosEl: TPasElement; ArgContext: TConvertContext): TJSElement; virtual;
|
||||
Function CreateBitWiseAnd(El: TPasElement; Value: TJSElement; const Mask: TMaxPrecInt; Shift: integer): TJSElement; virtual;
|
||||
Function ConvertParamsExpr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertArrayParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertFuncParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
@ -7753,6 +7756,132 @@ begin
|
||||
Result:=CreateLiteralNull(El);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertCharToInt(Arg: TJSElement;
|
||||
PosEl: TPasElement; ArgContext: TConvertContext): TJSElement;
|
||||
begin
|
||||
if (Arg is TJSLiteral) and (TJSLiteral(Arg).Value.ValueType=jstString) then
|
||||
begin
|
||||
// convert char literal to int
|
||||
ConvertCharLiteralToInt(TJSLiteral(Arg),PosEl,ArgContext);
|
||||
Result:=Arg;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// convert char to int -> Arg.charCodeAt(0)
|
||||
Result:=CreateCallCharCodeAt(Arg,0,PosEl);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertIntToInt(Arg: TJSElement; FromBT,
|
||||
ToBT: TResolverBaseType; PosEl: TPasElement; ArgContext: TConvertContext
|
||||
): TJSElement;
|
||||
var
|
||||
aResolver: TPas2JSResolver;
|
||||
MinVal, MaxVal: TMaxPrecInt;
|
||||
Call: TJSCallExpression;
|
||||
ShiftEx: TJSURShiftExpression;
|
||||
begin
|
||||
Result:=Arg;
|
||||
aResolver:=ArgContext.Resolver;
|
||||
if FromBT=btCurrency then
|
||||
begin
|
||||
if ToBT<>btCurrency then
|
||||
// currency to integer -> Math.floor(value/10000)
|
||||
Result:=CreateMathFloor(PosEl,CreateDivideNumber(PosEl,Result,10000));
|
||||
end
|
||||
else if ToBT=btCurrency then
|
||||
// integer to currency -> value*10000
|
||||
Result:=CreateMulNumber(PosEl,Result,10000);
|
||||
if (ToBT<>btIntDouble) and not (Result is TJSLiteral) then
|
||||
begin
|
||||
if bsRangeChecks in ArgContext.ScannerBoolSwitches then
|
||||
begin
|
||||
// rtl.rc(param,MinInt,MaxInt)
|
||||
if not aResolver.GetIntegerRange(ToBT,MinVal,MaxVal) then
|
||||
RaiseNotSupported(PosEl,ArgContext,20180425131839);
|
||||
Call:=CreateCallExpression(PosEl);
|
||||
Call.Expr:=CreatePrimitiveDotExpr(GetBIName(pbivnRTL)+'.'+GetBIName(pbifnRangeCheckInt),PosEl);
|
||||
Call.AddArg(Result);
|
||||
Result:=Call;
|
||||
Call.AddArg(CreateLiteralNumber(PosEl,MinVal));
|
||||
Call.AddArg(CreateLiteralNumber(PosEl,MaxVal));
|
||||
end
|
||||
else
|
||||
case ToBT of
|
||||
btByte:
|
||||
// value to byte -> value & 255
|
||||
if FromBT<>btByte then
|
||||
Result:=CreateBitWiseAnd(PosEl,Result,255,0);
|
||||
btShortInt:
|
||||
// value to shortint -> value & 255 << 24 >> 24
|
||||
if FromBT<>btShortInt then
|
||||
Result:=CreateBitWiseAnd(PosEl,Result,255,24);
|
||||
btWord:
|
||||
// value to word -> value & 65535
|
||||
if not (FromBT in [btByte,btWord]) then
|
||||
Result:=CreateBitWiseAnd(PosEl,Result,65535,0);
|
||||
btSmallInt:
|
||||
// value to smallint -> value & 65535 << 16 >> 16
|
||||
if not (FromBT in [btShortInt,btSmallInt]) then
|
||||
Result:=CreateBitWiseAnd(PosEl,Result,65535,16);
|
||||
btLongWord:
|
||||
// value to longword -> value >>> 0
|
||||
if not (FromBT in [btByte,btWord,btLongWord,btUIntSingle]) then
|
||||
begin
|
||||
ShiftEx:=TJSURShiftExpression(CreateElement(TJSURShiftExpression,PosEl));
|
||||
ShiftEx.A:=Result;
|
||||
ShiftEx.B:=CreateLiteralNumber(PosEl,0);
|
||||
Result:=ShiftEx;
|
||||
end;
|
||||
btLongint:
|
||||
// value to longint -> value & 0xffffffff
|
||||
if not (FromBT in [btShortInt,btSmallInt,btLongint,btIntSingle]) then
|
||||
Result:=CreateBitWiseAnd(PosEl,Result,$ffffffff,0);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.CreateBitWiseAnd(El: TPasElement; Value: TJSElement;
|
||||
const Mask: TMaxPrecInt; Shift: integer): TJSElement;
|
||||
// if sign=false: Value & Mask
|
||||
// if sign=true: Value & Mask << ZeroBits >> ZeroBits
|
||||
var
|
||||
AndEx: TJSBitwiseAndExpression;
|
||||
Hex: String;
|
||||
i: Integer;
|
||||
ShiftEx: TJSShiftExpression;
|
||||
begin
|
||||
AndEx:=TJSBitwiseAndExpression(CreateElement(TJSBitwiseAndExpression,El));
|
||||
Result:=AndEx;
|
||||
AndEx.A:=Value;
|
||||
AndEx.B:=CreateLiteralNumber(El,Mask);
|
||||
if Mask>999999 then
|
||||
begin
|
||||
Hex:=HexStr(Mask,8);
|
||||
i:=1;
|
||||
while i<8 do
|
||||
if Hex[i]='0' then
|
||||
inc(i)
|
||||
else
|
||||
break;
|
||||
Hex:=Copy(Hex,i,8);
|
||||
TJSLiteral(AndEx.B).Value.CustomValue:=TJSString('0x'+Hex);
|
||||
end;
|
||||
if Shift>0 then
|
||||
begin
|
||||
// value << ZeroBits
|
||||
ShiftEx:=TJSLShiftExpression(CreateElement(TJSLShiftExpression,El));
|
||||
ShiftEx.A:=Result;
|
||||
Result:=ShiftEx;
|
||||
ShiftEx.B:=CreateLiteralNumber(El,Shift);
|
||||
// value << ZeroBits >> ZeroBits
|
||||
ShiftEx:=TJSRShiftExpression(CreateElement(TJSRShiftExpression,El));
|
||||
ShiftEx.A:=Result;
|
||||
Result:=ShiftEx;
|
||||
ShiftEx.B:=CreateLiteralNumber(El,Shift);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertInheritedExpr(El: TInheritedExpr;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
|
||||
@ -7967,7 +8096,7 @@ var
|
||||
begin
|
||||
Result:=ConvertExpression(Param,ArgContext);
|
||||
NeedMinus1:=true;
|
||||
if (Result is TJSLiteral) then
|
||||
if Result is TJSLiteral then
|
||||
begin
|
||||
JSVal:=TJSLiteral(Result).Value;
|
||||
if (JSVal.ValueType=jstNumber) then
|
||||
@ -8107,20 +8236,6 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ConvCharToInt(var Arg: TJSElement; Param: TPasElement);
|
||||
begin
|
||||
if (Arg is TJSLiteral) and (TJSLiteral(Arg).Value.ValueType=jstString) then
|
||||
begin
|
||||
// convert char literal to int
|
||||
ConvertCharLiteralToInt(TJSLiteral(Arg),Param,ArgContext);
|
||||
end
|
||||
else
|
||||
begin
|
||||
// convert char to int -> Arg.charCodeAt(0)
|
||||
Arg:=CreateCallCharCodeAt(Arg,0,Param);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ConvertArray(ArrayEl: TPasArrayType);
|
||||
var
|
||||
BracketEx, Sub: TJSBracketMemberExpression;
|
||||
@ -8232,7 +8347,7 @@ var
|
||||
end
|
||||
else
|
||||
Int:=ord(TResEvalString(LowRg).S[1]);
|
||||
ConvCharToInt(Arg,Param);
|
||||
Arg:=ConvertCharToInt(Arg,Param,ArgContext);
|
||||
end;
|
||||
{$ENDIF}
|
||||
revkUnicodeString:
|
||||
@ -8241,7 +8356,7 @@ var
|
||||
ArgContext.Resolver.RaiseXExpectedButYFound(20170910213247,'char','string',Param)
|
||||
else
|
||||
Int:=ord(TResEvalUTF16(LowRg).S[1]);
|
||||
ConvCharToInt(Arg,Param);
|
||||
Arg:=ConvertCharToInt(Arg,Param,ArgContext);
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(Param,ArgContext,20170910170446);
|
||||
@ -9459,46 +9574,6 @@ var
|
||||
JSBaseType:=JSBaseTypeData.JSBaseType;
|
||||
end;
|
||||
|
||||
function CreateBitWiseAnd(Value: TJSElement; const Mask: TMaxPrecInt; Shift: integer): TJSElement;
|
||||
// if sign=false: Value & Mask
|
||||
// if sign=true: Value & Mask << ZeroBits >> ZeroBits
|
||||
var
|
||||
AndEx: TJSBitwiseAndExpression;
|
||||
Hex: String;
|
||||
i: Integer;
|
||||
ShiftEx: TJSShiftExpression;
|
||||
begin
|
||||
AndEx:=TJSBitwiseAndExpression(CreateElement(TJSBitwiseAndExpression,El));
|
||||
Result:=AndEx;
|
||||
AndEx.A:=Value;
|
||||
AndEx.B:=CreateLiteralNumber(El,Mask);
|
||||
if Mask>999999 then
|
||||
begin
|
||||
Hex:=HexStr(Mask,8);
|
||||
i:=1;
|
||||
while i<8 do
|
||||
if Hex[i]='0' then
|
||||
inc(i)
|
||||
else
|
||||
break;
|
||||
Hex:=Copy(Hex,i,8);
|
||||
TJSLiteral(AndEx.B).Value.CustomValue:=TJSString('0x'+Hex);
|
||||
end;
|
||||
if Shift>0 then
|
||||
begin
|
||||
// value << ZeroBits
|
||||
ShiftEx:=TJSLShiftExpression(CreateElement(TJSLShiftExpression,El));
|
||||
ShiftEx.A:=Result;
|
||||
Result:=ShiftEx;
|
||||
ShiftEx.B:=CreateLiteralNumber(El,Shift);
|
||||
// value << ZeroBits >> ZeroBits
|
||||
ShiftEx:=TJSRShiftExpression(CreateElement(TJSRShiftExpression,El));
|
||||
ShiftEx.A:=Result;
|
||||
Result:=ShiftEx;
|
||||
ShiftEx.B:=CreateLiteralNumber(El,Shift);
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
NotEqual: TJSEqualityExpressionNE;
|
||||
CondExpr: TJSConditionalExpression;
|
||||
@ -9507,9 +9582,8 @@ var
|
||||
AddExpr: TJSAdditiveExpressionPlus;
|
||||
TypeEl: TPasType;
|
||||
C: TClass;
|
||||
Int, MinVal, MaxVal: TMaxPrecInt;
|
||||
Int: TMaxPrecInt;
|
||||
aResolver: TPas2JSResolver;
|
||||
ShiftEx: TJSURShiftExpression;
|
||||
begin
|
||||
Result:=nil;
|
||||
Param:=El.Params[0];
|
||||
@ -9525,62 +9599,7 @@ begin
|
||||
begin
|
||||
// integer to integer -> value
|
||||
Result:=ConvertExpression(Param,AContext);
|
||||
if ParamResolved.BaseType=btCurrency then
|
||||
begin
|
||||
if to_bt<>btCurrency then
|
||||
// currency to integer -> Math.floor(value/10000)
|
||||
Result:=CreateMathFloor(Param,CreateDivideNumber(Param,Result,10000));
|
||||
end
|
||||
else if to_bt=btCurrency then
|
||||
// integer to currency -> value*10000
|
||||
Result:=CreateMulNumber(Param,Result,10000);
|
||||
if (to_bt<>btIntDouble) and not (Result is TJSLiteral) then
|
||||
begin
|
||||
if bsRangeChecks in AContext.ScannerBoolSwitches then
|
||||
begin
|
||||
// rtl.rc(param,MinInt,MaxInt)
|
||||
if not aResolver.GetIntegerRange(to_bt,MinVal,MaxVal) then
|
||||
RaiseNotSupported(Param,AContext,20180425131839);
|
||||
Call:=CreateCallExpression(El);
|
||||
Call.Expr:=CreatePrimitiveDotExpr(GetBIName(pbivnRTL)+'.'+GetBIName(pbifnRangeCheckInt),El);
|
||||
Call.AddArg(Result);
|
||||
Result:=Call;
|
||||
Call.AddArg(CreateLiteralNumber(El,MinVal));
|
||||
Call.AddArg(CreateLiteralNumber(El,MaxVal));
|
||||
end
|
||||
else
|
||||
case to_bt of
|
||||
btByte:
|
||||
// value to byte -> value & 255
|
||||
if ParamResolved.BaseType<>btByte then
|
||||
Result:=CreateBitWiseAnd(Result,255,0);
|
||||
btShortInt:
|
||||
// value to shortint -> value & 255 << 24 >> 24
|
||||
if ParamResolved.BaseType<>btShortInt then
|
||||
Result:=CreateBitWiseAnd(Result,255,24);
|
||||
btWord:
|
||||
// value to word -> value & 65535
|
||||
if not (ParamResolved.BaseType in [btByte,btWord]) then
|
||||
Result:=CreateBitWiseAnd(Result,65535,0);
|
||||
btSmallInt:
|
||||
// value to smallint -> value & 65535 << 16 >> 16
|
||||
if not (ParamResolved.BaseType in [btShortInt,btSmallInt]) then
|
||||
Result:=CreateBitWiseAnd(Result,65535,16);
|
||||
btLongWord:
|
||||
// value to longword -> value >>> 0
|
||||
if not (ParamResolved.BaseType in [btByte,btWord,btLongWord,btUIntSingle]) then
|
||||
begin
|
||||
ShiftEx:=TJSURShiftExpression(CreateElement(TJSURShiftExpression,El));
|
||||
ShiftEx.A:=Result;
|
||||
ShiftEx.B:=CreateLiteralNumber(El,0);
|
||||
Result:=ShiftEx;
|
||||
end;
|
||||
btLongint:
|
||||
// value to longint -> value & 0xffffffff
|
||||
if not (ParamResolved.BaseType in [btShortInt,btSmallInt,btLongint,btIntSingle]) then
|
||||
Result:=CreateBitWiseAnd(Result,$ffffffff,0);
|
||||
end;
|
||||
end;
|
||||
Result:=ConvertIntToInt(Result,ParamResolved.BaseType,to_bt,El,AContext);
|
||||
exit;
|
||||
end
|
||||
else if ParamResolved.BaseType in btAllJSBooleans then
|
||||
@ -9598,6 +9617,14 @@ begin
|
||||
Result:=CondExpr;
|
||||
exit;
|
||||
end
|
||||
else if ParamResolved.BaseType in btAllJSChars then
|
||||
begin
|
||||
// char to integer
|
||||
Result:=ConvertExpression(Param,AContext);
|
||||
Result:=ConvertCharToInt(Result,El,AContext);
|
||||
Result:=ConvertIntToInt(Result,btWord,to_bt,El,AContext);
|
||||
exit;
|
||||
end
|
||||
else if ParamResolved.BaseType=btContext then
|
||||
begin
|
||||
if ParamResolved.LoTypeEl.ClassType=TPasEnumType then
|
||||
|
@ -6431,6 +6431,9 @@ begin
|
||||
' c:=succ(c);',
|
||||
' c:=low(c);',
|
||||
' c:=high(c);',
|
||||
' i:=byte(c);',
|
||||
' i:=word(c);',
|
||||
' i:=longint(c);',
|
||||
'']);
|
||||
ConvertProgram;
|
||||
CheckSource('TestChar_BuiltInProcs',
|
||||
@ -6447,6 +6450,9 @@ begin
|
||||
'$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
|
||||
'$mod.c = "\x00";',
|
||||
'$mod.c = "\uFFFF";',
|
||||
'$mod.i = $mod.c.charCodeAt() & 255;',
|
||||
'$mod.i = $mod.c.charCodeAt();',
|
||||
'$mod.i = $mod.c.charCodeAt() & 0xFFFFFFFF;',
|
||||
'']));
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user