Jump to content
matthew180

BASIC / XB Translator (TidBit)

Recommended Posts

When the game contests started up around here again I was thinking of making an entry, but then remembered all the reasons I dislike BASIC and XB (besides how slow they are.) No indentation, no labels, comments that eat up memory, etc. I've wanted to make a new language for our beloved 99/4A for a long time, but alas that is just another project out of many on the list.

 

However, in lieu of a new language, I figured it would be easy enough to add some of those features via a "translator". You would still code with BASIC, but without line numbers and such, then the translator would trim out spaces and remarks, add the line numbers, and spit out the code to copy and paste into Classic99.

 

I wrote the guts of it last night with these features:

 

* No line numbers allowed, they will be assigned

 

* Labels can consist of A-Z, a-z, 0-9, _, and -. They can be any length, but a maximum line length is 256 characters. Label "definitions" must start a line and end with a single colon. Labels can be referenced any place a line number can be used, currently: THEN, ELSE, [ON]GOTO, [ON]GOSUB, and ON ERROR.

 

* Comments are stripped from the code. Comments are any line that start with REM or // (C/C++ style single line comment notation). XB also has a "trailing comment" designated by a ! that causes the rest of the line to be ignored. These comments will be stripped as well.

 

* Leading space is ignored so you can indent as much as you like.

 

* Long lines can be split by ending a line with .. (two consecutive periods). These lines will be joined into one long line and the XB limit of 140 characters will be checked.

 

* Starting line numbers and the increment can be set.

 

 

Features I was thinking of adding:

 

* Support multiple source files.

 

 

Currently the translator is written in PHP, which makes it conducive to being set up on a webpage. However, that might make development cumbersome, so I was thinking of making it a native Windows app. I'd like to hear opinions either way.

 

 

 

This post will always have the latest code.

 

CHANGE LOG:

V1.0 November 20, 2010
    * Initial release

V1.1 February 13, 2011
    * Added forced line number override.

    * Fixed label bug.

    * Fixed max line number bug.

    * Change REM statements to be included in output code.

V1.2 February 25, 2011
    * Added the missing RESTORE, BREAK, and UNBREAK commands / statements to the list
      of tokens that support a line number or list of line numbers.

V1.3 Feb 26, 2011
    * Fixed REM and ! comments.

V2.0 March 16, 2015
    * Fixed using RETURN in an error context when used in an IF/THEN/ELSE statement, i.e. IF exp THEN RETURN <label>.

    * Added additional support for the other ON <statement> (BREAK, ERROR, etc.) commands that can accept a line-number list.

    * Added a version number to keep track of updates.

    * Added a readme.txt with instructions on how to use TidBit on the command line or with PHP's built-in web server.

    * Removed requirement to have .. after the XB :: operator

    * Added ENDIF pseudo statement

V2.1 June 25, 2016
    * Removed requirement to have .. after THEN or ELSE statements, or after the
      last expression before an ELSE statement.

    * Prevent the keyword 'PRINT' from being used as a label to avoid possible
      errors due to the BASIC use of the colon with a print statement: 'PRINT: :'

V2.2 September 10, 2016
    * Added more debug statements.

    * Added check to not allow the auto line number from being overwritten by a
      forced line number if the forced line number is less than the current auto
      line number.  This prevents accidental loss of code.

V3.0 September 13, 2016
    * Simplified parser stage.  Being less-smart reduces errors.

    * Added list of reserved words to avoid label confusion.

    * Fixed bugs in expression parsing with embedded strings.

    * Fixed string parsing bug with escaped double quotes.

    * Fixed XB ! comments that were along on a line.

    * Fixed XB :: operator when following PRINT or DISPLAY AT with colon options.

V3.1 November 17, 2019
    * Fixed incorrect parsing of the double-colon (::) when it was used
      immediately following a label.

    * Syntax cleanup and comment improvements.

tidbit_v3.0.zip

tidbit_v31.zip

Edited by matthew180
New updates
  • Like 1

Share this post


Link to post
Share on other sites

I'm trying to understand what this is. You'd code in a modified, less cumbersome and line-number-driven form of BASIC -- kind of a more refined take on it -- and then this would sorta "assemble" it back into a BASIC listing the 99/4A could deal with?

Share this post


Link to post
Share on other sites

I think that's the long and short of it. :) Matthew talked about this in chat about a week ago. Great stuff.... Sort of a reverse-Wilhelm's compiler. :)

