Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:31 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: MMBasic Transpiler

     Page 1 of 2    
Author Message
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:39pm 22 Jul 2020
Copy link to clipboard 
Print this post

Hello folks,

Release 1, beta 1 of my MMBasic Transpiler is now released.

What is it?

A transcompiler and code-formatter for MMBasic 5.05 running on the Colour Maximite 2.

Features:
* Flattens #Include hierarchies
   * useful for moving code from the CMM2 to other MMBasic flavours
     that currently do not support #Include.
   * supports multiple levels of #Include and does not require the
     files to have ".inc" file-extension
         * MMBasic 5.05 on the CMM2 only supports a single level of
           #Include, i.e. a ".bas" file can #Include one or more ".inc"
           files and that's it.
* Configurable code reformatting
   * automatic indentation.
   * automatic update of spacing between tokens.
   * remove comments.
   * remove empty-lines.
* Conditional commenting/uncommenting of code sections
   * useful for supporting multiple MMBasic flavours from a single source-tree.
* Configurable token replacement
   * useful for improving performance by inlining constants
     and shortening identifiers.
   * currently only supports a 1 -> 1 mapping.


For more information see https://github.com/thwill1000/mmbasic-transpiler/blob/master/README.md

Where can I download a zip file?

https://github.com/thwill1000/mmbasic-transpiler/releases/download/r1b1/mbt-r1b1.zip

What does it contain that might be worth repurposing for my own creations?

* Lexer/tokenizer for the MMBasic language.
* Implementations of 'Set' and 'Map' datastructures.
* Command-line option parsing built upon the lexer.
* The beginnings of an MMBasic unit-testing framework.

Hope that it's of some use,

Tom
Edited 2020-07-22 22:43 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:46pm 22 Jul 2020
Copy link to clipboard 
Print this post

Ugh, sorry about the mess, my original post included a right-arrow character (Alt-26) that the forum software didn't like. I'll see if I can get Glenn to remove the empty posts.

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
abraxas
Regular Member

Joined: 16/06/2020
Location: Canada
Posts: 99
Posted: 02:27pm 22 Jul 2020
Copy link to clipboard 
Print this post

  thwill said  Hello folks,

Release 1, beta 1 of my MMBasic Transpiler is now released.

What is it?

A transcompiler and code-formatter for MMBasic 5.05 running on the Colour Maximite 2.

Features:
* Flattens #Include hierarchies
   * useful for moving code from the CMM2 to other MMBasic flavours
     that currently do not support #Include.
   * supports multiple levels of #Include and does not require the
     files to have ".inc" file-extension
         * MMBasic 5.05 on the CMM2 only supports a single level of
           #Include, i.e. a ".bas" file can #Include one or more ".inc"
           files and that's it.
* Configurable code reformatting
   * automatic indentation.
   * automatic update of spacing between tokens.
   * remove comments.
   * remove empty-lines.
* Conditional commenting/uncommenting of code sections
   * useful for supporting multiple MMBasic flavours from a single source-tree.
* Configurable token replacement
   * useful for improving performance by inlining constants
     and shortening identifiers.
   * currently only supports a 1 -> 1 mapping.


For more information see https://github.com/thwill1000/mmbasic-transpiler/blob/master/README.md

Where can I download a zip file?

https://github.com/thwill1000/mmbasic-transpiler/releases/download/r1b1/mbt-r1b1.zip

What does it contain that might be worth repurposing for my own creations?

* Lexer/tokenizer for the MMBasic language.
* Implementations of 'Set' and 'Map' datastructures.
* Command-line option parsing built upon the lexer.
* The beginnings of an MMBasic unit-testing framework.

Hope that it's of some use,

Tom


Great initial feature set, thwill! Thanks for this work. I think I will have a play with it on my sources. That said, the killer feature for me would be the ability to inline CONST variables. In tight loops I resort to using hardcoded magic numbers to avoid the cost of indirection that the interpreter adds to dereference a variable. Is that feature in line with the things you envision for this project?
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 02:34pm 22 Jul 2020
Copy link to clipboard 
Print this post

  abraxas said  That said, the killer feature for me would be the ability to inline CONST variables ...


Hi "abraxas", it could be prettier and more automated, but I'm already using the transpiler for constant inlining, at least if the constant value is a single token.

If you transpile this:

'!set INLINE_CONSTANTS
'!replace A 1
'!replace B 2
'!comment_if INLINE_CONSTANTS
Const A = 1
Const B = 2
'!endif

Print A + B


Then you get this:

Print 1 + 2


EDIT: Note there is nothing magic about the choice of INLINE_CONSTANTS as the name for the controlling flag.

Regards,

Tom
Edited 2020-07-23 00:40 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
abraxas
Regular Member

