Last active
February 18, 2017 19:33
-
-
Save Varriount/42643edc4e817f767251bd4c75d58c22 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The below code is not valid C code - a preprocessor must be used: | |
``` | |
CHAKRA_API | |
JsParseModuleSource( | |
_In_ JsModuleRecord requestModule, | |
_In_ JsSourceContext sourceContext, | |
_In_ BYTE* script, | |
_In_ unsigned int scriptLength, | |
_In_ JsParseModuleSourceFlags sourceFlag, | |
_Outptr_result_maybenull_ JsValueRef* exceptionValueRef); | |
``` | |
`CHAKRA_API`, `_In_`, and `_Outptr_result_maybenull_` are all macros. They *might* be defined like below: | |
``` | |
#define CHAKRA_API __declspec(dllexport) void | |
#define _In_ | |
#define _Outptr_result_maybenull_ | |
``` | |
The problem with the above macros is that C2Nim normally tries turning such macros into Nim templates. | |
Nim templates are not equivalent to C macros however, and only a subset of C macros can be converted. | |
Additionally, even if a macro can be converted, it's not always used in a way that can be translated to Nim. | |
C2Nim would attempt such a translation, and fail. | |
``` | |
template _In_(): expr = | |
discard | |
template _Outptr_result_maybenull_(): expr = | |
discard | |
template CHAKRA_API(): | |
??? # C2Nim: "I don't know how to turn declspec into valid Nim code!" | |
``` | |
Even if the translation of the macros succeeded, the macros usage couldn't be translated: | |
``` | |
# Not valid Nim code! | |
proc JsParseModuleSource*( | |
_In_() JsModuleRecord requestModule, | |
_In_() JsSourceContext sourceContext, | |
_In_() ptr Byte script, | |
_In_() unsigned int scriptLength, | |
_In_() JsParseModuleSourceFlags sourceFlag, | |
_Outptr_result_maybenull_() ptr JsValueRef exceptionValueRef | |
): CHAKRA_API() | |
``` | |
The solution to the above problems is a C2Nim-specific preprocessor macro, `#def`. | |
`#def` does what a `#define` in C does - performs exact replacement. | |
When translating a file, you replace `#define` with `#def` for any macros that are 'odd' (can't be translated). | |
Thus, the code | |
``` | |
#def CHAKRA_API __declspec(dllexport) void | |
#def _In_ | |
#def _Outptr_result_maybenull_ | |
CHAKRA_API | |
JsParseModuleSource( | |
_In_ JsModuleRecord requestModule, | |
_In_ JsSourceContext sourceContext, | |
_In_ BYTE* script, | |
_In_ unsigned int scriptLength, | |
_In_ JsParseModuleSourceFlags sourceFlag, | |
_Outptr_result_maybenull_ JsValueRef* exceptionValueRef); | |
) | |
``` | |
gets turned into the C code | |
``` | |
__declspec(dllexport) void | |
JsParseModuleSource( | |
JsModuleRecord requestModule, | |
JsSourceContext sourceContext, | |
BYTE* script, | |
unsigned int scriptLength, | |
JsParseModuleSourceFlags sourceFlag, | |
JsValueRef* exceptionValueRef); | |
``` | |
Unfortunately, we still have a problem! C2Nim doesn't know how to translate `__declspec(dllexport)`. | |
For this, we have to modify the source, and define `CHAKRA_API` as the blank macro `#def CHAKRA_API`. | |
``` | |
#def CHAKRA_API void | |
#def _In_ | |
#def _Outptr_result_maybenull_ | |
CHAKRA_API | |
JsParseModuleSource( | |
_In_ JsModuleRecord requestModule, | |
_In_ JsSourceContext sourceContext, | |
_In_ BYTE* script, | |
_In_ unsigned int scriptLength, | |
_In_ JsParseModuleSourceFlags sourceFlag, | |
_Outptr_result_maybenull_ JsValueRef* exceptionValueRef); | |
``` | |
Gets turned into the C code | |
``` | |
JsParseModuleSource( | |
JsModuleRecord requestModule, | |
JsSourceContext sourceContext, | |
BYTE* script, | |
unsigned int scriptLength, | |
JsParseModuleSourceFlags sourceFlag, | |
JsValueRef* exceptionValueRef); | |
``` | |
Which gets turned into the Nim code | |
``` | |
proc JsParseModuleSource*( | |
JsModuleRecord requestModule, | |
JsSourceContext sourceContext, | |
ptr Byte script, | |
unsigned int scriptLength, | |
JsParseModuleSourceFlags sourceFlag, | |
ptr JsValueRef exceptionValueRef | |
): void | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment