Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 16:58 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: MMBasic Transpiler

     Page 2 of 2    
Author Message
thwill

Guru

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

  JohnS said  Often called a call tree.


In which case, yes my code would be a potential starting point for that and I'll add it to my ideas list. However if you want something soon then you are probably out of luck.

Regards,

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: 01:35pm 31 Jul 2020
Copy link to clipboard 
Print this post

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


Correct.

  Quote  Beware recursion...


Right you are. No recursion, though, in the programs I'm looking at.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
thwill

Guru

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

I've been looking some more and I don't think it's as difficult as I first thought:

- Enumerate all functions and subroutines
- For each build a list of identifiers they reference
- Eliminate from each list any identifier that doesn't match a function or subroutine
- Print, but "beware of recursion"

If the wife and kids let me I'll take a look this weekend.

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: 10:26pm 03 Aug 2020
Copy link to clipboard 
Print this post

"lizby" is this the sort of output you were looking for:

*GLOBAL* <main.bas 1>
   list_init <../common/list.inc 6>
       list_clear <../common/list.inc 11>
   main <main.bas 43>
       cendl <main.bas 26>
       cerror <main.bas 36>
       cl_parse <cmdline.inc 6>
           cl_usage <cmdline.inc 61>
           cl_version <cmdline.inc 72>
           lx_option$ <../sptrans/lexer.inc 364>
               lx_token$ <../sptrans/lexer.inc 248>
           lx_parse_command_line <../sptrans/lexer.inc 311>
               lx_advance <../sptrans/lexer.inc 83>
               lx_parse_comment_or_directive <../sptrans/lexer.inc 175>
                   lx_parse_comment <../sptrans/lexer.inc 192>
                       lx_store <../sptrans/lexer.inc 136>
                   lx_parse_directive <../sptrans/lexer.inc 183>
                       lx_advance <../sptrans/lexer.inc 83>
                       lx_advance_while <../sptrans/lexer.inc 144>
                           lx_advance <../sptrans/lexer.inc 83>
                       lx_store <../sptrans/lexer.inc 136>
               lx_parse_keyword <../sptrans/lexer.inc 211>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_is_keyword <../sptrans/lexer.inc 224>
                       set_get <../common/set.inc 33>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_number <../sptrans/lexer.inc 101>
                   lx_parse_binary <../sptrans/lexer.inc 148>
                       lx_advance <../sptrans/lexer.inc 83>
                       lx_advance_while <../sptrans/lexer.inc 144>
                           lx_advance <../sptrans/lexer.inc 83>
                       lx_store <../sptrans/lexer.inc 136>
                   lx_parse_decimal <../sptrans/lexer.inc 117>
                       lx_advance <../sptrans/lexer.inc 83>
                       lx_advance_while <../sptrans/lexer.inc 144>
                           lx_advance <../sptrans/lexer.inc 83>
                       lx_store <../sptrans/lexer.inc 136>
                   lx_parse_hexadecimal <../sptrans/lexer.inc 157>
                       lx_advance <../sptrans/lexer.inc 83>
                       lx_advance_while <../sptrans/lexer.inc 144>
                           lx_advance <../sptrans/lexer.inc 83>
                       lx_store <../sptrans/lexer.inc 136>
                   lx_parse_octal <../sptrans/lexer.inc 166>
                       lx_advance <../sptrans/lexer.inc 83>
                       lx_advance_while <../sptrans/lexer.inc 144>
                           lx_advance <../sptrans/lexer.inc 83>
                       lx_store <../sptrans/lexer.inc 136>
               lx_parse_option <../sptrans/lexer.inc 336>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_string <../sptrans/lexer.inc 197>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_until <../sptrans/lexer.inc 207>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_symbol <../sptrans/lexer.inc 228>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_reset_globals <../sptrans/lexer.inc 68>
           lx_string$ <../sptrans/lexer.inc 272>
               lx_token$ <../sptrans/lexer.inc 248>
           lx_token$ <../sptrans/lexer.inc 248>
           op_set <options.inc 14>
               op_set_infile <options.inc 26>
               op_set_outfile <options.inc 30>
       cl_usage <cmdline.inc 61>
       cout <main.bas 31>
       fi_exists <../common/file.inc 80>
           fi_get_canonical$ <../common/file.inc 43>
               fi_is_absolute <../common/file.inc 33>
               list_init <../common/list.inc 6>
                   list_clear <../common/list.inc 11>
               list_remove <../common/list.inc 36>
               str_join$ <../common/string.inc 22>
               str_tokenise <../common/string.inc 5>
       generate <process.inc 181>
           map_get$ <../common/map.inc 51>
               set_get <../common/set.inc 33>
       handle_eof <main.bas 118>
           cout <main.bas 31>
           in_close <../sptrans/input.inc 29>
               list_pop$ <../common/list.inc 47>
       handle_include <main.bas 106>
           cendl <main.bas 26>
           cout <main.bas 31>
           in_open <../sptrans/input.inc 10>
               fi_exists <../common/file.inc 80>
                   fi_get_canonical$ <../common/file.inc 43>
                       fi_is_absolute <../common/file.inc 33>
                       list_init <../common/list.inc 6>
                           list_clear <../common/list.inc 11>
                       list_remove <../common/list.inc 36>
                       str_join$ <../common/string.inc 22>
                       str_tokenise <../common/string.inc 5>
               fi_get_parent$ <../common/file.inc 6>
               fi_is_absolute <../common/file.inc 33>
               list_push <../common/list.inc 53>
           lx_string$ <../sptrans/lexer.inc 272>
               lx_token$ <../sptrans/lexer.inc 248>
       in_open <../sptrans/input.inc 10>
           fi_exists <../common/file.inc 80>
               fi_get_canonical$ <../common/file.inc 43>
                   fi_is_absolute <../common/file.inc 33>
                   list_init <../common/list.inc 6>
                       list_clear <../common/list.inc 11>
                   list_remove <../common/list.inc 36>
                   str_join$ <../common/string.inc 22>
                   str_tokenise <../common/string.inc 5>
           fi_get_parent$ <../common/file.inc 6>
           fi_is_absolute <../common/file.inc 33>
           list_push <../common/list.inc 53>
       in_readln$ <../sptrans/input.inc 34>
       lx_load_keywords <../sptrans/lexer.inc 30>
           set_put <../common/set.inc 21>
               set_get <../common/set.inc 33>
       lx_parse_basic <../sptrans/lexer.inc 45>
           lx_advance <../sptrans/lexer.inc 83>
           lx_parse_comment_or_directive <../sptrans/lexer.inc 175>
               lx_parse_comment <../sptrans/lexer.inc 192>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_directive <../sptrans/lexer.inc 183>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
           lx_parse_keyword <../sptrans/lexer.inc 211>
               lx_advance <../sptrans/lexer.inc 83>
               lx_advance_while <../sptrans/lexer.inc 144>
                   lx_advance <../sptrans/lexer.inc 83>
               lx_is_keyword <../sptrans/lexer.inc 224>
                   set_get <../common/set.inc 33>
               lx_store <../sptrans/lexer.inc 136>
           lx_parse_number <../sptrans/lexer.inc 101>
               lx_parse_binary <../sptrans/lexer.inc 148>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_decimal <../sptrans/lexer.inc 117>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_hexadecimal <../sptrans/lexer.inc 157>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
               lx_parse_octal <../sptrans/lexer.inc 166>
                   lx_advance <../sptrans/lexer.inc 83>
                   lx_advance_while <../sptrans/lexer.inc 144>
                       lx_advance <../sptrans/lexer.inc 83>
                   lx_store <../sptrans/lexer.inc 136>
           lx_parse_string <../sptrans/lexer.inc 197>
               lx_advance <../sptrans/lexer.inc 83>
               lx_advance_until <../sptrans/lexer.inc 207>
                   lx_advance <../sptrans/lexer.inc 83>
               lx_store <../sptrans/lexer.inc 136>
           lx_parse_symbol <../sptrans/lexer.inc 228>
               lx_advance <../sptrans/lexer.inc 83>
               lx_store <../sptrans/lexer.inc 136>
           lx_reset_globals <../sptrans/lexer.inc 68>
       lx_token_lc$ <../sptrans/lexer.inc 257>
           lx_token$ <../sptrans/lexer.inc 248>
       op_init <options.inc 6>
       out_close <../sptrans/output.inc 14>
       out_open <../sptrans/output.inc 7>
       pass1_completed <process.inc 55>
           init_current_calls_set <process.inc 103>
               set_init <../common/set.inc 6>
                   set_clear <../common/set.inc 12>
           init_global_calls_set <process.inc 97>
               set_init <../common/set.inc 6>
                   set_clear <../common/set.inc 12>
           init_subs_map <process.inc 69>
               map_init <../common/map.inc 6>
                   map_clear <../common/map.inc 12>
               map_put <../common/map.inc 22>
                   map_sort <../common/map.inc 34>
                   set_get <../common/set.inc 33>
       pass2_completed <process.inc 150>
           pass2_sub_end <process.inc 132>
               map_get$ <../common/map.inc 51>
                   set_get <../common/set.inc 33>
               map_put <../common/map.inc 22>
                   map_sort <../common/map.inc 34>
                   set_get <../common/set.inc 33>
               set_clear <../common/set.inc 12>
       process <process.inc 18>
           lx_token$ <../sptrans/lexer.inc 248>
           lx_token_lc$ <../sptrans/lexer.inc 257>
               lx_token$ <../sptrans/lexer.inc 248>
           pass1_sub_begin <process.inc 45>
           pass2_identifier <process.inc 112>
               lx_token_lc$ <../sptrans/lexer.inc 257>
                   lx_token$ <../sptrans/lexer.inc 248>
               map_get$ <../common/map.inc 51>
                   set_get <../common/set.inc 33>
               set_put <../common/set.inc 21>
                   set_get <../common/set.inc 33>
           pass2_sub_end <process.inc 132>
               map_get$ <../common/map.inc 51>
                   set_get <../common/set.inc 33>
               map_put <../common/map.inc 22>
                   map_sort <../common/map.inc 34>
                   set_get <../common/set.inc 33>
               set_clear <../common/set.inc 12>
   set_init <../common/set.inc 6>
       set_clear <../common/set.inc 12>


