Author(s) |
Greg Shah Sergey Yevtushenko |
Date |
April 8,
2005 |
Access Control |
CONFIDENTIAL |
Type
Name |
Supported
In P2J |
AS
clause abbreviation |
Documented
Abbreviation |
Reserved
Keyword |
Comments |
character |
Y |
c |
char |
no |
a string --> there is no representation of a single character that is not a string |
com-handle |
N |
com-handle |
no |
only used on Windows for
Active-X or COM objects |
|
date |
Y |
da |
no |
||
decimal |
Y |
de |
dec |
no |
a floating point number |
handle |
Y |
handle |
no |
||
integer |
Y |
i |
int |
no |
|
logical |
Y |
l |
no |
||
memptr |
Y |
m |
n/a |
no |
this is an undocumented keyword
(not in the keyword index) |
raw |
Y |
ra |
no |
||
recid |
Y |
re |
yes |
||
rowid |
Y |
row |
yes |
||
widget-handle |
Y |
widg |
widget-h |
no |
Symbol Type |
Namespace |
Scoping Support |
Abbreviation Support |
Notes |
language keywords | unique |
no |
yes |
Also handles reserved/unreserved
processing. In the P2J implementation this is mostly a feature of
the lexer. |
variables (global shared, scoped shared and local) | overlapping with database fields, shared with widgets |
yes |
no |
This implementation actually
splits this namespace from that of widgets although in Progress they
are the same namespace. This was done to keep the implementation
simple (no complex, multi-level lookups are needed). |
database fields | overlapping with variables |
yes |
yes |
See Schema
Names section for details. |
procedures | shared with functions |
no (cannot be nested) | no |
In the current implementation of
the parser this is a separate namespace, however it should have no
negative effects due to the assumption that only correct Progress 4GL
source files will be processed. |
functions | shared with procedures |
no (cannot be nested) |
built-in - yes user-defined - no |
In the current implementation of the parser this is a separate namespace, however it should have no negative effects due to the assumption that only correct Progress 4GL source files will be processed. |
labels |
unique |
yes |
no |
|
triggers | no |
no |
no |
Triggers are not named and have
no namespace implications. |
databases | shared with aliases |
no |
no |
|
aliases | shared with databases |
no |
no |
|
tables | shared with buffers, temp-tables
and work-tables |
yes |
yes |
|
indices |
TBD | TBD | TBD | |
sequences |
TBD | TBD | TBD | |
buffers | shared with tables, temp-tables and work-tables | yes |
no |
|
widgets | shared with variables |
yes |
no |
includes browse, button,
combo-box,
editor, fill-ins, literal, radio-set, selection-list, slider, text,
toggle-box This implementation actually splits this namespace from that of variables although in Progress they are the same namespace. This was done to keep the implementation simple (no complex, multi-level lookups are needed). |
frames, windows, dialogs |
unique |
yes |
no |
Frames can't be named the same
as an existing browse widget that is in scope, even though they DON'T
share the same namespace! Perhaps this is due to an implicit frame created for the browse, but not externally exposed? |
menus, sub-menus | unique |
TBD |
TBD |
|
menu-items |
unique |
TBD |
TBD |
|
queries | unique |
TBD | TBD | |
streams | unique |
scoped to the procedure |
no |
|
temp-tables |
shared with buffers, tables and work-tables | yes |
TBD | |
work-tables (workfiles) | shared with buffers, temp-tables and tables | yes |
TBD |
Search
Name |
Matches
Nothing (is ambiguous) |
Matches
cust |
Matches
customer |
c |
yes |
||
cu |
yes |
||
cus |
yes |
||
cust |
yes |
||
custo |
yes |
||
custom |
yes |
||
custome |
yes |
||
customer |
yes |
Language
Construct |
Type |
Reference
Type |
any field reference in an
expression |
lvalue |
free reference |
AMBIGUOUS record | built-in function |
free reference |
AVAILABLE record | built-in function | free reference |
ASSIGN field = expression |
statement |
free reference |
ASSIGN record | statement |
free reference |
BUFFER-COMPARE buffer TO buffer | statement | free reference |
BUFFER-COPY buffer TO buffer | statement | free reference |
CAN-FIND( record ... ) |
built-in function | no reference |
CAN-FIND( ... OF record ) | built-in function | free reference |
CREATE record |
statement |
free reference |
CURRENT-CHANGED record |
built-in function | free reference |
DEFINE BROWSE browse_name QUERY
query_name DISPLAY record WITH ... |
statement |
free reference |
DEFINE BUFFER buffer-name FOR record | statement |
no reference |
DEFINE FRAME frame-name record | statement | no reference |
DEFINE PARAMETER BUFFER
buffername FOR record |
statement |
free reference |
DEFINE PARAMETER TABLE FOR
temp-table-name |
statement |
no reference |
DEFINE type PARAMETER
TABLE-HANDLE FOR temp-table-handle |
statement |
unknown |
DEFINE TEMP-TABLE temp-table-name LIKE record | statement | no reference |
DEFINE QUERY <queryname>
FOR <tablename> |
statement | free reference |
DELETE record |
statement |
free reference |
DISPLAY record |
statement |
free reference |
DO FOR record |
statement | strong |
DO PRESELECT record |
statement | weak |
EMPTY TEMP-TABLE record |
statement |
free reference |
EXPORT record |
statement |
free reference |
FIND ... record |
statement | free reference |
FOR EACH record |
statement | weak |
FOR FIRST record |
statement | weak |
FOR LAST record |
statement | weak |
FORM record |
statement |
no reference |
FUNCTION func_name RETURNS type
(BUFFER buffername FOR record, ...). |
statement |
free reference |
FUNCTION func_name RETURNS type (TABLE FOR temp_table_name, ...). | statement |
no reference |
IMPORT record |
statement |
free reference |
INSERT record |
statement | free reference |
LOCKED record |
built-in function | free reference |
NEW record |
built-in function | free reference |
ON dbevent OF record |
statement |
free reference |
OPEN QUERY query ... record ... |
statement | free reference |
PROMPT-FOR record |
statement |
free reference |
RAW-TRANSFER buffer TO buffer |
statement |
free reference |
RECID record |
built-in function | free reference |
RELEASE record |
statement |
free reference |
REPEAT FOR record |
statement | strong |
REPEAT PRESELECT record |
statement | weak |
ROWID record |
built-in function | free reference |
RUN procedure (BUFFER record,
...) |
statement |
free reference |
SET record |
statement |
free reference |
UPDATE record |
statement | free reference |
VALIDATE record |
statement |
free reference |
Progress
Source Code |
Notes |
message "hello". find first customer. |
This is the most simple
case. There is 1 free reference and the buffer created is
associated with the external procedure. |
message "hello". repeat: find first customer. end. |
Another simple case with a
single free reference. The scope is assigned at the nearest
enclosing block that holds all references (and which has the record
scoping property). In this case, the scope is associated with the
repeat block instead of the external procedure. |
repeat: repeat: repeat: repeat: repeat: find first customer. end. repeat: repeat: find first customer. end. end. end. end. end. end. |
In the absence of weak
references, 2 or more free references will all combine into a single
scope at the at the nearest enclosing block that holds all references
(and which has the record scoping property). Note that the level of nesting has no impact on this result. |
do for customer: for each customer: end. find first customer. end. for each customer: end. |
Here, the DO FOR block
establishes a strong scope. All customer references within this
block are all scoped to the block. In this example, the free
reference is not considered unbound because it is within the strong
scope. Also note that no free references external to the same
buffer are allowed outside this strong scope. The weak reference within the strong scope is part of that scope, but the weak reference outside of the strong scope has its own buffer/record scope. No implicit scoping will occur, everything is fixed and explicit. |
message
"hello". for each customer: end. |
This weak reference is the
simple case where the buffer created is associated with the FOR block. No implicit scoping changes will occur. |
message "hello". for each customer: end. for each customer: end. |
These 2 weak references each
have their own scope where the buffer created is associated with each
FOR block. No implicit scoping changes will occur. |
message "hello". do preselect each customer: find first customer. find next customer. end. for each customer: end. |
This is an example of two weak
scopes that are sequential. Please note that while it is not
possible to have a free reference inside a FOR EACH block, the
PRESELECT blocks must by their nature use free references to read
records. |
message
"hello". repeat: for each customer: end. find first customer. end. |
This is the
most simple type of implicit scope expansion. The default scope
for the weak reference is raised to the enclosing REPEAT block due to
the presence of the FIND free reference. The REPEAT block in this case would be considered an expanded scope in the text above. |
message "hello". repeat: repeat: for each customer: end. end. end. find first customer. |
This implicit scope expansion
shows that the default
scope for the weak reference is raised to the external procedure due to
the presence and location of the FIND free reference. An
important note is that the nesting level of the FOR EACH weak reference
makes no difference with this behavior. Likewise, whether or not
the FIND was deeply nested has no impact. The decision to
implicitly expand scope is based on the presence of an unbound free reference and the order
in which the buffer references occur. |
message
"hello". repeat: find first customer. repeat: repeat: for each customer: end. end. end. end. |
This implicit scope expansion
shows that the default
scope for the weak reference is raised to the REPEAT block even though
it follows the FIND free reference. In this case, there is no
prior weak reference or expanded scope
to which to bind. |
repeat: repeat: repeat: for each customer. end. repeat: repeat: find first customer. end. repeat: repeat: find first customer. end. end. end. end. end. end. |
In this case when the first free
reference is encountered there is a prior weak reference AND it is at a
different (higher in this case) nesting level so that changes the
target block chosen. It is important to note that following free references that are enclosed in this active scope (see rules 3 and 5 above) are automatically scoped to this same level and do not have any further impact. |
repeat: repeat: repeat: repeat: repeat: find first customer. end. repeat: repeat: find first customer. end. end. end. end. for each customer. end. end. end. |
As the tree is walked, when an unbound free reference is encountered (the first FIND), a backward search will be made. In this case, no weak references or expanded scopes are found. So the free reference will bind to the next weak reference encountered. This expands the scope to the 2nd level REPEAT block. |
repeat: repeat: for each customer: end. find first customer. end. repeat: for each customer: end. find first customer. end. end. |
An example of 2 expanded scopes that never
combine. This separation is due to the nesting levels of the
scopes. |
repeat: repeat: for each customer: end. find first customer. end. repeat: for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. end. repeat: repeat: find first customer. end. find first customer. end. end. end. |
A more complex example that
shows that nesting may stop two expanded
scopes from combining at a higher level, but that no matter how
deeply nested the original unbound free
reference and the weak reference to which it binds, the rollup process
stops at the end of the expanded scope.
If no subsequent free references occur outside of the expanded scope, such that it is
rolled up further, this condition holds. |
repeat: repeat: for each customer: end. find first customer. end. repeat: for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. end. repeat: repeat: find first customer. end. find first customer. end. end. end. find first customer. |
A more complex example that
shows that nesting may stop two expanded
scopes from combining at a higher level, even when there are
subsequent free references that occur outside of the parent block of
both expanded scopes, such
that the last one (forming a firewall)
it is rolled up further while the first one is left separate. |
message
"hello". repeat: repeat: for each customer: end. find first customer. end. repeat: find first customer. end. repeat: for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. end. repeat: repeat: find first customer. end. find first customer. end. end. end. |
The introduction of an
intermediate free reference between what would have been 2 separate expanded scopes causes the first expanded scope to be raised up (as
the bind target) and the entire contents of the 4th REPEAT block
automatically have their scope raised because they are inside of an active scope. |
repeat: repeat: repeat: repeat: repeat: find first customer. end. repeat: repeat: find first customer. end. end. end. end. for each customer. end. for each customer. end. for each customer. end. end. end. |
Another example of active scope processing. The
number or order of subsequent enclosed references does not make any
difference. |
message "hello". repeat: for each customer: end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. for each customer: end. end. |
This demonstrates the effect
that nesting has (and doesn't have) on implicit scope expansion.
All of the weak references in the top level REPEAT block never have
their scope expanded because there is no unbound free reference at a nesting
level that can affect them. However, the nested weak reference
inside the 3rd level REPEAT block is the bind target for the single
FIND free reference. The 2nd level REPEAT block is the nearest
enclosing scope that can contain both weak and free references AND
which has record scoping properties (see the next example). So
the resulting expanded scope
is never expanded again due to no additional unbound free references. It is important to note that the relative nesting of the weak and free referneces within the 2nd level REPEAT block only affects the target block to which the scope is expanded. The relative nesting of the weak and free references does NOT affect the choice of which weak reference is bound to the free reference! Rather, this is primarily a sequence issue (it is almost always determined by the order or occurrence). The only exception is noted in rules 6a and 10f above. |
message "hello". repeat: for each customer: end. for each customer: end. for each customer: end. do: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. for each customer: end. end. |
The only difference between this
example and the previous one is that the 2nd level REPEAT block has
been changed to a DO block. Since the DO block has no record
scoping property by default, this means that the nearest enclosing
block which has this property is the top level REPEAT block. Once
the scope expands to this level (due to the FIND free reference), the
previous weak references that are direct children of the target REPEAT
block have their scope expanded too. Once that expanded scope is active, the subsequent weak
references (the last one in the file) is automatically expanded too. |
message "hello". repeat: for each customer: end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. for each customer: end. find first customer. end. |
This is an example of the
exception in rule 10f above. 2 expansions occur, in series.
The first is due to the deeply nested FIND free reference. This
expands scope to the 2nd level REPEAT block and binds to the 4th
instance of FOR EACH. Then when the 2nd FIND free reference is
encountered, it binds to the 5th FOR EACH, raises scope to the
top-level REPEAT block and then searches backward to expand the scope
of prior weak or expanded scopes.
In this case it stops its search when it encounters the first expanded scope (this is an example
of the firewall described in
rule 10d above). This means that the previous weak scopes each
remain separate and independent (islands)
but enclosed within a larger scope of the same buffer name. |
message "hello". repeat: for each customer: end. repeat: for each customer: end. find first customer. end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. find first customer. end. |
This demonstrates that a free
reference can bind to the closest prior expanded scope. That expanded scope also performs the firewall function, causing all prior
weak references and expanded scopes
at that level to remain scoped as they are (no expansion of their scope
to a higher level). |
message "hello". repeat: for each customer: end. repeat: for each customer: end. find first customer. end. repeat: for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. end. find first customer. end. |
This demonstrates that the
closest prior expanded scope
can be inside a nested block. That expanded scope still performs the firewall function, causing all prior
weak references and expanded scopes
at that level to remain scoped as they are (no expansion of their scope
to a higher level). In the backwards search, the prior expanded scope is found before the weak reference (the 4th FOR EACH), which is why the prior expanded scope is the bind target for the last FIND free reference and why the nested FOR EACH weak references are their own independent scopes. |
message "hello". repeat: for each customer: end. repeat: for each customer: end. find first customer. end. repeat: for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. for each customer: end. end. find first customer. end. |
The closest prior weak reference
in this case is the bind target for the final free reference.
However we can still see that the rollup process forces the closest
prior expanded scope to be
raised and that expanded scope
performs the firewall
function. Thus all prior weak references and expanded scopes in the nested 2nd
level REPEAT block AND at the 1st level REPEAT block level to remain
scoped as they are (no expansion of their scope to a higher level). In the backwards search, the nested prior expanded scope is found as the first bind target. This is because a nested weak reference (except for the rule 10f above) cannot be a bind target. |
repeat: for each customer: end. repeat: for each customer: end. find first customer. end. for each customer: end. for each customer: end. repeat: for each customer: end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. end. end. find first customer. end. |
This shows that the last free
reference binds to the first weak reference in a nested block (the 3rd
REPEAT block, see rule 6c above). But also note that the all
prior weak references and the closest prior expanded scope also get rolled up. That expanded scope
forms a firewall which leaves
the 1st FOR EACH as an island. All weak references in the nested block (the 3rd REPEAT block) after the first one, are not rolled up. The key points here are:
|
repeat: for each customer. end. for each customer. end. repeat: repeat: for each customer. end. repeat: for each customer. end. find first customer. end. repeat: for each customer. end. find first customer. end. repeat: for each customer. end. find first customer. end. for each customer. end. end. for each customer. end. end. for each customer. end. find first customer. end. |
Another example of how the rollup process stops processing when
it encounters the closest prior expanded
scope, even if this is deeply
nested in sub-blocks. |
message "hello". repeat: for each customer: end. find first customer. repeat: for each customer: end. find first customer. end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. repeat: repeat: find first customer. end. end. end. find first customer. end. |
The introduction of a free
reference early (the first FIND on line 8) in a program which causes
the scope to be expanded early to the top-level REPEAT. All
subsequent references within this top-level REPEAT block will scope to
this level no matter the order or sub-nesting depth. This is an
example of the effect of an active
scope as described by rules 3 and 5 above. Note that without this early free reference, the firewall effect that is seen in the previous example. |
message "hello". repeat: for each customer: end. find first customer. repeat: for each customer: end. end. for each customer: end. for each customer: end. repeat: repeat: for each customer: end. end. for each customer: end. end. for each customer: end. for each customer: end. end. |
Another example of the active scope effect. Note that
in this case only a single free reference exists in the entire program,
but the result is the same. Also note that the sub-nesting level
has no impact on whether the contained weak references (or expanded scopes if any had existed
in this example) would have their scope expanded. |
repeat: for each customer. end. for each customer. end. repeat: repeat: repeat: for each customer. end. end. for each customer. end. repeat: for each customer. end. end. repeat: for each customer. end. end. for each customer. end. end. for each customer. end. end. for each customer. end. repeat: for each customer. end. for each customer. end. end. for each customer. end. find first customer. end. |
This is an important example of
the rollup process.
There is only a single free reference (the FIND statement at the end)
and it binds to the FOR EACH just prior to it. The rollup process occurs from there,
and since there is no prior expanded
scope to act as a firewall,
the rollup continues all the
way up to the top of the enclosing top-level REPEAT. Both direct
child weak references and the first occurring weak references in 2
nested blocks are rolled up.
Note that due to nesting 6 weak scopes do NOT get rolled up. |
repeat: for each customer: end. for each customer: end. repeat: repeat: repeat: find first customer. end. end. repeat: for each customer: end. end. end. for each customer: end. end. |
This helps demonstrate the
sequential nature of the bind target decision. The 1st free
reference is encountered deeply nested inside the 4th REPEAT
block. It searches backward and binds to the 2nd FOR EACH (just
inside the top-level REPEAT block). The rollup process then raises the
scope for the 1st FOR EACH to the same top-level REPEAT block and
ends. Now the last 2 weak references are both contained inside an
active scope, so they
automatically get their scope raised too. If the FIND free reference and the 3rd FOR EACH were transposed in sequence, the result would have been 4 separate scopes, rather than 1 single scope. Note that nesting in this case has no affect, only the sequence mattered. |
Scenario |
Scope
Type |
Statement |
Table |
Scoped-To Block | Disambiguates
Outside Unqualified Field Name |
1 |
free |
FIND FIRST |
table1 |
external proc |
Y |
2 |
weak |
FOR EACH |
table1 |
FOR |
n/a (since there are no
conditions outside the naturally enclosing block that cause an implicit
expansion of scope, there are also no outside references to
disambiguate) |
3 |
strong |
DO FOR |
table1 |
DO |
n/a |
4 |
weak |
FOR EACH |
table1 |
external proc |
Y |
4 |
free |
FIND FIRST |
table1 |
external proc | Y (the weak and free scopes are
combined into a larger scope) |
5 |
strong |
DO FOR |
table1 |
fails compile |
n/a |
5 |
free |
FIND FIRST |
table1 |
fails compile |
n/a |
6 |
weak |
FOR EACH |
table1 |
external proc |
Y |
6 |
weak |
FOR EACH |
table1 |
external proc |
Y |
6 |
free |
FIND FIRST |
table1 |
external proc |
Y (all 3 references have the
same scope) |
7 |
weak |
FOR EACH |
table1 |
external proc |
N |
7 |
weak |
FOR EACH |
table2 |
FOR |
N |
7 |
free |
FIND FIRST |
table1 |
external proc |
N (even though the first weak
reference scope is expanded to the external proc and combined with this
free reference, the unqualified field names are not supported outside
of the FOR block!) |
8 |
strong |
DO FOR |
table1 |
DO |
N |
8 |
weak |
FOR EACH |
table2 |
external proc |
Y |
8 |
free |
FIND FIRST |
table2 |
external proc |
Y (the weak and free scopes are combined into a larger scope) |
9 |
strong |
DO FOR |
table1 |
fails compile |
n/a |
9 |
strong |
DO FOR |
table2 |
fails compile |
n/a |
9 |
free |
FIND FIRST |
table2 |
fails compile |
n/a (see scenario 5 of which
this is simply a variant) |
10 |
free |
FIND LAST (inside non-scoped DO
block) |
table1 |
external proc |
Y |
10 |
free |
FIND FIRST (outside non-scoped
DO block) |
table1 |
external proc |
Y (both free scopes are combined into a larger scope) |
11 |
free |
FIND LAST (inside non-scoped DO block) | table1 |
external proc |
N |
11 |
free |
FIND FIRST (outside non-scoped DO block) | table2 |
external proc |
N (different scopes can't be
combined, no unqualified field names are added to the namespace) |
Block
Type |
Nestable |
Can Contain | Affects
Symbol Scope |
Provides Iteration |
Notes |
external procedure | no |
any block |
yes |
no |
This is implicitly defined at
the beginning and end of a source file. This is the only block
that does not correspond with any language statement. |
internal procedure |
no |
trigger editing do repeat for |
yes |
no |
|
user-defined function |
no |
trigger editing do repeat for |
yes |
no |
Only in the case where the FUNCTION statement is not a
forward declaration (using the FORWARD
keyword). |
trigger |
yes |
trigger editing do repeat for |
yes |
no |
Triggers can be nested inside
any other block and can be nested inside other triggers. Internal
procedures and functions cannot be nested inside triggers. |
editing |
yes |
trigger do repeat for |
no |
no |
Editing blocks can be nested
inside any other block EXCEPT for another editing block. |
do |
yes |
trigger editing do repeat for |
no |
yes |
Only unqualified schema symbol
scope can be affected by these blocks. |
repeat |
yes |
trigger editing do repeat for |
no |
yes |
Only unqualified schema symbol scope can be affected by these blocks. |
for | yes |
trigger editing do repeat for |
no |
yes |
Only unqualified schema symbol scope can be affected by these blocks. |
Left Operand
Type |
Operator |
Right
Operand Type |
Result Type |
Notes |
date |
+ |
numeric |
date |
right operand represents # of
days to add to the left operand |
string |
+ |
string |
string |
string concatenation |
numeric |
+ |
numeric |
see notes for multiplication |
|
n/a |
+ |
numeric |
same as right operand |
unary plus is a NOP |
date |
- |
date |
integer |
returns a number of days
difference |
date |
- |
numeric |
date |
right operand represents # of
days to subtract from the left operand |
numeric |
- |
numeric |
see notes for multiplication | |
n/a |
- |
numeric |
same as right operand |
unary minus is the negation
operator |
numeric |
* |
numeric |
see notes |
dec * dec = dec dec * int = dec int * dec = dec int * int = int |
numeric |
/ |
numeric | decimal |
|
numeric (cast to integer, after
cast it must be > 0) |
MODULO |
numeric (cast to integer, after cast it must be > 0) | integer |
|
any type |
EQ or = |
same type as left operand |
boolean |
|
any type | NE or <> |
same type as left operand | boolean | |
any type | LT or < | same type as left operand | boolean | |
any type | GT or > | same type as left operand | boolean | |
any type | LE or <= |
same type as left operand | boolean | |
any type | GE or >= | same type as left operand | boolean | |
n/a |
NOT |
boolean |
boolean |
|
boolean |
OR |
boolean |
boolean | |
boolean |
AND |
boolean |
boolean | |
string |
MATCHES |
pattern |
boolean | pattern is a Progress 4GL string
that follows is similar in nature to a regular expression. however the
syntax is different |
string |
BEGINS |
string |
boolean | |
lvalue (database field) of
character type |
CONTAINS |
word list |
boolean | this is a list of words with
custom logical AND and OR operators, please see page 960 in the
Progress Language Reference for details; note that this operator is only valid in a WHERE clause but is implemented in the primary expression processing to greatly reduce complexity (and more importantly, parser ambiguity) |
Mechanism |
Type |
External File Linkage |
Supported |
Description |
APPLY statement | invocation |
Y |
Y |
Invokes a specific event in a
procedure and/or on a widget. This event can be defined in a separate procedure (identified by a user-defined handle or possibly a system handle or something returned from method/attribute access) OR can be invoked upon a shared widget (something defined in another source file and passed in for usage in this procedure) which would cause the event definition in the original source file to be executed. There is no way to use the APPLY statement to cause a new procedure to be loaded. Instead APPLY inherently requires that any externally referenced widget or procedure must already have been loaded (and is still on the procedure stack). |
BTOS | invocation | Y |
Y |
Executes command via the BTOS command processor. |
CALL statement | invocation | Y |
N |
Invokes a user defined external C function. |
DDE * statements | invocation | Y |
N |
Interfaces with Windows DDE. |
DOS | invocation | Y |
Y |
Executes command via the DOS/Windows command processor. |
DYNAMIC-FUNCTION function | invocation | Y |
N |
Executes a user defined function, possibly in an external procedure (identified by a user-defined handle or possibly a system handle or something returned from method/attribute access). |
EDITING phrase/block | entry point |
N |
Y |
Defines a block that executes on each key press event; it is called in-line with the update, set or prompt-for statements and serves to modify/expose the key processing where otherwise only the default processing would occur; this is a specialized type of callback which is only in scope for the duration of the enclosing language statement, so it is not callable directly by user-written Progress code. |
EVENT-PROCEDURE phrase |
entry point |
N |
N |
Defines a call back for when a procedure executed via RUN ASYNCHRONOUS completes. |
FUNCTION | entry point | Y |
Y |
Defines a user defined function
with a specific name (if it is not a FORWARD declaration). If this is declared as "IN procedure_handle" or "IN SUPER", the function actually resides in another source file. |
function call |
invocation |
Y |
Y |
An invocation of a known
user-defined function or built-in function as part of an
expression. It is possible that the definition resides in another
source file. See FUNCTION. |
INPUT THROUGH (INPUT THRU) | invocation | Y |
Y |
Executes an external program and obtains Progress procedure input from the stdout of the external program. |
INPUT-OUTPUT THROUGH
(INPUT-OUTPUT THRU) |
invocation | Y |
Y |
Executes an external program and pipes Progress procedure output to the stdin for the external program and obtains Progress procedure input from the stdout of the external program. |
method call |
invocation |
N |
Y |
An invocation of a built-in method as part of an expression. |
ON statement |
entry point | Y |
Y |
Defines a block associated with a specific event. |
OS2 | invocation | Y |
Y |
Executes command via cmd.exe. |
OS-COMMAND |
invocation | Y |
Y |
Executes command via an OS specific command processor. |
OUTPUT THROUGH (OUTPUT THRU) |
invocation | Y |
Y |
Executes an external program and
pipes Progress procedure output to the stdin for the external program. |
PROCEDURE statement |
entry point | Y |
Y |
Defines an internal
procedure. It is possible to invoke this from another source file
using "RUN procedure IN handle". |
PROCESS-EVENTS statement |
event processing exit |
N |
N |
Synchronously dispatch pending events, then continue. |
PROMPT-FOR statement |
event processing exit | N |
Y |
Executes a WAIT-FOR internally. |
PUBLISH statement |
invocation | Y |
N |
Generates a named event. |
RUN path-name<<member-name>> | invocation | Y |
N |
Runs a specific member in an r-code library. |
RUN procedure_name | invocation | Y |
Y |
Runs an internal procedure or calls an entry point in a shared library (e.g. a Windows DLL). |
RUN procedure_name in handle | invocation | Y |
N |
Runs an internal procedure defined in another file that is in scope on the stack or which has previously been run with the persistent option. |
RUN STORED-PROCEDURE statement |
invocation | Y |
N |
Executes a stored procedure on a SQL-based dataserver. |
RUN SUPER statement |
invocation | Y |
N |
Runs the super procedure version of the current internal procedure. |
SET |
event processing exit | N |
Y |
Executes a WAIT-FOR internally. |
SUBSCRIBE statement | entry point | Y |
N |
Requests notification of a named event. |
SUPER function | invocation | Y |
N |
Executes SUPER version of a user defined function. |
TRIGGERS phrase | entry point | Y |
N |
Associates a block with a specific event. |
UNIX |
invocation | Y |
Y |
Executes command via sh. |
UPDATE |
event processing exit | N |
Y |
Executes a WAIT-FOR internally. |
VMS |
invocation |
Y |
Y |
Executes command via VMS command
shell. |
WAIT-FOR statement |
event processing exit | N |
Y |
Dispatch all events until a specific stop event occurs. |
<?xml version="1.0"?>
<!--Persisted CallGraph-->
<graph-root>
<call-graph-node filename="./path/root.p">
<call-graph-node filename="./path/referenced1.p">
<call-graph-node filename="./path/referenced1_1.p" />
<call-graph-node filename="./path/referenced1_2.p" />
</call-graph-node>
<call-graph-node filename="./path/referenced2.p">
<call-graph-node filename="./path/referenced2_1.p" />
<call-graph-node filename="./path/referenced2_2.p">
<call-graph-node filename="./path/referenced2_2_1.p" />
<call-graph-node filename="./path/referenced2_2_1.p" />
</call-graph-node>
</call-graph-node>
</call-graph-node>
</graph-root>