Shop OBEX P1 Docs P2 Docs Learn Events
FlexProp: a complete programming system for P2 (and P1) - Page 21 — Parallax Forums

FlexProp: a complete programming system for P2 (and P1)

1181921232455

Comments

  • aaaaaaaargh,
    For the second half of what you said, have you already tried using a constant, or literal expression that compiles to a constant, in a case statement?

    The optimizer is pretty strong to know these things already and remove a ton of code.

  • @aaaaaaaargh said:
    Hello,
    to make FlexBasic even more awesome it would be nice to have more options in the select case statement.
    e.g
    Case 1,5,436
    Case 10 To 20, 30, 40 To 50
    Case "S","T","U"

    That would be a nice addition, I'll see what I can do.

    or an integer jumptable like in freebasic
    Select Case As Const integer_expression
    to make fast jumps would also be a nice addition

    The compiler will automatically use jump tables if it can (i.e. the jump table size is not too large), both for SELECT CASE and for ON GOTO.

  • @ersmith said:
    The compiler will automatically use jump tables if it can (i.e. the jump table size is not too large)

    Oh that sounds great, is there any way to know when the table is "too large", maybe from the .lst file?

  • @ersmith re FlexBASIC: Is there a way to detect what type of variable (long, ulong, float, byte, etc) has been passed to a function/sub whose inputs have been typed as ANY? Here is where I’m going with this conceptually: (vartype() is an imaginary “magic” function that returns the type of the variable given to it)

    FUNCTION AddIt(a as any, b as any) as string
    Select case vartype(a) 
       Case long_type
          Return strInt$(a+b)
       Case float_type
          Return str$(a+b)
       Case else
          Return “error”
    End select
    END FUNCTION
    

    Any pointers? :)

  • @aaaaaaaargh said:

    @ersmith said:
    The compiler will automatically use jump tables if it can (i.e. the jump table size is not too large)

    Oh that sounds great, is there any way to know when the table is "too large", maybe from the .lst file?

    Sure, if you look at the .lst file the select case will look something like:

    0075c                 | '   select case n
    0075c     D7 B0 01 F6 |     mov local02, local01
    00760     01 B0 85 F1 |     sub local02, #1
    00764     06 B0 25 F3 |     fle local02, #6
    00768     30 B0 61 FD |     jmprel  local02
    0076c                 | LR__0001
    0076c     18 00 90 FD |     jmp #LR__0002
    00770     14 00 90 FD |     jmp #LR__0002
    00774     4C 00 90 FD |     jmp #LR__0004
    00778     48 00 90 FD |     jmp #LR__0004
    0077c     44 00 90 FD |     jmp #LR__0004
    00780     40 00 90 FD |     jmp #LR__0004
    00784     78 00 90 FD |     jmp #LR__0006
    00788                 | LR__0002
    00788                 | '      print "one or two"
    

    in the case where a jump table is used.

    If a jump table can't be used, then the select case turns into a series of tests and branches, like:

    0075c                 | '   select case n
    0075c     01 00 00 FF 
    00760     E8 AF 5D F2 |     cmps    local01, ##1000 wcz
    00764     0C 00 90 CD |  if_b   jmp #LR__0001
    00768     03 00 00 FF 
    0076c     D0 AF 5D F2 |     cmps    local01, ##2000 wcz
    00770     1C 00 90 ED |  if_be  jmp #LR__0003
    00774                 | LR__0001
    00774     03 AE 5D F2 |     cmps    local01, #3 wcz
    00778     08 00 90 CD |  if_b   jmp #LR__0002
    0077c     05 AE 5D F2 |     cmps    local01, #5 wcz
    00780     48 00 90 ED |  if_be  jmp #LR__0005
    

    The general rule of thumb is that for a jump table there can be at most 255 entries, and at least 1/6 of those must be distinct (so if you have one case that covers 200 entries and then 2 more single cases, it'll use compares instead of a jump).

  • @JRoark said:
    @ersmith re FlexBASIC: Is there a way to detect what type of variable (long, ulong, float, byte, etc) has been passed to a function/sub whose inputs have been typed as ANY? Here is where I’m going with this conceptually: (vartype() is an imaginary “magic” function that returns the type of the variable given to it)

    FUNCTION AddIt(a as any, b as any) as string
    Select case vartype(a) 
       Case long_type
          Return strInt$(a+b)
       Case float_type
          Return str$(a+b)
       Case else
          Return “error”
    End select
    END FUNCTION
    

    Any pointers? :)

    There is no run time type information, so there's really no way to do exactly this. You could perhaps come close with a template function:

    any(T) FUNCTION Addit(a as T, b as T) as string
      dim x as T
      dim intx as long
      x = a + b
      intx = x
      if (intx == x) then
        return strInt$(intx)
      else
        return str$(x)
      end if
    END FUNCTION
    

    This has a few problems in the current flexbasic, namely:
    (1) The template type system seems to get the type of Addit confused a bit, and it ends up as not being exactly a string but rather a pointer to a character (so it cannot be printed directly :( ). This is a bug, and I'll try to fix it, but the temporary workaround is to assign it to a string.
    (2) The optimizer isn't smart enough to optimize away the intx == x test in the case where the original variables are of type long. I'll work on fixing that as well.

  • aaaaaaaarghaaaaaaaargh Posts: 82
    edited 2021-07-30 15:32

    @ersmith said:
    Sure, if you look at the .lst file the select case will look something like:

    Thanks, that works great! :smile:

  • arkretarkret Posts: 8
    edited 2021-08-02 22:40

    Hello, flexprop won't compile. Everything was working good in February when I last used it. I reinstalled flexprop to the latelest version. The program opens and I can open and save files. When I click Compile nothing happens. Any ideas what the problem is?

    Also there is no compile window below the code.

  • @arkret said:
    Hello, flexprop won't compile. Everything was working good in February when I last used it. I reinstalled flexprop to the latelest version. The program opens and I can open and save files. When I click Compile nothing happens. Any ideas what the problem is?

    (1) What platform are you running on? Windows, Mac, Linux?
    (2) Did you download flexprop.zip, or build flexprop yourself from source? If a download, which version did you download?

    Also there is no compile window below the code.

    That makes me think that somehow your config file may have been corrupted. Try deleting that -- it's named ".flexprop.config" and is found in your home directory. Alternatively, try creating an empty file named .flexprop.config in the same directory as flexprop.exe / flexprop.tcl.

  • @ersmith said:
    (1) What platform are you running on? Windows, Mac, Linux?
    (2) Did you download flexprop.zip, or build flexprop yourself from source? If a download, which version did you download?

    I am using a Mac and I downloaded 5.5.2

    That makes me think that somehow your config file may have been corrupted. Try deleting that -- it's named ".flexprop.config" and is found in your home directory. Alternatively, try creating an empty file named .flexprop.config in the same directory as flexprop.exe / flexprop.tcl.

    I could not find a "flexprop.config" but I did try to create a blank text file and save it int he same folder as flexprop.tcl. I might not have understood where flexprop.config is supposed to be?

    I also deleted flexprop and reinstalled it. Still no compile window.

  • @arkret said:

    That makes me think that somehow your config file may have been corrupted. Try deleting that -- it's named ".flexprop.config" and is found in your home directory. Alternatively, try creating an empty file named .flexprop.config in the same directory as flexprop.exe / flexprop.tcl.

    I could not find a "flexprop.config" but I did try to create a blank text file and save it int he same folder as flexprop.tcl. I might not have understood where flexprop.config is supposed to be?

    Note that there are two periods, one at the very beginning and one in between the words "flexprop" and "config". From a console window you could try:

    rm ~/.flexprop.config
    

    to get rid of the file.

  • @ersmith said:

    Note that there are two periods, one at the very beginning and one in between the words "flexprop" and "config". From a console window you could try:

    rm ~/.flexprop.config
    

    to get rid of the file.

    I tried that and still nothing. Here is the view from the terminal window:

    The default interactive shell is now zsh.
    To update your account to use zsh, please run chsh -s /bin/zsh.
    For more details, please visit https://support.apple.com/kb/HT208050.
    Alexs-MacBook-Pro:~ alex$ /Users/alex/Desktop/flexprop/flexprop.tcl ; exit;
    rm ~/.flexprop.config

    Am I missing something? Is there a setting that I need to change?

  • I don't understand why there's a line that says "/Users/alex/Desktop/flexprop/flexprop.tcl; exit;" in your terminal output. You need to do the rm ~/.flexprop.config before running flexprop.tcl. Here's what I suggest:

    (1) Restart your Mac, so we know we're starting fresh. There's an option for this under the apple menu.
    (2) Log in and start the Terminal app. You can get to this by browsing to /Applications/Utilities in the finder, then clicking on Terminal
    (3) Type:

    rm ~/.flexprop.config
    cd ~/flexprop
    ./flexprop.tcl
    

    FlexProp should start up. It'll be configured for P2 by default; if that's the correct platform, then go to File > Open File... in the menu bar, and select one of the samples (e.g. blink_all_cogs.spin. It should load into the top part of the window. Then click on the "Compile & Run on P2" button. If you have a P2 Eval board this should cause all the built in LEDs to start blinking in a kind of pseudo-random pattern. You'll also get some compile messages in the "Compiler Output" pane in the bottom part of the main FlexProp window.

    There's also a console window opened with a connection to the serial port. That seems to be a little bit wonky right now, it doesn't always appear on top but if you look for it it should be there.

  • @ersmith said:

    (1) Restart your Mac, so we know we're starting fresh. There's an option for this under the apple menu.
    (2) Log in and start the Terminal app. You can get to this by browsing to /Applications/Utilities in the finder, then clicking on Terminal
    (3) Type:

    rm ~/.flexprop.config
    cd ~/flexprop
    ./flexprop.tcl
    

    Now the compiler window is back and says the code compiles, but nothing is loading onto the P2 Eval? I am using the blink1.spin2. I tried this board on another computer and it seems to work, so it is not the board.

  • What error messages are showing up in the "Propeller Output" terminal window when you try to run on the P2? Do any serial ports show up under the FlexProp "Ports" menu? If you select the "Special > Enter P2 ROM Taqoz" menu item do you see the TAQOZ# prompt in the propeller output window that opens up? This is not the same as the compiler output window, it's a new terminal window that opens... as I mentioned sometimes it gets hidden by other windows, so you may have to look for it.

  • Hello!
    I have couple of questions related to flexbasic:
    1) Is there a way to access FlexBasic Variables / Arrays using different variable types by declaring them at the Address of another variable?
    Back in the old days I used this kind of thing a lot (in Powerbasic) using the DIM xxxx AT Address command
    Something like this

    DIM L(64) AS ULONG
    DIM B(256) AS UBYTE  AT Addressof(L(0))
    

    2) Or partial variabel access like on the Basic Stamp
    abyte = aword.HIGHBYTE

    3) Is there any way to redim an Array?
    REDIM BLA(5)

    kind regars,
    Fred

  • @Fred777 said:
    1) Is there a way to access FlexBasic Variables / Arrays using different variable types by declaring them at the Address of another variable?
    Back in the old days I used this kind of thing a lot (in Powerbasic) using the DIM xxxx AT Address command
    Something like this

    DIM L(64) AS ULONG
    DIM B(256) AS UBYTE  AT Addressof(L(0))
    

    Not directly, but FlexBasic has pointers and CAST so you can do something like:

    DIM B AS UBYTE POINTER
    B = CAST(UBYTE POINTER, @L(0))
    

    (or to save typing and skip type checking you could do B = CAST(ANY, @L(0)), since ANY can be cast to/from anything at all).

    2) Or partial variabel access like on the Basic Stamp
    abyte = aword.HIGHBYTE

    Hmmm, that might be an interesting thing to add to the language, but for now you'll have to shift and mask (abyte = (aword>>8) AND 255).

    3) Is there any way to redim an Array?
    REDIM BLA(5)

    No, in FlexBasic arrays occupy a fixed (static) amount of memory, and it's not possible to change that. Again, you might be able to accomplish something similar with pointers.

    Regards,
    Eric

  • Thanks for your response, I'll try the pointer thing. ;-)

    @ersmith said:
    Hmmm, that might be an interesting thing to add to the language, but for now you'll have to shift and mask (abyte = (aword>>8) AND 255).

    If your're considering this then here is a list of what good old PBASIC has:

    LOWBYTE  Low byte of a word 
    HIGHBYTE High byte of a word 
    BYTE0    Low byte of a word 
    BYTE1    High byte of a word 
    LOWNIB   Low nibble of a word or byte 
    HIGHNIB  High nibble of a word or byte 
    NIB0     Nibble 0 of a word or byte 
    NIB1     Nibble 1 of a word or byte 
    NIB2     Nibble 2 of a word 
    NIB3     Nibble 3 of a word 
    LOWBIT   Low bit (LSB) of a word, byte, or nibble 
    HIGHBIT  High bit (MSB) of a word, byte, or nibble 
    BIT0     Bit 0 (LSB) of a word, byte, or nibble 
    BIT1     Bit 1 of a word, byte, or nibble 
    BIT2     Bit 2 of a word, byte, or nibble 
    BIT3     Bit 3 of a word, byte, or nibble 
    BIT4 ... BIT7  Bits 4 through 7 of a word or byte 
    BIT8 ... BIT15  Bits 8 through 15 of a word 
    

    really useful stuff for the humble basic programmer :-)

  • Hi,
    have a strange effect in flexbasic when using Function for "cog" / pausems / optimizer level1: (happens in V5.5.2 and 5.9.1-beta-v5.4.3-419-g359148b7)

    Consider the follwoing code:

    OPTION EXPLICIT
    const HEAPSIZE=8192  
    
    Function TestFunc(Adr As ulong) as ubyte
       pauseus 1
        Return 33
    End Function    
    
    Dim Time1,Time2,a as ulong
    Dim b             as ubyte
    
    While 1
    
        Time1 = GetUs()
    
       For a = 1 to 100
          b = TestFunc(111)
       Next a
    
       Time2 = GetUs()
        Print "Time:";Time2-Time1;"   [ENTER]";
       Input$(1)
    
    Wend
    
    

    When runing this using flexbasic with optimizer level 1 (-O1) then output is as follows
    Time:422 [ENTER]
    But when the Function runs in cog ( Function for "cog" TestFunc(Adr As ulong) as ubyte ) it hangs and nothing is displayed.
    This only seems to happen with optimizer level -O1
    So switching to optimizer level 0 or 2 also fixes it.
    But also removing the "pauseus" statement fixes this.
    Strange......

  • @aaaaaaaargh : Thank you for the bug report. The problem is that the optimizer is incorrectly putting the loop that calls TestFunc into FCACHE if TestFunc is marked as "cog". The pausems function also uses FCACHE, and so this causes corruption. WIth -O0 there is no fcache, and with -O2 the pausems is inlined and so doesn't need to be called.

    This will be fixed in the next version, but for now, avoid using the for "cog" specifier for functions that are not leaf functions (i.e. that call other functions).

  • JRoarkJRoark Posts: 1,215
    edited 2021-08-07 17:03

    @ersmith It appears some mischief is occuring in the way of things being relocated in 5.9.1-BETA in Windows. Specifically any attempt to access the "Terminal Only" option from "Main Menu - > Special -> Terminal Only" gives you:

    Windows cannot find 'd:/Flex2Gui/flexgui/src/bin/loadp2'. Make sure you typed the name correctly then try again.
    

    I noted that LoadP2.exe is located in the 'd:/Flex2Gui/flexgui/src/bin/loadp2" path instead, so as a quick fix I just created the missing directory and copied the file, but I figured you'd want to know for the next release.

    EDIT: Whoops. Looks like several things didn't make it into the "new" tree. I cant compile either, (same missing file error) so I just copied the whole schmutz over.

    EDIT2: Now I can get the compiler to run, but it isn't finding some of the C libraries. Example:

    "d:/Flex2Gui/flexgui/src/bin/flexspin" -2 -l --tabs=3 -D_BAUD=230400 -O1    -I "d:/Flex2Gui/flexgui/src/include"  "d:/Flex2Gui/flexgui/P2 Libs/DateTimeLibP2.bas"
    Propeller Spin/PASM Compiler 'FlexSpin' (c) 2011-2021 Total Spectrum Software Inc.
    Version 5.9.1-beta-v5.4.3-419-g359148b7 Compiled on: Aug  3 2021
    No such file or directory
    DateTimeLibP2.bas
    Unable to open file `libsys/fmt.c': child process exited abnormally
    Finished at Sat Aug  7 11:37:18 2021
    

    EDIT3: It also looks like there were some changes to the SPIN parser. When compiling ERSmith's ANSI.SPIN, it got grumpy when IF/ELSEIF's used a mix of tabs and spaces for indents. I've never actually edited this code (Me no se habla Spin), and it's compiled fine up until now.

    EDIT4: Having fixed the above (I think), now it's not finding libc/unix/mount.c

  • I had 6.0 beta on my Linux box, that was having similar problems. Once I loaded 5.9.1BETA to my Linux box, everything started working as expected. I can confirm that the Windows 5.9.1 BETA is showing the same same thing on my Windows box.

    Ray

  • Sorry for the mix-up with 5.9.1; the version I uploaded had the wrong paths. I've put a corrected version up on Patreon that should have this fixed.

    The TABS problem has probably been there for a while. For maximum compatibility you should set the FlexGui tab stops to 8 characters -- that option is passed to the compiler and used by it to figure out indentation in Spin code.

  • JRoarkJRoark Posts: 1,215
    edited 2021-08-08 18:52

    @ERSmith: This may just be a lack of information on my part, but here goes. RE: FlexBASIC 5.9.1-B under windows with REV C Eval board. The code I'm using to show this is below.

    Issue #1: If FLASH is enabled on the board, you cant use the SD card. And vice-versa.

    To prove it, configure the switches like this, insert an SD card and run the test code below. You can't compile to flash (or boot from flash), but the SD card works fine:

    USB RES=ON
    FLASH=OFF
    P59+=OFF
    P591=OFF
    

    Now change one switch and you can compile to flash (and boot from it), but the SD card wont work:

    USB RES=ON
    FLASH=ON   <-- this
    P59+=OFF
    P591=OFF
    

    My understanding is that FLASH and SD should coexist together, but it doesn't seem to work that way. Any idea what is going on here?

    ISSUE #2: While looking thru the FS code in SDMM.CC, I came on this:

    static
    void dly_us (UINT n)    /* Delay n microseconds (avr-gcc -Os) */
    {
        _waitx( n * 160 );
    }
    

    As I read this, that will produce an N uS delay... but only at 160 mhz. There are a bunch of different calls to that routine in the filesystem code. I was having some flakey issues with reading/writing to the SD card, and when I changed that 160 to 320 the problems started getting better. Is there a better way to do this delay that accounts for CPU speed? (Not a C coder here!)

    Find below the test code I used for Issue #1. Ugly, but works:

    OPTION EXPLICIT                         ' must declare all variables explicitly
    OPTION BASE 0                               ' array base index is zero, not one
    
    CONST _clkfreq = 320_000_000
    dim tmpbuffer$, filename$ as string
    dim myerr as long
    
        filename$ = "/sd/file.txt"
        tmpbuffer$ = "THIS IS A TEST. "
        print 
        print "SDMMC Test"
        print "========================"    
        try
            print "WRITE PHASE:"
            print "-Attempting MOUNT...";
            mount ("/sd",  _vfs_open_sdcard())
            print " success!"
            print "-Attempting OPEN...";
            open filename$ for append as #3
            print " success!"
            print "-Attempting WRITE...";
            print #3 tmpBuffer$;
            print " success!"
            print "-Attempting CLOSE...";
            close #3
            print " success!"
            print
            print "READ PHASE:"
            print "-Attempting OPEN...";
            open "/sd/file.txt" for input as #3
            print " success!"
            print "-Attempting READ...";
            tmpbuffer$ = ""
            tmpbuffer$ = input$(128,3)
            print " success!"
            print " Data:["; tmpbuffer$; "]"
            print "-Attempting CLOSE...";
            close #3
            print " success!"
            print
        catch myErr
            'no sd card, card is full, etc
            print
            print "ERROR=";myErr; " [";strError$(myErr); "]"
        end try
    
        print "========================"    
        print "All done."
    
  • JRoarkJRoark Posts: 1,215
    edited 2021-08-09 14:14

    @ersmith Another bit of wierdness for you: The FlexBASIC GetUS() function works for about ~75 minutes after boot up (on a 320mhz clock setting). When it hits 0xFFFF_FFFF, it stops there. It doesn't roll over and start counting back at 0x0000_0000. So any program that uses GetUS() will run for ~75 minutes before it stops working correctly. I assume the same issue will be present in GetMS() and GetSec() as well, but I haven't tried those due to the long time involved. From the docs:

    GETUS()
    Builtin function. Returns the number of microseconds since the device was
    turned on. On the Propeller 1 this wraps around after approximately 54 seconds.
    On the P2 the system counter has 64 bits, so it will work for about an hour.
    

    The docs don't actually say the function WILL work past the 32-bit terminal count on the P2 (the wrap seems only to occur for the P1), so I cant really call this a bug, but... is there any way to make these function(s) roll over to zero when they reach max count on the P2? (Or make them 64 bits, since the underlying system counter in the P2 is 64 bits, and because then it would take me ~1,827 years to find the next rollover bug to gripe about, in which case I'll be forced to file that bug report in the afterlife). :)

  • @JRoark said:
    @ERSmith: This may just be a lack of information on my part, but here goes. RE: FlexBASIC 5.9.1-B under windows with REV C Eval board. The code I'm using to show this is below.

    Issue #1: If FLASH is enabled on the board, you cant use the SD card. And vice-versa.

    I honestly don't know if this is a hardware or software issue. Is there any way you can test it with some other software (not FlexProp's built in SD routines)? I'm not in a position right now to be able to try this on a real board.

    ISSUE #2: While looking thru the FS code in SDMM.CC, I came on this:

    static
    void dly_us (UINT n)  /* Delay n microseconds (avr-gcc -Os) */
    {
        _waitx( n * 160 );
    }
    

    Ouch, that's some old crufty code. Instead of the _waitx( n*160 ) it should read _waitus(n).

    @ersmith Another bit of wierdness for you: The FlexBASIC GetUS() function works for about ~75 minutes after boot up (on a 320mhz clock setting). When it hits 0xFFFF_FFFF, it stops there. It doesn't roll over and start counting back at 0x0000_0000.

    Actually it's even weirder than that, it kind of "bounces" at 0 and then starts counting down. It's my mistake, I assumed that the qdiv instruction to do a 64 bit by 32 bit division would wrap around on overflow, but it doesn't, it does some weird stuff with the remainder instead. I'll try to find a work-around in the next release.

  • What is the command to create a textfile and print to it in Spin2?

  • @arkret said:
    What is the command to create a textfile and print to it in Spin2?

    There isn't one, Spin2 doesn't have any file handling routines built in. If you want to do that sort of thing you'd be better off to use BASIC.

  • With Flex you can easily leverage the strengths of each language. Write the file handling routines in BASIC, include them as an object in your Spin code, and then pass the object a pointer to the buffer in your Spin code.

  • @ersmith Is there any way in FlexBASIC to define a string constant that does not contain "typeable" characters? What I'm looking for is a constant for a CR (or LF, or a BS, etc), but this doesn't work:

    CONST cr = chr$(13)
       or
    CONST cr$ = 13
    

    In the first case, the compiler doesn't know about CHR$() as it relates to making a constant, and in the other it just assigns the value of 13. If the text was "typeable", then it would be easy:

    CONST greeting = "How ya doin?"
    

    I'm confuzzified.

Sign In or Register to comment.