Difference between revisions of "Language Reference/Attributes"
(→Insertion Points: facts) |
(All programPoint info moved here) |
||
(76 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
{{languageReferenceNavbar|Attributes}} | {{languageReferenceNavbar|Attributes}} | ||
Various declarations can be annotated with attributes. | Various definitions and declarations can be annotated with attributes. This section describes the general syntax of attributes and where they can be placed. It also describes the meaning of the specific attributes. | ||
=== Syntax === | === Syntax === | ||
Line 12: | Line 12: | ||
<LowerCaseIdentifier> ( <Literal>-comma-sep-list )</vipbnf> | <LowerCaseIdentifier> ( <Literal>-comma-sep-list )</vipbnf> | ||
where the literals must either be numbers or string literals. | |||
=== Insertion Points === | === Insertion Points === | ||
The attributes of interfaces, classes and implementations | The attributes of interfaces, classes and implementations are right after the scope qualifications. | ||
<vipbnf><InterfaceDeclaration> : | <vipbnf><InterfaceDeclaration> : | ||
interface <IinterfaceName> | |||
<ScopeQualifications> | |||
<Attributes>-opt | |||
<Sections> | |||
end interface <IinterfaceName>-opt</vipbnf> | |||
<vipbnf><ClassDeclaration> : | <vipbnf><ClassDeclaration> : | ||
class <ClassName> <ConstructionType>-opt | |||
<ScopeQualifications> | |||
<Attributes>-opt | |||
<Sections> | |||
end class <ClassName>-opt</vipbnf> | |||
<vipbnf><ClassImplementation> : | <vipbnf><ClassImplementation> : | ||
implement <ClassName> < | implement <ClassName> | ||
<ScopeQualifications> | |||
<Attributes>-opt | |||
<Sections> | |||
end implement <ClassName>-opt</vipbnf> | |||
The attributes of constants, domains, predicates, properties and facts | The attributes of constants, domains, predicates, properties and facts are at the end (i.e. right before the terminating dot). | ||
<vipbnf><ConstantDefinition>: one of | <vipbnf><ConstantDefinition>: one of | ||
<ConstantName> = <ConstantValue> <Attributes> | <ConstantName> = <ConstantValue> <Attributes>-opt | ||
<ConstantName> : <TypeName> = <ConstantValue> <Attributes></vipbnf> | <ConstantName> : <TypeName> = <ConstantValue> <Attributes>-opt</vipbnf> | ||
<vipbnf><DomainDefinition>: | <vipbnf><DomainDefinition>: | ||
<DomainName> <FormalTypeParameterList>-opt = <TypeExpression> <Attributes></vipbnf> | <DomainName> <FormalTypeParameterList>-opt = <TypeExpression> <Attributes>-opt</vipbnf> | ||
<vipbnf><PredicateDeclaration> : | <vipbnf><PredicateDeclaration> : | ||
<PredicateName> : <PredicateDomain> <LinkName>-opt <Attributes>-opt | |||
<PredicateName> : <PredicateDomainName> <LinkName>-opt <Attributes>-opt</vipbnf> | |||
<vipbnf><PropertyDeclaration> : | <vipbnf><PropertyDeclaration> : | ||
<PropertyName> : <PropertyType> <FlowPattern>-list-opt <Attributes></vipbnf> | <PropertyName> : <PropertyType> <FlowPattern>-list-opt <Attributes>-opt</vipbnf> | ||
<vipbnf><FactDeclaration> : | <vipbnf><FactDeclaration> : | ||
<FactVariableDeclaration> <Attributes>-opt | |||
<FactFunctorDeclaration> <Attributes>-opt</vipbnf> | |||
The attributes of formal arguments are at the end. | |||
<vipbnf><FormalArgument> : | |||
<TypeExpression> <ArgumentName>-opt <Attributes>-opt</vipbnf> | |||
=== Specific Attributes === | === Specific Attributes === | ||
==== attribute ==== | |||
This attribute is used on a functor domain to indicate that the functors in the domain can be used as attributes elsewhere in the program. | |||
{{Example| | |||
<vip> | |||
domains | |||
meta = | |||
meta; | |||
metaDisplayAs(string DisplayAs) [attribute]. | |||
</vip> | |||
}} | |||
See [[Program Defined Attributes]]. | |||
==== byVal ==== | |||
An argument is transferred directly on the stack rather than using a pointer. Valid for formal predicate arguments provided the <vp>language</vp> is <vp>stdcall</vp>, <vp>apicall</vp> or <vp>c</vp>. | |||
{{Example| | |||
<vip> | |||
domains | |||
point = point(integer X, integer Y). | |||
predicates | |||
externalP : (point Point [byVal]) language apicall. | |||
</vip>}} | |||
The attribute can also be used in combination with the <vp>out</vp> attribute: | |||
{{Example| | |||
<vip> | |||
predicates | |||
externalP2 : (point Point [byVal, out]) language apicall. | |||
</vip>}} | |||
In that case a <vp>point</vp> structure will be allocated before the call then a pointer to that structure is transferred handed to the external predicate which can then fill the structure with relevant data. | |||
==== classInitializer ==== | |||
This attribute indicates that a predicate should be invoked as a class initializer. It can be applied to a class predicate that does not take any arguments. The predicate will be invoked when the initialization code invokes the <vp>runtime_api::runProgramInitialization</vp>. A class can have any number of class initializer which will be invoked in an undetermined order. Notice that other classes may not have been initialized. | |||
The predicate <vp>xxx::initialize</vp> is registered as a class initializer: | |||
<vip> | |||
implement xxx | |||
class predicates | |||
initialize : () [classInitializer]. | |||
clauses | |||
initialize() :- | |||
… | |||
end class xxx | |||
</vip> | |||
==== constant ==== | |||
The <vp>constant</vp> attribute is used to declare fact variables that cannot be changed once they have been initialized. | |||
See {{lang2|Facts|Constant fact variables|Constant fact variables}}. | |||
==== compiletimeSetting ==== | |||
The <vp>compiletimeSetting</vp> attribute indicates that a constant should be considered a compiletime setting. As a result the compiler will suppress warnings about always failing/succeding code and about unreachable code that may be caused by this constant. The warning suppession is an approximation, because it a may be impossible/difficult to determine the cause of a warning. | |||
<vip> | |||
implement xxx | |||
constants | |||
debugOutput : boolean = false [compiletimeSetting]. | |||
clauses | |||
pppp(...) :- | |||
... | |||
if true = debugOutput then | |||
% do not give a warning about unreachable code | |||
log::write(...) | |||
end if, | |||
... | |||
end implement xxx | |||
</vip> | |||
==== default ==== | |||
It is problematic to update functor domains, if terms have been persisted in serialized form. Because new programs cannot deal with old serializations. | |||
The two attributes <vp>default/1</vp> and <vp>retiredFunctor/1</vp> can help dealing with this problem. | |||
The last arguments of a functor can have default values: | |||
<vip> | |||
domains | |||
ppp = | |||
fct( | |||
integer A, | |||
real B, | |||
ddd C, | |||
integer* New [default([])], | |||
real New2 [default(0)] | |||
). | |||
</vip> | |||
The default attribute does not change anything within the program; it only affects the deserialization. If during deserialization we meet the closing parenthesis too soon we supply default values for the remaining arguments. | |||
'''Notice''' that this will only work for '''text''' deserialization. | |||
See also [[Functor Domain Versioning]]. | |||
==== deprecated ==== | ==== deprecated ==== | ||
The declared entity is deprecated | The declared entity is deprecated. The string literal describes how to migrate from it. The entity still exists, but usage will cause a warning. | ||
The entity will not exist in future versions of Visual Prolog. | The entity will not exist in future versions of Visual Prolog. Valid for member declarations and scopes. | ||
{{Example| | |||
<vip>predicates | |||
oldFashioned : (string Arg) [deprecated("Use newFashion instead")].</vip> | |||
}} | |||
==== explicitTag ==== | |||
This predicate can be used on a functor domain to ensure that the memory representation of all terms have a functor. Without this attribute the compiler optimizes the representation such that some alternatives doesn't have a functor in the term, and such that functors with arguments are represented as a pointer value. The main purpose of this attribute is to ensure compatibility with foreign code. | |||
{{Example| | |||
<vip>domains | |||
menu = | |||
resMenu(resid Resid); | |||
dynMenu(menuItem* SubMenu); | |||
noMenu | |||
[explicitTag].</vip> | |||
}} | |||
==== formatString ==== | |||
The argument is a format string for a subsequent ellipsis argument (i.e. <vp>...</vp>). Valid for one string argument of a predicate with an ellipsis argument. The use of <vp>formatString</vp> will make the compiler check the validity of actual arguments with respect to actual format strings (where possible). | |||
{{Example| | {{Example| | ||
<vip>predicates | <vip>predicates | ||
writef : (string Format [formatString], ...).</vip> | |||
}} | }} | ||
==== | The format string can contain ordinary characters which are printed without modification, and format fields, that begins with the percent <vp>%</vp> sign. If the percent sign is followed by some unknown character (not the format specifier) - then this character will be printed without modifications. To output a <vp>%</vp> character you must write <vp>%%</vp> in the format string. | ||
<vip>predicates | |||
writef : (string Format [formatstring], ...).</vip> | |||
The format fields specification is: | |||
[-][0][width][.precision][type] | |||
All fields are optional. | |||
[-] Hyphen indicates that the field is to be left justified; right justified is the default. Having no effect when width value is not set, or the number of characters in the actual value is greater than width value. | |||
[0] Zero before width means for values that zeros will be added until the minimum width is reached. If 0(zero) and -(hyphen) appear, the 0 is ignored | |||
[width] Positive decimal number specifying a minimum field size. If the number of characters in the actual value is less than width value - then the required number of space ' ' characters will be added before the value (or after it, if '-' field was set). No changes occurs if number of characters in the actual value is greater than the width value. | |||
[.precision] The point '.' with the following unsigned decimal number can specify either the precision of a floating-point image or the maximum number of characters to be printed from a string. | |||
[type] Specifies other format then the default for the given. For example, in the type field, you can give a specifier that says an integer will be formatted as an unsigned. The possible values are: | |||
:{|{{prettytable}} | |||
|- | |||
| f || Format real's in fixed-decimal notation (such as 123.4 or 0.004321). This is the default for real's. | |||
|- | |||
| e || Format real's in exponential notation (such as 1.234e+002 or 4.321e-003). | |||
|- | |||
| g || Format real's in the shortest of f and e format, but always in e format if exponent of the value is less than -4 or greater than or equal to the precision. Trailing zeros are truncated. | |||
|- | |||
| d or D || Format as a signed decimal number. | |||
|- | |||
| u or U || Format as an unsigned integer. | |||
|- | |||
| x or X || Format as a hexadecimal number. | |||
|- | |||
| o or O || Format as an octal number. | |||
|- | |||
| c || Format as a char. | |||
|- | |||
| B || Format as the Visual Prolog binary type. | |||
|- | |||
| R || Format as a database reference number. | |||
|- | |||
| p || Format as the presented value. | |||
|- | |||
| P || Format as a procedure parameter. | |||
|- | |||
| s || Format as a string. | |||
|} | |||
==== generated ==== | |||
This attribute can be placed on interfaces, classes and implementation to indicate that the code is generated by some tool. As result the compiler will issue less warnings about the code. | |||
{{Example| | |||
<vip> | |||
interface iSomething supports iUnknown | |||
[generated] | |||
... | |||
</vip> | |||
}} | |||
==== immediate ==== | |||
The attribute immediate enforces immediate (i.e. non-late) initialization of a fact variable: | |||
{{Example| | |||
<vip> | |||
facts | |||
current : integer := initializeCurrent() [immediate]. | |||
</vip> | |||
}} | |||
See also {{Lang2|Facts|Fact Variable Declarations|Fact Variable Declarations}}. | |||
==== in ==== | |||
The | The argument is an input argument. Valid for a formal predicate argument. | ||
{{Example| | {{Example| | ||
<vip>predicates | <vip>predicates | ||
pred : (string InputArg [in]). | |||
</vip> | |||
}} | }} | ||
==== in_iterate ==== | |||
Defines an in-iterator predicate for a domain or interface. See the description of the {{lang2|Terms|in|in}} operator. | |||
==== in_test ==== | |||
Defines an in-test for a domain or interface. See the description of the {{lang2|Terms|in|in}} operator. | |||
==== inline ==== | ==== inline ==== | ||
inline alters the memory layout of a struct (i.e. a single alternative functor domain with an align qualification). The | <vp>inline</vp> alters the memory layout of a struct (i.e. a single alternative functor domain with an align qualification). The purpose of the attribute is to ease interfacing to foreign languages and should normally not be used for pure Visual Prolog. | ||
<vp>inline</vp> can be used in three cases: | |||
* inlining a struct rather than having a pointer to the struct | |||
* inlining a fixed size string | |||
* inlining a fixed number of bytes | |||
* inlining a prolog predicate type (as a struct with two fields) | |||
When using <vp>inline</vp> on struct field in another struct its data will be inlined instead of having a pointer to the struct | |||
{{Example| | {{Example| | ||
<vip>domains | <vip>domains | ||
point = | point =p(integer X, integer Y). | ||
domains | domains | ||
rectangle = | rectangle = | ||
r( | |||
point UpperLeft [inline], | point UpperLeft [inline], | ||
point LowerRight [inline] | point LowerRight [inline] | ||
).</vip> | |||
Since <vp>UpperLeft</vp> and <vp>LowerRight</vp> are inlined the struct have the same memory layout as this one: | |||
<vip>domains | |||
rectangle2 = | |||
r2( | |||
integer UpperLeft_X, | |||
integer UpperLeft_Y, | |||
integer LowerRight_X, | |||
integer LowerRight_Y | |||
).</vip> | ).</vip> | ||
}} | }} | ||
When using <vp>inline(<size>)</vp> on a <vp>string</vp> or a <vp>string8</vp> field in a struct, the struct will contain a fixed size string with <vp><size></vp> characters (i.e. <vp>char</vp> or <vp>char8</vp>, respectively). The strings will be zero terminated if they are shorter than <vp><size></vp>, but not if they have <vp><size></vp> characters. | |||
{{Example| | {{Example| | ||
<vip>domains | <vip>domains | ||
device = | device = | ||
device( | device( | ||
integer Id, | integer Id, | ||
string DeviceName [inline( | string DeviceName [inline(12)] | ||
).</vip> | ).</vip> | ||
<vp>DeviceName</vp> is an inlined Unicode string of length 12. | |||
The struct have the same layout as: | |||
<vip>domains | |||
device = | |||
device( | |||
integer Id, | |||
char DeviceName_01, | |||
char DeviceName_02, | |||
char DeviceName_03, | |||
char DeviceName_04, | |||
char DeviceName_05, | |||
char DeviceName_06, | |||
char DeviceName_07, | |||
char DeviceName_08, | |||
char DeviceName_09, | |||
char DeviceName_10, | |||
char DeviceName_11, | |||
char DeviceName_12 | |||
).</vip> | |||
}} | |||
When using <vp>inline(<size>)</vp> on the <vp>pointer</vp> type the struct will contain <vp><size></vp> bytes, and the pointer will become a pointer to that field: | |||
{{Example| | |||
<vip>domains | |||
mark = | |||
mark( | |||
integer Position, | |||
pointer Data [inline(8)] | |||
).</vip> | |||
<vp>Data</vp> is pointer to 8 inlined bytes | |||
The struct have the same layout as: | |||
<vip>domains | |||
mark2 = | |||
mark2( | |||
integer Position, | |||
byte Data_1, | |||
byte Data_2, | |||
byte Data_3, | |||
byte Data_4, | |||
byte Data_5, | |||
byte Data_6, | |||
byte Data_7, | |||
byte Data_8 | |||
).</vip> | |||
And <vp>Data</vp> will point to <vp>Data_1</vp>. | |||
}} | |||
==== intrinsic ==== | |||
A declaration which has special meaning and handling in the compiler (semi-built-in). | |||
==== mandatoryOut ==== | |||
Used to prevent a predicate from having optional output parameters (see {{Lang2|Terms|Optional parameters|Optional parameters}}). | |||
{{Example|This predicate does not have optional output paramters | |||
<vip> | |||
predicates | |||
ppp : (integer X [out]) [mandatoryOut]. % The output parameter is mandatory | |||
</vip> | |||
}} | |||
==== noDefaultConstructor ==== | |||
Used for a class to indicate that it should not have an implicit default constructor, and can thus be used to a class that does not have any public constructors at all. Valid for an object creating class declaration. | |||
{{Example| | |||
<vip>class classWithoutPublicConstructors : myInterface | |||
open core | |||
[noDefaultConstructor] | |||
... | |||
end class classWithoutPublicConstructors</vip> | |||
}} | |||
==== out ==== | |||
The argument is an output argument. Valid for a formal predicate argument. | |||
{{Example| | |||
<vip>predicates | |||
pred : (string OutputArg [out]).</vip> | |||
}} | |||
==== pack ==== | |||
The <vp>[pack(n)]</vp> attribute (where <vp>n</vp> is a number) instructs the compiler to use <vp>n</vp> as packing size for a functor domains. By default the packing size is <vp>4</vp> in 32 bit programs and <vp>8</vp> in 64 bit programs. This attribute is mainly intended for compatibility with C/C++ api's. | |||
{{Example| | |||
<vip> | |||
domains | |||
packed = packed(integer8, pointer) [pack(2)]. | |||
</vip> | |||
}} | |||
The attribute can used on a <vp>class</vp> declaration to cover all domains in that class. | |||
{{Example|The domains used with the RichEdit control must all be packed with 4: | |||
<vip> | |||
class richEdit_native | |||
open core, gui_native | |||
[pack(4)] | |||
% pack all domains with packing size 4 | |||
end class richEdit_native | |||
</vip> | |||
}} | |||
==== programPoint ==== | |||
<vp>programPoint</vp>'s are used by the exception mechanism to indicate where exceptions are raised and continued, but the usage is not limited to that purpose. | |||
The <vp>programPoint</vp> attribute is used predicate or constructor declaration to indicate that it receives an extra input argument which describes the place in a program (program point) where this predicate was called. This additional argument has <vp>programPoint</vp> type which is declared in the PFC core class like: | |||
<vip>domains | |||
programPoint = programPoint(hScopeDescriptor ClassDescriptor, string PredicateName, sourceCursor Cursor). | |||
</vip> | |||
The <vp>programPoint</vp> attribute can be added to a predicate declaration like this: | |||
<vip>predicates | |||
raiseAnException : (integer X) erroneous [programPoint].</vip> | |||
Adding this attribute actually means that two predicates are declared, the one you have mentioned and an another one with name <vp>raiseAnException_explicit</vp> which in addition to the arguments of <vp>raiseAnException</vp> takes a <vp>programPoint</vp> as first argument: | |||
<vip>predicates | |||
raiseAnException : (integer X) erroneous. | |||
predicates | |||
raiseAnException_explicit : (programPoint ProgramPoint, integer X) erroneous.</vip> | |||
When you call <vp>raiseAnException</vp> the compiler will create a program point and call <vp>raiseAnException_explicit</vp> instead. | |||
{{example| | |||
<vip>clauses | |||
test() :- | |||
raiseAnException(17).</vip> | |||
will actually correspond to: | |||
<vip>clauses | |||
test() :- | |||
raiseAnException_explicit(programPoint(...), 17). | |||
</vip> | |||
where the program point corresponds to the point where <vp>raiseAnException</vp> is called in the <vp>test</vp> predicate.}} | |||
If you have a programPoint you can directly call the explicit predicate with it. | |||
{{example| | |||
<vip>clauses | |||
raiseAnExceptio17_explicit(ProgramPoint) :- | |||
raiseAnException_explicit(ProgramPoint, 17). | |||
</vip> | |||
Typically, as in this example, explicit predicates will call other explicit predicates with the programPoint they receive in order to use an "original" call point in a nested explicit predicate.}} | |||
Such code is treated in the usual way. I.e. when calling <vp>raiseAnException</vp> or <vp>raiseAnException_explicit</vp> will in both cases result in calling <vp>raiseAnException_explicit</vp>, so this is the only predicate that needs an implementation. In fact, it is illegal to state clauses for the non-explicit predicate that will never be called. | |||
There is also a built-in predicate, [[Language Reference/Built-in entities#programPoint|<vp>programPoint/0-></vp>]], which returns a <vp>programPoint</vp> corresponding to the place where it is called. | |||
To summarize: | |||
* A predicate declaration with <vp>programPoint</vp> attribute actually declares two predicates. A non-explicit and an explicit predicate. | |||
* Calling the non-explicit predicate actually results in calling the explicit predicate with the call point as additional argument. | |||
* Only the explicit predicate should be implemented. | |||
==== presenter ==== | |||
Used to specify the presenter of a domain. | |||
{{Example| | |||
<vip>domains | |||
someDomain = ... [presenter(presenter_someDomain)]. | |||
</vip> | |||
}} | |||
Also used without argument to specify that an interface has a presenter. | |||
{{Example| | |||
<vip>interface something [presenter] | |||
... | |||
end interface something</vip> | |||
}} | |||
See [[Presenters]]. | |||
==== queryable ==== | |||
Makes an entity 'queryable', so that it is available for reflextion using the class <vp>predicateExtractor</vp>. | |||
==== retired ==== | |||
The declared entity is retired. The string literal describes how to migrate from it. The entity does not exist anymore. | |||
{{Example| | |||
<vip>predicates | |||
veryOldFashioned : (string Arg) [retired("Use newFashion instead")].</vip> | |||
}} | |||
==== retiredFunctor ==== | |||
Functor alternatives can be retired. | |||
<vip>domains | |||
ppp = | |||
fct(integer A, real B, ddd C) [retiredFunctor(aaa::fct_ppp)]; | |||
fct2(integer A, ddd C, integer* New).</vip> | |||
<vp>aaa::fct_ppp</vp> must be a predicate with this type (it can be an anonymous predicate): | |||
<vip>predicates | |||
fct_ppp : (integer A, real B, ddd C) -> ppp NewValue.</vip> | |||
I.e. it takes the arguments of the old functor and returns a value in the functor domain. | |||
In the program fct is does not exist at all, it is retired. But in the deserialization fct terms can still be handled: The arguments are parsed according to the types, and then the value is created by invoking <vp>aaa::fct_ppp</vp>. | |||
This method will also work for binary serializations, provided: | |||
* The old domain had more than one alternative (so there are functor numbers in the serialization) | |||
* New alternatives are added last (to retain functor numbers) | |||
It is however not recommend using binary serialization for inter-session persistence. | |||
See also [[Functor Domain Versioning]]. | |||
==== sealed ==== | |||
Used for an interface to indicate that it cannot be supported by any other interface. This allows to create more efficient codes, because the compiler provides some optimization when using the objects of such type. Valid for an object creating class declaration as a construction interface. | |||
{{Example| | |||
<vip>interface myInterface | |||
[sealed] | |||
... | |||
end interface myInterface | |||
class myClass : myInterface | |||
... | |||
end class myClass</vip> | |||
}} | |||
==== this ==== | |||
Used for declaring {{lang2|Predicates|Extension Predicates|extension predicates}}. | |||
{{Example| | |||
<vip> | |||
class predicates | |||
extension : (unsigned V [this]). | |||
</vip> | |||
}} | |||
==== union ==== | |||
Used for creating functor domains with several alternatives but no real functors. This should only be used to mimic C/C++ union structs in low-level interfacing. Valid for functor domain with several alternatives and alignment. | |||
{{Example| | |||
<vip>domains | |||
u64var = align 4 | |||
u64(unsigned64 Value64); | |||
u64_struct(unsigned Low32, unsigned High32) | |||
[union].</vip> | |||
}} | |||
==== used ==== | |||
An unused local member can be marked <vp>used</vp> to prevent the compiler to issue a warning and remove the corresponding code. Valid for members. | |||
{{Example| | |||
<vip>predicates | |||
seeminglyUnused : () [used].</vip> | |||
}} | }} |
Latest revision as of 13:14, 4 January 2024
Various definitions and declarations can be annotated with attributes. This section describes the general syntax of attributes and where they can be placed. It also describes the meaning of the specific attributes.
Syntax
Attributes : [ Attribute-comma-sep-list ]
Attribute : one of LowerCaseIdentifier LowerCaseIdentifier ( Literal-comma-sep-list )
where the literals must either be numbers or string literals.
Insertion Points
The attributes of interfaces, classes and implementations are right after the scope qualifications.
InterfaceDeclaration : interface IinterfaceName ScopeQualifications Attributes-opt Sections end interface IinterfaceName-opt
ClassDeclaration : class ClassName ConstructionType-opt ScopeQualifications Attributes-opt Sections end class ClassName-opt
ClassImplementation : implement ClassName ScopeQualifications Attributes-opt Sections end implement ClassName-opt
The attributes of constants, domains, predicates, properties and facts are at the end (i.e. right before the terminating dot).
ConstantDefinition: one of ConstantName = ConstantValue Attributes-opt ConstantName : TypeName = ConstantValue Attributes-opt
DomainDefinition: DomainName FormalTypeParameterList-opt = TypeExpression Attributes-opt
PredicateDeclaration : PredicateName : PredicateDomain LinkName-opt Attributes-opt PredicateName : PredicateDomainName LinkName-opt Attributes-opt
PropertyDeclaration : PropertyName : PropertyType FlowPattern-list-opt Attributes-opt
FactDeclaration : FactVariableDeclaration Attributes-opt FactFunctorDeclaration Attributes-opt
The attributes of formal arguments are at the end.
FormalArgument : TypeExpression ArgumentName-opt Attributes-opt
Specific Attributes
attribute
This attribute is used on a functor domain to indicate that the functors in the domain can be used as attributes elsewhere in the program.
domains meta = meta; metaDisplayAs(string DisplayAs) [attribute].
See Program Defined Attributes.
byVal
An argument is transferred directly on the stack rather than using a pointer. Valid for formal predicate arguments provided the language is stdcall, apicall or c.
domains point = point(integer X, integer Y). predicates externalP : (point Point [byVal]) language apicall.
The attribute can also be used in combination with the out attribute:
predicates externalP2 : (point Point [byVal, out]) language apicall.
In that case a point structure will be allocated before the call then a pointer to that structure is transferred handed to the external predicate which can then fill the structure with relevant data.
classInitializer
This attribute indicates that a predicate should be invoked as a class initializer. It can be applied to a class predicate that does not take any arguments. The predicate will be invoked when the initialization code invokes the runtime_api::runProgramInitialization. A class can have any number of class initializer which will be invoked in an undetermined order. Notice that other classes may not have been initialized.
The predicate xxx::initialize is registered as a class initializer:
implement xxx class predicates initialize : () [classInitializer]. clauses initialize() :- … end class xxx
constant
The constant attribute is used to declare fact variables that cannot be changed once they have been initialized.
compiletimeSetting
The compiletimeSetting attribute indicates that a constant should be considered a compiletime setting. As a result the compiler will suppress warnings about always failing/succeding code and about unreachable code that may be caused by this constant. The warning suppession is an approximation, because it a may be impossible/difficult to determine the cause of a warning.
implement xxx constants debugOutput : boolean = false [compiletimeSetting]. clauses pppp(...) :- ... if true = debugOutput then % do not give a warning about unreachable code log::write(...) end if, ... end implement xxx
default
It is problematic to update functor domains, if terms have been persisted in serialized form. Because new programs cannot deal with old serializations.
The two attributes default/1 and retiredFunctor/1 can help dealing with this problem.
The last arguments of a functor can have default values:
domains ppp = fct( integer A, real B, ddd C, integer* New [default([])], real New2 [default(0)] ).
The default attribute does not change anything within the program; it only affects the deserialization. If during deserialization we meet the closing parenthesis too soon we supply default values for the remaining arguments.
Notice that this will only work for text deserialization.
See also Functor Domain Versioning.
deprecated
The declared entity is deprecated. The string literal describes how to migrate from it. The entity still exists, but usage will cause a warning. The entity will not exist in future versions of Visual Prolog. Valid for member declarations and scopes.
predicates oldFashioned : (string Arg) [deprecated("Use newFashion instead")].
explicitTag
This predicate can be used on a functor domain to ensure that the memory representation of all terms have a functor. Without this attribute the compiler optimizes the representation such that some alternatives doesn't have a functor in the term, and such that functors with arguments are represented as a pointer value. The main purpose of this attribute is to ensure compatibility with foreign code.
domains menu = resMenu(resid Resid); dynMenu(menuItem* SubMenu); noMenu [explicitTag].
formatString
The argument is a format string for a subsequent ellipsis argument (i.e. ...). Valid for one string argument of a predicate with an ellipsis argument. The use of formatString will make the compiler check the validity of actual arguments with respect to actual format strings (where possible).
predicates writef : (string Format [formatString], ...).
The format string can contain ordinary characters which are printed without modification, and format fields, that begins with the percent % sign. If the percent sign is followed by some unknown character (not the format specifier) - then this character will be printed without modifications. To output a % character you must write %% in the format string.
predicates writef : (string Format [formatstring], ...).
The format fields specification is:
[-][0][width][.precision][type]
All fields are optional.
[-] Hyphen indicates that the field is to be left justified; right justified is the default. Having no effect when width value is not set, or the number of characters in the actual value is greater than width value.
[0] Zero before width means for values that zeros will be added until the minimum width is reached. If 0(zero) and -(hyphen) appear, the 0 is ignored
[width] Positive decimal number specifying a minimum field size. If the number of characters in the actual value is less than width value - then the required number of space ' ' characters will be added before the value (or after it, if '-' field was set). No changes occurs if number of characters in the actual value is greater than the width value.
[.precision] The point '.' with the following unsigned decimal number can specify either the precision of a floating-point image or the maximum number of characters to be printed from a string.
[type] Specifies other format then the default for the given. For example, in the type field, you can give a specifier that says an integer will be formatted as an unsigned. The possible values are:
f Format real's in fixed-decimal notation (such as 123.4 or 0.004321). This is the default for real's. e Format real's in exponential notation (such as 1.234e+002 or 4.321e-003). g Format real's in the shortest of f and e format, but always in e format if exponent of the value is less than -4 or greater than or equal to the precision. Trailing zeros are truncated. d or D Format as a signed decimal number. u or U Format as an unsigned integer. x or X Format as a hexadecimal number. o or O Format as an octal number. c Format as a char. B Format as the Visual Prolog binary type. R Format as a database reference number. p Format as the presented value. P Format as a procedure parameter. s Format as a string.
generated
This attribute can be placed on interfaces, classes and implementation to indicate that the code is generated by some tool. As result the compiler will issue less warnings about the code.
interface iSomething supports iUnknown [generated] ...
immediate
The attribute immediate enforces immediate (i.e. non-late) initialization of a fact variable:
facts current : integer := initializeCurrent() [immediate].
See also Fact Variable Declarations.
in
The argument is an input argument. Valid for a formal predicate argument.
predicates pred : (string InputArg [in]).
in_iterate
Defines an in-iterator predicate for a domain or interface. See the description of the in operator.
in_test
Defines an in-test for a domain or interface. See the description of the in operator.
inline
inline alters the memory layout of a struct (i.e. a single alternative functor domain with an align qualification). The purpose of the attribute is to ease interfacing to foreign languages and should normally not be used for pure Visual Prolog.
inline can be used in three cases:
- inlining a struct rather than having a pointer to the struct
- inlining a fixed size string
- inlining a fixed number of bytes
- inlining a prolog predicate type (as a struct with two fields)
When using inline on struct field in another struct its data will be inlined instead of having a pointer to the struct
domains point =p(integer X, integer Y). domains rectangle = r( point UpperLeft [inline], point LowerRight [inline] ).
Since UpperLeft and LowerRight are inlined the struct have the same memory layout as this one:
domains rectangle2 = r2( integer UpperLeft_X, integer UpperLeft_Y, integer LowerRight_X, integer LowerRight_Y ).
When using inline(<size>) on a string or a string8 field in a struct, the struct will contain a fixed size string with <size> characters (i.e. char or char8, respectively). The strings will be zero terminated if they are shorter than <size>, but not if they have <size> characters.
domains device = device( integer Id, string DeviceName [inline(12)] ).
DeviceName is an inlined Unicode string of length 12. The struct have the same layout as:
domains device = device( integer Id, char DeviceName_01, char DeviceName_02, char DeviceName_03, char DeviceName_04, char DeviceName_05, char DeviceName_06, char DeviceName_07, char DeviceName_08, char DeviceName_09, char DeviceName_10, char DeviceName_11, char DeviceName_12 ).
When using inline(<size>) on the pointer type the struct will contain <size> bytes, and the pointer will become a pointer to that field:
domains mark = mark( integer Position, pointer Data [inline(8)] ).
Data is pointer to 8 inlined bytes The struct have the same layout as:
domains mark2 = mark2( integer Position, byte Data_1, byte Data_2, byte Data_3, byte Data_4, byte Data_5, byte Data_6, byte Data_7, byte Data_8 ).
And Data will point to Data_1.
intrinsic
A declaration which has special meaning and handling in the compiler (semi-built-in).
mandatoryOut
Used to prevent a predicate from having optional output parameters (see Optional parameters).
predicates ppp : (integer X [out]) [mandatoryOut]. % The output parameter is mandatory
noDefaultConstructor
Used for a class to indicate that it should not have an implicit default constructor, and can thus be used to a class that does not have any public constructors at all. Valid for an object creating class declaration.
class classWithoutPublicConstructors : myInterface open core [noDefaultConstructor] ... end class classWithoutPublicConstructors
out
The argument is an output argument. Valid for a formal predicate argument.
predicates pred : (string OutputArg [out]).
pack
The [pack(n)] attribute (where n is a number) instructs the compiler to use n as packing size for a functor domains. By default the packing size is 4 in 32 bit programs and 8 in 64 bit programs. This attribute is mainly intended for compatibility with C/C++ api's.
domains packed = packed(integer8, pointer) [pack(2)].
The attribute can used on a class declaration to cover all domains in that class.
class richEdit_native open core, gui_native [pack(4)] % pack all domains with packing size 4 end class richEdit_native
programPoint
programPoint's are used by the exception mechanism to indicate where exceptions are raised and continued, but the usage is not limited to that purpose.
The programPoint attribute is used predicate or constructor declaration to indicate that it receives an extra input argument which describes the place in a program (program point) where this predicate was called. This additional argument has programPoint type which is declared in the PFC core class like:
domains programPoint = programPoint(hScopeDescriptor ClassDescriptor, string PredicateName, sourceCursor Cursor).
The programPoint attribute can be added to a predicate declaration like this:
predicates raiseAnException : (integer X) erroneous [programPoint].
Adding this attribute actually means that two predicates are declared, the one you have mentioned and an another one with name raiseAnException_explicit which in addition to the arguments of raiseAnException takes a programPoint as first argument:
predicates raiseAnException : (integer X) erroneous. predicates raiseAnException_explicit : (programPoint ProgramPoint, integer X) erroneous.
When you call raiseAnException the compiler will create a program point and call raiseAnException_explicit instead.
clauses test() :- raiseAnException(17).
will actually correspond to:
clauses test() :- raiseAnException_explicit(programPoint(...), 17).
If you have a programPoint you can directly call the explicit predicate with it.
clauses raiseAnExceptio17_explicit(ProgramPoint) :- raiseAnException_explicit(ProgramPoint, 17).
Such code is treated in the usual way. I.e. when calling raiseAnException or raiseAnException_explicit will in both cases result in calling raiseAnException_explicit, so this is the only predicate that needs an implementation. In fact, it is illegal to state clauses for the non-explicit predicate that will never be called.
There is also a built-in predicate, programPoint/0->, which returns a programPoint corresponding to the place where it is called.
To summarize:
- A predicate declaration with programPoint attribute actually declares two predicates. A non-explicit and an explicit predicate.
- Calling the non-explicit predicate actually results in calling the explicit predicate with the call point as additional argument.
- Only the explicit predicate should be implemented.
presenter
Used to specify the presenter of a domain.
domains someDomain = ... [presenter(presenter_someDomain)].
Also used without argument to specify that an interface has a presenter.
interface something [presenter] ... end interface something
See Presenters.
queryable
Makes an entity 'queryable', so that it is available for reflextion using the class predicateExtractor.
retired
The declared entity is retired. The string literal describes how to migrate from it. The entity does not exist anymore.
predicates veryOldFashioned : (string Arg) [retired("Use newFashion instead")].
retiredFunctor
Functor alternatives can be retired.
domains ppp = fct(integer A, real B, ddd C) [retiredFunctor(aaa::fct_ppp)]; fct2(integer A, ddd C, integer* New).
aaa::fct_ppp must be a predicate with this type (it can be an anonymous predicate):
predicates fct_ppp : (integer A, real B, ddd C) -> ppp NewValue.
I.e. it takes the arguments of the old functor and returns a value in the functor domain.
In the program fct is does not exist at all, it is retired. But in the deserialization fct terms can still be handled: The arguments are parsed according to the types, and then the value is created by invoking aaa::fct_ppp.
This method will also work for binary serializations, provided:
- The old domain had more than one alternative (so there are functor numbers in the serialization)
- New alternatives are added last (to retain functor numbers)
It is however not recommend using binary serialization for inter-session persistence.
See also Functor Domain Versioning.
sealed
Used for an interface to indicate that it cannot be supported by any other interface. This allows to create more efficient codes, because the compiler provides some optimization when using the objects of such type. Valid for an object creating class declaration as a construction interface.
interface myInterface [sealed] ... end interface myInterface class myClass : myInterface ... end class myClass
this
Used for declaring extension predicates.
class predicates extension : (unsigned V [this]).
union
Used for creating functor domains with several alternatives but no real functors. This should only be used to mimic C/C++ union structs in low-level interfacing. Valid for functor domain with several alternatives and alignment.
domains u64var = align 4 u64(unsigned64 Value64); u64_struct(unsigned Low32, unsigned High32) [union].
used
An unused local member can be marked used to prevent the compiler to issue a warning and remove the corresponding code. Valid for members.
predicates seeminglyUnused : () [used].