Share this post


Link to post
Share on other sites

When the game contests started up around here again I was thinking of making an entry, but then remembered all the reasons I dislike BASIC and XB (besides how slow they are.) No indentation, no labels, comments that eat up memory, etc. I've wanted to make a new language for our beloved 99/4A for a long time, but alas that is just another project out of many on the list.

 

However, in lieu of a new language, I figured it would be easy enough to add some of those features via a "translator". You would still code with BASIC, but without line numbers and such, then the translator would trim out spaces and remarks, add the line numbers, and spit out the code to copy and paste into Classic99.

 

I wrote the guts of it last night with these features:

 

* No line numbers allowed, they will be assigned

 

* Labels can consist of A-Z, a-z, 0-9, _, and -. They can be any length, but a maximum line length is 256 characters. Label "definitions" must start a line and end with a single colon. Labels can be referenced any place a line number can be used, currently: THEN, ELSE, [ON]GOTO, [ON]GOSUB, and ON ERROR.

 

* Comments are stripped from the code. Comments are any line that start with REM or // (C/C++ style single line comment notation). XB also has a "trailing comment" designated by a ! that causes the rest of the line to be ignored. These comments will be stripped as well.

 

* Leading space is ignored so you can indent as much as you like.

 

* Long lines can be split by ending a line with ... These lines will be joined into one long line and the XB limit of 140 characters will be checked.

 

* Starting line numbers and the increment can be set.

 

* A keyword "proc" can be added to specify "procedure" line numbering, which causes the line number counter to change to the next highest multiple of the specified value. What this does is allows you to number subroutines starting at certain values, like 1000, 2000, 3000, etc.

 

 

Features I was thinking of adding:

 

* Support multiple source files.

 

 

Currently the translator is written in PHP, which makes it conducive to being set up on a webpage. However, that might make development cumbersome, so I was thinking of making it a native Windows app. I'd like to hear opinions either way.

 

Examples coming soon.

 

Matthew

 

 

A command-line app would be fine, although a native Windows app would be cool too. You could whip something like that up in C# easily enough. :)

 

Looking forward to seeing it! Line numbers are a pain, indeed, to deal with.

 

Adamantyr

Share this post


Link to post
Share on other sites

Rather than pasting the resultant code in Classic99, how hard would it be to save the file in DV163 (merge format)?

 

I've never looked at DV163 - is it tokenised or text?

 

Mark

Share this post


Link to post
Share on other sites

Oohhh... Would be nice if we could make "includes" of commonly use functions, whatevers... I spend way too much time re-writing stuff.

Share this post


Link to post
Share on other sites

Can you open source this, I'll like to fallow along with your development, since it mirrors a project I'm working on. I mainly want to see how you are pharsing the commands. And assigning varibles.

Share this post


Link to post
Share on other sites

Here is some example code, sorry I didn't post any sooner. I'll get to the other questions in a little bit. This is an example of my Hunt Kill Maze generator.

 

Input:

 

 

//
// Hunter-Killer Maze Algorithm
// TI-99/4A Extended BASIC Version
//

// Initialize
CALL CLEAR :: OPTION BASE 0 :: RANDOMIZE
CALL CHAR(96,"0000000000000000")
CALL CHAR(97,"0101010101010101")
CALL CHAR(98,"00000000000000FF")
CALL CHAR(99,"01010101010101FF")
CALL CHAR(100,"017D4545457D01FF")
CALL COLOR(9,2,11)

// Initialize the maze screen offset and starting "hunt" mode coordinate.
OX=10 :: OY=6 :: HX=1 :: HY=1

// Dimmension the MAZE array and initialize the border.
SX=12 :: SY=12 :: ..
DIM MAZE(13,13)

FOR I=0 TO SX+1 :: ..
    MAZE(I,0)=-1 :: ..
    MAZE(I,SY+1)=-1 :: ..
NEXT I

FOR I=1 TO SY :: ..
    MAZE(0,I)=-1 :: ..
    MAZE(SX+1,I)=-1 :: ..
NEXT I

// Dimmension and initialize the direction-to-offset lookup table.  What
// this does is saves us from having to use IF statements to find out
// what to add to X and Y for a given direction D.
DIM P(4,2)
    P(1,1)=0 :: ..
    P(1,2)=-1 :: ..
    P(2,1)=1 :: ..
    P(2,2)=0
    P(3,1)=0 :: ..
    P(3,2)=1 :: ..
    P(4,1)=-1 :: ..
    P(4,2)=0

