generation of pascal code for simple headers is nearly complete

This commit is contained in:
ocoursiere
2002-11-19 00:29:01 +00:00
parent 6c12d69ffa
commit 8b6fc36fab
3 changed files with 160 additions and 35 deletions

View File

@@ -25,6 +25,9 @@ interface
uses uses
Classes, SysUtils, xmlread, dom; Classes, SysUtils, xmlread, dom;
const
ImportFuncString = ' cdecl; external BePascalLibName name ''%s_%s'';';
type type
TNode = class(TObject) TNode = class(TObject)
private private
@@ -92,6 +95,7 @@ type
private private
FResultType : TResultType; FResultType : TResultType;
FClasse : TClasse; FClasse : TClasse;
BodyPas : string;
function GetParam(Index : integer) : TParam; function GetParam(Index : integer) : TParam;
protected protected
public public
@@ -100,6 +104,10 @@ type
function IsConstructor : boolean; function IsConstructor : boolean;
function IsDestructor : boolean; function IsDestructor : boolean;
function HasParams : boolean; function HasParams : boolean;
function ProcName : string;
function ProcNameInObject : string;
function SelfParam : string;
function SelfParamImpl : string;
procedure Start; override; procedure Start; override;
procedure Ends; override; procedure Ends; override;
property ResultType : TResultType read FResultType; property ResultType : TResultType read FResultType;
@@ -111,13 +119,16 @@ type
protected protected
function GetType : string; function GetType : string;
public public
function IsObject : boolean;
property Typ : string read GetType; property Typ : string read GetType;
end; end;
TParam = class(TTypedItem) TParam = class(TTypedItem)
private private
FFunction : TFunction;
protected protected
public public
procedure Middle; override; procedure Middle; override;
property ParentFunction : TFunction read FFunction;
end; end;
TResultType = class(TNode) TResultType = class(TNode)
private private
@@ -372,6 +383,7 @@ begin
if Node.ChildNodes.Item[i].Attributes.GetNamedItem('NAME') <> nil then if Node.ChildNodes.Item[i].Attributes.GetNamedItem('NAME') <> nil then
begin begin
aParam := TParam.Create(Node.ChildNodes.Item[i]); aParam := TParam.Create(Node.ChildNodes.Item[i]);
aParam.FFunction := Self;
WriteLn('Param : ' + aParam.Name + '; ' + 'Type : ' + aParam.Typ); WriteLn('Param : ' + aParam.Name + '; ' + 'Type : ' + aParam.Typ);
List.AddObject(aParam.Name, aParam); List.AddObject(aParam.Name, aParam);
end end
@@ -412,6 +424,42 @@ begin
Result := (Count > 0); Result := (Count > 0);
end; end;
function TFunction.ProcName : string;
begin
if IsConstructor then
Result := 'Create'
else if IsDestructor then
Result := 'Free'
else
Result := Name;
end;
function TFunction.ProcNameInObject : string;
begin
if IsConstructor then
Result := 'Create'
else if IsDestructor then
Result := 'Destroy'
else
Result := Name;
end;
function TFunction.SelfParam : string;
begin
if IsConstructor then
Result := '(AObject : TBeObject; '
else
Result := '(AObject : TCPlusObject; '
end;
function TFunction.SelfParamImpl : string;
begin
if IsConstructor then
Result := '(Self, '
else
Result := '(CPlusObject, '
end;
procedure TFunction.Start; procedure TFunction.Start;
var var
EndChar : string; EndChar : string;
@@ -424,49 +472,101 @@ begin
with SourceWriter.InterfacePas do with SourceWriter.InterfacePas do
begin begin
if IsConstructor then if IsConstructor then
Add(Format(' constructor %s%s', [Name, EndChar])) Add(Format(' constructor %s%s', [ProcNameInObject, EndChar]))
else if IsDestructor then else if IsDestructor then
Add(Format(' destructor %s%s', [Name, EndChar])) Add(Format(' destructor %s%s', [ProcNameInObject, EndChar]))
else if (ResultType.Typ = '') or (ResultType.Typ = 'void') then else if (ResultType.Typ = '') or (ResultType.Typ = 'void') then
Add(Format(' procedure %s%s', [Name, EndChar])) Add(Format(' procedure %s%s', [Name, EndChar]))
else else
Add(Format(' function %s%s', [Name, EndChar])); Add(Format(' function %s%s', [Name, EndChar]));
end; end;
// Import of C functions
with SourceWriter.ImportFuncsPas do
begin
if (ResultType.Typ = '') or (ResultType.Typ = 'void') then
Add(Format('procedure %s_%s%s', [Classe.Name, ProcName, SelfParam]))
else
Add(Format('function %s_%s%s', [Classe.Name, ProcName, SelfParam]));
end;
with SourceWriter.ImplementationPas do
begin
if (ResultType.Typ = '') or (ResultType.Typ = 'void') then
Add(Format('procedure %s.%s%s', [CppToPas(Classe.Name + ' *'), ProcName, EndChar]))
else
Add(Format('function %s.%s%s', [CppToPas(Classe.Name + ' *'), ProcName, EndChar]));
end;
//Body
if (ResultType.Typ = '') or (ResultType.Typ = 'void') then
BodyPas := Format(' %s_%s%s', [Classe.Name, ProcName, SelfParamImpl])
else
BodyPas := Format(' %s_%s%s', [Classe.Name, ProcName, SelfParamImpl]);
end; end;
procedure TFunction.Ends; procedure TFunction.Ends;
var var
s : string;
EndChar : string; EndChar : string;
begin procedure DeleteLastSep(List : TStringList);
WriteLn('Function ends'); var
if hasParams then s : string;
begin begin
EndChar := ')'; // Delete the last '; '
with SourceWriter.InterfacePas do s := List.Strings[List.Count - 1];
begin System.Delete(s, Length(s) - 1, 2);
// Delete the last '; ' List.Strings[List.Count - 1] := s;
s := Strings[Count - 1];
System.Delete(s, Length(s) - 1, 2);
Strings[Count - 1] := s;
end;
end
else
begin
EndChar := '';
end; end;
with SourceWriter.InterfacePas do procedure AddLastSep(List : TStringList);
var
s : string;
begin begin
if not((ResultType.Typ = '') or (ResultType.Typ = 'void')) then if not((ResultType.Typ = '') or (ResultType.Typ = 'void')) then
begin begin
WriteLn(ResultType.Typ); WriteLn(ResultType.Typ);
WriteLn(Name); WriteLn(Name);
s := Format('%s%s : %s;', [Strings[Count - 1], EndChar, CppToPas(ResultType.Typ)]); s := Format('%s%s : %s;', [List.Strings[List.Count - 1], EndChar, CppToPas(ResultType.Typ)]);
Strings[Count - 1] := s; List.Strings[List.Count - 1] := s;
end end
else else
Strings[Count - 1] := Format('%s%s;', [Strings[Count - 1], EndChar]); List.Strings[List.Count - 1] := Format('%s%s;', [List.Strings[List.Count - 1], EndChar]);
end; end;
var
s : string;
begin
WriteLn('Function ends');
if hasParams then
begin
EndChar := ')';
DeleteLastSep(SourceWriter.InterfacePas);
end
else
begin
EndChar := '';
end;
AddLastSep(SourceWriter.InterfacePas);
// Import C functions
EndChar := ')';
DeleteLastSep(SourceWriter.ImportFuncsPas);
AddLastSep(SourceWriter.ImportFuncsPas);
with SourceWriter.ImportFuncsPas do
begin
s := Format('%s' + ImportFuncString, [Strings[Count - 1], Classe.Name, ProcName]);
Strings[Count - 1] := s;
end;
if hasParams then
begin
EndChar := ')';
DeleteLastSep(SourceWriter.ImplementationPas);
end
else
begin
EndChar := '';
end;
AddLastSep(SourceWriter.ImplementationPas);
SourceWriter.ImplementationPas.Add('begin');
System.Delete(BodyPas, Length(BodyPas) - 1, 2);
SourceWriter.ImplementationPas.Add(BodyPas + ');');
SourceWriter.ImplementationPas.Add('end;');
SourceWriter.ImplementationPas.Add('');
end; end;
function TTypedItem.GetType : string; function TTypedItem.GetType : string;
@@ -474,18 +574,31 @@ begin
Result := FNode.Attributes.GetNamedItem('TYPE').NodeValue; Result := FNode.Attributes.GetNamedItem('TYPE').NodeValue;
end; end;
function TTypedItem.IsObject : boolean;
begin
// The first letter is a 'B' -> this is an object !
Result := (Typ[1] = 'B');
end;
procedure TParam.Middle; procedure TParam.Middle;
var procedure WriteParam(List : TStringList);
s : string; var
s : string;
begin
WriteLn(List.Strings[List.Count - 1]);
s := Format('%s%s : %s; ', [List.Strings[List.Count - 1], Name, CppToPas(Typ)]);
List.Strings[List.Count - 1] := s;
WriteLn(List.Strings[List.Count - 1]);
end;
begin begin
WriteLn('Param Middle'); WriteLn('Param Middle');
with SourceWriter.InterfacePas do WriteParam(SourceWriter.InterfacePas);
begin WriteParam(SourceWriter.ImportFuncsPas);
WriteLn(Strings[Count - 1]); WriteParam(SourceWriter.ImplementationPas);
s := Format('%s%s : %s; ', [Strings[Count - 1], Name, CppToPas(Typ)]); if IsObject then
Strings[Count - 1] := s; ParentFunction.BodyPas := Format('%s%s.CPlusObject, ', [ParentFunction.BodyPas, Name])
WriteLn(Strings[Count - 1]); else
end; ParentFunction.BodyPas := Format('%s%s, ', [ParentFunction.BodyPas, Name]);
end; end;
function TResultType.GetType : string; function TResultType.GetType : string;

