NotSoBASIC

As discussed in a previous posting, I’ve been musing over the development of a modernised version of the classic procedural BASIC language, especially with the Raspberry Pi in mind.

With this in mind I’ve been setting out some goals for a project and working a little on some of the syntactical details to bring structures, advanced for-loop constructs and other modern features to a BASIC language as backwardly compatible with the old Sinclair QL SuperBASIC as possible.

So, here are the goals:

  1. The language is aimed at both the 13 year old bedroom coder, getting him/her enthused about programming, and the basic needs of general scientist. (Surprisingly, the needs of these two disparate groups are very similar.)
  2. It must be platform agnostic and portable. It must also have a non-restrictive, encumbered license, such as the GPL, so probably Apache, so as to allow it to be implemented on all platforms, including Apple’s iOS.
  3. It must have at least two, probably three, levels of language, beginner, standard and advanced. The beginner would, like its predecessors in the 8bit era, be forced to use line numbers, for example.
  4. It must have fully integrated sound and screen control available simply, just as in the old 8bit micro days. This, with the proper manual, allow a 13 year old to annoy the family within 15 minutes of the person starting to play.
  5. The graphical capability must include simple ways to generate publishable scientific graphical output both to the screen and as encapsulated Postscript, PDF and JPEG.
  6. The language must have modern compound variables, such as structures, possibly even pseudo-pointers so as to be able to store references to data or procedures and pass them around.
  7. The language should be as backwardly compatible with Sinclair QL SuperBASIC as possible. It’s a well tested language and it works.
  8. The language should be designed to be extendable but it is not envisaged that this would be in the first version.
  9. The language IS NOT designed to be a general purpose application development language, though later extensions may give this ability.
  10. The language will have proper scoping of variables with variables within procedures being local to the current call, unless otherwise specified. This allows for recursion.
  11. All devices and files are accessed via a URI in an open statement.
  12. Channels (file descriptors) must be a special variable type which can be stored in arrays and passed around.

As I said earlier, I’ve been thinking about how to do a great deal of this syntactically as well. This is where I’ve got so far:

[Edit: The latest version of the following information can be found on my website. The  information below was correct at 10am 23rd February 2012.]

Variables.

Variable names MUST start with a alphabetic character and can only contain alphabetic, numeric and underscore characters. A suffix can be appended so as to give the variable a specific type, e.g. string. Without a suffix character the variable defaults to a floating point value.

Suffixes are:

$ string
@ pointer

Compound variables.

Compound variables (structures) can be created using the “DEFine STRUCTure” command to create a template and then creating special variables with the “STRUCTure” command:

DEFine STRUCTure name
varnam
[…]
END STRUCTure

STRUCTure name varnam[,varnam]

An array of structures can also be created using the STRUCTure command, e.g.

STRUCTure name varnam(3)

The values can be accessed using a “dot” notation, e.g.

DEFine STRUCTure person
name$
age
DIMention vitals(3)
END STRUCTure

STRUCTure person myself, friends(3)

myself.name$ = “Stephen”
myself.age = 30
myself.vitals(1) = 36
myself.vitals(2) = 26
myself.vitals(3) = 36

friends(1).name$ = “Julie”
friends(1).age = 21
friends(1).vitals(1) = 36
friends(1).vitals(2) = 26
friends(1).vitals(3) = 36

As with standard arrays, arrays of structures can be multi-dimentional.

Structures can contain any number of standard variables, static arrays types and other structures. However, only structures defined BEFORE the one being defined can be used. Structure definitions are parsed before execution of the program begins. Structure variable creation takes place during execution.

Loops.

FOR/NEXT:

FOR assignment (TO expression [STEP expression] | UNTIL expression | WHILE
expression) [NEXT assignment]
..
[CONTINUE]
..
NEXT [var]

The assignment flags the variable as the loop index variable. Loop index variables are normal variables.

The assignment and the evaluation of the assignment expression happen only once, when entering the loop. The test expressions get evaluated once every trip through the loop at the beginning. If the TO or UNTIL expressions evaluate to zero at the time of loop entry the commands within the loop do not get run.

The STEP operator can only be used if the loop index variable is either a floating point variable or an integer. The expression is evaluated to a floating point value and then added to the loop index variable. If the loop index variable is an integer then the value returned by the expression stripped of its factional part (as with ABS()) before being added to the variable.

WHILE/END WHILE:

WHILE expression [NEXT assignment]

[CONTINUE]

END WHILE

Equivalent to a FOR loop without an assignment using the WHILE variant e.g.

x = 10
WHILE x > 3 NEXT x += y / 3

END WHILE

is equivalent to