DIM DBIT(4) :: ..
    DBIT(1)=1 :: ..
    DBIT(2)=2 :: ..
    DBIT(3)=4 :: ..
    DBIT(4)=8

DIM DINV(4) :: ..
    DINV(1)=4 :: ..
    DINV(2)=8 :: ..
    DINV(3)=1 :: ..
    DINV(4)=2

// Draw the initial maze, all walls up.
FOR I=OY TO OY+SY-1
    CALL HCHAR(I,OX,99,SX)
NEXT I

// Pick a random starting point and enter Kill mode.
KillMode:

    X=INT(RND*SX)+1 :: ..
    Y=INT(RND*SY)+1 :: ..
    IF MAZE(X,Y)<>0 THEN ..
        KillMode

    DISPLAY AT(1,1):"KILL"

    // Pick a random direction D (1-4) and remember it (D1) so we know when we
    // have tried all 4 directions for this cell.  RND is a very expensive
    // instruction, as is the multiplication.
    PickRandomDirection:

        D=INT(RND*3)+1 :: ..
        D1=D

        CheckNewCell:
            // Generate a new cell location (NX,NY) and see if it is okay to move there.
            NX=X+P(D,1) :: ..
            NY=Y+P(D,2)

            IF MAZE(NX,NY)<>0 THEN InvalidDirection

            // Drop the wall in the current cell for the direction in which we are
            // leaving the cell.  Then display the proper wall character for this cell.
            MAZE(X,Y)=MAZE(X,Y) OR DBIT(D)
            C=99

            IF (MAZE(X,Y) AND 2)=2 THEN ..
                C=98

            IF (MAZE(X,Y) AND 4)=4 THEN ..
                IF C=98 THEN ..
                    C=96 ..
                ELSE ..
                    C=97

            CALL HCHAR(OY+Y-1,OX+X-1,C)

            // Set X and Y to the new cell and drop the wall for the direction in which
            // we just entered the cell.
            X=NX :: ..
            Y=NY :: ..
            MAZE(X,Y)=DINV(D)

    GOTO PickRandomDirection

    InvalidDirection:

        D=D+1 :: ..
        IF D>4 THEN ..
            D=1

    IF D<>D1 THEN ..
        CheckNewCell

// Begin "hunt" mode.  Displays the proper character for the current cell
// and marks the cell as "complete".
HuntMode:

    C=99
    IF (MAZE(X,Y) AND 2)=2 THEN ..
        C=98

    IF (MAZE(X,Y) AND 4)=4 THEN ..
        IF C=98 THEN ..
            C=96 ..
        ELSE ..
            C=97

    CALL HCHAR(OY+Y-1,OX+X-1,C)
    MAZE(X,Y)=MAZE(X,Y) OR 16

    // Set up the hunt loops.  Hunting is a sequential scan over the maze,
    // looking for a cell that has been visited but is not yet complete.
    // Once the whole maze has been scanned in hunt mode and all cells are
    // found to be "complete", the maze is done.

    RESET=0

    FOR J=HY TO SY :: ..
        DISPLAY AT(1,1):"HUNT: ";J

        FOR I=HX TO SX

            // Looking for a visited cell to being Kill mode again.  All cells that
            // are either 0 or >=16 are unvisited or complete, and are skipped.

            // If an unvisited cell (0) is found, the next time we enter hunting mode,
            // we must begin at the beginning (indicated by the RESET variable.)
            // However, if there are no unvisited cells up to the next cell to
            // continue with, we can pick up hunting were we left off.

            IF MAZE(I,J)=0 THEN ..
                RESET=1 :: ..
                GOTO Next_I

            IF MAZE(I,J)>=16 THEN ..
                Next_I

            // A valid cell was found, so set that as the current cell.  The direciton
            // is set instead of chosen again at random since 1. this cell already had
            // a random direction chosen for it once before, and 2. chosing a random
            // number is expensive and we want to avoid it if possible.  This is why
            // we jump back to the line just following the random direction generation.

            X=I :: Y=J

            IF RESET=0 THEN ..
                HX=I :: ..
                HY=J ..
            ELSE ..
                HX=1 :: ..
                HY=1

            DISPLAY AT(1,1):"KILL"
            D=4 :: ..
            D1=4

            // Hmm, jumping out of a FOR - NEXT loop is not really good
            // programming practice.
            GOTO CheckNewCell

        // Hunting loop iterators.  If we picked up hunting where we had left off
        // on a previous hunting loop, the hunting column (HX) must be reset back
        // to 1, otherwise hunting would miss chunks of the maze if we hunt past
        // the current line during this hunting iteration.
        Next_I:
        NEXT I

        HX=1

    NEXT J