View File

@@ -118,8 +118,10 @@ begin
FCpp.SaveToFile(FFileName + '.cpp'); FCpp.SaveToFile(FFileName + '.cpp');
FCpp.Free; FCpp.Free;
FPas.Add(FInterfacePas.Text); FPas.Add(FInterfacePas.Text);
FPas.Add(FImplementationPas.Text);
FPas.Add(FImportFuncsPas.Text); FPas.Add(FImportFuncsPas.Text);
FPas.Add('implementation');
FPas.Add('');
FPas.Add(FImplementationPas.Text);
// write the end of pascal unit // write the end of pascal unit
FPas.Add('end.'); FPas.Add('end.');
FPas.SaveToFile(LowerCase(FFileName) + '.pp'); FPas.SaveToFile(LowerCase(FFileName) + '.pp');

View File

@@ -14,12 +14,18 @@ const
TypMapFileName = 'typemap.txt'; TypMapFileName = 'typemap.txt';
var var
aTypMap : TStringList; aTypMap : TStringList;
NewTypMap : TStringList;
function CppToPas(CppType : string) : string; function CppToPas(CppType : string) : string;
var
i : integer;
begin begin
Result := aTypMap.Values[CppType]; Result := aTypMap.Values[CppType];
// if Result = '' then if Result = '' then
// aTypMap.Values[CppType] := ''; begin
if not NewTypMap.Find(CppType + '=', i) then
NewTypMap.Add(CppType + '=');
end;
end; end;
function PasToCpp(PasType : string) : string; function PasToCpp(PasType : string) : string;
@@ -32,10 +38,14 @@ initialization
aTypMap := TStringList.Create; aTypMap := TStringList.Create;
aTypMap.LoadFromFile(TypMapFileName); aTypMap.LoadFromFile(TypMapFileName);
aTypMap.Sorted := True; aTypMap.Sorted := True;
NewTypMap := TStringList.Create;
NewTypMap.Sorted := True;
finalization finalization
// WriteLn(aTypMap.Text); // WriteLn(aTypMap.Text);
aTypMap.SaveToFile(TypMapFileName); aTypMap.SaveToFile(TypMapFileName);
aTypMap.Free; aTypMap.Free;
NewTypMap.SaveToFile(TypMapFileName + '.new');
NewTypMap.Free;
end. end.