2026-05-02 00:53:56 +03:00
|
|
|
{
|
|
|
|
|
Blaise - An Object Pascal Compiler
|
|
|
|
|
Copyright (c) 2026 Graeme Geldenhuys
|
2026-05-03 21:45:29 +03:00
|
|
|
SPDX-License-Identifier: Apache-2.0 WITH Swift-exception
|
|
|
|
|
Licensed under the Apache License v2.0 with Runtime Library Exception.
|
2026-05-02 00:53:56 +03:00
|
|
|
See LICENSE file in the project root for full license terms.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unit cp.test.opdf;
|
|
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
|
|
uses
|
|
|
|
|
Classes, SysUtils, fpcunit, testregistry,
|
|
|
|
|
uLexer, uParser, uAST, uSemantic, uDebugOPDF;
|
|
|
|
|
|
|
|
|
|
type
|
|
|
|
|
TOPDFTests = class(TTestCase)
|
|
|
|
|
private
|
|
|
|
|
function GenOPDF(const ASrc: string): string;
|
|
|
|
|
function Contains(const AText, AFragment: string): Boolean;
|
|
|
|
|
published
|
|
|
|
|
procedure TestOPDF_SectionDeclaration;
|
|
|
|
|
procedure TestOPDF_HeaderMagic;
|
|
|
|
|
procedure TestOPDF_HeaderVersion;
|
|
|
|
|
procedure TestOPDF_TotalRecordsPatched;
|
|
|
|
|
procedure TestOPDF_Primitive_Integer;
|
|
|
|
|
procedure TestOPDF_Primitive_Boolean;
|
|
|
|
|
procedure TestOPDF_Primitive_Int64;
|
|
|
|
|
procedure TestOPDF_AnsiStr_Record;
|
|
|
|
|
procedure TestOPDF_GlobalVar_QuadLabel;
|
|
|
|
|
procedure TestOPDF_GlobalVar_RecType;
|
|
|
|
|
procedure TestOPDF_Enum_RecType;
|
|
|
|
|
procedure TestOPDF_Enum_MemberName;
|
|
|
|
|
procedure TestOPDF_Class_RecType;
|
|
|
|
|
procedure TestOPDF_Class_VtableRef;
|
|
|
|
|
procedure TestOPDF_FunctionScope_RecType;
|
|
|
|
|
procedure TestOPDF_FunctionScope_LowPC;
|
|
|
|
|
procedure TestOPDF_Parameter_RecType;
|
|
|
|
|
procedure TestOPDF_LocalVar_RecType;
|
|
|
|
|
procedure TestOPDF_LocalVar_RBPOffset;
|
|
|
|
|
procedure TestOPDF_LineInfo_RecType;
|
|
|
|
|
procedure TestOPDF_LineInfo_FileName;
|
|
|
|
|
procedure TestOPDF_LineInfo_LineNumber;
|
2026-05-02 01:16:31 +03:00
|
|
|
procedure TestOPDF_MainScope_RecType;
|
|
|
|
|
procedure TestOPDF_MainScope_LowPC;
|
|
|
|
|
procedure TestOPDF_MainScope_LineInfo;
|
2026-05-02 01:37:07 +03:00
|
|
|
{ Step 6c }
|
|
|
|
|
procedure TestOPDF_Pointer_RecType;
|
|
|
|
|
procedure TestOPDF_Array_Static_RecType;
|
|
|
|
|
procedure TestOPDF_Array_Static_IsDynamic;
|
|
|
|
|
procedure TestOPDF_Set_RecType;
|
|
|
|
|
procedure TestOPDF_Set_SizeInBytes;
|
|
|
|
|
procedure TestOPDF_Property_RecType;
|
|
|
|
|
procedure TestOPDF_Interface_RecType;
|
|
|
|
|
procedure TestOPDF_Constant_OrdRecord;
|
|
|
|
|
procedure TestOPDF_Constant_OrdValue;
|
|
|
|
|
procedure TestOPDF_Constant_StrRecord;
|
|
|
|
|
procedure TestOPDF_UnitDir_Present;
|
|
|
|
|
procedure TestOPDF_UnitDir_UnitCount;
|
2026-05-02 00:53:56 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
|
|
function TOPDFTests.GenOPDF(const ASrc: string): string;
|
|
|
|
|
var
|
|
|
|
|
L: TLexer;
|
|
|
|
|
P: TParser;
|
|
|
|
|
Pr: TProgram;
|
|
|
|
|
A: TSemanticAnalyser;
|
|
|
|
|
E: TOPDFEmitter;
|
|
|
|
|
begin
|
|
|
|
|
L := TLexer.Create(ASrc);
|
|
|
|
|
P := TParser.Create(L);
|
|
|
|
|
Pr := P.Parse;
|
|
|
|
|
A := TSemanticAnalyser.Create;
|
|
|
|
|
try
|
|
|
|
|
A.Analyse(Pr);
|
|
|
|
|
E := TOPDFEmitter.Create(Pr, 'test.pas');
|
|
|
|
|
try
|
|
|
|
|
Result := E.GetOutput;
|
|
|
|
|
finally
|
|
|
|
|
E.Free;
|
|
|
|
|
end;
|
|
|
|
|
finally
|
|
|
|
|
A.Free;
|
|
|
|
|
Pr.Free;
|
|
|
|
|
P.Free;
|
|
|
|
|
L.Free;
|
|
|
|
|
end;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
function TOPDFTests.Contains(const AText, AFragment: string): Boolean;
|
|
|
|
|
begin
|
|
|
|
|
Result := Pos(AFragment, AText) > 0;
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
{ ------------------------------------------------------------------ }
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_SectionDeclaration;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('section directive present', Contains(Out, '.section .opdf'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_HeaderMagic;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('OPDF magic bytes present', Contains(Out, '.byte 79, 80, 68, 70'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_HeaderVersion;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('version word present', Contains(Out, '.word 1'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_TotalRecordsPatched;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; var X: Integer; begin end.');
|
|
|
|
|
AssertFalse('TotalRecords not still zero placeholder',
|
|
|
|
|
Contains(Out, '.int 0 # TotalRecords'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Primitive_Integer;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; var X: Integer; begin end.');
|
|
|
|
|
AssertTrue('recPrimitive Integer comment', Contains(Out, '# recPrimitive: Integer'));
|
|
|
|
|
AssertTrue('Integer name emitted', Contains(Out, '.ascii "Integer"'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Primitive_Boolean;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('recPrimitive Boolean present', Contains(Out, '# recPrimitive: Boolean'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Primitive_Int64;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('recPrimitive Int64 present', Contains(Out, '# recPrimitive: Int64'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_AnsiStr_Record;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
2026-05-02 14:31:47 +03:00
|
|
|
AssertTrue('recUtf8Str present', Contains(Out, '# recUtf8Str'));
|
|
|
|
|
AssertTrue('Utf8String name emitted', Contains(Out, '.ascii "Utf8String"'));
|
2026-05-02 00:53:56 +03:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_GlobalVar_QuadLabel;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var MyVar: Integer;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('global var .quad label', Contains(Out, '.quad MyVar'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_GlobalVar_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var MyVar: Integer;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recGlobalVar comment', Contains(Out, '# recGlobalVar: MyVar'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Enum_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type TColor = (clRed, clGreen, clBlue);' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recEnum comment', Contains(Out, '# recEnum: TColor'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Enum_MemberName;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type TColor = (clRed, clGreen, clBlue);' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('enum member name in output', Contains(Out, '.ascii "clRed"'));
|
|
|
|
|
AssertTrue('second member', Contains(Out, '.ascii "clBlue"'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Class_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type' + LineEnding +
|
|
|
|
|
' TDog = class' + LineEnding +
|
|
|
|
|
' FName: string;' + LineEnding +
|
|
|
|
|
' end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recClass comment', Contains(Out, '# recClass: TDog'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Class_VtableRef;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type' + LineEnding +
|
|
|
|
|
' TDog = class' + LineEnding +
|
|
|
|
|
' FName: string;' + LineEnding +
|
|
|
|
|
' end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('vtable reference in class record', Contains(Out, 'vtable_TDog'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_FunctionScope_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Greet;' + LineEnding +
|
|
|
|
|
'begin end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recFunctionScope comment', Contains(Out, '# recFunctionScope: Greet'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_FunctionScope_LowPC;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Greet;' + LineEnding +
|
|
|
|
|
'begin end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('LowPC label reference', Contains(Out, '.quad Greet'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Parameter_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Greet(Name: string);' + LineEnding +
|
|
|
|
|
'begin end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recParameter comment', Contains(Out, '# recParameter: Name'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_LocalVar_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Compute;' + LineEnding +
|
|
|
|
|
'var Total: Integer;' + LineEnding +
|
|
|
|
|
'begin end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recLocalVar comment', Contains(Out, '# recLocalVar: Total'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_LocalVar_RBPOffset;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Compute;' + LineEnding +
|
|
|
|
|
'var Total: Integer;' + LineEnding +
|
|
|
|
|
'begin end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('RBP offset line present', Contains(Out, '# LocationData (RBP offset)'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_LineInfo_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Work;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recLineInfo record present', Contains(Out, '# recLineInfo'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_LineInfo_FileName;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Work;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('source filename in line info', Contains(Out, '.ascii "test.pas"'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_LineInfo_LineNumber;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'procedure Work;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('line 5 recorded', Contains(Out, '.int 5 # LineNumber'));
|
|
|
|
|
end;
|
|
|
|
|
|
2026-05-02 01:16:31 +03:00
|
|
|
procedure TOPDFTests.TestOPDF_MainScope_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end.');
|
|
|
|
|
AssertTrue('recFunctionScope for main', Contains(Out, '# recFunctionScope: P'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_MainScope_LowPC;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end.');
|
|
|
|
|
AssertTrue('main LowPC label', Contains(Out, '.quad main'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_MainScope_LineInfo;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var X: Integer;' + LineEnding +
|
|
|
|
|
'begin' + LineEnding +
|
|
|
|
|
' X := 1;' + LineEnding +
|
|
|
|
|
'end.');
|
|
|
|
|
AssertTrue('line 4 in main body recorded', Contains(Out, '.int 4 # LineNumber'));
|
|
|
|
|
end;
|
|
|
|
|
|
2026-05-02 01:37:07 +03:00
|
|
|
procedure TOPDFTests.TestOPDF_Pointer_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
{ Use ^Integer as a class field type — inline pointer types work
|
|
|
|
|
in field/var positions even though 'type T = ^Foo' in the type
|
|
|
|
|
section is not yet parsed }
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type TFoo = class' + LineEnding +
|
|
|
|
|
' FNext: ^Integer;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recPointer comment', Contains(Out, '# recPointer: ^Integer'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Array_Static_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
{ Inline array type in global var — type section array decls not yet parsed }
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var A: array[1..5] of Integer;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recArray comment',
|
|
|
|
|
Contains(Out, '# recArray (static): array[1..5] of Integer'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Array_Static_IsDynamic;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'var A: array[1..5] of Integer;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('IsDynamic=0 for static array', Contains(Out, '.byte 0 # IsDynamic'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Set_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type' + LineEnding +
|
|
|
|
|
' TDays = (Mon, Tue, Wed);' + LineEnding +
|
|
|
|
|
' TDaySet = set of TDays;' + LineEnding +
|
|
|
|
|
'var S: TDaySet;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recSet comment', Contains(Out, '# recSet: TDaySet'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Set_SizeInBytes;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type' + LineEnding +
|
|
|
|
|
' TDays = (Mon, Tue, Wed);' + LineEnding +
|
|
|
|
|
' TDaySet = set of TDays;' + LineEnding +
|
|
|
|
|
'var S: TDaySet;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('SizeInBytes=4 for small set', Contains(Out, '.byte 4 # SizeInBytes'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Property_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type TFoo = class' + LineEnding +
|
|
|
|
|
' FVal: Integer;' + LineEnding +
|
|
|
|
|
' property Val: Integer read FVal write FVal;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recProperty comment', Contains(Out, '# recProperty: Val'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Interface_RecType;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'type IGreeter = interface' + LineEnding +
|
|
|
|
|
' procedure Greet;' + LineEnding +
|
|
|
|
|
'end;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recInterface comment', Contains(Out, '# recInterface: IGreeter'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Constant_OrdRecord;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'const MaxVal = 100;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recConstant for integer', Contains(Out, '# recConstant: MaxVal'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Constant_OrdValue;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'const MaxVal = 100;' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('constant value embedded', Contains(Out, '.quad 100 # Value'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_Constant_StrRecord;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF(
|
|
|
|
|
'program P;' + LineEnding +
|
|
|
|
|
'const Greeting = ''Hello'';' + LineEnding +
|
|
|
|
|
'begin end.');
|
|
|
|
|
AssertTrue('recConstant for string', Contains(Out, '# recConstant: Greeting'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_UnitDir_Present;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('recUnitDirectory present', Contains(Out, '# recUnitDirectory'));
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure TOPDFTests.TestOPDF_UnitDir_UnitCount;
|
|
|
|
|
var
|
|
|
|
|
Out: string;
|
|
|
|
|
begin
|
|
|
|
|
Out := GenOPDF('program P; begin end.');
|
|
|
|
|
AssertTrue('unit count is 1', Contains(Out, '.int 1 # UnitCount'));
|
|
|
|
|
end;
|
|
|
|
|
|
2026-05-02 00:53:56 +03:00
|
|
|
initialization
|
|
|
|
|
RegisterTest(TOPDFTests);
|
|
|
|
|
|
|
|
|
|
end.
|