DISPLAY AT(1,1):"DONE"
KeyWait: CALL KEY(0,K,S) :: IF S=0 THEN KeyWait

END

 

 

 

Output:

 

 

 

100 CALL CLEAR :: OPTION BASE 0 :: RANDOMIZE
110 CALL CHAR(96,"0000000000000000")
120 CALL CHAR(97,"0101010101010101")
130 CALL CHAR(98,"00000000000000FF")
140 CALL CHAR(99,"01010101010101FF")
150 CALL CHAR(100,"017D4545457D01FF")
160 CALL COLOR(9,2,11)
170 OX=10 :: OY=6 :: HX=1 :: HY=1
180 SX=12 :: SY=12 :: DIM MAZE(13,13)
190 FOR I=0 TO SX+1 :: MAZE(I,0)=-1 :: MAZE(I,SY+1)=-1 :: NEXT I
200 FOR I=1 TO SY :: MAZE(0,I)=-1 :: MAZE(SX+1,I)=-1 :: NEXT I
210 DIM P(4,2)
220 P(1,1)=0 :: P(1,2)=-1 :: P(2,1)=1 :: P(2,2)=0
230 P(3,1)=0 :: P(3,2)=1 :: P(4,1)=-1 :: P(4,2)=0
240 DIM DBIT(4) :: DBIT(1)=1 :: DBIT(2)=2 :: DBIT(3)=4 :: DBIT(4)=8
250 DIM DINV(4) :: DINV(1)=4 :: DINV(2)=8 :: DINV(3)=1 :: DINV(4)=2
260 FOR I=OY TO OY+SY-1
270 CALL HCHAR(I,OX,99,SX)
280 NEXT I
290 X=INT(RND*SX)+1 :: Y=INT(RND*SY)+1 :: IF MAZE(X,Y)<>0 THEN 290
300 DISPLAY AT(1,1):"KILL"
310 D=INT(RND*3)+1 :: D1=D
320 NX=X+P(D,1) :: NY=Y+P(D,2)
330 IF MAZE(NX,NY)<>0 THEN 410
340 MAZE(X,Y)=MAZE(X,Y) OR DBIT(D)
350 C=99
360 IF (MAZE(X,Y) AND 2)=2 THEN C=98
370 IF (MAZE(X,Y) AND 4)=4 THEN IF C=98 THEN C=96 ELSE C=97
380 CALL HCHAR(OY+Y-1,OX+X-1,C)
390 X=NX :: Y=NY :: MAZE(X,Y)=DINV(D)
400 GOTO 310
410 D=D+1 :: IF D>4 THEN D=1
420 IF D<>D1 THEN 320
430 C=99
440 IF (MAZE(X,Y) AND 2)=2 THEN C=98
450 IF (MAZE(X,Y) AND 4)=4 THEN IF C=98 THEN C=96 ELSE C=97
460 CALL HCHAR(OY+Y-1,OX+X-1,C)
470 MAZE(X,Y)=MAZE(X,Y) OR 16
480 RESET=0
490 FOR J=HY TO SY :: DISPLAY AT(1,1):"HUNT: ";J
500 FOR I=HX TO SX
510 IF MAZE(I,J)=0 THEN RESET=1 :: GOTO 580
520 IF MAZE(I,J)>=16 THEN 580
530 X=I :: Y=J
540 IF RESET=0 THEN HX=I :: HY=J ELSE HX=1 :: HY=1
550 DISPLAY AT(1,1):"KILL"
560 D=4 :: D1=4
570 GOTO 320
580 NEXT I
590 HX=1
600 NEXT J
610 DISPLAY AT(1,1):"DONE"
620 CALL KEY(0,K,S) :: IF S=0 THEN 620
630 END

 

 

Matthew

Edited by matthew180

Share this post


Link to post
Share on other sites

Rather than pasting the resultant code in Classic99, how hard would it be to save the file in DV163 (merge format)?

 

