diff --git a/flamingo/flamingo.c b/flamingo/flamingo.c index cdcd209..65559f3 100644 --- a/flamingo/flamingo.c +++ b/flamingo/flamingo.c @@ -146,8 +146,9 @@ char* flamingo_err(flamingo_t* flamingo) { return flamingo->err; } -void flamingo_register_cb_call(flamingo_t* flamingo, flamingo_cb_call_t cb, void* data) { - // fprintf(stderr, "%s: not implemented\n", __func__); +void flamingo_register_external_fn_cb(flamingo_t* flamingo, flamingo_external_fn_cb_t cb, void* data) { // TODO Better name for this. + flamingo->external_fn_cb = cb; + flamingo->external_fn_cb_data = data; } static int parse(flamingo_t* flamingo, TSNode node) { diff --git a/flamingo/flamingo.h b/flamingo/flamingo.h index ac324d6..383436b 100644 --- a/flamingo/flamingo.h +++ b/flamingo/flamingo.h @@ -12,7 +12,7 @@ typedef struct flamingo_val_t flamingo_val_t; typedef struct flamingo_var_t flamingo_var_t; typedef struct flamingo_scope_t flamingo_scope_t; -typedef int (*flamingo_cb_call_t)(flamingo_t* flamingo, char* name, void* data); +typedef int (*flamingo_external_fn_cb_t)(flamingo_t* flamingo, size_t name_size, char* name, void* data); typedef enum { FLAMINGO_VAL_KIND_NONE, @@ -26,7 +26,7 @@ typedef enum { typedef enum { FLAMINGO_FN_KIND_FUNCTION, FLAMINGO_FN_KIND_CLASS, - FLAMINGO_FN_KIND_PROTO, + FLAMINGO_FN_KIND_PROTO, // XXX Maybe a better name for this is '*_EXTERN'? } flamingo_fn_kind_t; typedef void* flamingo_ts_node_t; // Opaque type, because user shouldn't have to include Tree-sitter stuff in their namespace (or concern themselves with Tree-sitter at all for that matter). @@ -104,7 +104,8 @@ struct flamingo_t { char err[256]; bool errors_outstanding; - flamingo_cb_call_t cb_call; + flamingo_external_fn_cb_t external_fn_cb; + void* external_fn_cb_data; // Runtime stuff. @@ -132,7 +133,7 @@ int flamingo_create(flamingo_t* flamingo, char const* progname, char* src, size_ void flamingo_destroy(flamingo_t* flamingo); char* flamingo_err(flamingo_t* flamingo); -void flamingo_register_cb_call(flamingo_t* flamingo, flamingo_cb_call_t cb, void* data); +void flamingo_register_external_fn_cb(flamingo_t* flamingo, flamingo_external_fn_cb_t cb, void* data); int flamingo_inherit_scope_stack(flamingo_t* flamingo, size_t stack_size, flamingo_scope_t** stack); int flamingo_run(flamingo_t* flamingo); diff --git a/flamingo/grammar/call.h b/flamingo/grammar/call.h index 6c9e1a8..58ad06c 100644 --- a/flamingo/grammar/call.h +++ b/flamingo/grammar/call.h @@ -172,12 +172,23 @@ static int parse_call(flamingo_t* flamingo, TSNode node, flamingo_val_t** val) { } } - // Actually parse the function's body. + // If external function: call the external function callback. + // If function or class: actually parse the function's body. TSNode* const body = callable->fn.body; flamingo_scope_t* inner_scope; - if (parse_block(flamingo, *body, is_class ? &inner_scope : NULL) < 0) { + if (callable->fn.kind == FLAMINGO_FN_KIND_PROTO) { + if (flamingo->external_fn_cb == NULL) { + return error(flamingo, "cannot call external function without a external function callback being set"); + } + + flamingo->external_fn_cb(flamingo, callable->name_size, callable->name, flamingo->external_fn_cb_data); + + // TODO Rest. + } + + else if (parse_block(flamingo, *body, is_class ? &inner_scope : NULL) < 0) { return -1; } diff --git a/flamingo/grammar/import.h b/flamingo/grammar/import.h index fe31e3b..cb97c6c 100644 --- a/flamingo/grammar/import.h +++ b/flamingo/grammar/import.h @@ -62,7 +62,7 @@ static int import(flamingo_t* flamingo, char* path) { goto err_flamingo_create; } - flamingo_register_cb_call(imported_flamingo, flamingo->cb_call, NULL); + flamingo_register_external_fn_cb(imported_flamingo, flamingo->external_fn_cb, flamingo->external_fn_cb_data); // Set the scope stack for the imported flamingo instance to be the same as ours. diff --git a/main.c b/main.c index 8d71f2a..8a4278f 100644 --- a/main.c +++ b/main.c @@ -36,8 +36,8 @@ static void usage(void) { exit(EXIT_FAILURE); } -static int call_cb(flamingo_t* flamingo, char* name, void* data) { - printf("function call: %s\n", name); +static int external_fn_cb(flamingo_t* flamingo, size_t name_size, char* name, void* data) { + printf("function call: %.*s\n", (int) name_size, name); return 0; } @@ -95,7 +95,7 @@ int main(int argc, char* argv[]) { goto err_flamingo_create; } - flamingo_register_cb_call(&flamingo, call_cb, NULL); + flamingo_register_external_fn_cb(&flamingo, external_fn_cb, NULL); // run program