Shop Learn
Request for feature: ALIAS — Parallax Forums

Request for feature: ALIAS

@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

  • pik33pik33 Posts: 1,673
    edited 2022-01-26 08:57

    IWe have a preprocessor in Basic so maybe

    #define delayms pausems

    can do the job

  • ersmithersmith Posts: 5,336

    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.

  • msrobotsmsrobots Posts: 3,555

    In my Not so humble opinion case sensetivity(sp?) does not make sense in ANY language.

    Enjoy!

    Mike

  • JRoarkJRoark Posts: 1,048

    @ersmith said:
    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.

    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.

  • JRoarkJRoark Posts: 1,048

    @whicker said:
    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.

  • msrobotsmsrobots Posts: 3,555

    but why not use the existing name?

  • pik33pik33 Posts: 1,673

    @msrobots said:
    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:

    sub putpixel(x,y,c)
    v030.putpixel(x,y,c)
    end sub
    
    sub position(x,y)
    v030.setcursorpos(x,y)
    end sub
    
    

    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:

    pub plot(x,y,c)
    putpixel(x,y,c)
    

    and then from Basic I use plot instead of putpixel. Then I can change the putpixel function pointer from Basic and it works.

  • pik33pik33 Posts: 1,673
    edited 2022-01-27 10:22

    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

  • ersmithersmith Posts: 5,336

    @pik33 said:
    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".

  • ersmithersmith Posts: 5,336

    @pik33 said:
    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

    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.

  • ersmithersmith Posts: 5,336

    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:

    DECLARE newIdent ALIAS oldIdent
    

    With this form, every reference to newIdent in the code is translated behind the scenes to oldIdent. 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:

    DIM x as single
    DECLARE xi ALIAS x AS integer
    

    then both x and xi point to the same variable; when referred to as x the data is interpreted as a single, but when referred to as xi 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:

    DIM x as single
    DECLARE xa ALIAS x AS ubyte(4)
    

    Then the individual bytes of the variable x may be addressed as xa(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.

  • JRoarkJRoark Posts: 1,048

    @ersmith WOWZERS! I love it! Thank you!

  • pik33pik33 Posts: 1,673
    edited 2022-01-27 21:34

    This DECLARE ALIAS implemented one of Pascal's absolute keyword functionalities. Two things in one construct :) Good to have both of these.

  • JRoarkJRoark Posts: 1,048

    This hit at exactly the right time:

    DIM x as single
    DECLARE xa ALIAS x AS ubyte(4)
    

    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.

  • yetiyeti Posts: 813
    edited 2022-01-28 06:34

    @pik33 said:
    This DECLARE ALIAS implemented one of Pascal's absolute keyword functionalities. Two things in one construct :) Good to have both of these.

    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?

  • pik33pik33 Posts: 1,673
    edited 2022-01-28 07:18

    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.

  • ersmithersmith Posts: 5,336

    @yeti said:

    @pik33 said:
    This DECLARE ALIAS implemented one of Pascal's absolute keyword functionalities. Two things in one construct :) Good to have both of these.

    Do you see a way to use it like TP's absolute with a constant address?

    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.

  • ersmithersmith Posts: 5,336

    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:

    declare xa alias 0x10000 as integer
    

    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.

  • MicksterMickster Posts: 2,082
    edited 2022-01-29 15:50

    @JRoark said:
    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.

    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

  • JRoarkJRoark Posts: 1,048

    @Mickster said:
    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…

  • pik33pik33 Posts: 1,673
    edited 2022-02-05 18:18

    It seems the compiler doesn't like arrays to be absolute aliased.

    declare title alias $73838 as ulong(28)

    then

    title(6)=title(6)+asc("P")
    title(7)=title(7)+asc("r")
    title(8)=title(8)+asc("o")
    title(9)=title(9)+asc("p")
    title(10)=title(10)+asc("2")
    title(11)=title(11)+asc("p")
    title(12)=title(12)+asc("l")
    title(13)=title(13)+asc("a")
    title(14)=title(14)+asc("y")
    title(16)=title(16)+asc("v")
    title(17)=title(17)+asc(".")
    title(18)=title(18)+asc("0")
    title(19)=title(19)+asc(".")
    title(20)=title(20)+asc("0")
    title(21)=title(21)+asc("8")
    

    was translated to

    01e40     38 7A 06 FB |     rdlong  local03, ##473144
    01e44     50 7A 06 F1 |     add local03, #80
    01e48     9C 03 00 FF 
    01e4c     38 7A 66 FC |     wrlong  local03, ##473144
    01e50     9C 03 00 FF 
    01e54     38 7A 06 FB |     rdlong  local03, ##473144
    01e58     72 7A 06 F1 |     add local03, #114
    01e5c     9C 03 00 FF 
    01e60     38 7A 66 FC |     wrlong  local03, ##473144
    01e64     9C 03 00 FF 
    01e68     38 7A 06 FB |     rdlong  local03, ##473144
    01e6c     6F 7A 06 F1 |     add local03, #111
    01e70     9C 03 00 FF 
    01e74     38 7A 66 FC |     wrlong  local03, ##473144
    01e78     9C 03 00 FF 
    01e7c     38 7A 06 FB |     rdlong  local03, ##473144
    01e80     70 7A 06 F1 |     add local03, #112
    01e84     9C 03 00 FF 
    01e88     38 7A 66 FC |     wrlong  local03, ##473144
    01e8c     9C 03 00 FF 
    01e90     38 7A 06 FB |     rdlong  local03, ##473144
    01e94     32 7A 06 F1 |     add local03, #50
    01e98     9C 03 00 FF 
    01e9c     38 7A 66 FC |     wrlong  local03, ##473144
    01ea0     9C 03 00 FF 
    01ea4     38 7A 06 FB |     rdlong  local03, ##473144
    01ea8     70 7A 06 F1 |     add local03, #112
    01eac     9C 03 00 FF 
    01eb0     38 7A 66 FC |     wrlong  local03, ##473144
    01eb4     9C 03 00 FF 
    01eb8     38 7A 06 FB |     rdlong  local03, ##473144
    01ebc     6C 7A 06 F1 |     add local03, #108
    01ec0     9C 03 00 FF 
    01ec4     38 7A 66 FC |     wrlong  local03, ##473144
    01ec8     9C 03 00 FF 
    01ecc     38 7A 06 FB |     rdlong  local03, ##473144
    01ed0     61 7A 06 F1 |     add local03, #97
    01ed4     9C 03 00 FF 
    01ed8     38 7A 66 FC |     wrlong  local03, ##473144
    01edc     9C 03 00 FF 
    01ee0     38 7A 06 FB |     rdlong  local03, ##473144
    01ee4     79 7A 06 F1 |     add local03, #121
    01ee8     9C 03 00 FF 
    01eec     38 7A 66 FC |     wrlong  local03, ##473144
    01ef0     9C 03 00 FF 
    01ef4     38 7A 06 FB |     rdlong  local03, ##473144
    01ef8     76 7A 06 F1 |     add local03, #118
    01efc     9C 03 00 FF 
    01f00     38 7A 66 FC |     wrlong  local03, ##473144
    01f04     9C 03 00 FF 
    01f08     38 7A 06 FB |     rdlong  local03, ##473144
    01f0c     2E 7A 06 F1 |     add local03, #46
    01f10     9C 03 00 FF 
    01f14     38 7A 66 FC |     wrlong  local03, ##473144
    01f18     9C 03 00 FF 
    01f1c     38 7A 06 FB |     rdlong  local03, ##473144
    01f20     30 7A 06 F1 |     add local03, #48
    01f24     9C 03 00 FF 
    01f28     38 7A 66 FC |     wrlong  local03, ##473144
    01f2c     9C 03 00 FF 
    01f30     38 7A 06 FB |     rdlong  local03, ##473144
    01f34     2E 7A 06 F1 |     add local03, #46
    01f38     9C 03 00 FF 
    01f3c     38 7A 66 FC |     wrlong  local03, ##473144
    01f40     9C 03 00 FF 
    01f44     38 7A 06 FB |     rdlong  local03, ##473144
    01f48     30 7A 06 F1 |     add local03, #48
    01f4c     9C 03 00 FF 
    01f50     38 7A 66 FC |     wrlong  local03, ##473144
    01f54     9C 03 00 FF 
    01f58     38 7A 06 FB |     rdlong  local03, ##473144
    01f5c     38 7A 06 F1 |     add local03, #56
    
  • Read what ersmith said.
    "The value must be a literal integer".

  • pik33pik33 Posts: 1,673

    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.

  • ersmithersmith Posts: 5,336

    Constant indices don't work: variable ones do. That's a bug in the optimizer, and is fixed in the current github.

Sign In or Register to comment.