Wiki
Clone wikiMindStream / Articles in English / Script engine organisation / How the “word” is organised
Caching. How the “word” is organised.
The terms of the “word”, “variable” and “constant” were introduced there and we learned to use them.
Now, we will talk about “what actually the word is”.
The “word” or the “element of the dictionary” is a “record in the dictionary” which is given as the “key/value”.
I.e. the word:
#!delphi : A ACode ; // A
will be represented in the dictionary as a pair:
( A ACode )
where:
A
is the name of the word.
ACode
is the code of the word.
Put it more exactly, it will be represented as a set of three:
( : A ACode )
where:
:
is the stereotype of the word.
A
is the name of the word.
ACode
is the code of the word.
What is the stereotype of the word?
This is kind of a “category” the “word” belongs to.
The stereotype can determine different limitations for work with the word.
These can be, for example: - "constants" can calculate values only, or - "variables" can both return values and store them, or - "words" can calculate values as well as store nested elements.
Stereotypes also specify the sets of operations applicable for the element of the dictionary (it will be discussed further).
Let’s demonstrate the use of stereotypes with the example:
#!delphi : A ACode ; // A VAR B CONST C 1
This example will look in the dictionary as follows:
#!delphi ( : A ACode ) ( VAR B {BValue} ) ( CONST C 1 )
#!delphi : A ACode ; // A VAR B CONST C 1 CONST D C
( : A ACode )
( VAR B {BValue} )
( CONST C 1 )
( CONST D ref C )
Note that the element D is not represented with the value "1" but refers to the element C - "ref C".
This is to be discussed further.
So, how the nested words are represented in the dictionary?
At this point, it appears that the words are represented not even in a set of three, but of four:
( Stereotype Word_Name Word_Code Nested_Dictionary )
.
Let us demonstrate it with an example.
The following code:
#!delphi : A VAR X ACode ; // A
( : A ACode Dict( VAR X {XValue} ) )
where Dict( ... )
is the internal dictionary of the word A
.
And the following example:
#!delphi : A VAR X ACode ; // A VAR B CONST C 1 CONST D C
( : A ACode Dict( VAR X {XValue} ) )
( VAR B {BValue} Dict( ) )
( CONST C 1 Dict( ) )
( CONST D ref C Dict( ) )
Thus, the obvious question that arises is: "as the dictionary is the key/value, then can we get access to the nested elements of the word?"
The answer is: yes, since we have the overall code reflection.
How can we do it?
Three wonderful words of axiomatics can be used:
@
gets the address of the word.DO
executes the words by the address (reversed@
).%%
gets by the word address the nested word by the name .
Look how the word %%
is defined:
#!delphi OBJECT operator %% OBJECT IN aWord ^ IN aName OBJECT VAR l_Member aName DO aWord pop:Word:FindMember >>> l_Member if ( l_Member pop:object:IsNil ) then ( Result := nil ) else ( Result := ( l_Member pop:KeyWord:Word ) ) ; // %%
- aWord is the word for which the nested element is sought.
- aName is the name of the nested element.
It also returns the value like OBJECT which is the address of the nested element or nil if such element is not found.
Let us give the example of use:
#!delphi : A : X 2 ; // X 1 ; // A @ A // takes the address of the word A %% // is the operation %% 'X' // is the name of the sought word X DO // executes the found word Print // prints the value
The integer value “2” is printed in the console and it returns the word X.
What do we do if there is no nested word?
In this case, we need to check the returned value for nil.
The example:
#!delphi : A : X 2 ; // X 1 ; // A VAR l_ElementAddr // the variable to store the address of the element @ A %% 'X' >>> l_ElementAddr // returns the address of the word X if NOT ( l_ElementAddr IsNil ) then // we check it begin l_ElementAddr DO // prints 2 end @ A %% 'Y' >>> l_ElementAddr // returns the address of the word Y if NOT ( l_ElementAddr IsNil ) then // checks the address begin l_ElementAddr DO // prints nothing // for we do not get there // since the element A has no element Y end
@
and DO
?
Yes, we can.
We have the word ::
for it.
It is defined in this way:
#!delphi ^@ operator :: ^@ IN aSelf ^L IN aName OBJECT VAR l_Self aSelf |^@ >>> l_Self STRING VAR l_Name aName |N >>> l_Name OBJECT VAR l_Res l_Self %% l_Name >>> l_Res ASSURE NOT ( l_Res pop:object:IsNil ) [ Field not found: ' l_Self LIST %P Reverted ==> ( |N '::' ) l_Self |N '::' l_Name ] l_Res >>> Result ; // ::
#!delphi : A : X 2 ; // X 1 ; // A A :: X Print // prints the value "2" that returns X A :: Y Print // throws the Run-Time error "field Y not found"
::
can be used to both read and write the values of the nested elements (if they support it).
The modifier ^@
specifies it before the operation :: is declared.
It means
the reference is returned but not the value
.
The example:
#!delphi : A VAR X ; // A A :: X := 2 // assigns the value “2” to the field X A :: X Print // prints the value
Yes, we can.
How?
This is what my next article is about.
Updated