BCX allows you to pass inline C code using the exclamation mark (!) as an operator.
Syntax:! /* C statement goes here */ |
When ! is used outside of a BCX FUNCTION or SUB procedure, the emitted C code is located in the main function of the C translation.
The following sample shows how to create a C coded local DWORD variable.
PRINT GetMachineName$() FUNCTION GetMachineName$ LOCAL A$ ! DWORD b; /* allocate a local variable in C and include C comments! */ b = 256 GetComputerName(A$, &b) ' the & operator means "PASS THE ADDRESS" of b FUNCTION = A$ END FUNCTION
BCX allows you to pass inline C code using a $CCODE directive placed before and after the C code.
Syntax:$CCODE /* C statements go here */ $CCODE |
When $CCODE ... $CCODE is used outside of a BCX FUNCTION or SUB procedure, the emitted C code is located in the main function of the C translation.
PRINT "BCX Code Here." $CCODE // declare the variables: int nNumber; int *pPointer; // now, give a value to them: nNumber = 15; pPointer = &nNumber; // print out the value of nNumber: printf("nNumber is equal to : %d\n", nNumber); // now, alter nNumber through pPointer: *pPointer = 25; // prove that nNumber has changed as a result of the above // by printing its value again: printf("nNumber is equal to : %d\n", nNumber); $CCODE PRINT "BCX Code Here."
BCX Code Here. nNumber is equal to : 15 nNumber is equal to : 25 BCX Code Here.
When the $CCODE HEADER directive is used, everything sandwiched between the $CCODE HEADER and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User Defined Constants' section. $CCODE HEADER is useful, particularly, for inlined C source pragma statements.
Syntax:$CCODE HEADER /* C statements go here */ $CCODE |
$CCODE HEADER #if VERSION == 1 #define INCFILE "vers1.h" #elif VERSION == 2 #define INCFILE "vers2.h" // and so on #else #define INCFILE "versN.h" #endif #include INCFILE $CCODE
When the $CCODE ENUM directive is used, everything sandwiched between the $CCODE ENUM and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User's GLOBAL Enumerations' section.
Syntax:$CCODE ENUM /* C statements go here */ $CCODE |
$CCODE ENUM enum a{a=100,b,c,d=200,e,f}; $CCODE PRINT a, b, c, d, e, f
100 101 102 200 201 202
When the $CCODE CONST directive is used, everything sandwiched between the $CCODE CONST and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User Defined Constants' section.
Syntax:$CCODE CONST /* C statements go here */ $CCODE |
When the $CCODE UDT directive is used, everything sandwiched between the $CCODE UDT and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User Defined Types And Unions' section.
Syntax:$CCODE UDT /* C statements go here */ $CCODE |
For $CCODE CONST and $CCODE UDT.
$CCODE CONST #define QWERTY_CLASS struct _QWERTY* $CCODE $CCODE UDT typedef struct _QWERTY { int a; float b; char c[80]; } QWERTY, *LPQWERTY; $CCODE GLOBAL MyType [10,10,10] AS QWERTY MyType [2,3,4].a = 1 MyType [2,3,4].b! = 2.345 MyType [2,3,4].c$ = "hello world from a poly-dimensional udt!" PRINT MyType[2,3,4].a PRINT MyType[2,3,4].b! PRINT UCASE$(MyType[2,3,4].c$)
1 2.345 HELLO WORLD FROM A POLY-DIMENSIONAL UDT!
When the $CCODE SET directive is used, everything sandwiched between the $CCODE SET and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User's GLOBAL SET Statements' section.
Syntax:$CCODE SET /* C statements go here */ $CCODE |
TYPE foo A AS INTEGER B AS INTEGER C AS BYTE END TYPE $CCODE SET static foo MyFoo[]= { {12,13}, {19,20} }; $CCODE ? MyFoo[0].A ? MyFoo[0].B ? MyFoo[0].C ? MyFoo[1].A ? MyFoo[1].B ? MyFoo[1].C
12 13 0 19 20 0
$CCODE FUNCSUB is used to enclose a complete C code procedure.
When the $CCODE FUNCSUB directive is used, everything sandwiched between the $CCODE FUNCSUB and the terminating $CCODE statements is placed at the file scope level of the emitted C source in the 'User's C code' section.
A prototype is not needed in this case because the placement in the emitted C source is before the main procedure.
Syntax:$CCODE FUNCSUB /* C statements go here */ $CCODE |
DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM $CCODE FUNCSUB char* Remove_All_White_Space(char* str1) { char *obuf,*nbuf; if (str1) { for (obuf=str1,nbuf=str1;*obuf; ++obuf) { if (!isspace(*obuf)) *nbuf++=*obuf; } *nbuf=0; } return str1; } $CCODE
The top to bottom order of placement of the C code translated from the $CCODE directives is
The $HEADER directive works like $CCODE except everything sandwiched between two $HEADER statements is placed at the file scope level of the emitted C source. $HEADER is useful particularly for pragma statements and declaring prototypes for inlined C source functions. A $HEADER directive is placed before and after the C code.
Syntax:$HEADER /* C statements go here */ $HEADER |
$HEADER #define KitchenSinkIsIncluded $HEADER $HEADER #ifndef KitchenSinkIsIncluded #include <KitchenSink.h> #else #define CallThePlumber 1 #endif $HEADER
The $CPROTO directive is used for declaring prototypes for inlined C source functions.
Syntax 1:$CPROTO ! ProcedureDataType ProcedureName(ParameterDataType); |
When using $CPROTO with a C language
prototype, a space-exclamation mark-space must precede the
prototype. Also remember, that in C , a
semicolon is required at the end of of the prototype.
Everything following the $CPROTO ! is
placed at the file scope level of the emitted C source in the 'User's Prototypes' section.
$CPROTO ! char* Remove_All_White_Space(char*); DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM $CCODE char* Remove_All_White_Space(char* str1) { char *obuf,*nbuf; if (str1) { for (obuf=str1,nbuf=str1;*obuf; ++obuf) { if (!isspace(*obuf)) *nbuf++=*obuf; } *nbuf=0; } return str1; } $CCODE
Syntax 2:$CPROTO [FUNCTION/SUB] Foo$(a%, b$) |
$CPROTO, also, will accept a BCX FUNCTION or SUB declaration which will be translated to C code and placed correctly in the 'User Prototypes' section of the C translation.
$CPROTO FUNCTION Remove_All_White_Space$ (a$) DIM a$ DIM b$ a$ = " this is a test " b$ = Remove_All_White_Space(a$) PRINT b$ END PROGRAM ! char* Remove_All_White_Space(char* str1) ! { ! char *obuf,*nbuf; ! if (str1) ! { ! for (obuf=str1,nbuf=str1;*obuf; ! ++obuf) ! { ! if (!isspace(*obuf)) ! *nbuf++=*obuf; ! } ! *nbuf=0; ! } ! return str1; ! }
The $PRAGMA directive is translated to the C keyword #pragma. The utility and syntax varies between compilers for the #pragma directives.
Syntax:$PRAGMA compiler specific instruction and arguments |
To include the Dwmapi.lib library to a code compilation using Microsoft or Pelles C, use this
$PRAGMA comment(LIB, "Dwmapi.lib")
Details for using pragma directives with the Microsoft compiler are available on their Microsoft Pragma directives and the __pragma and _Pragma keywords page.
Here is a snippet of code from the BCX translator which shows how $PRAGMA is used to suppress a MinGW compiler generated warning. A $PRAGMA "diagnostic ignored" is placed immediately before the cast to CPP_FARPROC that causes the warning. The $PRAGMA "diagnosic pop" restores the diagnostics to their previous condition.
$IFDEF (__GNUC__) $PRAGMA GCC diagnostic ignored "-Wcast-function-type" PPProc = (CPP_FARPROC) GetProcAddress(PPDLL_HANDLE,"ProcessLine"); $PRAGMA GCC diagnostic pop $ELSE PPProc = (CPP_FARPROC) GetProcAddress(PPDLL_HANDLE,"ProcessLine"); $ENDIF