$PP directive
Purpose: $PP directive causes a preprocessor named bcxpp.dll to be invoked and each succeeding source line to be preprocessed until a second $PP is encountered.
Syntax: $PP' Loads and turns on preprocessor. ' source code here to be preprocessed $PP' Turn off preprocessor. |
The preprocessor is a dynamic link library named bcxpp.dll that is located within the paths that Win32 looks for .dlls. See Win32 SDK help file under "LoadLibrary" for details.
The template(bcxpp.bas) for making a pp dll can be downloaded from the BCX Yahoo Files/BCX_Files section. The pp dll contains one exported procedure called ProcessLine. After processing all directives and just before parsing a line of code, BCX passes the line to the preprocessor for handling as it sees fit. Then the pp passes the line back to BCX which proceeds normally.
Here is a template for a Preprocessor DLL:
'==================================================================== ' BEGIN Preprocessor DLL TEMPLATE '==================================================================== $DLL '==================================================================== ' BCX Preprocessor DLL ' Created by Vic McClung 4/19/2003 ' =================================================================== ' This dll must be in a place where Win32 looks for DLLs. I ' recommend putting it in the /bin folder of BCX. '==================================================================== ' FUNCTION ProcessLine(Src$) AS LONG EXPORT ' put code to preprocess modify Src$ ' Src$ is passed by reference so any changes ' will be returned to BCX for final processing. ' FUNCTION = 1 ' Return 0 means error ' ' Return 2 means to goto ReProcess: label and reprocess line ' END FUNCTION '==================================================================== ' Note: When you arrive here, BCX has already TRIM$(Src$) and processed ' all lines with directives such as $COMMENT, $CCODE, $LIBRARY, etc. If you ' want BCX to run the line back thru from the start, then return 2 and it ' will goto ReProcess label and it will behave just as if it had read the ' line from the source file. Be careful if you do this. In fact, be ' careful when you use the preprocessor, period. ' ' One other thing is worth mentioning, BCX has removed the _ continuation ' characters at the end of lines and concatenated those into one long line ' when this procedure is called. '==================================================================== ' Enums for tokkinds - kinds of tokens ENUM TOK_ERROR, _ ' Error TOK_EOF, _ ' End-Of-File TOK_NL, _ ' Newline TOK_ID, _ ' identifier TOK_NUM, _ ' number TOK_STR, _ ' string literal TOK_OP, _ ' operators TOK_SYM, _ ' symbol TOK_CMT, _ ' comment TOK_INC, _ ' include TOK_META, _ ' meta statement TOK_ILC, _ ' in line 'C' code TOK_LCC, _ ' line continuation char '_' in BASIC TOK_KW, _ ' Keyword TOK_CMD, _ ' Command TOK_FUNC, _ ' built in function TOK_EOL, _ ' End of Line CHR$(0) TOK_LABEL ' label: GLOBAL stack$[512] GLOBAL tokkind[512] AS LONG GLOBAL index AS LONG GLOBAL p AS CHAR PTR GLOBAL token$ FUNCTION ProcessLine(Src$) AS LONG EXPORT LOCAL kind AS LONG, i AS LONG p = Src$ index = 0 DO IF *p = 0 THEN EXIT LOOP token$ = "" kind = getNext() IF kind THEN IF kind = TOK_CMT THEN token$ = MID$(Src$,(p - Src$)) *p = 0 END IF IF kind = TOK_EOL THEN EXIT LOOP END IF stack$[index] = token$ tokkind[index] = kind index++ ELSE ' error Src$ = token$ ' put error message in Src$ to pass back to BCX FUNCTION = 0' return 0 to indicate error! END IF '=============================================================== ' code goes here to process the tokens contained in stack$ array '=============================================================== LOOP '==================================================================== ' Return a zero to throw an error back to BCX and return the error ' message in the Src$ string. Return 2 if you want to run this line ' back thru from the top just remember that you may get it again ' as the next line to process, depends on what line contains. '==================================================================== FUNCTION = 1 END FUNCTION FUNCTION getNext() AS BOOLEAN ' see bcxpp.bas code for parser/tokenizer code END FUNCTION '==================================================================== ' END Preprocessor DLL TEMPLATE '====================================================================
The BCX Preprocessor:
Normally, BCX reads each line from the source file, one line at a time. Before BCX reads the next line, a flurry of stuff happens -- called parsing and tokenizing. If BCX's parser / tokenizer does not understand the line coming in from the BASIC source file, either an error is thrown or bad code is emitted.
The preprocessor is a dynamic link library named bcxpp.dll that is located within the paths that Win32 looks for .dlls. See Win32 SDK help file under "LoadLibrary" for details. Simply put, what the bcxpp.dll does is intercept the line of code coming in from the Basic source file and allows the user to change or modify it to suit and then pass the modifed code back to BCX's parser/tokenizer routines to handle as it would normally.
The bcxpp.dll allows one to introduce new meta-commands, structures,functions, constants, almost anything, and to translate these new(NOT BUILT IN FEATURES) into a format that BCX will accept -before- BCX parser/tokenizer gets a crack at it.
Think of the BCX preprocessor(dll) as a user-defined PLUGIN. The bcxpp.dll is only needed if you try to use the functionality defined inside a bcxpp.dll, otherwise BCX will function without it.
Notes about $PP:
$PP
,
it loads the dll if it can find it. If it cannot find the dll or
cannot locate the
ProcessLine
procedure in the dll, it aborts with
appropriate message. In addition to loading the dll on the first
instance, BCX turns on preprocessing and passes the source code line to
the preprocessor. Each subsequent encounter simple turns the preprocessor on if
off and off if on. The dll is unloaded by BCX upon termination.
STDCALL
directive with
$DLL
.