This is the output from running my current code on itself, the values in <> are the file and line number declaring the csub/function/sub.

Regards,

Tom
Edited 2020-08-04 08:32 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 11:00pm 03 Aug 2020
Copy link to clipboard 
Print this post

Looks good, thanks. I'd probably want to use a flag to turn of the "<>", since I don't usually have include files.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 09:20am 04 Aug 2020
Copy link to clipboard 
Print this post

  lizby said  Looks good, thanks. I'd probably want to use a flag to turn of the "<>", since I don't usually have include files.


OK, I can probably identify when only a single file is analysed and automatically omit them.

Would you still want the output to include the references to the line number containing the declaration ?

I'm still several days away from making the code available, need to: handle recursion, find/fix at least one bug (it gives no output when run against Z-MIM) and tidy up the output side.

Regards,

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:28pm 04 Aug 2020
Copy link to clipboard 
Print this post

Tom -- the line number reference looks useful.

By "handle recursion" do you mean something like when you've found that a SUB/FUNCTION calls something which has already been called in the same branch of the call tree, you output something like "** Recursion to ? **" and cease following the chain?
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:30pm 04 Aug 2020
Copy link to clipboard 
Print this post

  lizby said  Tom -- the line number reference looks useful.

By "handle recursion" do you mean something like when you've found that a SUB/FUNCTION calls something which has already been called in the same branch of the call tree, you output something like "** Recursion to ? **" and cease following the chain?


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

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 04:53pm 18 Aug 2020
Copy link to clipboard 
Print this post

OK, it's been a trial but I think the next beta is ready:

Release 1b2:
- The package has been renamed to "SP Tools" and the GitHub address changed
  correspondingly: https://github.com/thwill1000/sptools

  It currently consists of 3 programs:

    spflow  - Generates graph of function/subroutine dependencies for MMBasic.

    sptest  - Unit-test framework for MMBasic,
              * rudimentary at the moment and requires Option Base 0.

    sptrans - Transpiler and code-formatter for MMBasic.
              * code-formatting is ropey as I've found out trying to use it
                on the "Welcome Tape" project.

- sptrans: Increased maximum number of tokens supported per line from
           50 => 100.
- sptrans: Added support for identifiers with ! or % suffixes; $ was already
           supported.


Read more here: https://github.com/thwill1000/sptools/blob/master/README.md

Download here: https://github.com/thwill1000/sptools/releases/download/r1b2/sptools-r1b2.zip

The vocies in my head are telling me I've cocked this release up in some fashion, so I'll be interested to hear how

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
     Page 2 of 2    
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