unit uengShaderFileTypes; {$mode objfpc}{$H+} {$I uengShaderFile.inc} interface uses Classes, SysUtils {$IFDEF SHADER_FILE_USE_BITSPACE_UTILS} , uutlSerialization, uutlCommon, uutlGenerics {$ELSE} , uengShaderFileGenerics {$ENDIF} ; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// {$IFDEF SHADER_FILE_USE_BITSPACE_UTILS} IengShaderFileWriter = uutlSerialization.IutlFileWriter; IengShaderFileReader = uutlSerialization.IutlFileReader; TengShaderFileReader = uutlSerialization.TutlSimpleFileReader; TengShaderFileWriter = uutlSerialization.TutlSimpleFileWriter; TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount; {$ELSE} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TIntfObjNoRefCount = class(TObject, IUnknown) protected fRefCount : longint; { implement methods of IUnknown } function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual; function _Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; virtual; public property RefCount: LongInt read fRefCount; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// IengShaderFileReader = interface ['{3A9C3AE3-CAEE-44C9-85BE-0BCAA5C1BE7A}'] function LoadStream(const aFilename: String; const aStream: TStream): Boolean; end; IengShaderFileWriter = interface ['{3DF84644-9FC4-4A8A-88C2-73F13E72B1ED}'] procedure SaveStream(const aFilename: String; const aStream: TStream); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderFileReader = class(TInterfacedObject, IengShaderFileReader) public function LoadStream(const aFilename: String; const aStream: TStream): Boolean; end; TengShaderFileWriter = class(TInterfacedObject, IengShaderFileWriter) public procedure SaveStream(const aFilename: String; const aStream: TStream); end; {$ENDIF} TengShaderPartLogLevel = ( llDebug, llInfo, llWarning, llError, llThrow ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderCode = class(TStringList) end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengMetaType = ( metaUnknown, metaNormal, metaVersion, metaExtension, metaLayout); TengMetaData = class(TObject) private fMetaType: TengMetaType; fName: String; fValues: TStringList; function GetCount: Integer; function GetValues: TStrings; public property MetaType: TengMetaType read fMetaType; property Name: String read fName; property Count: Integer read GetCount; property Values: TStrings read GetValues; procedure Assign(const aValues: TengMetaData); constructor Create(const aName: String; const aType: TengMetaType); destructor Destroy; override; end; TengMetaDataList = specialize TutlSimpleList; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengShaderPart = class(Exception) protected function GenerateMessage: String; virtual; public Sender: TObject; Line: Integer; Col: Integer; Filename: String; procedure PrintTrace(const aLines: TStrings); function PrintTrace: String; constructor Create(const aSender: TObject); overload; constructor Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; constructor Create(const aMsg: String; const aSender: TObject); overload; constructor Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; EengShaderPartInternal = class(EengShaderPart); EengExpression = class(EengShaderPart); EengExpressionInternal = class(EengExpression) ErrorCode: Integer; constructor Create(const aErrorCode: Integer; const aSender: TObject); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengInvalidToken = class(EengShaderPartInternal) protected function GenerateMessage: String; override; public SenderClassName: String; Token: String; constructor Create(const aSenderClassName: String; const aToken: String; const aSender: TObject); overload; constructor Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengUnexpectedToken = class(EengShaderPart) protected function GenerateMessage: String; override; public Token: String; Expected: String; constructor Create(const aToken, aExpected: String; const aSender: TObject); overload; constructor Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengInvalidParamter = class(EengShaderPart) protected function GenerateMessage: String; override; public Param: String; Expected: String; constructor Create(const aParam, aExpected: String; const aSender: TObject); overload; constructor Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengInvalidParamterCount = class(EengShaderPart) protected function GenerateMessage: String; override; public Token: String; ExpectedMin: Integer; ExpectedMax: Integer; constructor Create(const aToken: String; const aExpected: Integer; const aSender: TObject); overload; constructor Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject); overload; constructor Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; constructor Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengInvalidIdentifier = class(EengShaderPart) protected function GenerateMessage: String; override; public Identifier: String; constructor Create(const aIdentifier: String; const aSender: TObject); overload; constructor Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengOutOfRange = class(EengShaderPartInternal) protected function GenerateMessage: String; override; public Min: Integer; Max: Integer; Index: Integer; constructor Create(const aMin, aMax, aIndex: Integer; const aSender: TObject); overload; constructor Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengDuplicateIdentifier = class(EengShaderPart) protected function GenerateMessage: String; override; public Name: String; New: TObject; Old: TObject; constructor Create(const aName: String; const aNew, aOld, aSender: TObject); overload; constructor Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EengUnknownIdentifier = class(EengShaderPart) protected function GenerateMessage: String; override; public Name: String; constructor Create(const aName: String; const aSender: TObject); overload; constructor Create(const aName: String; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); overload; end; implementation uses uengShaderPart; {$IFNDEF SHADER_FILE_USE_BITSPACE_UTILS} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TIntfObjNoRefCount////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TIntfObjNoRefCount.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; begin if getinterface(iid,obj) then result := S_OK else result := longint(E_NOINTERFACE); end; function TIntfObjNoRefCount._AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; begin result := InterLockedIncrement(fRefCount); end; function TIntfObjNoRefCount._Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; begin result := InterLockedDecrement(fRefCount); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFileReader////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderFileReader.LoadStream(const aFilename: String; const aStream: TStream): Boolean; var fs: TFileStream; begin result := FileExists(aFilename); if result then begin fs := TFileStream.Create(aFilename, fmOpenRead); try aStream.CopyFrom(fs, fs.Size - fs.Position); finally FreeAndNil(fs); end; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFileWriter////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderFileWriter.SaveStream(const aFilename: String; const aStream: TStream); var fs: TFileStream; begin fs := TFileStream.Create(aFilename, fmCreate); try fs.CopyFrom(aStream, aStream.Size - aStream.Position); finally FreeAndNil(fs); end; end; {$ENDIF} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengMetaData////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengMetaData.GetCount: Integer; begin result := fValues.Count; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengMetaData.GetValues: TStrings; begin result := fValues; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengMetaData.Assign(const aValues: TengMetaData); begin fName := aValues.Name; fMetaType := aValues.MetaType; fValues.Clear; fValues.AddStrings(aValues.Values); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TengMetaData.Create(const aName: String; const aType: TengMetaType); begin inherited Create; fName := aName; fMetaType := aType; fValues := TStringList.Create; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TengMetaData.Destroy; begin FreeAndNil(fValues); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengExpressionInternal//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengExpressionInternal.Create(const aErrorCode: Integer; const aSender: TObject); begin ErrorCode := aErrorCode; inherited Create('internal error: ' + IntToStr(ErrorCode), aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengShaderPart//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengShaderPart.GenerateMessage: String; begin result := ''; // DUMMY end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure EengShaderPart.PrintTrace(const aLines: TStrings); function GetName(const aPart: TengShaderPart): String; begin result := aPart.GetTokenName; if (result = '') then result := aPart.ClassName else result := result + ' (' + aPart.ClassName + ')'; end; begin if not Assigned(Sender) or not (Sender is TengShaderPart) then exit; aLines.Add(Message); (Sender as TengShaderPart).PrintTrace(' ', aLines); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengShaderPart.PrintTrace: String; var sl: TStringList; begin sl := TStringList.Create; try PrintTrace(sl); result := sl.Text; finally FreeAndNil(sl); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengShaderPart.Create(const aSender: TObject); begin Create(GenerateMessage, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengShaderPart.Create(const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Create(GenerateMessage, aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengShaderPart.Create(const aMsg: String; const aSender: TObject); begin Sender := nil; if Assigned(aSender) then Create( aMsg, (aSender as TengShaderPart).Line, (aSender as TengShaderPart).Col, (aSender as TengShaderPart).Filename, aSender) else inherited Create(Format('%s: %s', [ ClassName, aMsg])); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengShaderPart.Create(const aMsg: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Sender := aSender; Line := aLine; Col := aCol; Filename := aFilename; inherited Create(Format('%s (%s %d:%d): %s',[ ClassName, ExtractFileName(Filename), Line+1, Col, aMsg])) end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidToken////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengInvalidToken.GenerateMessage: String; begin result := 'invalid token: ' + SenderClassName + ' <> '+ Token; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aSender: TObject); begin SenderClassName := aSenderClassName; Token := aToken; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidToken.Create(const aSenderClassName: String; const aToken: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin SenderClassName := aSenderClassName; Token := aToken; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengUnexpectedToken/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengUnexpectedToken.GenerateMessage: String; begin result := 'unexpected token: ' + Token; if (Expected <> '') then result := result + '(expected ' + Expected + ')'; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aSender: TObject); begin Token := aToken; Expected := aExpected; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengUnexpectedToken.Create(const aToken, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Token := aToken; Expected := aExpected; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidParamter/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengInvalidParamter.GenerateMessage: String; begin result := 'invalid parameter: ' + Param; if (Expected <> '') then result := result + '(expected ' + Expected + ')'; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aSender: TObject); begin Param := aParam; Expected := aExpected; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamter.Create(const aParam, aExpected: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Param := aParam; Expected := aExpected; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidParamterCount////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengInvalidParamterCount.GenerateMessage: String; begin result := 'invalid parameter count in ' + Token + '(expected '; if (ExpectedMin = ExpectedMax) then result := result + IntToStr(ExpectedMin) else if (ExpectedMax < 0) then result := result + ' at least ' + IntToStr(ExpectedMin) else result := IntToStr(ExpectedMin) + ' to ' + IntToStr(ExpectedMax); result := result + 'parameter)'; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected: Integer; const aSender: TObject); begin Token := aToken; ExpectedMin := aExpected; ExpectedMax := aExpected; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax: Integer; const aSender: TObject); begin Token := aToken; ExpectedMin := aExpectedMin; ExpectedMax := aExpectedMax; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamterCount.Create(const aToken: String; const aExpected, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Token := aToken; ExpectedMin := aExpected; ExpectedMax := aExpected; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidParamterCount.Create(const aToken: String; const aExpectedMin, aExpectedMax, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Token := aToken; ExpectedMin := aExpectedMin; ExpectedMax := aExpectedMax; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengInvalidIdentifier///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengInvalidIdentifier.GenerateMessage: String; begin result := 'invalid identifier: ' + Identifier; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aSender: TObject); begin Identifier := aIdentifier; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengInvalidIdentifier.Create(const aIdentifier: String; const aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Identifier := aIdentifier; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengOutOfRange//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengOutOfRange.GenerateMessage: String; begin result := format('index (%d) out of range (%d:%d)', [Index, Min, Max]) end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengOutOfRange.Create(const aMin, aMax, aIndex: Integer; const aSender: TObject); begin Min := aMin; Max := aMax; Index := aIndex; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengOutOfRange.Create(const aMin, aMax, aIndex, aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Min := aMin; Max := aMax; Index := aIndex; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengDuplicateIdentifier/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengDuplicateIdentifier.GenerateMessage: String; begin result := 'duplicate identifier: ' + Name; if (New is TengShaderPart) then result := result + Format('(%s %d:%d)', [ (New as TengShaderPart).Filename, (New as TengShaderPart).Line, (New as TengShaderPart).Col]); if (Old is TengShaderPart) then result := result + Format('(previously declared here %s %d:%d)', [ (Old as TengShaderPart).Filename, (Old as TengShaderPart).Line, (Old as TengShaderPart).Col]); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld, aSender: TObject); begin Name := aName; New := aNew; Old := aOld; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengDuplicateIdentifier.Create(const aName: String; const aNew, aOld: TObject; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Name := aName; New := aNew; Old := aOld; inherited Create(aLine, aCol, aFilename, aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //EengUnknownIdentifier///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function EengUnknownIdentifier.GenerateMessage: String; begin result := 'unknown identifier: ' + Name; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengUnknownIdentifier.Create(const aName: String; const aSender: TObject); begin Name := aName; inherited Create(aSender); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor EengUnknownIdentifier.Create(const aName: String; aLine, aCol: Integer; const aFilename: String; const aSender: TObject); begin Name := aName; inherited Create(aLine, aCol, aFilename, aSender); end; end.