> My point is still valid but with no direct consequence (it seems to me) to the way
> that the Project Oberon compiler is working. The obj.lev does not receive the
> level of the constant string but it's length. It maybe not a big deal as the current
> implementation doesn't care about it. Or there is some insight reason to have
> the string length put in the obj.lev that is not visible to me.
For the record, the meaning of the field obj.lev for string constants is as follows:
1. In Project Oberon 2013, the field obj.lev is "abused" to hold the length (len) of string constants. The reason is (probably) that there simply aren't any other fields available in obj to hold the string length. This choice may also be one of the
reasons, why exporting and importing string constants is, in fact, not implemented in Project Oberon 2013, i.e. it just does not work (unlike in Extended Oberon).
2. In Extended Oberon, the field obj.lev consistently holds the scope level for all (!) declared identifiers, i.e. also for constants, types and procedures, not just variables (see ORP.Declarations). This makes it trivial to disallow access to all (!)
intermediate identifiers with a single ELSIF clause at the end of ORP.qualident (instead of ORG.MakeItem), and in all (!) cases when an item is used, not just when it is initially created.
3. In Extended Oberon, the length of a string constant (len) is encoded together with its string buffer position (strx) in the single object field obj.val. This was necessary because no other fields were available in obj (except exno perhaps, but there
are other reasons not to abuse that field). The encoding of obj.val (20bits for strx, 12 bits for len for globally declared strings) was chosen such that implementing exporting and importing string constants is made easy, i.e. such that the *same* code
in ORG.MakeItem can be used for global and imported string constants (where the least significant 20bits are the exno):
x.a := y.val MOD 100000H; (*strx/exno*) x.b := y.val DIV 100000H (*len*)
The field x.r is used to determine whether a string is global (x.r = 0) or imported (x.r = mno). This is why ORG.MakeStringItem (which is only ever called for global, but not for imported strings) has been adapted to include the assignment x.r := 0, and
ORG.MakeItem (which is used for imported strings), the assignment x.r := y.lev automatically sets x.r to the mno for imported strings (because ORB.Import sets y.lev to mno).
For the above reasons, one cannot simply mix and match code from Project Oberon 2013 and Extended Oberon. One has to take "all or nothing" from ORP.Declarations, ORP.qualident, ORP.loadStringAdr, ORG.MakeStringItem, ORG.MakeItem, ORB.Export and ORG.Close.
All this is explained in more detail at:
https://github.com/andreaspirklbauer/Oberon-importing-string-constants
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)