FOR x = 10 WHILE x > 3 NEXT x += y / 3

NEXT

DO/UNTIL:

DO

[CONTINUE]

UNTIL expression

The commands within the loop are run until the expression evaluates to a non-zero value.

Functions and procedures.

A function is merely a special form of a procedure which MUST return a numeric value. The suffix of a procedure determines its type, in the same way as variable names.

DEFine PROCedure name[(parameter[,parameter[…]])]

[RETURN expression]
END PROCedure

DEFine FUNction name[(parameter[,parameter[…]])]

RETURN expression
END FUNction

Parameters are local names with reference the passed values by reference. This means that any modification of the parameters within the procedure will change the value of any variables passed to it.

Variables created within the procedure will be local to the current incarnation, allowing recursion. Variables with global scope are available within procedures but will be superseded by any local variables with the same name.

20 thoughts on “NotSoBASIC

  1. I think that a project of this ilk is more than commendable – it was only recently I was talking with an electronics engineer, who wanted a simple means of programming a quick graphical display application for his mobile (taking data from a USB port). The existing tools would have been a huge learning process for what could be covered in a short 50-100 line BASIC program.

    I would like to see some more of the SuperBASIC approach to loops in any implementation – being able to easily create a single line FOR loop (or multiples) without needing the NEXT command is a great help, for example:

    FOR x=1 TO 255: FOR y=1 TO 200: AT x,y: PRINT ‘X’

    Also I do like the ability to not only use NEXT, but END FOR, as this allows you to have commands which are exercised at the very end of the loop, only once the end value is reached, whilst EXIT jumps past the END FOR statement, for example:

    FOR x=1 to 100
    IF 1/x<RND(0 to 1): EXIT x
    PRINT x
    NEXT x
    PRINT 'No random number was found less than 1/x'
    END FOR x

    • I plan to base the syntax fully on SuperBASIC and then extend it.

      There are a few exceptions, such as file and device access where the QL device nomenclature doesn’t fit the modern world. In this case I plan to use URI definitions instead.

      I realise that the definitions I gave above were not quite SuperBASIC as I’m currently going on memory rather than reading directly from the manual. Once the design process gets further down the road I can tidy things up.

  2. Similar to something I was intending to try to create myself. A sort of Super-SuperBasic, complete with structures etc.

    I was intending to do away with the $ and % suffixes though, I hate them. They are not needed as long as people use meaningful variable names. (CustomerName, InvoiceNumber etc).

    If you decide to go down this route, try ANTLR (www.antlr.org) as the interpreter generator. My own plans were to use ANTLR to define the grammar, built a C or C++ interpreter from ANTLR and incorporate it into an application written in C++ with either Qt or wxWidgets.

    After all, as they say on Top Gear, how hard can it be? ๐Ÿ˜‰

    Unfortunately, like many of my projects, they start off well, and die pretty quickly as time constraints and “life” get in the way. It doesn’t help that I have tendonitus in my thumb at the moment either – one handed typing is no fun.

    Cheers,
    Norm.

  3. Actually, a lot of beginners find the suffixes very useful as they remind them of the type of the variable. It’s good training to introduce the ideas of specific types early on.

    Also, remember that beginners never use meaningful names! They learn the usefulness of them later, the hard way, generally.

    As for the language and the toolkit. It may be best to target the use of Ojbective C and OpenStep as these are available on all platforms and give a head start with any native ports to the Mac and iOS devices.

    • That’s fine by me, however, the suffixes shouldn’t be mandatory. If I want to define a string variable as “MyName” and you want to call it “NormsName$” both should be valid.

      This means that the definition of a variable name should be:

      * Starts with an alpha or underscore;
      * Contains 0 or more alphas, numerics, underscores or $%- characters;

      And if people are still being taught to use variables such as x, y, z etc, then the teachers need teaching!

      Cheers,]
      Norm.

      • How would you tell the interpreter what type the variable is?

        Would you have to define all your variables using something such as:

        TYPE INTeger myint, myarray(15)
        TYPE REAL myreal
        TYPE STRING mystring

        etc.?

        Not very backwardly compatible.

        • Why not? In the list of “desirements” for this new language, option 11 invalidates QL Compatibility – all devices and files are specified by a URI – where the QL uses FLPn_ or MDVn_ etc.

          We already have to define an array as having dimensions and/or lengths.

          We would be starting from scratch and incorporating various good bits from the QL and losing the bad bits – like line numbers, type suffixes etc.

          But nothing is set in stone.

          Cheers,
          Norm.

          • Actually, for absolute beginners line numbers are very useful as it focuses their attention on the logical, sequential processing of the statements. This is why I suggested language levels. Only the beginner mode would enforce line numbers, which are merely special form of label which happens to be numeric and ascending downwards.

            Remember, that this is a basic training language primarily, with the ability to grow with the user and perform some useful scientific calculations and graph plotting etc. It’s called BASIC for a reason. (Beginner’s All-purpose Symbolic Instruction Code)

          • Oh, as for using URIs instead of the QDOS way, the reason is that the URI is far more flexible and the standard is defined. It also means that you can transparently access networked resources easily and transparently.

            Want to save your work to a remote server?

            SAVE “ftp://myusername:password@ftp.somewhere.else/myfile.bas”

            Job done!

            Want to open a remote file for reading?

            OPEN #myfile “http://www.somethere.net/~wibble/myfile.dat”

    • Objective-C is, quote, “used primarily on Apple’s Mac OS X and iOS” – which is hardly cross platform. No good on a Raspberry Pi for example.

      Another quote “OPENSTEP and OSE were purchased by Apple, who effectively ended the commercial development of implementing OpenStep for other platforms,” so the remaining OpenStep is GNUStep it seems.

      However, it would be great if whatever was developed was able to run on Windows, Linux, BSD, Various Unixes, Whatever Apple has out this week and Android.

      Cheers,
      Norm.

      • Yes, it’d have to be GNUStep on non-Apple platforms. But at least it *IS* cross platform.

        GNUStep should be compatible with Raspberry Pi and Objective C is a fully supported language within the GCC compiler suite. i.e. fully Raspberry Pi complient.

  4. I miss such a tool too. I agree it would be very helpful on home computing,
    computing learning and professional fronts. QL’s SuperBASIC and SBASIC are very close to it, but as said they would need an update in several fields.

    This makes me remember an article on the same subject I found me some time ago:

    http://www.osnews.com/story/23464/Why_Johnny_Can_t_Code
    http://www.salon.com/technology/feature/2006/09/14/basic/

    Anyway, writing a new language is a huge task. Another approach could be to
    adapt an existant multiplatform BASIC such as FreeBASIC
    (htt://www.freebasic.net). It’s a compiler, so a layer of macros and
    preprocessor commands could do the task to some extent. But of course a
    compiler would make things more complicated for the final user.

  5. Hi Steve,

    Line numbers – hmmm. I’m not completely convinced. I never found them useful when I was a beginner other than knowing that the program starts at the lowest number (unless otherwise informed) and proceeds to the highest (unless otherwise informed), however, that too could be explained by stating that “execution starts at the top and works down” or “execution always starts at a function called main and proceeds, as instructed, from there”.

    I do find line numbers useful when I print out some code and I need to keep the pages in order though! ๐Ÿ˜‰

    Pascal was a teaching language originally purely to get around the so called horrors of Basic. Pascal has no line numbers and variables have to be defined before use and in a specific part of the program. (Well, officially anyway, I haven’t used pure Pascal for many years – things have most likely changed.)

    Nowadays a lot of people thing that Basic should be condemned (I’m not one of them) as a teaching language and Python used instead. From what I’ve seen of Python, I disagree!

    Cheers,
    Norm.

    PS. Sorry for the discontinuation here, there was no “reply” button below your post. Too many levels of reply perhaps?

    • Yes, Python’s a bit of a horror story really, especially the structural whitespace.

      As for line numbers, it’s surprising how important they can be for some people. I was talking to a friend who’s a science teacher and he recounted how many pupils couldn’t handle the concept of a logical progression.

  6. I suggest taking a look to the SpecBAS project by Paul Dunn (http://specbas.co.uk). It’s a BASIC interpreter based on the old ZX Spectrum’s BASIC, but much improved, more powerful and multiplatform. It is still alpha but looks quite promising. I think it soon will suit the needs you mention.

    There are binary packages for Windows, Linux (Intel) and the Pandora’s ร…ngstrรถm (http://openpandora.org). It’s written in Free Pascal and it’s open source, so it can be compiled for other platforms as well.

    In fact I’m considering SpecBAS as an alternative to SBASIC for a couple of game projects under development. The source code conversion would not be
    difficult, and the benefits would be remarkable: wider audience; easier programming of sounds and graphics; and the chance to be able to contribute to an open and evolving project.

    • Thanks for mentioning SpecBAS ๐Ÿ™‚

      It has been ported to the Raspberry PI, but performance is quite a lot slower than on other platforms due to the ARM cpu not supporting floating point hardware very well – the Pandora version uses vfpv3, but the PI only supports v2. SpecBAS currently only uses floats for value storage, but that is due to change soon with integer support.

      I’m also leaving line numbers in, as I like them :-p

      D.

Leave a Reply to steve Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.