pastojs: intrinsics lo/hi, issue #34964, patch from Kryvichh

git-svn-id: trunk@41148 -
This commit is contained in:
Mattias Gaertner 2019-01-30 16:44:48 +00:00
parent 70c4d45474
commit 6160a2ad51
6 changed files with 441 additions and 11 deletions

View File

@ -25,7 +25,7 @@ Works:
- int/uint
- unary +, -
- binary: +, -, *, div, mod, ^^, =, <>, <, >, <=, >=, and, or, xor, not, shl, shr
- low(), high(), pred(), succ(), ord()
- Low(), High(), Pred(), Succ(), Ord(), Lo(), Hi()
- typecast longint(-1), word(-2), intsingle(-1), uintsingle(1)
- float:
- typecast single(double), double(single), float(integer)
@ -714,6 +714,8 @@ type
function EvalStrFunc(Params: TParamsExpr; Flags: TResEvalFlags): TResEvalValue; virtual;
function EvalStringAddExpr(Expr, LeftExpr, RightExpr: TPasExpr;
LeftValue, RightValue: TResEvalValue): TResEvalValue; virtual;
function LoHiValue(Value: TResEvalValue; ShiftSize: Integer; Mask: LongWord;
ErrorEl: TPasElement): TResEvalValue; virtual;
function EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
Flags: TResEvalFlags): TResEvalEnum; virtual;
{$ifdef FPC_HAS_CPSTRING}
@ -735,6 +737,7 @@ type
TResExprEvaluatorClass = class of TResExprEvaluator;
procedure ReleaseEvalValue(var Value: TResEvalValue);
function NumberIsFloat(const Value: string): boolean;
{$ifdef FPC_HAS_CPSTRING}
function RawStrToCaption(const r: RawByteString; MaxLength: integer): string;
@ -757,6 +760,17 @@ begin
Value:=nil;
end;
function NumberIsFloat(const Value: string): boolean;
var
i: Integer;
begin
if Value='' then exit(false);
if Value[1] in ['$','%','&'] then exit(false);
for i:=2 to length(Value) do
if Value[i] in ['.','E','e'] then exit(true);
Result:=false;
end;
{$ifdef FPC_HAS_CPSTRING}
function RawStrToCaption(const r: RawByteString; MaxLength: integer): string;
var
@ -4849,6 +4863,35 @@ begin
end;
end;
function TResExprEvaluator.LoHiValue(Value: TResEvalValue; ShiftSize: Integer;
Mask: LongWord; ErrorEl: TPasElement): TResEvalValue;
var
uint: LongWord;
begin
case Value.Kind of
revkInt:
{$IFDEF Pas2js}
if ShiftSize=32 then
uint := (TResEvalInt(Value).Int div $100000000) and Mask;
else
{$ENDIF}
uint := (TResEvalInt(Value).Int shr ShiftSize) and Mask;
revkUInt:
{$IFDEF Pas2js}
if ShiftSize=32 then
uint := (TResEvalUInt(Value).UInt div $100000000) and Mask;
else
{$ENDIF}
uint := (TResEvalUInt(Value).UInt shr ShiftSize) and Mask;
else
{$IFDEF VerbosePasResEval}
writeln('TResExprEvaluator.LoHiValue ',Value.AsDebugString);
{$ENDIF}
RaiseNotYetImplemented(20190129012100,ErrorEl);
end;
Result := TResEvalInt.CreateValue(uint);
end;
function TResExprEvaluator.EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
Flags: TResEvalFlags): TResEvalEnum;
var

View File

@ -228,6 +228,13 @@ Works:
- with
- self
- built-in procedure Val(const s: string; var e: enumtype; out Code: integertype);
- intrinsic functions Lo and Hi, depending on $mode (ObjFPC or Delphi):
- In $MODE DELPHI:
function Lo/Hi(i: <any integer type>): Byte
- In $MODE OBJFPC:
function Lo/Hi(i: Byte/ShortInt/Word/SmallInt): Byte
function Lo/Hi(i: LongWord/LongInt/UIntSingle/IntSingle): Word
function Lo/Hi(i: QWord/Int64/UIntDouble/IntDouble): LongWord
- helpers:
- class
- record
@ -549,6 +556,8 @@ type
bfStrFunc,
bfWriteStr,
bfVal,
bfLo,
bfHi,
bfConcatArray,
bfConcatString,
bfCopyArray,
@ -584,6 +593,8 @@ const
'Str',
'WriteStr',
'Val',
'Lo',
'Hi',
'Concat',
'Concat',
'Copy',
@ -1689,6 +1700,12 @@ type
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
procedure BI_Val_OnFinishParamsExpr(Proc: TResElDataBuiltInProc;
Params: TParamsExpr); virtual;
function BI_LoHi_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
procedure BI_LoHi_OnGetCallResult(Proc: TResElDataBuiltInProc;
Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
procedure BI_LoHi_OnEval(Proc: TResElDataBuiltInProc;
Params: TParamsExpr; Flags: TResEvalFlags; out Evaluated: TResEvalValue); virtual;
function BI_ConcatArray_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
procedure BI_ConcatArray_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
@ -2015,6 +2032,8 @@ type
function IsElementSkipped(El: TPasElement): boolean; virtual;
function FindLocalBuiltInSymbol(El: TPasElement): TPasElement; virtual;
function GetLastSection: TPasSection;
function GetShiftAndMaskForLoHiFunc(BaseType: TResolverBaseType;
isLoFunc: Boolean; out Mask: LongWord): Integer;
public
// options
property Options: TPasResolverOptions read FOptions write FOptions;
@ -14387,6 +14406,77 @@ begin
FinishCallArgAccess(P[2],rraOutParam);
end;
function TPasResolver.BI_LoHi_OnGetCallCompatibility(
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
var
Params: TParamsExpr;
Param: TPasExpr;
ParamResolved: TPasResolverResult;
begin
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
Exit(cIncompatible);
Params:=TParamsExpr(Expr);
// first Param: any integer type
Param:=Params.params[0];
ComputeElement(Param,ParamResolved,[]);
Result:=cIncompatible;
if (rrfReadable in ParamResolved.Flags)
and (ParamResolved.BaseType in btAllInteger)
then
Result:=cExact;
if Result=cIncompatible then
Exit(CheckRaiseTypeArgNo(20190128232600,1,Param,ParamResolved,'integer type',RaiseOnError));
Result:=CheckBuiltInMaxParamCount(Proc,Params,1,RaiseOnError);
end;
procedure TPasResolver.BI_LoHi_OnGetCallResult(Proc: TResElDataBuiltInProc;
Params: TParamsExpr; out ResolvedEl: TPasResolverResult);
var
ResolvedParam: TPasResolverResult;
BaseType: TResolverBaseType;
Mask: LongWord;
begin
ComputeElement(Params.Params[0],ResolvedParam,[]);
GetShiftAndMaskForLoHiFunc(ResolvedParam.BaseType, Proc.BuiltIn=bfLo, Mask);
case Mask of
$F, $FF: BaseType := btByte;
$FFFF: BaseType := btWord;
else { $FFFFFFFF } BaseType := btLongWord;
end;
SetResolverIdentifier(ResolvedEl,BaseType,Proc.Proc,
FBaseTypes[BaseType],FBaseTypes[BaseType],[rrfReadable]);
end;
procedure TPasResolver.BI_LoHi_OnEval(Proc: TResElDataBuiltInProc;
Params: TParamsExpr; Flags: TResEvalFlags; out Evaluated: TResEvalValue);
var
Param: TPasExpr;
ResolvedParam: TPasResolverResult;
Value: TResEvalValue;
Shift: Integer;
Mask: LongWord;
begin
Evaluated := nil;
Param := Params.Params[0];
Value := Eval(Param,Flags);
{$IFDEF VerbosePasResEval}
{AllowWriteln}
if value=nil then
writeln('TPasResolver.BI_LoHi_OnEval Value=NIL')
else
writeln('TPasResolver.BI_LoHi_OnEval Value=',value.AsDebugString);
{AllowWriteln-}
{$ENDIF}
if Value=nil then exit;
try
ComputeElement(Param,ResolvedParam,[]);
Shift := GetShiftAndMaskForLoHiFunc(ResolvedParam.BaseType, Proc.BuiltIn=bfLo, Mask);
Evaluated := fExprEvaluator.LoHiValue(Value,Shift,Mask,Params);
finally
ReleaseEvalValue(Value);
end;
end;
function TPasResolver.BI_ConcatArray_OnGetCallCompatibility(
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
var
@ -16337,6 +16427,14 @@ begin
AddBuiltInProc('Val','procedure Val(const String; var Value: bool|int|float|enum; out Int)',
@BI_Val_OnGetCallCompatibility,nil,nil,
@BI_Val_OnFinishParamsExpr,bfVal,[bipfCanBeStatement]);
if bfLo in TheBaseProcs then
AddBuiltInProc('Lo','function Lo(X: any integer type): Byte|Word)',
@BI_LoHi_OnGetCallCompatibility,@BI_LoHi_OnGetCallResult,
@BI_LoHi_OnEval,nil,bfLo);
if bfHi in TheBaseProcs then
AddBuiltInProc('Hi','function Hi(X: any integer type): Byte|Word)',
@BI_LoHi_OnGetCallCompatibility,@BI_LoHi_OnGetCallResult,
@BI_LoHi_OnEval,nil,bfHi);
if bfConcatArray in TheBaseProcs then
AddBuiltInProc('Concat','function Concat(const Array1, Array2, ...): Array',
@BI_ConcatArray_OnGetCallCompatibility,@BI_ConcatArray_OnGetCallResult,
@ -21095,6 +21193,8 @@ var
ElClass: TClass;
bt: TResolverBaseType;
TypeEl: TPasType;
Value: TResEvalValue;
Int: TMaxPrecInt;
begin
if StartEl=nil then StartEl:=El;
ResolvedEl:=Default(TPasResolverResult);
@ -21114,14 +21214,35 @@ begin
ComputeIdentifier(TPrimitiveExpr(El));
end;
pekNumber:
if Pos('.',TPrimitiveExpr(El).Value)>0 then
SetResolverValueExpr(ResolvedEl,BaseTypeExtended,
FBaseTypes[BaseTypeExtended],FBaseTypes[BaseTypeExtended],
TPrimitiveExpr(El),[rrfReadable])
else
SetResolverValueExpr(ResolvedEl,btLongint,
FBaseTypes[btLongint],FBaseTypes[btLongint],
TPrimitiveExpr(El),[rrfReadable]);
begin
if NumberIsFloat(TPrimitiveExpr(El).Value) then
bt:=BaseTypeExtended
else if length(TPrimitiveExpr(El).Value)<10 then
bt:=btLongint
else
begin
Value:=Eval(TPrimitiveExpr(El),[]);
if Value=nil then
RaiseNotYetImplemented(20190130162601,El);
try
case Value.Kind of
revkInt:
begin
Int:=TResEvalInt(Value).Int;
bt:=GetSmallestIntegerBaseType(Int,Int);
end;
revkUInt:
bt:=btQWord;
else
bt:=BaseTypeExtended;
end;
finally
ReleaseEvalValue(Value);
end;
end;
SetResolverValueExpr(ResolvedEl,bt,FBaseTypes[bt],FBaseTypes[bt],
TPrimitiveExpr(El),[rrfReadable])
end;
pekString:
begin
{$IFDEF VerbosePasResolver}
@ -22599,6 +22720,43 @@ begin
Result:=Module.InterfaceSection;
end;
function TPasResolver.GetShiftAndMaskForLoHiFunc(BaseType: TResolverBaseType;
isLoFunc: Boolean; out Mask: LongWord): Integer;
const
SHIFT_SIZE: array[btByte..{$IFDEF HasInt64}btComp{$ELSE}btIntDouble{$ENDIF}] of Integer = (
4, // btByte
8, // btShortInt FPC lo/hi(shortint) works like SmallInt
8, 8, // btWord, btSmallInt
16, 16, 16, 16, // btUIntSingle, btIntSingle, btLongWord, btLongint
32, 32 // btUIntDouble, btIntDouble
{$IFDEF HasInt64}
, 32, 32, 32 // btQWord, btInt64, btComp
{$endif}
);
begin
if (BaseType >= Low(SHIFT_SIZE)) and (BaseType <= High(SHIFT_SIZE)) then
begin
if msDelphi in CurrentParser.CurrentModeswitches then
Result := 8
else
Result := SHIFT_SIZE[BaseType];
case Result of
8: Mask := $FF;
16: Mask := $FFFF;
32: Mask := $FFFFFFFF;
else
{4} Mask := $F;
end;
if isLoFunc then
Result := 0;
end
else
begin
RaiseInternalError(20190130122300);
Result := -1;
end;
end;
function TPasResolver.CheckSrcIsADstType(const ResolvedSrcType,
ResolvedDestType: TPasResolverResult): integer;
// finds distance between classes SrcType and DestType

View File

@ -2797,6 +2797,20 @@ begin
' r=low(word)+high(int64);',
' s=low(longint)+high(integer);',
' t=succ(2)+pred(2);',
' lo1:byte=lo(word($1234));',
' hi1:byte=hi(word($1234));',
' lo2:word=lo(longword($1234CDEF));',
' hi2:word=hi(longword($1234CDEF));',
' lo3:word=lo(LongInt(-$1234CDEF));',
' hi3:word=hi(LongInt(-$1234CDEF));',
' lo4:byte=lo(byte($34));',
' hi4:byte=hi(byte($34));',
' lo5:byte=lo(shortint(-$34));',
' hi5:byte=hi(shortint(-$34));',
' lo6:longword=lo($123456789ABCDEF0);',
' hi6:longword=hi($123456789ABCDEF0);',
' lo7:longword=lo(-$123456789ABCDEF0);',
' hi7:longword=hi(-$123456789ABCDEF0);',
'begin']);
ParseProgram;
CheckResolverUnexpectedHints;
@ -4359,6 +4373,10 @@ begin
Add(' if i>=j then;');
Add(' if i<j then;');
Add(' if i<=j then;');
Add(' i:=lo($1234);');
Add(' i:=lo($1234CDEF);');
Add(' i:=hi($1234);');
Add(' i:=hi($1234CDEF);');
ParseProgram;
end;

View File

@ -1836,6 +1836,7 @@ type
Function ConvertBuiltInStrParam(El: TPasExpr; AContext: TConvertContext; IsStrFunc, IsFirst: boolean): TJSElement; virtual;
Function ConvertBuiltIn_WriteStr(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
Function ConvertBuiltIn_Val(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
Function ConvertBuiltIn_LoHi(El: TParamsExpr; AContext: TConvertContext; IsLoFunc: Boolean): TJSElement; virtual;
Function ConvertBuiltIn_ConcatArray(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
Function ConvertBuiltIn_ConcatString(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
Function ConvertBuiltIn_CopyArray(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
@ -9020,6 +9021,8 @@ begin
bfStrFunc: Result:=ConvertBuiltIn_StrFunc(El,AContext);
bfWriteStr: Result:=ConvertBuiltIn_WriteStr(El,AContext);
bfVal: Result:=ConvertBuiltIn_Val(El,AContext);
bfLo: Result := ConvertBuiltIn_LoHi(El,AContext,True);
bfHi: Result := ConvertBuiltIn_LoHi(El,AContext,False);
bfConcatArray: Result:=ConvertBuiltIn_ConcatArray(El,AContext);
bfConcatString: Result:=ConvertBuiltIn_ConcatString(El,AContext);
bfCopyArray: Result:=ConvertBuiltIn_CopyArray(El,AContext);
@ -11099,6 +11102,66 @@ begin
end;
end;
function TPasToJSConverter.ConvertBuiltIn_LoHi(El: TParamsExpr;
AContext: TConvertContext; IsLoFunc: Boolean): TJSElement;
var
ResolvedParam: TPasResolverResult;
Param: TPasExpr;
Mask: LongWord;
Shift, Digits: Integer;
ShiftEx: TJSShiftExpression;
AndEx: TJSBitwiseAndExpression;
begin
Result := nil;
if AContext.Resolver=nil then
RaiseInconsistency(20190129102200,El);
Param := El.Params[0];
AContext.Resolver.ComputeElement(Param,ResolvedParam,[]);
if not (ResolvedParam.BaseType in btAllInteger) then
DoError(20190129121100,nXExpectedButYFound,sXExpectedButYFound,['integer type',
AContext.Resolver.GetResolverResultDescription(ResolvedParam)],Param);
Shift := AContext.Resolver.GetShiftAndMaskForLoHiFunc(ResolvedParam.BaseType,IsLoFunc,Mask);
Result := ConvertExpression(Param,AContext);
// Note: convert Param first, as it might raise an exception
if Shift > 0 then
begin
if Shift=32 then
begin
// JS bitwise operations work only 32bit -> use division for bigger shifts
Result:=CreateMathFloor(El,CreateDivideNumber(El,Result,$100000000));
end
else
begin
ShiftEx := TJSRShiftExpression(CreateElement(TJSRShiftExpression,El));
ShiftEx.A := Result;
ShiftEx.B := CreateLiteralNumber(El, Shift);
Result := ShiftEx;
end;
end;
case Mask of
$FF: Digits := 2;
$FFFF: Digits := 4;
$FFFFFFFF: Digits := 8;
else { $F } Digits := 1;
end;
if Digits<8 then
begin
// & Mask
AndEx := TJSBitwiseAndExpression(CreateElement(TJSBitwiseAndExpression,El));
AndEx.A := Result;
AndEx.B := CreateLiteralHexNumber(El,Mask,Digits);
Result := AndEx;
end
else
begin
// mask to longword -> >>> 0
ShiftEx:=TJSURShiftExpression(CreateElement(TJSURShiftExpression,El));
ShiftEx.A:=Result;
ShiftEx.B:=CreateLiteralNumber(El,0);
Result:=ShiftEx;
end;
end;
function TPasToJSConverter.ConvertBuiltIn_ConcatArray(El: TParamsExpr;
AContext: TConvertContext): TJSElement;
// concat(array1, array2)

View File

@ -370,6 +370,8 @@ type
// statements
Procedure TestNestBegin;
Procedure TestIncDec;
Procedure TestLoHiFpcMode;
Procedure TestLoHiDelphiMode;
Procedure TestAssignments;
Procedure TestArithmeticOperators1;
Procedure TestLogicalOperators;
@ -2683,6 +2685,154 @@ begin
]));
end;
procedure TTestModule.TestLoHiFpcMode;
begin
StartProgram(false);
Add([
'{$mode objfpc}',
'const',
' LoByte1 = Lo(Word($1234));',
' HiByte1 = Hi(Word($1234));',
' LoByte2 = Lo(SmallInt($1234));',
' HiByte2 = Hi(SmallInt($1234));',
' LoWord1 = Lo($1234CDEF);',
' HiWord1 = Hi($1234CDEF);',
' LoWord2 = Lo(-$1234CDEF);',
' HiWord2 = Hi(-$1234CDEF);',
' lo4:byte=lo(byte($34));',
' hi4:byte=hi(byte($34));',
' lo5:byte=lo(shortint(-$34));',
' hi5:byte=hi(shortint(-$34));',
' lo6:longword=lo($123456789ABCDE);',
' hi6:longword=hi($123456789ABCDE);',
' lo7:longword=lo(-$123456789ABCDE);',
' hi7:longword=hi(-$123456789ABCDE);',
'var',
' b: Byte;',
' ss: shortint;',
' w: Word;',
' si: SmallInt;',
' lw: LongWord;',
' li: LongInt;',
' b2: Byte;',
' ni: nativeint;',
'begin',
' w := $1234;',
' ss := -$12;',
' b := lo(ss);',
' b := HI(ss);',
' b := lo(w);',
' b := HI(w);',
' b2 := lo(b);',
' b2 := hi(b);',
' lw := $1234CDEF;',
' w := lo(lw);',
' w := hi(lw);',
' ni := $123456789ABCDE;',
' lw := lo(ni);',
' lw := hi(ni);',
'']);
ConvertProgram;
CheckSource('TestLoHiFpcMode',
LinesToStr([ // statements
'this.LoByte1 = 0x1234 & 0xFF;',
'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
'this.LoByte2 = 0x1234 & 0xFF;',
'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
'this.LoWord1 = 0x1234CDEF & 0xFFFF;',
'this.HiWord1 = (0x1234CDEF >> 16) & 0xFFFF;',
'this.LoWord2 = -0x1234CDEF & 0xFFFF;',
'this.HiWord2 = (-0x1234CDEF >> 16) & 0xFFFF;',
'this.lo4 = 0x34 & 0xF;',
'this.hi4 = (0x34 >> 4) & 0xF;',
'this.lo5 = (((-0x34 & 255) << 24) >> 24) & 0xFF;',
'this.hi5 = ((((-0x34 & 255) << 24) >> 24) >> 8) & 0xFF;',
'this.lo6 = 0x123456789ABCDE >>> 0;',
'this.hi6 = 1193046 >>> 0;',
'this.lo7 = -0x123456789ABCDE >>> 0;',
'this.hi7 = Math.floor(-0x123456789ABCDE / 4294967296) >>> 0;',
'this.b = 0;',
'this.ss = 0;',
'this.w = 0;',
'this.si = 0;',
'this.lw = 0;',
'this.li = 0;',
'this.b2 = 0;',
'this.ni = 0;',
'']),
LinesToStr([ // this.$main
'$mod.w = 0x1234;',
'$mod.ss = -0x12;',
'$mod.b = $mod.ss & 0xFF;',
'$mod.b = ($mod.ss >> 8) & 0xFF;',
'$mod.b = $mod.w & 0xFF;',
'$mod.b = ($mod.w >> 8) & 0xFF;',
'$mod.b2 = $mod.b & 0xF;',
'$mod.b2 = ($mod.b >> 4) & 0xF;',
'$mod.lw = 0x1234CDEF;',
'$mod.w = $mod.lw & 0xFFFF;',
'$mod.w = ($mod.lw >> 16) & 0xFFFF;',
'$mod.ni = 0x123456789ABCDE;',
'$mod.lw = $mod.ni >>> 0;',
'$mod.lw = Math.floor($mod.ni / 4294967296) >>> 0;',
'']));
end;
procedure TTestModule.TestLoHiDelphiMode;
begin
StartProgram(false);
Add([
'{$mode delphi}',
'const',
' LoByte1 = Lo(Word($1234));',
' HiByte1 = Hi(Word($1234));',
' LoByte2 = Lo(SmallInt($1234));',
' HiByte2 = Hi(SmallInt($1234));',
' LoByte3 = Lo($1234CDEF);',
' HiByte3 = Hi($1234CDEF);',
' LoByte4 = Lo(-$1234CDEF);',
' HiByte4 = Hi(-$1234CDEF);',
'var',
' b: Byte;',
' w: Word;',
' si: SmallInt;',
' lw: LongWord;',
' li: LongInt;',
'begin',
' w := $1234;',
' b := lo(w);',
' b := HI(w);',
' lw := $1234CDEF;',
' b := lo(lw);',
' b := hi(lw);',
'']);
ConvertProgram;
CheckSource('TestLoHiDelphiMode',
LinesToStr([ // statements
'this.LoByte1 = 0x1234 & 0xFF;',
'this.HiByte1 = (0x1234 >> 8) & 0xFF;',
'this.LoByte2 = 0x1234 & 0xFF;',
'this.HiByte2 = (0x1234 >> 8) & 0xFF;',
'this.LoByte3 = 0x1234CDEF & 0xFF;',
'this.HiByte3 = (0x1234CDEF >> 8) & 0xFF;',
'this.LoByte4 = -0x1234CDEF & 0xFF;',
'this.HiByte4 = (-0x1234CDEF >> 8) & 0xFF;',
'this.b = 0;',
'this.w = 0;',
'this.si = 0;',
'this.lw = 0;',
'this.li = 0;'
]),
LinesToStr([ // this.$main
'$mod.w = 0x1234;',
'$mod.b = $mod.w & 0xFF;',
'$mod.b = ($mod.w >> 8) & 0xFF;',
'$mod.lw = 0x1234CDEF;',
'$mod.b = $mod.lw & 0xFF;',
'$mod.b = ($mod.lw >> 8) & 0xFF;'
]));
end;
procedure TTestModule.TestAssignments;
begin
StartProgram(false);

View File

@ -26,8 +26,6 @@ begin
P.Directory:=ADirectory;
P.Version:='3.3.1';
P.OSes:=AllUnixOSes+AllBSDOSes+AllWindowsOSes-[WinCE];
if Defaults.CPU=jvm then
P.OSes := P.OSes - [android];
P.Dependencies.Add('fcl-json');
P.Dependencies.Add('fcl-js');
P.Dependencies.Add('fcl-passrc');