diff --git a/src/llvm/function/function-types.h b/src/llvm/function/function-types.h new file mode 100644 index 0000000..0af0c1a --- /dev/null +++ b/src/llvm/function/function-types.h @@ -0,0 +1,28 @@ + +#ifndef LLVM_TYPES_FUNCTION_TYPES_H_ +#define LLVM_TYPES_FUNCTION_TYPES_H_ + +#include +#include + +enum IO_Qualifier_t { + Unspec, + In, + Out, + InOut +}; + +typedef struct GemstoneParam_t { + const char* name; + enum IO_Qualifier_t qualifier; + GemstoneTypeRef typename; +} GemstoneParam; + +typedef struct GemstoneFun_t { + const char* name; + GArray* params; +} GemstoneFun; + +typedef GemstoneFun* GemstoneFunRef; + +#endif // LLVM_TYPES_FUNCTION_TYPES_H_ diff --git a/src/llvm/function/function.c b/src/llvm/function/function.c index 08a3e45..40323ba 100644 --- a/src/llvm/function/function.c +++ b/src/llvm/function/function.c @@ -1,6 +1,6 @@ -#include "ast/ast.h" -#include "llvm/types/scope.h" +#include +#include #include #include #include @@ -74,3 +74,34 @@ GemstoneParam param_from_ast(const TypeScopeRef scope, const AST_NODE_PTR node) return param; } + +GemstoneFunRef fun_from_ast(const TypeScopeRef scope, const AST_NODE_PTR node) { + if (node->kind != AST_Fun) { + PANIC("Node must be of type AST_Fun: %s", AST_node_to_string(node)); + } + + GemstoneFunRef function = malloc(sizeof(GemstoneFun)); + function->name = AST_get_node(node, 0)->value; + function->params = g_array_new(FALSE, FALSE, sizeof(GemstoneParam)); + + AST_NODE_PTR list = AST_get_node(node, 1); + for (size_t i = 0; i < list->child_count; i++) { + AST_NODE_PTR param_list = AST_get_node(list, i); + + for (size_t k = 0; k < param_list->child_count; k++) { + AST_NODE_PTR param = AST_get_node(param_list, k); + + GemstoneParam par = param_from_ast(scope, param); + + g_array_append_val(function->params, par); + } + } + + // TODO: parse function body + return function; +} + +void fun_delete(const GemstoneFunRef fun) { + g_array_free(fun->params, TRUE); + free(fun); +} diff --git a/src/llvm/function/function.h b/src/llvm/function/function.h index da74126..3e6ceec 100644 --- a/src/llvm/function/function.h +++ b/src/llvm/function/function.h @@ -3,25 +3,8 @@ #define LLVM_FUNCTION_H_ #include -#include - -enum IO_Qualifier_t { - Unspec, - In, - Out, - InOut -}; - -typedef struct GemstoneParam_t { - const char* name; - enum IO_Qualifier_t qualifier; - GemstoneTypeRef typename; -} GemstoneParam; - -typedef struct GemstoneFun_t { - const char* name; - // TODO: add array of parameters -} GemstoneFun; +#include +#include /** * @brief Convert an AST node into a function parameter struct @@ -35,8 +18,15 @@ GemstoneParam param_from_ast(const TypeScopeRef scope, const AST_NODE_PTR node); * @brief Convert an AST node into a function * * @param node the node starting a function - * @return GemstoneFun + * @return GemstoneFunRef */ -GemstoneFun fun_from_ast(const TypeScopeRef scope, const AST_NODE_PTR node); +GemstoneFunRef fun_from_ast(const TypeScopeRef scope, const AST_NODE_PTR node); + +/** + * @brief Delete the given function + * + * @param fun + */ +void fun_delete(const GemstoneFunRef fun); #endif // LLVM_FUNCTION_H_ diff --git a/src/llvm/types/scope.c b/src/llvm/types/scope.c index 659a99f..347b83e 100644 --- a/src/llvm/types/scope.c +++ b/src/llvm/types/scope.c @@ -1,4 +1,5 @@ +#include #include #include #include @@ -6,6 +7,7 @@ struct TypeScope_t { GArray* types; GArray* scopes; + GArray* funcs; TypeScopeRef parent; }; @@ -15,6 +17,7 @@ TypeScopeRef type_scope_new() { // neither zero termination no initialisazion to zero needed scope->scopes = g_array_new(FALSE, FALSE, sizeof(TypeScopeRef)); scope->types = g_array_new(FALSE, FALSE, sizeof(GemstoneTypedefRef)); + scope->funcs = g_array_new(FALSE, FALSE, sizeof(GemstoneFunRef)); scope->parent = NULL; return scope; @@ -70,6 +73,27 @@ void type_scope_delete(TypeScopeRef scope) { g_array_free(scope->scopes, TRUE); g_array_free(scope->types, TRUE); + g_array_free(scope->funcs, TRUE); free(scope); } + +void type_scope_add_fun(TypeScopeRef scope, GemstoneFunRef function) { + g_array_append_val(scope->funcs, function); +} + +GemstoneFunRef type_scope_get_fun_from_name(TypeScopeRef scope, const char* name) { + for (guint i = 0; i < scope->funcs->len; i++) { + GemstoneFunRef funref = ((GemstoneFunRef*) scope->funcs->data)[i]; + + if (strcmp(funref->name, name) == 0) { + return funref; + } + } + + if (scope->parent == NULL) { + return NULL; + } + + return type_scope_get_fun_from_name(scope->parent, name); +} diff --git a/src/llvm/types/scope.h b/src/llvm/types/scope.h index 3e79003..c58a367 100644 --- a/src/llvm/types/scope.h +++ b/src/llvm/types/scope.h @@ -2,6 +2,7 @@ #ifndef LLVM_TYPE_SCOPE_H_ #define LLVM_TYPE_SCOPE_H_ +#include #include #include @@ -80,4 +81,22 @@ GemstoneTypedefRef type_scope_get_type_from_name(TypeScopeRef scope, const char* [[gnu::nonnull(1)]] void type_scope_delete(TypeScopeRef scope); +/** + * @brief Add a function ot the type scope + * + * @param scope + * @param function + */ +void type_scope_add_fun(TypeScopeRef scope, GemstoneFunRef function); + +/** + * @brief Attempts to find a function by its name in the current scope + * + * @param scope + * @param name + * @return GemstoneFunRef + */ +[[gnu::nonnull(1), gnu::nonnull(2)]] +GemstoneFunRef type_scope_get_fun_from_name(TypeScopeRef scope, const char* name); + #endif // LLVM_TYPE_SCOPE_H_ diff --git a/tests/llvm/params/params.c b/tests/llvm/params/params.c index 8aa96d3..36a2ea4 100644 --- a/tests/llvm/params/params.c +++ b/tests/llvm/params/params.c @@ -102,17 +102,10 @@ int main(int argc, char *argv[]) { TypeScopeRef scope = type_scope_new(); AST_NODE_PTR fun = AST_get_node(root, 0); - AST_NODE_PTR list = AST_get_node(fun, 1); - - for (size_t i = 0; i < list->child_count; i++) { - AST_NODE_PTR param_list = AST_get_node(list, i); - - for (size_t k = 0; k < param_list->child_count; k++) { - AST_NODE_PTR param = AST_get_node(param_list, i); - - GemstoneParam par = param_from_ast(scope, param); - } - } + + GemstoneFunRef function = fun_from_ast(scope, fun); + type_scope_add_fun(scope, function); + assert(function->params->len == 3); type_scope_delete(scope); diff --git a/tests/llvm/params/test.txt b/tests/llvm/params/test.txt index fa2dc57..1b94e93 100644 --- a/tests/llvm/params/test.txt +++ b/tests/llvm/params/test.txt @@ -1,4 +1,4 @@ -fun a(in int: a, in float: b) { +fun a(in out int: a, in float: b)(out float: c) { a = 0 } \ No newline at end of file