diff --git a/%5BWIP%5D-External-Libraries.md b/%5BWIP%5D-External-Libraries.md index 0814de2..47f8861 100644 --- a/%5BWIP%5D-External-Libraries.md +++ b/%5BWIP%5D-External-Libraries.md @@ -8,10 +8,79 @@ Our ground syntax will be `call !Example_GreetUser $username &greet` ## C code First, import `groundext.h`. Then, start a new function. For our example, we will call it `greetUser`. ```c -#include +#include "groundext.h" GroundValue greetUser(GroundScope* scope, List args) { } ``` -To create our function, we need to access our arguments. Use `args.value` \ No newline at end of file +To create our function, we need to access our arguments. Use `args.values[idx]` for an argument. `args.values[0]` is the first argument, `args.values[1]` is the second argument, etc. + +```c +#include "groundext.h" + +GroundValue greetUser(GroundScope* scope, List args) { + const char* argument = args.values[0].data.stringVal; +} +``` +The function expects us to return a `GroundValue`. After we create our string, we need to convert it to a `GroundValue` using the `groundCreateValue()` command. The syntax is `groundCreateValue(TYPE, value)`. + +All together, we can write our function like this: + +```c +#include "groundext.h" +#include +#include + +GroundValue greetUser(GroundScope* scope, List args) { + const char* argument = args.values[0].data.stringVal; + // Create return char* + char* ret = malloc(9+strlen(argument)); + snprintf(ret, 9+strlen(argument), "%s%s%s", "Hello, ", argument, "!"); + // Convert char* to GroundValue + return groundCreateValue(STRING, ret); +} +``` +We can add as many functions as we want here, but these won't work yet. To allow Ground to access these variables, we need to add the following code +```c +void ground_init(GroundScope* scope) { + groundAddNativeFunction(scope, "name", function, RETURNTYPE, argNum, ARG1TYPE, name, ARG2TYPE, name, ...); +} +``` +For our example, it would look something like this: +```c +#include "groundext.h" +#include +#include + +GroundValue greetUser(GroundScope* scope, List args) { + const char* argument = args.values[0].data.stringVal; + // Create return char* + char* ret = malloc(9+strlen(argument)); + snprintf(ret, 9+strlen(argument), "%s%s%s", "Hello, ", argument, "!"); + // Convert char* to GroundValue + return groundCreateValue(STRING, ret); +} + +void ground_init(GroundScope* scope) { + groundAddNativeFunction(scope, "Example.GreetUser", greetUser, STRING, 1, STRING, "username"); +} +``` +Now all we need to do is compile with `gcc file.c -shared -o file.so -fPIC`. + +## Ground Code +Once we have created the shared object file, we can import it as follows + +```grnd +extern "file" +``` +We can call our function with `call !Example.GreetUser $string &out` + +Example: + +```py +extern "file" + +call !Example.GreetUser "DiamondNether90" &out +println $out # Prints "Hello, DiamondNether90!" +``` \ No newline at end of file