A module can have one or more export clauses and the name of an export clause doesn't have to be equal to the name of the module.
Sample module code with separate interface
and
implementation
parts:
module DemoModule interface; { interface part } export DemoModule = (FooType, SetFoo, GetFoo); type FooType = Integer; procedure SetFoo (f: FooType); function GetFoo: FooType; end. module DemoModule implementation; { implementation part } import StandardInput; StandardOutput; var Foo: FooType; { Note: the effect is the same as a `forward' directive would have: parameter lists and result types are not allowed in the declaration of exported routines, according to EP. In GPC, they are allowed, but not required. } procedure SetFoo; begin Foo := f end; function GetFoo; begin GetFoo := Foo end; to begin do begin Foo := 59; WriteLn ('Just an example of a module initializer. See comment below') end; to end do begin Foo := 0; WriteLn ('Goodbye') end; end.
Alternatively the module interface and implementation may be combined as follows:
module DemoMod2; { Alternative method } export Catch22 = (FooType, SetFoo, GetFoo); type FooType = Integer; procedure SetFoo (f: FooType); function GetFoo: FooType; end; { note: this `end' is required here, even if the module-block below would be empty. } var Foo: FooType; procedure SetFoo; begin Foo := f end; function GetFoo; begin GetFoo := Foo end; end.
Either one of the two methods may be used like this:
program ModuleDemo (Output); import DemoModule; begin SetFoo (999); WriteLn (GetFoo); end.
program ModDemo2 (Output); import Catch22 in 'demomod2.pas'; begin SetFoo (999); WriteLn (GetFoo); end.
Somewhat simpler GPC modules are also supported. Please note: This is not supported in the Extended Pascal standard.
This is a simpler module support that does not require exports, imports, module headers etc.
These non-standard simple GPC modules look like the following example. They do not have an export part, do not have a separate module-block, do not use import/export features.
Instead, you have to emulate the exporting/importing yourself using attribute and external name.
module DemoMod3; type FooType = Integer; var Foo: FooType; procedure SetFoo (f: FooType); attribute (name = 'SetFoo'); begin Foo := f end; function GetFoo: FooType; attribute (name = 'GetFoo'); begin GetFoo := Foo; end; end.
program ModDemo3 (Output); {$L demomod3.pas} { explicitly link module } { Manually do the "import" from DemoMod3 } type FooType = Integer; procedure SetFoo (f: FooType); external name 'SetFoo'; function GetFoo: FooType; external name 'GetFoo'; begin SetFoo (999); WriteLn (GetFoo) end.
Module initialization and finalization:
The to begin do
module initialization and to end do
module finalization constructs now work on every target.
By the way: The “GPC specific” module definition is almost identical to the PXSC standard. With an additional keyword `global' which puts a declaration into an export interface with the name of the module, it will be the same. @@This is planned.