Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:02 02 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 FW feature request: #define with params

Author Message
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 08:49pm 27 Feb 2021
Copy link to clipboard 
Print this post

Hi,

I have an MMBasic feature request:

#DEFINE has been introduced in 5.06 FW. Would it be possible at all to add support for parameters to #DEFINE?
E.g. #DEFINE DIST(x,y) SQR(x*x+y*y)

I have a lot of small wrapper functions like these:


FUNCTION Vector_create%(x!, y!)
 'Store vector as two Fix16.16 numbers, x in the upper 32 bits, y in the lower.
 Vector_create% = (CINT(x!*65536)<<32) OR (CINT(y!*65536) AND &HFFFFFFFF)
END FUNCTION

SUB Vector_setX(v%, x!)
 v% = (CINT(x!*65536)<<32) OR (v% AND &HFFFFFFFF)
END SUB

SUB Vector_setY(v%, y!)
 v% = (v% AND &HFFFFFFFF00000000) OR (CINT(y!*65536) AND &HFFFFFFFF)
END SUB

FUNCTION Vector_getX!(v%)
 Vector_getX! = (v%>>>32)/65536
END FUNCTION

FUNCTION Vector_getY!(v%)
 'Sign extend if necessary.
 Vector_getY! = ((v%<<32)>>>32)/65536
END FUNCTION


Being able to write code like is important, because it helps to make a program more readable.
For smaller programs that's just a nice-to-have, but for bigger projects it really makes a difference.
If I see in a program (v%>>>32)/65536, I don't immediately think 'Oh yeah, that's the x component of a 16.16 fixed point vector converted to a float'. But when I see Vector_getX!(v%), that's clear.

Unfortunately, the function call overhead for small wrapper functions is huge:

This is an xProf of my game loop:

Object.inc:[120-124]: 11                          :*
Object.inc:[140-144]: 0                           :
Object.inc:[175-179]: 2                           :
Object.inc:[185-189]: 35                          :****
Object.inc:[240-244]: 97                          :*************
ObjectList.inc:[125-129]: 0                       :
ObjectList.inc:[155-159]: 84                      :***********
ObjectList.inc:[160-164]: 49                      :******
ObjectList.inc:[225-229]: 9                       :*
ObjectListIterator.inc:[20-24]: 69                :*********
ObjectListIterator.inc:[25-29]: 62                :********
ObjectListIterator.inc:[30-34]: 41                :*****
ObjectListIterator.inc:[35-39]: 65                :********
ObjectListIterator.inc:[40-44]: 13                :*
Sprite.inc:[145-149]: 1                           :
Utility.inc:[35-39]: 53                           :*******
Utility.inc:[40-44]: 20                           :**
Utility.inc:[45-49]: 4                            :
Utility.inc:[50-54]: 9                            :*
Utility.inc:[100-104]: 1                          :
Vector.inc:[5-9]: 1                               :
Vector.inc:[30-34]: 146                           :********************
Vector.inc:[35-39]: 78                            :**********


All but one of peak entries are small wrapper function like the ones I showed for Vector.inc. Inlining these would result in a big performance win.

Peter Mather, if you're reading this, please let me know whether or not adding #DEFINEs with params is a reasonable option.
If it's not, that's fine of course, feature creep and all that. But in that case I will probably go ahead and write an MMBasic preprocessor that does this kind of macro expansion.

Cheers,
Ruben/Epsilon.
Epsilon CMM2 projects
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 10:44pm 27 Feb 2021
Copy link to clipboard 
Print this post

  Quote  Peter Mather, if you're reading this, please let me know whether or not adding #DEFINEs with params is a reasonable option.


No: I hate writing parsing and this would be complex
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 08:01am 01 Mar 2021
Copy link to clipboard 
Print this post

Sounds suitable for a pre-processor along the lines of Tom's "transpiler".

With some thought you could probably write and debug code without pre-processing and when working make it faster by using the pre-processor.

John
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 09:44am 01 Mar 2021
Copy link to clipboard 
Print this post

  JohnS said  Sounds suitable for a pre-processor along the lines of Tom's "transpiler".


Hah, I'm surprised anyone remembers that as there wasn't much interest at the time.

John is talking about the "sptrans" component of sptools. If you do end up using any of that you probably want to look at the "develop-r1b3" branch rather than "master" as it contains another 40 odd change-sets of improvements, though not particularly relvant to the question at hand.

Unfortunately "sptrans" also only handles simple replacements using the:
       
'!replace <to> <from>

directive, because that is all that I required at the time.

I did briefly looking at extending it do something closer to C macros, but it wasn't completely trivial and there were "enabling" improvements to be made to the underlying lexer/parser that I thought should be done first. Then @matherp added #define and I thought (apparently incorrectly) that might be the first step in him working on other extensions to MMBasic's preprocessor so I decided to sit back and wait to see what happened.

I don't see myself coming back to this in the near future as I have been distracted by other projects, and then (sorry @Turbo64) been further distracted from those distractions . Only another 20 years until retirement and then I'll be able to get in some serious programming, can you wait until then ?

Best wishes,

Tom
Edited 2021-03-01 20:30 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:10pm 01 Mar 2021
Copy link to clipboard 
Print this post

Probably not too bad to do in lex+yacc / flex+bison or the like, then, especially if you add some easy to parse markers.

John
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 12:13pm 01 Mar 2021
Copy link to clipboard 
Print this post

  Quote   (sorry @Turbo64)

Keep safe. Live long and prosper.
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:21pm 01 Mar 2021
Copy link to clipboard 
Print this post

  Turbo46 said  
  Quote   (sorry @Turbo64)


SAAINT is still happening Bill, I just wanted to use some recent enthusiasm to have a blitz on trying out another idea and see if it was a runner.
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 06:44pm 01 Mar 2021
Copy link to clipboard 
Print this post

So I did the one-liner inlining, and performance jumped by a factor of two. Good, but not nearly enough. I will also need to inline 2-5 line functions. And if I have that, I might as well flatten the entire call tree.
However, even if I start from Tom's codebase, writing a preprocessor that can handle multi-line functions is a big task. And all I want is to optimize my game loop.

Another issue is that you lose the direct mapping between source code and the processed code. For an MMBasic program I think it's important to keep that mapping.

So I think I'm just going to handle my optimizations the old fashioned way: profile, then optimize where needed using inlining, unrolling, the occasional csub, etc. The optimized code will be less readable, unfortunately. I'll have to mitigate that with comments (mostly by putting the original code in comments actually).
Epsilon CMM2 projects
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025