Joined: 16/06/2020
Location: Canada
Posts: 99
Posted: 03:28pm 22 Jul 2020
Copy link to clipboard 
Print this post

  thwill said  
  abraxas said  That said, the killer feature for me would be the ability to inline CONST variables ...


Hi "abraxas", it could be prettier and more automated, but I'm already using the transpiler for constant inlining, at least if the constant value is a single token.

If you transpile this:

'!set INLINE_CONSTANTS
'!replace A 1
'!replace B 2
'!comment_if INLINE_CONSTANTS
Const A = 1
Const B = 2
'!endif

Print A + B


Then you get this:

Print 1 + 2


EDIT: Note there is nothing magic about the choice of INLINE_CONSTANTS as the name for the controlling flag.

Regards,

Tom


Thanks, Tom. Is there a reason to repeat yourself in the source though? Looks like you have to declare each replacement explicitly with the '!replace statements?
Is there a possibility in the future for a '!replace ALL as a catch all for inlining every CONST variable?
Edited 2020-07-23 01:29 by abraxas
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 03:50pm 22 Jul 2020
Copy link to clipboard 
Print this post

  abraxas said  Thanks, Tom. Is there a reason to repeat yourself in the source though? Looks like you have to declare each replacement explicitly with the '!replace statements?
Is there a possibility in the future for a '!replace ALL as a catch all for inlining every CONST variable?


Actually I'm not sure that is possible in the general case. Consider the following which I believe to be valid MMBasic:

If foo Then
 Const A = 1
Else
 Const A = 2
EndIf


There is no way for the transpiler to know what value to use for 'A' unless 'foo' is also a Const .. and even then you start having to build a lot of "smarts" into the transpiler. The behaviour of an interpreted language like MMBasic a lot more "interesting" than something compiled like "C".

That leaves you with 2 options:

- Either the transpiler imposes restrictions on what subset of BASIC it allows, e.g. if it finds there are two declarations of A then it simply refuses to transpile, or better yet it won't create an automatic replacement for A.

- Or you are forced to use the transpiler as a preprocessor, i.e. you write code that won't RUN unless it is first transpiled, which you can already do, e.g.

Option Explicit On
'!replace A 1
'!replace B 2

Print A + B


Regards,

Tom
Edited 2020-07-23 02:01 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
abraxas
Regular Member

Joined: 16/06/2020
Location: Canada
Posts: 99
Posted: 04:27pm 22 Jul 2020
Copy link to clipboard 
Print this post

  thwill said  
  abraxas said  Thanks, Tom. Is there a reason to repeat yourself in the source though? Looks like you have to declare each replacement explicitly with the '!replace statements?
Is there a possibility in the future for a '!replace ALL as a catch all for inlining every CONST variable?


Actually I'm not sure that is possible in the general case. Consider the following which I believe to be valid MMBasic:

If foo Then
 Const A = 1
Else
 Const A = 2
EndIf


There is no way for the transpiler to know what value to use for 'A' unless 'foo' is also a Const .. and even then you start having to build a lot of "smarts" into the transpiler. The behaviour of an interpreted language like MMBasic a lot more "interesting" than something compiled like "C".

That leaves you with 2 options:

- Either the transpiler imposes restrictions on what subset of BASIC it allows, e.g. if it finds there are two declarations of A then it simply refuses to transpile, or better yet it won't create an automatic replacement for A.

- Or you are forced to use the transpiler as a preprocessor, i.e. you write code that won't RUN unless it is first transpiled, which you can already do, e.g.

Option Explicit On
'!replace A 1
'!replace B 2

Print A + B


Regards,

Tom


Yeah, that's a very astute point, Tom. Now I understand the limits. I'm still biased to read code as if it's compiled when it's not. What you said makes sense and the way you handle this is probably the best compromise (or at least I can't think of any improvement at this point).
 
Atomizer_Zero
Senior Member

Joined: 04/07/2020
Location: United Kingdom
Posts: 134
Posted: 07:46pm 27 Jul 2020
Copy link to clipboard 
Print this post

Decided to give this a try, as a break from grilling over lines and lines of code for hours on end recently...

It starts out fine, but it gets some part through my second .inc file, and gives me an error [169] error: index out of bounds


is it something in my code causing this? I didn't add any extra options to the cmdline.

cheers
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 07:50pm 27 Jul 2020
Copy link to clipboard 
Print this post

  Atomizer_Zero said  It starts out fine, but it gets some part through my second .inc file, and gives me an error [169] error: index out of bounds


That suggests it thinks there is a line with more than 50 BASIC tokens on it, sounds unlikely so probably a bug on my side.

Can you point me at the code in question and I'll see what I can do.

Regards,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:07pm 27 Jul 2020
Copy link to clipboard 
Print this post

"Worked" for me on the last version posted here: https://www.thebackshed.com/forum/ViewTopic.php?FID=16&TID=12399&LastEntry=Y#151086

I quote "Worked" because I'm not connected to a VGA monitor so I can't execute the result.

Regards,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:14pm 27 Jul 2020
Copy link to clipboard 
Print this post

Looking at this code I would say there is at least a 10% speed improvement waiting in reducing identifier lengths.

Maybe 5% or more in inlining the constants.

Maybe 5% in inlining the 1-2 line functions - my transpiler can't help with that yet I'm afraid.

Regards,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 08:17pm 27 Jul 2020
Copy link to clipboard 
Print this post

Sorry ... wrong program, I thought this was the Boulderdash port.

Let's go back to the beginning, can you point me at the code ?



Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Atomizer_Zero
Senior Member

Joined: 04/07/2020
Location: United Kingdom
Posts: 134
Posted: 09:31pm 27 Jul 2020
Copy link to clipboard 
Print this post

lol. No worries. I haven't actually released my code yet, as it's far from complete and probably needs a complete rewrite to be honest.


When you said " a line with more than 50 basic tokens in ", what exactly is a basic token?
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 10:37pm 27 Jul 2020
Copy link to clipboard 
Print this post

  Atomizer_Zero said  When you said " a line with more than 50 basic tokens in ", what exactly is a basic token?


For the transpiler a token is a keyword (e.g. DIM), identifier (i.e. variable/sub/function name), operator or other symbol (e.g. >= or :), number literal (e.g. 42, 3.6e-17, &hFF), string literal (e.g. "foo bar"), directive or comment. So it is unlikely you have 50 on one line unless you are doing something very peculiar.

Note that Peter will occasionally talk about the limited number of tokens restricting the ability to extend MMBasic, this is different. Each of the MMBasic's top-level 128 operators/functions and 128 commands has a unique *byte* value that is used when the firmware tokenises a file to execute. Because the language has now reached the 256 token limit that can fit in a byte there are restrictions on how it can be extended without a significant rewrite.

I'm not sure what command line you are using, but if you execute:

       RUN "/mbt/mbt.bas", "input.bas"

Then you should see the output on the console up until the failing line in your code.

You can also add the -C flag to syntax highlight the output if you are using a VT100 terminal.

I'm really curious to find out what is going on so I'd appreciate it if you would persevere with mbt, I can add some additional diagnostics if necessary.

Regards,

Tom
Edited 2020-07-28 08:38 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 10:39pm 27 Jul 2020
Copy link to clipboard 
Print this post

Deleted strange double post.
Edited 2020-07-28 09:14 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
Atomizer_Zero
Senior Member

Joined: 04/07/2020
Location: United Kingdom
Posts: 134
Posted: 11:17pm 27 Jul 2020
Copy link to clipboard 
Print this post

1871:                     If (SPRSCLN(i, 2)) And &H80 = 0 Then
1872:                         If (((SLINE - SPRSCLN(i, 0))And &HFF)< 8) Then
1873:                             LOSPRADDR = (((SPRSCLN(i, 1) And &H01) << 12) Or ((SPRSCLN(i, 1) And &HFE) << 4) Or ((SLINE - SPRSCLN(i, 0)) And &H07)) And &HFFFF
1874:                         Else
[169] Error: Index out of bounds


This is where it fails. It's a complicated nested if else set of statements that call functions and do bit manipulation and such. So i'm not surprised it's causing issues lol.

I'm going to have to rewrite this at some point anyway, as it's very unoptimized and probably doesn't even work properly in it's current state haha.
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 11:52pm 27 Jul 2020
Copy link to clipboard 
Print this post

Right, that line does contain more than 50 tokens I guess that means I need to up the limit.

You can fix it for yourself by editing line 55 of "mbt.bas":

       Const LX_MAX_TOKENS = 50

Thanks for reporting the problem,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 12:16pm 31 Jul 2020
Copy link to clipboard 
Print this post

Tom--I know your transpiler has a different purpose, but since it seems it must do most of the parsing work needed, would it be difficult to modify it to produce a hierarchical tree of a program's structure? For instance:

A   B   C
    D   C
    E   F   C
    G   H   B   C
    I


~
Edited 2020-07-31 22:17 by lizby
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:24pm 31 Jul 2020
Copy link to clipboard 
Print this post

Hi Lizby,

I'm sorry, I don't understand. What are the elements A, B, C ... ?

Perhaps a more specific example would help.

Regards,

Tom
Edited 2020-07-31 22:26 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 12:58pm 31 Jul 2020
Copy link to clipboard 
Print this post

I guess they're each the names of SUBs and FUNCTIONs.

So, A calls each of B, D, E, G and I.

Often called a call tree.

Beware recursion...

John
Edited 2020-07-31 23:00 by JohnS
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025