Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 15:36 04 Jul 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 : MM & uMM: Crunch v3.1

Author Message
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 07:30pm 11 Jan 2015
Copy link to clipboard 
Print this post

I have updated CRUNCH.BAS to support code written for the uMite MkII. Apart from adding the uMite's unique commands and functions, it now supports the revised rules for defining variables i.e. two new type suffixes (% for integer and ! for Float) and no two variables can have the same name (previously A and A$ were separate variables).

I have tested it under DOS 4.5 in a laptop under Win7 and MMBasic 4.5 on a Mono Maximite but I don't have a uMite and would appreciate it if someone would try it and let me know if there are any problems.

You can dowload the code here.

Briefly, Crunch will reduce the code size of a program on any MMBasic variant by making the code more compact. It will also give a small performance improvement in most cases. To accomplish this, it:
- removes all comments and unnecessary lines, spaces and tabs.
- replaces all variable names, labels, Sub names and Function names with one or two character names.

To execute it either:
- type at the prompt Crunch <inputFileName[.bas]> <outputFileName[.bas]>
e.g Crunch Hearts uHearts
- or update Crunch.dat with input and output file names

Note that:
- Input and Output Filenames don't need the extension. .BAS is assumed.
- Output filename cannot be the same as input.
- You cannot run Crunch on the uMite; only on DOS, Mono or Colour MaxiMite, MiniMite or equivalent.
- The resulting Crunched code should run successfully on the device for which it was coded. i.e. this version of Crunch not only supports uMite but all the other Mite variants. (I assume that these new rules will be incorporated in future versions of MMBasic.)
- Don't discard the original code; the Crunched code will be very difficult to decipher as the names of everything will have changed other than key (reserved) words, numbers and quoted strings.

Options:
You can add one or more switches after the OutputFileName, in any order, in both the command and the Crunch.dat record:
/B suppresses removal of unnecessary blanks and tabs in the code.
/C suppresses removal of comments and blank lines
/F suppresses replacement of Function and Subroutine names.
/L suppresses replacement of Label names.
/P pauses the listing at a pageful and awaits any key press before continuing.
/T sets Testing=True within both Crunch.bas and CrunchA.bas (used for debugging). /T also prevents temporary files from being deleted. CrunchSV.tmp is particularly useful as it is a sorted list of new vs old name.

Cheers,
Hugh

 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 12:23am 12 Jan 2015
Copy link to clipboard 
Print this post

Hi Hugh

I tried this on one of my graphics routines and it mangles the Cfunctions. These need to be special cased out of the crunch.

I've attached an example of the problem code.

2015-01-12_102255_st7920.zip

Best regards

Peter
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 11:24am 12 Jan 2015
Copy link to clipboard 
Print this post

Peter. How silly of me. I completely overlooked CFunction code. My apologies and thanks for your example.
Cheers,
Hugh
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 03:37pm 12 Jan 2015
Copy link to clipboard 
Print this post

Peter,
I have asked Crunch to copy unchanged, everything appearing between CFUNCTION xxx and END CFUNCTION other than blank lines and comments. It also shifts the lines of hex codes to the left margin. If these edits upset the code, let me know.

You can download the updated version here. (Now including all of the Crunch suite files)

If you would like to try it again, Peter, I would greatly appreciate it. My test of your sample file has reduced it from 45KB to 35KB (a bit over 20% reduction). Whether that gives you a performance improvement, only you can tell.

Cheers,
Hugh

 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 11:07pm 12 Jan 2015
Copy link to clipboard 
Print this post

Hugh

The code is also breaking &H, &B literals. If you run it on the code I attached it creates an error on line 32

The Cfunctions look OK but it didn't get that far to check fully.

Best Regards

PeterEdited by matherp 2015-01-14
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 11:35pm 12 Jan 2015
Copy link to clipboard 
Print this post

Hugh, re CFunctions, you can remove any leading and trailing white space from the hex lines, and replace any multiple white spaces with single white space which separate the 8 digit hex opcodes. (CFuncGen only ever uses single white space).

Peter
The only Konstant is Change
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 12:28pm 13 Jan 2015
Copy link to clipboard 
Print this post

@matherp and G8JCF
Peter and Peter,
Thanks for your input. I will investigate the &H and &B problem (most likely &anything). It may be a few days before I have a chance to look at it... this end of the week is busy (perhaps I ought to go back to work - I seem to be busier than ever in retirement!!)
Cheers
Hugh
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 01:44pm 13 Jan 2015
Copy link to clipboard 
Print this post

@matherp
Ahh-Haa!! Not having used them in my own code, I hadn't considered testing for Binary, Hex or Octal constants. It does now.
I have looked through the result of crunching the first 250-odd lines of your source code and it all looks reasonable, but the final arbiter, as always, is does the crunched code work?

Updated version is 2015-01-13_234204_Crunch3.1.zip

Cheers,
Hugh
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10195
Posted: 10:42pm 13 Jan 2015
Copy link to clipboard 
Print this post

SPOKE TOO SOON

lines 104,107,110,112 115, 121, 133, 145 of the crunched code are corrupted IF statements.