I've never looked at DV163 - is it tokenised or text?

 

Mark

 

I don't know anything about the Merge format. Direct me to the some info and I'll look into generating an output in that format if it is not too involved. I'm trying to keep it simply at this point, and not consume all my time.

 

Matthew

Share this post


Link to post
Share on other sites

Oohhh... Would be nice if we could make "includes" of commonly use functions, whatevers... I spend way too much time re-writing stuff.

 

I can do something like C/C++ #include... I suppose that is cleaner than specifying a bunch of input files on the command line. Is this a desired feature then?

 

Matthew

Share this post


Link to post
Share on other sites

Can you open source this, I'll like to fallow along with your development, since it mirrors a project I'm working on. I mainly want to see how you are pharsing the commands. And assigning varibles.

 

I guess so, but at this point it is a 4 hour hack and I totally abuse PHP's string handling. Initially I wanted to go the poor-man's way and just string replace the labels after I made the list. However, since BASIC supports strings, and the text in a string could legally be the same text as a label, you can't just search-and-replace, you have to parse the context. Language parsing is something I've been messing with for a while, so it did not take long to modify something I had written before.

 

Detecting the labels is easy because of the stipulation I made about them having to start a line and end with a single colon; that is pass 1. Replacing them later in context is pass 2, and that's where the parsing comes in. Depending on where this goes, it may evolve into complete BASIC parsing, but not right now.

 

Attached is the current code. It will run any place you have access to PHP 5.x, which includes Windows, Unix, and MAC. Depending on if people start to use it, I'm considering a C version with a native Windows/MAC/Unix GUI.

 

Matthew

tidbit.zip

Share this post


Link to post
Share on other sites

Now that I have written a program for my own creation, I'm thinking I don't like the ... for continuation. Something shorter maybe, like .. or just a single . Can an BASIC or XB line ever end in a single period?

 

I was also thinking about adding an ENDIF token that is simply ignored, but it would allow closing of the IF statements that would look more natural.

 

Matthew

Edited by matthew180

Share this post


Link to post
Share on other sites

Variables? You mean the labels? The program uses two passes, so the labels can be referenced before they are defined. The first pass goes through and finds all the labels and assigns line numbers. The second pass goes through and replaces the references with line numbers.

 

So you can do something like:

 

Loop:
   INPUT A
   IF A < 1 OR A > 3 THEN Loop

   ON A GOSUB proc1, proc2, proc3
   END

proc1:
   PRINT "You selected 1"
   RETURN

proc2:
   PRINT "You selected 2"
   RETURN

proc3:
   PRINT "You selected 3"
   RETURN

 

The references to proc1, proc2, and proc3 are used before they are defined, which is fine. The exact output for the above code is (I copied and pasted it to a file and ran the translator):

 

100 INPUT A
110 IF A < 1 OR A > 3 THEN 100
120 ON A GOSUB 140,160,180
130 END
140 PRINT "You selected 1"
150 RETURN
160 PRINT "You selected 2"
170 RETURN
180 PRINT "You selected 3"
190 RETURN

 

 

Matthew

Share this post


Link to post
Share on other sites

Well, I just added the ENDIF pseudo token. I also changed the line continuation operator from three periods ( ... ) to just two ( .. ) and removed the need to have them on the end of a line that ends with XB's multi-line double colon ( :: ) operator.

 

// Old (meaning a few hours ago) way:
A=1 :: ...
B=1

IF A=B THEN ...
   C=2

// New way, .. is not required if a line ends with :: plus optional ENDIF
A=1 ::
B=1

IF A=B THEN ..
   C=2
ENDIF


// Translates to:
100 A=1 :: B=1
110 IF A=B THEN C=2

 

I guess I just need to add the #include support. I was also thinking of having unreferenced code automatically discarded. Doing this means you could have a huge file full of your favorite subroutines and just #include it in all your programs. Then, only the subroutines you actually reference will actually make it into the real output. I don't know, what do you all think?

 

Matthew

Share this post


Link to post
Share on other sites

... for line continuation is nice, but I would also like to suggest that the \ be available, as well. It has been the standard "long line" indicator for just about every system I have worked on which allowed long lines.

Share this post


Link to post
Share on other sites

How about a toggle for automatic line continuation. Like if you're programming for TI Basic, you don't want it. For XB you might not want it, so debugging, tracing, editing is easier. And finally for XB you would want it (multiple-statement lines) for speed and efficiency (less memory as I understand). I don't know, but ENDIF might then be vital.

 

