Plugins extend the capabilities of FlavorLang by allowing developers (like you) to write custom functions in C. This tutorial walks you through creating, compiling, and using plugins in your FlavorLang scripts.
- Writing Your First Plugin
- Compiling Your Plugin
- Using Your Plugin in FlavorLang
- Running the Script
- Best Practices
- License
Plugins interact with FlavorLang using the API defined in fl_plugin.h
. Key components of the API include:
- InterpretResult: Returned by plugin functions, containing the result value & metadata.
- ASTNode: Represents the Abstract Syntax Tree (AST) node passed to the plugin function.
- Helper Functions:
create_default_value()
: Creates a defaultLiteralValue
.make_result()
: Builds anInterpretResult
from aLiteralValue
.
Here's a plugin with two functions:
printSomething
: Prints a string passed as an argument.addNumbers
: Adds two integers passed as arguments.
example_plugin.c
#include "fl_plugin.h"
#include <stdio.h>
// Function to print a message
InterpretResult printSomething(struct ASTNode *node, Environment *env) {
(void)env; // unused
// Get the arguments list from the function call AST node
ASTNode *args = node->function_call.arguments;
char *msg = "No message";
if (args != NULL && args->type == AST_LITERAL &&
args->literal.type == LITERAL_STRING) {
msg = args->literal.value.string;
}
printf("Plugin says: %s\n", msg);
// Return a default value (0)
LiteralValue lv = create_default_value();
return make_result(lv, false, false);
}
// Function to add two numbers
InterpretResult addNumbers(struct ASTNode *node, Environment *env) {
(void)env; // unused
// Extract arguments from the function call node
ASTNode *args = node->function_call.arguments;
// Validate the number of arguments
if (args == NULL || args->next == NULL) {
fprintf(stderr, "Error: addNumbers requires 2 arguments.\n");
LiteralValue error_value = create_default_value();
return make_result(error_value, false, false);
}
// Extract & validate the arguments as integers
INT_SIZE num1 =
(args->type == AST_LITERAL && args->literal.type == LITERAL_INTEGER)
? args->literal.value.integer
: 0;
INT_SIZE num2 = (args->next->type == AST_LITERAL &&
args->next->literal.type == LITERAL_INTEGER)
? args->next->literal.value.integer
: 0;
INT_SIZE result = num1 + num2;
printf("Adding " INT_FORMAT " + " INT_FORMAT " = " INT_FORMAT "\n", num1,
num2, result);
// Return the result
LiteralValue result_value;
result_value.type = LITERAL_INTEGER;
result_value.data.integer = result;
return make_result(result_value, false, false);
}
FlavorLang provides a --make-plugin
flag to simplify plugin compilation:
$ flavor example_plugin.c --make-plugin
This command creates a shared library file (example_plugin.so
on Linux/macOS or example_plugin.dll
on Windows — currently only Linux/macOS is supported).
To compile the plugin manually, use the following commands:
Linux/macOS
gcc -shared -o example_plugin.so -fPIC example_plugin.c
Windows
cl /LD example_plugin.c /Fpexample_plugin.dll
Ensure fl_plugin.h is in the include path during compilation.
Use the cimport
function to load your plugin in a FlavorLang script:
cimport("example_plugin.so", "printSomething");
cimport("example_plugin.so", "addNumbers");
Once imported, plugin functions can be called like native FlavorLang functions:
Example Script: test_plugin.flv
cimport("example_plugin.so", "printSomething");
cimport("example_plugin.so", "addNumbers");
printSomething("Hello, Plugin!");
let result = addNumbers(10, 20);
serve("Addition Result:", result);
Execute the script using the flavor
command:
$ flavor test_plugin.flv
Output:
Plugin says: Hello, Plugin!
Adding 10 + 20 = 30
Addition Result: 30
- Argument Validation: Always check the number & type of arguments passed to your plugin functions to prevent runtime errors.
- Cross-Platform Support: Use platform-specific flags & file extensions when compiling plugins for different operating systems.
- Error Messaging: Provide clear & informative error messages when argument validation fails.
This project is licensed under the Apache 2.0 License — see the LICENSE file for details.
© 2024-2025 Kenneth Oliver. All rights reserved.