PBASIC 2.5 Alias Semantics: Missing Intuitive Options?
Phil Pilgrim (PhiPi)
Posts: 23,514
This should be simple. I've got a 7-byte array named char. I want to share the first two elements with a couple scratch variables, scr0, and scr1. Here's my first, very intuitive approach:
Nope: compiler wags its finger at the (0) subscript. Okay, that seems rather arbitrary, but I've got another option:
'Still doesn't like the subscript. So I try this:
Nope again: compiler points to the BYTE0 complaining that it wants a smaller-sized modifier than the Byte that char is defined as. But why?
Okay, if it wants something smaller, my last resort:
The compiler likes it, but I don't. I've reserved eight bytes for char, when I only needed seven. And what if char and the scratch variables had needed to be Words instead of Bytes? Furthermore, what if I had need a scr2? There's no BYTE2 modifier available for that.
Okay, I know I can get where I want to go with something like this:
But this is bad, bad, bad. It assumes that variables of like size are allocated in order of appearance (which they happen to be), but that's a hidden rule (i.e. not obvious from the program itself).
The more intuitive approaches are logical, consistent, and should just work; but they don't. OTOH, even though I've had my coffee, I may be missing something obvious. I do hope so.
-Phil
' {$STAMP BS2pe} ' {$PBASIC 2.5} char VAR Byte(7) scr0 VAR char(0) scr1 VAR char(1)
Nope: compiler wags its finger at the (0) subscript. Okay, that seems rather arbitrary, but I've got another option:
' {$STAMP BS2pe} ' {$PBASIC 2.5} char VAR Byte(7) scr0 VAR char.LOWBYTE(0) scr1 VAR char.LOWBYTE(1)
'Still doesn't like the subscript. So I try this:
' {$STAMP BS2pe} ' {$PBASIC 2.5} char VAR Byte(7) scr0 VAR char.BYTE0 scr1 VAR char.BYTE1
Nope again: compiler points to the BYTE0 complaining that it wants a smaller-sized modifier than the Byte that char is defined as. But why?
Okay, if it wants something smaller, my last resort:
' {$STAMP BS2pe} ' {$PBASIC 2.5} wchar VAR Word(4) char VAR wchar.BYTE0 scr0 VAR wchar.BYTE0 scr1 VAR wchar.BYTE1
The compiler likes it, but I don't. I've reserved eight bytes for char, when I only needed seven. And what if char and the scratch variables had needed to be Words instead of Bytes? Furthermore, what if I had need a scr2? There's no BYTE2 modifier available for that.
Okay, I know I can get where I want to go with something like this:
' {$STAMP BS2pe} ' {$PBASIC 2.5} scr0 VAR Byte scr1 VAR Byte dummy VAR Byte(5) char VAR scr0
But this is bad, bad, bad. It assumes that variables of like size are allocated in order of appearance (which they happen to be), but that's a hidden rule (i.e. not obvious from the program itself).
The more intuitive approaches are logical, consistent, and should just work; but they don't. OTOH, even though I've had my coffee, I may be missing something obvious. I do hope so.
-Phil
Comments
You'll have to take it up with Jeff about aliasing to array variables. But I have simply accepted the workaround of using implicit arrays, which works beautifully.
IMHO, it is not even ugly.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Well, I guess we can agree to disagree about aesthetics. It just pains me that things could be better than they are, without breaking anything. PBASIC 2.6 maybe? I hope so!
-Phil
BTW, some time ago in some thread, you had made observations about counterintuitive behavior in the parsing of WAIT strings in SERIN commands, with repeating characters. Do you recall that thread, where it is?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Is this the thread you're referring to?
··http://forums.parallax.com/showthread.php?p=628740
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
Heh, I know what you mean. But it's not all bad. If I forget the page was ever there to begin with, the joy of rediscovery is just as thrilling as seeing it the first time!
-Phil
Yes, this is a bit backwords, but does work reliably.·
Here's how I would do it:
It doesn't matter that scr1 will only be referenced as a single character.· Incidentally,·the BASIC Stamp 2 (and above) always treats any reference to a variable as a base+offset operation, regardless of whether it was actually defined as an array or not.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Jeff Martin
· Sr. Software Engineer
· Parallax, Inc.
'Any chance of a change in the next version of PBASIC?
-Phil
The same set of physical memory locations serves multiple purposes, both as as single variables , different sizes, as well as arrays. Efficient use of limited Stamp ram. That could also be done in a syntax that starts with an array like char(8), and creates aliases off of that, but it is still no more or less messy when it has to serve lots of purposes.
My program template starts by defining a set of word variables, because word variables are always first in memory and stay put, even if other scratch variables of any size are defined later. Some of the initial words are fixed in purpose as pointers and status flags, while others serve different local purposes as tasks come up in the program flow. Sometimes they are used individually, as in acquiring data from an ADC, and sometimes as an array with different sizes of elements, such as retrieving a byte string from a real time clock and then processing it as an array of nibs. There is lots of exchange, getting and putting values from scratchpad RAM. When the scope of a task that uses a variable is very limited, local, I usually don't even bother to give it a separate alias name, just a note in a comment. I find that less prone to error than keeping track of what alias is associated with which physical memory location. The small mind model, close to the hardware. It works for me, anyway.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
When I programmed the Scribbler template, I simply gave up tyring to let the compiler do the allocation. The code below is what I ended up with. I guess it's the only way to get absolute control over where things go. And there's no mistaking how much memory is left over, either. It would be interesting, though, to come up with a spreadsheet-type app that lets you enter the allocation table graphically and writes the code for it. Hmmm.
But all these other techniques notwithstanding, I would still like to see array element aliasing.
-Phil
VAR Word
or
VAR Byte
in each position where in the above it is assigned as,
VAR wN ' with N=0, 1, 2
or
VAR bN ' with N=6, .. ,25
All the assignments of aliases would remain exactly as they are. The end result would be exactly the same allocation by the compiler of names to the physical memory locations. I'm not saying there would be any advantage to doing it that way within that well thought out structure, just wondering about why you gave up on the compiler?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com
It's not so much that it might mess it up, but that you can't see what it's doing or, in my case, see at a glance from the program source alone (i.e. without hitting CTRL-M) how much is left over. Granted, the allocation rule, "Assign from bigeest to smallest, and after that in order by appearance," is logical, consistent, and unlikely to change; but it's not part of the language's syntax. So programs that rely on it don't reveal that allocation explicitly (i.e. without one's considering the hidden rule). I just needed to be able to see what I was doing. In most cases, however, I don't really care how things are allocated, unless I'm bumping up against memory limits and having to share variables.
This is why — getting back to the original subject — I believe that array aliasing is important. An array, even though it's allocated by the compiler, imposes a visible substructure on its own portion of the memory. By aliasing variablea to array elements, I could see at a glance where, within that substructure these variables lie and how much of that structure is shared. Plus, as we've seen, if the array already exists for another purpose, trying to alias variables to it leads to awkwardness in PBASIC 2.5. It's a minor point perhaps, but the convenience seems far to outweigh any reasons for not doing it, which, from a solely technical standpoint, appear non-existent.
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 8/10/2007 7:37:28 PM GMT