:)

Share this post


Link to post
Share on other sites

... for line continuation is nice, but I would also like to suggest that the \ be available, as well. It has been the standard "long line" indicator for just about every system I have worked on which allowed long lines.

 

True, same here, however I tried the \ and didn't really like it. The main difference between BASIC and other languages is that the other languages *have* an end of line terminator, or other constructs to denote blocks (like parenthesis, curly braces, etc.) Thus, most languages fall into the category of "context-free grammar". BASIC (as we know it on classic computers, ie. "line number" BASIC) is not one of those languages.

 

Because the end of a line denotes the end of a statement in BASIC, you can only have one statement per line. To get around this, BASIC (in general) uses the single colon to allow more than one statement per line. TI's XB uses a double colon because of the PRINT statement's use of a single colon. However, even with the multi-statement operator ( : or :: ) you still cannot break the line over multiple lines because the language does not have any way to know when the statement is done (that and line numbers mess that up.)

 

In other languages, the \ is hardly ever seen because the languages allow you to structure the statements with as much formatting as you want, they simply eat the white space until the "end of statement" token is found. Thus you can do:

 

   if ( a == b ) { c = d; }

or

   if
   ( a == b )
   { c = d; }

or
   if ( a == b ) {
       c = d;
   }

or
   if ( a == b )
       c = d;
etc.

 

The parens denote the expression, the curly braces denote the block (which defaults to a single statement if omitted), and the semicolon terminates a statement. Imagine having to use the \ for every line break:

 

   if ( a == b ) \
   { \
       c = d; \
   }

 

Starts to look really bad, and this is what we have to do in BASIC since the end of a line is used to terminate a statement. I tested with part of the code I'm using as an example:

 

IF (MAZE(X,Y) AND 4)=4 THEN \
   IF C=98 THEN \
       C=96 \
   ELSE \
       C=97
   ENDIF
ENDIF

- or -

IF (MAZE(X,Y) AND 4)=4 THEN ..
   IF C=98 THEN ..
       C=96 ..
   ELSE ..
       C=97
   ENDIF
ENDIF

 

The double period just looked cleaner to me. Unless we adopt an end of line terminator (like a semicolon), and make the ENDIF required, then multi-line statements need an operator that is unused in the language, and it will need to appear on every line. I tried to use a character that was small and low on the line. Hmm, I suppose it could also be a single underscore.

 

IF (MAZE(X,Y) AND 4)=4 THEN _
   IF C=98 THEN _
       C=96 _
   ELSE _
       C=97
   ENDIF
ENDIF

 

Thoughts? Periods are simple to type though since they don't require the shift key.

 

Matthew

Share this post


Link to post
Share on other sites

How about a toggle for automatic line continuation. Like if you're programming for TI Basic, you don't want it. For XB you might not want it, so debugging, tracing, editing is easier. And finally for XB you would want it (multiple-statement lines) for speed and efficiency (less memory as I understand). I don't know, but ENDIF might then be vital.

 

:)

 

ENDIF would be required, as would a terminator for any open-ended construct. Also, I would have to rewrite the code and basically make a full-blown BASIC parser so I could determine the complete state of the program (hell, at that point I could just start interpreting the language and executing the instructions... ;) )

 

Right now the multi-line support is done before my basic statement parsing (because it is easy to detect the :: or .. at the end of a line), and that would all have to change. Maybe down the road, but I'd rather have people start to use what I've so far and see where it goes. Right now it is good enough for what I wanted to do, and if I end up being the only one to use it, then it does not much matter.

 

Matthew

Share this post


Link to post
Share on other sites

This would be so helpful for the bucket of crap I've wound up with in the BoCC contest... I'm constantly renumbering... Almost done, though, but the code is no longer anything to be proud of - but will work - and is seemingly efficient enough. I won't ever be coding in BASIC again, but I'm curious - will the support single line BASIC statements? In a time-machine-based world, it'd be awesome if it could rewrite compound IF/THEN/ELSE into the crap we must deal with in BASIC... Again, this is totally unrequired by me - since I'll never be doing this again... :)

 

-H

Edited by unhuman

Share this post


Link to post
Share on other sites

Not sure you even need line extensions

