Shop OBEX P1 Docs P2 Docs Learn Events
New BASIC compiler for Prop1 and Prop2 - Page 19 — Parallax Forums

New BASIC compiler for Prop1 and Prop2

11415161719

Comments

  • Roy Eltham is porting the Simple Libraries to fastspin's C compiler. That will allow us to access those libraries from BASIC and Spin as well, since fastspin supports all 3 languages.
    I am thinking about doing a test run, using my CM2302 module and using fastspin Basic. Of course what I would like to do is use the dht22 C code that is in the SimpleIDE library.

    Not quite sure as to where I should start with this. First I would have to get the actual C code that is in the SimpleIDE library, then what do I have to do to make it usable with fastspin Basic.

    Ray
  • Hi
    Having much fun playing with fastspin basic on P1, version 3.9.24.
    Just found a bugget- It seems hex numbers not recognised in data statements.
    ie.
    data 0xaa,0haa,&haa when read into ubyte array all return 0
    changing to decimal works fine
    using hex otherwise seems ok

    Dave


  • tritonium wrote: »
    Hi
    Having much fun playing with fastspin basic on P1, version 3.9.24.
    Just found a bugget- It seems hex numbers not recognised in data statements.
    ie.
    data 0xaa,0haa,&haa when read into ubyte array all return 0
    changing to decimal works fine
    using hex otherwise seems ok

    Dave

    Thanks for the bug report! The "data" statement uses the same code that input does, and it only supported decimal. The next release of fastspin will support hex and binary numbers in data and input. 3.9.26 should be available soon.

    Regards,
    Eric
  • New versions of fastspin and spin2gui (version 3.9.26) are available now from the usual places. There are several improvements to the BASIC compiler, including support for DEF FN and for hex numbers in DATA and INPUT, and also a bug fix for SELECT CASE. There is also an experimental -z flag for compressing the output code, but this is still somewhat buggy so not really ready for production.
  • Hi
    Thanks ersmith.
    I have been using FreeBasic for a number of years so this is a nice resource I never expected. Its going to be especially useful when I finally get my hands on a P2. Being reliant on PropBasic I thought I would be stranded but now I look forward to P2's arrival.
    Thanks again
    Dave
  • ersmith wrote: »
    There is also an experimental -z flag for compressing the output code, but this is still somewhat buggy so not really ready for production.
    It took a while of scratching the back of my head until I realised that "-z" needs a slower terminal baud rate... \o/
    ...at least on P1.
  • Hi again

    Pleased to report all permutations of hex formatting accepted in data statements in new version- thanks.

    Dave
  • Hi

    In trying to read the character rom on P1 in fastspin basic I needed a way to access memory and could not fine a peek or rdlong so resorted to making a function.-
    function rdval(adr as uinteger)
    dim valu as uinteger
    	asm
    	rdlong valu,adr
    	end asm
    return valu
    end function
    


    Is there a proper way?
    Did I miss the obvious?

    Dave
  • The "obvious" way to read from memory is to use a pointer. To cast integers to pointers it's necessary to go through a generic value (of type "any"), like so:
    function rdval(adr as any) as uinteger
      dim p as uinteger pointer
      p = adr
      return p(0)
    end function
    
    print rdval(0xe000)
    
  • kwinnkwinn Posts: 8,697
    edited 2019-05-09 14:26
    ersmith wrote: »
    The "obvious" way to read from memory is to use a pointer. To cast integers to pointers it's necessary to go through a generic value (of type "any"), like so:
    function rdval(adr as any) as uinteger
      dim p as uinteger pointer
      p = adr
      return p(0)
    end function
    
    print rdval(0xe000)
    

    That looks to me like a very "C" style expression and function. It has been a long time since I have done any Basic coding. Have modern day Basics all morphed towards C or is this an atypical version?
  • kwinn wrote: »
    ersmith wrote: »
    The "obvious" way to read from memory is to use a pointer. To cast integers to pointers it's necessary to go through a generic value (of type "any"), like so:
    function rdval(adr as any) as uinteger
      dim p as uinteger pointer
      p = adr
      return p(0)
    end function
    
    print rdval(0xe000)
    

    That looks to me like a very "C" style expression and function. It has been a long time since I have done any Basic coding. Have modern day Basics all morphed towards C or is this an atypical version?
    I guess traditional BASIC would have PEEK and POKE. This seems much cleaner.

  • kwinnkwinn Posts: 8,697
    David Betz wrote: »
    kwinn wrote: »
    ersmith wrote: »
    The "obvious" way to read from memory is to use a pointer. To cast integers to pointers it's necessary to go through a generic value (of type "any"), like so:
    function rdval(adr as any) as uinteger
      dim p as uinteger pointer
      p = adr
      return p(0)
    end function
    
    print rdval(0xe000)
    

    That looks to me like a very "C" style expression and function. It has been a long time since I have done any Basic coding. Have modern day Basics all morphed towards C or is this an atypical version?
    I guess traditional BASIC would have PEEK and POKE. This seems much cleaner.

    I agree. Nice to see multiple languages merging towards common expressions and simpler logical ways of doing things.
  • HI
    The "obvious" way to read from memory is to use a pointer. To cast integers to pointers it's necessary to go through a generic value (of type "any"), like so:
    function rdval(adr as any) as uinteger
    dim p as uinteger pointer
    p = adr
    return p(0)
    end function

    print rdval(0xe000)

    Oh boy "casting is one of those new fangled things I've never needed like oop in general and although that is in FreeBasic I've somehow survived without it.

    Anyway that worked fine- so I tried to put that straight into the main code-

    If I try-
    dim z as uinteger
    dim adr as any
    dim p as uinteger pointer
    adr=&H8000
     p = adr(0)
    
    I get-
    
    error: incompatible types in assignment
    

    I'm out of my depth here, but it seems this can only be done within a function

    I've tried all sorts of other permutations and get various errors (like 'not a function')

    can I use a pointer outside a function? if so can you please give me an example.

    Perhaps I'll stick to my way of doing it within pasm blocks.
    are there any other 'refinements' I need to be aware of-
    is it not possible to have good old uncomplicated peek and poke so dumbos like me can survive.

    Don't get me wrong- I think the work you are doing is incredible- but when we old timers see "basic", well old dogs new tricks etc....

    Dave

  • David BetzDavid Betz Posts: 14,511
    edited 2019-05-10 01:18
    Maybe you can try this:
    function peek(adr as any) as uinteger
      dim p as uinteger pointer
      p = adr
      return p(0)
    end function
    
    sub poke(adr as any, val as uinteger)
      dim p as uinteger pointer
      p = adr
      p(0) = val
    end sub
    

    Well, I don't really know BASIC all that well so this might not be quite right but something like this should get you back to the old way BASIC did this.
  • You can't use a variable of type "any" as an array, which is why the compiler is complaining about "adr(0)" ("adr" is of type "any" so you could be asking for an array reference or a function call, it doesn't know which). You'll have to assign the address to a pointer before trying to read from it:
       dim adr as any
       dim p as uinteger pointer
       adr = &H8000
       p = adr ' we have to index through p
       x = p(0) ' sets x to data from &H8000
       y = p(1) ' sets y to data from &H8004
    
    I don't know if there's a shorter way to do this in FreeBasic; some quick googling didn't turn up any equivalent to C casts, but I may have just missed it. I'd like to add something like that though so we could do something like C's:
       p = (uint *)0x8000
    
    Actually there is one way to avoid it, although it's a bit ugly. The literal "0" already has type "any" so it can be assigned to anything:
       dim memp as uinteger pointer
       memp = 0
       print memp(0x8000/4)
    
    The ugliness is that you have to remember to divide by 4 when doing the indexing. If you're using a byte pointer that won't be necessary though.
  • @"David Betz" 's "peek" and "poke" functions (or something like them) look fine too, you could include them in your code. The only change I would make is to make the "val" parameter to "poke" be a uinteger to match the uinteger pointer inside the function.
  • ersmith wrote: »
    @"David Betz" 's "peek" and "poke" functions (or something like them) look fine too, you could include them in your code. The only change I would make is to make the "val" parameter to "poke" be a uinteger to match the uinteger pointer inside the function.
    Thanks for the suggestion. I fixed it in my post.

  • There's a new release of fastspin with improved BASIC support. This round I've added much better support for objects, including inline class definitions (they no longer have to be in a separate file) and passing objects to functions. There's also a STR$() function for converting numbers to strings, and a new template syntax for generic functions. I've made an announcement in the fastspin thread, but also wanted to post here because (a) the BASIC language is considerably updated, and (b) it works on P1 as well as P2, and some people may not follow the P2 threads.

    I've added "basic.pdf", the current FlexBASIC manual, to the first post; links to fastspin and spin2gui releases are also in that post.
  • tritoniumtritonium Posts: 539
    edited 2019-09-02 12:54
    Hi
    Having problems with new release- I haven't tried this yet on previous version
    Using string to hold a list of values using chr$ and +
    (having trouble inserting a picture of the results....)
    dim as ubyte mx,tst
    dim as string hi,ho,hum
    tst=1
    hi="helloooooooooooooo"	'this works
    showit
    tst=2
    hi=(chr$(100)+chr$(103)+chr$(106)+chr$(0x2C)+chr$(0x2C)+chr$(0x2E)+chr$(0x2E)+chr$(0x21))'this doesnt
    showit
    tst=3
    hi=chr$(49)+chr$(50)+chr$(51)+chr$(52)+chr$(53)+chr$(54)+chr$(55)+chr$(56)'this doesnt 8 char 1 too many
    showit
    tst=4
    hi=chr$(49)+chr$(50)+chr$(51)+chr$(52)+chr$(53)+chr$(54)+chr$(55)'this does up to 7 chars
    showit
    tst=5
    hi=chr$(49)+chr$(50)+chr$(51)+chr$(52)+chr$(53)+chr$(54)+chr$(55)
    ho=chr$(56)+chr$(57)+chr$(58)+chr$(59)
    showit
    
    print "done"
    
    do
    loop
    
    sub showit
    print "========= testoutput ";tst;"==========="
    hum=hi+ho
    print len(hi),len(ho),len(hum)
    print hum
    for mx=1 to len(hum)
    	print asc(mid$(hum,mx,1)),
    next
    print
    end sub
    
    end
    

    The above fails in various ways
    strings longer than 7 digits fail

    dim as ubyte mx,tst
    dim as string hi,ho,hum
    
    hi=chr$(49)+chr$(50)+chr$(51)+chr$(52)+chr$(53)+chr$(54)+chr$(55)
    ho=chr$(56)+chr$(57)+chr$(58)+chr$(59)
    hum=hi+ho
    print len(hi),len(ho),len(hum)
    print hum
    for mx=1 to len(hum)
    	print asc(mid$(hum,mx,1)),
    next
    
    print "done"
    
    do
    loop
    

    this code works on its own but failed in previous code
    notice the length is printed in hex!!
    dim as ubyte mx,tst
    dim as string hi,ho,hum
    
    hi=chr$(49)+chr$(50)+chr$(51)+chr$(52)+chr$(53)+chr$(54)+chr$(55)
    ho=chr$(56)+chr$(57)+chr$(58)+chr$(59)+chr$(60)+chr$(61)+chr$(62)
    hum=hi+ho
    
    
    print len(hi),len(ho),len(hum)
    print hum
    for mx=1 to len(hum)
    	print asc(mid$(hum,mx,1)),
    next
    
    print "done"
    
    do
    loop
    

    the above fails when 14 chr() or more added


    also does not like chr$(0)


    Dave
  • Hi again
    sorry about this but still more-
    dim as ubyte x,d,z
    dim as string sdat,str
    pausems 100
    sdat="$00,03,06,0C,0C,0E,1E,11"
    
    print sdat,
    print left$(sdat,1)
    
    if left$(sdat,1)= "$" then
    
    	for x= 2 to 23 step 3
    		str="0x"+mid$(sdat,x,2)
    		d=val(str)		
    		print x,str,d
    	next
    print
    	for x= 2 to 23 step 3
    		str="&H"+mid$(sdat,x,2)
    		d=val(str)		
    		print x,str,d
    	next
    
    end if
    
    do
    loop
    end
    
    commenting out the "if-end if" statements and it works

    As you can see I am trying to find a way to encode binary numbers into a string (so that I can send binary numbers to an spi port and aschii text with the same subroutine. Using chr$ doesn't work as shown, so a string with the leftmost digit a dollar sign will indicate to the subroutine- this is hex data not aschii .

    Also val does not work on "&H" notated hex data string but ok with "0x"

    Dave
  • High again-again

    HAHA well if I remove the blank line between the if test and the for x loop it works for "0x" prefix!!
    if left$(sdat,1)= "$" then
    
    	for x= 2 to 23 step 3
    

    Dave
  • I haven't had a chance to really look at this yet (I'll try to soon) but in the meantime have you tried increasing the size of the heap? The garbage collector isn't perfect, especially if there are a lot of allocations in the same function (in this case the main program). So you could try defining
    const HEAPSIZE=8192
    
    in your program and see if that helps. Alternatively, you could check all the return values from string functions and the string + operator for nil to see if they're running out of memory.
  • Wow @tritonium , you've certainly found some interesting bugs. Thanks for the test programs!

    Some of the things you've found:

    (1) The problem with concatenating strings in-line was indeed a heap size problem. If you have an expression like "a+b+c+d"..., the compiler generates various temporaries that are still "live" in the course of the expression (until the statement ends). So they cannot be garbage collected, and with the tiny default memory heap space on Propeller1 you'll run out of memory. If you build up the string piece by piece this is less likely to happen, but it's still pretty easy to run out of memory with the default heap (which is made worse by another bug, see below).

    (1b) The heap space issue is further compounded by a library bug. The compiler creates a symbol __real_heapsize__ which contains the size of the heap in longs. Unfortunately the library declares this in bytes, so the actual space available is only 1/4 what the user requested. This is easily fixed though: in the file include/libsys/gcptrs.spin, change the declaration:
        byte 0[__real_heapsize__]
    
    to
        long 0[__real_heapsize__]
    

    (2) That CHR$(0) does not work is a feature rather than a bug, but it should be documented. Strings in FlexBASIC are all of the zero terminated variety, so CHR$(0) in the middle of a string will terminate the string.

    (3) There's a nasty parser bug which causes it to lose track of all statements after an empty line that appears in some contexts (e.g. right after THEN). It's a typo, so it's easy to fix (and is fixed in github now) but for now I'd suggest avoiding blank lines as the first lines of any set of compound statements (e.g. right after IF..THEN, or FOR, or DO, or WHILE).

    (4) Some of the built in functions (like LEN) are written in Spin and did not have types associated with them, so they were interpreted by BASIC as returning type "generic". That's why LEN(x) was printed in hex.

    (5) As you've noticed VAL doesn't recognize "&" prefixes. It'd be nice if it did, and I'll look into that.

    (6) If you can send out the characters as decimal, you could use STR$(x) to convert them. Alternatively, I'd suggest writing some kind of a hex conversion function like:
    function hex$(x as uinteger) as string
      dim p as ubyte pointer
      dim i, digit as uinteger
      p = new ubyte(9) ' include space for trailing 0
      p(8) = 0
      for i = 0 to 7
        digit = x >> (i*4)
        digit = digit and 0xf
        if digit > 9 then
          p(7-i) = (digit - 10) + asc("a")
        else
          p(7-i) = digit + asc("0")
        end if
      next i
      return p
    end function
    
  • Ah, I see the problem with VAL: it was accepting "&h20" as being 32, but not "&H20" (it only recognized lower case letters).That's fixed now in github. I'll be creating a new release soon I hope.
  • Hi

    Gosh that was quick!
    I must admit I was beginning to think I was losing the plot...
    I suspected the chr$(0) had something to do with 0 terminated strings-Propbasic uses those- but I've often used then in qbasic and I think in Freebasic for sending serial binary data.

    Thanks- will update and move on- much appreciated
    now to test some more...

    Dave
  • @tritonium, why not write your stings as initialised arrays and convert them from there to whatever you need? The data would be converted to binary at compile time and zeroes don't hurt in arrays.
    '' dim as string sdat
    '' sdat="$00,03,06,0C,0C,0E,1E,11"
    ''
    '' vs:
    
    option base 1 ' is default but I need this as reminder :-)
    dim shared as ubyte adat(8) = { &h00,&h03,&h06,&h0C,&h0C,&h0E,&h1E,&h11 }
    
    print "adat =";
    for i=1 to 8
      print " ";adat(i);
    next i
    print
    

    —▷ just for fun: extreme example
  • Hi @yeti

    Thanks for the example and heigh- that's a great link https://forums.parallax.com/discussion/comment/1453189/#Comment_1453189
    don't ever remember seeing it and with that title I would have been there like a shot! Got some interesting reading ahead :lol:

    Yes I realise there are work rounds- in fact I found some- however when the language doesn't behave as expected its worth flagging up to the author. It can lead you down blind alleys and waste time, and in my case- make me doubt my sanity!!!

    I wanted a subroutine that would accept both strings and binary data, and to make chr$ of it was the simplest route.

    Dave
  • tritonium wrote: »
    Thanks for the example and heigh- that's a great link https://forums.parallax.com/discussion/comment/1453189/#Comment_1453189
    don't ever remember seeing it and with that title I would have been there like a shot! Got some interesting reading ahead :lol:
    I don't think it makes sense to only focus on BASIC there. Let's widen the focus and put examples in every language FastSpin supports in there.

    One of FastSpin's major strengths is that all supported languages easily can be mixed and this already happens under the hood even if one thinks to be only using BASIC.

    Can please some forum demigod modify the title to reflect this? Maybe simply by changing "Testing the new Fastspin basic compiler for P1" to "Testing the new Fastspin basic compiler for P1"?
  • PublisonPublison Posts: 12,366
    edited 2019-09-03 17:21
    Can please some forum demigod modify the title to reflect this? Maybe simply by changing "Testing the new Fastspin basic compiler for P1" to "Testing the new Fastspin basic compiler for P1"?

    I would have to get permission from the OP to do that.

  • Hi

    Changing the title of a thread 20 pages long could lead to confusion.
    Why not start another.
    I can understand your motivation, but dropping 'basic' from the title would stop me from looking at it. We all have different interests; some will be 'C', others assembler, basic etc etc.
    A thread for each would be good so when a new posting comes up you know it will be something you personally would be interested in.

    my thoughts

    Dave
Sign In or Register to comment.