ExternalSymbol¶
The ExternalSymbol is a symbol
node that represents a symbol declared in another module.
Declaration¶
Syntax¶
ExternalSymbol(symbol_table parent_symtab, identifier name,
symbol external, identifier module_name, identifier* scope_names,
identifier original_name, access access)
Arguments¶
Argument Name |
Denotes |
---|---|
|
the parent symbol table that contains the external symbol |
|
the name of the external symbol in the current symbol table |
|
pointer to the actual symbol definition |
|
the name of the module the symbol is in |
|
a list of names if the symbol is in a nested symbol table. For example if it is a local variable in a function |
|
the name of the symbol in the external symbol table |
|
access type |
Return values¶
None.
Description¶
ExternalSymbol represents symbols that cannot be looked up in the current scoped symbol table. As an example, if a variable is defined in a module, but used in a nested subroutine, that is not an external symbol because it can be resolved in the current symbol table (nested subroutine) by following the parents. However if a symbol is used from a different module, then it is an external symbol, because usual symbol resolution by going to the parents will not find the definition.
The ExternalSymbol
is the only way to reference a symbol that cannot be accessed in the scoped symbol table by visiting the parents. There is a special handling for it in the serialization and deserialization: the external
member is not serialized (since it is a pointer) and in deserialization the pointer is reconstructed from the original_name
and scope_names
.
The scope_names
contains the names of the external symbol table starting from the top how to get to the symbol. This approach allows to reference any nested symbol (such as a local variable in a function in a module). However, we might later change the design to only allow referencing top level module entities.
One can think of the ExternalSymbol
as the “import” statement in Python, or the “use” statement in Fortran.
Types¶
Examples¶
module module_num
integer :: my_num = 5
end module
program main
use module_num
print *, my_num
end program
ASR:
(TranslationUnit
(SymbolTable
1
{
main:
(Program
(SymbolTable
3
{
my_num:
(ExternalSymbol
3
my_num
2 my_num
module_num
[]
my_num
Public
)
})
main
[module_num]
[(Print
()
[(Var 3 my_num)]
()
()
)]
),
module_num:
(Module
(SymbolTable
2
{
my_num:
(Variable
2
my_num
[]
Local
(IntegerConstant 5 (Integer 4 []))
()
Save
(Integer 4 [])
Source
Public
Required
.false.
)
})
module_num
[]
.false.
.false.
)
})
[]
)