IF( has been replaced by W(

editing these and the program does then work perfectly

rgds

Peter

____________________________________________________________ __________

Hugh

Works great now.

Results:
Your Crunch: memory used 34K, cfunctions 12K, free 14K
MMedit autocrunch: memory used 38k, cfunctions 12K, free 10K

Great work

There is one further refinement that could save even more space:

I use definitions like:
Dim integer i
dim i as integer

and subroutine and functions:
sub mysub(i as integer)
function myfunc(i as integer)as integer

You could get rid of all the "integer" and "as integer" (same for string and float) and replace with variable suffixes: i%, i$ and i!

This isn't guaranteed to save space but will save quite a lot in nearly all cases.

You would need to special case the OPTION DEFAULT statement

Thanks again - I will certainly be using your code.

Peter
Edited by matherp 2015-01-15
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 01:42am 14 Jan 2015
Copy link to clipboard 
Print this post

@matherp,
Yes, I can see why "IF(" would be misinterpreted by Crunch's find variables routine and I am sure it is quite valid code, but why would you put the test in brackets? I have never seen anyone do that before. I live and learn!
Easily fixed by adding IF( as a reserved word to the list in Cmd.txt and then running KEYWORDS.bas

Result: 2015-01-14_113135_Crunch3.1.zip

Edit: 14/1/2015
Actually, there is a perfectly valid case for an open bracket following an IF as in
IF(a+b)/c=d THEN
End Edit

As for the different ways of defining variables which may save space, I will look at them, however I doubt if they will do much as I am sure MMBasic replaces them with tokens. Nevertheless I will have a go at implementing your suggestion and see if there is any gain.

The next thing I have been meaning to do is to compact the code further by concatenating lines into multi-statement lines where possible. This may give us a greater performance improvement as labels and Sub/Function names will come closer to the start of code in memory.

Many thanks for testing the code. I couldn't have done it without you and I am sure others will be grateful for your time and effort.
Cheers,
Hugh

p.s. Geoff. You might like to comment on whether the above suggestions are likely to have any significant effect on size and performance.Edited by shoebuckle 2015-01-15
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 01:04pm 14 Jan 2015
Copy link to clipboard 
Print this post

  shoebuckle said  The next thing I have been meaning to do is to compact the code further by concatenating lines into multi-statement lines where possible. This may give us a greater performance improvement as labels and Sub/Function names will come closer to the start of code in memory.


A newline uses four bytes of memory whereas a statement separator uses two bytes, so you will save a little memory by joining lines together.

However, MMBasic caches sub/function and label locations so that it can jump direct to the item rather than having to search the program, so moving them closer to the start of the program will not affect performance.

Geoff
Geoff Graham - http://geoffg.net
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 01:10pm 14 Jan 2015
Copy link to clipboard 
Print this post

Good work Hugh.
I am still resisting the temptation to go the extra step in MMEdit.

One other small improvement I considered is removing variables/constants that are only referred to once.

When it's a list of defines, it is relatively easy but there are places when removing the variable is probably not do-able.

Peters test code has a few of the difficult ones:
  Quote  Variables which are only refered to in one line:
J 135
LCD_of 165
LCD_PIX 173
LCD_DRAWCHAR 173
i% 203
colour 227
LCD.CRect Sub 344


I think I will work on a simpler means of calling your program from MMEdit....

Jim
VK7JH
MMedit
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 02:51pm 14 Jan 2015
Copy link to clipboard 
Print this post

I just did some tests using ALPHANUM (in MMLib) on a Mono MM under MMBasic v4.5 to which I added a timer and printed MEMORY on completion. The three sets of numbers represent:
- the program in its Original form
- Crunched using the latest version of Crunch (posted above)
- Crunched and Compacted into 255 character (max) multi-statement lines

. Original Crunched Compacted
-------- -------- ---------
Time 233,461 179,736 23%saving 166,441 29% saving
Program 13KB 16% 446 lines 4KB 5% 271 lines 3KB 4% 32 lines
Variables 6KB 7% 43 vars same same
General 1KB 1% same same
Free 66KB 76% 75KB 87% 76KB 88%


Results will vary by program but you can see that Crunch improves performance of ALPHANUM.BAS by almost 25% and creating multi-statement lines gives an extra 6% gain. (The input text doc was 261KB.)

Size is a bit more dramatic with crunch. The reduction in size of Compacted over Crunched is probably only approx 500B which has taken it below the next 1KB threshold. (See Geoff's post above.)
Variable and General storage isn't altered by crunching the code.

The performance and size gain of compaction may be important for some projects so I will incorporate it but I am reluctant to alter the subject source code in any other way. It looks like a minefield and the gain may be minimal.

There are only 4 rules for compaction that I am aware of, over and above crunching:
- No Command or Function may overflow onto the next line.
- A label must start on a new line.
- A new line must be started after a single-line IF. i.e. IF expr THEN statement [ELSE statement]
- A new line must be started after a comment.

Cheers,
Hugh
Edited by shoebuckle 2015-01-16
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 03:01pm 14 Jan 2015
Copy link to clipboard 
Print this post

  Geoffg said   A newline uses four bytes of memory whereas a statement separator uses two bytes, so you will save a little memory by joining lines together.

However, MMBasic caches sub/function and label locations so that it can jump direct to the item rather than having to search the program, so moving them closer to the start of the program will not affect performance.

Geoff


Thanks Geoff

One other question. Tests seem to indicate that FUNCTION xxx and SUB xxx do not need to start on a new line. Is this safe?

Cheers,
Hugh
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3282
Posted: 04:51pm 14 Jan 2015
Copy link to clipboard 
Print this post

Yes, they can come after a statement separator (:) as well as on a new line.
Geoff Graham - http://geoffg.net
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 07:47pm 14 Jan 2015
Copy link to clipboard 
Print this post

  Geoffg said   Yes, they can come after a statement separator (:) as well as on a new line.

Thanks Geoff.
Hugh
 
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