unit srLiteral; {$mode objfpc}{$H+} interface uses sysutils, Half16, srType, ginodes, srNode; type PsrLiteralKey=^TsrLiteralKey; TsrLiteralKey=record ntype:TsrNodeType; dtype:TsrDataType; Value:PtrUint; name :PChar; end; TsrLiteral=class(TsrNode) public pLeft,pRight:TsrLiteral; public key:TsrLiteralKey; // function _GetPrintData:RawByteString; override; function _GetData(data:Pointer):Ptruint; override; // class function c(n1,n2:PsrLiteralKey):Integer; static; property Value:PtrUint read key.Value; Function AsBool:Boolean; inline; Function AsUint8:Byte; inline; Function AsInt8:Shortint; inline; Function AsUint16:Word; inline; Function AsInt16:Smallint; inline; Function AsUint32:DWORD; inline; function AsInt32:Integer; inline; Function AsUint64:QWORD; inline; Function AsInt64:Int64; inline; Function AsHalf16:THalf16; inline; Function AsFloat32:Single; inline; Function AsFloat64:Double; inline; Function GetPrintData:RawByteString; Function GetData(data:Pointer):Ptruint; end; ntLiteral=TsrLiteral; TsrLiteralString=class(TsrLiteral) // function _GetPrintData:RawByteString; override; function _GetData(data:Pointer):Ptruint; override; // Function GetPrintData:RawByteString; Function GetData(data:Pointer):Ptruint; end; ntLiteralString=TsrLiteralString; TsrLiteralConst=class(TsrLiteral) function _GetPrintData:RawByteString; override; function _GetData(data:Pointer):Ptruint; override; // Function GetPrintData:RawByteString; Function GetData(data:Pointer):Ptruint; end; ntLiteralConst=TsrLiteralConst; PsrLiteralList=^TsrLiteralList; TsrLiteralList=object type TNodeTree=specialize TNodeTreeClass; var FEmit:TCustomEmit; FTree:TNodeTree; Procedure Init(Emit:TCustomEmit); function FetchLiteral(Value:PtrUint;name:PChar):TsrLiteral; function FetchString(name:PChar):TsrLiteralString; function FetchConst(dtype:TsrDataType;Value:PtrUint):TsrLiteralConst; end; implementation function TsrLiteral._GetPrintData:RawByteString; begin Result:=GetPrintData; end; function TsrLiteral._GetData(data:Pointer):Ptruint; begin Result:=GetData(data); end; // function TsrLiteralString._GetPrintData:RawByteString; begin Result:=GetPrintData; end; function TsrLiteralString._GetData(data:Pointer):Ptruint; begin Result:=GetData(data); end; // function TsrLiteralConst._GetPrintData:RawByteString; begin Result:=GetPrintData; end; function TsrLiteralConst._GetData(data:Pointer):Ptruint; begin Result:=GetData(data); end; // class function TsrLiteral.c(n1,n2:PsrLiteralKey):Integer; begin Result:=ord(ptruint(n1^.ntype)>ptruint(n2^.ntype))-ord(ptruint(n1^.ntype)0) then Exit; // Result:=ord(ord(n1^.dtype)>ord(n2^.dtype))-ord(ord(n1^.dtype)0) then Exit; // Result:=ord(n1^.Value>n2^.Value)-ord(n1^.Value0) then Exit; // Result:=ComparePChar(n1^.name,n2^.name); end; // Function TsrLiteral.AsBool:Boolean; inline; begin Assert(Self<>nil); Result:=PBoolean(@key.Value)^; end; Function TsrLiteral.AsUint8:Byte; inline; begin Assert(Self<>nil); Result:=PByte(@key.Value)^; end; Function TsrLiteral.AsInt8:Shortint; inline; begin Assert(Self<>nil); Result:=PShortint(@key.Value)^; end; Function TsrLiteral.AsUint16:Word; inline; begin Assert(Self<>nil); Result:=PWord(@key.Value)^; end; Function TsrLiteral.AsInt16:Smallint; inline; begin Assert(Self<>nil); Result:=PSmallint(@key.Value)^; end; Function TsrLiteral.AsUint32:DWORD; inline; begin Assert(Self<>nil); Result:=PDWORD(@key.Value)^; end; Function TsrLiteral.AsInt32:Integer; inline; begin Assert(Self<>nil); Result:=PInteger(@key.Value)^; end; Function TsrLiteral.AsUint64:QWORD; inline; begin Assert(Self<>nil); Result:=key.Value; end; Function TsrLiteral.AsInt64:Int64; inline; begin Assert(Self<>nil); Result:=Int64(key.Value); end; Function TsrLiteral.AsHalf16:THalf16; inline; begin Assert(Self<>nil); Result:=PHalf16(@key.Value)^ end; Function TsrLiteral.AsFloat32:Single; inline; begin Assert(Self<>nil); Result:=PSingle(@key.Value)^; end; Function TsrLiteral.AsFloat64:Double; inline; begin Assert(Self<>nil); Result:=PDouble(@key.Value)^; end; Function TsrLiteral.GetPrintData:RawByteString; begin if (key.name=nil) or (StrLen(key.name)=0) then begin Result:=IntToStr(key.Value); end else if (key.name='0x') then begin Result:='0x'+HexStr(key.Value,8); end else begin Result:=key.name; end; end; Function TsrLiteral.GetData(data:Pointer):Ptruint; begin Result:=SizeOf(DWORD); if (data<>nil) then begin PDWORD(data)^:=DWORD(key.Value); end; end; // Function TsrLiteralString.GetPrintData:RawByteString; begin Result:='"'+key.name+'"'; end; Function TsrLiteralString.GetData(data:Pointer):Ptruint; begin Result:=StrLen(key.name)+1; if (data<>nil) then begin Move(key.name^,data^,Result); end; end; // const DefaultFormatSettings : TFormatSettings = ( CurrencyFormat: 1; NegCurrFormat: 5; ThousandSeparator: ','; DecimalSeparator: '.'; CurrencyDecimals: 2; DateSeparator: '-'; TimeSeparator: ':'; ListSeparator: ','; CurrencyString: '$'; ShortDateFormat: ''; LongDateFormat: ''; TimeAMString: ''; TimePMString: ''; ShortTimeFormat: ''; LongTimeFormat : ''; ShortMonthNames:('','','','','','','','','','','',''); LongMonthNames :('','','','','','','','','','','',''); ShortDayNames :('','','','','','',''); LongDayNames :('','','','','','',''); TwoDigitYearCenturyWindow: 50; ); Function TsrLiteralConst.GetPrintData:RawByteString; begin Result:=''; case key.dtype of dtUnknow :Result:='0x'+HexStr(key.Value,4); dtBool : Case AsBool of true :Result:='true'; false:Result:='false'; end; dtHalf16 : Result:=FloatToStr(Single(AsHalf16),DefaultFormatSettings); dtFloat32: Result:=FloatToStr( AsFloat32,DefaultFormatSettings); dtFloat64: Result:=FloatToStr( AsFloat64,DefaultFormatSettings); dtInt8 : Result:=IntToStr(AsInt8); dtUint8 : Result:=IntToStr(AsUint8); dtInt16 : Result:=IntToStr(AsInt16); dtUint16 : Result:=IntToStr(AsUint16); dtInt32 : Result:=IntToStr(AsInt32); dtUint32 : Result:=IntToStr(AsUint32); dtInt64 : Result:=IntToStr(AsInt64); dtUint64 : Result:=IntToStr(AsUint64); else; end; end; Function TsrLiteralConst.GetData(data:Pointer):Ptruint; begin Result:=0; Case key.dtype.BitSize of 8:begin Result:=SizeOf(BYTE); if (data<>nil) then begin PBYTE(data)^:=BYTE(key.Value); end; end; 16:begin Result:=SizeOf(WORD); if (data<>nil) then begin PWORD(data)^:=WORD(key.Value); end; end; 32:begin Result:=SizeOf(DWORD); if (data<>nil) then begin PDWORD(data)^:=DWORD(key.Value); end; end; 64:begin Result:=SizeOf(QWORD); if (data<>nil) then begin PQWORD(data)^:=key.Value; end; end; else; end; end; // Procedure TsrLiteralList.Init(Emit:TCustomEmit); begin FEmit:=Emit; end; function TsrLiteralList.FetchLiteral(Value:PtrUint;name:PChar):TsrLiteral; var key:TsrLiteralKey; size:ptrint; begin key:=Default(TsrLiteralKey); key.ntype:=ntLiteral; key.dtype:=dtUint32; key.Value:=Value; key.name :=name; Result:=FTree.Find(@key); if (Result=nil) then begin Result:=FEmit.specialize New; Result.key:=key; if (name<>nil) then begin size:=StrLen(name)+1; Result.key.name:=FEmit.Alloc(size); Move(name^,Result.key.name^,size); end; FTree.Insert(Result); end; end; function TsrLiteralList.FetchString(name:PChar):TsrLiteralString; var key:TsrLiteralKey; size_o:ptrint; size_a:ptrint; begin key:=Default(TsrLiteralKey); key.ntype:=ntLiteralString; key.dtype:=dtString; key.name :=name; Result:=TsrLiteralString(FTree.Find(@key)); if (Result=nil) then begin Result:=FEmit.specialize New; Result.key:=key; if (name<>nil) then begin size_o:=StrLen(name); size_a:=Align(size_o+1,SizeOf(DWORD)); //align DW Result.key.name:=FEmit.Alloc(size_a); Move(name^,Result.key.name^,size_o); end else begin Result.key.name:=FEmit.Alloc(SizeOf(DWORD)); //space DW end; FTree.Insert(Result); end; end; function TsrLiteralList.FetchConst(dtype:TsrDataType;Value:PtrUint):TsrLiteralConst; var key:TsrLiteralKey; begin key:=Default(TsrLiteralKey); key.ntype:=ntLiteralConst; key.dtype:=dtype; key.Value:=Value; Result:=TsrLiteralConst(FTree.Find(@key)); if (Result=nil) then begin Result:=FEmit.specialize New; Result.key:=key; FTree.Insert(Result); end; end; end.