SX=12 :: SY=12 :: ...
DIM MAZE(13,13)
[/code[
to
[code]
SX=12 :: SY=12 :: 
DIM MAZE(13,13)

 

In this case after the interpreter see "::" it knows the next statement (if on the same line or not) will be added to the same line in the output

 

The same with IF THENS

IF (MAZE(X,Y) AND 4)=4 THEN 
   IF C=98 THEN 
       C=96 
   ELSE 
       C=97
   ENDIF
ENDIF

 

once it finds a IF it enter a structure of what comes next and stays in this structure until it see the ENDIF.

Share this post


Link to post
Share on other sites

but I'm curious - will the support single line BASIC statements?

 

This will support anything you can currently do in BASIC. All I'm mainly doing is automating the line numbers and adding support for labels. The multi-line support I'm adding is just cosmetic. The lines will be joined and still have to make a valid BASIC or XB single line statement. The multi-line operator I've added is simply for the tool to know what lines to join. Both BASIC and XB are supported, it simply depends on how you write your code. If you are using just BASIC, don't use XB instructions or the :: operator. The tool has no knowledge of BASIC vs. XB.

 

Matthew

Share this post


Link to post
Share on other sites

Not sure you even need line extensions

SX=12 :: SY=12 :: ...
DIM MAZE(13,13)

to

SX=12 :: SY=12 :: 
DIM MAZE(13,13)

 

In this case after the interpreter see "::" it knows the next statement (if on the same line or not) will be added to the same line in the output

 

Yup, I already did that. See one of my previous posts from last night. I came to the same conclusion. :)

 

The same with IF THENS

IF (MAZE(X,Y) AND 4)=4 THEN 
   IF C=98 THEN 
       C=96 
   ELSE 
       C=97
   ENDIF
ENDIF

 

once it finds a IF it enter a structure of what comes next and stays in this structure until it see the ENDIF.

 

That would mean making ENDIF required, which I can do, but that starts to change the language itself. But I'd like to know what people think. Also, you still have to use the multi-line statement operator if you have more than one statement in the "THEN" or "ELSE" clauses:

 

IF A=0 THEN
   C=1 ::
   D=5
ENDIF

- would translate to -

100 IF A=0 THEN C=1:=5

 

Matthew

Share this post


Link to post
Share on other sites

 

 

That would mean making ENDIF required, which I can do, but that starts to change the language itself. But I'd like to know what people think. Also, you still have to use the multi-line statement operator if you have more than one statement in the "THEN" or "ELSE" clauses:

 

IF A=0 THEN
   C=1 ::
   D=5
ENDIF

- would translate to -

100 IF A=0 THEN C=1:=5

 

 

 

 

- would translate to -

100 IF A=0 THEN C=1:=5

 

 

 

 

I think the :: would not be needed here because you are in the IF THEN structure and multiple resolves are going to be by default on the same line

 

IF A=0 THEN
   C=1
   D=5
ELSE
   C=2
   D=1
ENDIF


IF A=0 THEN  ;enter the structure resolve condition output 1st half of line "IF A=0 THEN "
Loop to compute resolve
repeat until ENDIF or ELSE
line 1 command C=1 store in resolve string RS="C=1"
line 2 command D=5 store in resolve string RS="C=1"+":=5"
end loop
line 3 command ELSE  add resolve string to output line "IF A=0 THEN C=1:=5"
loop to resolve else RS=" ELSE"
line 4 command 1 C=2 in RS=" ELSE"+"C=2"
line 5 command 2 D=1 add to RS="ELSE C=2"+":=1"
line 6 command ENDIF
end loop cause of ENDIF and add RS to output line  "IF A=0 THEN C=1:=5 ELSE C=2"+":=1"

 

 

You could of course have the resolves on one line before the translation it would just treat a :: as adding a new command to the resolve string.

IF A=0 THEN
   C=1:=5
ELSE
   C=2:=1
ENDIF

as far as that goes this should be allowable to because you are in the structure
IF A=0 THEN C=1:=5 ELSE C=2:=1 ENDIF
because the structure will in pass one break out all commands
line 1 "IF A=0 THEN "
line 2 "C=1"
line 3 ":=5"
line 4 " ELSE "
line 5 "C=2"
line 6 ":=1"
line 7 ENDIF

pass 2 output add lines 1 though 6
"IF A=0 THEN C=1:=5 ELSE C=2:=1"

Edited by jchase1970

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...