![]() |
Forum Index : Microcontroller and PC projects : CMM2 FW feature request: #define with params
Author | Message | ||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
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 KingdomPosts: 10315 |
No: I hate writing parsing and this would be complex |
||||
JohnS Guru ![]() Joined: 18/11/2011 Location: United KingdomPosts: 4044 |
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 KingdomPosts: 4311 |
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 ![]() 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 KingdomPosts: 4044 |
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: AustraliaPosts: 1642 |
![]() Keep safe. Live long and prosper. |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4311 |
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: BelgiumPosts: 255 |
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 |
||||
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |