FPC Compatibility


(Matt Robertson) #1

As discussed in this thread, there are a number of places where Oxygene is not compatible with FPC, at least as of Elements 10. These changes would go a long way toward allowing shared code between FPC and Oxygene targets.

  1. Conditional directive within a definition.

     	aBool, 
     {$IF NOT OXYGENE}
     	aBoolTwo, 
     {$ENDIF NOT OXYGENE}
     	aBoolThree: Boolean;
    
  2. Conditional directive within a case statement.

     CASE dataType OF
     	kDefault:
     	BEGIN
     		...
     	END;
     {$IF Target_Android}
     	kAndroidStuff:
     	BEGIN
     		...
     	END;
     {$ENDIF}
     END;
    
  3. otherwise keyword in case statements (already logged as bug #81607)

  4. Support for destructor keyword (not recognized even in Delphi compatibility mode). It would be nice to have a compatibility option at least to treat “destructor” as an alternative for “procedure” even though Oxygene doesn’t actually use destructors.

  5. Return function value by assigning to function name.

    function IsActive: boolean;
    begin
    IsActive := false;
    end;

  6. The compiler complains about not recognizing the {$ALIGN} directive. It seems like this should simply be ignored instead of throwing an error - again, at least in compatibility mode.


(marc hoffman) #2

otherwise should be implemented, since a few weeks ago (in (now misnamed <g>) Delphi Compatibility Mode only, of course).

Pretty sure destructor is supposed to work, as well. Can you give us a test case where it doesn’t?

The other suggestions, I’ll log.


(RemObjects) #3

Thanks, logged as bugs://81778 (IFDEFs)


(RemObjects) #4

Thanks, logged as bugs://81779 (result)


(RemObjects) #5

Thanks, logged as bugs://81780 (align)


(Matt Robertson) #6

Hmm I’m not seeing it on .2364. Created a new java console app, set Delphi Compatibility to ‘Yes’ in settings, added a case statement in main like this:

class method Main(args: array of String): Int32;
begin
  var i: LongInt;

  i := 3;
  
  case i of
    1:
      System.out.println('1');
    2:
      System.out.println('2');
    otherwise:
      System.out.println('other');
  end;
end;

I get build error Type mismatch, expected "Integer" on the “otherwise”.

Full project file looks like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProductVersion>3.5</ProductVersion>
    <ProjectGuid>{95484A6E-1A03-45FF-8853-74228EC13632}</ProjectGuid>
    <OutputType>Executable</OutputType>
    <Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
    <RootNamespace>otherwise</RootNamespace>
    <DefaultUses>remobjects.elements.rtl</DefaultUses>
    <DelphiCompatibility>True</DelphiCompatibility>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <Optimize>False</Optimize>
    <OutputPath>.\Bin\Debug</OutputPath>
    <DefineConstants>DEBUG;TRACE;</DefineConstants>
    <GenerateDebugInfo>True</GenerateDebugInfo>
    <EnableAsserts>True</EnableAsserts>
    <CpuType>anycpu</CpuType>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <OutputPath>.\Bin\Release</OutputPath>
    <CpuType>anycpu</CpuType>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="rt" />
    <Reference Include="cooper">
      <Private>True</Private>
    </Reference>
    <Reference Include="elements">
      <Private>True</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.pas" />
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.Cooper.targets" />
</Project>

(marc hoffman) #7

Hmm, reproduced. will reopen. […] ah my bad, looks like we had a commit for it, nit the issue isn’t closed yet. I’ll follow up with the compiler team.

Side Q: does otherwise need the : or nor? else does NOT use a colon, and I had assumed otherwise was supposed to work interchangeably with else, in case?


(RemObjects) #9

Thanks, logged as bugs://81783 (Destroy)


(Matt Robertson) #10

My mistake - no it does not need the colon.


(RemObjects) #11

bugs://81780 got closed with status fixed.


(Carlo Kok) #12

Fixed.

Fixed.

Destroy compiles now too but I have to think about what to best map that to.


(Carlo Kok) #13

can you give a more complete example of this?

  case i of
    1:
      writeLn('1');
    2:
      writeLn('2');
    {$IFDEF TEST}
    3: writeLn("");
    {$ENDIF}
    otherwise
      writeLn('other');
  end;

works fine.

What kind of definition? Method def, variable def?


(Matt Robertson) #14

Hmm I’ll have to play around with the first one to see what was causing the problem - it is working fine for me too. I actually noticed the problem in Water’s code complete, not EBuild. I have the legacy preprocessor enabled in my project, so the compiler doesn’t complain about these, but Water still appears to use the Elements 10 preprocessor for code complete. That said, this is the same problem I was originally having with the compiler before enabling legacy preprocessor. I’ll try to see if I can figure out what’s actually causing a problem with this.

Variable definitions, as in the specific case I mentioned here. I can wrap entire method definitions in a directive without issue. I can also wrap a variable definition without issue, I just can’t wrap in the middle of a variable definition as in the example above.


(marc hoffman) #15

Fixed, thanx!


(Matt Robertson) #16

Another compatibility issue is the original one from this thread that it seems we all forgot about by the end of the thread (myself included) :slight_smile:

{$if TARGET_RT_BIG_ENDIAN}
type
	wide = record
		case boolean of
			false:
				(hi: SInt32;
				 lo: UInt32);
			true:
				(int:	SInt64)
	end;
{$endif}

It seems that case statements are not allowed in records, even in a false ifdef. I understand it must be syntactically correct throughout, but it would be fantastic for compatibility to at least allow FPC-correct syntax in undefined blocks as Marc mentioned in that thread.


(Carlo Kok) #17

Whoops yes. I’ve logged a new bug so we can’t lose track of it.


(Carlo Kok) #18

Just to be clear; this thread is now solved for you?


(Matt Robertson) #19

Yes. Thanks!


(RemObjects) #20

bugs://81778 got closed with status fixed.


(Matt Robertson) #21

@ck Actually I just noticed, destructor still does not seem to be supported, at least by the Water IDE. The changelog for .2365 shows
81783: Delphi/FPC Compatibility: support for destructor (wip)

When I compile with DESTRUCTOR Destroy; in Water it shows error colon (:) expected.