New BASIC compiler for Prop1 and Prop2

1111214161719

Comments

  • yetiyeti Posts: 532
    edited 2018-12-15 - 10:05:46
    jmg wrote: »
    yeti wrote: »
    That's why having no default may be the best solution.

    Not quite, as then you have a lottery, smarter to follow the existing standard of freebasic’s default.
    Then, pasted code gives no surprises.
    Lottery?
    What???

    Needing an "option base" before the 1st "dim array(..)" is the exact opposite of lottery.
    You have to think about what you need instead of starting to code, forgetting "option base" and maybe getting something that does not match the default.

    And executing pasted code without thinking is what made "christma.exec" possible.

    I don't want sloppy or forgiving defaults. I want correct programs.
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
  • Beware of Foo(0) eh eh!

    For what it's worth tracking Freebasic too closely makes no sense at all.
    Freebasic is a monster.

    P1 is a micro controller, Flexibasic works because it takes advantage of the unique architecture of the Propeller and the embedded spin language.

    Ron
  • I disagree, the idea to be able to copy from Freebasic and get the same results is a great idea.

    QuickBasic and VB also start at zero by default.
    I really don't see it as any kind of deviation from the norm when defaulting for Option Base 0, but being able to set to 1.
  • yetiyeti Posts: 532
    edited 2018-12-15 - 12:08:49
    "option base 0" is the 2nd best default.

    Not being able to dimension arrays without prior explicitely setting "option base something" still looks better to me:
    $ cat option-base.bas
    option base 1
    
    dim a(2)
    dim b(3)
    
    ''
    '' set
    ''
    for i=1 to 2
      a(i) = 1000+i
    next i
    
    for i=0 to 2
      b(i) = 2000+i
    next i
    
    ''
    '' get
    ''
    for i=1 to 2
      print "a(";i;") = ";a(i)
    next i
    
    for i=0 to 2
      print "b(";i;") = ";b(i)
    next i
    $ fastspin option-base.bas 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
    Version 3.9.13-beta-96efba6 Compiled on: Dec 15 2018
    option-base.bas
    option-base.pasm
    Done.
    Program size is 4932 bytes
    $ spinsim -b option-base.binary 
    a(1) = 1001
    a(2) = 2000
    b(0) = 2000
    b(1) = 2001
    b(2) = 2002
    
    It will not prevent such errors but when looking for the reason you do not need to know the default then and every reader of that code will see what the coder wanted to be correct.

    A bit of self documentation in the code.

    Does that one line more really hurt sooooo much?

    Defaults are faults!
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
  • yeti wrote: »
    "option base 0" is the 2nd best default.

    Not being able to dimension arrays without prior explicitely setting "option base something" still looks better to me:
    ...

    It's called "option base" and not "required base" :innocent:
  • yetiyeti Posts: 532
    edited 2018-12-15 - 16:56:09
    Ariba wrote: »
    It's called "option base" and not "required base" :innocent:
    Make it "default base 0" then? smilie_girl_101.gif
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
  • @yeti: you're correct that making it a "required base" instead of "option base" would be safer. But honestly I don't think people choose BASIC for safety, but rather for convenience. So I think there should be a default, and it seems the consensus here is for a base of 0.
  • David BetzDavid Betz Posts: 13,417
    edited 2018-12-15 - 17:47:53
    ersmith wrote: »
    @yeti: you're correct that making it a "required base" instead of "option base" would be safer. But honestly I don't think people choose BASIC for safety, but rather for convenience. So I think there should be a default, and it seems the consensus here is for a base of 0.
    So the default will allocate 11 elements for an array that is declared with "DIM foo(10)" with indices of 0-10? I guess that's the safest approach.
  • Some useful BASIC commands that are not yet implemented in FlexBasic:

    ON x GOTO/GOSUB label1, label2, ...

    I think this can be replaced by a function table, and a call per function pointer.
    But speaking of tables, I miss data handling in FlexBasic.

    DATA 1,2,3.14,"string",0
    x = READ
    RESTORE label

    You can already have initialized global arrays for tables, but DATA is more flexible in that you can mix numbers, labels and strings.
    It's a bit like the DAT section in Spin.

    Andy
  • David Betz wrote: »
    ersmith wrote: »
    @yeti: you're correct that making it a "required base" instead of "option base" would be safer. But honestly I don't think people choose BASIC for safety, but rather for convenience. So I think there should be a default, and it seems the consensus here is for a base of 0.
    So the default will allocate 11 elements for an array that is declared with "DIM foo(10)" with indices of 0-10? I guess that's the safest approach.

    Yes, in the default case "DIM foo(10)" becomes "DIM foo(0 TO 10)" which will allocate 11 elements. And if you set "option base 9" then "DIM foo(10)" becomes "DIM foo(9 TO 10)" and allocates 2 elements. In all cases DIM is given an upper bound rather than a size. I think this is the way most BASICs work.
  • Andy:

    DATA is a really tricky case. You're right that it's like the DAT section, but it has to store a mixture of data types (floats, integers, strings) and I'm not sure how we can check that the values being read have the right types.

    One way to implement it is to store the contents verbatim (as a string) in memory and then parse that string at runtime. Or, I guess we could store a long for each item (assuming everything fits in a long), with strings converted to pointers to their contents, but then there's no type checking on the READ. Maybe a long + a type flag?
  • yetiyeti Posts: 532
    edited 2018-12-15 - 18:33:06
    MBASIC treats reading data into the wrong type of variable as syntax error:
    list
    10 DATA 1,2,"moo!"
    20 READ A : PRINT A
    30 READ A : PRINT A
    40 READ A : PRINT A
    Ok
    run
     1 
     2 
    Syntax error in 10
    Ok
    
    Reading the same items as strings succeeds:
    10 DATA 1,2,"moo!"
    20 READ A$ : PRINT A$
    30 READ A$ : PRINT A$
    40 READ A$ : PRINT A$
    Ok
    run
    1
    2
    moo!
    Ok
    
    Classic "DATA" just is a partially indexed list of strings.
    This can be emulated by an array of strings.
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
  • ersmith wrote: »
    Andy:

    DATA is a really tricky case. You're right that it's like the DAT section, but it has to store a mixture of data types (floats, integers, strings) and I'm not sure how we can check that the values being read have the right types.

    One way to implement it is to store the contents verbatim (as a string) in memory and then parse that string at runtime. Or, I guess we could store a long for each item (assuming everything fits in a long), with strings converted to pointers to their contents, but then there's no type checking on the READ. Maybe a long + a type flag?

    Maybe it should be done compatible to Spin.
    DATAB for bytes, DATAW for words and DATAL or just DATA for longs and floats. With the same rules as in Spin ("..." for appended ASCII).
    They generate initialzed arrays, but you can set labels in between for partial array access.

    Not sure if READ and RESTORE makes then much sense. READ would need to know the size, or you need READB, READW.

    Andy
  • whickerwhicker Posts: 460
    edited 2018-12-15 - 20:02:41
    I'm just thinking out loud here.

    Let's look at the typical INPUT command in the 8-bit home computers.

    If you'd implement the INPUT {"prompt"} {,or;} {var} statement, then it flows naturally from there.
    INPUT knows the type of the {var} it is seeking, or in this case read from SERIAL.
    INPUT also has no qualms about refusing entry and starting over, saying something like *BAD VALUE, REDO FROM START*.

    The inputted byte string usually goes into the "crunch buffer" that a BASIC interpreter typically has, if it is running in immediate mode.
    So it gets a series of characters, and usually ENTER is pressed... some kind of EOL marker anyways. Let's be forgiving of (CR, CR+LF, or LF)!

    Processing begins:
    Ignore any leading spaces then I think it goes through and sees if it has a number (+ - . 0~9), or if it encounters an alpha character then it knows it's a string.
    Paths diverge then, ultimately copying to {var}, which it knows the type and min/max range constraints of.

    READ would be the same as an INPUT {var}, but redirected to a byte pointer.
    At program start, the byte pointer is initialized to the very first DATA statement (an implicit RESTORE command).
    The byte pointer has to know some things like what range it's allowed to work within, and awareness of the RESTORE command if used with a line number or label.

    I think DATA statements would end up compiling to one or more constant strings (whose length can be very long).
    So the byte pointer is read and incremented until it encounters the end of the string, or a comma. The data being fed into the crunch buffer. The crunch buffer then is interpreted to be either a number or string and put into the READ variable.

    To make it easier, maybe require only one variable per READ?
  • ersmith wrote: »
    David Betz wrote: »
    ersmith wrote: »
    @yeti: you're correct that making it a "required base" instead of "option base" would be safer. But honestly I don't think people choose BASIC for safety, but rather for convenience. So I think there should be a default, and it seems the consensus here is for a base of 0.
    So the default will allocate 11 elements for an array that is declared with "DIM foo(10)" with indices of 0-10? I guess that's the safest approach.

    Yes, in the default case "DIM foo(10)" becomes "DIM foo(0 TO 10)" which will allocate 11 elements. And if you set "option base 9" then "DIM foo(10)" becomes "DIM foo(9 TO 10)" and allocates 2 elements. In all cases DIM is given an upper bound rather than a size. I think this is the way most BASICs work.
    Hmmm... Now I'm remembering why I'm not a BASIC programmer anymore.

  • potatoheadpotatohead Posts: 9,765
    edited 2018-12-15 - 21:21:22
    You're too advanced. Basic programmers don't worry about such things.

    :D
    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: https://forums.parallax.com/discussion/123709/commented-graphics-demo-spin<br>
  • potatohead wrote: »
    You're too advanced. Basic programmers don't worry about such things.

    :D
    I have had fun implementing BASIC interpreters though. I wrote a couple for the P1. Seems Eric has BASIC under control for the P2 though.

  • I think he has done a great job. I can't wait for my eval board. I want to play. My fpga boards got water damage. It's been a long wait.
    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: https://forums.parallax.com/discussion/123709/commented-graphics-demo-spin<br>
  • David Betz wrote: »
    ersmith wrote: »
    David Betz wrote: »
    ersmith wrote: »
    @yeti: you're correct that making it a "required base" instead of "option base" would be safer. But honestly I don't think people choose BASIC for safety, but rather for convenience. So I think there should be a default, and it seems the consensus here is for a base of 0.
    So the default will allocate 11 elements for an array that is declared with "DIM foo(10)" with indices of 0-10? I guess that's the safest approach.

    Yes, in the default case "DIM foo(10)" becomes "DIM foo(0 TO 10)" which will allocate 11 elements. And if you set "option base 9" then "DIM foo(10)" becomes "DIM foo(9 TO 10)" and allocates 2 elements. In all cases DIM is given an upper bound rather than a size. I think this is the way most BASICs work.
    Hmmm... Now I'm remembering why I'm not a BASIC programmer anymore.

    Teacher:
    Let's count to 5.

    Student:
    0, 1, 2, 3, 4

    Teacher:
    You're far too advanced for my class.
  • koehlerkoehler Posts: 576
    edited 2018-12-15 - 22:41:28
    The option base is an option, however why not cut to the quick and eliminate the problem at the source?

    Dim a(0,10)
    Dim b(1,10)
    Dim c(2,10)

    I'm sure someone won't like it, however there are so many known semantic issues with programming, it seems like we are decades past when simple solutions should have been applied.
    I always love the complaining about how this or that will cause extra typing. Lets have more rules and regulations requiring memorization vs something that is actually more Human readable.

    For my next trick, I'll show you one easy trick the experts don't want you to know which solves the white space tab vs spaces issue.
    ---- This space available for rent ----<br>
  • koehler wrote: »
    The option base is an option, however why not cut to the quick and eliminate the problem at the source?

    Dim a(0,10)
    Dim b(1,10)
    Dim c(2,10)
    I'm going to support that, but with FreeBasic syntax:
    Dim a(0 to 10)
    Dim b(1 to 10)
    Dim c(2 to 10)
    
    Careful programmers can use this version so there is no confusion about the base. But for compatibility with other BASICs I think we still need "option base".


  • David Betz wrote: »
    potatohead wrote: »
    You're too advanced. Basic programmers don't worry about such things.

    :D
    I have had fun implementing BASIC interpreters though. I wrote a couple for the P1. Seems Eric has BASIC under control for the P2 though.

    Well, a BASIC interpreter for P2 would still be nice to have, since it could run on the machine. Being able to type commands interactively would be great. We do have Tachyon for P2, but not everyone will be comfortable with FORTH syntax.

  • Yes. The FORTH is difficult. I must say Peter has done very well with Tachyon though. I used it a time or two on the P1, and it was the first FORTH I was able to find useful. Having it as the resident system tool in the P2 is going to be spiffy. With a well chosen dictionary, lots of one liner useful things will end up being passed around. All good, IMHO.

    Thanks for this work ersmith. It's great, and I am super eager to make use of it.

    There are BASICS we can compile. Eventually, the best BASIC will probably be a mostly PASM thing, using skip and friends for some real speed.
    Do not taunt Happy Fun Ball! @opengeekorg ---> Be Excellent To One Another SKYPE = acuity_doug
    Parallax colors simplified: https://forums.parallax.com/discussion/123709/commented-graphics-demo-spin<br>
  • ersmith wrote: »
    David Betz wrote: »
    potatohead wrote: »
    You're too advanced. Basic programmers don't worry about such things.

    :D
    I have had fun implementing BASIC interpreters though. I wrote a couple for the P1. Seems Eric has BASIC under control for the P2 though.

    Well, a BASIC interpreter for P2 would still be nice to have, since it could run on the machine. Being able to type commands interactively would be great. We do have Tachyon for P2, but not everyone will be comfortable with FORTH syntax.
    Actually, I was thinking about that after I posted my previous message. However, I think with the relatively large amount of memory on the P2 that Eric might be able to get his BASIC compiler working on the P2 itself. In any case, I fully intend to play with the XBYTE feature to create fast byte code interpreters for some of the languages I wrote for the P1 even if they never really get used by anyone.
  • David Betz wrote: »
    ersmith wrote: »
    Well, a BASIC interpreter for P2 would still be nice to have, since it could run on the machine. Being able to type commands interactively would be great. We do have Tachyon for P2, but not everyone will be comfortable with FORTH syntax.
    Actually, I was thinking about that after I posted my previous message. However, I think with the relatively large amount of memory on the P2 that Eric might be able to get his BASIC compiler working on the P2 itself. In any case, I fully intend to play with the XBYTE feature to create fast byte code interpreters for some of the languages I wrote for the P1 even if they never really get used by anyone.

    I'm looking forward to seeing what you come up with. XBYTE certainly seems like a good way to implement interpreters.

    I don't think fastspin will ever fit on the P2, it's got more than 512K bytes of code alone, and it does a lot of dynamic memory allocation.

    Eric
  • Ariba wrote: »
    Some useful BASIC commands that are not yet implemented in FlexBasic:

    ON x GOTO/GOSUB label1, label2, ...

    I think this can be replaced by a function table, and a call per function pointer.


    Andy

    +1000

    This is great for state-machine sequencing....to switch a sequence off, make x=0. Just been playing with this in Android BASIC! and no matter the value of x, the execution time doesn't change so it feels like there is some pointer/jump-table thing happening.

    Failure is not an option...it's bundled with the software.
  • It would be useful to do this in an if statement.
    dim list(127) as ubyte 
    dim lptr as ubyte
    let mes1$ = "Error-list"
    
    
    if list(lptr) = &h20              'This does not compile
        ser.str(mes1$) 
    end if
    


    Ron
  • yetiyeti Posts: 532
    edited 2018-12-18 - 12:30:55
    I tried it with "print" instead of using "ser.*" and added a "then" to the "if" line:
    $ cat rsut20181218-1221.bas
    dim list(127) as ubyte
    dim lptr as ubyte
    let mes1$ = "Error-list"
    
    if list(lptr) = &h20 then
        print mes1$
    end if
    $ fastspin-3.9.12 rsut20181218-1221.bas 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
    Version 3.9.12 Compiled on: Dec 10 2018
    rsut20181218-1221.bas
    rsut20181218-1221.pasm
    Done.
    Program size is 1620 bytes
    $ █
    

    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
  • Duh!

    My bad, IF needs a Then.


    Ron


  • yetiyeti Posts: 532
    edited 2018-12-18 - 13:46:42
    rsut wrote: »
    My bad, IF needs a Then.
    You're not alone!
    My 1st try on multi line "if"s was without "then" too.

    Maybe the grammar can be tuned to make that "then" optional?

    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ No Source – No Go! ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷
Sign In or Register to comment.