Building a Select Case to call user functions

Started by kevin, January 31, 2023, 07:37:50 PM

Previous topic - Next topic

kevin

   Here's a #coding concept that's a little more for the advanced PlayBASIC coders to dip into. In this example (Bellow) were going to load some PlayBASIC source code; skim that code for function names that match a particular pattern, then output those function names to build a Select Code statement in source code.

 Why would we do this ?

  Well let's say you want to write simple scripts for your programs where the user can customize your programs behavior by feeding it a list of custom commands. There's all sort of levels to this, but often we just need something simple that will process an input string and call the functions required to perform the operations the user wants..

  Bellow we're focusing on the calling part of the this process, as often it's difficult to maintain part of building your own scripting parser as you have to write this code by hand; which is open to all that's errors. But we can avoid some of those problem by writing a program that will generate the code for us from our list of available functions.


  This PlayBASIC source code contains a function called "Build_Select_Statement" that takes a file name as an argument (in the form of a string). The function opens the file, reads its contents into a string, and closes the file. Then, the function searches for all instances of "function UCF_" in the string and stores each found function name in a list. The function then looks for a specific template function in the string, replaces the placeholder for the list of function names with the actual list, and outputs the modified template function.


 


   This example is a single file example of how you might generate a select case statement from a group of functions.    

   This PlayBASIC code contains a function called "Build_Select_Statement" that takes a file name as an argument (in the form of a string). The function opens the file, reads its contents into a string, and closes the file. Then, the function searches for all instances of "function UCF_" in the string and stores each found function name in a list. The function then looks for a specific template function in the string, replaces the placeholder for the list of function names with the actual list, and outputs the modified template function.

   
 

   NOTES:

          RUN IN DEBUG MODE =  F7 To Run
   
         You need to have saved this example for it run
        


PlayBASIC Code: [Select]
; PROJECT : User Callable Function Parser
; AUTHOR : Kev Picone - PlayBASIC Tutor - Https://playbasic.com
; CREATED : 1/02/2023
; EDITED : 1/02/2023
; ---------------------------------------------------------------------

/*
RUN IN DEBUG MODE = F7 To Run

You need to have saved this example for it run

In this example the generated code is output to the debug
console, in a real world use case you would save it to disk
and use the include directive to import the code into your
project

*/


Build_Select_Statement("main.pba")


Sync
waitkey
end


Function Build_Select_Statement(File$)

// You'd most like have a hand written template
// but
fh=readnewfile(file$)
if fh
RawCode$=readchr$(fh,Filesize(File$))
closefile fh

// End of line in TEXT file / Source code
cr$=chr$(10)+Chr$(13)

// Find the functions that match out pattern
Key$="function"+" UCF_"

// Insert the string that will hold our generated source code
CaseCode$=cr$

// Find the functions that match our key within this source code
LastMatch=0
do
MatchPos = instring(RAwCode$,key$,LastMatch,true)
if MatchPos =0 then exitdo

// Function the brackets after this
Open_Bracket_POs = instring(RawCode$,"(",MatchPos)

if Open_Bracket_POs > MatchPOs

StartPos =MatchPos+Len(Key$)
Name$= mid$(RAwCode$,StartPOS,Open_Bracket_POs-StartPOS)


// Make the SELECT CASE code to catch and call this function
CaseCode$ +=" case "+chr$(34)+upper$(Name$)+chr$(34)+cr$

// Add the prefix to the name
Name$=replace$(Key$,"function ","")+Name$

CaseCode$ +=" "+Name$+"()"+cr$
CaseCode$ +=cr$

else
#print "Errror Missing after function name dude"
endif

LastMatch = MatchPOs+Len(Key$)
loop


// -----------------------------------------------------------------
// Create the caller function from the template example
// -----------------------------------------------------------------

Pos =instring(RAwCode$,"Function"+" TEMPLATE_CALL_UCF_FUNCTION",0,1)
if Pos>0
EndPos =instring(RAwCode$,"//END OF TEMPLATE",pos,true)
if EndPos>pos
CustomFunction$ = mid$(RawCode$,Pos,EndPOS-pos)

// Remove the TEMPLATE from the function name
CustomFunction$ = replace$(CustomFunction$,"Function TEMPLATE_","Function ")

// insert the CASES
CustomFunction$ = replace$(CustomFunction$,"//[INSERT CASES HERE]",CaseCode$)


// DUMP the Generate CODE TO THE DEBUG CONSOLE
#print CustomFunction$



endif
endif
endif

EndFunction



// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------
// -------------------------------------------------------------------


Function TEMPLATE_CALL_UCF_FUNCTION(Opcode$)

Select upper$(OPcode$)

//[INSERT CASES HERE]

EndSelect

EndFunction
//END OF TEMPLATE





// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------->> FUNCTION LIBRARY <<-------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

function UCF_RedTEXT()
EndFunction

function UCF_GreenTEXT()
EndFunction

function UCF_BlueTEXT()
EndFunction

function UCF_CLS()
EndFunction









 Given an input file of the following PlayBASIC source code



// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------->> FUNCTION LIBRARY <<-------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

function UCF_RedTEXT()
EndFunction

function UCF_GreenTEXT()
EndFunction

function UCF_BlueTEXT()
EndFunction

function UCF_CLS()
EndFunction








  This example creates


PlayBASIC Code: [Select]
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// EXAMPLE OF THE CREATED CALLER FUNCTION
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------


Function CALL_UCF_FUNCTION(Opcode$)

Select upper$(OPcode$)



case "REDTEXT"

UCF_RedTEXT()


case "GREENTEXT"

UCF_GreenTEXT()


case "BLUETEXT"

UCF_BlueTEXT()


case "CLS"

UCF_CLS()




EndSelect

EndFunction






Related PlayBASIC Source Code Examples

 - PlayBASIC (CLASSIC) Project Loader / Source Merger Functions

  - PLayBASIC Documentation: - See CallFunction