mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 09:26:15 +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
|
// conversion magic
|
||||||
SetCodePage(RawByteString(Result), CP_ACP, False);
|
SetCodePage(RawByteString(Result), CP_ACP, False);
|
||||||
end;
|
end;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
function QuoteJSString(const S: TJSString; Quote: TJSChar): TJSString;
|
function QuoteJSString(const S: TJSString; Quote: TJSChar): TJSString;
|
||||||
var
|
var
|
||||||
@ -302,8 +303,6 @@ begin
|
|||||||
Result := Result + Quote;
|
Result := Result + Quote;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$endif}
|
|
||||||
|
|
||||||
{ TBufferWriter }
|
{ TBufferWriter }
|
||||||
|
|
||||||
function TBufferWriter.GetBufferLength: Integer;
|
function TBufferWriter.GetBufferLength: Integer;
|
||||||
|
@ -1803,6 +1803,9 @@ type
|
|||||||
Function ConvertArrayValues(El: TArrayValues; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertArrayValues(El: TArrayValues; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertInheritedExpr(El: TInheritedExpr; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertInheritedExpr(El: TInheritedExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertNilExpr(El: TNilExpr; 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 ConvertParamsExpr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertArrayParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertArrayParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function ConvertFuncParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
Function ConvertFuncParams(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||||
@ -7753,6 +7756,132 @@ begin
|
|||||||
Result:=CreateLiteralNull(El);
|
Result:=CreateLiteralNull(El);
|
||||||
end;
|
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;
|
function TPasToJSConverter.ConvertInheritedExpr(El: TInheritedExpr;
|
||||||
AContext: TConvertContext): TJSElement;
|
AContext: TConvertContext): TJSElement;
|
||||||
|
|
||||||
@ -7967,7 +8096,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Result:=ConvertExpression(Param,ArgContext);
|
Result:=ConvertExpression(Param,ArgContext);
|
||||||
NeedMinus1:=true;
|
NeedMinus1:=true;
|
||||||
if (Result is TJSLiteral) then
|
if Result is TJSLiteral then
|
||||||
begin
|
begin
|
||||||
JSVal:=TJSLiteral(Result).Value;
|
JSVal:=TJSLiteral(Result).Value;
|
||||||
if (JSVal.ValueType=jstNumber) then
|
if (JSVal.ValueType=jstNumber) then
|
||||||
@ -8107,20 +8236,6 @@ var
|
|||||||
end;
|
end;
|
||||||
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);
|
procedure ConvertArray(ArrayEl: TPasArrayType);
|
||||||
var
|
var
|
||||||
BracketEx, Sub: TJSBracketMemberExpression;
|
BracketEx, Sub: TJSBracketMemberExpression;
|
||||||
@ -8232,7 +8347,7 @@ var
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
Int:=ord(TResEvalString(LowRg).S[1]);
|
Int:=ord(TResEvalString(LowRg).S[1]);
|
||||||
ConvCharToInt(Arg,Param);
|
Arg:=ConvertCharToInt(Arg,Param,ArgContext);
|
||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
revkUnicodeString:
|
revkUnicodeString:
|
||||||
@ -8241,7 +8356,7 @@ var
|
|||||||
ArgContext.Resolver.RaiseXExpectedButYFound(20170910213247,'char','string',Param)
|
ArgContext.Resolver.RaiseXExpectedButYFound(20170910213247,'char','string',Param)
|
||||||
else
|
else
|
||||||
Int:=ord(TResEvalUTF16(LowRg).S[1]);
|
Int:=ord(TResEvalUTF16(LowRg).S[1]);
|
||||||
ConvCharToInt(Arg,Param);
|
Arg:=ConvertCharToInt(Arg,Param,ArgContext);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
RaiseNotSupported(Param,ArgContext,20170910170446);
|
RaiseNotSupported(Param,ArgContext,20170910170446);
|
||||||
@ -9459,46 +9574,6 @@ var
|
|||||||
JSBaseType:=JSBaseTypeData.JSBaseType;
|
JSBaseType:=JSBaseTypeData.JSBaseType;
|
||||||
end;
|
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
|
var
|
||||||
NotEqual: TJSEqualityExpressionNE;
|
NotEqual: TJSEqualityExpressionNE;
|
||||||
CondExpr: TJSConditionalExpression;
|
CondExpr: TJSConditionalExpression;
|
||||||
@ -9507,9 +9582,8 @@ var
|
|||||||
AddExpr: TJSAdditiveExpressionPlus;
|
AddExpr: TJSAdditiveExpressionPlus;
|
||||||
TypeEl: TPasType;
|
TypeEl: TPasType;
|
||||||
C: TClass;
|
C: TClass;
|
||||||
Int, MinVal, MaxVal: TMaxPrecInt;
|
Int: TMaxPrecInt;
|
||||||
aResolver: TPas2JSResolver;
|
aResolver: TPas2JSResolver;
|
||||||
ShiftEx: TJSURShiftExpression;
|
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
Param:=El.Params[0];
|
Param:=El.Params[0];
|
||||||
@ -9525,62 +9599,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
// integer to integer -> value
|
// integer to integer -> value
|
||||||
Result:=ConvertExpression(Param,AContext);
|
Result:=ConvertExpression(Param,AContext);
|
||||||
if ParamResolved.BaseType=btCurrency then
|
Result:=ConvertIntToInt(Result,ParamResolved.BaseType,to_bt,El,AContext);
|
||||||
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;
|
|
||||||
exit;
|
exit;
|
||||||
end
|
end
|
||||||
else if ParamResolved.BaseType in btAllJSBooleans then
|
else if ParamResolved.BaseType in btAllJSBooleans then
|
||||||
@ -9598,6 +9617,14 @@ begin
|
|||||||
Result:=CondExpr;
|
Result:=CondExpr;
|
||||||
exit;
|
exit;
|
||||||
end
|
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
|
else if ParamResolved.BaseType=btContext then
|
||||||
begin
|
begin
|
||||||
if ParamResolved.LoTypeEl.ClassType=TPasEnumType then
|
if ParamResolved.LoTypeEl.ClassType=TPasEnumType then
|
||||||
|
@ -6431,6 +6431,9 @@ begin
|
|||||||
' c:=succ(c);',
|
' c:=succ(c);',
|
||||||
' c:=low(c);',
|
' c:=low(c);',
|
||||||
' c:=high(c);',
|
' c:=high(c);',
|
||||||
|
' i:=byte(c);',
|
||||||
|
' i:=word(c);',
|
||||||
|
' i:=longint(c);',
|
||||||
'']);
|
'']);
|
||||||
ConvertProgram;
|
ConvertProgram;
|
||||||
CheckSource('TestChar_BuiltInProcs',
|
CheckSource('TestChar_BuiltInProcs',
|
||||||
@ -6447,6 +6450,9 @@ begin
|
|||||||
'$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
|
'$mod.c = String.fromCharCode($mod.c.charCodeAt() + 1);',
|
||||||
'$mod.c = "\x00";',
|
'$mod.c = "\x00";',
|
||||||
'$mod.c = "\uFFFF";',
|
'$mod.c = "\uFFFF";',
|
||||||
|
'$mod.i = $mod.c.charCodeAt() & 255;',
|
||||||
|
'$mod.i = $mod.c.charCodeAt();',
|
||||||
|
'$mod.i = $mod.c.charCodeAt() & 0xFFFFFFFF;',
|
||||||
'']));
|
'']));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user