Request for feature: ALIAS
JRoark
Posts: 1,215
@ersmith Would you consider adding a new feature to FlexBASIC? If possible, an ALIAS keyword (or similar) that would allow all calls to a specified sub/function be rerouted by the compiler to another sub/function?
Example:
ALIAS delayms() as pausems()
So any calls made to delayms() would be sent instead to pausems(). No changes in argument types, order etc need occur. Just a 1:1 swap of one function name for another.
Comments
IWe have a preprocessor in Basic so maybe
#define delayms pausems
can do the job
An alias feature is not a bad idea, but as @pik33 said the #define command will handle this in current versions of FlexBASIC. The only downside of #define is that it is case sensitive; I'll probably change this in a future release, since case sensitivity in the preprocessor makes sense for C but not for BASIC and Spin.
In my Not so humble opinion case sensetivity(sp?) does not make sense in ANY language.
Enjoy!
Mike
Muchly appreciated, Eric! I guess the syntax isnt too important, but the more I think on this the more I’d like to see something like:
declare delayMS() as alias pauseMS()
@pik33 Yup, I’ve been using the #define functionality for quite a while now, but I’m really bad about camelCase’ing things inconsistently, which tends to raise havoc. As @msrobots says, a “perfect” language (BASIC! hehehe) should be entirely case-insensitive.
JRoark are you asking to be able to redefine the "alias" during program runtime, as a function pointer? as I'm sure you're aware, this basic is compiled and not interpreted at runtime.
If you were to define a function named delayMS where all it did was call pauseMS, the optimizer would see this.
I’m just looking to “remap” any calls made to the function specified by the alias to another function. This would be done at compile-time. I could indeed insert a “stub” routine that did nothing but call the “right” routine, but that seems a bit ugly. I believe ALIAS is how this gets handled in most other BASICs.
but why not use the existing name?
(1) porting the code from another Basic "flavor"
(2) using functions from objects
I forgot about #define and my include file is full of these:
I will rewrite this using #define
Function pointers work in Spin, even in flexspin variant, but I had problems to make it run in Basic. The problem was strange. I have 4 putpixel variants for 1,2,4,8 bpp screen. The Spin driver uses function pointers to set the proper putpixel when it sets the graphics mode.
At the main Basic program I can do
v030.putpixel=v030.p4
and it works: functions in p030, like putchar, box, circle, now use 4bpp putpixel variants. But... Basic program doesnt. Calling v030.putpixel after the change doesn't call the new function and I don't know what is exactly called because nothing is drawn on the screen
I worked this around:
In the driver:
and then from Basic I use plot instead of putpixel. Then I can change the putpixel function pointer from Basic and it works.
I have to learn how to use a preprocessor .... this works:
#define putpixel1 v030.putpixel
This works... strange. I can't use 'putpixel' after this any more as it says :
error: unknown identifier v030 in class hng033rm_spin2
#define putpixel v030.putpixel
That's because every occurence of the word "putpixel" is replaced by "v030.putpixel", and it is recursive, so "putpixel" exands to "v030.putpixel", but then that putpixel expands again to "v030.putpixel.putpixel".
How exactly are you calling it? It's possible that BASIC is getting confused about the type of v030.putpixel... as a member of a Spin object it doesn't naturally have a type (so in particular BASIC will not know that it is a pointer to a function). I'm actually a little surprised that this isn't causing some kind of error.
Here's the documentation for DECLARE ALIAS that's checked in to github now:
DECLARE ALIAS
This form of declare defines an alias for an existing identifier. The simple form is just:
With this form, every reference to
newIdent
in the code is translated behind the scenes tooldIdent
. This will work for any kind of identifier, including functions, subroutines, and constants.For identifiers that represent variables, it is also possible to have the alias represent a different "view" of the variable (using a different type). For example, after:
then both
x
andxi
point to the same variable; when referred to asx
the data is interpreted as a single, but when referred to asxi
it is interpreted as an integer. Note that no type checking or conversion is performed, so this is potentially a dangerous way to alias variables, and should be used with care.For global variables and members of classes, it is also possible to alias the individual bytes of the variable:
Then the individual bytes of the variable
x
may be addressed asxa(0)
,xa(1)
, and so forth. There are some huge caveats associated with this:(1) Again, no type checking is performed (including checking of the size of the array), so it is the programmer's responsibility to make sure the array is of the appropriate size.
(2) This form of ALIAS will not usually work as expected with local variables, which are kept in registers rather than memory.
@ersmith WOWZERS! I love it! Thank you!
This DECLARE ALIAS implemented one of Pascal's absolute keyword functionalities. Two things in one construct Good to have both of these.
This hit at exactly the right time:
I’ve been searching for a way to quickly save chunks of memory (structures, arrays) to flash or non-vol memory when power drops… and restore it when power returns. This gives me new hope I can do that without bloating the code much at all. Just read it all out byte for byte and stuff it into non-vol.
Do you see a way to use it like TP's absolute with a constant address?
Currently I use
var mem8 = cast(ubyte ptr,0)
to overlay the hub memory with an array (substitute for peek/poke), but maybe there is a new way to do this via the aliases.If not (yet), maybe allowing integer (address) constants in there would make sense?
This syntax seems to have no option to place the variable at the address. I use absolute in RPi to name the hardware registers and use them as variables - here is an example of such use: https://github.com/pik33/SimpleAudio P2 has no such things as registers in the hub space. To access memory at the address I wrote a set of peek/poke functions (peek/dpeek/lpeek, poke,dpoke,lpoke) - and addr - these functions should be a standard functions in any Basic - they are sufficient for me now.
No, and the internal mechanism as set up right now wouldn't really work with an address instead of a symbol. Since the P2 doesn't have any memory mapped registers I don't think it's a big loss.
Hmmm, I think I spoke too soon. In the particular case where you want to declare an alias to an integer address, you can now do:
to make
xa
be an integer value located at address 0x10000. The value must be a literal integer (if you use a constant, you'll end up creating an alias for the constant name).I also noticed that PRINT of pointers was throwing a compile error. I think making it print a hex address instead makes more sense, so I've done that.
FYI: I have been looking at this device. In the event of a power failure, the cap provides enough power to automatically dump the SRAM to EEPROM.
https://uk.farnell.com/microchip/47l16-i-p/eeram-16kbit-2k-x-8bit-dip-8/dp/2674852?st=47l16
That is an interesting creature indeed. Time to study that data sheet…
It seems the compiler doesn't like arrays to be absolute aliased.
declare title alias $73838 as ulong(28)
then
was translated to
Read what ersmith said.
"The value must be a literal integer".
The value** IS** literal integer and the variable IS placed at the addres I wanted. This worked.
The problem is: if this variable is an array, indices don't work.
Instead of doing operation on elements of array, all operations was done on its first element.
Constant indices don't work: variable ones do. That's a bug in the optimizer, and is fixed in the current github.